Skip to contents

Runs a DTSCAN-style clustering pipeline using a Delaunay triangulation of point coordinates, global pruning based on z-scored triangle areas and edge lengths, and MinPts graph expansion. Returns only the cluster labels vector aligned to the input rows.

Usage

sf_dtscan(x, min_pts = 5, area_z_min = 0, length_z_min = 0, id_col = NULL)

Arguments

x

An sf object with POINT geometry.

min_pts

Minimum neighbour count for a point to be treated as a core point. Neighbours are the sites directly connected by kept Delaunay edges after pruning. If multiple input points share exactly the same coordinates, they are collapsed to one site and their multiplicity contributes to this count.

area_z_min

Threshold (in SD units) on the inverse z-score of triangle areas used for pruning. Larger thresholds keep only progressively smaller-than-average triangles and prune more edges. Default to 0.

length_z_min

Threshold (in SD units) on the inverse z-score of Delaunay edge lengths used for pruning. Larger thresholds keep only progressively shorter-than-average edges and prune more connections.

id_col

Optional character scalar naming a unique identifier column in x used to align output. If NULL or missing from x, output is aligned by current row order.

Value

An integer vector of cluster labels of length nrow(x). 0 indicates noise/unassigned; positive integers are cluster ids.

Details

Identical coordinates are collapsed before triangulation; their multiplicity contributes to MinPts via effective_degree = degree + (mult - 1). Cluster labels are produced by starting a new cluster at each unassigned core site (a site meeting the MinPts rule) and iteratively visiting all sites reachable through pruned Delaunay edges from that seed; the cluster id is assigned to every visited site.

References

Kim, J., & Cho, J. (2019). Delaunay triangulation-based spatial clustering technique for enhanced adjacent boundary detection and segmentation of LiDAR 3D point clouds. Sensors, 19(18), 3926. doi:10.3390/s19183926

Examples

data(mini_ruff)
x = as_ctdf(mini_ruff)[.id %in% 90:177]
x[,
  cluster := sf_dtscan(
    st_as_sf(x),
    id_col = ".id",
    min_pts = 5,
    area_z_min = 0,
    length_z_min = 0
  )
]
#> Error in st_as_sf(x): could not find function "st_as_sf"