🌍 AI + Cesium:利用 MCP 协议实现 3D 地球的自然语言交互

🌍 AI + Cesium:利用 MCP 协议实现 3D 地球的自然语言交互

前言 🚀

想象一下:你不需要在复杂的 GIS 系统中点击几十次来寻找某个坐标,只需像聊天一样对 AI 说:“带我去上海东方明珠,并标注附近的三家医院。” 地图便会如丝般顺滑地旋转、缩放、并自动插上标记。

这就是我们今天要实现的效果 —— 基于 MCP 协议,通过自然语言直接控制 Cesium 3D 地球。 🤖🗺️


什么是 MCP?🤔

在深入代码之前,我们先来聊聊这位“功臣”:MCP(Model Context Protocol)

引用 DeepSeek 的专业解释:MCP 是由 Anthropic 公司推出的开放标准协议。你可以把它理解为 AI 应用的 “通用 USB-C 接口”

  • 核心目标:打破“数据孤岛”,让 AI 能够安全、统一地访问本地文件、数据库或调用 API。
  • 架构模式:采用 客户端-服务器 模式。AI 助手作为客户端,通过 MCP 协议与特定的 MCP 服务器通信,从而获得“手”和“眼”的功能。

一句话总结:MCP 让 AI 从只能动嘴的“聊天机器人”,变成了能查资料、能执行操作的 “智能代理(AI Agent)”。💪


开发准备 🛠️

我们将基于开源项目 cesium-mcp 进行开发。

1. 安装依赖 📦

首先在你的 Cesium 项目中安装桥接插件:

npm install cesium-mcp-bridge

方式一:通过 Trae 直接控制 🛰️

如果你使用的是字节跳动出品的 AI IDE —— Trae,你可以直接在编辑器中“调教”你的地球。

1. 桥接初始化

在你的 Cesium 初始化代码中,将 viewer 实例传给 CesiumBridge

import { CesiumBridge } from 'cesium-mcp-bridge'

// 初始化 viewer 后
const bridge = new CesiumBridge(viewer)

2. 配置 Trae 的 MCP 服务

在 Trae 的设置中找到 MCP 配置,添加如下内容:

{
  "mcpServers": {
    "cesium-mcp": {
      "command": "npx",
      "args": ["cesium-mcp-runtime"],
      "env": {
        "PORT": "9100"
      }
    }
  }
}

💡 小贴士:这里 Trae 会自动负责启动 cesium-mcp-runtime 服务,你不需要再按照官方文档手动运行命令。

image-20260401172633337

显示绿色对勾说明链接成功 ✅。

3. 建立 WebSocket 通信

为了让 Trae 发出的指令能传达到我们的页面,需要手动实现一段 WebSocket 逻辑:

// 手动实现 WebSocket 连接逻辑
const serverUrl = 'ws://localhost:9100'
const socket = new WebSocket(serverUrl)

socket.onopen = () => {
  console.log('[CesiumBridge] Connected to MCP server at', serverUrl)
}

socket.onmessage = async (event) => {
  try {
    const data = JSON.parse(event.data)
    console.log('[CesiumBridge] Received message:', data)

    const action = data.action || data.method
    if (action) {
      console.log(`[CesiumBridge] Executing command: ${action}`, data.params)

      // 调用 bridge 执行 AI 发来的指令
      const result = await bridge.execute({
        action: action,
        params: data.params || {},
      })

      console.log('[CesiumBridge] Execution result:', result)

      // 返回结果给服务器
      // 关键:必须回传相同的 id,以便服务器识别这是哪个请求的响应
      const response = {
        type: 'result',
        id: data.id,
        success: result.success,
        data: result.data,
        error: result.error,
        message: result.message,
      }

      socket.send(JSON.stringify(response))
    }
  } catch (e) {
    console.error('[CesiumBridge] Error processing message:', e)
  }
}

socket.onclose = () => {
  console.warn('[CesiumBridge] Disconnected from MCP server')
}

配置成功后,你可以直接在 Trae 的对话框里说:“把地图转到巴黎”,它真的会动!✨


方式二:在前端 UI 中集成 AI 助手 🎨

