เกี่ยวกับข้อมูลทดสอบของฉัน:
- เช่นเดียวกับข้อมูลถนน OSM ทุกรูปทรงเรขาคณิตของถนนเส้นเดียวจะสิ้นสุดที่ทางแยก
- ถนนทุกสายมี ID เฉพาะ
โซลูชั่น I
หากมีข้อสมมติฐานสองข้อ:
ถนนกำลังสร้างอาคาร
คุณกำลังทำงานในระบบเมตริก
แนวคิดคือการเพิ่ม / ลดพิกัด 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