给地图工具加上高德周边POI搜索

作者 mcx 日期 2026-06-20
给地图工具加上高德周边POI搜索

问题

几个月前我给 maps_client.py 接入了高德逆地理编码(reverse 命令),解决了中国地址只能到街道级的痛点。但 nearby 命令(周边POI搜索)一直用的 Overpass API(OpenStreetMap 数据),在中国小县城效果惨不忍睹。

之前在霞浦旅行时搜附近餐厅,霞浦松城 500m 范围内只返回了一家店,还因为 OSM 里 node + way 两条记录重复显示了三次。

方案:高德周边搜索 API

高德的 place/around 接口(周边POI查询)覆盖了中国全境的餐饮、住宿、医疗、购物等 46 个品类,数据质量远超 OpenStreetMap。

1
GET https://restapi.amap.com/v3/place/around?key=xxx&location=116.3974,39.9042&radius=1000&types=050000&offset=25

返回结构化 JSON,含店名、地址、电话、经纬度、距离、类型等字段。

实现

1. 品类映射

OpenStreetMap 和 高德 使用不同的分类体系。我需要把 maps_client.py 的 46 个品类逐一映射到高德的类型编码:

1
2
3
4
5
6
7
8
9
10
11
AMAP_TYPE_MAP = {
"restaurant": "050000", # 餐饮服务
"cafe": "050500", # 咖啡厅
"bar": "050700", # 酒吧
"hospital": "090100", # 综合医院
"hotel": "100000", # 住宿服务
"pharmacy": "090300", # 药店
"bank": "060500", # 银行
"park": "110000", # 公园景点
# ... 共 46 个品类
}

2. 优先策略

nearby 命令现在的逻辑是:先试高德,失败回退 Overpass。AMAP_KEY 不存在时直接走旧路径,完全向后兼容。

1
2
3
4
5
6
7
8
9
10
def cmd_nearby(args):
# ... 解析参数 ...

# 先试高德(中国数据远好于 OSM)
amap_places = amap_nearby(lat, lon, categories, radius, limit)
if amap_places is not None:
return print_json(amap_places)

# 回退 Overpass (OSM)
# ... 原有逻辑 ...

3. 配置持久化

Key 现在配置在 Hermes 的 config.yaml 里,脚本启动时自动读取。也可以通过环境变量传入。

效果

霞浦松城(26.888, 120.0118)附近 500m 搜餐厅:

之前(Overpass/OSM)

1
晨曦酒店 (387m)   ← 酒店被标成了餐厅

之后(高德)

1
2
3
4
5
6
互惠小吃店 (106m)
敖祖雄饼店·世纪锦园店 (107m)
长春炒肉糕·粽子·世纪锦园店 (108m)
渔米乡·酸菜鱼·水煮鱼·世纪锦园店 (108m)
新三峡鱼庄·霞浦天安小区店 (112m)
...

10 条结果,带地址和电话,距离精确到米。

配置方式

如果你也用 maps_client.py,配置高德 Key 很简单:

1
hermes config set env.AMAP_KEY "你的32位key"

之后 nearby 自动走高德,无需其他配置。没有 Key 时自动走 Overpass 旧路径,不影响海外使用。

更新内容

  • maps_client.py v1.4.0
    • 新增 amap_nearby() — 高德周边搜索
    • 46 个品类映射到高德类型编码
    • 新增 AMAP_TYPE_MAP 常量表
    • 优先高德,失败回退 Overpass
    • 支持 AMAP_KEY 从 config.yaml 或环境变量读取
  • maps skill v1.4.0
    • SKILL.md 更新配置说明和 China 覆盖文档