7

I'm working with the project which has driver tracking module. I've lat/long in my database, I'm fetching it on date and username.

The current implementation is working fine with 10 lat/long approx. But when its having more number of lat/long it's just drawing path between first 10 points.

For others it gives a status of OVER_QUERY_LIMIT

As others suggested in this, I've to delay each request of direction service.

I've search a lot, but could not found any notable solution.

Here is my code.

var markers =   [{
    "Latitude": -33.7316000000,
    "Longitude": 151.0789000000
}, {
    "Latitude": -33.7316000000,
    "Longitude": 151.0788000000
}, {
    "Latitude": -33.7316000000,
    "Longitude": 151.0789000000
}, {
    "Latitude": -33.7316000000,
    "Longitude": 151.0789000000
}, {
    "Latitude": -33.7316000000,
    "Longitude": 151.0789000000
}, {
    "Latitude": -33.7247000000,
    "Longitude": 151.0859000000
}, {
    "Latitude": -33.7243000000,
    "Longitude": 151.0967000000
}, {
    "Latitude": -33.7198000000,
    "Longitude": 151.1062000000
}, {
    "Latitude": -33.7109000000,
    "Longitude": 151.1043000000
}, {
    "Latitude": -33.7029000000,
    "Longitude": 151.0992000000
}, {
    "Latitude": -33.7108000000,
    "Longitude": 151.1044000000
}, {
    "Latitude": -33.7186000000,
    "Longitude": 151.1101000000
}, {
    "Latitude": -33.7239000000,
    "Longitude": 151.1190000000
}, {
    "Latitude": -33.7313000000,
    "Longitude": 151.1253000000
}, {
    "Latitude": -33.7370000000,
    "Longitude": 151.1337000000
}, {
    "Latitude": -33.7438000000,
    "Longitude": 151.1409000000
}, {
    "Latitude": -33.7510000000,
    "Longitude": 151.1475000000
}, {
    "Latitude": -33.7584000000,
    "Longitude": 151.1537000000
}, {
    "Latitude": -33.7670000000,
    "Longitude": 151.1572000000
}, {
    "Latitude": -33.7732000000,
    "Longitude": 151.1652000000
}, {
    "Latitude": -33.7812000000,
    "Longitude": 151.1703000000
}, {
    "Latitude": -33.7869000000,
    "Longitude": 151.1788000000
}, {
    "Latitude": -33.7960000000,
    "Longitude": 151.1782000000
}, {
    "Latitude": -33.7987000000,
    "Longitude": 151.1796000000
}, {
    "Latitude": -33.8078000000,
    "Longitude": 151.1792000000
}, {
    "Latitude": -33.8169000000,
    "Longitude": 151.1794000000
}, {
    "Latitude": -33.8232000000,
    "Longitude": 151.1872000000
}, {
    "Latitude": -33.8245000000,
    "Longitude": 151.1979000000
}, {
    "Latitude": -33.8287000000,
    "Longitude": 151.2075000000
}, {
    "Latitude": -33.8378000000,
    "Longitude": 151.2071000000
}, {
    "Latitude": -33.8458000000,
    "Longitude": 151.2121000000
}, {
    "Latitude": -33.8546000000,
    "Longitude": 151.2092000000
}, {
    "Latitude": -33.8631000000,
    "Longitude": 151.2049000000
}, {
    "Latitude": -33.8720000000,
    "Longitude": 151.2028000000
}, {
    "Latitude": -33.8785000000,
    "Longitude": 151.2103000000
}, {
    "Latitude": -33.8841000000,
    "Longitude": 151.2018000000
}, {
    "Latitude": -33.8848000000,
    "Longitude": 151.1910000000
}, {
    "Latitude": -33.8860000000,
    "Longitude": 151.1802000000
}, {
    "Latitude": -33.8879000000,
    "Longitude": 151.1696000000
}, {
    "Latitude": -33.8881000000,
    "Longitude": 151.1587000000
}, {
    "Latitude": -33.8901000000,
    "Longitude": 151.1481000000
}, {
    "Latitude": -33.8860000000,
    "Longitude": 151.1384000000
}, {
    "Latitude": -33.8792000000,
    "Longitude": 151.1311000000
}, {
    "Latitude": -33.8720000000,
    "Longitude": 151.1244000000
}, {
    "Latitude": -33.8700000000,
    "Longitude": 151.1138000000
}, {
    "Latitude": -33.8687000000,
    "Longitude": 151.1031000000
}, {
    "Latitude": -33.8654000000,
    "Longitude": 151.0930000000
}, {
    "Latitude": -33.8624000000,
    "Longitude": 151.0828000000
}, {
    "Latitude": -33.8580000000,
    "Longitude": 151.0732000000
}, {
    "Latitude": -33.8550000000,
    "Longitude": 151.0629000000
}, {
    "Latitude": -33.8500000000,
    "Longitude": 151.0539000000
}, {
    "Latitude": -33.8439000000,
    "Longitude": 151.0459000000
}, {
    "Latitude": -33.8391000000,
    "Longitude": 151.0367000000
}, {
    "Latitude": -33.8344000000,
    "Longitude": 151.0273000000
}, {
    "Latitude": -33.8297000000,
    "Longitude": 151.0179000000
}, {
    "Latitude": -33.8271000000,
    "Longitude": 151.0073000000
}, {
    "Latitude": -33.8279000000,
    "Longitude": 150.9964000000
}, {
    "Latitude": -33.8234000000,
    "Longitude": 150.9869000000
}, {
    "Latitude": -33.8176000000,
    "Longitude": 150.9785000000
}, {
    "Latitude": -33.8171000000,
    "Longitude": 150.9677000000
}, {
    "Latitude": -33.8146000000,
    "Longitude": 150.9572000000
}, {
    "Latitude": -33.8122000000,
    "Longitude": 150.9467000000
}, {
    "Latitude": -33.8096000000,
    "Longitude": 150.9362000000
}, {
    "Latitude": -33.8064000000,
    "Longitude": 150.9261000000
}, {
    "Latitude": -33.8144000000,
    "Longitude": 150.9210000000
}, {
    "Latitude": -33.8232000000,
    "Longitude": 150.9183000000
}, {
    "Latitude": -33.8316000000,
    "Longitude": 150.9143000000
}, {
    "Latitude": -33.8366000000,
    "Longitude": 150.9053000000
}, {
    "Latitude": -33.8446000000,
    "Longitude": 150.9003000000
}]

