Bagaimana cara mengubah isoline menjadi isopolygons dengan postgis?


9

Saya punya tabel tabel postgis isoline yang didefinisikan seperti ini:

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

Secara visual objek linestring ini terlihat seperti ini:

masukkan deskripsi gambar di sini

Saya tahu luas spasial data saya, jadi saya bisa menambahkan Bbox, jadi LineStrings bisa ditutup.

masukkan deskripsi gambar di sini

Saya ingin membuat tabel isopolygon myisopolygonsdari myisolinestabel, dengan poligon, yang tidak akan tumpang tindih tetapi membuat permukaan yang kontinyu dan memiliki kolom valdengan valisolasi terendah , dari mana poligon dibentuk. Saya mengerti itu dapat dibentuk dari isoline tertutup sendiri (pulau), atau isoline ditutup dengan bbox, dalam hal ini valharus diambil dari isoline tertentu. Secara visual seharusnya terlihat seperti ini:

masukkan deskripsi gambar di sini

Saya pikir saya bisa membuat topologi entah bagaimana dan kemudian mengubah wajah menjadi poligon, tetapi saya tidak mengerti bagaimana melakukannya dengan benar. Bagaimana ini bisa dilakukan?

Pilihan lain adalah menggunakan fungsi perbedaan secara rekursif antara bbox dan setiap poligon yang dibuat, tapi saya kira itu bukan cara yang tepat untuk melakukannya, dan jelas tidak cepat sama sekali.


ST_Split atau ST_BuildArea adalah kandidat yang baik untuk masalah Anda
nickves

Jawaban:


3

Inilah solusi menggunakan ST_Polygonize. Ini menghasilkan poligon untuk setiap batas, dan memberikan ketinggian minimum dan maksimum yang dicakup oleh poligon. Algoritme tidak dapat membedakan antara puncak dan depresi dan akan mengembalikan ketinggian yang sama untuk min dan maks dalam kasus ini.

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;

The WITHklausul dari query "menutup" setiap kontur terbuka dengan unioning mereka dengan tingkat yang sedikit-kontrak dari kontur yang ada. (Luasnya dikontrak untuk mencuci kesalahan pembulatan yang dihasilkan dari penggunaan ST_Extent, yang menghasilkan kotak presisi tunggal, dengan ST_Polygonize, yang membutuhkan input tertutup sempurna dan mengangguk dalam presisi doulbe). Jika kontur Anda sudah ditutup (mis. Anda bekerja dengan sebuah pulau), maka langkah ini dapat dihilangkan.


0

Saya tidak terlalu berpengalaman, tapi saya akan mencoba fungsi geometri ST_MakePolygon (geometri garis luar, geometri [] interiorlinestrings);


Itu tidak benar-benar menjawab pertanyaan sepenuhnya.
John Powell

0

Menggunakan bbox Anda dan mengulangi setiap garis kontur, Anda dapat menggunakan ST_ConcaveHulluntuk mengubah setiap wilayah menjadi poligon.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.