Polygon composition

A function for composing polygons is not-so-surprisingly named ST_MakePolygon. For a solid polygon without holes, it accepts one argument-a closed LineString.

  1. For example, a triangle-shaped polygon can be created using the following query:
        SELECT
ST_MakePolygon(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.90),ST_MakePoint(20,50)]));
  1. An attempt to create a polygon from fewer than four points will result in an error:
        SELECT
ST_MakePolygon(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98), ST_MakePoint(19.90,49.96)]));
ERROR: lwpoly_from_lwlines: shell must have at least 4 points

And if a ring is not closed:

        SELECT
ST_MakePolygon(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.96),ST_MakePoint(20,50),
ST_MakePoint(20.01,50.01)]));
ERROR: lwpoly_from_lwlines: shell must be closed

When creating simple shapes using coordinates typed by hand, it's rather obvious if a ring is closed or not. But what if there are hundreds or thousands of vertices? Luckily, PostGIS has a function for finding out whether a LineString is closed or not--it's called ST_IsClosed:

       SELECT
ST_IsClosed(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.96),ST_MakePoint(20,50),
ST_MakePoint(20.01,50.01)]));
st_isclosed
-------------
f

SELECT
ST_IsClosed(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.96),ST_MakePoint(20,50),
ST_MakePoint(20,50)]));
st_isclosed
-------------
t
When using Boolean-returning functions in the PostgreSQL console, f stands for false, and t for true.

PostGIS can also snap the ends of a ring to create a polygon from an unclosed LineString. Just replace ST_MakePolygon with ST_Polygonize:

        SELECT
ST_Polygonize(ST_MakeLine(ARRAY[ST_MakePoint(20,50),
ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.96),ST_MakePoint(20,50),
ST_MakePoint(20.01,50.01)]));
st_polygonize
--------------------
010700000000000000
(1 row)

Beware though--this is an automated process, and for some shapes it can lead to undesirable effects, like weirdly-shaped MultiPolygons.

  1. For constructing a polygon with holes, the interior ring(s) should be supplied as an ARRAY:
       SELECT ST_MakePolygon(
ST_MakeLine(ARRAY[ST_MakePoint(20,50),ST_MakePoint(19.95,49.98),
ST_MakePoint(19.90,49.90),ST_MakePoint(20,50)]),

ARRAY[ST_MakeLine(ARRAY[ST_MakePoint(19.95,49.97),ST_MakePoint
(19.943,49.963),
ST_MakePoint(19.955,49.965),ST_MakePoint(19.95,49.97)])]
);
An example polygon with exterior and interior rings created with ST_MakePolygon.