Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
2  
may be you could buffer them? –  iant Jun 26 '13 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 '13 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 '13 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 '13 at 14:12

1 Answer 1

up vote 3 down vote accepted

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 (
  VALUES
   -- 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
)
SELECT
  ST_GeometryType(hull) AS hull_type,
  ST_AsText(hull) AS hull,
  ST_AsText(
  CASE
    WHEN ST_GeometryType(hull) = 'ST_Polygon' THEN hull
    ELSE ST_Buffer(hull, 0.01)
  END) AS always_polygon
FROM hulls;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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