I am working with point clusters and want to create the rough shape of the cluster in the form of a polygon using ST_ConvexHull(). I'm having problems with single outliers though, as they don't convert to a polygon but to a POINT:

SELECT ST_AsText(ST_ConvexHull(ST_Collect(point))) ...

POLYGON((13.01741532 52.40118295,13.382100866593 52.516280103729, ...))
POINT(12.5 51.5)

Is there a way to force small geometries (single or double points) into a polygon? I want to simplify the subsequent processing by guaranteeing polygons; accuracy is not a high priority in this case, making a minimal triangle out of a single point is fine, even if not exact.

  • 3
    may be you could buffer them?
    – Ian Turton
    Jun 26, 2013 at 11:09
  • I suppose that's a way, but that may produce unnecessarily complex geometries. I'd be a lot happier with a minimal bounding triangle. :)
    – deceze
    Jun 26, 2013 at 11:33
  • A "minimal bounding triangle" would be a point or a line segment. @iant is correct: any solution would be a prima facie buffer so the only questions are what shape that buffer should have and how large it ought to be.
    – whuber
    Jun 26, 2013 at 13:34
  • OK, I guess buffering it is then. Anyone care to put this into an answer so I can accept it? :)
    – deceze
    Jun 26, 2013 at 14:12

1 Answer 1


ST_ConvexHull can return Points, Linestrings, or Polygons so you'll need to buffer anything that isn't a polygon. As @whuber states, the exact buffering is up to you. The following query illustrates the general idea.

WITH pts(pt, grp) AS (
   -- single point
  (ST_MakePoint(1,1), 1),
   -- two points
   (ST_MakePoint(1,1), 2),
   (ST_MakePoint(1,2), 2),
   -- linear points - makes a linestring
   (ST_MakePoint(1,1), 3),
   (ST_MakePoint(1,2), 3),
   (ST_MakePoint(1,3), 3),
   -- expected case
   (ST_MakePoint(1,1), 4),
   (ST_MakePoint(1,2), 4),
   (ST_MakePoint(2,1), 4)
), hulls AS (
  SELECT ST_ConvexHull(ST_Collect(pt)) AS hull
  FROM pts
  GROUP BY grp
  ST_GeometryType(hull) AS hull_type,
  ST_AsText(hull) AS hull,
    WHEN ST_GeometryType(hull) = 'ST_Polygon' THEN hull
    ELSE ST_Buffer(hull, 0.01)
  END) AS always_polygon
FROM hulls;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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