web-dev-qa-db-fra.com

Dépasser 23 waypoints par limite de demande sur l'API Google Directions (niveau professionnel / professionnel)

J'aimerais utiliser l'API Google Directions pour développer un logiciel de planification d'itinéraire pour une entreprise qui gère les chasse-neige en hiver et l'aménagement paysager en été. L'une des exigences des clients est qu'il soit capable de calculer des itinéraires avec au moins 30 (de préférence plus) waypoints. Selon la documentation (citée ci-dessous), même les clients de Google Maps API for Work sont limités à seulement 23 waypoints par demande.

L'utilisation de l'API Google Directions est soumise à une limite de requêtes de 2 500 demandes de directions par jour. Les demandes de directions individuelles peuvent contenir jusqu'à 8 points de cheminement intermédiaires dans la demande. Les clients Google Maps API for Work peuvent interroger jusqu'à 100 000 demandes de directions par jour, avec jusqu'à 23 waypoints autorisés dans chaque demande.

Quelqu'un connaît-il une solution de contournement - de quelque manière que ce soit - pour contourner ce problème?

Aussi - pourrait-il être possible d'utiliser une solution de contournement pour l'API gratuite? J'entends que les premiers comptes sont assez chers.

Merci!! Marc

27
Marc H

Vous avez raison, le premier prix est plutôt cher à partir de 10 000 $, la dernière fois que j'ai parlé avec un représentant Google au téléphone.

J'ai trouvé une solution de contournement que j'ai mise en place pour contourner en quelque sorte la limitation des 8 points de cheminement. J'ai pu le faire fonctionner.

J'ai fait cela en recevant mes points de cheminement et en les divisant en différents itinéraires, mais en les rassemblant comme le même itinéraire.

Par exemple, s'il y avait 30 waypoints nécessaires, je dessinerais 4 lignes, mais avec la même couleur, etc. Donc, fondamentalement, vous coupez les waypoints en différentes routes en appelant le rendu des directions à chaque fois comme s'il s'agissait d'une route différente. La clé est après la première route que la route suivante doit commencer avec le dernier waypoint de la route précédente (cela garantit que les lignes de route sont connectées les unes aux autres)

Cela fonctionne, mais vous devez écrire beaucoup plus de code que ce que vous auriez si vous aviez un compte Premier, et vous demandez beaucoup plus de directions dans ce cas.

J'ai cherché et réfléchi à d'autres façons de le faire sans avoir de compte Premier et j'ai échoué.

Cependant, lorsque j'ai parlé à Google, ils ont dit qu'ils avaient l'intention de créer une structure de paiement à plusieurs niveaux pour les clients ayant des désirs/besoins différents. Par exemple, si un client a juste besoin de plus de waypoints et non pas d'un tas de demandes de direction supplémentaires.

J'espère que cela vous aidera, car cela a fonctionné pour moi dans une application pratique.

