Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fit Bounds in Google Map Render Directions

I am trying to render directions for 48 waypoints, but google only allows 8 waypoints to be rendered per request. so I do multiple requests (in my case 6). However, the API somehow doed fitBounds() for the last request.

How can I show all the 48 waypoints in one map using fitBounds() and/or setZoom()

My code is as below: -

function DisplayDirection(directionList){

    var interval = 8; // upper bound for usage limits in google directions API is 8
    var startIndex =0;
    var maxmimumIndex = directionList.length-1; // Total number of waypoints in this route
    var partialEndIndex = interval-1; // end waypoint at start
    var iteration = 0; // loop controler
    directionsService = new google.maps.DirectionsService();
    var resultSet = new Array();
    var directionsDisplayList = new Array();
    var resultsCached = 0;
    var bounds = new google.maps.LatLngBounds();

    do { //do...while to iterate over multiple requests
        iteration++;
        if(iteration>1){
            startIndex = startIndex+interval;
            partialEndIndex = startIndex+interval;
        }

        var directionsDisplay = new google.maps.DirectionsRenderer({
                markerOptions: {
                    visible:false
                }      
            });
        directionsDisplayList.push(
            directionsDisplay
        ); 

        directionsDisplayList[iteration-1].setMap(map);

        var origin = directionList[startIndex];
        var destination = partialEndIndex < maxmimumIndex ? directionList[partialEndIndex]:directionList[maxmimumIndex];
        waypoints = new Array();

        for(var i=startIndex+1;i<partialEndIndex;i++){
            if(i>maxmimumIndex){                
                break;
            }       

            waypoints.push(
                {
                    location:directionList[i],
                    stopover:true
                }
            );
            latlong = directionList[i].split(","); //
            lat = latlong[0];  //
            lng = latlong[1]; //
            bounds.extend (new google.maps.LatLng(lat,lng)); //extend the bounds            
        }

        var request = {
            origin: origin,
            destination: destination,
            waypoints : waypoints,
            provideRouteAlternatives:false,
            travelMode: google.maps.TravelMode.WALKING,
            unitSystem: google.maps.UnitSystem.METRIC
        }

        directionsService.route(request, function(result, status) {
            if(status == google.maps.DirectionsStatus.OK) {
                //Cashe the results to render directions//
                resultSet.push(result);                             
                if(resultSet.length==iteration){
                    for(var i=0; i<iteration; i++){
                        directionsDisplayList[i].setDirections(resultSet[i]);                                                           
                    }
                    map.fitBounds(bounds);                  
                }                   
            }           
        });

    }while (partialEndIndex <= maxmimumIndex);      
}
like image 556
user778930 Avatar asked Jan 24 '13 01:01

user778930


1 Answers

Use the preserveViewport option of the DirectionsRenderer to prevent the automatic zoom to the route, then set the viewport you like.

{preserveViewport: true}

Then combine the bounds returned in each individual directions result with google.maps.LatLngBounds.union

function DisplayDirection(directionList) {
  var interval = 8; // upper bound for usage limits in google directions API is 8
  var startIndex = 0;
  var maxmimumIndex = directionList.length - 1; // Total number of waypoints in this route
  var partialEndIndex = interval - 1; // end waypoint at start
  var iteration = 0; // loop controler
  directionsService = new google.maps.DirectionsService();
  var resultSet = new Array();
  var directionsDisplayList = new Array();
  var resultsCached = 0;
  var bounds = new google.maps.LatLngBounds();

  do { //do...while to iterate over multiple requests
    iteration++;
    if (iteration > 1) {
      startIndex = startIndex + interval;
      partialEndIndex = startIndex + interval;
    }

    var directionsDisplay = new google.maps.DirectionsRenderer({
      preserveViewport: true, // prevent auto zoom to result
      markerOptions: {
        visible: false
      }
    });
    directionsDisplayList.push(
      directionsDisplay
    );

    directionsDisplayList[iteration - 1].setMap(map);

    var origin = directionList[startIndex];
    var destination = partialEndIndex < maxmimumIndex ? directionList[partialEndIndex] : directionList[maxmimumIndex];
    waypoints = new Array();

    for (var i = startIndex + 1; i < partialEndIndex; i++) {
      if (i > maxmimumIndex) {
        break;
      }

      waypoints.push({
        location: directionList[i],
        stopover: true
      });
      latlong = directionList[i].split(","); //
      lat = latlong[0]; //
      lng = latlong[1]; //
      bounds.extend(new google.maps.LatLng(lat, lng)); //extend the bounds            
    }

    var request = {
      origin: origin,
      destination: destination,
      waypoints: waypoints,
      provideRouteAlternatives: false,
      travelMode: google.maps.TravelMode.WALKING,
      unitSystem: google.maps.UnitSystem.METRIC
    }

    directionsService.route(request, function(result, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        //Cashe the results to render directions//
        resultSet.push(result);
        if (resultSet.length == iteration) {
          // empty bounds
          var bounds = new google.maps.LatLngBounds();
          for (var i = 0; i < iteration; i++) {
            directionsDisplayList[i].setDirections(resultSet[i]);
            // combine all the bounds of the results together with union
            if (i == 0) {
              bounds = resultSet[i].routes[0].bounds;
            } else {
              bounds.union(resultSet[i].routes[0].bounds);
            }
          }
          // fit the map to the resulting bounds
          map.fitBounds(bounds);
        }
      }
    });

  } while (partialEndIndex <= maxmimumIndex);
}

