You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OSMnx提取城市全量人行横道的代码优化问询

问题

需要提取某一城市(如芝加哥)在OSM中所有已标注的人行横道(包括标记和未标记的),但当前使用的代码仅能捕获部分目标,仍有不少已映射的交叉口人行横道未被获取,现寻求代码修改方案。

当前代码
import osmnx as ox

# Set console logging to True
ox.settings.log_console = True

# Set useful tags for walking network
useful_tags = ox.settings.useful_tags_way + [
    'crossing', 'crossing:uncontrolled', 'crossing:zebra', 'crossing:marked',
    'crossing:traffic_signals', 'crossing:school', 'crossing:island',
    'crossing:refuge_island', 'crossing:island:central',
    'crossing:island:central:traffic_signals', 'crossing:island:central:marked',
    'crossing:island:central:zebra', 'crossing:unmarked', 'highway:crossing',
    'pedestrian'
]

ox.config(use_cache=True, log_console=True, useful_tags_way=useful_tags)

# Download the network with specified tags
G = ox.graph_from_place(query='Chicago, Illinois, USA', network_type='walk', simplify=False, retain_all=True)

# Identify and remove non-walk edges
non_walk = []
for u, v, k, d in G.edges(keys=True, data=True):
    is_walk = "walk" in d and d["walk"] == "designated"
    is_crossing = (
        d.get("highway") in ["crossing", "pedestrian"] or
        "crossing" in d or
        "crossing:uncontrolled" in d or
        "crossing:raised" in d or
        "crossing:speed_table" in d or
        "crossing:hump" in d or
        "crossing:zebra" in d or
        "crossing:marked" in d or
        "crossing:traffic_signals" in d or
        "crossing:school" in d or
        "crossing:island" in d or
        "crossing:refuge_island" in d or
        "crossing:island:central" in d or
        "crossing:island:central:traffic_signals" in d or
        "crossing:island:central:marked" in d or
        "crossing:island:central:zebra" in d or
        "crossing:unmarked" in d or
        "highway:crossing" in d or
        "pedestrian" in d
    )

    # Include pedestrian crossings at intersections without traffic signals
    is_intersection = "highway" in d and d["highway"] == "uncontrolled_intersection"
    if is_intersection and not is_crossing:
        is_crossing = True

    # Exclude pedestrian sidewalks
    is_sidewalk = "sidewalk" in d
    if not is_walk and not is_crossing and not is_sidewalk:
        non_walk.append((u, v, k))

G.remove_edges_from(non_walk)
G = ox.utils_graph.remove_isolated_nodes(G)
G = ox.simplify_graph(G)

# Calculate and print total edge length
stats = ox.stats.basic_stats(G)
print("Total Edge Length:", stats["edge_length_total"])

# Plot the graph
ox.plot_graph(G, node_color="w", node_size=15, edge_color="b", edge_linewidth=0.5, figsize=(20, 20))
问题现象

当前代码生成的结果(含GeoPackage文件)遗漏了部分已在OSM中标注的交叉口人行横道:

  • 对比可见,右侧是需要捕获的交叉口人行横道,左侧是遗漏的部分
  • 生成的芝加哥人行横道OSMnx图谱也存在明显遗漏
代码修改方案

1. 调整OSM数据查询方式,直接针对人行横道标签筛选

原代码基于步行网络下载,可能遗漏部分仅标注人行横道属性的道路段。改用ox.geometries_from_place直接获取含人行横道标签的要素,再转换为图结构:

# 替换原graph_from_place部分
tags = {
    'highway': ['crossing', 'pedestrian'],
    'crossing': ['*']  # 匹配所有crossing相关标签
}
# 获取所有符合标签的几何要素
gdf = ox.geometries_from_place('Chicago, Illinois, USA', tags=tags)
# 转换为图结构
G = ox.graph_from_gdfs(gdf[gdf.geometry.type == 'LineString'], gdf[gdf.geometry.type == 'Point'])

2. 优化人行横道判断逻辑,覆盖更多OSM标签规则

OSM中人行横道的标注方式多样,比如部分交叉口的人行横道会标注在道路的crossing属性中,而非单独的highway=crossing。修改判断逻辑:

# 替换原is_crossing判断
def is_valid_crossing(d):
    # 直接标记为人行横道的道路段
    if d.get('highway') in ['crossing', 'pedestrian']:
        return True
    # 道路上标注了人行横道属性
    if 'crossing' in d:
        crossing_val = d['crossing']
        # 匹配所有有效人行横道类型,包括unmarked、marked等
        return crossing_val not in ['no', 'none']
    # 交叉口处的人行横道(部分交叉口会将人行横道关联到节点或道路属性)
    if d.get('highway') in ['uncontrolled_intersection', 'traffic_signals']:
        return True
    # 包含人行横道相关的子标签
    for key in d.keys():
        if key.startswith('crossing:') and d[key] not in ['no', 'none']:
            return True
    return False

3. 避免过早简化图结构导致丢失信息

原代码中ox.simplify_graph会合并相邻节点,可能丢失交叉口处的人行横道细节。建议先完成筛选再按需简化,或关闭自动简化:

# 移除G = ox.simplify_graph(G)这一行,或改为保留更多细节的简化
G = ox.simplify_graph(G, strict=False)

4. 补充标签集合,确保获取所有相关属性

扩展useful_tags,加入更多OSM中与人行横道相关的标签:

useful_tags = ox.settings.useful_tags_way + [
    'crossing', 'crossing:uncontrolled', 'crossing:zebra', 'crossing:marked',
    'crossing:traffic_signals', 'crossing:school', 'crossing:island',
    'crossing:refuge_island', 'crossing:island:central',
    'crossing:island:central:traffic_signals', 'crossing:island:central:marked',
    'crossing:island:central:zebra', 'crossing:unmarked', 'highway:crossing',
    'pedestrian', 'crossing:raised', 'crossing:speed_table', 'crossing:hump',
    'crossing:informal', 'crossing:light_signals', 'crossing:marked:no'
]

完整修改后代码

import osmnx as ox

# 设置控制台日志
ox.settings.log_console = True

# 扩展有用标签集合
useful_tags = ox.settings.useful_tags_way + [
    'crossing', 'crossing:uncontrolled', 'crossing:zebra', 'crossing:marked',
    'crossing:traffic_signals', 'crossing:school', 'crossing:island',
    'crossing:refuge_island', 'crossing:island:central',
    'crossing:island:central:traffic_signals', 'crossing:island:central:marked',
    'crossing:island:central:zebra', 'crossing:unmarked', 'highway:crossing',
    'pedestrian', 'crossing:raised', 'crossing:speed_table', 'crossing:hump',
    'crossing:informal', 'crossing:light_signals'
]

ox.config(use_cache=True, log_console=True, useful_tags_way=useful_tags)

# 直接查询含人行横道标签的要素
tags = {
    'highway': ['crossing', 'pedestrian'],
    'crossing': ['*']
}
gdf = ox.geometries_from_place('Chicago, Illinois, USA', tags=tags)

# 转换为图结构
G = ox.graph_from_gdfs(gdf[gdf.geometry.type == 'LineString'], gdf[gdf.geometry.type == 'Point'], simplify=False)

# 筛选有效人行横道边
non_crossing = []
for u, v, k, d in G.edges(keys=True, data=True):
    def is_valid_crossing(edge_data):
        if edge_data.get('highway') in ['crossing', 'pedestrian']:
            return True
        if 'crossing' in edge_data:
            return edge_data['crossing'] not in ['no', 'none']
        if edge_data.get('highway') in ['uncontrolled_intersection', 'traffic_signals']:
            return True
        for key in edge_data.keys():
            if key.startswith('crossing:') and edge_data[key] not in ['no', 'none']:
                return True
        return False

    if not is_valid_crossing(d):
        non_crossing.append((u, v, k))

G.remove_edges_from(non_crossing)
G = ox.utils_graph.remove_isolated_nodes(G)
# 按需简化,保留更多细节
G = ox.simplify_graph(G, strict=False)

# 统计并输出总长度
stats = ox.stats.basic_stats(G)
print("总边长度:", stats["edge_length_total"])

# 绘制图谱
ox.plot_graph(G, node_color="w", node_size=15, edge_color="b", edge_linewidth=0.5, figsize=(20, 20))

内容的提问来源于stack exchange,提问作者mm13816

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:57:07