19
Bill Blankenship
function initMap() {
    var service = new google.maps.DirectionsService;
    var map = new google.maps.Map(document.getElementById('map'));

    // list of points
    var stations = [
        {lat: 48.9812840, lng: 21.2171920, name: 'Station 1'},
        {lat: 48.9832841, lng: 21.2176398, name: 'Station 2'},
        {lat: 48.9856443, lng: 21.2209088, name: 'Station 3'},
        {lat: 48.9861461, lng: 21.2261563, name: 'Station 4'},
        {lat: 48.9874682, lng: 21.2294855, name: 'Station 5'},
        {lat: 48.9909244, lng: 21.2295512, name: 'Station 6'},
        {lat: 48.9928871, lng: 21.2292352, name: 'Station 7'},
        {lat: 48.9921334, lng: 21.2246742, name: 'Station 8'},
        {lat: 48.9943196, lng: 21.2234792, name: 'Station 9'},
        {lat: 48.9966345, lng: 21.2221262, name: 'Station 10'},
        {lat: 48.9981191, lng: 21.2271386, name: 'Station 11'},
        {lat: 49.0009168, lng: 21.2359527, name: 'Station 12'},
        {lat: 49.0017950, lng: 21.2392890, name: 'Station 13'},
        {lat: 48.9991912, lng: 21.2398272, name: 'Station 14'},
        {lat: 48.9959850, lng: 21.2418410, name: 'Station 15'},
        {lat: 48.9931772, lng: 21.2453901, name: 'Station 16'},
        {lat: 48.9963512, lng: 21.2525850, name: 'Station 17'},
        {lat: 48.9985134, lng: 21.2508423, name: 'Station 18'},
        {lat: 49.0085000, lng: 21.2508000, name: 'Station 19'},
        {lat: 49.0093000, lng: 21.2528000, name: 'Station 20'},
        {lat: 49.0103000, lng: 21.2560000, name: 'Station 21'},
        {lat: 49.0112000, lng: 21.2590000, name: 'Station 22'},
        {lat: 49.0124000, lng: 21.2620000, name: 'Station 23'},
        {lat: 49.0135000, lng: 21.2650000, name: 'Station 24'},
        {lat: 49.0149000, lng: 21.2680000, name: 'Station 25'},
        {lat: 49.0171000, lng: 21.2710000, name: 'Station 26'},
        {lat: 49.0198000, lng: 21.2740000, name: 'Station 27'},
        {lat: 49.0305000, lng: 21.3000000, name: 'Station 28'},
    ];
    
    // Zoom and center map automatically by stations (each station will be in visible map area)
    var lngs = stations.map(function(station) { return station.lng; });
    var lats = stations.map(function(station) { return station.lat; });
    map.fitBounds({
        west: Math.min.apply(null, lngs),
        east: Math.max.apply(null, lngs),
        north: Math.min.apply(null, lats),
        south: Math.max.apply(null, lats),
    });
    
    // Show stations on the map as markers
    for (var i = 0; i < stations.length; i++) {
        if (!stations[i].name)
            continue;
        new google.maps.Marker({
            position: stations[i],
            map: map,
            title: stations[i].name
        });
    }

    // Divide route to several parts because max stations limit is 25 (23 waypoints + 1 Origin + 1 destination)
    for (var i = 0, parts = [], max = 8 - 1; i < stations.length; i = i + max)
        parts.Push(stations.slice(i, i + max + 1));

    // Callback function to process service results
    var service_callback = function(response, status) {
        if (status != 'OK') {
            console.log('Directions request failed due to ' + status);
            return;
        }
        var renderer = new google.maps.DirectionsRenderer;
        renderer.setMap(map);
        renderer.setOptions({ suppressMarkers: true, preserveViewport: true });
        renderer.setDirections(response);
    };
        
    // Send requests to service to get route (for stations count <= 25 only one request will be sent)
    for (var i = 0; i < parts.length; i++) {
        // Waypoints does not include first station (Origin) and last station (destination)
        var waypoints = [];
        for (var j = 1; j < parts[i].length - 1; j++)
            waypoints.Push({location: parts[i][j], stopover: false});
        // Service options
        var service_options = {
            Origin: parts[i][0],
            destination: parts[i][parts[i].length - 1],
            waypoints: waypoints,
            travelMode: 'WALKING'
        };
        // Send request
        service.route(service_options, service_callback);
    }
  }
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
#map {
    height: 100%;     
    width: 100%;
    height: 100%;
}
<div id="map"></div>

<!-- without API KEY set variable "max" to 8 -->
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>

<!-- with API KEY set variable "max" to 25 -->
<!-- <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap&key=YOUR_API_KEY"></script>-->

Avec le code suivant, vous pouvez utiliser autant de waypoints que vous en avez besoin et vous n'obtiendrez jamais d'erreur MAX_WAYPOINTS_EXCEEDED . N'oubliez pas de remplacer "YOUR_API_KEY" par votre clé API ou de supprimer & key = YOUR_API_KEY de l'URL de l'API Google et de définir la variable "max" sur 8 (max = 25 lorsque vous utilisez API KEY, max = 8 lorsque vous n'utilisez pas API KEY).

