使用google.maps.DirectionsService类时,将一些航点传递给其请求,将获得一个google.maps.DirectionsResult对象,该对象可以使用google.maps.DirectionsRenderer类在地图上显示。
默认情况下,指定的航点将显示为标记为A,B,C等标记......
如果DirectionsRenderer配置为可拖动,则拖动这些航点标记将依次触发DirectionsRenderer上的directions_changed
,填充其dragResult
属性,并最终更改基础路线。如果要显示,此更改将传播到每个相关对象,包括指令面板。
我无法弄清楚如何以编程方式模拟此拖动操作。我已经尝试操纵DirectionsResult对象并调用DirectionsRenderer对象的setDirections
方法,但这种操作通常会导致路径不一致。
例如,有时我的一个航点落在死胡同上。
获取我的DirectionsResult对象后,我会迭代它的每一条腿。如果之间的角度
接近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 :(得分: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;
}
之后,如果&#34;优化&#34; DirectionsResult拥有物业&#34; needReroute&#34;设置为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);
}
});
};