[postgis-users] Points from Polygon

Mike Toews mwtoews at sfu.ca
Sat Jun 27 18:23:24 PDT 2009


tommy408 wrote:
> How can I extract points from all the vertex of a polygon?
>
> I see there are ST_NPoints and ST_PointN for linestring.  But nothing for
> polygons.  Maybe convert polygon to linestring then linestring to points?
>   
I had the same requirement a few weeks ago, and it turns out there is 
not built-in function (yet), so you need to write your own function. 
Here is what I came up with. It returns a geometry_dump data type, which 
has members 'part' and 'geom'. It is similar to ST_Dump(), but returns 
points. I have Postgres 8.3, which means that I need to wrap one 
set-returning function in another so I can use the function on the 
left-side of the FROM in an SQL statement. (This is a non-issue with 
8.4). It works with POLYGON and MULTIPOLYGON geometry types. Also, my 
solution only returns points for boundary polygons (not inner 
rings/islands, etc.):

CREATE OR REPLACE FUNCTION st_dumppoints_plpgsql(geometry)
  RETURNS SETOF geometry_dump AS
$BODY$DECLARE
 m integer;
 g geometry;
 n integer;
 p geometry_dump%ROWTYPE;
BEGIN
  IF GeometryType($1) LIKE 'MULTI%' THEN
    FOR m IN SELECT generate_series(1, ST_NumGeometries($1)) LOOP
      p.path[1] := m; -- use to store Multipolygon number
      g := ST_Boundary(ST_GeometryN($1, m));
      FOR n IN SELECT generate_series(1, ST_NumPoints(g) - 1) LOOP
        p.path[2] := n; -- use to store Point number
        p.geom := ST_PointN(g, n);
        RETURN NEXT p;
      END LOOP;
    END LOOP;
  ELSE -- It is not a MULTI- geometry
    g := ST_Boundary($1);
    FOR n IN SELECT generate_series(1, ST_NumPoints(g) - 1) LOOP
      p.path[1] := n; -- use to store Point number
      p.geom := ST_PointN(g, n);
      RETURN NEXT p;
    END LOOP;
  END IF;
  RETURN;
END;$BODY$
  LANGUAGE 'plpgsql' IMMUTABLE STRICT
  COST 100
  ROWS 1000;


CREATE OR REPLACE FUNCTION st_dumppoints(geometry)
  RETURNS SETOF geometry_dump AS
'SELECT * FROM ST_DumpPoints_plpgsql($1);'
  LANGUAGE 'sql' IMMUTABLE STRICT
  COST 100
  ROWS 1000;



--Mike



More information about the postgis-users mailing list