OSMNX中custom_filter与df.apply筛选自行车道结果差异问题
问题:OSMnx custom_filter筛选自行车道结果异常
我在统计德国卡尔斯鲁厄市的自行车道总长度时,发现两种方法结果差异极大:
- 方法一用
custom_filter='["highway"~"cycleway"]'筛选,得到约23公里 - 方法二先获取全部自行车网络,再筛选
highway字段包含"cycleway"的条目,得到约109公里
手动核对后发现:方法一仅统计了带多个标签(如['cycleway', 'service'])的路段,漏掉了仅标记为"cycleway"的路段;方法二则两种都统计到了。想知道方法一中custom_filter的使用错误在哪里。
两种方法代码
方法一
city = "Karlsruhe, Germany" graph = ox.graph_from_place(city, network_type="bike", custom_filter='["highway"~"cycleway"]') cycleways = ox.graph_to_gdfs(graph, nodes=False, edges=True) length = cycleways["length"].sum()/1000 print(length)
方法二
city = "Karlsruhe, Germany" graph = ox.graph_from_place(city, network_type="bike") cycleways = ox.graph_to_gdfs(graph, nodes=False, edges=True) contains_cycleway = cycleways["highway"].apply(lambda value: "cycleway" in str(value)) cycleways = cycleways[contains_cycleway] length = cycleways["length"].sum()/1000 print(length)
原因与修正方案
核心错误
custom_filter会覆盖network_type的默认规则:当你同时指定network_type="bike"和custom_filter时,OSMnx会忽略自行车网络的默认过滤条件(比如排除bicycle=no的道路),仅用你写的custom_filter筛选。而方法二中,network_type="bike"会自动过滤掉不允许自行车通行的道路,之后你再筛选highway包含cycleway的条目,范围更准确。- 你的
custom_filter缺少通行权限过滤:仅用["highway"~"cycleway"]会获取所有highway标签含cycleway的道路,但其中可能包含bicycle=no的路段,而方法二中的network_type="bike"已经排除了这些。你手动核对发现方法一没统计仅标记为cycleway的路段,大概率是因为这类路段都符合自行车通行规则,但你的custom_filter没结合network_type的默认过滤,导致Overpass返回的结果不全。
修正后的custom_filter写法
如果你想通过custom_filter实现和方法二完全一致的效果,需要把自行车网络的默认过滤条件和自定义筛选结合起来:
写法一:严格匹配方法二的逻辑
city = "Karlsruhe, Germany" # 结合自行车网络默认过滤规则 + 仅保留highway含cycleway的道路 custom_filter = '["highway"~"cycleway|path|track|footway|bridleway|steps|pedestrian|living_street|service|unclassified|residential|tertiary|secondary|primary|trunk"]["bicycle"!~"no"]["highway"~"cycleway"]' graph = ox.graph_from_place(city, custom_filter=custom_filter) cycleways = ox.graph_to_gdfs(graph, nodes=False, edges=True) length = cycleways["length"].sum()/1000 print(length)
写法二:更简洁的目标匹配
如果你只需要highway含cycleway且允许自行车通行的道路,直接写:
custom_filter = '["highway"~"cycleway"]["bicycle"!~"no"]'
这样就能同时匹配:
- 仅标记为
"cycleway"的单一标签道路 - 含
"cycleway"的多标签道路(如['cycleway', 'service']) - 自动排除
bicycle=no的无效路段
关键注意点
- Overpass QL语法中:
["highway"="cycleway"]:仅匹配highway值完全等于cycleway的道路(包括单一标签和仅含cycleway的多标签数组)["highway"~"cycleway"]:匹配highway值(或多标签数组中的元素)包含cycleway的道路(比如cycleway_link也会被匹配,若不需要可调整正则为["highway"~"^cycleway$"])
- 只要指定
custom_filter,network_type的默认规则就会失效,需要手动添加必要的过滤条件(如["bicycle"!~"no"])。
内容的提问来源于stack exchange,提问作者FesterShinetop
相关产品推荐
相关产品推荐

