javascript for loop prints the same set of cities 5 times instead of 5 distinct sets of cities

advertisements

I have some javascript and html (below) I'm trying to loop through an array of cities and get the distance between each city using google maps API I got this working when I typed in two cities but when I hard coded in the array of 22 cities it displays the same set of cities each time, instead of each distinct set of two cities and the distance between them.

I'm guessing that this is related to timing and that the return from google's api is overwriting my variables somewhere but I can not figure out how to fix it.

Right now the loops are limited to 3 to save time while trouble shooting.

expected output: Rostock,Germany, Lubeck,Germany 200km Rostock, Hamburg 100km lubeck, Hamburg 50km hamburg, Rostock 210km

what I get: hamburg, Rostock 210km hamburg, Rostock 0km hamburg, Rostock 210km hamburg, Rostock 0km hamburg, Rostock 210km

what am I doing wrong?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <meta name="robots" content="noindex,follow" />
    <title>Calculate driving distance with Google Maps API</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7j_Q-rshuWkc8HyFI4V2HxQYPm-xtd00hTQOC0OXpAMO40FHAxT29dNBGfxqMPq5zwdeiDSHEPL89A" type="text/javascript"></script>
    <!-- According to the Google Maps API Terms of Service you are required display a Google map when using the Google Maps API. see: http://code.google.com/apis/maps/terms.html -->
    <script type="text/javascript">

   // var geocoder, location1, location2, gDir;

//city array
var cities = ["Rostock,Germany",
"Lubeck,Germany",
"Hamburg,Germany",
"Bremen,Germany",
"Hannover,Germany",
"Kassel,Germany",
"Dusseldorf,Germany",
"Koln,Germany",
"St. Augustine,Germany",
"Bonn,Germany",
"Wiesbaden,Germany",
"Frankfurt,Germany",
"Mannheim,Germany",
"Karlsruhe,Germany",
"Baden Baden,Germany",
"Stuttgart,Germany",
"Munich,Germany",
"Nurnberg,Germany",
"Dresden,Germany",
"Leipzig,Germany",
"Berlin,Germany",
"Basel,switzerland"];

    function initialize() {
        geocoder = new GClientGeocoder();
        gDir = new GDirections();
        GEvent.addListener(gDir, "load", function() {
            var drivingDistanceMiles = gDir.getDistance().meters / 1609.344;
            var drivingDistanceKilometers = gDir.getDistance().meters / 1000;
            document.getElementById('results').innerHTML = document.getElementById('results').innerHTML+ location1.address+";  "+location2.address+" "+ drivingDistanceKilometers + ' km</br>';
        });
    }

    function getDistance(i,j){
        geocoder.getLocations(cities[i], function (response) {

                    if (!response || response.Status.code != 200)
                    {
                        alert("Sorry, we were unable to geocode the first address");
                    }
                    else
                    {
                        location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                        geocoder.getLocations(cities[j], function (response) {
                            if (!response || response.Status.code != 200)
                            {
                                alert("Sorry, we were unable to geocode the second address"+j);
                            }
                            else
                            {
                                //alert("i "+i+"  "+cities[i]+";    j "+j+"  "+cities[j]);
                                location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
                                gDir.load('from: ' + location1.address + ' to: ' + location2.address);

                            }
                        });
                    }
                });
    }

    function showLocation() {
        for(var i=0; i<3; i++){  //adjust loop to match array !!!!!!!!!!!!
            for(var j=0; j<3; j++){
                var geocoder, location1, location2, gDir;
                if(cities[i]==cities[j]){}
                else{   

                    initialize()
                    getDistance(i,j);
                }
            }
        }

    }
//<body onload="initialize()">
    </script>
</head>

<body >

    <form action="#" onsubmit="showLocation(); return false;">
        <p>
            <input type="text" name="address1" value="Address 1" />
            <input type="text" name="address2" value="Address 2" />
            <input type="submit" value="Search" />
        </p>
    </form>
    <p id="results"></p>

</body>
</html>


You put some things in the for-loop that only have to be done once. initialize() should obviously be called only once.

My code is (something like) what you are trying to do. Notice this: for(var j=i; ... What j=i does, is so you don't calculate the distance twice (example: Rostock-Lubeck and Lubeck-Rostock).

1 big problem: Google doesn't like it when you send many directionsService requests at a short time. Where I'm testing, Google stops after 10 requests. Maybe a delay between requests could solve this (I have to check).

<script type="text/javascript">
  //city array
  var cities = ["Rostock,Germany", "Lubeck,Germany", "Hamburg,Germany", "Bremen,Germany", "Hannover,Germany", "Kassel,Germany", "Dusseldorf,Germany", "Koln,Germany", "St. Augustine,Germany", "Bonn,Germany", "Wiesbaden,Germany", "Frankfurt,Germany", "Mannheim,Germany", "Karlsruhe,Germany", "Baden Baden,Germany", "Stuttgart,Germany", "Munich,Germany", "Nurnberg,Germany", "Dresden,Germany", "Leipzig,Germany", "Berlin,Germany", "Basel,switzerland"];
  var directionsService;

  function initialize() {
    directionsService = new google.maps.DirectionsService();
  }
  // Let directionsService calculate the distance between two cities.
  function getDistance(i, j) {
    var request = {
      origin: cities[i],
      destination: cities[j],
      travelMode: google.maps.TravelMode.DRIVING
    };
    var location1 = cities[i];
    var location2 = cities[j];
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        var distance = 0;
        for(var i=0; i<response.routes[0].legs.length; ++i) {
          distance += response.routes[0].legs[i].distance.value;
        }
        //var drivingDistanceMiles = gDir.getDistance().meters / 1609.344;
        var drivingDistanceKilometers = distance / 1000;
        document.getElementById('results').innerHTML += location1 + ";  " + location2  +" " + drivingDistanceKilometers + ' km</br>';
      }
    });
  }
  function showDistances() {
    // loop over all cities.  Skip directions between twice the same city
    for(var i=0; i<5 && i<cities.length; i++) {
      for(var j=i; j<5 && j<cities.length; j++) {
        if(i==j) {
          // skip
        }
        else {
          getDistance(i,j);
        }
      }
    }
  }
</script>

...

<body  onload="initialize()">
  <form action="#" onsubmit="showDistances(); return false;">

...