<style>
html, body { height: 100%; margin: 0; padding: 0; }
#map { height: 100%; width: 100%; height: 100%; }
</style>
<div id="map"></div>
<script>
  function initMap() {
    var service = new google.maps.DirectionsService;
    var map = new google.maps.Map(document.getElementById('map'));

    // list of points
    var stations = [
        {lat: 48.9812840, lng: 21.2171920, name: 'Station 1'},
        {lat: 48.9832841, lng: 21.2176398, name: 'Station 2'},
        {lat: 48.9856443, lng: 21.2209088, name: 'Station 3'},
        {lat: 48.9861461, lng: 21.2261563, name: 'Station 4'},
        {lat: 48.9874682, lng: 21.2294855, name: 'Station 5'},
        {lat: 48.9909244, lng: 21.2295512, name: 'Station 6'},
        {lat: 48.9928871, lng: 21.2292352, name: 'Station 7'},
        {lat: 48.9921334, lng: 21.2246742, name: 'Station 8'},
        {lat: 48.9943196, lng: 21.2234792, name: 'Station 9'},
        {lat: 48.9966345, lng: 21.2221262, name: 'Station 10'},
        {lat: 48.9981191, lng: 21.2271386, name: 'Station 11'},
        {lat: 49.0009168, lng: 21.2359527, name: 'Station 12'},
        {lat: 49.0017950, lng: 21.2392890, name: 'Station 13'},
        {lat: 48.9991912, lng: 21.2398272, name: 'Station 14'},
        {lat: 48.9959850, lng: 21.2418410, name: 'Station 15'},
        {lat: 48.9931772, lng: 21.2453901, name: 'Station 16'},
        {lat: 48.9963512, lng: 21.2525850, name: 'Station 17'},
        {lat: 48.9985134, lng: 21.2508423, name: 'Station 18'},
        {lat: 49.0085000, lng: 21.2508000, name: 'Station 19'},
        {lat: 49.0093000, lng: 21.2528000, name: 'Station 20'},
        {lat: 49.0103000, lng: 21.2560000, name: 'Station 21'},
        {lat: 49.0112000, lng: 21.2590000, name: 'Station 22'},
        {lat: 49.0124000, lng: 21.2620000, name: 'Station 23'},
        {lat: 49.0135000, lng: 21.2650000, name: 'Station 24'},
        {lat: 49.0149000, lng: 21.2680000, name: 'Station 25'},
        {lat: 49.0171000, lng: 21.2710000, name: 'Station 26'},
        {lat: 49.0198000, lng: 21.2740000, name: 'Station 27'},
        {lat: 49.0305000, lng: 21.3000000, name: 'Station 28'},
        // ... as many other stations as you need
    ];

    // Zoom and center map automatically by stations (each station will be in visible map area)
    var lngs = stations.map(function(station) { return station.lng; });
    var lats = stations.map(function(station) { return station.lat; });
    map.fitBounds({
        west: Math.min.apply(null, lngs),
        east: Math.max.apply(null, lngs),
        north: Math.min.apply(null, lats),
        south: Math.max.apply(null, lats),
    });

    // Show stations on the map as markers
    for (var i = 0; i < stations.length; i++) {
        new google.maps.Marker({
            position: stations[i],
            map: map,
            title: stations[i].name
        });
    }

    // Divide route to several parts because max stations limit is 25 (23 waypoints + 1 Origin + 1 destination)
    for (var i = 0, parts = [], max = 25 - 1; i < stations.length; i = i + max)
        parts.Push(stations.slice(i, i + max + 1));

    // Service callback to process service results
    var service_callback = function(response, status) {
        if (status != 'OK') {
            console.log('Directions request failed due to ' + status);
            return;
        }
        var renderer = new google.maps.DirectionsRenderer;
        renderer.setMap(map);
        renderer.setOptions({ suppressMarkers: true, preserveViewport: true });
        renderer.setDirections(response);
    };

    // Send requests to service to get route (for stations count <= 25 only one request will be sent)
    for (var i = 0; i < parts.length; i++) {
        // Waypoints does not include first station (Origin) and last station (destination)
        var waypoints = [];
        for (var j = 1; j < parts[i].length - 1; j++)
            waypoints.Push({location: parts[i][j], stopover: false});
        // Service options
        var service_options = {
            Origin: parts[i][0],
            destination: parts[i][parts[i].length - 1],
            waypoints: waypoints,
            travelMode: 'WALKING'
        };
        // Send request
        service.route(service_options, service_callback);
    }
  }
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>

You can see screen here.

violon avec boutons afficher/masquer la ligne

15
mikep

Voici un hack pour utiliser plus de 8 waypoints.Veuillez vérifier ma solution pour cela.

Dessin d'une feuille de route avec plus de 8 waypoints en utilisant l'API Google Directions

0
Nullify

Il y a une solution facile autour de cette solution.

Gardez les waypoints dans le tableau en fonction de la valeur du seuil de distance et continuez à les ajouter. Une fois que vous avez atteint la limite de 8 valeurs dans le tableau, affectez la 1ère position (origine) du tableau de points de cheminement à un nouveau tableau de points de cheminement .... Attribuez le dernier point de cheminement au nouveau point de cheminement en tant que 2e élément ... remplacez maintenant le ancien tableau de waypoints avec ce nouveau et continuez.

Watever vous faites les waypoints ne traversera jamais plus de 8 valeurs et il gardera une trace de l'itinéraire emprunté pour le tracer (sauf si le voyage est trop long)

var addWaypoint = function(point) {
    if($scope.waypoints.length > 8){
        var temp = [];
        temp.Push($scope.waypoints[0]); //Start Point
        temp.Push($scope.waypoints[7]); //Last point
        temp.Push(point); //New point
        $scope.waypoints = temp; //Replace the old object with this new one
    }
    else 
        $scope.waypoints.Push(point);
}
0
anupsahu