Analisis tepi poligon PostGIS (orientasi, panjang tepi)

9

Saya agak baru di dunia GIS dan terutama PostGIS, jadi tolong permisi jika jawabannya tampak jelas ...

Saya ingin melakukan analisis pada sejumlah bangunan. Satu hal yang saya tertarik adalah permukaan fasad mereka bersama dengan orientasi masing-masing. Seperti yang diilustrasikan dalam gambar di bawah ini, saya ingin memiliki panjang dan orientasi (normal) semua tepi dalam serangkaian poligon. Dalam contoh saya hanya menyoroti satu permukaan.

masukkan deskripsi gambar di sini

Tabel hasil dapat terlihat seperti ini:

building_id | edge_id | orientation | edge_length
-------------------------------------------------
      1     |    1    |     315     |    10.0
      1     |    2    |      45     |     7.0
      1     |   ...   |     ...     |     ...

Namun, saya tidak yakin apakah ini cara yang cerdas untuk menyimpan hasil untuk diproses lebih lanjut (mis. Menghitung jarak dari tepi ke gedung berikutnya, dll.). Jadi pertanyaan saya ada dua:

  1. Apakah ada fungsi PostGIS yang efisien yang dapat menganalisis tepi poligon? Dalam hal tidak ada fungsi PostGIS asli saya atau akan tertarik pada pendekatan berbasis Python.
  2. Apa yang akan menjadi cara cerdas untuk menyimpan hasilnya dalam tabel PostGIS, karena poligon mungkin memiliki jumlah sisi yang berbeda?
n1000
sumber
2
Pertama-tama buat segmen poligon: stackoverflow.com/questions/7595635/... Kemudian titik awal dan titik akhir koordinat harus menuju ke kolom seperti x1, y1 dan x2, y2 dan dari ST_Azimuth (ST_Startpoint (geometri), ST_Endpoint (geometri)) . ( postgis.org/docs/ST_Azimuth.html )
Tamas Kosa
1
@TamasKosa: Anda memiliki esensi dari jawaban yang bagus. Mengapa tidak mengembangkannya menjadi satu? Juga, untuk normals, azimuth perlu +/- pi / 2.
Martin F
1
@TamasKosa Ini adalah pendekatan yang saya juga pikirkan. Gunakan ST_ExteriorRing dan kemudian dapatkan azimuth seperti yang Anda katakan. Bagaimana saya bisa menyimpan hasilnya secara ideal, karena bangunan dapat memiliki jumlah tepi yang berbeda? Dalam tabel seperti yang saya jelaskan di atas? Saya setuju dengan MartinF, ini hampir merupakan jawaban;)
n1000
Hanya ingin tahu, mengapa Anda ingin normals ... paparan sinar matahari?
Martin F
1
Bagian pertama dari pertanyaan Anda telah dijawab - Anda dapat menggunakan ST_Dumppoints dan ST_Azimuth. Untuk bagian kedua, karena tidak ada elemen spasial untuk output, saya akan berpikir tautan ke polygonID dan edge_id seperti yang Anda temukan.
John Powell

Jawaban:

10

Kemarin saya tidak punya waktu untuk membuatnya secara detail ... Lihat solusi saya dalam 4 langkah:

CREATE OR REPLACE VIEW bd_segment AS
SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) AS ep
    FROM
       -- extract the individual linestrings
       (SELECT (ST_Dump(ST_Boundary(the_geom))).geom
       FROM bd) AS linestrings;

CREATE OR REPLACE VIEW bd_segment_geom AS
SELECT sp, ep, st_makeline(sp, ep) 
FROM bd_segment;

CREATE OR REPLACE view bd_segment_id AS 
SELECT bd.gid, row_number() 
    OVER (order by bd.gid), degrees(st_azimuth(ff.sp, ff.ep)-1.57079633) AS az_deg,
    ST_LENGTH(ff.st_makeline) , ff.st_makeline FROM bd_segment_geom ff
JOIN bd ON st_touches(ff.st_makeline, bd.the_geom)
GROUP BY bd.gid, ff.sp, ff.ep, ff.st_makeline;

UPDATE bd_segment_id
SET az_deg = az_deg + 360
WHERE az_deg < 0;

Kueri terakhir memberi Anda id bangunan dengan gabungan spasial menggunakan st_touches. Semoga ini bisa membantu. Perbarui - Dalam qgis solusinya terlihat seperti ini: masukkan deskripsi gambar di sini

Tamas Kosa
sumber
1
Impresif! Saya berhasil. Terima kasih banyak! Menjadi sedikit lambat dengan sejumlah besar bangunan. Azimuth bukan normal saat ini. Apakah Anda juga punya ide bagaimana mengatasinya? Saya tidak yakin bagaimana menemukan sisi "eksterior" poligon.
n1000
1
tambahkan 90 derajat ke azimuth di radian seperti ini: degrees (st_azimuth (ff.sp, ff.ep) +1.57079633). Terkadang akan menghasilkan nilai yang lebih besar dari 360. tetapi dengan kueri pembaruan Anda dapat menggantinya. Jika Anda ingin menggunakan tampilan statis buat "CREATE MATERIALIZED VIEW" dan itu tidak akan lambat hanya pada saat pertama.
Tamas Kosa
2
Tidak terlalu. Dengan asumsi Utara adalah 0 °, ini akan memberikan yang normal menuju bagian dalam poligon / bangunan (seperti juga terlihat pada tangkapan layar Anda). Tetapi Anda benar - sederhana UPDATEharus melakukan trik. Sekali lagi terima kasih atas solusi hebat ini. Saya akan menunggu beberapa hari lagi jika jawaban lain muncul, sebelum menerimanya.
n1000
1
Bagaimana dengan ST_ForceRHR? Jawaban ini sebenarnya tampak baik-baik saja.
Jakub Kania
@ JakubKania Saya mencoba mencari ST_ForceRHRsolusi, tetapi tidak berhasil. Akan berterima kasih atas petunjuk ... Saya mencobaST_Dump(ST_Boundary(ST_ForceRHR(the_geom)))
n1000