QgisStreamMCP
QGIS为您的AI助手提供服务 --部署一次,从任何地方使用QGIS。无需本地安装,也不需要GIS专业知识。
在Docker中运行一个完整的QGIS桌面,并将其作为MCP服务器公开。你的人工智能助手有42个工具,涵盖数据加载、空间分析、制图和多格式导出。你不需要安装QGIS——人工智能可以在任何时候从任何设备完全代表你处理它。
管理员只部署一次容器(在服务器、NAS或本地)。用户连接他们的AI客户端,并立即在他们的对话中使用QGIS功能。
亮点
- 无需QGIS --完整的QGIS桌面在Docker中运行。你的人工智能助手代表你使用它——不需要本地安装,也不需要GIS专业知识。
- 随处可用 --在服务器上或本地部署。从任何兼容MCP的AI客户端(克劳德桌面、光标、继续…)连接。
- 智能数据管道 —
set_study_zone("Montpellier")然后smart_load("bdtopo_batiments").下载WFS作为本地GeoPackage,具有自动分页、R树空间索引、CRS变换功能。处理速度比实时WFS快60-250倍。 - 30+预配置的法语数据集 -BD TOPO,Admin Express,RPG,IGN正射影像,地籍图,DEM,Corine Land Cover,OSM,Esri。无需API密钥。
- 完整的QGIS桌面 --通过noVNC实现实时GUI。AI和用户同时在同一个实例上工作。
- 1000+处理算法 --原住民、GDAL、GRASS、SAGA。所有这些都可以通过MCP工具访问。
- 自动化食谱 --预先构建的工作流程(密度分析、洪水风险、土地覆盖、海岸压力)。一个命令:
run_recipe("risque_inondation", zone="Nimes"). - 多格式导出 --PDF布局、交互式传单地图(标准、洪水分析、时间)、QField移动包、Grist协作文档。
- MCP应用程序 --直接嵌入对话中的交互式QGIS视图(VNC查看器、文件上传、键盘/鼠标转发)。
快速开始
git clone https://github.com/nic01asFr/QgisStreamMCP.git
cd QgisStreamMCP
docker compose up -d --build端点
| 端口 | 服务 | URL |
|---|---|---|
| 6080 | 无VNC(浏览器中的QGIS) | http://localhost:6080 |
| 8100 | MCP服务器(流式HTTP) | http://localhost:8100/mcp |
| 8080 | REST API | http://localhost:8080/docs |
| 8081 | MJPEG流 | http://localhost:8081/stream |
连接到克劳德桌面
添加 claude_desktop_config.json:
{
"mcpServers": {
"qgis": {
"url": "http://localhost:8100/mcp"
}
}
}智能数据加载
核心创新:一个结构化的管道,用快速的本地GeoPackage文件取代不可靠的实时WFS连接。
为什么?
| 问题 | 实时WFS | 智能加载 |
|---|---|---|
| 分页 | IGN在5000时自动截断 | ogr2ogr自动处理所有页面 |
| 空间索引 | 无(内存中) | GeoPackage中的R树 |
| 处理速度 | 60-250x慢(网络+无索引) | 快速本地文件 |
| 分析期间的网络 | 每个功能的HTTP请求 | 零网络 |
| CRS混淆 | 混合4326/3857/2154 | 标准化EPSG:2154 |
管道
1. set_study_zone(target="Montpellier") # Geocode, store bbox, zoom
2. smart_load(id="osm_xyz") # Basemap (streaming)
3. smart_load(id="bdtopo_batiments") # Buildings (download GPKG)
4. smart_load(id="bdtopo_routes") # Roads (download GPKG)
5. get_screenshot # Verify
6. run_processing / execute_python # Analyze
7. export_pdf / export_web_map / ... # Deliver (PDF, HTML, QField, Grist)性能(蒙彼利埃,约10公里bbox)
| 操作 | 功能 | 时间 |
|---|---|---|
| 下载建筑物 | 10000 | ~30s |
| 下载道路 | 5000 | 6.8秒 |
| 缓存重新加载(第二次调用) | 10000 | 即时 |
| 缓冲区50m | 10000 | 1.8s |
| 使用后溶解 | 10000 | 2.2秒 |
| 密度网格500m | 440个单元 | 0.3s |
缓存
下载被缓存在 /data/cache/ 使用bbox哈希。相同面积=24小时瞬时重新加载。
可用数据源
所有来源都是免费的(IGN自2021年7月开放数据)。不需要API密钥。
矢量数据(WFS,下载为GPKG)
| ID | 名称 | 关键属性 |
|---|---|---|
bdtopo_batiments | 建筑物 | 性质、用途、高度、楼层、材料 |
bdtopo_routes | 道路 | 性质、重要性、宽度、车道、速度 |
bdtopo_hydrographie | 河流 | 名称、类别、宽度 |
bdtopo_vegetation | 植被带 | 自然 |
bdtopo_voie_ferree | 铁路 | 性质,nb_voies |
bdtopo_hydro_surfaces | 水体 | 性质、名称 |
bdtopo_communes | 公社(BD TOPO) | 名称、代码INSEE、人口 |
admin_express_communes | 社区(Admin Express) | 名称、代码、人口 |
admin_express_departements | 部门 | 名称、代码 |
admin_express_regions | 地区 | 名称、代码 |
rpg | 农业地块 | 作物类型、面积 |
bdtopo_poi | 兴趣点 | 性质 |
bdtopo_lieu_dit | 地名 | 名称 |
bdtopo_surface_activite | 活动区 | 自然 |
bdtopo_equipement_transport | 交通设施 | 性质 |
底图(流媒体)
| ID | 名称 |
|---|---|
osm_xyz | OpenStreetMap |
ign_planign | IGN v2计划 |
ign_scan25 | IGN 1:25000 顶级卡 |
cartodb_positron | 灯光底图 |
cartodb_dark | 黑暗底图 |
esri_world_topo | Esri世界地形图 |
stamen_terrain | 斯塔曼地形(起伏) |
图像(流媒体)
| ID | 名称 |
|---|---|
ign_ortho_wmts | IGN正射影像(WMTS,快速) |
ign_ortho_wms | IGN正射影像(WMS) |
ign_ortho_irc | IGN红外照片 |
esri_world_imagery | Esri卫星 |
其他(WMS/neneneba API)
| ID | 名称 |
|---|---|
ign_cadastre | 地籍地块 |
ign_dem | 高分辨率DEM |
corine_land_cover | 2018年土地覆盖 |
ban_geocode | 地址地理编码API |
geo_api_communes | 公共信息API |
dvf_api | 房地产交易API |
panoramax | 街道图像API |
ign_altimetrie | API高程 |
食谱
预构建的工作流模板,可自动完成从数据加载到样式化地图导出的完整分析。
| ID | 名称 | 描述 |
|---|---|---|
densite_bati | 建筑密度 | 带刻度符号的十六进制网格密度分析 |
urbanisme_general | 城市概述 | 建筑、道路、植被、水文,风格分类 |
risque_inondation | 洪水风险 | 洪水区、建筑暴露、缓冲区分析+交互式网络地图 |
occupation_sol | 土地覆盖 | 具有分类符号的Corine土地覆盖 |
pression_fonciere_cotiere | 沿海陆地压力 | 2020-2024年DVF交易,沿海带+时间网络地图 |
用法
# Automated (all steps in one shot)
run_recipe(id="risque_inondation", zone="Nimes")
# Manual (follow steps one by one)
get_recipe(id="densite_bati", zone="Montpellier")
→ Returns step-by-step instructions to execute individually导出格式
PDF布局
通过QGIS打印布局和预构建模板(A3横向、A4纵向)打印就绪的PDF。包括标题、图例、比例尺、指北针和数据源。
apply_layout_template(template="a3_landscape", title="Flood Risk — Nimes")
export_pdf(layout="a3_landscape")交互式网络地图
带有嵌入式GeoJSON数据的传单HTML文件。三个专用模板:
| 模板 | 用例 | 功能 |
|---|---|---|
| 标准 | 常规地图 | 图层切换、弹出窗口、图例、底图选择器 |
| 洪水 | 洪水风险分析 | 水位滑块、建筑暴露统计数据、动画 |
| 时序 | 时间序列 | 年份滑块、每段统计数据、趋势箭头、动画播放 |
QField移动套餐
便携式ZIP已准备就绪 QField 移动数据收集:
.qgz具有相关GPKG来源的项目- 所有矢量层都具体化为单独的GeoPackages
- 可编辑的 观察 带有表单小部件(下拉菜单、日期选择器、相机、自由文本)的图层
export_qfield(project_name="terrain_survey")
→ /data/terrain_survey_qfield.zipGrist文件
将QGIS项目层或任何HTML映射转换为 谷物 协作文档(.grist):
- 来自项目 --使用自定义地图小部件将可见矢量图层导出为Grist表格
- 来自HTML --通用转换器:接受任何包含GeoJSON的HTML文件(洪水图、时间图、qgis2web导出),并创建一个Grist文档,其中包含表格中的数据和原始交互式地图作为Grist自定义小部件
检测到的列类型: Choice (彩色下拉菜单), Date (纪元时间戳), Ref (交叉表引用)。类似表格的表格会自动获得Grist Form页面。
# From QGIS project
export_grist(title="Urban Analysis")
# From any HTML with GeoJSON
export_grist(html_path="/data/flood_map_nimes.html")MCP工具
智能加载
| 工具 | 说明 |
|---|---|
set_study_zone | 定义学习区域(社区、地址、bbox)。地理编码、存储bbox、缩放画布。 |
get_study_zone | 获取当前学习区域(名称,4326+2154中的bbox)。 |
smart_load | 按目录ID加载数据。WFS→ 具有空间索引的本地GPKG。光栅流。 |
核心
| 工具 | 说明 |
|---|---|
execute_python | 运行PyQGIS代码,完全访问iface、项目、处理、, helpers 模块。 |
get_screenshot | 将QGIS画布捕获为PNG格式。修改工具后自动包含。 |
get_project_info | 当前项目状态(图层、CRS、布局、范围)。 |
run_processing | 执行1000多种处理算法中的任何一种。 |
search_algorithms | 按关键字查找处理算法。 |
zoom_to | 导航到范围、图层或点。 |
数据和图层
| 工具 | 说明 |
|---|---|
add_layer | 按URI添加矢量/光栅/WFS/WMS |
remove_layer | 移除一层。 |
get_features | 使用属性/空间过滤器查询特征。 |
list_datasources | 浏览预配置的数据目录。 |
add_from_catalog | 按目录ID添加源 |
样式
| 工具 | 说明 |
|---|---|
set_layer_style | 应用单色、分类或分级符号。 |
set_layer_visibility | 显示/隐藏图层。 |
apply_layout_template | 应用打印布局模板(A3横向、A4纵向)。 |
list_layout_templates | 列出可用的布局模板。 |
食谱
| 工具 | 说明 |
|---|---|
list_recipes | 浏览可用的工作流配方。 |
get_recipe | 通过参数替换获取配方详细信息。 |
run_recipe | 自动执行一个完整的配方(一次性完成所有步骤)。 |
出口
| 工具 | 说明 |
|---|---|
export_pdf | 将打印布局导出为PDF。 |
export_web_map | 将可见层导出为交互式传单HTML。 |
export_flood_map | 交互式洪水分析HTML(水位滑块,建筑物曝光)。 |
export_temporal_map | 交互式时间分析HTML(年份滑块,动画播放)。 |
export_qfield | QField就绪ZIP包(.qgz+GPKG+可编辑观测层)。 |
export_grist | 使用GeoJSON从项目层或任何HTML中提取Grist文档。 |
export_layer | 将矢量图层导出到GPKG、GeoJSON、Shapefile、CSV。 |
文件
| 工具 | 说明 |
|---|---|
upload_file | 上传文件(shapefile、GeoJSON、GPKG、CSV、TIFF、项目)。 |
download_file | 从/data/下载文件。 |
list_files | 列出/data/中的文件。 |
delete_file | 从/data/中删除文件。 |
download_project | 将项目另存为.qgz。 |
GUI交互
| 工具 | 说明 |
|---|---|
qgis_desktop_ui | 在对话中打开交互式QGIS MCP应用程序。 |
mouse_click / mouse_scroll / mouse_drag / key_press | 通过xdotool直接进行GUI交互。 |
项目
| 工具 | 说明 |
|---|---|
new_project | 创建空项目。 |
open_project | 打开一个.qgz项目。 |
save_project | 保存当前项目。 |
MCP技能(资源)
指导人工智能助手专业知识的参考文件:
| 资源URI | 内容 |
|---|---|
skill://smart-loading | 智能加载管道——set_study_gone+Smart_load、CRS处理、缓存 |
skill://pyqgis | PyQGIS脚本模式和API使用 |
skill://processing | 处理算法指南(原生、GDAL、GRASS) |
skill://cartography | 符号、标签、打印布局、PDF导出 |
skill://helpers | 现成的Python帮助程序(地理编码、add_wfs、zoom_to、create_point_layer…) |
skill://data-sources | 法国国家数据集参考 |
skill://recipes | 工作流配方参考 |
skill://external-services | 从PyQGIS脚本调用外部HTTP服务 |
skill://qgis-status | 实时QGIS实例状态 |
MCP提示
| 提示 | 描述 |
|---|---|
analyse_territoire | 区域分析模板(区域+问题)。 |
workflow_donnees | 引导式工作流程 --基于主题的加载(城市规划、环境、交通、农业、风险),并附有分步说明。 |
MCP应用程序
直接嵌入Claude对话中的交互式QGIS视图:
- 实时VNC查看器 --在对话中查看QGIS并与之互动
- 文件上传 --将文件直接拖放到QGIS容器中
- 键盘/鼠标转发 --无需离开聊天室即可进行全面交互
- MJPEG回退 --轻量级流,提供快速视觉反馈
示例工作流
手册:城市分析
User: "Analyse l'urbanisation autour de Montpellier"
AI: [set_study_zone("Montpellier")]
→ Geocodes, stores bbox, zooms canvas
[smart_load("osm_xyz")] → OpenStreetMap basemap
[smart_load("bdtopo_batiments")] → 10,000 buildings as GPKG
[smart_load("bdtopo_routes")] → 5,000 road segments
[execute_python → density grid] → 500m hex grid, graduated symbology
[apply_layout_template("a3_landscape", title="Densité bâtie — Montpellier")]
[export_pdf] → /data/densite_montpellier.pdf自动化:配方的洪水风险
User: "Analyse le risque inondation à Nîmes"
AI: [run_recipe("risque_inondation", zone="Nimes")]
→ Executes all steps automatically:
1. set_study_zone("Nimes")
2. smart_load basemap + buildings + flood zones
3. Buffer analysis (50m, 100m, 200m from flood zones)
4. Building exposure classification
5. Graduated symbology
→ Returns screenshot + statistics
[export_flood_map(include_fields=["nature","usage","height"])]
→ Interactive HTML with water height slider
[export_grist(html_path="/data/flood_map_nimes.html")]
→ Grist document with editable tables + embedded map widget现场调查:QField Export
User: "Prépare un relevé terrain pour la commune de Sète"
AI: [set_study_zone("Sète")]
[smart_load("bdtopo_batiments")]
[smart_load("bdtopo_routes")]
[set_layer_style("Batiments", type="categorized", field="usage")]
[export_qfield(project_name="releve_sete")]
→ ZIP with .qgz + GPKGs + Observations layer (camera, dropdowns, date picker)
→ Ready to load on QField mobile app扩展外部服务
PyQGIS脚本(execute_python)可以调用容器中可访问的任何HTTP服务——本地或远程。这涵盖了ML推理API、自定义后端、卫星处理器、提升服务或任何内部API。
通过环境变量传递服务URL .env:
MY_SERVICE_URL=http://host.docker.internal:8001然后在脚本中使用它们:
import os, urllib.request, json
url = os.environ.get("MY_SERVICE_URL")
# call your service...host.docker.internal 解析到主机,允许访问容器外运行的服务。
建筑
┌─────────────────────────────────────────────────────────────┐
│ QgisStreamMCP Container │
│ │
│ supervisord │
│ ├── Xvfb :99 (virtual display 1920x1080) │
│ ├── fluxbox (window manager) │
│ ├── QGIS Desktop ◄─────────────────────┐ │
│ │ └── qgis_bridge.py (startup) │ UNIX socket │
│ ├── x11vnc → noVNC (:6080) │ │
│ ├── api_server.py (:8080) ───┘ │
│ ├── main_mcp.py (:8100) ───┘ │
│ └── stream_server.py (:8081) │
│ │
│ /data/ (user files, projects) │
│ /data/cache/ (smart_load GPKG cache, 24h) │
│ /app/skills/ (MCP skill documents) │
│ /app/datasources.json (30+ pre-configured sources) │
└──────────┬──────────────────────────────────────────────────┘
│ HTTP (optional)
▼
External services (any HTTP API reachable from the container)通信流
Claude Desktop / MCP Client
│ JSON-RPC over Streamable HTTP (:8100)
▼
main_mcp.py (MCP Server)
│ UNIX socket /tmp/qgis_bridge.sock
▼
qgis_bridge.py (runs inside QGIS, main thread)
│ PyQGIS API (iface, QgsProject, processing)
▼
QGIS Desktop (Xvfb display :99)
│ X11
▼
x11vnc → websockify → noVNC (:6080)
│ WebSocket
▼
User's browser发展
# Source files are mounted as volumes — edit locally
# Restart to apply changes:
docker compose restart qgisstreammcp
# View logs
docker compose logs -f qgisstreammcp
# Test API
curl http://localhost:8080/health
curl -X POST http://localhost:8080/api/execute \
-H "Content-Type: application/json" \
-d '{"code": "result[\"v\"] = Qgis.version()"}'
# Test smart loading
curl -X POST http://localhost:8080/api/execute \
-H "Content-Type: application/json" \
-d '{"code": "result.update(helpers.set_study_zone(\"Montpellier\"))", "timeout": 30}'项目结构
QgisStreamMCP/
├── main_mcp.py # MCP Server (40 tools, 10 resources, 3 prompts)
├── datasources.json # 30+ pre-configured data sources catalog
├── qgis_app.html # MCP App (interactive QGIS in conversation)
├── src/
│ ├── qgis_bridge.py # Runs inside QGIS (UNIX socket bridge, 45 actions)
│ ├── qgis_helpers.py # Python helpers (geocode, smart loading, etc.)
│ ├── api_server.py # FastAPI REST API
│ └── stream_server.py # MJPEG stream
├── skills/ # MCP Resources (AI skill documents)
│ ├── smart_loading.md
│ ├── pyqgis.md
│ ├── processing.md
│ ├── cartography.md
│ ├── helpers.md
│ ├── data_sources.md
│ └── external_services.md
├── recipes/ # Workflow recipes (JSON)
│ ├── densite_bati.json
│ ├── urbanisme_general.json
│ ├── risque_inondation.json
│ ├── occupation_sol.json
│ └── pression_fonciere_cotiere.json
├── templates/ # Print layout templates (.qpt)
│ ├── a3_landscape.qpt
│ ├── a4_portrait.qpt
│ └── web/ # Leaflet HTML templates
│ ├── leaflet_template.html
│ ├── leaflet_flood_template.html
│ └── leaflet_temporal_template.html
├── projects/ # QGIS project files (persisted)
├── docs/ # Architecture diagrams
├── Dockerfile
├── docker-compose.yml
├── supervisord.conf
├── entrypoint.sh
├── requirements.txt
└── CLAUDE.md许可证
麻省理工学院
积分
- QGIS — https://qgis.org
- 无VNC — https://novnc.com
- 主控程序 — https://modelcontextprotocol.io
- IGN地球板块 — https://data.geopf.fr(免费法国国家地理数据)
- GDAL/OGR — https://gdal.org(数据转换和下载引擎)
