| 1 | == Building areas from lines == |
| 2 | Built-in PostGIS functions [http://postgis.net/docs/ST_BuildArea.html ST_BuildArea] and [http://postgis.net/docs/ST_Polygonize.html ST_Polygonize] can be used to construct Polygons from linework. However the start/end points of all lines must touch each other to form the polygons. Also the linework needs to be properly noded at intersections, rather than just crossing each other. |
| 3 | |
| 4 | A user-submitted function takes a collection of LINESTRING or a MULTILINESTRING geometry and returns a geometry: |
| 5 | {{{ |
| 6 | #!sql |
| 7 | CREATE OR REPLACE FUNCTION ST_BuildAreaLinework(linework geometry) RETURNS geometry AS |
| 8 | 'WITH data AS (SELECT * FROM ST_Dump($1)) |
| 9 | SELECT ST_SetSRID(ST_BuildArea(ST_Collect(geom)), ST_SRID($1)) |
| 10 | FROM |
| 11 | ( |
| 12 | SELECT (ST_Dump(ST_Union(geom))).geom FROM data |
| 13 | ) t1, |
| 14 | ( |
| 15 | SELECT ST_Union(ST_Intersection(A.geom, B.geom)) AS pt |
| 16 | FROM data A, data B |
| 17 | WHERE A.path[1] < B.path[1] AND ST_Intersects(A.geom, B.geom) |
| 18 | ) t2 |
| 19 | WHERE ST_Intersects(ST_StartPoint(geom), pt) AND ST_Intersects(ST_EndPoint(geom), pt);' LANGUAGE sql IMMUTABLE; |
| 20 | }}} |
| 21 | |
| 22 | For example: |
| 23 | {{{ |
| 24 | #!sql |
| 25 | SELECT ST_BuildAreaLinework('MULTILINESTRING((36 35,45 307),(30 290,390 280),(320 60,300 310),(20 60,320 60),(120 140,168 225),(140 220,220 150,120 170))'); |
| 26 | }}} |
| 27 | |
| 28 | == External links == |
| 29 | * [http://2010.foss4g.org/presentations/3369.pdf PostGIS: Tips for Power Users], by Paul Ramsey |
| 30 | * [http://spatialdbadvisor.com/postgis_tips_tricks/120/building-polygons-from-overlapping-linestrings-requiring-intersection Building polygons from overlapping linestrings requiring intersection], by Simon Greener |