获取主要城市所有十字路口列表的最佳来源和方式是什么?
如果不介意一些误报,以下 Overpass API 脚本可以很轻松地从 OpenStreetMap 数据中获取道路交叉口:
(脚本无法检测错误交叉点 - 但只有两条线相交,例如,当一条道路由 OSM 数据中的多个道路对象表示时)
如果脚本离线,请直接在此处查看更具可读性的版本:
示例脚本:
<!-- Only select the type of ways you are interested in -->
<query type="way" into="relevant_ways">
<has-kv k="highway"/>
<has-kv k="highway" modv="not" regv="footway|cycleway|path|service|track"/>
<bbox-query {{bbox}}/>
</query>
<!-- Now find all intersection nodes for each way independently -->
<foreach from="relevant_ways" into="this_way">
<!-- Get all ways which are linked to this way -->
<recurse from="this_way" type="way-node" into="this_ways_nodes"/>
<recurse from="this_ways_nodes" type="node-way" into="linked_ways"/>
<!-- Again, only select the ways you are interested in, see beginning -->
<query type="way" into="linked_ways">
<item set="linked_ways"/>
<has-kv k="highway"/>
<has-kv k="highway" modv="not" regv="footway|cycleway|path|service|track"/>
</query>
<!-- Get all linked ways without the current way -->
<difference into="linked_ways_only">
<item set="linked_ways"/>
<item set="this_way"/>
</difference>
<recurse from="linked_ways_only" type="way-node" into="linked_ways_only_nodes"/>
<!-- Return all intersection nodes -->
<query type="node">
<item set="linked_ways_only_nodes"/>
<item set="this_ways_nodes"/>
</query>
<print/>
</foreach>
您可以使用 OpenStreetMap 数据来做到这一点。
下载城市的数据(使用导出链接:http://www.openstreetmap.org/export 或从此处获取数据:http://metro.teczno.com/;还有其他来源,但这里不是列出它们的地方)。
查找“highway”标签具有适当值的所有元素 (http://wiki.openstreetmap.org/wiki/Key:highway)。
对于每种这样的方式,获取组成它的节点 ID。
创建一个数组,其中包含由高速公路信息(名称等)和节点组成的条目,每个节点一个。
根据节点 ID 对数组进行排序。按节点对条目进行分组,以便具有重复节点的一组条目表示交集。
遍历数组,提取其中包含多个条目的每组条目,并将一个新条目添加到交叉点列表中。此时,您可以提取高速公路信息,以便可以通过在那里相遇的高速公路来表征交叉路口。
我知道这是一个简短的总结。但我知道它是有效的,因为它是我在地图渲染库中使用的系统,用于在创建路线数据时识别交叉点。
这是 OpenStreetMap 数据的 OverpassQL 查询,返回的误报较少:
[out:json][timeout:25][bbox:{{bbox}}];
// The public street network
way["highway"~"^(trunk|primary|secondary|tertiary|unclassified|residential)$"]->.streets;
// Get nodes that connect between three or more street segments
node(way_link.streets:3-)->.connections;
// Get intersections between distinct streets
foreach .connections->.connection(
// Get adjacent streets
way(bn.connection);
// If the names don't all match, add the node to the set of intersections
if (u(t["name"]) == "< multiple values found >") {
(.connection; .intersections;)->.intersections;
}
);
.intersections out geom;
这个 GIS Stack Exchange 答案更详细地解释了查询,以及旧版本 Overpass API 的更复杂版本。您还可以在 OSM Wiki 上找到此查询。