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

如何用OverPass查询语言获取城镇及州/省名称?

获取指定半径内城镇并确保返回州/省名称的解决方案

问题背景

我开发了一个Node.js工具,用来获取用户位置100英里(160934米)范围内的城镇/城市,但返回结果里只有部分地点的wikipedia标签包含州/省信息,无该标签的地点就拿不到对应行政区域信息,加admin_level过滤也没解决问题。

原查询代码:

// Overpass API endpoint
const overpassUrl = 'https://overpass-api.de/api/interpreter';

// Query to retrieve both cities and towns within a radius
const overpassQuery = `
[out:json];
(
  node["place"="town"](around:160934,${userLat},${userLon});
  node["place"="city"](around:160934,${userLat},${userLon});
);
out body;
>;
out skel qt;
`;

原请求处理代码:

// Make the HTTP request to the Overpass API using fetch
fetch(overpassUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({ data: overpassQuery })
})
.then(response => {
  // Error handling here and...
  return response.json();
})
.then(data => {
  data.elements.forEach(node => {
    node.distance = calculateDistance(userLat, userLon, node.lat, node.lon);
  });

  // Process the JSON data
  // Sort the results by distance
  const sortedResults = data.elements.sort((a, b) => a.distance - b.distance);
  console.log(data);
})
.catch(error => console.error('Error:', error));

解决方法

依赖wikipedia标签不可靠,正确的做法是通过Overpass API的反向关联查询,直接获取城镇所属的州/省级行政区域(对应admin_level,不同国家层级有差异,比如美国州是admin_level=4,中国省是admin_level=2)。

1. 修改Overpass查询语句

调整查询,让它同时获取城镇节点和它们所属的行政区域关系:

const overpassQuery = `
[out:json];
// 先获取目标范围内的城镇/城市节点
(
  node["place"="town"](around:160934,${userLat},${userLon});
  node["place"="city"](around:160934,${userLat},${userLon});
);
// 反向获取这些节点所属的行政区域关系(匹配常见的州/省层级)
out body;
>;
relation["admin_level"~"2|4"]["boundary"="administrative"];
out body;
`;

这里admin_level~"2|4"是兼容不同国家的行政层级,你可以根据目标区域调整(比如只查美国就用admin_level="4")。

2. 处理返回结果,匹配城镇对应的州/省

在数据处理阶段,把每个城镇和对应的行政区域关联起来:

fetch(overpassUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({ data: overpassQuery })
})
.then(response => {
  if (!response.ok) throw new Error('Network response was not ok');
  return response.json();
})
.then(data => {
  // 分离城镇节点和行政区域关系
  const towns = data.elements.filter(el => el.type === 'node' && (el.tags.place === 'town' || el.tags.place === 'city'));
  const adminRegions = data.elements.filter(el => el.type === 'relation' && el.tags.boundary === 'administrative');

  // 给每个城镇匹配对应的州/省
  const townsWithRegion = towns.map(town => {
    // 找到包含该城镇节点的行政区域(通过relation的members)
    const region = adminRegions.find(rel => 
      rel.members.some(member => member.type === 'node' && member.ref === town.id)
    );
    return {
      ...town,
      distance: calculateDistance(userLat, userLon, town.lat, town.lon),
      stateProvince: region ? region.tags.name : 'Unknown' // 提取行政区域名称
    };
  });

  // 按距离排序
  const sortedResults = townsWithRegion.sort((a, b) => a.distance - b.distance);
  console.log(sortedResults);
})
.catch(error => console.error('Error:', error));

关键说明

  • admin_level的取值:不同国家的行政层级定义不同,比如:
    • 美国:州是admin_level=4
    • 中国:省是admin_level=2
    • 欧盟部分国家:州/大区是admin_level=4
  • 如果查询范围跨多个国家,可以保留admin_level~"2|4"来覆盖主流情况,后续可以根据地点的国家标签(tags.country)进一步筛选对应层级。

内容的提问来源于stack exchange,提问作者Zlatan Omerović

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:05:04