You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps Directions API问题:获取带途经点及Leg信息的夏季短路线

解决Google Maps Directions API中stopover设置与夏季路线的冲突问题

我完全懂你现在的头疼点——既要拿到途经点对应的Leg分段信息,又得让API走那条只在夏季开放的短路线,这俩需求单独都能实现,放一起就卡壳了对吧?

咱们先理清楚问题根源:当你把stopover设为true时,API会把每个途经点当成必须停靠的站点,这时候它的优先级是确保能到达每个停靠点(哪怕绕路),直接忽略了departureTime指定的夏季开放路线;而stopover: false时,途经点只是引导路线的参考点,API会优先选最优的夏季短路线,但不会把路线拆分成对应的Leg段。

那怎么破?试试分两次请求API的方案,完美兼顾两个需求:

  • 第一步:用stopover: false请求一次,拿到正确的夏季短路线(包含途经点的实际路径);
  • 第二步:把这条路线的起点、途经点、终点拆成连续的点对,逐个请求API(每个请求都带上夏季的departureTime),这样就能得到每一段的Leg信息;
  • 最后把这些Leg信息合并,就能得到你想要的完整结果。

下面是调整后的代码,你可以直接测试:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<script type="text/javascript">
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var wptruefalse;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var myOptions = {
    zoom: 6,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  directionsDisplay.setMap(map);
  calcRoute();
}

function calcRoute() {
  var first = new google.maps.LatLng(61.84448683734486, 8.85223388671875);
  var second = new google.maps.LatLng(61.75298123367897, 9.078826904296875);
  var start = new google.maps.LatLng(61.484039,7.645798);
  var end = new google.maps.LatLng(61.944118091023746,7.97882080078125);
  
  // 第一步:先获取正确的夏季短路线(stopover=false)
  var initialRequest = {
    origin: start,
    destination: end,
    waypoints: [{location: first, stopover: false}, {location: second, stopover: false}],
    optimizeWaypoints: true,
    travelMode: google.maps.DirectionsTravelMode.DRIVING,
    drivingOptions: {
      departureTime: new Date("08/08/2018")
    },
  };
  
  directionsService.route(initialRequest, function (initialResponse, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      // 提取路线上的关键节点:起点 + 优化后的途经点 + 终点
      var route = initialResponse.routes[0];
      var waypointLocations = [];
      waypointLocations.push(route.legs[0].start_location);
      // 提取途经点的实际位置
      route.waypoint_order.forEach(function(idx) {
        waypointLocations.push(initialRequest.waypoints[idx].location);
      });
      waypointLocations.push(route.legs[0].end_location);
      
      // 第二步:分段请求获取每一段的Leg信息
      var allLegs = [];
      var currentIndex = 0;
      
      function fetchNextLeg() {
        if (currentIndex >= waypointLocations.length - 1) {
          // 所有Leg获取完成,合并并显示
          displayCombinedRoute(allLegs);
          return;
        }
        
        var segmentRequest = {
          origin: waypointLocations[currentIndex],
          destination: waypointLocations[currentIndex + 1],
          travelMode: google.maps.DirectionsTravelMode.DRIVING,
          drivingOptions: {
            departureTime: new Date("08/08/2018")
          },
        };
        
        directionsService.route(segmentRequest, function(segResponse, segStatus) {
          if (segStatus == google.maps.DirectionsStatus.OK) {
            allLegs.push(segResponse.routes[0].legs[0]);
            currentIndex++;
            fetchNextLeg();
          } else {
            alert("Segment request failed: " + segStatus);
          }
        });
      }
      
      fetchNextLeg();
    } else {
      alert("Initial directions response failed: " + status);
    }
  });
}

function displayCombinedRoute(allLegs) {
  // 构造合并后的路线对象,适配DirectionsRenderer
  var combinedRoute = {
    routes: [{
      legs: allLegs,
      overview_path: [],
      bounds: new google.maps.LatLngBounds()
    }]
  };
  
  // 合并overview_path和bounds
  allLegs.forEach(function(leg) {
    leg.steps.forEach(function(step) {
      combinedRoute.routes[0].overview_path = combinedRoute.routes[0].overview_path.concat(step.path);
    });
    combinedRoute.routes[0].bounds.extend(leg.start_location);
    combinedRoute.routes[0].bounds.extend(leg.end_location);
  });
  
  // 显示路线
  directionsDisplay.setDirections(combinedRoute);
  
  // 显示Leg信息
  var summaryPanel = document.getElementById("directions_panel");
  summaryPanel.innerHTML = "";
  for (var i = 0; i < allLegs.length; i++) {
    var routeSegment = i + 1;
    summaryPanel.innerHTML += "<b>Route Segment: " + routeSegment + "</b><br />";
    summaryPanel.innerHTML += allLegs[i].start_address + " to ";
    summaryPanel.innerHTML += allLegs[i].end_address + "<br />";
    summaryPanel.innerHTML += allLegs[i].distance.text + "<br /><br />";
  }
}

function doClick(myRadio) {
  // 这里我们固定用分阶段方案,不管stopover选择,因为要兼顾两个需求
  calcRoute();
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="float:left;width:70%;height:100%;"></div>
<div id="control_panel" style="float:right;width:30%;text-align:left;padding-top:20px">
  API Key is needed to test properly
  <form>
    <input type="radio" name="wpradio" onclick="doClick(this);" value="true" checked> True
    <input type="radio" name="wpradio" onclick="doClick(this);" value="false"> False
  </form>
  <div id="directions_panel" style="margin:20px;background-color:#FFEE77;"></div>
</div>
</body>
</html>

这个方案的核心是先用stopover: false锁定正确的夏季路线,再把路线拆分成小段单独请求,这样每一段都能返回对应的Leg信息,同时保证走的是夏季开放的道路。

内容的提问来源于stack exchange,提问作者Lesley Persyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:10:04