城市距离计算Skill city-distance

这个技能用于计算两个城市之间的直线距离和道路距离,基于免费的OpenStreetMap服务和Haversine公式。它适用于交通规划、旅行路线优化、地理数据分析和应用开发。关键词:城市距离、直线距离、道路距离、OpenStreetMap、Haversine公式、地理计算、API集成、交通出行。

交通规划 0 次安装 0 次浏览 更新于 3/22/2026

name: city-distance description: 使用免费的OpenStreetMap服务计算两个城市之间的直线距离和道路距离。

城市距离技能

目的:使用免费的、无需API密钥的公共服务和本地Haversine计算,计算两个城市之间的直线距离和道路距离。

功能:

  • 使用Haversine公式计算直线距离。
  • 使用OpenStreetMap路由端点(routing.openstreetmap.de)计算道路距离,无需API密钥。
  • 可选地通过沿路线采样点并使用Nominatim(免费)进行反向地理编码,列出中间城市。

文件:

  • city_distance_calculator.js — 示例Node.js脚本,展示计算过程。
  • 示例:EXAMPLES.md,包含工作示例(巴黎–柏林,巴黎–迪拜)

使用场景:

  • 快速获取两个城市之间的直线和驾驶距离,无需支付API费用。
  • 生成驾驶路线上的大致定居点列表,用于规划或可视化。

先决条件:

  • Node.js 18+ 用于Node.js示例(原生fetch可用)
  • curl 和 jq 用于Bash示例

代理提示:

使用免费的OpenStreetMap服务计算{cityA}和{cityB}之间的直线(Haversine)距离和驾驶距离。返回距离(以公里为单位),并可选地列出驾驶路线上的主要城镇。

示例

Bash(使用OSM路由,jq):

set -euo pipefail
CITY_A_LAT=48.8566
CITY_A_LON=2.3522
CITY_B_LAT=52.52
CITY_B_LON=13.4050

URL="https://routing.openstreetmap.de/routed-car/route/v1/driving/${CITY_A_LON},${CITY_A_LAT};${CITY_B_LON},${CITY_B_LAT}?overview=false"

curl -fsS --max-time 10 "$URL" | jq -r '.routes[0].distance / 1000'

Node.js(使用原生fetch,AbortController,错误处理):

// city_distance_calculator.js
async function fetchJson(url, timeoutMs = 10000) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeoutMs);
  try {
    const res = await fetch(url, { signal: controller.signal });
    clearTimeout(id);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } catch (err) {
    clearTimeout(id);
    throw err;
  }
}

function haversine(lat1, lon1, lat2, lon2) {
  const R = 6371e3;
  const toRad = d => (d * Math.PI) / 180;
  const φ1 = toRad(lat1), φ2 = toRad(lat2);
  const Δφ = toRad(lat2 - lat1), Δλ = toRad(lon2 - lon1);
  const a = Math.sin(Δφ/2)**2 + Math.cos(φ1)*Math.cos(φ2)*Math.sin(Δλ/2)**2;
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return (R * c) / 1000;
}

(async () => {
  const paris = { lat: 48.8566, lon: 2.3522 };
  const berlin = { lat: 52.52, lon: 13.4050 };
  console.log('Line-of-sight (km):', haversine(paris.lat, paris.lon, berlin.lat, berlin.lon).toFixed(2));

  const url = `https://routing.openstreetmap.de/routed-car/route/v1/driving/${paris.lon},${paris.lat};${berlin.lon},${berlin.lat}?overview=false`;
  const data = await fetchJson(url, 15000);
  console.log('Driving distance (km):', (data.routes[0].distance / 1000).toFixed(2));
})();

注意事项 / 速率限制:

  • routing.openstreetmap.de 和 Nominatim 是公共服务,有使用政策和速率限制。请尊重使用(缓存结果,避免大量自动轮询)。
  • 对于生产级使用,考虑托管自己的OSRM/GraphHopper实例或使用具有SLA的商业API。

另见:

  • SKILL_TEMPLATE.md