รับบรรทัดทั้งหมดที่ล้อมรอบจุด


12

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


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

คำตอบ:


3

เกี่ยวกับข้อมูลทดสอบของฉัน:

  1. เช่นเดียวกับข้อมูลถนน OSM ทุกรูปทรงเรขาคณิตของถนนเส้นเดียวจะสิ้นสุดที่ทางแยก
  2. ถนนทุกสายมี ID เฉพาะ

โซลูชั่น I

หากมีข้อสมมติฐานสองข้อ:

  1. ถนนกำลังสร้างอาคาร

  2. คุณกำลังทำงานในระบบเมตริก

แนวคิดคือการเพิ่ม / ลดพิกัด X และ Y ของจุด หากคุณทำงานในระบบเมตริกคุณสามารถไปทางทิศตะวันออกของจุดของคุณได้ 1 เมตรสร้างจุดใหม่และสร้างเส้นที่มีจุดเดิม คุณจะไปทางทิศตะวันออกต่อไปจนกว่าเส้นจะตัดกับถนน ในการมองหาทางแยกในฝั่งตะวันตกคุณต้องลบ 1m จากพิกัด X ดั้งเดิม เช่นเดียวกับพิกัด Y หากไม่มีถนนในภาคเหนือ / ตะวันออก / ใต้ / ตะวันตกเคาน์เตอร์จะหยุดที่ 1,000 (m) เมื่อคุณรู้ว่าอาจมีถนนในระยะทางมากกว่า 1,000 เมตรคุณต้องเปลี่ยนค่านี้

คุณสามารถแก้ปัญหาด้วยรหัสต่อไปนี้:

แก้ไข

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

startpoint_iter = startpoint.getFeatures()
for feature in startpoint_iter:
    geom = feature.geometry()
    if geom.type() == QGis.Point:
        xy = geom.asPoint()
        x,y = xy[0], xy[1]

line_start = QgsPoint(x,y)      

def reached(direction, count_m):
    road_reached = None
    road = None
    count=1
    while road_reached < 1 and count <=count_m:
        count += 1
        if direction == 'N':
            line_end = QgsPoint(x, y+count)
        if direction == 'E':
            line_end = QgsPoint(x+count,y)
        if direction == 'S':
            line_end = QgsPoint(x,y-count)
        if direction == 'W':
            line_end = QgsPoint(x-count,y)
        line = QgsGeometry.fromPolyline([line_start,line_end])
        for f in roads.getFeatures():
            if line.intersects(f.geometry()):
                road_reached = 1
                road = f['name']
                print road

reached('N', 1000)
reached('E', 1000)
reached('S', 1000)
reached('W', 1000)

อีกตัวอย่างหนึ่งที่แสดงว่าถนนอีในตะวันออกไม่ได้รับการยอมรับว่าเป็นถนนใกล้เคียงของจุด

ป้อนคำอธิบายรูปภาพที่นี่

วิธีเรียกใช้ฟังก์ชันและเอาต์พุต:

>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d

หากมีถนนมากกว่า 4 เส้นล้อมรอบจุดที่คุณต้องมองไปในทิศทางอื่น (เปลี่ยนทั้ง X และ Y) หรือคุณสามารถเปลี่ยนราบของเส้นหมายความว่าคุณสามารถหมุนได้หนึ่งองศาภายในช่วง 0-360 °

โซลูชัน II

แรงบันดาลใจจากความคิดเห็นคุณยังสามารถPolygonizeถนนของคุณก่อน ดังนั้นคุณสามารถใช้เครื่องมือจาก QGIS Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonizeนี้: polygonเปลี่ยนชื่อชั้นชั่วคราว สมมติว่าคุณต้องการให้ชื่อถนนเป็นจุดที่ล้อมรอบด้วยถนนเท่านั้น มิฉะนั้นคุณต้องใช้SOLUTION ฉัน ใช้งานได้ก็ต่อเมื่อถนนทุกสายเชื่อมต่อกัน (จัดชิด)!

ป้อนคำอธิบายรูปภาพที่นี่

ก่อนอื่นจุดจะต้องตัดกับรูปหลายเหลี่ยม แนวคิดก็คือตอนนี้ทั้งสองจุดเริ่มต้นANDจุดสิ้นสุดของเส้นล้อมรอบต้องตัดกับรูปหลายเหลี่ยม

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "polygon":
        poly = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

for h in startpoint.getFeatures():
    for g in poly.getFeatures():
        if h.geometry().intersects(g.geometry()):
            poly_geom = g.geometry()
            for f in roads.getFeatures():
                geom = f.geometry().asPolyline()
                start_point = QgsGeometry.fromPoint(QgsPoint(geom[0]))
                end_point = QgsGeometry.fromPoint(QgsPoint(geom[-1]))
                if poly_geom.intersects(start_point) and poly_geom.intersects(end_point):
                    print f['name']

ผลลัพธ์:

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