proof of concept fiddle (with 51 points)

code snippet:

var geocoder;
var map;

function initialize() {
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 3,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  document.getElementById('info').innerHTML = "entries:" + directionList.length;
  DisplayDirection(directionList);
}
google.maps.event.addDomListener(window, "load", initialize);

function DisplayDirection(directionList) {
  var interval = 8; // upper bound for usage limits in google directions API is 8
  var startIndex = 0;
  var maxmimumIndex = directionList.length - 1; // Total number of waypoints in this route
  var partialEndIndex = interval - 1; // end waypoint at start
  var iteration = 0; // loop controler
  directionsService = new google.maps.DirectionsService();
  var resultSet = new Array();
  var directionsDisplayList = new Array();
  var resultsCached = 0;
  var bounds = new google.maps.LatLngBounds();

  do { //do...while to iterate over multiple requests
    iteration++;
    if (iteration > 1) {
      startIndex = startIndex + interval;
      partialEndIndex = startIndex + interval;
    }

    var directionsDisplay = new google.maps.DirectionsRenderer({
      preserveViewport: true,
      markerOptions: {
        visible: false
      }
    });
    directionsDisplayList.push(
      directionsDisplay
    );

    directionsDisplayList[iteration - 1].setMap(map);

    var origin = directionList[startIndex];
    var destination = partialEndIndex < maxmimumIndex ? directionList[partialEndIndex] : directionList[maxmimumIndex];
    waypoints = new Array();

    for (var i = startIndex + 1; i < partialEndIndex; i++) {
      if (i > maxmimumIndex) {
        break;
      }

      waypoints.push({
        location: directionList[i],
        stopover: true
      });
      latlong = directionList[i].split(","); //
      lat = latlong[0]; //
      lng = latlong[1]; //
      bounds.extend(new google.maps.LatLng(lat, lng)); //extend the bounds            
    }

    var request = {
      origin: origin,
      destination: destination,
      waypoints: waypoints,
      provideRouteAlternatives: false,
      travelMode: google.maps.TravelMode.WALKING,
      unitSystem: google.maps.UnitSystem.METRIC
    }

    directionsService.route(request, function(result, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        //Cashe the results to render directions//
        resultSet.push(result);
        if (resultSet.length == iteration) {
          var bounds = new google.maps.LatLngBounds();
          for (var i = 0; i < iteration; i++) {
            directionsDisplayList[i].setDirections(resultSet[i]);
            if (i == 0) {
              bounds = resultSet[i].routes[0].bounds;
            } else {
              bounds.union(resultSet[i].routes[0].bounds);
            }
          }
          map.fitBounds(bounds);
        }
      }
    });

  } while (partialEndIndex <= maxmimumIndex);
}
var directionList = [
  "52.1615470947258,20.80514430999756",
  "52.15991486090931,20.804049968719482",
  "52.15772967999426,20.805788040161133",
  "52.15586034371232,20.80460786819458",
  "52.15923693975469,20.80113172531128",
  "52.159849043774074, 20.791990756988525",
  "52.15986220720892,20.790467262268066",
  "52.16202095784738,20.7806396484375",
  "52.16088894313116,20.77737808227539",
  "52.15255590234335,20.784244537353516",
  "52.14747369312591,20.791218280792236",
  "52.14963304460396,20.79387903213501",
  "52.1704725, 20.8118862",
  "52.1845184, 20.8400429",
  "52.200343, 20.8274304",
  "52.2015168, 20.799051599999984",
  "52.18724, 20.76437569999996",
  "52.18032700000001, 20.75405180000007",
  "52.1716078, 20.743079899999998",
  "49.9636566, 20.1216374",
  "51.8484715, 20.9852811",
  "51.40272359999999, 21.14713329999995",
  "51.2464536, 22.5684463",
  "51.1431232, 23.47119859999998",
  "50.7230879, 23.251968",
  "50.5826005, 22.053585999999996",
  "50.0411867, 21.999119599999972",
  "50.0121011, 20.9858407",
  "49.6174535, 20.7153326",
  "49.4215158, 20.959420799999975",
  "49.0018324, 21.23931189999996",
  "48.7163857, 21.2610746",
  "48.0963631, 20.762385999999992",
  "47.9025348, 20.3772284",
  "47.1621355, 20.1824712",
  "47.497912, 19.04023499999994",
  "48.3061414, 18.076375999999982",
  "48.1485965, 17.1077477",
  "48.2081743, 16.3738189",
  "48.30694, 14.28583",
  "48.16542, 14.03664",
  "48.05009, 14.41827",
  "47.80949, 13.055",
  "47.8571272, 12.1181047",
  "48.1351253, 11.58198",
  "52.52000659999999, 13.404953999999975",
  "53.5510846, 9.99368179999999",
  "50.1109221, 8.6821267",
  "52.3702157, 4.895167899999933",
  "50.8503396, 4.3517103",
  "48.856614, 2.3522219"
];
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="info"></div>
<div id="map_canvas"></div>
like image 50
geocodezip Avatar answered Sep 23 '22 07:09

geocodezip