Jak przekształcić izoliny w izopoligony za pomocą postgis?

9

Mam tabelę tabeli postgis izolinii, która jest zdefiniowana w następujący sposób:

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

Wizualnie te obiekty liniowe wyglądają tak:

wprowadź opis zdjęcia tutaj

Znam zasięg przestrzenny moich danych, więc mogę dodać Bbox, aby LineStrings mogło być jakby zamknięte.

wprowadź opis zdjęcia tutaj

Chcę utworzyć tabelę izopoligonów myisopolygonsz myisolinestabeli z wielobokami, które nie będą się nakładać, ale utworzą ciągłą powierzchnię i będą miały kolumnę valz najniższą valz izolinii, z której powstał wielokąt. Rozumiem, że można go wytworzyć z samozamykającej izoliny (wyspy) lub izoliny zamkniętej za pomocą bbox, w takim przypadku valnależy ją pobrać z tej konkretnej izolat. Wizualnie powinno to wyglądać tak:

wprowadź opis zdjęcia tutaj

Myślałem, że mogę jakoś stworzyć topologię, a następnie przekształcić twarze w wielokąty, ale nie rozumiem, jak to zrobić poprawnie. Jak można to zrobić?

Inną opcją byłoby rekurencyjne użycie funkcji różnicy między bbox a każdym utworzonym wielokątem, ale myślę, że nie jest to właściwy sposób na zrobienie tego i zdecydowanie nie jest szybki.

mofoyoda
źródło
ST_Split lub ST_BuildArea są dobrymi kandydatami do rozwiązania twojego problemu
nickves 26.04.16

Odpowiedzi:

3

Oto rozwiązanie za pomocą ST_Polygonize. Generuje wielobok dla każdej granicy i zapewnia min. I maks. Rzędną pokrywaną przez wielobok. Algorytm nie może rozróżnić piku i depresji i w tych przypadkach zwróci tę samą wysokość dla wartości minimalnej i maksymalnej.

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;

WITHKlauzula kwerendy „zamyka” otwarte kontury przez unioning im lekko zamówienia stopniu istniejących konturów. (Zakontraktowano zakres, aby zmyć wszelkie błędy zaokrągleń wynikające z użycia ST_Extent, który tworzy pudełko o pojedynczej precyzji, z ST_Polygonize, który wymaga idealnie zamkniętych i ukośnych danych wejściowych z dokładnością doulbe). Jeśli twoje kontury są już zamknięte (tzn. Pracujesz z wyspą), ten krok można pominąć.

dbaston
źródło
0

Nie jestem bardzo doświadczony, ale spróbowałbym funkcji geometrii ST_MakePolygon (geometria zewnętrzna linia, geometria [] wewnętrzna linia);

Simona
źródło
To tak naprawdę nie odpowiada w pełni na pytanie.
John Powell,
0

Za pomocą bbox i iteracji po każdej linii konturu możesz użyć ST_ConcaveHulldo przekształcenia każdego regionu w wielokąt.

Travis Webb
źródło