var mapOptions = {
    center: new google.maps.LatLng(markers[0].Latitude, markers[0].Longitude),
    zoom: 10,
    scrollwheel: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};

var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);

var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();


for (i = 0; i < markers.length; i++) {
    var data = markers[i]
    var myLatlng = new google.maps.LatLng(data.Latitude, data.Longitude);
    lat_lng.push(myLatlng);
    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        title: data.title

    });

latlngbounds.extend(marker.position);
(function(marker, data) {
    google.maps.event.addListener(marker, "click", function(e) {

        var html = "<b>Test</b>";
        infoWindow.setContent(html);
        infoWindow.open(map, marker, html);
    });
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);


var iconsetngs = {
    path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};

//Initialize the Direction Service
var service = new google.maps.DirectionsService();


var polylineoptns = {
    strokeOpacity: 0.8,
    strokeWeight: 3,
    strokeColor: '#4986E7',

    map: map,
    icons: [{
        repeat: '600px', //CHANGE THIS VALUE TO CHANGE THE DISTANCE BETWEEN ARROWS
        icon: iconsetngs,
        offset: '100%'
    }]
};

//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length; i++) {
    if ((i + 1) < lat_lng.length) {
        var src = lat_lng[i];
        var des = lat_lng[i + 1];
        service.route({
            origin: src,
            destination: des,
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        }, function(result, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                //Initialize the Path Array
                var path = new google.maps.MVCArray();
                var poly = new google.maps.Polyline(polylineoptns);

                poly.setPath(path);

                for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                    path.push(result.routes[0].overview_path[i]);
                }
            }
        });

    }
} 

