-1

I'm trying to generate a Route with Google Directions API. Generating the Route is not the problem, but I`d like to load the Route points by limiting the route in 9 hours or (32.400 secs)

I tried putting it inside a While (Loop), the process calculates the time but an error occurs in processing the Directions API (Query Over limit) Does anyone have any ideas ?

My code...

(function ($) {
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;

var zoomLevel = 16;
var idInfoBoxAberto;
var infoBox = [];
Markers = [];
cor = '#0586e7';
indice = {};
customers = new Array();

var loc = ' - São Paulo,';  // Define location
var registros = 1;

function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer({ suppressMarkers: true });

    var sp = new google.maps.LatLng(-23.6492, -46.6600);  // Define center map (SP- Brasil)

    var myOptions = {
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center: sp,
        disableDefaultUI: true,
        styles: [{ "stylers": [{ "saturation": -100 }, { "gamma": 1 }] }, { "elementType": "labels.text.stroke", "stylers": [{ "visibility": "off" }] }, { "featureType": "poi.business", "elementType": "labels.text", "stylers": [{ "visibility": "off" }] }, { "featureType": "poi.business", "elementType": "labels.icon", "stylers": [{ "visibility": "off" }] }, { "featureType": "poi.place_of_worship", "elementType": "labels.text", "stylers": [{ "visibility": "off" }] }, { "featureType": "poi.place_of_worship", "elementType": "labels.icon", "stylers": [{ "visibility": "off" }] }, { "featureType": "road", "elementType": "geometry", "stylers": [{ "visibility": "simplified" }] }, { "featureType": "water", "stylers": [{ "visibility": "on" }, { "saturation": 50 }, { "gamma": 0 }, { "hue": "#50a5d1" }] }, { "featureType": "administrative.neighborhood", "elementType": "labels.text.fill", "stylers": [{ "color": "#333333" }] }, { "featureType": "road.local", "elementType": "labels.text", "stylers": [{ "weight": 0.5 }, { "color": "#333333" }] }, { "featureType": "transit.station", "elementType": "labels.icon", "stylers": [{ "gamma": 1 }, { "saturation": 50 }] }]
    };

    map = new google.maps.Map(document.getElementById("google-map"), myOptions);
    directionsDisplay.setMap(map);

    calcRoute(' - São Paulo,');
}

initialize();

function calcRoute(loc) {

    $.getJSON('http://dbtraining.com.br/startup/app/maps/rota/' + loc, function (pontos) {
        var RouteIndex = pontos[0].rota;
        //console.log(RouteIndex);

        $.each(pontos, function (index, ponto) {

            if (RouteIndex != ponto.rota) {
                RouteIndex = ponto.rota;
                cor = getRandomColor();
            }

            customers[registros] = {
                "id": ponto.id,
                "cliente": ponto.Cliente,
                "endereco": ponto.endereco,
                "territorio": ponto.Territorio,
                "rota": ponto.rota,
                "distance": ponto.distance,
                "color": cor,
                "lat": ponto.lat,
                "lng": ponto.lng
            };
            registros++;
        });

        //Sort array by Distance
        customers.sort(function (a, b) {
            return (a.distance > b.distance) ? 1 : ((b.distance > a.distance) ? -1 : 0);
        });

        var start = new google.maps.LatLng(customers[0].lat, customers[0].lng);
        var end = new google.maps.LatLng(customers[0].lat, customers[0].lng);

        var waypts = [];
        var i = 1;

        var distance = 0;
        var time = 0;
        var totaltime = 0;

        // Load Waypoints.
        while (i < 20) {
            waypts.push({ location: customers[i].endereco, stopover: true });


            var request = {
                origin: start,
                destination: end,
                waypoints: waypts,
                optimizeWaypoints: true,
                travelMode: google.maps.DirectionsTravelMode.WALKING
            };

            directionsService.route(request, function (response, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    directionsDisplay.setDirections(response);

                    var route = response.routes[0];

                    for (var i = 0; i < route.legs.length; i++) {
                        var theLeg = route.legs[i];

                        var marker = new google.maps.Marker({
                            id: i,
                            position: route.legs[i].start_location,
                            map: map,
                            title: "Stop number: " + i,
                            icon: '../img/markers/marker.png',
                            label: {
                                text: i.toString()
                            }
                        });

                        attachInfoWindow(marker, i, route.legs[i]);

                        time = theLeg.duration.value ;
                        totaltime += time + 5400;

                        console.log("ID.............: " + getKey(customers, "endereco", "R. Herculano de Freitas, 85 - Bela Vista, São Paulo - SP, 01308-020, Brasil"));
                        console.log("Start..........: " + theLeg.start_address);
                        console.log("Destination....: " + theLeg.end_address);
                        console.log("Location.......: " + theLeg.start_location.lat() + "," + theLeg.start_location.lng());
                        console.log("Distance.......: " + theLeg.distance.text);
                        console.log("Travel time....: " + secondsToTime(theLeg.duration.value));
                        console.log("Service time...: " + secondsToTime(5400));
                        console.log(totaltime);
                        console.log("------------------------------");

                    }

                    if (totaltime >= 32000) {
                        break; // break While Loop
                    }

                } else {
                    alert("directions response " + status);
                }
            });

            sleep(1000);
            i++;
        }
    }); //end getJSON
}




