Search code examples
sqlpostgresqlpostgisspatial

How to draw a polygon that corresponds to the area of a point cluster?


Given the following dataset I am trying to create a polygon that covers the minimal area of a point cluster:

CREATE TABLE public.points ( 
  cat integer,
  geom geometry (point, 4326)
);

INSERT INTO points VALUES 
  (1,'SRID=4326;POINT(-35.3971 -8.1366)'),
  (1,'SRID=4326;POINT(-35.388 -8.1366)'),
  (1,'SRID=4326;POINT(-35.3907 -8.1302)'),
  (1,'SRID=4326;POINT(-35.3925 -8.1366)'),
  (1,'SRID=4326;POINT(-35.3896 -8.1418)'),
  (2,'SRID=4326;POINT(-35.3996 -8.1418)'),
  (2,'SRID=4326;POINT(-35.4056 -8.1418)'),
  (2,'SRID=4326;POINT(-35.4056 -8.1542)');

I've tried using ST_Envelope, but as the name suggests, it creates an envelope around the cluster and therefore a much larger area than we need.

SELECT ST_Envelope(geom) FROM (
  SELECT ST_Collect(geom) AS geom
  FROM points GROUP BY cat
) mypoints

How to shrink the envelopes to create a polygon that more or less covers only the points and space in between?


Solution

  • To create such a polygon you have to use either ST_ConvexHull or ST_ConcaveHull, e.g.

    WITH j AS (
      SELECT ST_Collect(geom) AS geom
      FROM points GROUP BY cat
    )
    SELECT ST_ConvexHull(geom) FROM j 
    UNION ALL SELECT geom FROM j;
    

    enter image description here

    Note: UNION ALL SELECT geom FROM j with all points just for illustration purposes.