Here is the result.

enter image description here

I've tired to delay call of direction service in this way in forloop:

 setInterval(function() {

     var directionsRequest = {
         origin: src,
         destination: des,
         travelMode: google.maps.TravelMode.DRIVING
     };

     service.route(directionsRequest, function(result, status) {
         if (status === google.maps.DirectionsStatus.OK) {
             for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                 var path = new google.maps.MVCArray();
                 var poly = new google.maps.Polyline(polylineoptns);
                 poly.setPath(path);

            for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
                path.push(result.routes[0].overview_path[i]);
               }
             }
         } else {
             console.log(status)
         }
     })

 }, 1000);

But it also gives a same status!!

Community
  • 1
  • 1
Hina Khuman
  • 757
  • 3
  • 14
  • 41
  • Add an else case to let you know the status returned by the directions service when it isn't "OK" – geocodezip Mar 15 '17 at 07:30
  • Okay, let me add that. thanks! – Hina Khuman Mar 15 '17 at 07:31
  • @geocodezip: I've added else part and it gives me status `OVER_QUERY_LIMIT` and my map looks like: http://imgr.es/3O2Q – Hina Khuman Mar 15 '17 at 07:40
  • introduce time delay in for loop before service.route – Priyank Mehta Mar 15 '17 at 10:13
  • @PriyankMehta: can you please let me know how can I do it? I've tried but issues is not resolved. – Hina Khuman Mar 16 '17 at 08:39
  • @geocodezip: Can you please give a way to sorting out this issue? – Hina Khuman Mar 16 '17 at 10:00
  • Did you look for duplicates of your "new" question (how to handle `OVER_QUERY_LIMIT` responses from Google's services)? – geocodezip Mar 16 '17 at 10:39
  • @geocodezip: Yes, [that all are](http://stackoverflow.com/questions/14014074/google-maps-api-over-query-limit-per-second-limit) for "Geocode" not for direction service. And I didn't get [proper solution](http://stackoverflow.com/questions/29827891/add-many-routes-using-google-maps-directions-service-over-query-limit) – Hina Khuman Mar 16 '17 at 11:01

1 Answers1

14

I think you can easily find an answer and explanation in the official documentation of Maps JavaScript API:

https://developers.google.com/maps/documentation/javascript/usage

Service requests are rate-limited per user session, regardless of how many users share the same project. When you first load the service API, you are allocated an initial quota of requests. Once you use this quota, the API enforces rate limits on additional requests on a per-second basis. If too many requests are made within a certain time period, the API returns an OVER_QUERY_LIMIT response code. The per-session rate limit prevents the use of client-side services for batch requests. For batch requests, use the Maps API web services.

That means when you load the page you have an initial bucket of requests for directions service (I believe this is 10 requests), once you have used 10 initial requests you can execute only 1 request per second. So, you have to wait one second before execution of the each next directions request.

The code snippet might be something similar to

var delayFactor = 0;

function m_get_directions_route (request) {
    directions.route(request, function(result, status) {
        if (status === google.maps.DirectionsStatus.OK) {
            //Process you route here
        } else if (status === google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
            delayFactor++;
            setTimeout(function () {
                m_get_directions_route(request);
            }, delayFactor * 1000);
        } else {
            console.log("Route: " + status);
        }
    });
} 

for (var i = 0; i < lat_lng.length; i++) {
    if ((i + 1) < lat_lng.length) {
        var src = lat_lng[i];
        var des = lat_lng[i + 1];

        var request = {
            origin: src,
            destination: des,
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };

        m_get_directions_route (request);
    }
}

With this code ten requests will be executed immediately and following requests will be executed after 1, 2, 3, ... seconds.

xomena
  • 31,125
  • 6
  • 88
  • 117
  • 1
    When the path is broken between two markers what is the status of the response? Probably Google just cannot construct the route due to certain road segment's restrictions (e.g. one way roads, turn restrictions or closed roads, etc.). – xomena Mar 19 '17 at 11:44