【问题标题】:change google.maps.DirectionsResult programmatically以编程方式更改 google.maps.DirectionsResult
【发布时间】:2015-08-16 17:56:01
【问题描述】:

当使用google.maps.DirectionsService 类时,将一些路点传递给它的请求,将获得一个 google.maps.DirectionsResult 对象,而该对象又可以使用google.maps.DirectionsRenderer 类显示在地图上。

默认情况下,指定的航点将显示为标记为 A、B、C 等的标记...

如果 DirectionsRenderer 配置为可拖动,则拖动这些航点标记将依次在 DirectionsRenderer 上触发 directions_changed,填充其 dragResult 属性,并最终更改基础路线。如果您正在显示,此更改会传播到包括说明面板在内的每个相关对象。

上述行为is shown in this example

我不知道如何以编程方式模拟这个拖动动作。我尝试过操作 DirectionsResult 对象并调用 DirectionsRenderer 对象的setDirections 方法,但这种操作往往会导致路线不一致。

例如,有时我的一个航点会陷入死胡同。

得到我的 DirectionsResult 对象后,我在它的每条腿上进行迭代。如果

  1. 给定腿的最后一步和
  2. 下一站的第一步

接近 180° 这意味着我必须返回,所以我想将该航路点更改为下一个合适的位置。我是这样做的:

var computeHeading=function(location1,location2) {
    return google.maps.geometry.spherical.computeHeading(location1,location2);
};

var legsArray = DirectionsResult.routes[0].legs;
for (var legIndex = 0; legIndex < legsArray.length - 1; legIndex++) {
    // Current leg
    var DirectionsLeg = legsArray[legIndex];

    // Last Step of current Leg
    var lastDirectionsStep = DirectionsLeg.steps.slice(-1)[0];

    // Next Leg
    var nextDirectionsLeg = legsArray[legIndex + 1];

    // First step of Next Leg
    var nextDirectionsStep = nextDirectionsLeg.steps[0];

    var lastHeading = computeHeading(lastDirectionsStep.start_location, lastDirectionsStep.end_location);
    var nextHeading = computeHeading(nextDirectionsStep.start_location, nextDirectionsStep.end_location);
    var theAngle = Math.abs(nextHeading-lastHeading);

    // Arbitrary threshold. If the angle is over 170 it's a deadend
    if(theAngle>170) {
        DirectionsLeg.steps.pop();
        DirectionsLeg.end_location = DirectionsLeg.steps.slice(-1)[0].end_location;

        nextDirectionsLeg.steps = nextDirectionsLeg.steps.slice(1);
        nextDirectionsLeg.start_location =nextDirectionsLeg.steps[0].start_location;
    }
}

事实证明,支路 0 的倒数第二个位置并不总是与支路 1 的第二个位置相匹配,因此 我在路线支路之间产生了不需要的间隙。手动拖动航点标记时不会发生这种情况:它设法保持路线连续性。

【问题讨论】:

  • @geocodezip 我添加了我的代码。小心删除downvote:/?

标签: javascript google-maps google-maps-api-3


【解决方案1】:

事实证明,拖动标记会触发对 Directions API 的一次或多次调用,这是我为了经济而试图避免的。所以我想,在从原始 DirectionsResult 修剪腿之后,我应该重新定义航路点并请求一条新路线。

var optimizeRoute=function(DirectionsResult) {

    var computeHeading=function(location1,location2) {
        return google.maps.geometry.spherical.computeHeading(location1,location2);
    };

    var legsArray = DirectionsResult.routes[0].legs;
    for (var legIndex = 0; legIndex < legsArray.length - 1; legIndex++) {
        // Current leg
        var DirectionsLeg = legsArray[legIndex];

        // Last Step of current Leg
        var lastDirectionsStep = DirectionsLeg.steps.slice(-1)[0];

        // Next Leg
        var nextDirectionsLeg = legsArray[legIndex + 1];

        // First step of Next Leg
        var nextDirectionsStep = nextDirectionsLeg.steps[0];

        var lastHeading = computeHeading(lastDirectionsStep.start_location, lastDirectionsStep.end_location);
        var nextHeading = computeHeading(nextDirectionsStep.start_location, nextDirectionsStep.end_location);
        var theAngle = Math.abs(nextHeading-lastHeading);

        // Arbitrary threshold. If the angle is over 170 it's a deadend
        if(theAngle>170 && theAngle<190) {
            DirectionsLeg.steps.pop();
            DirectionsLeg.end_location = DirectionsLeg.steps.slice(-1)[0].end_location;
            DirectionsResult.request.waypoints[legIndex].location = DirectionsLeg.end_location;
            DirectionsResult.needsReroute = true;
        }
    }

    return DirectionsResult;
}

之后,如果“优化的”DirectionsResult 的“needReroute”属性设置为 true,我会重新调用 google.maps.DirectionsService 类,这次使用第一个 DirectionsResult.request 作为我修改后的请求。

所以,假设我有一个接受请求并回调 DirectionsResult 的函数:

var getRoute=function(myRequest,callback) {

   var DirectionsService=new google.maps.DirectionsService();

   DirectionsService.route(myRequest, function(DirectionsResult, status) {

    if(status === google.maps.DirectionsStatus.OK) {

         var optimizedDirectionsResult=optimizeRoute(DirectionsResult);

         if(optimizedDirectionsResult.needsReroute) {
             getRoute(optimizedDirectionsResult.request, callback);
         } else {
             callback(optimizedDirectionsResult);
         }

     } else {
       console.warn('failed',status);
       callback(null);
     }

   });

};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多