经常做地图开发的都知道,在传统地图开发中,周边搜索、路线规划、筛选排序往往需要硬编码多套接口逻辑,参数繁琐、扩展性差。用户需要经过输入关键词→筛选条件→选择排序方式→点击路线规划等多个步骤,才能完成一次简单的出行需求;而开发者则需要处理复杂的参数判断,不仅开发效率低,且扩展性差,难以适配用户多样化的自然语言需求。比如简单的,用户想实现5公里内评分大于4.6的咖啡店,按距离最近规划步行路线,传统开发模式下,需要单独开发关键词搜索、范围筛选、评分过滤、排序、路线规划等多个模块,且无法直接响应自然语言指令。 基于此,我今天分享结合腾讯位置服务(WebService API + JavaScript API GL)与AI自然语言解析技术,实现了一套一句话完成复杂地图操作的智能出行助手——用户只需输入自然语句,系统即可自动完成语义解析、POI搜索、最优推荐、路线计算和地图渲染,既简化了用户操作,也降低了开发者的开发成本
思维导图:
一、技术选型与整体架构
技术栈选型
当然了,为保证代码的轻量性、可运行性和易用性,我这次开发采用极简技术栈,无需依赖Vue、React等前端框架,具体选型如下:
-
地图渲染:腾讯地图 JavaScript API GL(v1.exp),支持3D地图渲染、点位标记、路线绘制,适配各类Web端场景;
-
核心接口:腾讯位置服务 WebService API,包含POI搜索接口(place/v1/search)、路线规划接口(direction/v1/walking/driving);
-
前端逻辑:原生JavaScript,负责AI语义解析、接口调用、逻辑串联;
-
界面开发:HTML5 + CSS3,简洁美观,适配不同屏幕尺寸;
-
AI解析:简易语义解析函数(可无缝对接豆包、通义千问、ChatGLM等真实大模型)。
实现的核心能力:
- 自然语言语义解析:将用户的自然语句,转化为地图API可识别的结构化参数;
- POI精准搜索:基于腾讯位置服务POI接口,实现关键词、范围、评分等多条件筛选;
- 多模式路线规划:支持步行、驾车两种常用出行方式,自动计算最优路线;
- 地图可视化渲染:精准标记推荐点位、绘制路线,支持自动视野适配;
- 结果反馈提示:将搜索结果、路线信息以弹窗形式反馈给用户,提升交互体验。
整体流程架构
整个系统的运行流程清晰易懂,分为5个核心步骤,形成完整的闭环,具体如下:
-
用户输入:用户在输入框中输入自然语言指令(如「5公里内评分>4.6的咖啡店,按距离最近,步行路线」);
-
AI解析:通过语义解析函数,将自然语句拆解为结构化参数(关键词、搜索范围、排序方式、筛选条件、出行方式);
-
接口调用:根据解析后的参数,调用腾讯位置服务POI搜索接口,获取符合条件的最优点位;
-
路线计算:基于当前定位(默认北京,可修改)和推荐点位,调用路线规划接口,获取路线坐标串、距离等信息;
-
可视化与反馈:在地图上标记推荐点位、绘制路线,并通过弹窗向用户反馈点位名称、地址、距离等信息。
二、前期准备
我们在运行本文提供的代码前,需先完成腾讯位置服务Key的申请与配置,步骤简单易懂,具体如下(新手必看):
-
访问腾讯位置服务控制台:lbs.qq.com/(无需注册,直接用QQ…
-
创建应用:登录后,点击控制台左侧「应用管理」→「创建应用」,填写应用名称(如「AI+地图智能出行助手」),选择应用类型(建议选择「Web端」),点击「创建」;
-
申请Key:创建应用后,点击「添加Key」,填写Key名称,选择「Web端」(JavaScript API GL),勾选「WebService API」和「JavaScript API GL」权限(必须勾选,否则接口无法调用);
-
配置域名白名单:为保证接口安全,需配置域名白名单,本地开发可直接填写「*」(允许所有域名访问),线上部署时需填写具体的域名;
-
获取Key:配置完成后,点击「确定」,即可在应用列表中获取到自己的Key,后续将其替换到代码中即可。
注意:Key是接口调用的凭证,请勿泄露给他人;若接口调用失败,可检查Key是否正确、权限是否开启、域名白名单是否配置正确。
三、完整可运行代码
下面附上运行代码:
大家注意: 替换 key为你在腾讯位置服务控制台申请的 Web 端 Key(开启 WebService、JSAPI)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>AI+地图智能推荐</title>
<style>
body{margin:0;padding:10px;background:#f5f5f5;}
#map{width:100%;height:70vh;border-radius:8px;}
.input-area{margin-bottom:10px;display:flex;gap:8px;}
#query{flex:1;padding:12px;border:1px solid #ddd;border-radius:6px;}
#searchBtn{padding:12px 20px;background:#12B7F5;color:white;border:none;border-radius:6px;cursor:pointer;}
</style>
</head>
<body>
<div class="input-area">
<input id="query" placeholder="例:5公里内评分>4.6咖啡店,按距离最近,步行路线"
value="5公里内评分>4.6的咖啡店,按距离最近,规划步行路线">
<button id="searchBtn">AI 解析搜索</button>
</div>
<div id="map"></div>
<!-- 腾讯地图 JS API GL -->
<script src="https://map.qq.com/api/gljs?v=1.exp&key=你的KEY"></script>
<script>
// 1. 初始化地图
const center = new TMap.LatLng(39.9046, 116.4074); // 北京
const map = new TMap.Map("map", {
center,
zoom: 14
});
let markerLayer, polylineLayer;
// 2. AI 解析:自然语言 → 地图参数(可替换为真实大模型)
function aiParseQuery(text) {
const res = {
keyword: "咖啡店",
radius: 5000,
sort: "distance", // distance / rating
filter: "rating>=4.6",
naviType: "walking" // walking / driving
};
if (/公里/.test(text)) res.radius = parseInt(text.match(/(\d+)公里/)[1]) * 1000;
if (/评分>?(\d+\.?\d*)/.test(text)) res.filter = `rating>=${text.match(/评分>?(\d+\.?\d*)/)[1]}`;
if (/距离最近/.test(text)) res.sort = "distance";
if (/评分最高/.test(text)) res.sort = "rating";
if (/步行/.test(text)) res.naviType = "walking";
if (/驾车/.test(text)) res.naviType = "driving";
if (/餐厅|火锅|烧烤|咖啡/.test(text)) res.keyword = text.match(/(餐厅|火锅|烧烤|咖啡店)/)[1];
return res;
}
// 3. 腾讯POI搜索(WebService)
async function searchPOI(params) {
const key = "你的KEY";
const url = `https://apis.map.qq.com/ws/place/v1/search`
+ `?keyword=${encodeURIComponent(params.keyword)}`
+ `&boundary=nearby(${center.lat},${center.lng},${params.radius})`
+ `&orderby=${params.sort}`
+ `&filter=${params.filter}`
+ `&page_size=5`
+ `&key=${key}&output=jsonp`;
return new Promise(resolve => {
const script = document.createElement('script');
window.callback = data => resolve(data?.data?.[0] || null);
script.src = url + '&callback=callback';
document.body.appendChild(script);
});
}
// 4. 路线规划
async function getRoute(from, to, type) {
const key = "你的KEY";
const api = type === "driving" ? "driving" : "walking";
const url = `https://apis.map.qq.com/ws/direction/v1/${api}/`
+ `?from=${from.lat},${from.lng}`
+ `&to=${to.lat},${to.lng}`
+ `&key=${key}&output=jsonp`;
return new Promise(resolve => {
const script = document.createElement('script');
window.routeCb = data => resolve(data?.result?.routes?.[0] || null);
script.src = url + '&callback=routeCb';
document.body.appendChild(script);
});
}
// 5. 绘制地图
function drawMap(to, coords) {
if (markerLayer) markerLayer.setMap(null);
if (polylineLayer) polylineLayer.setMap(null);
// 终点标记
markerLayer = new TMap.MultiMarker({
map,
geometries: [{ position: to, content: "推荐" }]
});
// 路线
const path = coords.map(p => new TMap.LatLng(p.lat, p.lng));
polylineLayer = new TMap.MultiPolyline({
map,
geometries: [{
paths: path,
style: { color: "#12B7F5", width: 6 }
}]
});
map.fitBounds(path);
}
// 6. 主流程
document.getElementById('searchBtn').onclick = async () => {
const text = document.getElementById('query').value;
const params = aiParseQuery(text);
console.log("AI解析参数", params);
const poi = await searchPOI(params);
if (!poi) return alert("未找到符合条件结果");
const to = new TMap.LatLng(poi.location.lat, poi.location.lng);
const route = await getRoute(center, to, params.naviType);
if (!route) return alert("路线失败");
drawMap(to, route.polyline);
alert(`推荐:${poi.title}\n地址:${poi.address}\n距离:${route.distance}m`);
};
</script>
</body>
</html>
这里说一下几个关键点:
- AI 解析:把自然语言转成地图可执行参数,非常容易接入 ChatGLM / Qwen / GPT 等大模型。
- POI 搜索:支持距离/评分排序、过滤、范围、关键词,满足绝大多数本地生活需求。
- 路线规划:支持步行/驾车,返回距离、坐标串,直接画线。
- 可视化:Marker + Polyline,自动视野适配。
四、代码模块详细解析
为帮助开发者更好地理解代码逻辑、便于二次开发,我单独对核心模块进行详细解析,结合代码注释,让新手也能轻松掌握。
全局配置区
该模块是新手重点修改的部分,包含两个核心配置:
-
KEY:腾讯位置服务Key,替换为自己申请的Key,否则接口无法调用;
-
center:默认定位坐标,默认是北京(39.9046, 116.4074),可修改为其他城市,例如上海(31.2304, 121.4737)、广州(23.1289, 113.2655)等,只需替换经纬度即可。
地图初始化模块
该模块用于初始化腾讯地图实例,核心参数说明:
-
center:地图中心坐标,与全局配置区的center一致;
-
zoom:地图缩放级别,范围1-20,数字越大,地图越清晰,默认设置为14(适合查看周边范围);
-
zoomControl:是否显示缩放控件(默认true,便于用户缩放地图);
-
scaleControl:是否显示比例尺控件(默认true,便于用户了解距离)。
同时声明了markerLayer(点位标记图层)和lineLayer(路线图层)两个全局变量,用于后续销毁重绘,避免重复绘制导致的界面混乱。
AI语义解析模块(核心)
该模块是实现「自然语言→地图操作」的核心,功能是将用户的自然语句拆解为结构化参数。其核心逻辑是通过正则表达式,提取自然语句中的关键信息(范围、评分、排序、出行方式、关键词),并赋值给params对象。
重点说明:
-
正则表达式适配了常见的自然语言表述,例如“3公里内”“评分>4.5”“距离最近”“步行路线”等,覆盖绝大多数用户需求;
-
该模块可无缝对接真实大模型(如豆包、通义千问),只需将aiParse函数替换为大模型接口调用,即可支持更复杂的语义解析,例如“先去咖啡店,再去超市,最后驾车回家”“晚上适合约会的安静餐厅,距离5公里内,评分4.8以上”等多意图、模糊语义指令;
-
可根据需求扩展关键词、筛选条件,例如增加“健身房”“电影院”等关键词,或增加“人均消费”等筛选条件。
POI搜索模块
该模块调用腾讯位置服务POI搜索接口(place/v1/search),核心作用是根据AI解析后的参数,搜索符合条件的点位。
关键参数说明(接口URL拼接部分):
-
keyword:搜索关键词,由AI解析获取;
-
boundary=nearby:周边搜索,参数为“中心纬度,中心经度,半径”,半径单位为米;
-
orderby:排序方式,distance(距离最近)、rating(评分最高);
-
filter:筛选条件,此处为评分筛选,格式为“rating>=X”;
-
page_size:返回结果数量,默认1个(最优结果),可修改为5、10等,实现多结果展示;
-
output=jsonp:采用jsonp格式,解决前端跨域问题(浏览器同源策略限制)。
接口返回的数据中,包含点位的名称、地址、坐标、评分等信息,本文只提取第一个最优结果,可根据需求扩展为多结果列表展示。
路线规划模块
该模块调用腾讯位置服务路线规划接口,支持步行、驾车两种出行方式,核心参数说明:
-
from:起点坐标,默认是全局配置的center(当前定位);
-
to:终点坐标,由POI搜索结果获取;
-
apiType:接口类型,根据出行方式选择walking(步行)或driving(驾车);
-
接口返回的数据中,包含路线坐标串(polyline)、距离(distance)、耗时(duration)等信息,本文主要使用polyline(用于绘制路线)和distance(用于反馈给用户)。
地图绘制模块
该模块用于在地图上绘制点位标记和路线,核心功能:
-
销毁旧图层:每次绘制前,销毁之前的markerLayer和lineLayer,避免重复绘制;
-
点位标记:使用MultiMarker组件,自定义点位显示样式(蓝色背景、白色文字),锚点设置为居中,确保点位显示美观;
-
路线绘制:使用MultiPolyline组件,设置路线颜色、宽度和边框,增强视觉效果;
-
视野适配:调用map.fitBounds(path),让路线和点位完全显示在地图中,无需用户手动缩放。
主流程模块
该模块是整个系统的入口,串联所有模块,执行流程如下:
-
获取用户输入,校验输入合法性(不能为空);
-
调用aiParse函数,解析自然语言,获取结构化参数;
-
调用searchPOI函数,获取推荐点位,校验结果合法性;
-
调用getRoute函数,获取路线信息,校验结果合法性;
-
调用drawMap函数,绘制地图点位和路线;
-
通过弹窗向用户反馈结果,包含点位名称、地址、出行方式、距离等信息。
同时,在控制台打印AI解析后的参数,便于开发者调试,排查问题。
五、测试说明
代码运行后,可直接复制以下测试语句,粘贴到输入框中,点击“AI解析搜索”,即可看到效果,无需额外配置:
-
3公里内评分>4.5的火锅,驾车路线;
-
2公里内评分>4.7的奶茶店,按距离最近,步行路线;
-
1公里内评分>4.4的餐厅,按评分最高;
-
5公里内的酒店,驾车路线;
-
4公里内的加油站,步行路线。
测试注意事项:
-
确保Key已正确替换,且权限已开启;
-
测试时需保证网络通畅,接口调用需要网络支持;
-
若未找到符合条件的点位,可调整搜索范围(如将3公里改为5公里)或评分条件(如将4.5改为4.0)。 大模型也可以替换为豆包、通义千问、ChatGLM等大模型的API接口,实现其他更复杂的语义解析。
六、常见问题与排错指南
在运行代码或二次开发过程中,可能会遇到一些问题,我也整理了常见问题及解决方法,帮助大家快速排错:
接口调用失败,控制台报错“Invalid Key”
原因:Key错误或未配置权限。
解决方法:
-
检查Key是否正确,确保替换了代码中的两处“你的KEY”;
-
登录腾讯位置服务控制台,检查应用的Key是否开启了“WebService API”和“JavaScript API GL”权限;
-
检查域名白名单配置,本地开发可设置为“*”,线上部署需填写具体域名。
未找到符合条件的点位,弹窗提示“未找到符合条件的点位”
原因:搜索条件过于严格(如范围太小、评分太高),或关键词错误。
解决方法:
-
调整搜索范围(如将3公里改为5公里);
-
降低评分条件(如将4.6改为4.0);
-
检查关键词是否正确,确保关键词在腾讯POI数据库中存在(如“咖啡店”“火锅”等常见关键词)。
路线规划失败,弹窗提示“路线规划失败”
原因:起点或终点坐标错误,或网络连接异常。
解决方法:
-
检查起点坐标(center)是否正确,确保是有效的经纬度;
-
检查POI搜索结果是否正常,确保toPoint坐标有效;
-
检查网络连接,刷新页面后重试。
地图不显示,或点位、路线不绘制
原因:地图初始化失败,或图层未正确绑定到地图实例。
解决方法:
-
检查腾讯地图JavaScript API GL的引入是否正确,确保URL中的Key已替换;
-
检查map实例是否初始化成功,可在控制台打印map,查看是否有值;
-
检查markerLayer和lineLayer是否绑定了map实例(drawMap函数中,确保map参数正确)。
七、总结
最后简单总结一下,这里我们基于腾讯位置服务与AI自然语言解析技术,实现了一套轻量化、可运行、可扩展的AI+地图智能出行助手。完全实现简化了用户的地图操作流程(一句话完成复杂需求),降低了开发者的开发成本(无框架依赖、开箱即用),同时具备较强的扩展性,可根据需求扩展多场景、多端适配,满足不同开发者的二次开发需求。希望本文的方案能为广大开发者提供参考与帮助。
#腾讯地图 #腾讯位置服务#腾讯位置服务征文大赛