简体   繁体   English

使用Google Maps API js时无法访问全局变量

[英]not able to access global variable while using google maps api js

In the below code, I am not able to access the value of variable distances . 在下面的代码中,我无法访问可变距离的值。 I think that is because of asynchronous call directionsService.route . 我认为这是因为异步调用directionsService.route How can I get the value variable distances ? 如何获得值可变距离?

  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);

Edit: I have updated complete code. 编辑:我已经更新了完整的代码。 What I am trying to do : I have fixed start point and some waypoints (order not fixed), I am trying to optimize waypoints, my end point is not fixed, it can be any so that to optimize the path, but it is necessary to provide end point while calling directionsService.route method , so I am taking one of the waypoints as end point and keeping rest other in waypoints only and then calculating total distance of the route. 我正在尝试做的事情:我有固定的起点和一些航路点(顺序不固定),我在尝试优化航路点,我的终点不是固定的,可以是优化路径的任意方式,但是这是必要的在调用directionsService.route方法时提供终点,因此我将其中一个航点作为终点,并仅在航点中保持其他休息,然后计算路线的总距离。 So each of the waypoint will become end point one by one , and others will remain waypoint. 因此,每个航路点将一个接一个地成为终点,其他航路点将保持为航点。 I will calculate total distance of all the combinations and then I will show only the directions of the route which has minimum distance. 我将计算所有组合的总距离,然后仅显示距离最小的路线的方向。

I would avoid calling asynchronous functions from inside a loop. 我会避免从循环内部调用异步函数。 It can be a pain keeping track of everything. 跟踪所有内容可能会很痛苦。

From what I understand of the question you are trying to find the shortest route with an arbitrary number of destinations. 据我对问题的了解,您正在尝试找到目的地数量任意的最短路线。 Instead of looping through each waypoint, pass the starting address and all of the destinations to the DistanceMatrix service which returns all of the route lengths from the origin to each waypoint. 无需遍历每个航路点,而是将起始地址和所有目的地传递给DistanceMatrix服务,该服务将返回从起点到每个航路点的所有路线长度。 When the results return sort from shortest to longest. 结果返回时,从最短到最长排序。 The longest destination will be the end address. 最长的目的地将是结束地址。 Then pass the start address, end address, and remaining waypoints to the DirectionService with the optimizeWaypoints turned on. 然后,在打开optimizeWaypoints将开始地址,结束地址和其余航路点传递给DirectionService

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

Relavent Code: 相关代码:

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);

The request is asynchronous. 该请求是异步的。

You have got to wait until the request completes before you check your global variable. 您必须等到请求完成后才能检查全局变量。

See this answer Is there any way to wait until the DirectionsService returns results? 查看此答案是否有任何方法可以等到DirectionsService返回结果?

EDIT If you really in a fix you can try making a Synchronous call with 编辑如果您确实在修复中,则可以尝试与进行同步调用

jQuery.ajaxSetup({async:false});

making sure you turn it on again after the method completes 确保在方法完成后再次将其打开

jQuery.ajaxSetup({async:true});

This comes with huge warning however as it can cause your browser to lock up use with caution 但是,这会带来巨大的警告,因为它可能会导致您的浏览器谨慎锁定使用

Your alert is firing before the callback has been fired. 在触发回调之前,您的警报正在触发。 I'd suggest you create another function and call that from your directionsService.route success callback eg 我建议您创建另一个函数,然后从directionsService.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
 }

You could then also remove the global variable and actually pass it into the afterComplete function, thus eliminating the need for a global (unless of course it is needed elsewhere) 然后,您还可以删除全局变量,然后将其实际传递到afterComplete函数中,从而消除了对全局变量的需求(当然,除非在其他地方需要它)

The DirectionsService is asynchronous. DirectionsService是异步的。 You need to use the results inside the call back function: 您需要在回调函数中使用结果:

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);
      }
    });
  }

The global variable will be available after the data comes back from the server and the callback function finishes running. 从服务器返回数据并且回调函数完成运行之后 ,全局变量将可用。 If you need to do something with it once it is available, do that in the call back function. 如果您需要对它进行一些处理,请在回调函数中执行此操作。

example

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM