PostGIS - Get a point inside a line or polygon

From the doc: ST_PointOnSurface — Returns a POINT guaranteed to lie on the surface.


In my case I have each geometry in disctint tables. What I did was :

  1. For lines -> ST_LineInterpolatePoint() with 0.5 factor.
  2. For polygons -> Test if ST_Centroid() is inside its geometry. If so, ST_Centroid() is the best choice, if not I choose PointOnSurface().

Here's the query :

SELECT
    CASE WHEN (SELECT the_geom FROM points WHERE gid = d.gid) IS NOT NULL
    THEN (SELECT the_geom FROM points WHERE gid = d.gid)
    WHEN (SELECT the_geom FROM lines WHERE gid = d.gid) IS NOT NULL
    THEN ST_LineInterpolatePoint((SELECT the_geom FROM lines WHERE gid = d.gid), 0.5)
    WHEN (SELECT the_geom FROM polygons WHERE gid = d.gid AND ST_Intersects(ST_Centroid(the_geom),the_geom)) IS NOT NULL
    THEN ST_Centroid((SELECT the_geom FROM polygons WHERE gid = d.gid))
    ELSE ST_PointOnSurface((SELECT the_geom FROM polygons WHERE gid = d.gid))
    END AS center
FROM someTable d

In the @Jose 's answer, instead of intersect we should use contains and in when condition we should use Boolean validation

SELECT
    CASE 
       WHEN (ST_Contains(the_geom, ST_Centroid(the_geom))) IS TRUE
       THEN ST_Centroid(the_geom)
       ELSE ST_PointOnSurface(the_geom)
    END AS center
FROM someTable