【问题标题】:Overpass / Overpy: Getting Ways from NodesOverpass / Overpy:从节点获取方法
【发布时间】:2018-05-21 08:56:43
【问题描述】:

我正在努力摸索 Overpass 以及我想要的,所以我希望有人可以提供帮助。

我有一条从 GPX 文件导入的路线。这已“捕捉”到 OSM 数据,所以我有路线上每个点的纬度/经度。其中每一个都与一个 OSM 节点重合,但我没有 OSM 节点 ID。

我还想找出这些点中的哪一个是我所说的“交叉点”,即路线从一个 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>

第二个&lt;union&gt; 子句为我提供了节点的方式。到目前为止,一切顺利。

然后我的计划是创建一个 Python 字典,其中包含节点 ID 作为其键,以及一组方式 ID 作为值:

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

【问题讨论】:

标签: python openstreetmap overpass-api


【解决方案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'}}

因此,我可以使用例如访问原始节点 ID 列表。 result.get_way(4755884)._node_ids.

【讨论】:

  • 感谢您发布您自己找到的答案;这对其他人有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多