Purpose: Group spatial points into density-based clusters (hotspots) and separate genuine clusters from scattered noise using DBSCAN.
Business problem: Hotspot detection is a core GIS analytic — incident clustering, crime/complaint hotspots, retail catchment cores, and sensor-anomaly grouping all reduce to "which points form dense neighborhoods."
Scope: Euclidean DBSCAN over 2-D coordinates. Great-circle (haversine) distance and spatial indexing are natural next steps for real geographic datasets.
Algorithm
DBSCAN: Two parameters — epsilon (neighborhood radius) and minPoints (density threshold). Core points have at least minPoints neighbors within epsilon; density-reachable points join the same cluster; everything else is noise.
No pre-set cluster count: Unlike k-means, DBSCAN discovers the number of clusters from the data and is robust to arbitrary cluster shapes.
Border reclamation: Points first labelled as noise are reclaimed as border points when they fall inside a later cluster's neighborhood — a subtle correctness detail preserved identically in both the native and managed paths.
Complexity: The MVP uses a brute-force O(n²) region query, which is honest and simple; a grid or k-d tree index would bring it toward O(n log n) for large inputs.
API Layer
Controller:SpatialClusterController is versioned at /api/v1/clustering and allows anonymous demo access.
Response:DbscanResultDto returns per-point cluster labels (-1 = noise), a cluster count, per-cluster sizes, and a noise tally.
Validation: The service enforces a point cap, a finite positive epsilon, a minimum-points floor, and finite coordinates.
Services and Native Boundary
Service:SpatialClusterService validates input, dispatches to SpatialClusterNativeBridge, and assembles the labelled result shared by both paths.
Native bridge:SpatialClusterNativeBridge marshals a contiguous point array and a preallocated label buffer into C++ and reads the returned cluster count.
C++ library:native/spatial_cluster_kernel exposes Cluster_RunDbscan, returning the cluster count and writing one label per point.
Why C++ here: DBSCAN's inner region-query loop is a tight numeric distance kernel over contiguous memory — a strong SIMD/cache-locality candidate as point counts grow.
Managed fallback:SpatialClusterService reproduces the identical algorithm in C#, so the workflow is correct with no native library present.
Engineering Decisions and Tradeoffs
DBSCAN over k-means: Chosen because hotspot analysis needs shape-agnostic clusters and an explicit noise class, which k-means cannot express.
Brute-force neighbors: Keeps the kernel transparent for a portfolio demo; the interface is stable enough to swap in a spatial index without changing the API.
Parity by construction: Native and managed code share the same label conventions and border-reclamation rule, making numeric-parity testing straightforward.
Future improvements: Haversine distance, k-d tree/grid acceleration, HDBSCAN, and Leaflet/ArcGIS overlays for real geographic incident data.
Interview Discussion Points
How do epsilon and minPoints trade off cluster granularity against noise sensitivity?
Why is DBSCAN a better fit than k-means for hotspot detection?
Where would a spatial index change the asymptotic complexity, and what does it cost to build?
How would you validate native/managed parity when floating-point order can differ?