Получить все строки, которые заключают точку

12

Я использую QGIS, и у меня есть точка и дорожная сеть. Мне нужно автоматически извлечь названия дорог, которые включают в себя конкретную точку. введите описание изображения здесь Анализ ближайших соседей и буферные зоны не могут выполнять эту работу, потому что во многих случаях точка ближе к измеренным расстояниям, чем соседние дороги, а не окружающие. Есть какие-нибудь идеи о том, как можно извлечь только окружающие дороги?

ML
источник
6
Возможно, преобразуйте ограждающую область (состоящую из серии линий) в многоугольник с атрибутами того, какие дороги образуют стены многоугольника, - тогда вы можете сделать простой выбор, перекрывая местоположение. В этом примере точка «145699» находится в пределах многоугольника «roada_roadb_roadc_roadd».
Карта Man

Ответы:

3

О моих тестовых данных:

  1. Как и OSM Road Data, каждая геометрия дороги заканчивается на перекрестке.
  2. Каждая дорога имеет уникальный идентификатор.

РЕШЕНИЕ I

Если есть два предположения:

  1. Дороги строят кварталы.

  2. Вы работаете в метрической системе.

Идея состоит в том, чтобы увеличить / уменьшить координаты X и Y точки. Если вы работаете в метрической системе, вы можете пройти 1 м к востоку от вашей точки, создать новую точку и создать линию с исходной точкой. Вы идете дальше на восток, пока линия не пересекает дорогу. Чтобы найти перекресток на западе, вы должны вычесть 1 м из исходной координаты X. То же самое для координаты Y. Если на севере / востоке / юге / западе дороги нет, счетчик останавливается на отметке 1000 (м). Если вы знаете, что на расстоянии более 1000 м может быть дорога, вы должны изменить это значение.

Вы можете решить задачу с помощью следующего кода:

Edited

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
Стефан
источник