Про мої тестові дані:
- Як і OSM Road Data, кожна окрема геометрія дороги закінчується на перехресті.
- Кожна дорога має унікальний ідентифікатор.
РІШЕННЯ I
Якщо є два припущення:
Дороги будують квартали.
Ви працюєте в метричній системі.
Ідея полягає у збільшенні / зменшенні координат X і Y точки. Якщо ви працюєте в межах метричної системи, ви можете піти на відстань 1 м на схід від своєї точки, створити нову точку та створити лінію з початковою точкою. Ви їдете далі на Схід, поки лінія не перетинає дорогу. Щоб шукати перехрестя на Заході, ви віднімаєте 1 м від початкової координати X. Те саме для координати Y. Якщо дороги на півночі / сході / півдні / заході немає, лічильник зупиняється на рівні 1000 (м). Коли ви знаєте, що дорога може бути на відстані більше 1000 м, ви повинні змінити це значення.
Ви можете вирішити завдання за допомогою наступного коду:
Відредаговано
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)
Ще один приклад, який показує, що дорога e на Сході не визнається сусідньою дорогою точки.
Як викликати функцію та вихід:
>>>>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
спочатку прокласти свої дороги. Therefor ви можете використовувати інструмент з QGIS: Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize
. Перейменуйте тимчасовий шар у polygon
. Якщо припустити, що ви хочете мати лише назви доріг для точки, яка повністю закрита дорогами. В іншому випадку ви повинні використовувати рішення , яке я . Це працює лише в тому випадку, якщо всі дороги підключені (оснащені)!
Спочатку точка повинна перетинатися з багатокутником. Тепер ідея полягає в тому, що обидва, початкова 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