0

I want to display optimize route for about 100 addresses on the Google maps. I have searched for that but Google gives only 8 addresses per request in free and 23 addresses in Paid API. Than I saw one website who is doing same thing using unlimited address and named "Route4Me".

The case is now I have all addresses's lati and longi in optimize manner. I just want to show a route using these data on Google maps.

This situation is not exact as to route from A to B in Google Maps. I want to map route more than 50 addresses in route on maps which thing google does not provide. So I want different solution.

can you please provide me a solution ?

Hardik Patel
  • 706
  • 5
  • 14
  • possible duplicate of [Google Maps API V3 : How show the direction from a point A to point B (Blue line)?](http://stackoverflow.com/questions/5959788/google-maps-api-v3-how-show-the-direction-from-a-point-a-to-point-b-blue-line). It isn't the _exact_ same, but they are asking the same concept. – bcdan Jul 10 '15 at 16:17
  • What are the 100 points? Possible duplicate of [Google Maps API to get bus route](http://stackoverflow.com/questions/15315347/google-maps-api-to-get-bus-route). The second example in that question shows how to make multiple directions requests and concatenate them together (but the solution is still subject to the quota and rate limit, don't know if that solution supports 100 points without adding code to deal with the query limit. – geocodezip Jul 15 '15 at 02:47
  • Looks like the approach in [Google Maps API to get bus route](http://stackoverflow.com/questions/15315347/google-maps-api-to-get-bus-route) will do 90 points before running into the query limit. – geocodezip Jul 15 '15 at 04:37

2 Answers2

2

This code (from one of the examples in Google Maps API to get bus route, will (for me) display 90 points without running into the query limit.

jQuery(function() {

  var map = new window.google.maps.Map(document.getElementById("map"));
  // new up complex objects before passing them around
  var directionsDisplay = new window.google.maps.DirectionsRenderer({
    suppressMarkers: true
  });
  var directionsService = new window.google.maps.DirectionsService();

  Tour_startUp(stops);

  window.tour.loadMap(map, directionsDisplay);
  window.tour.fitBounds(map);

  if (stops.length > 1) window.tour.calcRoute(directionsService, directionsDisplay, map);
});

function Tour_startUp(stops) {
  document.getElementById('info').innerHTML = "stops:" + stops.length + "<BR>";
  if (!window.tour) window.tour = {
    updateStops: function(newStops) {
      stops = newStops;
    },
    // map: google map object
    // directionsDisplay: google directionsDisplay object (comes in empty)
    loadMap: function(map, directionsDisplay) {
      var myOptions = {
        zoom: 13,
        center: new window.google.maps.LatLng(44.833050, -68.749900),
        mapTypeId: window.google.maps.MapTypeId.ROADMAP
      };
      map.setOptions(myOptions);
      directionsDisplay.setMap(map);
    },
    fitBounds: function(map) {
      var bounds = new window.google.maps.LatLngBounds();

      // extend bounds for each record
      jQuery.each(stops, function(key, val) {
        var myLatlng = new window.google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
        bounds.extend(myLatlng);
      });
      map.fitBounds(bounds);
    },
    calcRoute: function(directionsService, directionsDisplay, map) {
      var directionsDisplays = [];
      var batches = [];
      var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
      var itemsCounter = 0;
      var wayptsExist = stops.length > 0;

      while (wayptsExist) {
        var subBatch = [];
        var subitemsCounter = 0;

        for (var j = itemsCounter; j < stops.length; j++) {
          subitemsCounter++;
          subBatch.push({
            location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
            stopover: true
          });
          if (subitemsCounter == itemsPerBatch) break;
        }

        itemsCounter += subitemsCounter;
        batches.push(subBatch);
        wayptsExist = itemsCounter < stops.length;
        // If it runs again there are still points. Minus 1 before continuing to
        // start up with end of previous tour leg
        itemsCounter--;
      }

      // now we should have a 2 dimensional array with a list of a list of waypoints
      var combinedResults;
      var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
      var directionsResultsReturned = 0;

      for (var k = 0; k < batches.length; k++) {
        var lastIndex = batches[k].length - 1;
        var start = batches[k][0].location;
        var end = batches[k][lastIndex].location;

        // trim first and last entry from array
        var waypts = [];
        waypts = batches[k];
        waypts.splice(0, 1);
        waypts.splice(waypts.length - 1, 1);

        var request = {
          origin: start,
          destination: end,
          waypoints: waypts,
          travelMode: window.google.maps.TravelMode.DRIVING
        };
        (function(kk) {
          directionsService.route(request, function(result, status) {
            if (status == window.google.maps.DirectionsStatus.OK) {
              var unsortedResult = {
                order: kk,
                result: result
              };
              unsortedResults.push(unsortedResult);

              directionsResultsReturned++;

              if (directionsResultsReturned == batches.length) // we've received all the results. put to map
              {
                // sort the returned values into their correct order
                unsortedResults.sort(function(a, b) {
                  return parseFloat(a.order) - parseFloat(b.order);
                });
                var count = 0;
                for (var key in unsortedResults) {
                  if (unsortedResults[key].result != null) {
                    if (unsortedResults.hasOwnProperty(key)) {
                      if (count == 0) // first results. new up the combinedResults object
                        combinedResults = unsortedResults[key].result;
                      else {
                        // only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
                        // directionResults object, but enough to draw a path on the map, which is all I need
                        combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
                        combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);

                        combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
                        combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
                      }
                      count++;
                    }
                  }
                }
                directionsDisplay.setDirections(combinedResults);
                var legs = combinedResults.routes[0].legs;
                for (var i = 0; i < legs.length; i++) {
                  var markerletter = "A".charCodeAt(0);
                  markerletter += i;
                  markerletter = String.fromCharCode(markerletter);
                  createMarker(directionsDisplay.getMap(), legs[i].start_location, "marker" + i, "some text for marker " + i + "<br>" + legs[i].start_address, markerletter);
                }
                var i = legs.length;
                var markerletter = "A".charCodeAt(0);
                markerletter += i;
                markerletter = String.fromCharCode(markerletter);
                createMarker(directionsDisplay.getMap(), legs[legs.length - 1].end_location, "marker" + i, "some text for the " + i + "marker<br>" + legs[legs.length - 1].end_address, markerletter);
              }
            } else {
              document.getElementById('info').innerHTML += "failed[" + kk + "]:" + status + "<br>";
            }
          });
        })(k);
      }
    }
  };

}
var infowindow = new google.maps.InfoWindow({
  size: new google.maps.Size(150, 50)
});


function createMarker(map, latlng, label, html, color) {
  // alert("createMarker("+latlng+","+label+","+html+","+color+")");
  var contentString = '<b>' + label + '</b><br>' + html;
  var marker = new google.maps.Marker({
    position: latlng,
    map: map,
    title: label,
    zIndex: Math.round(latlng.lat() * -100000) << 5
  });
  marker.myname = label;

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(contentString);
    infowindow.open(map, marker);
  });
  return marker;
}

var stops = [{
    "Geometry": {
      "Latitude": 44.833050,
      "Longitude": -68.749900
    }
  }, {
    "Geometry": {
      "Latitude": 44.832950,
      "Longitude": -68.749930
    }
  }, {
    "Geometry": {
      "Latitude": 44.832960,
      "Longitude": -68.749140
    }
  }, {
    "Geometry": {
      "Latitude": 44.832860,
      "Longitude": -68.749130
    }
  }, {
    "Geometry": {
      "Latitude": 44.832800,
      "Longitude": -68.749730
    }
  }, {
    "Geometry": {
      "Latitude": 44.832730,
      "Longitude": -68.750410
    }
  }, {
    "Geometry": {
      "Latitude": 44.833130,
      "Longitude": -68.751080
    }
  }, {
    "Geometry": {
      "Latitude": 44.829890,
      "Longitude": -68.753860
    }
  }, {
    "Geometry": {
      "Latitude": 44.828530,
      "Longitude": -68.755060
    }
  }, {
    "Geometry": {
      "Latitude": 44.828260,
      "Longitude": -68.754960
    }
  }, {
    "Geometry": {
      "Latitude": 44.828160,
      "Longitude": -68.754830
    }
  }, {
    "Geometry": {
      "Latitude": 44.827990,
      "Longitude": -68.754750
    }
  }, {
    "Geometry": {
      "Latitude": 44.826670,
      "Longitude": -68.754470
    }
  }, {
    "Geometry": {
      "Latitude": 44.826310,
      "Longitude": -68.754480
    }
  }, {
    "Geometry": {
      "Latitude": 44.826070,
      "Longitude": -68.754570
    }
  }, {
    "Geometry": {
      "Latitude": 44.825570,
      "Longitude": -68.755010
    }
  }, {
    "Geometry": {
      "Latitude": 44.825380,
      "Longitude": -68.755350
    }
  }, {
    "Geometry": {
      "Latitude": 44.825280,
      "Longitude": -68.755570
    }
  }, {
    "Geometry": {
      "Latitude": 44.825250,
      "Longitude": -68.755610
    }
  }, {
    "Geometry": {
      "Latitude": 44.824140,
      "Longitude": -68.758790
    }
  }, {
    "Geometry": {
      "Latitude": 44.823260,
      "Longitude": -68.761360
    }
  }, {
    "Geometry": {
      "Latitude": 44.821690,
      "Longitude": -68.765580
    }
  }, {
    "Geometry": {
      "Latitude": 44.820390,
      "Longitude": -68.769330
    }
  }, {
    "Geometry": {
      "Latitude": 44.819820,
      "Longitude": -68.771040
    }
  }, {
    "Geometry": {
      "Latitude": 44.819550,
      "Longitude": -68.772200
    }
  }, {
    "Geometry": {
      "Latitude": 44.819520,
      "Longitude": -68.772390
    }
  }, {
    "Geometry": {
      "Latitude": 44.819480,
      "Longitude": -68.772730
    }
  }, {
    "Geometry": {
      "Latitude": 44.819450,
      "Longitude": -68.773040
    }
  }, {
    "Geometry": {
      "Latitude": 44.819380,
      "Longitude": -68.775300
    }
  }, {
    "Geometry": {
      "Latitude": 44.819250,
      "Longitude": -68.778010
    }
  }, {
    "Geometry": {
      "Latitude": 44.819070,
      "Longitude": -68.779150
    }
  }, {
    "Geometry": {
      "Latitude": 44.818900,
      "Longitude": -68.779830
    }
  }, {
    "Geometry": {
      "Latitude": 44.818710,
      "Longitude": -68.780390
    }
  }, {
    "Geometry": {
      "Latitude": 44.816720,
      "Longitude": -68.785180
    }
  }, {
    "Geometry": {
      "Latitude": 44.815730,
      "Longitude": -68.787300
    }
  }, {
    "Geometry": {
      "Latitude": 44.815340,
      "Longitude": -68.787870
    }
  }, {
    "Geometry": {
      "Latitude": 44.814670,
      "Longitude": -68.788620
    }
  }, {
    "Geometry": {
      "Latitude": 44.814030,
      "Longitude": -68.789150
    }
  }, {
    "Geometry": {
      "Latitude": 44.813780,
      "Longitude": -68.789320
    }
  }, {
    "Geometry": {
      "Latitude": 44.813000,
      "Longitude": -68.789820
    }
  }, {
    "Geometry": {
      "Latitude": 44.811730,
      "Longitude": -68.790720
    }
  }, {
    "Geometry": {
      "Latitude": 44.807740,
      "Longitude": -68.794450
    }
  }, {
    "Geometry": {
      "Latitude": 44.804550,
      "Longitude": -68.798370
    }
  }, {
    "Geometry": {
      "Latitude": 44.803410,
      "Longitude": -68.799800
    }
  }, {
    "Geometry": {
      "Latitude": 44.802590,
      "Longitude": -68.800500
    }
  }, {
    "Geometry": {
      "Latitude": 44.802480,
      "Longitude": -68.800570
    }
  }, {
    "Geometry": {
      "Latitude": 44.802380,
      "Longitude": -68.800630
    }
  }, {
    "Geometry": {
      "Latitude": 44.802180,
      "Longitude": -68.800750
    }
  }, {
    "Geometry": {
      "Latitude": 44.801970,
      "Longitude": -68.800850
    }
  }, {
    "Geometry": {
      "Latitude": 44.798600,
      "Longitude": -68.802040
    }
  }, {
    "Geometry": {
      "Latitude": 44.794100,
      "Longitude": -68.803590
    }
  }, {
    "Geometry": {
      "Latitude": 44.793830,
      "Longitude": -68.803700
    }
  }, {
    "Geometry": {
      "Latitude": 44.793670,
      "Longitude": -68.803780
    }
  },
  /* {
      "Geometry": {
          "Latitude": 44.793440,
              "Longitude": -68.803900
      }
  }, {
      "Geometry": {
          "Latitude": 44.793160,
              "Longitude": -68.804070
      }
  }, {
      "Geometry": {
          "Latitude": 44.792960,
              "Longitude": -68.804190
      }
  }, {
      "Geometry": {
          "Latitude": 44.792680,
              "Longitude": -68.804380
      }
  }, {
      "Geometry": {
          "Latitude": 44.792320,
              "Longitude": -68.804640
      }
  }, {
      "Geometry": {
          "Latitude": 44.786920,
              "Longitude": -68.808470
      }
  }, {
      "Geometry": {
          "Latitude": 44.786890,
              "Longitude": -68.808490
      }
  }, {
      "Geometry": {
          "Latitude": 44.786600,
              "Longitude": -68.808700
      }
  }, {
      "Geometry": {
          "Latitude": 44.786230,
              "Longitude": -68.808980
      }
  }, {
      "Geometry": {
          "Latitude": 44.786020,
              "Longitude": -68.809120
      }
  },  */
  {
    "Geometry": {
      "Latitude": 44.785640,
      "Longitude": -68.809400
    }
  }, {
    "Geometry": {
      "Latitude": 44.785180,
      "Longitude": -68.809770
    }
  }, {
    "Geometry": {
      "Latitude": 44.784990,
      "Longitude": -68.809940
    }
  }, {
    "Geometry": {
      "Latitude": 44.784450,
      "Longitude": -68.810470
    }
  }, {
    "Geometry": {
      "Latitude": 44.784270,
      "Longitude": -68.810680
    }
  }, {
    "Geometry": {
      "Latitude": 44.783960,
      "Longitude": -68.811040
    }
  }, {
    "Geometry": {
      "Latitude": 44.783750,
      "Longitude": -68.811310
    }
  }, {
    "Geometry": {
      "Latitude": 44.783530,
      "Longitude": -68.811570
    }
  }, {
    "Geometry": {
      "Latitude": 44.783400,
      "Longitude": -68.811740
    }
  }, {
    "Geometry": {
      "Latitude": 44.782900,
      "Longitude": -68.812470
    }
  }, {
    "Geometry": {
      "Latitude": 44.782760,
      "Longitude": -68.812680
    }
  }, {
    "Geometry": {
      "Latitude": 44.782620,
      "Longitude": -68.812900
    }
  }, {
    "Geometry": {
      "Latitude": 44.782450,
      "Longitude": -68.813150
    }
  }, {
    "Geometry": {
      "Latitude": 44.782340,
      "Longitude": -68.813350
    }
  }, {
    "Geometry": {
      "Latitude": 44.782230,
      "Longitude": -68.813570
    }
  }, {
    "Geometry": {
      "Latitude": 44.782020,
      "Longitude": -68.813980
    }
  }, {
    "Geometry": {
      "Latitude": 44.781840,
      "Longitude": -68.814370
    }
  }, {
    "Geometry": {
      "Latitude": 44.781790,
      "Longitude": -68.814490
    }
  }, {
    "Geometry": {
      "Latitude": 44.781640,
      "Longitude": -68.814810
    }
  }, {
    "Geometry": {
      "Latitude": 44.781540,
      "Longitude": -68.815080
    }
  }, {
    "Geometry": {
      "Latitude": 44.780980,
      "Longitude": -68.816730
    }
  }, {
    "Geometry": {
      "Latitude": 44.780470,
      "Longitude": -68.819040
    }
  }, {
    "Geometry": {
      "Latitude": 44.780370,
      "Longitude": -68.819630
    }
  }, {
    "Geometry": {
      "Latitude": 44.779180,
      "Longitude": -68.828500
    }
  }, {
    "Geometry": {
      "Latitude": 44.777820,
      "Longitude": -68.838660
    }
  }, {
    "Geometry": {
      "Latitude": 44.776430,
      "Longitude": -68.848970
    }
  }, {
    "Geometry": {
      "Latitude": 44.775570,
      "Longitude": -68.853390
    }
  }, {
    "Geometry": {
      "Latitude": 44.774960,
      "Longitude": -68.855750
    }
  }, {
    "Geometry": {
      "Latitude": 44.772540,
      "Longitude": -68.863700
    }
  }, {
    "Geometry": {
      "Latitude": 44.770830,
      "Longitude": -68.869140
    }
  }, {
    "Geometry": {
      "Latitude": 44.770790,
      "Longitude": -68.869270
    }
  }, {
    "Geometry": {
      "Latitude": 44.770750,
      "Longitude": -68.869400
    }
  }, {
    "Geometry": {
      "Latitude": 44.770040,
      "Longitude": -68.871710
    }
  }, {
    "Geometry": {
      "Latitude": 44.768590,
      "Longitude": -68.876700
    }
  }, {
    "Geometry": {
      "Latitude": 44.767780,
      "Longitude": -68.880520
    }
  }, {
    "Geometry": {
      "Latitude": 44.767660,
      "Longitude": -68.881240
    }
  }, {
    "Geometry": {
      "Latitude": 44.766610,
      "Longitude": -68.887230
    }
  }
];
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="info"></div>
<div id="map" style="border: 2px solid #3872ac;"></div>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
0

If you already have a pre-optimized list of 100 addresses stored in JSON data like this (as you say you do):

[
  {
    lat:36,
    lng:-80
  },
  {
    lat:37,
    lng:-81
  }
]

then you can use a loop to get the polylines between each of these locations using the Directions API, and then print the polylines to the map.

var map;
var director;

function initialize() {
  var mapOptions = {
    center: { lat: -34.397, lng: 150.644},
    zoom: 8
  };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  director = new google.maps.DirectionsService();
}
google.maps.event.addDomListener(window, 'load', initialize);

var json = [{lat:36, lng:-80}, {lat:37, lng:-81} ...... ]; //loaded using Ajax, copy and pasted to string, etc.
var pts = json.map(function(a){return new google.maps.LatLng(a.lat, a.lng0)});

var polylines = [];

function get(start, end, delay){
  setTimeout(function(){
    director.route({
      origin:start,
      destination:end,
      travelMode:google.maps.TravelMode.DRIVING //or whatever mode you want
    }, function(results, status){
      if(status === 'OK'){
        var routePts = []
        routePts = routePts.concat.apply(routePts, results[0].routes[0].legs[0].steps.map(function(a){return a.path}));
        polylines.push(new google.maps.Polyline({
          path:routePts,
          map:map
        }));
      }
    });
  }, delay);
}

function putToMap(){
  for(var i=0; i<pts.length-1; i++){
    get(pts[i], pts[i+1], i*200);
    var m = new google.maps.Marker({
      position:pts[i],
      map:map
    });
  }
  var m = new google.maps.Marker({
    position:pts[pts.length-1],
    map:map
  });
}

Hopefully this will be appropriately readable and streamlined enough to do what you want. If I am correct, you already have your points optimized, and stored in some sort of JSON. Since I do not know exactly how your JSON is configured, I gave a general example. It will need to be updated based on how yours is.

Essentially, what it does is take all the points, and get the directions for them after a timeout. For less time, you can integrate waypoints into this. I chose not to for demonstration purposes. It adds the route's polyline to the polylines array (for storage), and also draws it to the map. It also draws a marker to the map at the same time.

bcdan
  • 1,438
  • 1
  • 12
  • 25
  • I have tried to use your code but map is not generated. Can you please give me full code which you have in working mode ? – Hardik Patel Jul 17 '15 at 06:48
  • 1
    @HardikPatel You must have the right HTML tags. I expected that you would take the 5 minutes to adapt the code to your purposes, since you did not actually included code in your question. I will do it. – bcdan Jul 17 '15 at 11:30