Overpass / Overpy: получение путей от узлов

Я изо всех сил пытаюсь уложить Overpass так, как мне бы хотелось, поэтому я надеюсь, что кто-то сможет помочь.

У меня есть маршрут, который я импортирую из файла GPX. Это было привязано к данным OSM, поэтому у меня есть широта / долгота каждой точки на маршруте. Каждый из них совпадает с узлом OSM, но у меня нет идентификатора узла OSM.

Я также хочу выяснить, какие из этих точек я называю "пересечениями", т. Е. Где проходит маршрут от одного пути OSM к другому. Чтобы сделать это, я планировал перейти от узлов к дорогам (шоссе) и выяснить, где изменился маршрут, возможно, с некоторыми уточнениями, например, чтобы принять во внимание название пути.

Итак, используя Overpy, я обнаружил, что самый быстрый способ перейти от точек маршрута к узлам OSM - это объединить несколько запросов ограничивающего прямоугольника:

TOL = 0.00001

query = """
<osm-script>
  <union>
"""
for index, row in df_snapped.iterrows():
    query += '    <bbox-query s="{}" w="{}" n="{}" e="{}"/>\n'.format(
         round(row.lat-TOL, 5)
        ,round(row.lon-TOL, 5)
        ,round(row.lat+TOL, 5)
        ,round(row.lon+TOL, 5)
    )

query += """
  </union>
  <union into="_">
    <item from="_" into="_"/>
    <recurse from="_" into="_" type="node-way"/>
  </union>
  <print e="" from="_" geometry="skeleton" ids="yes" limit="" mode="body" n="" order="id" s="" w=""/>
</osm-script>
"""

Это приводит к запросу, подобному следующему:

<osm-script>
  <union>
    <bbox-query s="51.48825" w="-2.62352" n="51.48827" e="-2.6235"/>
    <bbox-query s="51.48801" w="-2.62364" n="51.48803" e="-2.62362"/>
    <bbox-query s="51.4878" w="-2.62373" n="51.48782" e="-2.62371"/>
    <bbox-query s="51.48697" w="-2.62406" n="51.48699" e="-2.62404"/>
    <bbox-query s="51.48682" w="-2.62414" n="51.48684" e="-2.62412"/>
    <bbox-query s="51.4868" w="-2.62416" n="51.48682" e="-2.62414"/>
    <bbox-query s="51.48665" w="-2.62431" n="51.48667" e="-2.62429"/>
    <bbox-query s="51.48654" w="-2.62442" n="51.48656" e="-2.6244"/>
    <bbox-query s="51.48633" w="-2.62463" n="51.48635" e="-2.62461"/>

    ...

  </union>
  <union into="_">
    <item from="_" into="_"/>
    <recurse from="_" into="_" type="node-way"/>
  </union>
  <print e="" from="_" geometry="skeleton" ids="yes" limit="" mode="body" n="" order="id" s="" w=""/>
</osm-script>

Второй <union> предложение дает мне пути от узлов. Все идет нормально.

Тогда я планирую создать словарь Python, содержащий идентификаторы узлов в качестве ключей и наборы идентификаторов пути в качестве значений:

node_ways = {}

for idx, way in enumerate(result.ways):
    nodes = way.get_nodes(resolve_missing=True)
    for node in nodes:
        if node.id in node_ways:
            temp = node_ways[node.id]
            temp.add(way.id)
            node_ways[node.id] = temp
        else:
            node_ways[node.id] = set([way.id])

Это прекрасно работает, но есть две проблемы:

  1. Использование resolve_missing=True На устранение всех недостающих узлов уходит около 3,5 минут, и я бы очень хотел сократить это время. Я пытался удалить resolve_missing=True и положить обработчик исключений вокруг get_nodes, но это приводит к тому, что набор узлов является неполным.
  2. Когда я использую resolve_missing=TrueЯ получаю все узлы на всех путях, которые пересекаются с исходным набором узлов. Это больше узлов, чем мне нужно. Я мог бы уменьшить это в коде, но в идеале я бы предпочел избавиться от необходимости использовать resolve_missing=True как-то.

Итак, мой вопрос: могу ли я либо адаптировать исходный запрос, чтобы получить нужный вывод, либо получить то, что мне нужно, и избежать использования resolve_missing=True каким-то другим способом?

1 ответ

Еще немного рытье нашло мне ответ. Выполнение например

vars(result.get_way(4755884))

дает внутреннюю структуру пути объекта:

{'_attribute_modifiers': {'changeset': int,
  'timestamp': <function overpy.Element.__init__.<locals>.<lambda>>,
  'uid': int,
  'version': int,
  'visible': <function overpy.Element.__init__.<locals>.<lambda>>},
 '_node_ids': [26229733,
  291529159,
  246189513,
  2682629060,
  291529223,
  3723657411,
  3723657424,
  2018716449,
  291530424,
  2018716450,
  291530803,
  26229737,
  1741942073,
  4100724928,
  4100724934],
 '_result': <overpy.Result at 0x221fc5b17f0>,
 'attributes': {},
 'center_lat': None,
 'center_lon': None,
 'id': 4755884,
 'tags': {'bicycle': 'yes',
  'highway': 'residential',
  'maxspeed': '20 mph',
  'name': 'Reedley Road',
  'postal_code': 'BS9',
  'sidewalk': 'both'}}

Поэтому я могу получить доступ к списку необработанных идентификаторов узлов, используя, например, result.get_way(4755884)._node_ids,

Другие вопросы по тегам