Python之osm-mcp-server包语法、参数和实际应用案例
osm-mcp-server 完整使用文档
一、包基础概述
1. 核心定义
osm-mcp-server 是面向 OSM(OpenStreetMap,开源街道地图) 的 MCP(Model Context Protocol,模型上下文协议)服务端Python工具包,核心作用:
- 搭建本地/远程MCP地图服务,让大模型(Claude、GPT、本地LLM)直接读写、查询、解析OSM地图数据;
- 封装OSM底层API、PBF/XML地图文件解析、地理要素检索、路网分析;
- 标准化MCP通信协议,提供统一接口给AI模型调用地理空间能力;
- 支持矢量地图裁剪、POI检索、道路拓扑提取、坐标转换、OSM数据入库。
2. 核心功能分类
| 模块 | 功能说明 |
|---|---|
| MCP服务模块 | 启动TCP/STDIO MCP服务,管理AI客户端连接、上下文会话、请求路由 |
| OSM解析引擎 | 解析.osm/.osm.pbf/.osm.gz文件,提取Node/Way/Relation三大要素 |
| 地理查询API | 按经纬度、边界框、标签(key=value)检索道路、建筑、商店、公交站点 |
| 空间计算工具 | WGS84/UTM坐标互转、距离计算、多边形面积、路网连通性分析 |
| OSM编辑接口 | 批量修改OSM标签、导出裁剪地图、生成简化矢量地图 |
| 数据持久化 | 对接SQLite/PostGIS,缓存OSM地图数据,加速重复查询 |
3. 适用场景
AI地图问答、本地离线OSM数据分析、自动驾驶路网提取、城市POI统计、GIS自动化脚本、LLM地理插件后端。
二、安装教程
环境前置要求
- Python ≥3.10(推荐3.11/3.12,低版本会缺失asyncio异步依赖)
- 系统依赖:
- Windows:无需额外系统库
- Linux:
apt install libosmpbf-dev protobuf-compiler - MacOS:
brew install osmpbf protobuf
- 配套依赖:
pyosmium(OSM解析核心)、mcp(MCP协议标准库)、shapely(空间几何)、geopy(地理编码)
标准安装命令
方式1:pip正式版
pip install osm-mcp-server
方式2:源码最新开发版
git clone https://github.com/osm-mcp/osm-mcp-server.git
cd osm-mcp-server
pip install -r requirements.txt
pip install .
方式3:离线内网安装
- 下载whl包:
pip download osm-mcp-server - 内网离线部署:
pip install *.whl --no-index
安装校验
import osm_mcp_server
print(osm_mcp_server.__version__)
# 输出版本号即安装成功
三、核心语法、类、参数全解析
3.1 顶层入口类 OSMMCPServer(服务启动核心)
构造函数语法
class OSMMCPServer(Server):
def __init__(
self,
osm_data_path: str | Path,
backend: Literal["pyosmium", "libosmpbf"] = "pyosmium",
cache_db: str = ":memory:",
max_conn: int = 10,
bbox_limit: tuple[float, float, float, float] | None = None,
enable_postgis: bool = False,
log_level: Literal["DEBUG", "INFO", "WARN", "ERROR"] = "INFO"
)
关键参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| osm_data_path | str/Path | 必填 | OSM地图文件路径,支持pbf/xml/gz,或OSM数据库路径 |
| backend | 枚举 | pyosmium | OSM解析后端;libosmpbf速度更快,适合超大地图 |
| cache_db | str | :memory: | 缓存数据库路径,填文件路径持久化缓存,内存模式重启丢失 |
| max_conn | int | 10 | MCP客户端最大并发连接数 |
| bbox_limit | 四元组 | None | 全局边界框限制 (min_lon, min_lat, max_lon, max_lat),超出范围不加载数据 |
| enable_postgis | bool | False | 是否启用PostGIS空间数据库,开启后支持百万级地图查询 |
| log_level | 枚举 | INFO | 日志输出等级,DEBUG输出完整请求/OSM要素详情 |
服务启动方法
- STDIO模式(对接本地AI客户端,如Claude Desktop)
async def start_stdio(self) -> None
- TCP网络模式(远程多AI客户端访问)
async def start_tcp(self, host: str = "127.0.0.1", port: int = 8787) -> None
3.2 内置工具函数(AI可直接调用的MCP工具)
包内置注册20+MCP工具,核心通用函数语法:
1. query_osm_by_bbox 边界框检索要素
async def query_osm_by_bbox(
min_lon: float,
min_lat: float,
max_lon: float,
max_lat: float,
tags: dict | None = None,
element_type: Literal["node", "way", "relation", "all"] = "all"
) -> list[dict]
- tags:标签过滤,例
{"shop":"supermarket"}只返回超市 - 返回值:标准化JSON数组,包含坐标、标签、OSM ID、几何信息
2. get_road_network 提取路网拓扑
async def get_road_network(bbox: tuple, road_levels: list[str]) -> dict
road_levels可选:motorway/trunk/primary/secondary/residential
3. convert_coordinate 坐标转换
async def convert_coordinate(lon: float, lat: float, target_crs: str) -> tuple[float, float]
target_crs支持:EPSG:4326(WGS84)、EPSG:32650(UTM)
4. export_cropped_osm 裁剪导出地图
async def export_cropped_osm(bbox: tuple, out_path: str, fmt: Literal["pbf", "xml"]) -> str
3.3 配置文件参数(osm_mcp_config.yaml)
可通过外部yaml配置替代代码传参,核心配置项:
server:
mode: stdio # stdio/tcp
tcp_port: 8787
max_connections: 15
osm:
data_file: "./china.pbf"
global_bbox: [116.3,39.9,116.5,40.1]
cache:
db_path: "./osm_cache.db"
expire_hours: 24
postgis:
enable: false
dsn: "postgresql://user:pass@127.0.0.1:5432/osm_db"
四、8个完整可运行实际应用案例
案例1:STDIO本地MCP服务(对接Claude桌面)
需求:启动本地OSM MCP服务,让Claude直接查询城市POI
import asyncio
from osm_mcp_server import OSMMCPServer
async def main():
# 初始化服务,加载北京区域OSM文件
server = OSMMCPServer(
osm_data_path="./beijing.pbf",
cache_db="./cache_beijing.db",
log_level="DEBUG"
)
# STDIO启动,AI客户端直接读取标准输入输出通信
await server.start_stdio()
if __name__ == "__main__":
asyncio.run(main())
使用:Claude Desktop配置mcp服务指向该脚本,对话中可直接提问“查询朝阳区所有便利店”。
案例2:TCP远程MCP地图服务(多LLM共享)
需求:局域网部署地图服务,多台机器GPT/本地大模型远程调用
import asyncio
from osm_mcp_server import OSMMCPServer
async def main():
server = OSMMCPServer(
osm_data_path="./country_china.pbf",
backend="libosmpbf",
max_conn=20
)
# 0.0.0.0监听所有局域网设备,端口8787
await server.start_tcp(host="0.0.0.0", port=8787)
if __name__ == "__main__":
asyncio.run(main())
客户端连接地址:tcp://192.168.1.100:8787
案例3:边界框批量检索城市所有写字楼POI
需求:代码直接调用内置查询工具,导出区域办公建筑列表
import asyncio
from osm_mcp_server import OSMMCPServer
async def query_office_buildings():
server = OSMMCPServer(osm_data_path="./shanghai.pbf")
# 上海静安区边界框
bbox = (121.43, 31.21, 121.48, 31.24)
min_lon, min_lat, max_lon, max_lat = bbox
# 调用查询工具,过滤办公建筑标签
office_list = await server.query_osm_by_bbox(
min_lon=min_lon,
min_lat=min_lat,
max_lon=max_lon,
max_lat=max_lat,
tags={"building": "office"},
element_type="way"
)
print(f"静安区写字楼总数:{len(office_list)}")
# 打印前5条数据
for item in office_list[:5]:
print(f"OSM_ID:{item['id']}, 坐标:{item['center']}, 标签:{item['tags']}")
asyncio.run(query_office_buildings())
案例4:提取城市主干道路网,计算道路长度
需求:导出区域高速、主干道路网,统计总里程
import asyncio
from osm_mcp_server import OSMMCPServer
async def calc_road_total_length():
server = OSMMCPServer(osm_data_path="./guangzhou.pbf")
bbox = (113.2,23.0,113.4,23.2)
road_data = await server.get_road_network(
bbox=bbox,
road_levels=["motorway", "trunk", "primary"]
)
total_km = road_data["total_length_km"]
print(f"广州核心区主干道总长度:{total_km:.2f} km")
# 输出单条道路明细
for road in road_data["roads"][:3]:
print(f"道路名称:{road['tags'].get('name','无名道路')},长度{road['length_km']:.2f}km")
asyncio.run(calc_road_total_length())
案例5:WGS84经纬度转UTM投影坐标(测绘场景)
需求:GIS测绘,转换OSM原始GPS坐标为平面UTM坐标用于距离测量
import asyncio
from osm_mcp_server import OSMMCPServer
async def coord_transform():
server = OSMMCPServer(osm_data_path="./test.pbf")
# 北京天安门经纬度
lon, lat = 116.403874, 39.914885
# 转换为UTM 50N投影
x, y = await server.convert_coordinate(lon, lat, target_crs="EPSG:32650")
print(f"UTM X:{x:.2f}, UTM Y:{y:.2f}")
# 反向转回WGS84
lon2, lat2 = await server.convert_coordinate(x, y, target_crs="EPSG:4326")
print(f"还原经纬度:{lon2:.6f}, {lat2:.6f}")
asyncio.run(coord_transform())
案例6:裁剪局部地图导出独立pbf文件
需求:从全国大地图中裁剪城市片区,生成轻量化离线地图
import asyncio
from osm_mcp_server import OSMMCPServer
from pathlib import Path
async def crop_osm_file():
server = OSMMCPServer(osm_data_path="./china_large.pbf")
out_path = Path("./hangzhou_suburb.pbf")
bbox = (120.0,30.2,120.3,30.4)
# 裁剪并导出pbf格式地图
result = await server.export_cropped_osm(
bbox=bbox,
out_path=str(out_path),
fmt="pbf"
)
print(f"裁剪完成,文件路径:{result}")
asyncio.run(crop_osm_file())
案例7:对接PostGIS数据库,百万级OSM数据持久查询
需求:大规模城市规划分析,将OSM要素存入空间数据库加速查询
import asyncio
from osm_mcp_server import OSMMCPServer
async def postgis_osm_query():
# 开启PostGIS后端
server = OSMMCPServer(
osm_data_path="./shenzhen_full.pbf",
enable_postgis=True,
cache_db="postgresql://postgres:123456@127.0.0.1:5432/osm_db"
)
# 查询所有地铁站点
subway_stations = await server.query_osm_by_bbox(
113.8,22.4,114.2,22.6,
tags={"railway": "station", "subway": "yes"}
)
print(f"深圳地铁站数量:{len(subway_stations)}")
asyncio.run(postgis_osm_query())
案例8:AI自动化脚本,批量统计各类生活配套POI
需求:循环查询超市、学校、医院、停车场,生成城市配套统计表
import asyncio
from osm_mcp_server import OSMMCPServer
async def stat_city_facility():
server = OSMMCPServer(osm_data_path="./chengdu.pbf")
city_bbox = (104.05,30.55,104.12,30.62)
min_lon,min_lat,max_lon,max_lat = city_bbox
# 定义需要统计的设施标签
facility_tags = [
("超市", {"shop":"supermarket"}),
("小学", {"amenity":"school", "school:type":"primary"}),
("医院", {"amenity":"hospital"}),
("停车场", {"amenity":"parking"})
]
stat_result = {}
for name, tag in facility_tags:
data = await server.query_osm_by_bbox(min_lon,min_lat,max_lon,max_lat,tags=tag)
stat_result[name] = len(data)
# 输出统计报表
print("成都主城区配套设施统计:")
for k,v in stat_result.items():
print(f"{k}:{v}个")
asyncio.run(stat_city_facility())
五、常见错误、报错解决方案
1. 安装阶段报错
报错1:ModuleNotFoundError: No module named 'pyosmium'
原因:依赖未自动安装,网络缺失编译包
解决:
# Linux/Mac
apt install libosmpbf-dev && pip install pyosmium
# Windows
pip install pyosmium-bin
报错2:protobuf编译失败 error: protobuf compiler not found
解决:安装系统protobuf工具,再重装包
# Ubuntu
apt install protobuf-compiler
# Mac
brew install protobuf
pip install osm-mcp-server --force-reinstall
2. 服务启动运行时错误
报错3:OSMFileLoadError: Failed to parse .pbf file
原因1:地图文件损坏、下载不完整;原因2:文件路径含中文/空格
解决:
- 重新下载OSM pbf地图;
- 修改文件路径为纯英文无空格;
- 切换
backend="libosmpbf"解析大文件。
报错4:OSError: address already in use port 8787
原因:TCP端口被占用
解决:更换端口 start_tcp(port=8788),或杀死占用端口进程。
报错5:MaxConnectionError: reach max_conn limit 10
原因:并发MCP客户端超过最大连接数
解决:初始化服务时调高max_conn=30。
3. 查询工具调用报错
报错6:BBoxRangeError: longitude out of [-180,180]
原因:传入的经纬度数值非法(超出全球坐标范围)
解决:校验边界框参数,经度-180180,纬度-9090。
报错7:PostGISConnectError: could not connect to postgres
原因:PostGIS地址、账号密码错误,数据库未创建
解决:检查dsn连接字符串,提前创建osm数据库并启用postgis扩展。
报错8:TagFilterWarning: empty tags dict returns all elements
非崩溃警告:未传入tags参数会返回区域全部要素,数据量大卡顿
解决:查询时必须指定业务标签过滤,缩小返回数据量。
4. 异步运行报错
报错9:RuntimeError: asyncio.run() cannot be called from a running event loop
原因:嵌套异步循环(Jupyter/异步web框架中直接运行脚本)
解决:Jupyter使用await main(),不要套asyncio.run()。
六、使用注意事项与性能优化
1. 地图文件性能规范
- 超大地图(>5GB全国pbf)必须使用
backend="libosmpbf",解析速度提升3~5倍; - 生产环境不要使用
:memory:缓存,配置本地sqlite持久缓存cache_db="./osm_cache.db"; - 全局限定
bbox_limit,避免加载全球全部要素造成内存溢出。
2. MCP服务部署规范
- 本地AI客户端(Claude Desktop/Ollama)使用
stdio模式,轻量化无端口占用; - 多客户端共享地图数据使用
tcp模式,设置合理max_conn; - 公网暴露TCP服务时增加鉴权(包支持token参数,生产环境必须开启)。
3. 内存与资源管控
- 单次query_osm_by_bbox不要跨超大区域(如全省),会一次性加载数十万要素;
- 批量统计场景拆分小边界框循环查询,降低单次内存占用;
- 长期运行服务定时调用内置
server.clear_cache()释放缓存内存。
4. 兼容性注意
- Python3.9及以下不支持异步MCP协议,必须3.10+;
- Windows下libosmpbf后端兼容性差,Windows优先使用pyosmium;
- OSM旧版
.osmxml文件解析效率远低于pbf,生产统一使用pbf格式。
5. 业务使用避坑
- OSM道路way要素是线段集合,获取中心点使用工具内置
center字段,不要手动计算; - 标签key/value区分大小写,
shop=Supermarket和shop=supermarket是两种标签; - 离线地图无实时更新,如需最新OSM数据需每日重新下载pbf文件。
《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。
更多推荐
所有评论(0)