การจับคู่ส่วนที่มีความยาวต่างกัน


13

ฉันพยายามที่จะจับคู่เซ็กเมนต์ขนาดเล็กกับเซ็กเมนต์ที่ใหญ่กว่าพวกเขาอาจเกี่ยวข้องกับ: ค่อนข้างใกล้เคียงตลับลูกปืนที่คล้ายกันและหันเข้าหากัน

นี่คือตัวอย่างทั่วไปของข้อมูลที่ฉันมี:

กลุ่ม

ที่นี่ฉันต้องจับคู่เซ็กเมนต์ 652 ถึง 198969 ขณะที่มี 711 และ 707 ไม่ตรงกับสิ่งใด

ฉันค้นหาวิธีการต่าง ๆ โดยเฉพาะในระยะทาง Hausdorff (ตามคำตอบที่นี่ ) ฉันคำนวณโดยใช้ PostGIS แต่ฉันได้รับผลลัพธ์แปลก ๆ : ระยะทางที่สั้นที่สุดที่ฉันได้รับคือระหว่าง 707 และ 198985 และ 652 มีระยะทางที่มากขึ้นถึง 198969 เช่นเดียวกับ 198985 (เช่นฉันสามารถเพิ่มคิวรีและผลลัพธ์หากต้องการ)

Hausdorff เป็นวิธีที่ถูกต้องในการแก้ปัญหานี้หรือไม่ มีวิธีอื่นหรือไม่? ฉันคิดว่าเพียงแค่สร้างชุดของการตรวจสอบเกี่ยวกับพารามิเตอร์ที่ฉันกล่าวถึง (ระยะทางแบริ่ง ฯลฯ ) แต่ฉันกลัวที่จะต้องเพิ่มเงื่อนไขทั้งหมดเพื่อจัดการกรณีขอบหรือสิ่งต่าง ๆ เช่น thresholding เกี่ยวกับพวกเขา หันเข้าหากัน

อัปเดต:ฉันพบวิธีการที่ดูเหมือนว่ายอมรับได้:

  • ฉันพบส่วนดำที่ใกล้ที่สุด 10 อันจากสีน้ำเงินที่ฉันพยายามจับคู่ (ใช้ตัว<->ดำเนินการPostGIS ) ซึ่งอยู่ห่างออกไปไม่ถึง 10 เมตร
  • ฉันจะสร้างกลุ่มใหม่โดยการหาจุดที่ใกล้ที่สุดไปยังจุดสิ้นสุดของส่วนสีน้ำเงินในแต่ละส่วนสีดำ (โดยใช้ST_ClosestPoint) และกรองผลลัพธ์ที่มีความยาวน้อยกว่า 90% ของส่วนสีฟ้า (หมายถึงกลุ่มที่ไม่ได้ หันหน้าไปทางหรือว่าแบริ่งที่แตกต่างกันเป็นมากกว่า ~ 20 °)
  • จากนั้นฉันก็จะได้ผลลัพธ์แรกเรียงตามระยะทางและระยะทาง Hausdorff ถ้ามี

อาจมีการปรับแต่งบางอย่าง แต่ดูเหมือนว่าจะทำหน้าที่ได้รับการยอมรับในขณะนี้ ยังคงมองหาวิธีอื่นหรือตรวจสอบเพิ่มเติมเพื่อเรียกใช้หากฉันพลาดกรณีขอบบางอย่าง


1
ทำไมไม่ใช้จุดปลายของส่วน (สีน้ำเงิน) เพื่อระบุการจับคู่ที่เป็นไปได้ในกลุ่มเป้าหมาย (สีดำ) ส่วนที่ตรงกับที่คุณกำลังมองหาเกิดขึ้นเมื่อจุดปลายทั้งสองอยู่ใกล้กับเป้าหมายร่วมกันซึ่งเป็นแบบสอบถามที่ง่ายต่อการดำเนินการ วิธีนี้จัดการกับความคลาดเคลื่อนที่เกิดจากข้อผิดพลาดในตำแหน่งของจุดปลายเซกเมนต์ซึ่งอาจเป็นสิ่งที่ท้าทายในการจัดการ: สังเกตว่าเซ็กเมนต์ที่สั้นมาก (สีน้ำเงิน) มีแบริ่งที่แม่นยำน้อยกว่าเซ็กเมนต์ที่ยาวกว่า
whuber

1
ใช่ฉันลองทำอะไรซักอย่างตามบรรทัดเหล่านี้ฉันจะอัปเดตคำถามพร้อมรายละเอียด
Jukurrpa

1
ไม่แน่ใจว่าฉันเข้าใจคุณถูกต้องหรือไม่ แต่คุณได้ลองสร้างเซนทรอยด์สำหรับเส้นสีน้ำเงินแล้วตรวจสอบระยะทางจากพวกเขาไปยังบรรทัดที่ใกล้ที่สุด
Cyril Mikhalchenko

1
สวัสดีไซริลฉันไม่ได้ทำงานกับปัญหานี้อีกต่อไป แต่ปัญหาก็คือเพื่อให้ตรงกับส่วนสีน้ำเงินตามการวางแนวของพวกเขาและพวกเขาจะ "เผชิญหน้า" เซ็กเมนต์สีดำมากแค่ไหน ซึ่งหมายความว่าในกรณีนี้ที่ 711 ไม่ควรจับคู่กับสิ่งใดแม้ว่าเขาจะค่อนข้างใกล้เคียงกับกลุ่มสีดำ
Jukurrpa

คำตอบ:


1

นี่คือฟังก์ชั่นสองสามอย่างที่ฉันเขียนที่ควรให้คุณทำสิ่งที่คุณต้องทำ ตรวจสอบและดูว่าบรรทัดนั้นเป็นเส้นหลายเส้นหรือส่วนถ้าเส้นแบ่งนั้นเกิดการระเบิดหรือไม่จากนั้นเปรียบเทียบ azimuth และผกผันของจุดแรกและจุดสุดท้ายบนเส้นตั้งเกณฑ์ให้คุณยอมรับสำหรับการตัดสินใจของคุณ นี่เป็นวิธีการ arcpy แต่สามารถแก้ไขได้

ส่งคืน azimuth จากส่วนของเส้น 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

ส่งคืนค่าผกผันจากคะแนน 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

ระเบิดรูปหลายเหลี่ยมเป็นส่วนของเส้น

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

วิ่งผ่านโต๊ะของคุณแบบนี้

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

คุณสมบัติเหล่านี้ควรมีอยู่ใน postgis - Firstpoint, Pointpoint, Pointarray ฉันถือว่าคุณสมบัติของ ESRI ด้านบนเพราะเป็นสิ่งที่ฉันรู้ดีที่สุด แต่สิ่งที่กล่าวมาข้างต้นสามารถเปลี่ยนให้ทำงานกับ Postgis ได้อย่างง่ายดาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.