Mencocokkan segmen dengan panjang berbeda

13

Saya mencoba untuk mencocokkan segmen kecil dengan segmen yang lebih besar yang paling mungkin terkait dengan mereka: relatif dekat, bantalan yang sama, dan saling berhadapan.

Berikut adalah contoh khas dari data yang saya miliki:

segmen

Di sini saya harus mencocokkan segmen 652 hingga 198969, sementara 711 dan 707 tidak cocok dengan apa pun.

Saya telah mencari metode yang berbeda, khususnya jarak Hausdorff (berdasarkan jawaban di sini ). Saya menghitungnya menggunakan PostGIS tapi saya mendapatkan hasil yang aneh: jarak terpendek yang saya dapatkan adalah antara 707 dan 198985, dan 652 memiliki jarak yang lebih besar ke 198969 daripada 198985 misalnya (saya dapat menambahkan kueri dan hasil jika diperlukan).

Apakah Hausdorff sebenarnya metode yang tepat untuk menyelesaikan ini? Apakah ada pendekatan lain? Saya berpikir untuk membuat satu set pemeriksaan pada parameter yang saya sebutkan (jarak, bantalan, dll.) Tetapi saya takut harus menambahkan sejumlah kondisi untuk menangani kasus tepi atau hal-hal seperti ambang batas pada seberapa banyak mereka saling berhadapan.

Pembaruan: Saya menemukan metode yang sepertinya kompromi yang dapat diterima:

  • Saya pertama kali menemukan 10 segmen hitam terdekat dari yang biru yang saya coba padankan (menggunakan <->operator PostGIS ) yang berjarak kurang dari 10 meter.
  • Saya kemudian membuat segmen baru dengan menemukan titik terdekat ke ujung segmen biru pada masing-masing yang hitam (menggunakan ST_ClosestPoint) dan menyaring hasil yang panjangnya kurang dari 90% dari yang biru (artinya segmen tidak menghadap, atau bahwa perbedaan bantalan lebih dari ~ 20 °)
  • Lalu saya mendapatkan hasil pertama yang diurutkan berdasarkan jarak dan jarak Hausdorff, jika ada.

Mungkin ada beberapa penyesuaian yang harus dilakukan tetapi tampaknya melakukan pekerjaan yang dapat diterima untuk saat ini. Masih mencari metode lain atau pemeriksaan tambahan untuk dijalankan jika saya melewatkan beberapa kasus tepi.

Jukurrpa
sumber
1
Mengapa tidak menggunakan titik akhir segmen (biru) untuk mengidentifikasi kemungkinan kecocokan di antara segmen target (hitam)? Segmen yang cocok yang Anda cari terjadi ketika kedua titik akhir dekat dengan target umum, yang merupakan kueri sederhana untuk dieksekusi. Metode ini menangani perbedaan yang disebabkan oleh kesalahan di lokasi titik akhir segmen, yang sebaliknya mungkin menantang untuk mengatasi: perhatikan bahwa segmen yang sangat pendek (biru) memiliki bantalan yang jauh lebih tepat daripada segmen yang lebih panjang.
whuber
1
Yap saya sebenarnya mencoba sesuatu seperti ini, saya akan memperbarui pertanyaan dengan detail.
Jukurrpa
1
Tidak yakin apakah saya mengerti Anda dengan benar, tetapi apakah Anda mencoba membuat centroid untuk garis biru dan kemudian memeriksa jarak dari mereka ke garis terdekat, sehingga meninggalkan jarak terpendek sebagai hasilnya?
Cyril M
1
Hai Cyril, saya tidak mengerjakan masalah ini lagi, tetapi masalahnya juga untuk mencocokkan segmen biru berdasarkan orientasi mereka, dan seberapa banyak mereka "menghadapi" segmen hitam. Yang berarti dalam kasus ini bahwa 711 tidak boleh cocok dengan apa pun meskipun dia cukup dekat dengan segmen hitam
Jukurrpa

Jawaban:

1

Berikut adalah beberapa fungsi yang saya tulis yang seharusnya membuat Anda melakukan apa yang perlu Anda lakukan. Periksa dan lihat apakah garis tersebut polyline atau segmen jika polyline meledakkan garis, lalu bandingkan azimuth dan kebalikan dari titik pertama dan titik terakhir pada garis, buat Anda kriteria yang dapat diterima untuk kode untuk membuat keputusan untuk Anda. Ini adalah metode yang kasar tetapi dapat dimodifikasi.

kembalikan azimuth dari segmen garis ESRI @shape

def returnAzimuth(shape):
    point1 = shape.firstPoint
    point2 = shape.lastPoint
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az
    return az

mengembalikan kebalikan dari poin ESRI

def returnInverse(point1,point2):
    dX = point2.X-point1.X
    dY = point2.Y-point1.Y
    dis = sqrt(dX**2+dY**2)
    az = math.atan2(dX,dY)*180/math.pi
    if az<0:
        az = az+360
        return az,dis
    return az,dis

meledak polyline menjadi segmen garis

def explodePolyline(shape):
    sr = "insert your spatial reference"
    lines=[]
    pnts = shape.getPart(0)
    for x in range(len(pnts)-1):
        array = arcpy.Array()
        point1 = arcpy.Point(pnts.getObject(x).X,pnts.getObject(x).Y,pnts.getObject(x).Z)
        point2 = arcpy.Point(pnts.getObject(x+1).X,pnts.getObject(x+1).Y,pnts.getObject(x+1).Z)
        array.add(point1)
        array.add(point2)
        line = arcpy.Polyline(array,sr,True,True)
        print(line)
        lines.append(line)
    return lines

jalankan melalui meja Anda seperti ini

for shape in Table:
    for shape2 in Table:
         check if shape is polyline:
            if yes, explode and compare returned line segments with shape2
                for seg in returnedlinesegments
                    if seg.firstpoint=shape2.lastpoint and shape.az=shape2.az
                        do stuff.....
            if no, compare shape and shape2
                if shape.firstpoint=shape2.lastpoint and shape.az=shape2.az
                   do stuff.....

properti ini harus tersedia di postgis - firstpoint, lastpoint, pointarray Saya menganggap properti esri di atas karena itulah yang saya tahu terbaik tetapi di atas dapat dengan mudah diubah untuk bekerja dengan postgis.

Gary Lester
sumber