Comment transformer des isolignes en isopolygones avec des postgis?

9

J'ai une table une table postgis d'isolignes qui est définie comme ceci:

CREATE TABLE myisolines
(
  gid serial NOT NULL,
  isotime timestamp without timezone,
  val numeric(10,4),
  geom geometry(LineString,4326)
);

Visuellement, ces objets linestring ressemblent à ceci:

entrez la description de l'image ici

Je connais l'étendue spatiale de mes données, donc je peux ajouter une Bbox, donc les LineStrings peuvent être en quelque sorte fermées.

entrez la description de l'image ici

Je veux créer une table d'isopolygones à myisopolygonspartir d'une myisolinestable, avec des polygones, qui ne se chevaucheront pas mais créeront une surface continue et auront une colonne valavec le plus bas vald'isolignes, à partir duquel le polygone a été formé. Je comprends qu'il peut être formé à partir d'isoline auto-fermée (îlot), ou d'isoline fermée avec bbox, dans ce cas, le valdoit être pris à partir de cette isoline particulière. Visuellement, cela devrait ressembler à ceci:

entrez la description de l'image ici

J'ai pensé que je pouvais créer la topologie d'une manière ou d'une autre, puis transformer des faces en polygones, mais je ne comprends pas comment le faire correctement. Comment cela peut-il être fait?

Une autre option serait d'utiliser récursivement une fonction de différence entre bbox et chaque polygone créé, mais je suppose que ce n'est pas la bonne façon de le faire, et certainement pas rapide du tout.

mofoyoda
la source
ST_Split ou ST_BuildArea sont de bons candidats pour votre problème
nickves

Réponses:

3

Voici une solution utilisant ST_Polygonize. Il génère un polygone pour chaque frontière et fournit l'élévation min et max couverte par le polygone. L'algorithme ne peut pas distinguer entre un pic et une dépression et retournera la même élévation pour le min et le max dans ces cas.

WITH closed_contours AS (
    SELECT 
      ST_Union(geom) AS geom 
    FROM 
      (SELECT geom FROM contours 
       UNION ALL 
       SELECT ST_SetSRID(ST_Boundary(ST_Expand(ST_Extent(geom), -1e-10)), 4326) 
       FROM contours) 
sq)

SELECT
  poly_id, 
  min(polys.geom) AS geom, 
  min(elevation)  AS min_elev, 
  max(elevation)  AS max_elev
FROM
  (SELECT row_number() OVER () AS poly_id, geom FROM
      (SELECT 
         (ST_Dump(ST_Polygonize(geom))).geom
       FROM closed_contours) dump
  ) polys
INNER JOIN contours ON ST_Intersects(polys.geom, contours.geom)
GROUP BY poly_id;

La WITHclause de la requête "ferme" tous les contours ouverts en les associant à l'étendue légèrement contractée des contours existants. (L'étendue est contractée pour éliminer les erreurs d'arrondi résultant de l'utilisation de ST_Extent, ce qui produit une boîte simple précision, avec ST_Polygonize, ce qui nécessite des entrées parfaitement fermées et inclinées en doulbe-précision). Si vos contours sont déjà fermés (c'est-à-dire que vous travaillez avec une île), cette étape peut être omise.

dbaston
la source
0

Je ne suis pas très expérimenté, mais j'essaierais la fonction géométrie ST_MakePolygon (géométrie ligne extérieure, ligne géométrie [] ligne intérieure);

Simona
la source
Cela ne répond pas vraiment à la question.
John Powell
0

En utilisant votre bbox et en itérant sur chaque ligne de contour, vous pouvez utiliser ST_ConcaveHullpour convertir chaque région en polygone.

Travis Webb
la source