function secondsToTime(secs) {
    secs = Math.round(secs);
    var hours = Math.floor(secs / (60 * 60));

    var divisor_for_minutes = secs % (60 * 60);
    var minutes = Math.floor(divisor_for_minutes / 60);

    var divisor_for_seconds = divisor_for_minutes % 60;
    var seconds = Math.ceil(divisor_for_seconds);

    var t = hours + ":" + minutes + ":" + seconds;

    return t;
}

function sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > milliseconds) {
            break;
        }
    }
}

function getRandomColor() {
    var length = 6;
    var chars = '0123456789ABCDEF';
    var hex = '#';
    while (length--) hex += chars[(Math.random() * 16) | 0];
    return hex;
}

function attachInfoWindow(marker, legIndex, leg) {
    var infowindow = new google.maps.InfoWindow({
        content: "<div><h3>Stop Number: " + legIndex + "</h3><p>" + leg.start_address + "</p><a href='#'>(Stop Details)</a></div>"
    });
    google.maps.event.addListener(marker, 'click', function () { //when the marker on map is clicked open info-window
        infowindow.open(map, marker);
        console.log(marker.get("id"));
    });

}

function getKey(obj, prop, val) {
    var keys = [];
    for (var key in obj) {
        if (obj[key].hasOwnProperty(prop) && obj[key][prop] === val) {
            keys.push(key);
        }
    }
    return keys;
}

function dynamicSort(property) {
    var sortOrder = 1;
    if (property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a, b) {
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

})(window.jQuery);

2 Answers2

0

I didn't read complete, but:

// Load Waypoints.
    while (i < 20)
    ...

can not work because the direction service is limited to 8 waypoints in one request. So you have to start a new request after reaching this limit or you request from point to point. If you search here for "multiple waypoints" you will find much examples for the solution.

ReFran
  • 757
  • 7
  • 14
  • When I load the Waypoints before calling the DirectionsService the route is processed without errors, but the time is much higher than my business rules. I know the DirectionsService is limited to up to 23 waypoints. My problem is: load a Waypoint, check the time, load another waypoint and check the time again until the time is equal to 32000 secs – Fabiano Santos Mar 22 '17 at 18:48
0

When I load the Waypoints before calling the DirectionsService the route is processed without errors, but the time is much higher than my business rules.

I know the DirectionsService is limited to up to 23 waypoints.

My problem is: load a Waypoint, check the time, load another waypoint and check the time again until the time is equal to 32000 secs

    // Load Waypoints.
       while (i < 20) {
       waypts.push({ location: customers[i].endereco, stopover: true });
       i++;
      }

Route with 20 waypoints

Link for jSon file: http://dbtraining.com.br/startup/app/maps/rota/sp

  • Maybe it is only a time problem. I think your sleep(1000) statement doesn't work. Have a look at this: http://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep – ReFran Mar 22 '17 at 20:18
  • The general calculation up to a time limit should be relativ simple. I would prefer to do it step by step without waypoints. I put a simple time calculation into my example (http://stackoverflow.com/questions/36023443/gmap-study-multi-auto-routes-direction-with-unlimited-waypoints-click-by-click). You may try if that click by click example works for you. If you want to have an example based on your needs, please state some lat, lons as csv values. Json would be some extra work. – ReFran Mar 22 '17 at 20:29