如何获取Google Maps选定路线途经的国家列表?求更优实现方案
Hey 伙计!完全懂你的需求——6年前的那些方案要么效率低,要么覆盖不全,我最近刚好折腾过类似的场景,给你分享几个更优的现代方案,都是基于Google Maps系列API的:
方案1:优化版 DirectionsService + 反向地理编码(高效首选)
这个方案核心是减少无效请求+精准过滤,比旧方法逐个步骤查询要高效得多:
- 步骤拆解:
- 用
DirectionsService获取完整路线,不用把每个路径点都拿去查,而是提取关键节点:比如每个路段(leg)的起点、终点,再给每个步骤(step)的路径做间隔采样(比如每10个点取1个),这样既能覆盖所有可能跨国家的路段,又不会产生冗余请求。 - 把这些关键节点批量传给反向地理编码接口,直接通过
result_type: ['country']参数过滤,只返回国家层级的结果,不用处理一堆无关的地址组件。 - 用
Set自动去重,最后转成数组得到唯一的国家列表。
- 用
代码示例(JavaScript)
const directionsService = new google.maps.DirectionsService(); const geocoder = new google.maps.Geocoder(); async function getRouteCountries(origin, destination) { try { // 1. 获取路线数据 const routeRes = await directionsService.route({ origin: origin, destination: destination, travelMode: google.maps.TravelMode.DRIVING // 可换成WALKING/TRANSIT }); const route = routeRes.routes[0]; const keyPoints = []; // 收集关键节点:路段起止点 + 路径采样点 route.legs.forEach(leg => { keyPoints.push(leg.start_location); keyPoints.push(leg.end_location); // 每个step的路径每10个点取一个,平衡精度和请求数 leg.steps.forEach(step => { const path = step.path; for (let i = 0; i < path.length; i += 10) { keyPoints.push(path[i]); } }); }); // 2. 批量反向地理编码(按API限制,每次最多5个点) const countrySet = new Set(); for (let i = 0; i < keyPoints.length; i += 5) { const batch = keyPoints.slice(i, i + 5); const promises = batch.map(point => geocoder.geocode({ location: point, result_type: ['country'] // 只返回国家结果 }).then(geoRes => { if (geoRes.results.length > 0) { // 提取国家信息,优先用ISO代码去重更准确 const countryComp = geoRes.results[0].address_components.find(comp => comp.types.includes('country') ); if (countryComp) { countrySet.add(countryComp.short_name); // 存ISO代码,比如CN、DE // 要名称的话用countryComp.long_name } } }) ); await Promise.all(promises); } // 转成数组返回,也可以把代码转成名称 return Array.from(countrySet); } catch (err) { console.error('获取路线国家失败:', err); return []; } } // 调用示例 getRouteCountries('巴黎, 法国', '柏林, 德国') .then(countries => console.log('途经国家ISO代码:', countries)) .catch(err => console.error(err));
优势说明
- 比旧方法减少70%以上的请求数,大大降低API成本和限流风险;
- 用ISO国家代码去重,完全避免名称翻译导致的重复;
- 支持所有出行模式(驾车、步行、公交)。
方案2:Roads API + 反向地理编码(高精度驾车路线专属)
如果是跨国家的乡村驾车路线,原始路径点可能落在野外,反向地理编码容易误判。这时候用Roads API的snappedToRoads把路径点对齐到道路上,再查国家就准多了:
核心步骤
- 用DirectionsService获取路线的
overview_path(精简版路径); - 把路径点传给Roads API,获取对齐到道路的精准坐标;
- 再用方案1的批量反向地理编码逻辑处理这些对齐后的点。
代码片段(关键部分)
async function getSnappedRouteCountries(origin, destination) { const routeRes = await directionsService.route({ origin, destination, travelMode: google.maps.TravelMode.DRIVING }); const overviewPath = routeRes.routes[0].overview_path; // 把路径点转成API要求的格式:"lat1,lng1|lat2,lng2..." const pathStr = overviewPath.map(p => `${p.lat()},${p.lng()}`).join('|'); // 调用Roads API(记得替换成你的API密钥) const roadsRes = await fetch(`https://roads.googleapis.com/v1/snapToRoads?path=${pathStr}&interpolate=true&key=YOUR_API_KEY`); const roadsData = await roadsRes.json(); // 提取对齐后的道路点 const snappedPoints = roadsData.snappedPoints.map(p => ({ lat: p.location.latitude, lng: p.location.longitude })); // 接下来用方案1的批量反向地理编码处理这些点... const countrySet = new Set(); // ... 省略批量处理逻辑,和方案1一致 return Array.from(countrySet); }
优势说明
- 解决野外路径点的误判问题,精度拉满;
- 适合需要极高准确性的货运、自驾导航类场景。
方案3:边界检测+候选验证(长距离路线优化)
如果是跨大洲的超长路线,前面的方法还是会有不少请求。这时候可以先缩小候选国家范围,再验证路线是否经过这些国家:
- 步骤拆解:
- 获取路线的边界框(
route.routes[0].bounds); - 在边界框内取几个关键点(比如四角+中心),反向地理编码得到候选国家列表;
- 用Google Maps Geometry库的
polyline.intersects方法,检查路线是否穿过每个候选国家的边界多边形(通过Places API获取国家的完整边界)。
- 获取路线的边界框(
注意事项
- 需要用到Places API获取国家的边界数据,需要额外申请权限;
- 适合跨大洲的超长路线,能把请求数降到个位数。
通用小贴士
- API配额控制:批量请求时一定要控制速率,Google Maps API有每秒请求限制,建议加个延时或者用指数退避;
- 优先用ISO代码:国家名称有多语言版本,用ISO 3166-1 alpha-2代码(比如CN、US)去重和存储最可靠;
- 异常处理:要处理路线不存在、API请求失败、某些点无法识别国家的情况。
内容的提问来源于stack exchange,提问作者David Czuchnowski
相关产品推荐
相关产品推荐

