作者: 对�
发布时间: 已于 2026-04-24 16:56:55 修改
来源: https://blog.csdn.net/2503_92571971/article/details/160478260
看到很多人写过ai可以做旅游“智能行程守护助手”,这个工具可以解决了两个核心痛点:堵车赶不上高铁和偏远景点下山打不到车。但是我和朋友讨论的时候想过,这些工具实际上真实需求还是没被解决:
“你解决了‘知道怎么坐公交下山’的问题,但没解决‘根本没有公交’的问题。例如之前朋友说的,霞云岭这种地方,连公交站都远,走路出去要一小时。如果有别的游客正好要从同一个地方下山,或者有顺路的车正在附近行驶,能不能让我知道?”
这个问题非常现实。真正的出行困难,往往不是“没有方案”,而是“有方案但无法执行”——偏远景区的公共交通覆盖率极低,而叫车平台往往没有足够的运力覆盖这类区域。 所以如果在现在这一类“智能行程守护助手”工具中增加一个核心功能或许可以解决这个问题: 周边同路人匹配与拼车推荐。当系统判定当前景区“打车难”时,会自动做三件事:1. 搜索周边正在规划前往同类目的地的其他用户,推荐组队拼车; 2. 搜索周边正在行驶的车辆(通过腾讯位置服务轨迹云API),判断是否有车辆方向匹配; 3. 将所有匹配结果显示在地图上,并生成组队邀请链接。
功能全景如下:
系统采用纯前端实现,核心是“AI Agent + 腾讯位置服务API + 轨迹云终端搜索”。
用户输入景区名称后,Agent调用三个层次的能力:
同路人匹配的逻辑基于腾讯位置服务轨迹云API的终端位置搜索能力。官方文档中明确指出,该能力支持“按城市范围、指定位置周边范围搜索符合条件的终端”,典型场景如“网约车业务:搜索某叫车乘客附近3公里有哪些空载的车辆”。在这个项目中,我将其扩展为:搜索周边正在规划前往同类目的地的用户和搜索周边正在行驶的车辆。
searchNearbyUsers的核心逻辑是:在轨迹云服务中维护一个实体(Entity)集合,每个用户打开页面时上报自己的位置和目标地点,然后通过轨迹云API的周边搜索能力,找出半径2km内target_location字段匹配的其他用户。
searchNearbyVehicles的核心逻辑是:通过filter参数筛选空载车辆,并利用_distance排序找到最近车辆,再判断车辆行驶方向与用户目标方向是否一致。
整个“打车难→找同路人→组队推荐”的流程完全由AI Agent自主决策:
用户输入“北京房山霞云岭,打不到车下山”
→ Agent调用searchNearbyPOI判断打车资源(出租车POI数量<2)
→ Agent调用searchNearbyUsers搜索周边同路人(返回匹配用户列表)
→ Agent调用searchNearbyVehicles搜索周边行驶车辆
→ 根据返回结果生成自然语言回答 + 地图标注
新增的同路人匹配功能依赖腾讯位置服务轨迹云(Track Cloud)。使用步骤如下:
注意:轨迹云服务需要后端支持用户位置上报。在Demo环境中,我们模拟实现了一套简化逻辑:用户位置存储在前端内存(或localStorage)中,通过WebSocket广播给周边用户。
// 搜索周边正在寻找同路的用户
// 核心API:轨迹云终端搜索,支持周边范围搜索 + 自定义字段筛选
async function searchNearbyUsers(lat, lng, radius = 3000) {
// 使用腾讯位置服务轨迹云的终端搜索能力
// API文档:按周边范围搜索 + 自定义字段筛选
const url = `https://apis.map.qq.com/track/v1/entity/search`;
const params = new URLSearchParams({
key: YOUR_API_KEY,
service_id: YOUR_SERVICE_ID,
location: `${lat},${lng}`,
radius: radius,
// 筛选条件:只查 status = 'waiting' 的用户
filter: "entity_fields.status = 'waiting'",
orderby: `_distance(${lat},${lng})`, // 按距离由近到远排序
page_size: 20
});
const response = await fetch(`${url}?${params}`);
const data = await response.json();
if (data.status === 0 && data.result && data.result.data) {
return data.result.data.map(entity => ({
entity_id: entity.entity_id,
entity_name: entity.entity_name,
location: entity.location,
target_location: entity.entity_fields?.target_location,
target_lat: entity.entity_fields?.target_lat,
target_lng: entity.entity_fields?.target_lng,
distance: entity.distance,
last_loctime: entity.last_loctime
}));
}
return [];
}
// 搜索周边正在行驶的车辆(出租车/顺风车)
async function searchNearbyVehicles(lat, lng, radius = 3000) {
// 同样使用轨迹云终端搜索,但筛选 vehicle_type 非空的终端
const url = `https://apis.map.qq.com/track/v1/entity/search`;
const params = new URLSearchParams({
key: YOUR_API_KEY,
service_id: YOUR_SERVICE_ID,
location: `${lat},${lng}`,
radius: radius,
// 筛选有 vehicle_type 字段且不为空的终端(代表车辆)
filter: "entity_fields.vehicle_type IS NOT NULL AND entity_fields.status = 'available'",
orderby: `_distance(${lat},${lng})`,
page_size: 20
});
const response = await fetch(`${url}?${params}`);
const data = await response.json();
if (data.status === 0 && data.result && data.result.data) {
const vehicles = data.result.data.map(entity => ({
entity_id: entity.entity_id,
location: entity.location,
vehicle_type: entity.entity_fields?.vehicle_type,
destination: entity.entity_fields?.destination,
distance: entity.distance,
last_loctime: entity.last_loctime
}));
// 方向匹配度计算:通过对比车辆目的地与用户目标地点是否一致
return vehicles;
}
return [];
}
// 计算方向匹配度(用户目标 vs 车辆目的地)
function calculateMatchScore(vehicle, userTargetLat, userTargetLng) {
if (!vehicle.destination || !vehicle.destination.lat) return 0;
// 计算车辆目的地与用户目标地点的距离
const dx = vehicle.destination.lat - userTargetLat;
const dy = vehicle.destination.lng - userTargetLng;
const distance = Math.sqrt(dx * dx + dy * dy);
// 距离越近,匹配分越高(最多100分,5km内匹配,超过5km为0)
const matchScore = Math.max(0, 100 - (distance / 50000) * 100);
return Math.min(100, Math.floor(matchScore));
}
在实际应用中,用户位置数据应通过后端服务上报到轨迹云。在Demo版本中,我们简化实现:每次用户打开页面或移动时,通过一个简单的HTTP API上报位置,然后通过WebSocket广播给周边用户。
// 用户位置上报(模拟版)
async function reportUserLocation(userId, lat, lng, targetLocation, targetLat, targetLng) {
// 上报到轨迹云
const url = `https://apis.map.qq.com/track/v1/entity/add`;
const body = {
key: YOUR_API_KEY,
service_id: YOUR_SERVICE_ID,
entity_id: userId,
entity_name: `游客_${userId.slice(-4)}`,
location: { lat, lng },
entity_fields: {
target_location: targetLocation,
target_lat: targetLat,
target_lng: targetLng,
status: 'waiting',
last_active: new Date().toISOString()
}
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
const data = await response.json();
return data.status === 0;
}
// WebSocket 广播位置给周边用户(简化实现)
// 实际生产环境应使用腾讯云IM或WebSocket服务
function initWebSocket(userId, onUserUpdate) {
const ws = new WebSocket(`wss://your-backend.com/location?userId=${userId}`);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'nearby_users') {
onUserUpdate(data.users);
}
};
return ws;
}
// 生成组队邀请信息(支持微信小程序跳转)
function createCarpoolInvite(meetingPoint, matchedUsers) {
// 方案一:微信小程序 URL Scheme(跳转到腾讯地图小程序拼车页)
const wxScheme = `weixin://dl/business/?t=map_carpool&from=${encodeURIComponent(meetingPoint.name)}&users=${matchedUsers.length}`;
// 方案二:生成分享文案
const shareText = `📍【拼车召集】我在${meetingPoint.name}附近,已有${matchedUsers.length}位同路人正在寻找拼车下山!点击加入:${wxScheme}`;
// 方案三:DeepLink 跳转到滴滴/高德拼车
const didiDeepLink = `didi://carpool?from=${encodeURIComponent(meetingPoint.address)}&to=${encodeURIComponent(meetingPoint.destination)}`;
return {
wxScheme,
shareText,
didiDeepLink,
meetingPoint,
matchedUsers: matchedUsers.map(u => ({
name: u.entity_name,
distance: u.distance,
target: u.target_location
}))
};
}
将新增功能整合到原有的AI Tool Calling流程中,让大模型自主判断何时调用同路人匹配工具。
// 新增工具定义
const additionalTools = [
{
type: "function",
function: {
name: "searchNearbyUsers",
description: "搜索当前景区周边正在寻找拼车下山或前往同类目的地的其他用户,用于推荐组队",
parameters: {
type: "object",
properties: {
lat: { type: "number", description: "当前景区纬度" },
lng: { type: "number", description: "当前景区经度" },
targetDestination: { type: "string", description: "目标下山后要去的地方" }
},
required: ["lat", "lng"]
}
}
},
{
type: "function",
function: {
name: "searchNearbyVehicles",
description: "搜索当前景区周边正在行驶的顺路车辆(出租车/顺风车),判断是否有空车可以接驳",
parameters: {
type: "object",
properties: {
lat: { type: "number", description: "当前景区纬度" },
lng: { type: "number", description: "当前景区经度" },
userTargetLat: { type: "number", description: "用户想去的目的地纬度" },
userTargetLng: { type: "number", description: "用户想去的目的地经度" }
},
required: ["lat", "lng"]
}
}
},
{
type: "function",
function: {
name: "createCarpoolInvite",
description: "生成拼车组队邀请链接,可用于分享给好友或跳转到出行平台",
parameters: {
type: "object",
properties: {
meetingPoint: { type: "object", description: "汇合点信息" },
matchedUsers: { type: "array", description: "匹配到的其他用户列表" }
},
required: ["meetingPoint"]
}
}
}
];
我输入:
“我在北京房山霞云岭,下山打不到车,附近有没有人一起拼车?”
AI处理流程:
AI回答:
🔍打车资源分析:霞云岭景区周边2km内未发现出租车/网约车服务点,属于“打车难区域”。👥同路人匹配:当前有2位用户也在霞云岭周边寻找下山拼车,目标均是“房山城区”,最远的一位距离你约1.2km。🚗周边车辆:附近有1辆顺风车正在行驶,目的地为“房山城区”,匹配度评分88分。📍 已在下方地图中标注你的位置(红色)、其他用户位置(橙色)和顺路车辆位置(蓝色)。💡 点击下方按钮可生成组队邀请,分享到微信群即可发起拼车!
在“智能行程守护助手”的基础上,新增了周边同路人匹配和顺路车辆搜索两大核心功能,将AI+地图的边界从“路线规划”拓展到了“社交化出行”。
核心贡献总结如下:
最后也想借这个机会呼吁:地图不仅仅是指路的工具,它也可以成为人与人连接的桥梁。当你在偏远景区无助的时候,能知道“附近还有人在同一条路”上——这本身,就是一种安慰。
项目完整代码:(暂不开放,可私聊)
参考资料:
作者: 吹竹笛的若城 发布时间: 于20260419 14:46:37发布 来源: https:
在移动优先与跨端兼容的需求下,H5地图API已成为企业连接用户与地理位置的核心工具无论是电商平台的门
在移动应用开发领域,Android地图开发是连接用户与线下场景的核心桥梁。无论是出行导航本地生活服务