如何编写Overpass查询获取指定邮编内的医院、学校等POI
优化Overpass查询:指定邮编内的POI(医院、学校)
原查询的问题
- 仅查询
node类型元素:很多医院、学校是以way(建筑多边形)或relation(复合设施)形式存在的,原查询会漏掉这些POI。 - bbox+邮编双重过滤冗余且不准确:手动定义的bbox可能无法覆盖邮编的完整区域,部分POI的
postal_code标签可能不在node上,导致过滤失效。 - 查询结构重复:多个相同逻辑的查询块可以合并简化。
优化方案1:基于邮编区域(Area)查询(推荐)
利用OpenStreetMap中邮编对应的Area对象,直接在目标邮编区域内检索所有类型的POI,无需手动设置bbox,准确性更高。
[out:json][timeout:25]; // 获取目标邮编对应的Area area["postal_code"~"^(90005|90006|90008)$"]->.postal_areas; // 在这些区域内查询医院、学校(包含node/way/relation) ( node["amenity"~"^(hospital|school)$"](area.postal_areas); way["amenity"~"^(hospital|school)$"](area.postal_areas); relation["amenity"~"^(hospital|school)$"](area.postal_areas); ); // 输出带中心坐标的结果,同时包含元素的基本信息 out center;
优化方案2:直接过滤邮编标签(兼容无Area的邮编)
如果部分邮编没有对应的Area对象,可以直接通过postal_code标签过滤,同时查询所有元素类型:
[out:json][timeout:25]; ( node["amenity"~"^(hospital|school)$"]["postal_code"~"^(90005|90006|90008)$"]; way["amenity"~"^(hospital|school)$"]["postal_code"~"^(90005|90006|90008)$"]; relation["amenity"~"^(hospital|school)$"]["postal_code"~"^(90005|90006|90008)$"]; ); // 对于way和relation,输出中心坐标 out center;
关键说明
- 使用正则表达式
~"^(xxx|xxx)$"可以一次性匹配多个邮编或POI类型,简化查询结构。 - 加入
timeout:25避免查询超时(默认超时时间较短,复杂查询容易失败)。 out center会自动计算way/relation的中心坐标,方便定位。
内容的提问来源于stack exchange,提问作者Ajay Dev M
相关产品推荐
相关产品推荐

