2

在下面的代码中,我无法访问变量distances的值。我认为这是因为异步调用DirectionService.route。如何获得值可变距离?

  var totalDistance;
  var distances = new Array();
  var directionsDisplay;
  var directionsService = new google.maps.DirectionsService();
  var map;
  var start = "ABC XYZ";
  var end ; 
  var points = new Array("Location ABC", "Location PQR", "Location XYZ", "Location more", "And     Some other location");

  function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();
    var mapOptions = {
      center: new google.maps.LatLng(13.0604220, 80.2495830),
      zoom: 10,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      draggableCursor: "crosshair"
    }; 
    map = new google.maps.Map(document.getElementById("map-canvas"),
        mapOptions);
    directionsDisplay.setMap(map);
  }
  function calcRoute() {
  for(var j=0;j<points.length;j++)
  {

    end = points[j];
    var waypoints = new Array();
    for(var i=0; i<points.length;i++)
    {
      if(i!=j)
      {
      waypoints.push({location:points[i], stopover: true});
      }
    }
    var request = {
    origin: start,
    destination: end,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function(response, status) { 
    if (status == google.maps.DirectionsStatus.OK) {
      var route = response.routes[0];
      totalDistance = 0;
      for ( var i=0;i<route.legs.length;i++)
      {
        totalDistance+=route.legs[i].distance.value;
      }
      distances.push(totalDistance); 
      }
    });
  }
  /*Now I want my distances value to be accessed from here i.e outside for loop.*/
  /*So that I can compare all the distances obtained */
}
  google.maps.event.addDomListener(window, 'load', initialize);

编辑:我已经更新了完整的代码。 我正在尝试做的事情:我有固定的起点和一些航点(顺序不固定),我正在尝试优化航点,我的终点不是固定的,它可以是任何优化路径,但这是必要的在调用 directionService.route 方法时提供终点,因此我将其中一个航路点作为终点,仅在航路点中保留其他航路点,然后计算路线的总距离。所以每一个航路点都会一个接一个地成为终点,其他航路点仍然是航路点。我将计算所有组合的总距离,然后我将只显示距离最小的路线的方向。

4

4 回答 4

1

我会避免从循环内部调用异步函数。跟踪所有事情可能会很痛苦。

根据我对这个问题的理解,您正试图找到具有任意数量目的地的最短路线。不是遍历每个航路点,而是将起始地址和所有目的地传递给DistanceMatrix服务,该服务返回从起点到每个航路点的所有路线长度。当结果返回时从最短到最长排序。最长的目的地将是结束地址。然后将开始地址、结束地址和剩余的航路点传递给DirectionService打开optimizeWaypoints的。

演示:http: //jsfiddle.net/bryan_weaver/snYJ2/

相关代码:

var map;
var origin = "4100 Ashby Road, St. Ann, MO 63074"
var destinations = [
    "2033 Dorsett Village, Maryland Heights, MO 63043",
    "1208 Tamm Avenue, St. Louis, MO 63139",
    "1964 S Old Highway 94 St Charles, MO 63303"];
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();

function calculateDistances() {
    var service = new google.maps.DistanceMatrixService();
    service.getDistanceMatrix({
        origins: [origin], //array of origins
        destinations: destinations, //array of destinations
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }, callback);
}

