I'm using ST_ClusterDBSCAN to cluster polygons. I'm familiar with the algorithm (or so I thought) but the results of the PostGIS implementation are confusing me. When running it with minpoints larger than 2, many of the clusters simply vanish, despite these very same clusters being present in a previous minpoints=2 run while having more than the specified minpoints number of features.

Here is an example using a subset of my complete data. The top image is a clustering done with eps=5 and minpoints=2. The bottom image is the same clustering, but with minpoints=5:


enter image description here


enter image description here

Notice how the dark blue cluster in the first image disappears when minpoints is raised to 5, despite there being 12 features in the first case. eps was not changed.

Am I missing a crucial detail in the algorithm or its implementation? Why are these clusters vanishing? I know that DBSCAN is not technically 100% deterministic but I would think that obvious clusters like this just straight-up vanishing is wrong.

So far as a workaround I just run it with minpoints=2 and then filter the results afterwards so exclude clusters with less than my actually desired minpoints value. But this is cumbersome and inefficient when scaling up.

I am using:

  • Postgres 11.2
  • PostGIS 2.5.2
  • GEOS 3.5.1

Here is some sample code to try it out on this data sample:

Create table

Too large for Stack Exchange, here is a pastebin link.

ST_ClusterDBSCAN with different minpoints

drop table if exists buildings_cluster_test_result_mp5;
create table buildings_cluster_test_result_mp5 as (
        ST_ClusterDBSCAN(b.geom, eps := 5, minpoints := 5) over () AS cid
        buildings_cluster_test b
drop table if exists buildings_cluster_test_result_mp2;
create table buildings_cluster_test_result_mp2 as (
        ST_ClusterDBSCAN(b.geom, eps := 5, minpoints := 2) over () AS cid
        buildings_cluster_test b

1 Answer 1


In your examples the DBSCAN algorithm is working correctly. The reason is that the minpoints parameter actually specifies the minimum number of close objects needed to start a cluster. That is, a cluster is only created around an object which has at least minpoints objects within a distance of eps of it.

The eps distance you are using is fairly small relative to the distance between objects. So for minpoints = 5, only the upper left cluster contains an item which has >= 5 items within distance eps of it.

The ST_ClusterWithin function might provide grouping which is closer to what you require (although it is not yet available as a window function, only as an aggregate).

  • ST_ClusterWithin should be equal toeps=0 for 99% of cases.
    – geozelot
    Mar 2 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.