Calculating shortest distance between polygons?

You can use ST_ClusterDBSCAN to group nearby geometries together and assigning them a cluster id. Cluster ID will be null for single geometries not within the specified distance of another.

Image taken from the help section showing cluster IDs:

enter image description here

This query should return only the records within 1000 m of Another. minpoints := 2 is to prevent single points from getting a cluster ID (since they are always within the distance of themselves):

SELECT * FROM
   (SELECT *, ST_ClusterDBSCAN(geom, eps := 1000, minpoints := 2) OVER () clusterid
      FROM int_20190124) t1
  WHERE t1.clusterid IS NOT NULL;

Example with points and 10000 m distance: enter image description here


Here is my approach,

It is called "buffer clustering at the required distance"

(do not beat off the fish from the pack at the specified distance, and then we will eat you :-)),

It consists of 6 points, swam...

The source data shown in figure 1 enter image description here

It is polygons of polygon type. Restrictions, example, are shown without object semantics, so that you can save it yourself.

1) Create a buffer equal to almost half the required distance, for example 501 m:

create table polygons_byf as SELECT ((ST_Buffer(geography(geom),501))::geometry) as geom FROM polygons;

2) Dissolving polygon:

create table polygons_byf_dump as select st_buffer( (st_dump( st_union( st_buffer(geom, 0.0000000001)))).geom, -0.0000000001) as geom FROM polygons_byf;

(John Powell :-)...)

see figure 2

enter image description here

3) Create the median point to the original polygon:

create table polygons_byf_centr as SELECT ST_PointOnSurface(geom) as geom FROM polygons;

see figure 3

enter image description here

4) Count the number of points that fall into the combined polygons:

create table polygons_pt_count as SELECT b.geom, count (*) as cnt FROM polygons_byf_centr a, polygons_byf_dump b WHERE st_intersects(a.geom, b.geom) GROUP BY b.geom ORDER BY b.geom;

see figure 4

enter image description here

5) Delete polygons that have only one point:

DELETE from polygons_pt_count WHERE cnt = '1';

see figure 5

enter image description here

6) Select only those polygons that meet our condition:

create table polygons_sel as SELECT ST_Intersection(a.geom, b.geom) as geom FROM polygons_pt_count a, polygons as b WHERE ST_Intersects (a.geom, b.geom)

see figure 6

enter image description here

7) That's all; this is our result.


SELECT id
FROM polygons
WHERE id IN (
    SELECT
        p1.id
    FROM polygons p1
    JOIN polygons p2 ON (ST_DWithin(p1.geom, p2.geom, 1000))
    WHERE p1.id <> p2.id
);

You can join polygons on ST_Dwithin to find these being at most one km far from others. Note distance being used is given in SRID units, so be careful when using degrees.

I assume GIST index on geom field as well as PRIMARY KEY on id field exists. As stated in docs, ST_Dwithin includes bbox comparison and generally speaking, it should be faster than building buffers around the input geometries.

Tags:

Postgis