PostGISGeometry Processing

ST_Polygonize

What is ST_Polygonize?

ST_Polygonize is a PostGIS aggregate function that builds polygons from a set of noded lines. Every enclosed face in the input linework becomes a polygon in the output, including faces that would be holes inside larger rings.

SQL
1ST_Polygonize(geometry set geomfield)geometry
2ST_Polygonize(geometry[] geom_array)geometry

The result is always a GeometryCollection of polygons — even if only one polygon is produced. The input must be noded (lines split at intersections) to polygonize correctly.

When would you use ST_Polygonize?

Use ST_Polygonize when you need all distinct faces from a network of lines — deriving every block enclosed by a road network, every patch between watercourses, or every face in a digitised sketch. It is the right tool when you want every enclosed face separately, including nested rings.

SQL
1SELECT ST_Polygonize(geom) AS faces
2FROM (
3  SELECT (ST_Dump(ST_Node(ST_Union(geom)))).geom
4  FROM road_network
5) t;

FAQs

Why is the result a GeometryCollection?

ST_Polygonize always returns a GeometryCollection even when there is only one polygon — it's a consequence of the aggregate returning a variable number of faces. Wrap in ST_CollectionExtract(..., 3) or apply ST_Dump to get individual polygons.

How is this different from ST_BuildArea?

ST_BuildArea recognises nested rings as holes and merges them into polygons with holes. ST_Polygonize treats every face as a separate polygon, including faces that would otherwise be interpreted as holes. Use ST_BuildArea when you want GIS-style polygons with holes; use ST_Polygonize when you want every face.

Why are some expected polygons missing?

If the input is not properly noded — lines cross without a shared vertex — ST_Polygonize cannot close the faces. Always run ST_Node(ST_Union(geom)) on the linework first to split every line at its intersections.

What if lines don't form any closed rings?

The result is an empty GeometryCollection. ST_Polygonize silently produces zero polygons from open or dangling lines — check the output size with ST_NumGeometries before assuming success.