Nom

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

Single input variant.

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

Code
SELECT ST_MakePolygon('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.

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

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

Code
SELECT ST_MakePolygon('LINESTRING(75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1)');
Export de raster
POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))
Figure
Geometry figure for visual-st-makepolygon-01

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

Code
SELECT ST_MakePolygon('LINESTRINGM(75.15 29.53 1,77 29 1,77.6 29.5 2, 75.15 29.53 2)');
Export de raster
POLYGONM((75.15 29.53 1,77 29 1,77.6 29.5 2,75.15 29.53 2))
Figure
Geometry figure for visual-st-makepolygon-02

Create a CurvePolygon from a CircularString shell.

Code
SELECT ST_MakePolygon('CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0)');
Export de raster
CURVEPOLYGON(CIRCULARSTRING(0 0,1 1,2 0,1 -1,0 0))
Figure
Geometry figure for visual-st-makepolygon-03

Outer shell with inner holes variant.

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

Code
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.

Code
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 AS geom
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.

Code
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;