Question

I have a table full of point geometries that display normally in GIS clients. I want to group the points on an attribute (groupid) and create convex hulls around those. Seems straightforward, but getting an unexpected result: a 'geometry' field with mix of points, linestrings and polygons. I was expecting only polygons, and maybe for groups with a count of 1 to be ignored. Any ideas?

The query:

SELECT groupid, ST_ConvexHull(ST_Collect(geom))) As hull_geom into hulledpoints
    FROM somepoints
    GROUP BY groupid;
Was it helpful?

Solution

The easiest way to ensure that you only have polygons is to ensure that you only take the convex hull of groups where the groupid count is greater than 2.

SELECT groupid, ST_ConvexHull(ST_Collect(geom))) As hull_geom into hulledpoints
FROM somepoints
GROUP BY groupid
HAVING count(groupid)>2;

This is because the convex hull of two points is a linestring, while the convex hull of a point is that same point, eg,

select ST_AsText(ST_ConvexHull(ST_Collect(St_MakePoint(1,1),St_MakePoint(2,2))));

which returns LINESTRING(1 1,2 2).

If you wanted to use a geometric rather than a sql approach, you could check the returned hulls were polygons. The following example returns nothing, as although there are three points, two are coincident, so the convex hull will still be a linestring.

with hulls as (select ST_ConvexHull(ST_Collect(Array[St_MakePoint(1,1),
  St_MakePoint(2,2), St_MakePoint(2,2)])) as hull)
select * from hulls where ST_GeometryType(hull)='ST_Polygon';

In your original example, you would write the above query along the lines of,

with hulls as (SELECT groupid, ST_ConvexHull(ST_Collect(geom)) As hull_geom 
  FROM somepoints  GROUP BY groupid)
select * from hulls where ST_GeometryType(hull_geom)='ST_Polygon';

OTHER TIPS

ad

"getting an unexpected result: a 'geometry' field with mix of points, linestrings and polygons."

That's easy to test: The convex hull of a point is a point

select st_astext(st_convexhull(st_makepoint(1,2)))

st_astext
POINT(1 2)

and for two points, it's a line

select st_astext(st_convexhull(st_collect(st_makepoint(1,2),st_makepoint(2,2))))

st_astext
LINESTRING(1 2,2 2)

If you have more GIS-related questions, feel free to post at http://gis.stackexchange.com.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top