PostGISClustering

ST_ClusterWithin

What is ST_ClusterWithin?

ST_ClusterWithin is a PostGIS aggregate function that groups input geometries into clusters using single-linkage clustering by distance. Any two geometries within the supplied distance threshold are in the same cluster; clusters merge transitively through chains of nearby geometries.

SQL
1ST_ClusterWithin(geometry set g, float8 distance)geometry[]
2ST_ClusterWithin(geometry[] g, float8 distance)geometry[]

The result is an array of GeometryCollections, one per cluster.

When would you use ST_ClusterWithin?

Use ST_ClusterWithin to merge features that are close enough to treat as a single group — grouping buildings within walking distance, collecting sensor readings into location-based bins, or merging overlapping or near-touching polygons. It is the distance-based cousin of ST_ClusterIntersecting.

SQL
1SELECT (ST_Dump(g)).geom AS cluster_member
2FROM (
3  SELECT unnest(ST_ClusterWithin(geom, 50)) AS g
4  FROM bus_stops
5) t;

FAQs

What units is the distance in?

The same units as the input geometry's SRID — metres for projected CRSs, degrees for geographic CRSs like EPSG:4326. For a 50-metre threshold on lat/lon data, reproject to a metric CRS first.

How is this different from ST_ClusterDBSCAN?

ST_ClusterWithin is single-linkage clustering: any two features within distance join the same cluster, and small sparse groups are kept. ST_ClusterDBSCAN adds a minpoints threshold to reject sparse groups as noise and is better at avoiding "chaining" artefacts in noisy data.

When should I use this over ST_ClusterIntersecting?

Use ST_ClusterIntersecting when you want to join only features that actually touch or overlap (distance = 0). Use ST_ClusterWithin when proximity — not strict touching — defines the clusters.

How do I get a single dissolved polygon per cluster?

Wrap each cluster collection with ST_Union: SELECT ST_Union(ST_CollectionExtract(g, 3)) FROM unnest(ST_ClusterWithin(geom, 50)) g. That dissolves each cluster's geometries into a single polygon or multipolygon.