Points from Polygon

View: New views
5 Messages — Rating Filter:   Alert me  

Points from Polygon

by tommy408 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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?

Re: Points from Polygon

by Mike Toews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
_______________________________________________
postgis-users mailing list
postgis-users@...
http://postgis.refractions.net/mailman/listinfo/postgis-users

Re: Points from Polygon

by Kevin Neufeld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes, that's right.  ST_Boundary will convert the polygon to
[multi]linestrings which you can then use to extract the points.

These have examples that should help:
http://postgis.refractions.net/documentation/manual-svn/ST_PointN.html
http://postgis.refractions.net/documentation/manual-svn/ST_NPoints.html
http://postgis.refractions.net/documentation/manual-svn/ST_GeometryN.html

Mike, nice solution with your function.  Have to give that a try sometime.
-- Kevin

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?
>  
_______________________________________________
postgis-users mailing list
postgis-users@...
http://postgis.refractions.net/mailman/listinfo/postgis-users

Re: Points from Polygon

by tommy408 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

thank you Mike and Kevin

Mike Toews wrote:
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
_______________________________________________
postgis-users mailing list
postgis-users@postgis.refractions.net
http://postgis.refractions.net/mailman/listinfo/postgis-users

Re: Points from Polygon

by Maxime van Noppen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 07/05/09 10:49, tommy408 wrote:
> thank you Mike and Kevin

There is another solution (that I use) to iterate over the points of a
Polygon. Via the ST_ExteriorRing function one can get the LineString of
the exterior ring and therefore use ST_PointN.

--
yabo
_______________________________________________
postgis-users mailing list
postgis-users@...
http://postgis.refractions.net/mailman/listinfo/postgis-users