GIS与LLM结合Web应用设计与实施方案
一、数据库设计
1.1 核心数据表结构
用户表(users)
| 字段名 |
类型 |
约束 |
描述 |
| user_id |
SERIAL |
PRIMARY KEY |
用户唯一标识 |
| username |
VARCHAR(50) |
UNIQUE, NOT NULL |
用户名 |
| email |
VARCHAR(100) |
UNIQUE, NOT NULL |
用户邮箱 |
| password_hash |
VARCHAR(255) |
NOT NULL |
密码哈希 |
| api_key |
VARCHAR(100) |
UNIQUE |
第三方API密钥 |
| role |
ENUM('admin', 'user') |
DEFAULT 'user' |
用户角色 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| updated_at |
TIMESTAMP |
DEFAULT NOW() |
更新时间 |
对话记录表(conversations)
| 字段名 |
类型 |
约束 |
描述 |
| conversation_id |
SERIAL |
PRIMARY KEY |
对话唯一标识 |
| user_id |
INTEGER |
FOREIGN KEY(users.user_id) |
关联用户ID |
| title |
VARCHAR(100) |
NOT NULL |
对话标题 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
| is_active |
BOOLEAN |
DEFAULT TRUE |
是否活跃 |
对话消息表(conversation_messages)
| 字段名 |
类型 |
约束 |
描述 |
| message_id |
SERIAL |
PRIMARY KEY |
消息唯一标识 |
| conversation_id |
INTEGER |
FOREIGN KEY(conversations.conversation_id) |
关联对话ID |
| sender |
ENUM('user', 'system', 'llm') |
NOT NULL |
发送者类型 |
| content |
TEXT |
NOT NULL |
消息内容 |
| content_type |
ENUM('text', 'image', 'map') |
DEFAULT 'text' |
内容类型 |
| timestamp |
TIMESTAMP |
DEFAULT NOW() |
发送时间 |
空间分析任务表(spatial_tasks)
| 字段名 |
类型 |
约束 |
描述 |
| task_id |
SERIAL |
PRIMARY KEY |
任务唯一标识 |
| user_id |
INTEGER |
FOREIGN KEY(users.user_id) |
关联用户ID |
| conversation_id |
INTEGER |
FOREIGN KEY(conversations.conversation_id) |
关联对话ID |
| mcp_service_name |
VARCHAR(50) |
NOT NULL |
MCP服务名称 |
| tool_name |
VARCHAR(50) |
NOT NULL |
工具名称 |
| parameters |
JSONB |
NOT NULL |
任务参数 |
| status |
ENUM('pending', 'executing', 'success', 'failed') |
DEFAULT 'pending' |
任务状态 |
| result_path |
VARCHAR(255) |
NULL |
结果存储路径 |
| started_at |
TIMESTAMP |
NULL |
开始时间 |
| completed_at |
TIMESTAMP |
NULL |
完成时间 |
MCP服务配置表(mcp_services)
| 字段名 |
类型 |
约束 |
描述 |
| service_id |
SERIAL |
PRIMARY KEY |
服务唯一标识 |
| name |
VARCHAR(100) |
NOT NULL |
服务名称 |
| service_type |
ENUM('RESOURCE', 'PROMPT', 'TOOL') |
NOT NULL |
服务类型 |
| description |
TEXT |
NULL |
服务描述 |
| url |
VARCHAR(255) |
NOT NULL |
服务URL |
| auth_method |
ENUM('none', 'api_key', 'oauth2') |
DEFAULT 'none' |
认证方式 |
| auth_config |
JSONB |
NULL |
认证配置 |
| schema |
JSONB |
NULL |
参数JSON Schema |
| is_official |
BOOLEAN |
DEFAULT FALSE |
是否官方认证 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
地图图层配置表(map_layers)
| 字段名 |
类型 |
约束 |
描述 |
| layer_id |
SERIAL |
PRIMARY KEY |
图层唯一标识 |
| user_id |
INTEGER |
FOREIGN KEY(users.user_id) |
关联用户ID |
| name |
VARCHAR(100) |
NOT NULL |
图层名称 |
| data_source |
VARCHAR(255) |
NOT NULL |
数据源路径 |
| style_config |
JSONB |
NULL |
样式配置 |
| is_visible |
BOOLEAN |
DEFAULT TRUE |
是否可见 |
| z_index |
INTEGER |
DEFAULT 0 |
图层顺序 |
| created_at |
TIMESTAMP |
DEFAULT NOW() |
创建时间 |
1.2 数据库安全策略
行级安全策略(RLS)
-- 启用RLS
ALTER TABLE spatial_tasks ENABLE ROW LEVEL SECURITY;
ALTER TABLE map_layers ENABLE ROW LEVEL SECURITY;
-- 创建策略
CREATE POLICY user_spatial_tasks_isolation ON spatial_tasks
FOR ALL USING (user_id = current_user_id());
CREATE POLICY user_layers_isolation ON map_layers
FOR ALL USING (user_id = current_user_id());
索引设计
-- 性能优化索引
CREATE INDEX idx_spatial_tasks_user_id ON spatial_tasks(user_id);
CREATE INDEX idx_conversations_user_id ON conversations(user_id);
CREATE INDEX idx_mcp_services_type ON mcp_services(service_type);
二、系统模块设计
2.1 客户端模块
2.1.1 UI层
| 模块 |
核心功能 |
关键函数 |
| 地图组件 |
图层渲染、交互控制 |
renderLayer(layerConfig)、handleMapClick(event) |
| 对话窗口 |
消息展示、输入处理 |
appendMessage(message)、handleSend() |
| 任务面板 |
任务列表、状态展示 |
updateTaskStatus(taskId, status) |
| 设置面板 |
服务配置、参数调整 |
saveServiceConfig(config) |
2.1.2 Host层
| 模块 |
核心功能 |
关键函数 |
| LLM客户端 |
大模型请求、流式处理 |
requestStream(prompt, callbacks) |
| 工具解析器 |
XML解析、参数提取 |
parseToolCall(xmlContent)、validateParameters(params) |
| 权限管理器 |
用户授权、操作审计 |
requestPermission(action)、logAction(action) |
2.1.3 Client层
| 模块 |
核心功能 |
关键函数 |
| MCP资源客户端 |
资源获取、缓存管理 |
getResource(uri, params)、cacheResource(resource) |
| MCP工具客户端 |
工具调用、结果处理 |
callTool(toolName, params)、handleToolResponse(response) |
| MCP提示客户端 |
模板加载、参数替换 |
getPromptTemplate(name)、renderPrompt(template, params) |
2.2 服务端模块
2.2.1 Server层
| 模块 |
核心功能 |
关键接口 |
| LLM服务 |
模型集成、流式响应 |
POST /api/v1/llm/chat |
| MCP服务 |
服务注册、请求路由 |
POST /api/v1/mcp/execute |
| 地图服务 |
图层管理、WMS发布 |
GET /api/v1/map/wms |
| 用户服务 |
认证授权、配置管理 |
POST /api/v1/auth/login |
2.2.2 Resource层
| 模块 |
核心功能 |
技术实现 |
| 空间分析引擎 |
地理处理、数据转换 |
GeoTools + JTS |
| 知识库服务 |
文档存储、检索 |
PostgreSQL +向量索引 |
| 数据存储服务 |
文件管理、元数据 |
MinIO + PostgreSQL |
三、API接口设计
3.1 客户端-服务端接口
LLM对话接口
POST /api/v1/llm/chat
Content-Type: application/json
Authorization: Bearer {token}
{
"conversation_id": "conv_123",
"prompt": "分析海珠区的建筑密度",
"stream": true,
"model": "deepseek-r1"
}
响应(SSE):
event: message
data: {"type": "text", "content": "正在调用空间分析工具..."}
event: tool_call
data: {
"service": "arcgis",
"tool": "density_analysis",
"parameters": {"region": "海珠区", "type": "building"}
}
event: message
data: {"type": "map", "content": "/api/v1/map/layers/result_456"}
MCP工具调用接口
POST /api/v1/mcp/execute
Content-Type: application/json
Authorization: Bearer {token}
{
"service_name": "arcgis",
"tool_name": "clip_analysis",
"parameters": {
"input_layer": "buildings",
"clip_layer": "haizhu_boundary"
}
}
响应:
{
"request_id": "req_789",
"status": "success",
"result": {
"output_layer": "clipped_buildings",
"feature_count": 1562
}
}
3.2 MCP服务接口规范
资源服务接口
GET /mcp/resources/{resource_uri}
Accept: application/json
Authorization: Bearer {token}
工具服务接口
POST /mcp/tools/{tool_name}
Content-Type: application/json
Authorization: Bearer {token}
{
"parameters": {
"param1": "value1",
"param2": "value2"
}
}
四、安全实现
4.1 认证与授权
- OAuth 2.1授权框架集成
- JWT令牌管理(访问令牌2小时,刷新令牌7天)
- 基于角色的访问控制(RBAC)
4.2 数据安全
- 所有API通信使用TLS 1.3加密
- 敏感数据存储加密(AES-256)
- 工具调用审计日志(保留90天)
4.3 MCP安全策略
- 用户明确授权机制(工具调用前弹窗确认)
- 资源访问白名单(仅允许访问指定目录)
- 第三方服务沙箱隔离(Docker容器化部署)
五、部署架构
5.1 容器化部署
├── docker-compose.yml
├── frontend/ # React应用
├── backend/ # Spring Boot服务
├── geoserver/ # 地图服务
├── postgres/ # 数据库
└── minio/ # 对象存储
5.2 服务交互流程
- 用户在前端输入自然语言请求
- 前端Host层调用LLM客户端获取响应
- LLM返回工具调用指令(XML格式)
- Host层解析指令并调用MCP工具客户端
- 服务端MCP模块路由请求至对应工具
- 工具执行完成后返回结果
- Host层将结果整理后发送至LLM生成最终回答
- 前端展示回答及地图结果