Como transformar isolinhas em isopolígonos com postgis?

9

Eu tenho uma tabela uma tabela postgis de isolines que é definida assim:

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

Visualmente, esses objetos de cadeia de linhas são assim:

insira a descrição da imagem aqui

Conheço a extensão espacial dos meus dados, para adicionar uma Bbox, para que os LineStrings possam ser fechados.

insira a descrição da imagem aqui

Quero criar uma tabela de isopolígonos a myisopolygonspartir da myisolinestabela, com polígonos, que não se sobreponham, mas criem uma superfície contínua e tenham uma coluna valcom o menor número valde isolinhas, a partir da qual o polígono foi formado. Eu entendo que ele pode ser formado a partir de isolina auto-fechada (ilha) ou isolina fechada com bbox, nesse caso, valdeve-se extrair dessa isolina específica. Visualmente, deve ficar assim:

insira a descrição da imagem aqui

Pensei que pudesse criar topologia de alguma forma e depois transformar faces em polígonos, mas não entendo como fazê-lo corretamente. Como isso pode ser feito?

Outra opção seria usar recursivamente uma função de diferença entre bbox e cada polígono criado, mas acho que não é o caminho certo para fazê-lo, e definitivamente não é rápido.

mofoyoda
fonte
ST_Split ou ST_BuildArea são bons candidatos para o seu problema
nickves

Respostas:

3

Aqui está uma solução usando ST_Polygonize. Ele gera um polígono para cada limite e fornece a elevação mínima e máxima cobertas pelo polígono. O algoritmo não pode distinguir entre um pico e uma depressão e retornará a mesma elevação para o mínimo e o máximo nesses casos.

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;

A WITHcláusula da consulta "fecha" todos os contornos abertos, unindo-os à extensão levemente contraída dos contornos existentes. (A extensão é contratada para eliminar os erros de arredondamento resultantes do uso de ST_Extent, que produz uma caixa de precisão única com ST_Polygonize, que requer entradas perfeitamente fechadas e acenadas na precisão de doulbe). Se seus contornos já estiverem fechados (ou seja, você estiver trabalhando com uma ilha), essa etapa poderá ser omitida.

dbaston
fonte
0

Não sou muito experiente, mas tentaria a função geometria ST_MakePolygon (geometry outerlinestring, geometry [] interiorlinestrings);

Simona
fonte
Isso realmente não responde totalmente à pergunta.
John Powell
0

Usando sua bbox e iterando sobre cada linha de contorno, você pode usar ST_ConcaveHullpara converter cada região em um polígono.

Travis Webb
fonte