以前,我问过问题“How can I find a list of street intersections from OpenStreetMap data?”。我修复了上一篇文章中的代码,该代码根据对上一个问题的响应,查找由两个或多个<way>
共享的节点。它(几乎)现在工作,我可以收集街道交叉口的坐标。 (仅使用具有标记属性“primary”,“secondary”,“residential”或“tertiary”的<way>
来查找多个<way>
共享的节点解决了问题。过滤掉其他<way>
,例如标记属性为“building”的那些def get_intersections(self, osm, input_type='file'):
"""
This method reads the passed osm file (xml) and finds intersections (nodes that are shared by two or more roads)
:param osm: An osm file or a string from get_osm()
"""
intersection_coordinates = []
if input_type == 'file':
tree = ET.parse(osm)
root = tree.getroot()
children = root.getchildren()
elif input_type == 'str':
tree = ET.fromstring(osm)
children = tree.getchildren()
counter = {}
for child in children:
if child.tag == 'way':
# Check if the way represents a "highway (road)"
# If the way that we are focusing right now is not a road,
# continue without checking any nodes
road = False
road_types = ('primary', 'secondary', 'residential', 'tertiary', 'service')
for item in child:
if item.tag == 'tag' and item.attrib['k'] == 'highway' and item.attrib['v'] in road_types:
road = True
if not road:
continue
for item in child:
if item.tag == 'nd':
nd_ref = item.attrib['ref']
if not nd_ref in counter:
counter[nd_ref] = 0
counter[nd_ref] += 1
# Find nodes that are shared with more than one way, which
# might correspond to intersections
intersections = filter(lambda x: counter[x] > 1, counter)
# Extract intersection coordinates
# You can plot the result using this url.
# http://www.darrinward.com/lat-long/
for child in children:
if child.tag == 'node' and child.attrib['id'] in intersections:
coordinate = child.attrib['lat'] + ',' + child.attrib['lon']
intersection_coordinates.append(coordinate)
return intersection_coordinates
我现在面临的问题是我收集的交叉点坐标并不详尽,我不知道这是由于OpenStreetMap数据的限制还是我的代码仍然搞砸了。请参阅下图。
Google地图上的图钉表示从OpenStreeMap收集的交叉口的纬度/经度坐标。虽然放置的引脚正确定位在交叉点上,但我使用的技术未能找到一些交叉点,例如同一图中红色箭头指向的交叉点。
我用来获取这些坐标的osm文件(xml文件)是:https://dl.dropboxusercontent.com/u/1047998/WashingtonDC.osm (此文件位于我的保管箱的公共文件夹中。抱歉,如果它不可用。)
我用来刮取数据的代码如下:
{{1}}
我感谢任何评论,建议和解决方案。如果您可以建议我采用任何其他方法来收集交叉点坐标,那也很棒。