PostGIS Permintaan Rekursif Berdasarkan Konektivitas Saluran

9

Saya mengalami kesulitan dengan kueri. Saya memiliki jaringan linestrings, masing-masing dengan nilai di kolom n_type. Ini bisa menjadi salah satu dari sedikit opsi. Saya ingin membuat tabel baru yang mengelompokkan setiap linestrings yang memiliki tipe yang sama dan yang membentuk garis kontinu.

Sebelum:

masukkan deskripsi gambar di sini

Setelah:

masukkan deskripsi gambar di sini

Inilah yang saya dapatkan sejauh ini. Ini mengembalikan hasil tetapi mereka tidak masuk akal - jenis tidak cocok dan mengembalikan terlalu banyak fitur.

Harap perhatikan juga bahwa saya mendefinisikan "kontinu" sebagai garis apa pun dalam jarak 5 kaki dari tetangganya dan bertemu dengan sudut kurang dari 30 derajat.

WITH RECURSIVE all_links (i, pk_uid, n_type, geom) AS (
    SELECT  1 AS i,
            pk_uid,
            n_type,
            geom
    FROM    network
    WHERE   n_type != 'none'

    UNION ALL

    SELECT  a.i + 1,
            b.pk_uid,
            b.n_type,
            b.geom
    FROM    network b, all_links a
    WHERE   b.n_type = a.n_type
    AND     b.geom <#> a.geom <= 5  --lines are continuous if within 5 feet of neighbor
    AND     ABS( DEGREES( 3*pi() - st_azimuth(st_startpoint(a.geom),st_endpoint(a.geom)) + st_azimuth(st_startpoint(b.geom),st_endpoint(b.geom)))::int % 360 - 180) <= 30 )  --only take links within 30 degrees of the same angle

SELECT i, n_type, ST_Union(the_geom) FROM all_links GROUP BY i, n_type

Saya berasumsi permintaan rekursif adalah cara untuk pergi, tapi saya senang terbukti salah tentang itu. Recursives agak sulit untuk grok.

Sunting: Saya juga harus menambahkan bahwa saya sudah mencoba menggabungkan menggunakan ST_Union dan ST_Linemerge, dan kemudian membuang hasilnya. Ini agak berhasil, tetapi tidak memperhitungkan persimpangan> 30 derajat dan juga tidak dapat menghormati toleransi lima kaki untuk konektivitas.

spencerrecneps
sumber
Tanpa menggali lebih jauh ke dalam ini, beberapa pengamatan. Anda harus menyatukan a.geom dan b.geom di klausa pilih Anda. Anda mungkin harus memastikan bahwa Anda tidak mencoba dan bergabung dengan garis untuk dirinya sendiri dengana.pk_uid != b.pk_uid
MickyT
@MickyT terima kasih. Saya seharusnya menyebutkan bahwa saya dapat melakukan penyatuan dalam klausa SELECT terakhir tetapi untuk saat ini baru saja dipilih * sehingga saya dapat melihat semua hasil. Saya akan memodifikasi cuplikan kode untuk menunjukkan seperti apa nantinya.
spencerrecneps
Permintaan rekursif sulit untuk grok. Lol dan +1
John Powell
Pandangan cepat menunjukkan Anda mungkin memiliki masalah dengan permintaan dasar / jangkar Anda. Anda harus memilih titik awal untuk setiap baris, A, B, C dll, yang kemudian Anda bangun di bagian rekursif. Mungkin Anda perlu menambahkan semacam pemesanan ke permintaan jangkar (mungkin dalam x atau y, arah - sulit diketahui tanpa melihat data). Saya akan memecah ini dan memastikan bahwa saya mendapatkan poin awal yang masuk akal terlebih dahulu, sebelum melanjutkan dengan bagian rekursif. Saya menggunakan kueri rekursif untuk menemukan coretan dalam deret waktu baru-baru ini, dan begitu saya memiliki titik jangkar diidentifikasi dengan benar, sisanya mudah (ish)
John Powell
@daston. Poin bagus, tetapi Anda dapat melakukan ini dengan kueri rekursif juga, dan belum semua orang menginstalnya.
John Powell

Jawaban:

1

Solusi Anda, setidaknya, melewatkan pemesanan awal komponen saluran seperti yang dikatakan John Barça.

Kueri rekursif sangat, sangat sulit untuk grok, kataku.

Anda harus mencoba meniru perilaku ST_Linemerge di fungsi basis data baru. Saya akan mencoba terlebih dahulu untuk melihat sumber implementasi ST_Linemerge dan mereplikasi, mengubahnya untuk menghasilkan kedutan sudut 30 derajat.

Untuk membuang dari agregasi segmen yang tidak pada sudut <30 derajat, Anda harus membandingkannya DI DALAM loop agregasi.

rpcavaco
sumber