Về dữ liệu thử nghiệm của tôi:
- Giống như Dữ liệu Đường OSM, mọi hình dạng đường đơn đều kết thúc ở ngã tư.
- Mỗi con đường có một ID duy nhất.
GIẢI PHÁP I
Nếu có hai giả định:
Đường đang xây dựng khu phố.
Bạn đang làm việc trong một hệ thống số liệu.
Ý tưởng là tăng / giảm tọa độ X và Y của điểm. Nếu bạn làm việc trong một hệ thống số liệu, bạn có thể đi 1m về phía Đông điểm của bạn, tạo một điểm mới và tạo một đường thẳng với điểm ban đầu. Bạn đang đi xa hơn về phía Đông cho đến khi đường cắt ngang một con đường. Để tìm một giao lộ ở phía Tây, bạn đã trừ đi 1m so với tọa độ X ban đầu. Tương tự cho tọa độ Y. Nếu không có đường ở phía Bắc / Đông / Nam / Tây thì quầy dừng ở 1000 (m). Khi bạn biết có thể có một con đường trong khoảng cách hơn 1000m, bạn phải thay đổi giá trị này.
Bạn có thể giải quyết tác vụ với đoạn mã sau:
Đã chỉnh sửa
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)
Một ví dụ khác cho thấy đường e ở phía Đông không được công nhận là đường gần đó.
Cách gọi hàm và đầu ra:
>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d
Nếu có nhiều hơn 4 đường bao quanh điểm bạn phải nhìn theo nhiều hướng hơn (thay đổi cả X và Y). Hoặc bạn có thể thay đổi góc phương vị của dòng của mình, nghĩa là bạn có thể xoay nó một độ trong phạm vi 0-360 °.
GIẢI PHÁP II
Lấy cảm hứng từ các bình luận bạn cũng có thể Polygonize
đường của bạn đầu tiên. Do đó, bạn có thể sử dụng một công cụ từ QGIS : Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize
. Đổi tên lớp tạm thời thành polygon
. Giả sử rằng bạn chỉ muốn có tên đường cho điểm được bao quanh hoàn toàn bởi đường. Nếu không, bạn phải sử dụng giải pháp tôi . Điều này chỉ hoạt động nếu tất cả các con đường được kết nối (chụp)!
Đầu tiên điểm phải giao với đa giác. Ý tưởng bây giờ là cả hai, điểm bắt đầu AND
của một đường bao quanh phải giao nhau với đa giác.
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']
Đầu ra:
road c
road b
road e
road f