Pages

Friday, October 21, 2011

Google Maps Eight Waypoints Limitation

Google maps DirectionsService (Google Maps API) has a eight waypoint limitation, so I needed to find how to map directions that had more than eight waypoints.

JQuery AJAX call that hit MS SQL Database, which returned a JSON string of waypoints.

Initialized a variable indicating the max waypoints allowed by Google DirectionsService: maxWayPts = 8;

A for loop handled the number of divisions, where an inner loop handled the maximum waypoints. The variable wpLength is the number of waypoints that was returned from the database.

for (var i = 0; i < wpLength; i++) {
    for (var j = i * maxWayPts; j < maxWayPts * (i + 1) - 1; j++)
 
    }
}

Initialized a oBounds object, which has two properties: origin and destination. The origin property holds the first waypoint and destination property holds the last waypoint.

Returned from database: JSON string – Array of objects put into oWayPts variable:



[
{
"title":"Starting Tour at BCT, Berea",
"descrip":"Official Starting Point: Berea Coffee and Tea, Bera KY",
"wayPoints":
[
{
"location":"Berea Coffee and Tea, Berea, KY",
"latLng": {"lat":37.572542,"lng":-84.288762},
"marker":null,
"zDate":"\/Date(1317960000000)\/"
},
{
"location":"Moran Mill Rd, KY",
"latLng":{"lat":37.603667,"lng":-84.347126},
"marker":null,"zDate":"\/Date(1317960000000)\/"
}
]


Initially, origin property is acquired by splicing from the waypoint array (oWayPts). oWayPts is an array of sting objects that was returned from the database.



var oBounds = {};
oBounds.origin = oWayPts.splice(0, 1);

Looping through, waypoints are pushed onto the wayPoints array and its elements are of type google.maps.DirectionsWaypoint. A forced break in the loop when at the end of the waypoints array (oWayPts).


for (var j = i * maxWayPts; j < maxWayPts * (i + 1) - 1; j++) {
    if (typeof oWayPts[j] === "undefined") {
        break;
    } else {
        wayPoints.push(
        {
            location: new google.maps.LatLng(oWayPts[j].latLng.lat, oWayPts[j].latLng.lng),
            stopover: false
        });
    }
}

After the looping through the inner for loop, the oBounds.destination property is set by splicing off the wayPoints array at its end. The oBounds.origin is set to the destination, which causes an overlapping of waypoints.



if (wayPoints.length > 0) {
    oBounds.destination = wayPoints.splice(wayPoints.length - 1, 1);
}

Now, the origin, destination, and waypoints are set. Now it is time to render using google.maps.DirectionsServices,render method, which a google.maps.DirectionsRequest is passed as a parameter. Below is the DirectionsRequest.



var directionsRequest = {
    travelMode: google.maps.DirectionsTravelMode.BICYCLING
}
directionsRequest.origin = new google.maps.LatLng(oBounds.origin[0].latLng.lat, oBounds.origin[0].latLng.lng);
 
/* 
Destination is of type waypoint. A waypoint consists of the following fields: •location (required) specifies the address of the waypoint. • stopover (optional) indicates whether this waypoint is a actual stop on the route (true) or instead only a preference to route through the indicated location (false). Stopovers are true by default.
------------------------------------ */
lat = oBounds.destination[0].location.lat();
lng = oBounds.destination[0].location.lng();
 
directionsRequest.destination = new google.maps.LatLng(lat, lng);
oBounds.origin = [{ latLng: { lat: lat, lng: lng}}];
 
directionsRequest.waypoints = wayPoints;

Now passing in the DirectionsRequest to DirectionsService.render method:


gMap.directionsService.route(directionsRequest, function (result, status) {
     if (status == google.maps.DirectionsStatus.OK) {
         gMap.renderPoints(result);
     }
 });



function renderPoints(arryResult) {
    var directionsRendererOpt = { map: map, suppressMarkers: true };
    var obj = document.getElementById("googleWritten");
    obj.innerHTML = "";
 
        var directionsRenderer = new google.maps.DirectionsRenderer(directionsRendererOpt);
        directionsRenderer.setPanel(obj);
        //Hold on to created overlay, so it could be removed from the map later.
        directionsRenders.push(directionsRenderer);
 
        directionsRenderer.setDirections(arryResult);
}

View a working example at deDogs

1 comment:

  1. Hola, no funciona el ejemplo, lo podrĂ­as poner On-line.

    ReplyDelete