2015-06-02 38 views
0

使用google.maps.DirectionsService類時,將某個路標傳遞給其請求,將獲得一個google.maps.DirectionsResult對象,該對象又可以使用google.maps.DirectionsRenderer類在地圖上顯示。以編程方式更改google.maps.DirectionsResult

指定航點會出現,在默認情況下,作爲標記物標記爲A,B,C等等...

如果的DirectionsRenderer被配置爲可拖動,拖航點的那些標記物將反過來觸發directions_changed上DirectionsRenderer,填充其dragResult財產,並最終改變基礎路線。如果您正在顯示它,則此更改將傳播到包括指令面板的每個相關對象。上述行爲is shown in this example

我不知道如何以編程方式模擬這種拖動動作。我嘗試過操作DirectionsResult對象並調用DirectionsRenderer對象的setDirections方法,但這種操作常常導致路由不一致。

例如,有時候我的一個航點會出現死角。

Waypoint on dead end

讓我的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的第二位置,所以我生成路線兩腿之間不必要的差距。手動拖動路標標記時不會發生這種情況:它會設法保持路線的連續性。

+0

@geocodezip我將自己的代碼。小心刪除downvote:/? – amenadiel

回答

0

事實證明,拖動標記會觸發一次或多次到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,讓我用第一DirectionsResult.request作爲對google.maps.DirectionsService類新的呼叫,這時候我的修改的請求。

所以,讓我們說我有這個功能,需要一個請求和回調一個的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); 
    } 

    }); 

};