Name

ST_MakePolygon — Creates a Polygon or CurvePolygon from a shell and optional list of holes.

Synopsis

geometry ST_MakePolygon(geometry linestring);

geometry ST_MakePolygon(geometry outerlinestring, geometry[] interiorlinestrings);

Description

Creates a Polygon or CurvePolygon formed by the given shell and optional array of holes. Input geometries must be closed LineStrings, CircularStrings, CompoundCurves, or NURBSCurves (rings). If any input ring is curved, the result is a CurvePolygon.

Variant 1: Accepts one shell ring.

Variant 2: Accepts a shell ring and an array of inner (hole) rings. A geometry array can be constructed using the PostgreSQL array_agg(), ARRAY[] or ARRAY() constructs.

[Note]

Cette fonction n'accepte pas les MultiLineStrings. Utilisez ST_LineMerge pour générer une LineString, ou ST_Dump pour extraire les LineStrings.

Cette fonction prend en charge la 3D et ne supprime pas l'indice z.

Enhanced: 3.7.0 - Support for curved input rings was introduced.

Exemples : variante avec une entrée unique

Créez un polygone à partir d'une LineString 2D.

SELECT ST_MakePolygon(ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)'));

Créez un polygone à partir d'une LineString ouverte, en utilisant ST_StartPoint et ST_AddPoint pour la fermer.

SELECT ST_MakePolygon(ST_AddPoint(foo.open_line, ST_StartPoint(foo.open_line)) )
FROM (
  SELECT ST_GeomFromText('LINESTRING(75 29,77 29,77 29, 75 29)') As open_line) As foo;

Créer un polygone à partir d'une LineString 3D

SELECT ST_AsEWKT(ST_MakePolygon('LINESTRING(75.15 29.53 1,77 29 1,77.6 29.5 1, 75.15 29.53 1)'));
POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))

Créer un polygone à partir d'une LineString avec des mesures

SELECT ST_AsEWKT(ST_MakePolygon('LINESTRINGM(75.15 29.53 1,77 29 1,77.6 29.5 2, 75.15 29.53 2)'));
POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2))

Create a CurvePolygon from a CircularString shell.

SELECT ST_AsText(ST_MakePolygon('CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0)'));
CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0))

Exemples : Enveloppe extérieure avec variante de trous intérieurs

Créer un polygone en forme de donut avec un trou supplémentaire

SELECT ST_MakePolygon(
    ST_ExteriorRing(ST_Buffer(ring.line,10)),
    ARRAY[  ST_Translate(ring.line, 1, 1),
        ST_ExteriorRing(ST_Buffer(ST_Point(20,20),1)) ]
    )
FROM (SELECT ST_ExteriorRing(ST_Buffer(ST_Point(10,10),10,10)) AS line ) AS ring;

Créez un ensemble de frontières de province avec des trous représentant des lacs. L'entrée est un tableau de polygones/multipolygones de province et un tableau de lignes d'eau. Les lignes formant des lacs sont déterminées en utilisant ST_IsClosed. Le réseau de la province est extrait en utilisant ST_Boundary. Comme requis par ST_MakePolygon, la frontière est forcée à être une seule LineString en utilisant ST_LineMerge. (Cependant, notez que si une province a plus d'une région ou a des îles, cela produira un polygone invalide). L'utilisation d'un LEFT JOIN garantit que toutes les provinces sont incluses, même si elles n'ont pas de lacs.

[Note]

La construction CASE est utilisée car le passage d'un tableau nul dans ST_MakePolygon entraîne une valeur de retour NULL.

SELECT p.gid, p.province_name,
    CASE WHEN array_agg(w.geom) IS NULL
    THEN p.geom
    ELSE  ST_MakePolygon(
        ST_LineMerge(ST_Boundary(p.geom)),
        array_agg(w.geom)) END
FROM
    provinces p LEFT JOIN waterlines w
        ON (ST_Within(w.geom, p.geom) AND ST_IsClosed(w.geom))
GROUP BY p.gid, p.province_name, p.geom;

Une autre technique consiste à utiliser une sous-requête corrélée et le constructeur ARRAY() qui convertit un ensemble de lignes en un tableau.

SELECT p.gid,  p.province_name,
    CASE WHEN EXISTS( SELECT w.geom
        FROM waterlines w
        WHERE ST_Within(w.geom, p.geom)
        AND ST_IsClosed(w.geom))
    THEN ST_MakePolygon(
        ST_LineMerge(ST_Boundary(p.geom)),
        ARRAY( SELECT w.geom
            FROM waterlines w
            WHERE ST_Within(w.geom, p.geom)
            AND ST_IsClosed(w.geom)))
    ELSE p.geom
    END AS geom
FROM provinces p;