function callback(response, status) {
    if (status != google.maps.DistanceMatrixStatus.OK) {
        alert('Error was: ' + status);
    } else {
        //we only have one origin so there should only be one row
        var routes = response.rows[0];               
        var sortable = [];
        var resultText = "Origin: <b>" + origin + "</b><br/>";
        resultText += "Possible Routes: <br/>";
        for (var i = routes.elements.length - 1; i >= 0; i--) {
            var rteLength = routes.elements[i].duration.value;
            resultText += "Route: <b>" + destinations[i] + "</b>, " 
                + "Route Length: <b>" + rteLength + "</b><br/>";
            sortable.push([destinations[i], rteLength]);
        }
        //sort the result lengths from shortest to longest.
        sortable.sort(function (a, b) {
            return a[1] - b[1];
        });
        //build the waypoints.
        var waypoints = [];
        for (j = 0; j < sortable.length - 1; j++) {
            console.log(sortable[j][0]);
            waypoints.push({
                location: sortable[j][0],
                stopover: true
            });
        }
        //start address == origin
        var start = origin;
        //end address is the furthest desitnation from the origin.
        var end = sortable[sortable.length - 1][0];
        //calculate the route with the waypoints        
        calculateRoute(start, end, waypoints);
        //log the routes and duration.
        $('#results').html(resultText);
    }
}

//Calculate the route of the shortest distance we found.
function calculateRoute(start, end, waypoints) {
    var request = {
        origin: start,
        destination: end,
        waypoints: waypoints,
        optimizeWaypoints: true,
        travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(result);
        }
    });
}

function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();
    var centerPosition = new google.maps.LatLng(38.713107, -90.42984);
    var options = {
        zoom: 12,
        center: centerPosition,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($('#map')[0], options);
    geocoder = new google.maps.Geocoder();
    directionsDisplay.setMap(map);
    calculateDistances();
}

google.maps.event.addDomListener(window, 'load', initialize);
于 2013-05-21T14:46:50.777 回答
0

请求是异步的。

在检查全局变量之前,您必须等到请求完成。

看到这个答案 有没有办法等到 DirectionsService 返回结果?

编辑如果您真的在修复中,您可以尝试使用

jQuery.ajaxSetup({async:false});

确保在方法完成后再次打开它

jQuery.ajaxSetup({async:true});

然而,这会带来巨大的警告,因为它可能会导致您的浏览器锁定使用 谨慎

于 2013-05-21T11:38:18.893 回答
0

您的警报在回调触发之前触发。我建议您创建另一个函数并从您的方向服务.route 成功回调中调用它,例如

 var totalDistance; /*Global Variable */
var distances = new Array();
var directionsService = new google.maps.DirectionsService();
/* Some request */
directionsService.route(request, function(response, status) { 
if (status == google.maps.DirectionsStatus.OK) {
 directionsDisplay.setDirections(response);
 var route = response.routes[0];
 totalDistance = 0;
 for ( var i=0;i<route.legs.length;i++)
 {
   totalDistance+=route.legs[i].distance.value;
 }
 distances.push(totalDistance);

 }
 afterComplete();// New function call moved outside for loop
 });
 function afterComplete(){
 alert(distances);  //Will display null
 }

然后,您还可以删除全局变量并将其实际传递给 afterComplete 函数,从而消除对全局变量的需要(当然,除非在其他地方需要它)

于 2013-05-21T11:42:20.927 回答
0

DirectionsService 是异步的。您需要在回调函数中使用结果:

function calcRoute() {
  for(var j=0;j<points.length;j++)
  {

    end = points[j];
    var waypoints = new Array();
    for(var i=0; i<points.length;i++)
    {
      if(i!=j)
      {
      waypoints.push({location:points[i], stopover: true});
      }
    }
    var request = {
    origin: start,
    destination: end,
    waypoints: waypoints,
    optimizeWaypoints: true,
    travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function(response, status) { 
      if (status == google.maps.DirectionsStatus.OK) {
        var route = response.routes[0];
        totalDistance = 0;
        for ( var i=0;i<route.legs.length;i++)
        {
          totalDistance+=route.legs[i].distance.value;
        }
        distances.push(totalDistance); 
      }
      else { alert("Distance Service request not successful:"+status); }
      if (distances.length == points.length){
        alert(distances);
      }
    });
  }

数据从服务器返回并且回调函数完成运行,全局变量将可用。如果您需要在它可用后对其进行处理,请在回调函数中执行此操作。

例子

于 2013-05-21T12:19:59.880 回答