Come trasformare isoline in isopoligoni con postgis?


9

Ho una tabella una tabella postgis di isoline che è definita in questo modo:

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

Visivamente questi oggetti linestring assomigliano a questo:

inserisci qui la descrizione dell'immagine

Conosco l'estensione spaziale dei miei dati, quindi posso aggiungere un Bbox, quindi LineStrings può essere chiuso.

inserisci qui la descrizione dell'immagine

Voglio creare una tabella di isopoligoni myisopolygonsda myisolinestabella, con poligoni, che non si sovrappongano ma creano una superficie continua e hanno una colonna valcon il più basso valdi isoline, da cui è stato formato il poligono. Capisco che può essere formato da isoline (isola) auto-chiuso, o isoline chiuso con bbox, in quel caso valdovrebbe essere preso da quel particolare isoline. Visivamente dovrebbe apparire così:

inserisci qui la descrizione dell'immagine

Pensavo di poter creare la topologia in qualche modo e quindi trasformare le facce in poligoni, ma non capisco come farlo correttamente. Come si può fare?

Un'altra opzione sarebbe quella di utilizzare ricorsivamente una funzione di differenza tra bbox e ciascun poligono creato, ma immagino che non sia il modo giusto per farlo, e sicuramente non è affatto veloce.


ST_Split o ST_BuildArea sono buoni candidati per il tuo problema
Nick,

Risposte:


3

Ecco una soluzione usando ST_Polygonize. Genera un poligono per ciascun confine e fornisce l'altezza minima e massima coperta dal poligono. L'algoritmo non è in grado di distinguere tra un picco e una depressione e in questi casi restituirà la stessa elevazione sia per il minimo che per il massimo.

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 WITHclausola della query "chiude" tutti i contorni aperti unendoli con l'estensione leggermente contratta dei contorni esistenti. (L'estensione è contratta per eliminare eventuali errori di arrotondamento risultanti dall'uso di ST_Extent, che produce una scatola a precisione singola, con ST_Polygonize, che richiede input perfettamente chiusi e annuiti in precisione doulbe). Se i contorni sono già chiusi (ad esempio, stai lavorando con un'isola), questo passaggio può essere omesso.


0

Non sono molto esperto, ma proverei la funzione geometria ST_MakePolygon (geometria rivestimento esterno, geometria [] rivestimento interno);


Questo in realtà non risponde completamente alla domanda.
John Powell,

0

Usando bbox e ripetendo ogni linea di contorno, puoi usare ST_ConcaveHullper convertire ogni regione in un poligono.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.