Install
openclaw skills install @ruiduobao/geoskill-geocoding-skillPerform forward and reverse geocoding using Nominatim and Open-Meteo APIs, supporting single and batch requests with CSV input and output.
openclaw skills install @ruiduobao/geoskill-geocoding-skillForward and reverse geocoding tool using Nominatim (OpenStreetMap) and Open-Meteo Geocoding API. Supports single and batch geocoding with rate limiting.
# Forward geocode
python scripts\geocoding-skill.py geocode --address "Beijing, China"
# Reverse geocode
python scripts\geocoding-skill.py reverse --lat 39.9042 --lon 116.4074
# Batch geocode from CSV
python scripts\geocoding-skill.py batch --input addresses.csv --address_col "address"
# Use Open-Meteo (faster, good for cities)
python scripts\geocoding-skill.py geocode --address "Tokyo" --provider open-meteo
| Parameter | Description | Default |
|---|---|---|
--address | Address to geocode | Required (geocode) |
--lat | Latitude (-90 to 90) | Required (reverse) |
--lon | Longitude (-180 to 180) | Required (reverse) |
--input | Input CSV file path | Required (batch) |
--address-col | Column name with addresses | Required (batch) |
--provider | Provider: nominatim or open-meteo | nominatim |
--output | Output file path | Auto-generated |
pip install requests>=2.28.0 tqdm numpy scipy
# Or: pip install -r scripts/requirements.txt
| Package | Purpose |
|---|---|
requests | HTTP requests to geocoding APIs |
tqdm | Progress bars for batch processing |
| Feature | Nominatim | Open-Meteo |
|---|---|---|
| Street address | ✅ | ❌ |
| City name | ✅ | ✅ |
| Country | ✅ | ✅ |
| Rate limit | 1 req/sec | None |
| Reverse geocoding | ✅ | ❌ (fallback to Nominatim) |
id,address
1,北京市天安门
2,上海市外滩
3,广州市天河区
For reverse geocoding batch:
id,lat,lon
1,39.9042,116.4074
2,31.2304,121.4737
| Column | Description |
|---|---|
id | Input row identifier |
address | Matched address (forward) |
lat | Latitude |
lon | Longitude |
display_name | Full display name |
confidence | Match confidence (0-1) |
| Error | Cause | Solution |
|---|---|---|
| Address not found | Ambiguous or non-existent address | Return empty result with confidence=0 |
| Network error | Connection failure | Auto-retry up to 3 times |
HTTP 429 | Rate limit exceeded | Wait and retry with backoff |
| CSV encoding error | Non-UTF-8 input | Convert to UTF-8 first |
When multiple matches are found, all candidates are returned with confidence scores. The highest confidence match appears first. Filter by confidence >= 0.5 for reliable results.
python scripts\geocoding-skill.py batch --input addresses.csv --timeout 60
Default timeout is 30 seconds per request. Increase for slow connections.
# Resume from last successful row
python scripts\geocoding-skill.py batch --input addresses.csv --resume --state-file .geocoding_state.json
The state file tracks completed rows, allowing interruption and resumption without reprocessing.
--language parameter to specify preferred language:
python scripts\geocoding-skill.py geocode --address "北京市" --language zh
en, zh, ja, ko, fr, de, etc.# Use a self-hosted Nominatim instance
python scripts\geocoding-skill.py geocode --address "Beijing" --endpoint https://nominatim.example.com/search
Default endpoint: https://nominatim.openstreetmap.org/search
# Prioritize results in China
python scripts\geocoding-skill.py geocode --address "Springfield" --countrycode us
Use --countrycode with ISO 3166-1 alpha-2 codes to bias results toward a specific country.
| Match Type | Typical Accuracy |
|---|---|
| Street address | 5-10 m |
| City name | ~1 km (city center) |
| Country | ~10 km (country centroid) |
| POI | Variable (10-100 m) |
@misc{nominatim,
title={Nominatim - OpenStreetMap reverse geocoding},
author={{OpenStreetMap contributors}},
year={2024},
url={https://nominatim.org/},
note={ODbL}
}
@misc{openmeteo2024geocoding,
title={Open-Meteo Geocoding API},
author={{Open-Meteo}},
year={2024},
url={https://open-meteo.com/en/docs/geocoding-api},
note={CC BY 4.0}
}
import pandas as pd
import folium
df = pd.read_csv("geocoded_results.csv")
m = folium.Map(location=[df["lat"].mean(), df["lon"].mean()], zoom_start=4)
for _, row in df.iterrows():
folium.Marker(
location=[row["lat"], row["lon"]],
popup=row["display_name"],
tooltip=str(row["id"])
).add_to(m)
m.save("geocoded_map.html")
| Error | Cause | Solution |
|---|---|---|
ConnectionError | Network issue | Check internet, retry |
HTTP 429 | Rate limit | Wait 60s, retry |
ValueError | Invalid input | Check parameter format |
| Empty output | No data | Try different parameters |
ModuleNotFoundError | Missing dep | Run pip install |
python scripts\geocoding-skill.py batch --input addresses.csv --output geocoded.json --resume
# .github/workflows/geocode-update.yml
name: Geocode Addresses
on:
push:
paths: ['data/addresses.csv']
jobs:
geocode:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install requests
- run: |
python scripts\geocoding-skill.py batch \
--input data/addresses.csv \
--output data/geocoded.json --resume
python scripts\geocoding-skill.py batch --input addresses.csv --output geocoded.json
# Convert to CSV and import
python -c "
import json, csv
data = json.load(open('geocoded.json'))
with open('geocoded.csv', 'w', newline='') as f:
w = csv.DictWriter(f, fieldnames=['input', 'lat', 'lon', 'display_name'])
w.writeheader()
for r in data:
w.writerow({'input': r['input'], 'lat': r['lat'], 'lon': r['lon'], 'display_name': r['display_name']})
"
psql -d gis_db -c "\COPY geocoded_addresses FROM 'geocoded.csv' CSV HEADER"
--resume to continue interrupted batch jobs--delay 1 to respect Nominatim rate limit (1 req/sec)--endpoint基于 Nominatim(OpenStreetMap)和 Open-Meteo 的正向/反向地理编码工具,支持单条和批量地理编码。
pip install requests>=2.28.0 tqdm numpy scipy
# 或: pip install -r scripts/requirements.txt
| 包 | 用途 |
|---|---|
requests | 地理编码 API 的 HTTP 请求 |
tqdm | 批量处理进度条 |
id,address
1,北京市天安门
2,上海市外滩
3,广州市天河区
反向地理编码批量输入:
id,lat,lon
1,39.9042,116.4074
2,31.2304,121.4737
| 列名 | 说明 |
|---|---|
id | 输入行标识 |
address | 匹配地址(正向) |
lat | 纬度 |
lon | 经度 |
display_name | 完整显示名称 |
confidence | 匹配置信度(0-1) |
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 地址未找到 | 模糊或不存在的地址 | 返回空结果,confidence=0 |
| 网络错误 | 连接失败 | 自动重试最多 3 次 |
HTTP 429 | 超出速率限制 | 等待后重试 |
| CSV 编码错误 | 非 UTF-8 输入 | 先转换为 UTF-8 |
找到多个匹配时,返回所有候选结果及置信度分数。最高置信度匹配排在首位。筛选 confidence >= 0.5 获取可靠结果。
python scripts\geocoding-skill.py batch --input addresses.csv --timeout 60
默认超时 30 秒/请求。网络较慢时增加超时时间。
# 从上次成功行恢复
python scripts\geocoding-skill.py batch --input addresses.csv --resume --state-file .geocoding_state.json
状态文件跟踪已完成行,支持中断后恢复,无需重新处理。
--language 参数指定首选语言:
python scripts\geocoding-skill.py geocode --address "北京市" --language zh
en、zh、ja、ko、fr、de 等# 使用自托管 Nominatim 实例
python scripts\geocoding-skill.py geocode --address "Beijing" --endpoint https://nominatim.example.com/search
默认端点:https://nominatim.openstreetmap.org/search
# 优先返回中国结果
python scripts\geocoding-skill.py geocode --address "Springfield" --countrycode us
使用 ISO 3166-1 alpha-2 代码指定 --countrycode 以偏向特定国家。
| 匹配类型 | 典型精度 |
|---|---|
| 街道地址 | 5-10 米 |
| 城市名 | ~1 公里(城市中心) |
| 国家 | ~10 公里(国家质心) |
| POI | 变化较大(10-100 米) |
@misc{nominatim,
title={Nominatim - OpenStreetMap reverse geocoding},
author={{OpenStreetMap contributors}},
year={2024},
url={https://nominatim.org/},
note={ODbL}
}
@misc{openmeteo2024geocoding,
title={Open-Meteo Geocoding API},
author={{Open-Meteo}},
year={2024},
url={https://open-meteo.com/en/docs/geocoding-api},
note={CC BY 4.0}
}
import pandas as pd
import folium
df = pd.read_csv("geocoded_results.csv")
m = folium.Map(location=[df["lat"].mean(), df["lon"].mean()], zoom_start=4)
for _, row in df.iterrows():
folium.Marker(
location=[row["lat"], row["lon"]],
popup=row["display_name"],
tooltip=str(row["id"])
).add_to(m)
m.save("geocoded_map.html")
| 错误 | 原因 | 解决方案 |
|---|---|---|
ConnectionError | 网络问题 | 检查网络,重试 |
HTTP 429 | 速率限制 | 等待 60 秒后重试 |
ValueError | 无效输入 | 检查参数格式 |
| 空输出 | 无数据 | 尝试不同参数 |
ModuleNotFoundError | 缺少依赖 | 运行 pip install |
基于 Nominatim(OpenStreetMap)和 Open-Meteo 的正向/反向地理编码工具,支持单条和批量地理编码。
# 正向地理编码
python scripts\geocoding-skill.py geocode --address "北京市天安门"
# 反向地理编码
python scripts\geocoding-skill.py reverse --lat 39.9042 --lon 116.4074
# 批量地理编码
python scripts\geocoding-skill.py batch --input addresses.csv --address_col "address"
# 使用 Open-Meteo(更快,适合城市名)
python scripts\geocoding-skill.py geocode --address "Tokyo" --provider open-meteo
| 功能 | Nominatim | Open-Meteo |
|---|---|---|
| 街道地址 | ✅ | ❌ |
| 城市名 | ✅ | ✅ |
| 国家 | ✅ | ✅ |
| 速率限制 | 1 请求/秒 | 无限制 |
| 反向地理编码 | ✅ | ❌(回退到 Nominatim) |