作者: 五年小兵勇闯互联网 发布时间: 已于 2026-04-17 11:15:55 修改
来源: https://blog.csdn.net/2302_77582029/article/details/160188552
活动链接:腾讯位置服务开发者征文大赛——AI赋能 重塑地图智能新体验

项目名称: AI智能地图助手开发方向: AI对话式地图(自然语言查地点、问路)技术栈: 腾讯位置服务JSAPI GL + AI大模型Demo地址: [120.55.41.72:8080、各位网络安全大佬不要攻击小弟,谢谢!]
作为开发者,你是否也遇到过这样的场景:
场景1 - 搜索困惑: 用户想找"天安门附近的咖啡馆",传统地图需要:
先定位天安门再搜索"咖啡馆"手动筛选附近结果查看详情判断是否符合需求
整个过程至少5步,对于不熟悉地图操作的老人和孩子来说,门槛很高。
场景2 - 路线规划繁琐: 想问"从北京西站到故宫怎么走最快",需要:
在起点框输入"北京西站"在终点框输入"故宫"选择出行方式查看多条路线对比
为什么不能直接问一句话就得到答案?
场景3 - 个性化推荐缺失: “帮我找个安静、有插座、人少的咖啡馆学习”,传统地图只能搜索关键词,无法理解"安静"、"人少"这种抽象需求。
2024年,大语言模型的爆发让自然语言交互成为可能。用户只需说:
“帮我找北京西站附近的咖啡馆”“从天安门到故宫怎么走?”“推荐几个人少的公园”
AI自动解析意图,调用地图API,返回精准结果——这就是AI对话式地图的价值。
本项目旨在打造一个AI智能地图助手,实现:
✅自然语言交互:用户用口语描述需求,无需学习专业操作✅智能意图识别:自动判断是搜索、导航还是推荐✅多轮对话支持:可以追问、补充条件、调整需求✅可视化展示:地图实时标记、路线可视化、详情弹窗✅混合AI架构:支持本地规则引擎和云端大模型切换
┌─────────────────────────────────────────────────┐
│ 用户界面层 │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ 对话界面 │ │ 地图展示 │ │
│ │ (Chat UI) │◄────►│ (Map Canvas) │ │
│ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────────────────────────┐
│ 应用逻辑层 │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ AI对话服务 │ │ 地图服务 │ │
│ │ (AI Service) │◄────►│ (Map Service) │ │
│ └──────────────┘ └──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ 意图解析 参数提取 操作执行 │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────────────────────────┐
│ API调用层 │
│ ┌────────────────┐ ┌─────────────────┐ │
│ │ 大模型API │ │ 腾讯位置服务API │ │
│ │ (可选云端) │ │ (JSAPI/WebSvc) │ │
│ └────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────┘
职责:
接收用户自然语言输入意图识别(搜索POI、路线规划、推荐、定位)参数提取(关键词、位置、起点终点等)生成友好响应文本
设计亮点:
// 支持多种AI引擎混合架构
class AIService {
processInput(input, context) {
switch (this.provider) {
case 'local': // 本地规则引擎(免费、快速)
return this.processLocal(input, context);
case 'qwen': // 通义千问云端API
return this.processQwen(input, context);
case 'zhipu': // 智谱GLM云端API
return this.processZhipu(input, context);
case 'custom': // 自定义API扩展
return this.processCustom(input, context);
}
}
}
意图识别规则示例:
const intents = {
search_poi: [
/找(.+)附近(.+)/, // "找北京西站附近的咖啡馆"
/搜索(.+)/, // "搜索咖啡"
/附近(.+)/ // "附近美食"
],
route_planning: [
/从(.+)到(.+)/, // "从天安门到故宫"
/(.+)到(.+)怎么走/ // "北京西站到故宫怎么走"
],
recommendation: [
/推荐(.+)/, // "推荐景点"
/人少的(.+)/ // "人少的咖啡馆"
]
};
职责:
地图初始化与渲染POI搜索与标记显示路线规划与可视化地理编码/逆地理编码定位服务
核心技术选择: 由于浏览器CORS限制,本项目使用JSONP方式调用WebService API,而非JSAPI服务模块。这样可:
✅ 完全规避跨域限制✅ 无需配置域名白名单✅ 兼容所有浏览器环境
核心API封装:
class MapService {
constructor() {
this.map = null;
this.apiKey = null; // 存储API密钥
this.markers = [];
}
// JSONP请求封装(规避CORS)
jsonpRequest(url) {
return new Promise((resolve, reject) => {
// 创建唯一callback名
const callbackName = 'jsonp_callback_' + Date.now();
const jsonpUrl = url + '&output=jsonp&callback=' + callbackName;
// 创建script标签(天然可跨域)
const script = document.createElement('script');
script.src = jsonpUrl;
// 定义全局callback函数
window[callbackName] = function(data) {
resolve(data);
delete window[callbackName];
document.body.removeChild(script);
};
// 错误和超时处理
script.onerror = () => reject(new Error('请求失败'));
setTimeout(() => {
if (window[callbackName]) {
reject(new Error('请求超时'));
}
}, 10000);
document.body.appendChild(script);
});
}
// POI搜索 - 使用WebService API
async searchPOI(params) {
const keyword = encodeURIComponent(params.keyword);
const region = encodeURIComponent(params.region || '北京');
const apiUrl = `https://apis.map.qq.com/ws/place/v1/search?keyword=${keyword}&boundary=region(${region},0)&key=${this.apiKey}`;
const data = await this.jsonpRequest(apiUrl);
// 详细数据验证
if (data.status !== 0) {
throw new Error(data.message || '搜索失败');
}
// 格式化返回数据
return data.data.map(poi => ({
title: poi.title,
address: poi.address,
location: { lat: poi.location.lat, lng: poi.location.lng },
distance: poi._distance || null
}));
}
// 路线规划 - 使用WebService API
async planRoute(params) {
const apiUrl = `https://apis.map.qq.com/ws/direction/v1/driving/?from=${params.from.lat},${params.from.lng}&to=${params.to.lat},${params.to.lng}&key=${this.apiKey}`;
const data = await this.jsonpRequest(apiUrl);
if (data.status !== 0) {
throw new Error(data.message || '路线规划失败');
}
// 转换数据格式
return {
result: {
routes: data.result.routes.map(route => ({
distance: route.distance,
duration: route.duration,
polyline: route.polyline,
steps: route.steps
}))
}
};
}
// 地理编码 - 地址转坐标
async geocoder(address) {
const apiUrl = `https://apis.map.qq.com/ws/geocoder/v1/?address=${encodeURIComponent(address)}&key=${this.apiKey}`;
const data = await this.jsonpRequest(apiUrl);
// 详细验证返回数据
if (data.status !== 0 || !data.result || !data.result.location) {
throw new Error('未找到地址对应的坐标');
}
return {
lat: data.result.location.lat,
lng: data.result.location.lng
};
}
// 在地图上显示POI
displayPOIOnMap(poiList) {
poiList.forEach((poi, index) => {
// 创建标记
const marker = new TMap.Marker({
map: this.map,
position: new TMap.LatLng(poi.location.lat, poi.location.lng)
});
// 添加信息窗口
const infoWindow = new TMap.InfoWindow({
map: this.map,
position: new TMap.LatLng(poi.location.lat, poi.location.lng),
content: `<h4>${poi.title}</h4><p>${poi.address}</p>`
});
marker.on('click', () => infoWindow.open());
this.markers.push({ marker, infoWindow });
});
}
}
设计亮点:
JSONP封装:统一处理跨域、错误、超时数据验证:多层检查避免undefined错误格式转换:统一数据结构便于前端使用
职责:
整合AI和地图服务处理用户交互流程状态管理(当前位置、聊天历史)错误处理与反馈
完整交互流程:
async function sendMessage() {
const userMessage = inputField.value.trim();
// 1. AI解析意图
const aiResult = await aiService.processInput(userMessage, {
currentLocation: appState.currentLocation,
region: '北京'
});
// 2. 根据意图执行地图操作
switch (aiResult.intent) {
case 'search_poi':
// 搜索POI → 在地图显示
const poiList = await mapService.searchPOI(aiResult.params);
mapService.displayPOIOnMap(poiList);
break;
case 'route_planning':
// 地理编码起点终点 → 路线规划 → 可视化
const from = await mapService.geocoder(aiResult.params.from);
const to = await mapService.geocoder(aiResult.params.to);
const route = await mapService.planRoute({ from, to });
mapService.displayRouteOnMap(route);
break;
}
// 3. 生成友好响应
addMessage('assistant', generateResponse(aiResult, poiList));
}
挑战:用户输入千变万化,如何准确识别意图?
方案:混合策略 - 规则匹配 + 云端大模型
使用正则表达式匹配常见句式:
// 示例:处理"找XX附近XX"
function processLocal(input) {
const match = input.match(/找(.+)附近(.+)/);
if (match) {
return {
intent: 'search_poi',
params: {
location: match[1], // "北京西站"
keyword: match[2] // "咖啡馆"
}
};
}
}
优点:
无需API调用,响应速度<50ms完全免费,适合高频简单查询可控性强,覆盖主流表达
缺点:
无法处理复杂语义(如"人少"、“安静”)需维护大量规则
调用通义千问或智谱GLM,使用提示词工程:
const prompt = `
请分析用户地图查询需求,提取关键信息:
用户输入: "${userInput}"
返回JSON格式:
{
"intent": "意图类型(search_poi/route_planning)",
"params": { "keyword": "...", "location": "..." },
"response": "友好的中文响应"
}
`;
const aiResponse = await callQwenAPI(prompt);
const parsed = JSON.parse(aiResponse);
优点:
理解复杂语义(“安静”、“有插座”、“评价好”)处理模糊表达(“找个地方学习”)多轮对话支持
缺点:
需要API Key(免费额度充足)响应时间200-500ms有配额限制
最佳实践:混合架构
// 简单查询用本地引擎
if (isSimpleQuery(input)) {
return processLocal(input);
}
// 复杂查询用云端AI
if (needDeepUnderstanding(input)) {
return processQwen(input);
}
场景:用户说"找北京西站附近的咖啡馆"
技术流程:
ERROR: [Mermaid] Lexical error on line 3. Unrecognized text. … B --> C[地理编码: 北京西站 → 坐标(39.89, 116.32)] -----------------------^
关键代码:
async function handlePOISearch(params) {
// Step1: 地理编码"北京西站"
const geocodeResult = await mapService.geocoder(
params.location + ', 北京'
);
// Step2: 以该坐标为中心搜索"咖啡馆"
const poiList = await mapService.searchPOI({
keyword: params.keyword,
location: geocodeResult, // 中心点
pageSize: 10
});
// Step3: 在地图上标记,显示距离
mapService.displayPOIOnMap(poiList, {
showDistance: true // 显示"距离XX米"
});
// Step4: 生成文本响应
let response = `找到${poiList.length}个结果:\n`;
poiList.forEach(poi => {
response += `${poi.title} - ${poi.distance}米\n`;
});
}
效果截图:

场景:用户问"从天安门到故宫怎么走"
实现步骤:
async function handleRoutePlanning(params) {
// 1. 地理编码起点和终点(JSONP方式)
const fromLocation = await mapService.geocoder('天安门, 北京');
const toLocation = await mapService.geocoder('故宫, 北京');
// 2. 调用腾讯WebService路线规划API
const routeResult = await mapService.planRoute({
from: fromLocation,
to: toLocation
// 不传policy参数,使用API默认最优路线
});
// 3. 提取路线信息
const route = routeResult.result.routes[0];
const distance = route.distance; // 米
const duration = route.duration; // 秒
const steps = route.steps; // 导航步骤
// 4. 在地图上绘制路线(JSAPI可视化)
mapService.displayRouteOnMap(routeResult);
// 5. 显示详细信息面板
showRouteInfo({
distance: `${(distance/1000).toFixed(2)}公里`,
duration: `${Math.floor(duration/60)}分钟`,
steps: steps.map(s => s.instruction)
});
}
关键技术架构:
数据查询:WebService API + JSONP(规避CORS)地图渲染:JSAPI GL Marker/Polyline(前端可视化)分离设计:查询层与渲染层解耦,提高稳定性 const route = routeResult.result.routes[0]; const distance = route.distance; // 米 const duration = route.duration; // 秒 const steps = route.steps; // 导航步骤// 4. 在地图上绘制��线 mapService.displayRouteOnMap(routeResult);// 5. 显示详细信息面板 showRouteInfo({ distance:${(distance/1000).toFixed(2)}公里, duration:${Math.floor(duration/60)}分钟, steps: steps.map(s => s.instruction) }); }
地图渲染效果:
**地图渲染效果**:

---
### 3.4 前端交互优化
#### 设计原则
1. **响应式布局**:对话面板+地图面板并排显示
2. **实时反馈**:AI思考时显示加载动画
3. **历史记录**:保留聊天记录,方便回顾
4. **快捷操作**:提供常用搜索快捷按钮
#### UI实现细节
```css
/* 左右分栏布局 */
.app-container {
display: flex;
height: 100vh;
gap: 20px;
}
.chat-panel {
flex: 0 0 450px; /* 固定宽度 */
background: white;
border-radius: 16px;
}
.map-panel {
flex: 1; /* 自适应剩余空间 */
position: relative;
}
/* 消息动画 */
.message {
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}

响应式布局:对话面板+地图面板并排显示实时反馈:AI思考时显示加载动画历史记录:保留聊天记录,方便回顾快捷操作:提供常用搜索快捷按钮
async function handleRoutePlanning(params) {
// 1. 地理编码起点和终点
const fromLocation = await mapService.geocoder('天安门, 北京');
const toLocation = await mapService.geocoder('故宫, 北京');
// 2. 调用腾讯路线规划API
const routeResult = await mapService.planRoute({
from: fromLocation,
to: toLocation,
policy: TMap.constants.DRIVING_POLICY.LEAST_TIME // 最短时间
});
// 3. 提取路线信息
const route = routeResult.result.routes[0];
const distance = route.distance; // 米
const duration = route.duration; // 秒
const steps = route.steps; // 导航步骤
// 4. 在地图上绘制��线
mapService.displayRouteOnMap(routeResult);
// 5. 显示详细信息面板
showRouteInfo({
distance: `${(distance/1000).toFixed(2)}公里`,
duration: `${Math.floor(duration/60)}分钟`,
steps: steps.map(s => s.instruction)
});
}
问题发现:
项目初期尝试使用JSAPI服务模块进行搜索和路线规划:
// ❌ 尝试1:使用JSAPI服务模块(失败) const searchService = new TMap.service.Search({ pageSize: 10 }); // 报错:Cannot read properties of undefined (reading ‘Search’)
原因分析:
JSAPI服务模块在某些环境下无法正常初始化或API Key未启用service模块权限加载顺序或依赖关系问题
尝试方案2:改用fetch调用WebService API
// ❌ 尝试2:使用fetch调用WebService API(被CORS拦截) const apiUrl = ‘https://apis.map.qq.com/ws/place/v1/search?keyword=咖啡馆&key=YOUR_KEY’; fetch(apiUrl) .then(response => response.json()) .then(data => console.log(data)); // 报错:CORS policy: No ‘Access-Control-Allow-Origin’ header
原因分析:
浏览器同源策略阻止跨域HTTP请求即使在腾讯控制台配置域名白名单,本地开发环境(localhost)仍受限fetch/XMLHttpRequest天然受CORS限制
最终方案:使用JSONP规避CORS
// ✅ 最终方案:JSONP(成功!)
function jsonpRequest(url) {
return new Promise((resolve, reject) => {
// 1. 创建唯一callback名
const callbackName = 'jsonp_callback_' + Date.now();
const jsonpUrl = url + '&output=jsonp&callback=' + callbackName;
// 2. 创建script标签(天然可跨域)
const script = document.createElement('script');
script.src = jsonpUrl;
// 3. 定义全局callback函数
window[callbackName] = function(data) {
resolve(data);
delete window[callbackName];
document.body.removeChild(script);
};
// 4. 错误和超时处理
script.onerror = () => reject(new Error('请求失败'));
setTimeout(() => {
if (window[callbackName]) {
reject(new Error('请求超时'));
}
}, 10000);
// 5. 执行
document.body.appendChild(script);
});
}
// 使用示例
const apiUrl = 'https://apis.map.qq.com/ws/place/v1/search?keyword=咖啡馆&key=YOUR_KEY';
jsonpRequest(apiUrl).then(data => {
console.log('搜索成功:', data);
});
JSONP原理:
利用
4. 用浏览器打开index.html即可运行
7.4 参考文档
腾讯位置服务开发文档JSAPI GL参考手册WebService API文档通义千问API指南
八、致谢与呼吁
感谢腾讯位置服务团队提供完善的API生态和技术支持,感谢CSDN组织本次征文活动,让开发者有机会展示创意、分享经验。
呼吁开发者同行:
AI+地图的融合才刚刚开始,潜力巨大!无论是:
🌱入门者:用自然语言创建第一个地图应用💻工程师:深度集成Agent、MCP协议📊分析师:探索时空数据洞察商业价值
都有发挥空间。期待看到更多创新案例,共同推动地图服务从「工具」进化为「智能大脑」!
技术栈: JavaScript + 腾讯位置服务JSAPI GL + AI大模型
**欢迎点赞、评论、转发,一起探讨AI+地图的无限可能!**🚀
在移动应用小程序或企业官网中,地图展示是连接用户与地理位置的核心入口。无论是展示门店位置规划物流路线
在智慧出行本地生活零售选址等场景中,精准的地图能力如定位POI搜索路径规划已成为企业数字化的刚需。腾
在物流调度共享出行智慧城市等领域,精确定位经纬度是企业实现高效运营的核心需求。无论是实时追踪车辆位置