地图技能
利用免费、开放的数据源实现位置智能。包含 8 条命令、44 个 POI 类别、零依赖(仅使用 Python 标准库)、无需 API 密钥。
数据源:OpenStreetMap/Nominatim、Overpass API、OSRM、TimeAPI.io。
此技能取代了旧的 find-nearby 技能—— find-nearby 的所有功能都已由下面的 nearby 命令覆盖,并保留了相同的 --near "<地点>" 快捷方式和多类别支持。
何时使用
- 用户发送 Telegram 位置标记(消息中包含经纬度)→ 使用
nearby - 用户需要地名的坐标 → 使用
search - 用户有坐标,需要地址 → 使用
reverse - 用户询问附近的餐厅、医院、药店、酒店等 → 使用
nearby - 用户需要驾车/步行/骑行的距离或行程时间 → 使用
distance - 用户需要两地之间逐向导航 → 使用
directions - 用户需要某个位置的时区信息 → 使用
timezone - 用户需要在地理区域内搜索 POI → 使用
area+bbox
前提条件
Python 3.8+(仅标准库 — 无需 pip 安装)。
脚本路径:~/.hermes/skills/maps/scripts/maps_client.py
命令
MAPS=~/.hermes/skills/maps/scripts/maps_client.py
search — 地名地理编码
python3 $MAPS search "Eiffel Tower"
python3 $MAPS search "1600 Pennsylvania Ave, Washington DC"
返回:纬度、经度、显示名称、类型、边界框、重要度评分。
reverse — 坐标转地址
python3 $MAPS reverse 48.8584 2.2945
返回:完整地址分解(街道、城市、州、国家、邮政编码)。
nearby — 按类别查找地点
# 根据坐标(例如来自 Telegram 位置标记)
python3 $MAPS nearby 48.8584 2.2945 restaurant --limit 10
python3 $MAPS nearby 40.7128 -74.0060 hospital --radius 2000
# 根据地址 / 城市 / 邮政编码 / 地标 — --near 自动进行地理编码
python3 $MAPS nearby --near "Times Square, New York" --category cafe
python3 $MAPS nearby --near "90210" --category pharmacy
# 将多个类别合并到一个查询中
python3 $MAPS nearby --near "downtown austin" --category restaurant --category bar --limit 10
46 个类别:restaurant、cafe、bar、hospital、pharmacy、hotel、guest_house、camp_site、supermarket、atm、gas_station、parking、museum、park、school、university、bank、police、fire_station、library、airport、train_station、bus_stop、church、mosque、synagogue、dentist、doctor、cinema、theatre、gym、swimming_pool、post_office、convenience_store、bakery、bookshop、laundry、car_wash、car_rental、bicycle_rental、taxi、veterinary、zoo、playground、stadium、nightclub。
每个结果包含:name、address、lat/lon、distance_m、maps_url(可点击的 Google 地图链接)、directions_url(从搜索点出发的 Google 地图导航),以及可用的推广标签——cuisine、hours(营业时间)、phone、website。
distance — 旅行距离与时间
python3 $MAPS distance "Paris" --to "Lyon"
python3 $MAPS distance "New York" --to "Boston" --mode driving
python3 $MAPS distance "Big Ben" --to "Tower Bridge" --mode walking
模式:driving(默认)、walking、cycling。返回道路距离、行程时间和直线距离(供对比)。
directions — 逐向导航
python3 $MAPS directions "Eiffel Tower" --to "Louvre Museum" --mode walking
python3 $MAPS directions "JFK Airport" --to "Times Square" --mode driving
返回带编号的步骤,包含指令、距离、行程时间、道路名称和操作类型(转弯、出发、到达等)。
timezone — 坐标对应的时区
python3 $MAPS timezone 48.8584 2.2945
python3 $MAPS timezone 35.6762 139.6503
返回时区名称、UTC 偏移量和当前本地时间。
area — 地点的边界框和区域
python3 $MAPS area "Manhattan, New York"
python3 $MAPS area "London"
返回边界框坐标、以公里为单位的宽度/高度和近似面积。可用作 bbox 命令的输入。
bbox — 在边界框内搜索
python3 $MAPS bbox 40.75 -74.00 40.77 -73.98 restaurant --limit 20
在地理矩形内查找 POI。先使用 area 获取命名地点的边界框坐标。
使用 Telegram 位置标记
当用户发送位置标记时,消息中包含 latitude: 和 longitude: 字段。提取它们并直接传递给 nearby:
# 用户发送了标记(36.17, -115.14)并询问“找到附近的咖啡馆”
python3 $MAPS nearby 36.17 -115.14 cafe --radius 1500
将结果显示为编号列表,包含名称、距离和 maps_url 字段,以便用户在聊天中点击打开链接。对于“现在营业吗?”的问题,请检查 hours 字段;如果缺失或不明确,请使用 web_search 核实,因为 OSM 的营业时间是社区维护的,并非总是最新。
工作流示例
“寻找罗马斗兽场附近的意大利餐厅”:
nearby --near "Colosseum Rome" --category restaurant --radius 500— 一条命令,自动地理编码
“他们发送的这个位置标记附近有什么?”:
- 从 Telegram 消息中提取经纬度
nearby LAT LON cafe --radius 1500
“如何从酒店步行到会议中心?”:
directions "Hotel Name" --to "Conference Center" --mode walking
“西雅图市中心有哪些餐厅?”:
area "Downtown Seattle"→ 获取边界框bbox S W N E restaurant --limit 30
陷阱
- Nominatim 服务条款:最多每秒 1 个请求(脚本会自动处理)
nearby需要经纬度或--near "<地址>"— 两者必须提供其一- OSRM 路由覆盖范围在欧洲和北美最佳
- Overpass API 在高峰时段可能较慢;脚本会自动在镜像之间回退(overpass-api.de → overpass.kumi.systems)
distance和directions使用--to标志指定目的地(而非位置参数)- 如果仅使用邮政编码在全球范围内产生歧义,请包括国家/州
验证
python3 ~/.hermes/skills/maps/scripts/maps_client.py search "Statue of Liberty"
# 应返回 lat ~40.689, lon ~-74.044
python3 ~/.hermes/skills/maps/scripts/maps_client.py nearby --near "Times Square" --category restaurant --limit 3
# 应返回时代广场附近约 500 米内的餐厅列表