24

How can I find a point that is guaranteed to be within a given polygon in PostGIS?

I am aware of the ST_Centroid function. However, the centroid is not always within a polygon, see below:

a centroid lying outside a polygon

Furthermore, I would like to avoid using a point that is on the polygon boundary, but rather want one that is inside the boundary (and not inside a hole in donut shaped polygons).

2 Answers 2

17

If you're looking for a PostGIS function that will tell you a point that's inside your polygon then the ST_PointOnSurface function may give you what you need.

SELECT 
   ST_AsText(ST_PointOnSurface('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'::geometry));

   st_astext
----------------
 POINT(2.5 2.5)
(1 row)
6

Found this function on the PostGIS mailinglist. I guess it is what you require:

CREATE OR REPLACE FUNCTION point_inside_geometry(param_geom geometry)
  RETURNS geometry AS
$$
  DECLARE
     var_cent geometry := ST_Centroid(param_geom);
     var_result geometry := var_cent;
  BEGIN
  -- If the centroid is outside the geometry then 
  -- calculate a box around centroid that is guaranteed to intersect the geometry
  -- take the intersection of that and find point on surface of intersection
 IF NOT ST_Intersects(param_geom, var_cent) THEN
  var_result := ST_PointOnSurface(ST_Intersection(param_geom, ST_Expand(var_cent, ST_Distance(var_cent,param_geom)*2) ));
 END IF;
 RETURN var_result;
  END;
  $$
  LANGUAGE plpgsql IMMUTABLE STRICT
  COST 100;
1
  • I like that this solution gives a point which is closer to the centroid than ST_PointOnSurface by itself, but it does also produce a point which is closer to the edge of the polygon. ST_PointOnSurface seems to choose a point which is as far away from any edges as possible. I suppose it's a matter of taste, as far as choosing the solution right for you.
    – dslh
    Commented Nov 5, 2013 at 23:38

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.