Отримайте всі рядки, які містять крапку


12

Я використовую QGIS і у мене є точка і дорожня мережа. Мені потрібно автоматично витягувати назви доріг, які додають конкретну точку. введіть тут опис зображення Аналіз найближчих сусідів та буферних зон не можуть виконати цю роботу, оскільки в багатьох випадках точка ближче, як міряється відстані, до сусідніх доріг, а не до сусідніх. Чи є ідеї, як можна було витягти лише огороджувальні дороги?


6
Можливо, перетворіть огороджуючу ділянку (що складається з серії ліній) у багатокутник з атрибутами того, які дороги складають стіни полігону - тоді ви можете зробити простий вибір, перекривши місце розташування. У цьому прикладі точка "145699" потрапляє в полігон "roada_roadb_roadc_roadd."
Карта Man

Відповіді:


3

Про мої тестові дані:

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

РІШЕННЯ I

Якщо є два припущення:

  1. Дороги будують квартали.

  2. Ви працюєте в метричній системі.

Ідея полягає у збільшенні / зменшенні координат 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.