更进一步,我们可以将这个功能直接集成到产品的 UI 界面中。用户直接在对话框中发送自然语言即可控制 Cesium 地球。

大致思路:给 AI 发送提示词(System Prompt)和工具定义(Tools),AI 根据用户意图选择合适的 Tool,返回对应指令的 JSON,由 CesiumBridge 解析并执行。

cesium-mcp给出了58个可用工具,这里只举例 flyToaddMarker

image-20260401175548587

1. 定义工具列表 (JSON Schema) 📋

const MAP_TOOLS = [
  {
    type: 'function',
    function: {
      name: 'flyTo',
      description: '将地图相机平滑飞行到指定坐标',
      parameters: {
        type: 'object',
        properties: {
          longitude: { type: 'number' },
          latitude: { type: 'number' },
          height: { type: 'number', default: 5000 },
        },
        required: ['longitude', 'latitude'],
      },
    },
  },
  {
    type: 'function',
    function: {
      name: 'addMarker',
      description: '在地图指定位置添加 HTML 标记',
      parameters: {
        type: 'object',
        properties: {
          longitude: { type: 'number' },
          latitude: { type: 'number' },
          label: { type: 'string' },
        },
        required: ['longitude', 'latitude', 'label'],
      },
    },
  },
]

2. 定义提示词 🧠

const messages = [
  {
    role: 'system',
    content:
      '你是一个专业的地图智能助手。你可以通过调用工具来控制 Cesium 地图。',
  },
  { role: 'assistant', content: '您好!我是您的智能地图助手。请下令。' },
]

3. 构造请求 📡

这里以本地 Ollama 模型为例(Qwen2.5),你也可以换成任意支持 Tool Call 的大模型。

const response = await fetch('http://192.168.10.10:11434/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'qwen2.5:latest',
    messages: apiMessages,
    tools: MAP_TOOLS,
    stream: true,
  }),
})

4. 指令解析与执行 ⚡

async function handleCommandExecution(msg: any) {
  // 1. 原生工具执行 (Tool Call)
  if (msg.tool_calls && msg.tool_calls.length > 0) {
    for (const tool of msg.tool_calls) {
      await bridge.execute({
        action: tool.function.name,
        params: tool.function.arguments,
      })
      // 反馈执行结果给上下文...
    }
  }
  // 2. 备选方案:文本正则解析指令 (针对不支持工具的模型)
  else {
    const jsonMatch = msg.content.match(/```json\s*([\s\S]*?)\s*```/)
    if (jsonMatch) {
      const cmds = JSON.parse(jsonMatch[1].trim())
      for (const cmd of cmds) await bridge.execute(cmd)
    }
  }
}

执行效果展示 📺

核心注意点 ⚠️

  1. 模型选择:并非所有模型都支持 Tools。推荐使用 Qwen2.5-7B 及以上、GPT-4o 或 Claude 3.5。如果模型不支持,建议在 System Prompt 中强调 JSON 输出格式。
  2. 坐标系陷阱:Cesium 默认使用 WGS84。如果你的数据源是 GCJ02(火星坐标系),记得在 bridge 执行前做一层 CoordTransform 转换。
  3. 安全性:绝不要让 AI 直接执行 eval() 或拼接字符串。使用 CesiumBridge 提供的规范化指令(Action/Params)能最大程度保证系统安全。
  4. 性能优化:对于高频的视角切换,建议在 UI 层增加防抖处理,或者在 AI 回复过程中增加“正在执行”的加载动画,提升用户体验。

结语 🌟

通过 MCP 协议,我们成功抹平了“自然语言”与“GIS 专业操作”之间的鸿沟。这不仅仅是一个好玩的功能,在应急指挥、智慧城市大屏汇报等场景下,这种交互方式能极大地降低系统的使用门槛。

如果你也对 GIS + AI 感兴趣,快去给项目点个 Star 试试吧!🚀


项目地址gaopengbin/cesium-mcp

参考文章前端直连模型 vs 完整 MCP:大模型驱动地图的原理与实践(技术栈Vue + Cesium + Node.js + WebSocket + MCP)