{"id":"5a57df1f-5771-49f8-b68e-bf3289deb5b7","shortId":"DdyxYu","kind":"skill","title":"city-distance","tagline":"Calculate line-of-sight and road distances between two cities using free OpenStreetMap services.","description":"# City Distance Skill\n\nPurpose: Calculate line-of-sight and road distances between two cities using free, API-keyless public services and local haversine calculations.\n\nWhat it does:\n- Computes line-of-sight distance using the Haversine formula.\n- Uses OpenStreetMap routing endpoint (routing.openstreetmap.de) to compute road distance without an API key.\n- Optionally lists intermediate cities by sampling points along the route and reverse-geocoding with Nominatim (free) to find nearby settlements.\n\nFiles:\n- city_distance_calculator.js — example Node.js script demonstrating the calculations.\n- examples: EXAMPLES.md with worked examples (Paris–Berlin, Paris–Dubai)\n\nWhen to use:\n- Quickly get straight-line and driving distances between two cities without paying for an API.\n- Generate a rough list of settlements along a driving route for planning or visualization.\n\nPrerequisites:\n- Node.js 18+ for the Node.js examples (native fetch available)\n- curl and jq for Bash examples\n\nAgent prompt:\n> Calculate both the straight-line (Haversine) distance and the driving distance between {cityA} and {cityB} using free OpenStreetMap services. Return distances in km and optionally list major towns along the driving route.\n\nExamples\n--------\n\nBash (uses OSM routing, jq):\n\n```bash\nset -euo pipefail\nCITY_A_LAT=48.8566\nCITY_A_LON=2.3522\nCITY_B_LAT=52.52\nCITY_B_LON=13.4050\n\nURL=\"https://routing.openstreetmap.de/routed-car/route/v1/driving/${CITY_A_LON},${CITY_A_LAT};${CITY_B_LON},${CITY_B_LAT}?overview=false\"\n\ncurl -fsS --max-time 10 \"$URL\" | jq -r '.routes[0].distance / 1000'\n```\n\nNode.js (uses native fetch, AbortController, error handling):\n\n```javascript\n// city_distance_calculator.js\nasync function fetchJson(url, timeoutMs = 10000) {\n  const controller = new AbortController();\n  const id = setTimeout(() => controller.abort(), timeoutMs);\n  try {\n    const res = await fetch(url, { signal: controller.signal });\n    clearTimeout(id);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.json();\n  } catch (err) {\n    clearTimeout(id);\n    throw err;\n  }\n}\n\nfunction haversine(lat1, lon1, lat2, lon2) {\n  const R = 6371e3;\n  const toRad = d => (d * Math.PI) / 180;\n  const φ1 = toRad(lat1), φ2 = toRad(lat2);\n  const Δφ = toRad(lat2 - lat1), Δλ = toRad(lon2 - lon1);\n  const a = Math.sin(Δφ/2)**2 + Math.cos(φ1)*Math.cos(φ2)*Math.sin(Δλ/2)**2;\n  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n  return (R * c) / 1000;\n}\n\n(async () => {\n  const paris = { lat: 48.8566, lon: 2.3522 };\n  const berlin = { lat: 52.52, lon: 13.4050 };\n  console.log('Line-of-sight (km):', haversine(paris.lat, paris.lon, berlin.lat, berlin.lon).toFixed(2));\n\n  const url = `https://routing.openstreetmap.de/routed-car/route/v1/driving/${paris.lon},${paris.lat};${berlin.lon},${berlin.lat}?overview=false`;\n  const data = await fetchJson(url, 15000);\n  console.log('Driving distance (km):', (data.routes[0].distance / 1000).toFixed(2));\n})();\n```\n\nNotes / Rate limits:\n- routing.openstreetmap.de and Nominatim are public services and have usage policies and rate limits. Use respectfully (cache results, avoid heavy automated polling).\n- For production-grade use, consider hosting your own OSRM/GraphHopper instance or using a commercial API with SLA.\n\nSee also:\n- SKILL_TEMPLATE.md","tags":["city","distance","open","skills","besoeasy","agent-skills","ai-agents","claude-code","clawdbot","clawdbot-skill","llm-tools","mcp-server"],"capabilities":["skill","source-besoeasy","skill-city-distance","topic-agent-skills","topic-ai-agents","topic-claude-code","topic-clawdbot","topic-clawdbot-skill","topic-llm-tools","topic-mcp-server","topic-openai","topic-openclaw","topic-vibe-coding","topic-vibecoding"],"categories":["open-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/besoeasy/open-skills/city-distance","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add besoeasy/open-skills","source_repo":"https://github.com/besoeasy/open-skills","install_from":"skills.sh"}},"qualityScore":"0.505","qualityRationale":"deterministic score 0.51 from registry signals: · indexed on github topic:agent-skills · 111 github stars · SKILL.md body (3,304 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T12:55:02.949Z","embedding":null,"createdAt":"2026-04-18T22:10:36.539Z","updatedAt":"2026-05-02T12:55:02.949Z","lastSeenAt":"2026-05-02T12:55:02.949Z","tsv":"'/2':335,343 '/routed-car/route/v1/driving/$':222,388 '0':247,406 '1':352 '10':242 '1000':249,357,408 '10000':264 '13.4050':218,370 '15000':400 '18':144 '180':314 '2':336,344,347,383,410 '2.3522':210,364 '48.8566':206,362 '52.52':214,368 '6371e3':308 'abortcontrol':254,268 'agent':158 'along':78,134,189 'also':454 'api':37,69,127,450 'api-keyless':36 'async':259,358 'autom':433 'avail':151 'avoid':431 'await':277,292,397 'b':212,216,230,233 'bash':156,194,199 'berlin':106,366 'berlin.lat':380,392 'berlin.lon':381,391 'c':346,356 'cach':429 'calcul':4,23,44,99,160 'catch':294 'citi':2,14,19,33,74,122,203,207,211,215,223,226,229,232 'city-dist':1 'city_distance_calculator.js':93,258 'citya':173 'cityb':175 'cleartimeout':282,296 'commerci':449 'comput':48,64 'consid':440 'console.log':371,401 'const':265,269,275,306,309,315,322,331,345,359,365,384,395 'control':266 'controller.abort':272 'controller.signal':281 'curl':152,237 'd':311,312 'data':396 'data.routes':405 'demonstr':97 'distanc':3,11,20,30,53,66,119,167,171,181,248,403,407 'drive':118,136,170,191,402 'dubai':108 'endpoint':61 'err':295,299 'error':255,288 'euo':201 'exampl':94,100,104,148,157,193 'examples.md':101 'fals':236,394 'fetch':150,253,278 'fetchjson':261,398 'file':92 'find':89 'formula':57 'free':16,35,87,177 'fss':238 'function':260,300 'generat':128 'geocod':84 'get':113 'grade':438 'handl':256 'haversin':43,56,166,301,377 'heavi':432 'host':441 'http':289 'id':270,283,297 'instanc':445 'intermedi':73 'javascript':257 'jq':154,198,244 'key':70 'keyless':38 'km':183,376,404 'lat':205,213,228,234,361,367 'lat1':302,318,326 'lat2':304,321,325 'limit':413,426 'line':6,25,50,116,165,373 'line-of-sight':5,24,49,372 'list':72,131,186 'local':42 'lon':209,217,225,231,363,369 'lon1':303,330 'lon2':305,329 'major':187 'math.atan2':348 'math.cos':337,339 'math.pi':313 'math.sin':333,341 'math.sqrt':349,351 'max':240 'max-tim':239 'nativ':149,252 'nearbi':90 'new':267,287 'node.js':95,143,147,250 'nominatim':86,416 'note':411 'openstreetmap':17,59,178 'option':71,185 'osm':196 'osrm/graphhopper':444 'overview':235,393 'pari':105,107,360 'paris.lat':378,390 'paris.lon':379,389 'pay':124 'pipefail':202 'plan':139 'point':77 'polici':423 'poll':434 'prerequisit':142 'product':437 'production-grad':436 'prompt':159 'public':39,418 'purpos':22 'quick':112 'r':245,307,355 'rate':412,425 'res':276 'res.json':293 'res.ok':285 'res.status':290 'respect':428 'result':430 'return':180,291,354 'revers':83 'reverse-geocod':82 'road':10,29,65 'rough':130 'rout':60,80,137,192,197,246 'routing.openstreetmap.de':62,221,387,414 'routing.openstreetmap.de/routed-car/route/v1/driving/$':220,386 'sampl':76 'script':96 'see':453 'servic':18,40,179,419 'set':200 'settimeout':271 'settlement':91,133 'sight':8,27,52,375 'signal':280 'skill':21 'skill-city-distance' 'skill_template.md':455 'sla':452 'source-besoeasy' 'straight':115,164 'straight-lin':114,163 'throw':286,298 'time':241 'timeoutm':263,273 'tofix':382,409 'topic-agent-skills' 'topic-ai-agents' 'topic-claude-code' 'topic-clawdbot' 'topic-clawdbot-skill' 'topic-llm-tools' 'topic-mcp-server' 'topic-openai' 'topic-openclaw' 'topic-vibe-coding' 'topic-vibecoding' 'torad':310,317,320,324,328 'town':188 'tri':274 'two':13,32,121 'url':219,243,262,279,385,399 'usag':422 'use':15,34,54,58,111,176,195,251,427,439,447 'visual':141 'without':67,123 'work':103 'δλ':327,342 'δφ':323,334 'φ1':316,338 'φ2':319,340","prices":[{"id":"185f1726-4828-408d-b2e5-cd2d65acd089","listingId":"5a57df1f-5771-49f8-b68e-bf3289deb5b7","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"besoeasy","category":"open-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:10:36.539Z"}],"sources":[{"listingId":"5a57df1f-5771-49f8-b68e-bf3289deb5b7","source":"github","sourceId":"besoeasy/open-skills/city-distance","sourceUrl":"https://github.com/besoeasy/open-skills/tree/main/skills/city-distance","isPrimary":false,"firstSeenAt":"2026-04-18T22:10:36.539Z","lastSeenAt":"2026-05-02T12:55:02.949Z"}],"details":{"listingId":"5a57df1f-5771-49f8-b68e-bf3289deb5b7","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"besoeasy","slug":"city-distance","github":{"repo":"besoeasy/open-skills","stars":111,"topics":["agent-skills","ai","ai-agents","claude-code","clawdbot","clawdbot-skill","llm-tools","mcp-server","openai","openclaw","vibe-coding","vibecoding"],"license":null,"html_url":"https://github.com/besoeasy/open-skills","pushed_at":"2026-03-31T13:05:30Z","description":"Battle-tested skill library for AI agents. Save 98% of API costs with ready-to-use code for crypto, PDFs, search, web scraping & more. No trial-and-error, no expensive APIs.","skill_md_sha":"dd8c03566154c4950dfdc1b3fe12288804a6f696","skill_md_path":"skills/city-distance/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/besoeasy/open-skills/tree/main/skills/city-distance"},"layout":"multi","source":"github","category":"open-skills","frontmatter":{"name":"city-distance","description":"Calculate line-of-sight and road distances between two cities using free OpenStreetMap services."},"skills_sh_url":"https://skills.sh/besoeasy/open-skills/city-distance"},"updatedAt":"2026-05-02T12:55:02.949Z"}}