Farklı uzunluklarda eşleşen segmentler


13

Küçük segmentleri daha büyük olasılıkla ilişkili oldukları daha büyük bir segmentle eşleştirmeye çalışıyorum: nispeten yakın, benzer rulman ve birbirine bakacak.

İşte sahip olduğum verilerin tipik bir örneği:

segmentler

Burada, 711 ve 707'nin hiçbir şeyle eşleşmediği sırada segment 652 ile 198969'u eşleştirmem gerekiyor.

Ben farklı yöntemler, özellikle Hausdorff mesafe ( burada cevaplara dayalı ) aradım . PostGIS kullanarak hesapladım ama garip sonuçlar alıyorum: en kısa mesafe 707 ile 198985 arasında ve 652'nin 198969'a 198985'ten daha büyük bir mesafesi var (gerekirse sorguyu ve sonuçları ekleyebilirim).

Hausdorff aslında bunu çözmek için doğru yöntem midir? Başka yaklaşımlar var mı? Bahsettiğim parametreler (mesafe, yön, vb.) Üzerinde bir dizi kontrol oluşturmayı düşündüm, ancak kenar vakaları veya ne kadar olduklarına dair eşik gibi şeyleri işlemek için bir sürü koşul eklemekten korkuyorum birbirine bakacak şekilde.

Güncelleme: Kabul edilebilir bir uzlaşma gibi görünen bir yöntem buldum:

  • İlk olarak, eşleştirmeye çalıştığım mavi alandan (PostGIS <->operatörünü kullanarak ) 10 metreden daha kısa olan en yakın 10 siyah segmenti buluyorum .
  • Daha sonra siyah olanların her birinde mavi segmentin uçlarına en yakın noktaları bularak yeni bir segment oluşturuyorum (kullanarak ST_ClosestPoint) ve uzunluğu mavi olanın% 90'ından az olan sonuçları filtreliyorum (yani segmentler bakan, veya rulman farkı ~ 20 ° 'den fazla)
  • Sonra ilk sonucu mesafeye ve varsa Hausdorff mesafesine göre sıralıyorum.

Yapılması gereken bazı ince ayarlar olabilir, ancak şimdilik kabul edilebilir bir iş yapıyor gibi görünüyor. Hala bazı kenar durumlarda kaçırdıysanız çalıştırmak için başka yöntemler veya ek kontroller arıyor.


1
Neden sadece (mavi) segmentlerin uç noktalarını hedef (siyah) segmentler arasındaki potansiyel eşleşmeleri belirlemek için kullanmıyorsunuz? Aradığınız segment eşleşmeleri, her iki uç nokta da yürütülmesi basit bir sorgu olan ortak bir hedefe yakın olduğunda gerçekleşir. Bu yöntem, segment uç noktalarının konumlarındaki hatalardan kaynaklanan, aksi takdirde başa çıkmak için zor olabilecek tutarsızlıkları ele alır: çok kısa (mavi) bir segmentin, daha uzun bir segmentten çok daha az hassas rulmana sahip olduğuna dikkat edin.
whuber

1
Evet aslında bu satırlarda bir şeyler deniyorum, soruyu ayrıntılarla güncelleyeceğim.
Jukurrpa

1
Sizi doğru anladığımdan emin değilim, ancak mavi çizgiler için sentroidler oluşturmaya ve sonra onlardan en yakın çizgilere olan mesafeleri kontrol etmeye ve sonuç olarak en kısa mesafeyi bırakmaya çalıştınız mı?
Cyril Mikhalchenko

1
Merhaba Cyril, artık bu sorun üzerinde çalışmıyorum, ancak sorun aynı zamanda mavi segmentleri yönlerine ve siyah segmentlere ne kadar "karşı karşıya kaldıklarına" göre de uydurmaktı. Bu, siyah segmentlere oldukça yakın olmasına rağmen 711'in hiçbir şeyle eşleşmemesi gerektiği anlamına gelir
Jukurrpa

Yanıtlar:


1

Burada, yazmanız gerekenleri yapmanıza izin veren birkaç işlev var. Çoklu çizgi çizgiyi patlatıyorsa çizginin çoklu çizgi mi yoksa segment olup olmadığını kontrol edin ve ardından azimut ile satırlardaki ilk nokta ile son noktanın tersini karşılaştırın, sizin için karar vermek üzere kod için kabul edilebilir kriterleri belirleyin. Bunlar kavisli yöntemlerdir ancak değiştirilebilirler.

ESRI @shape satır segmentinden azimut döndür

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

ESRI noktalarından tersine dönüş

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

çoklu çizgiyi çizgi segmentine patlat

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

masanızı böyle geçirin

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.....

Bu özellikler postgis - firstpoint, lastpoint, pointarray içinde mevcut olmalıdır. Yukarıdaki esri özelliklerini varsayıyorum çünkü en iyi bildiğim şey budur, ancak yukarıdaki postgis ile çalışmak için kolayca değiştirilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.