如何用Overpass通过关系ID为OSM对象匹配指定区域?
问题:用Overpass查询指定OSM对象并匹配指定关系区域
我想在单个Overpass查询中获取约10个指定的OSM对象,同时将它们匹配到手动挑选的约20个区域,最终输出每个对象的Node/Way标签、中心点以及所属区域。
之前我通过wikidata标签实现了类似功能,查询代码如下:
[out:json][timeout:10]; ( node(id:3959878839);way(id:162817836); ); foreach->.d( (.d;.d >;)->.d; .d out center; .d is_in; area._[wikidata~"(Q14201325|Q16895860)"]; out; ); >;;
但后续发现部分所需区域无法通过wikidata标签识别,因此打算改用关系ID(区域ID规则为关系ID加3600000000)。我尝试了以下查询,但无法输出区域信息,也不知道如何添加多个区域ID:
[out:json][timeout:10]; ( node(id:3959878839);way(id:162817836); ); foreach->.d( (.d;.d >;)->.d; .d out center; .d is_in; area._area(3611589457); out; ); >;;
修正方案
错误原因
你使用的area._area(3611589457)语法错误,Overpass中没有这种写法,需要通过属性匹配或提前加载区域来筛选目标范围。
方案1:在区域结果中筛选指定ID
适合少量区域的场景,直接在is_in的结果里匹配目标area ID:
[out:json][timeout:10]; // 定义要查询的OSM对象集合 ( node(id:3959878839); way(id:162817836); // 可继续添加更多node/way ID ); foreach->.d( // 获取对象及其依赖节点,确保中心点计算准确 (.d;.d >;)->.d; // 输出对象的标签和中心点坐标 .d out center; // 查询对象所属的所有层级区域 .d is_in; // 筛选目标区域(多个ID用|分隔) area._["id"~"^(3611589457|3611589616)$"]; // 输出匹配到的区域信息 out; ); >;;
方案2:提前加载目标区域(高效版)
适合20个区域的场景,提前加载所有目标区域再进行匹配,性能更优:
[out:json][timeout:10]; // 提前加载所有目标区域,多个ID用逗号分隔 area(id:3611589457,3611589616)->.target_areas; // 定义要查询的OSM对象集合 ( node(id:3959878839); way(id:162817836); // 可继续添加更多node/way ID ); foreach->.d( (.d;.d >;)->.d; .d out center; // 获取对象所属的所有区域 .d is_in->.containers; // 匹配提前加载的目标区域 .target_areas.containers; out; ); >;;
注意事项
- 添加更多区域时,方案1在正则表达式里用
|追加ID,方案2在area(id:...)里用逗号追加ID即可 - 输出结果中,每个OSM对象的信息后会紧跟其所属的目标区域数据,对应你预期的输出格式
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

