Aller au contenu

Depuis Google Route Optimization

Unmap Optimize accepte le format OptimizeToursRequest de l'API Route Optimization de Google Maps Platform et renvoie un OptimizeToursResponse. Une intégration REST peut conserver son traitement des requêtes et réponses pour les champs pris en charge, puis remplacer l'hôte et l'identifiant OAuth par l'hôte et la clé API d'Unmap. Consultez d'abord la table des champs. Les contraintes non prises en charge nécessitent des modifications de la requête; les temps de trajet, les solutions et certains comportements d'échec diffèrent.

Unmap n'est pas affilié à Google, et Google ne l'approuve pas. Les noms de produits de cette page servent seulement à dire quelle API le format d'Unmap suit.

Unmap Optimize est en service sur api.unmap.dev, sur les chemins de Google comme sur POST /optimize.

Changer l'URL de base

Unmap sert les chemins mêmes de Google; le plus petit changement est donc l'hôte :

GoogleUnmap
https://routeoptimization.googleapis.com/v1/projects/{project}:optimizeTourshttps://api.unmap.dev/v1/projects/{project}:optimizeTours
https://routeoptimization.googleapis.com/v1/projects/{project}/locations/{location}:optimizeTourshttps://api.unmap.dev/v1/projects/{project}/locations/{location}:optimizeTours

{project} et {location} peuvent rester tels quels : Unmap les ignore, tout comme parent dans le corps, parce que la clé API identifie le compte. Le même traitement répond aussi au chemin propre à Unmap, POST https://api.unmap.dev/optimize, celui à utiliser dans du nouveau code.

Seule optimizeTours est mise en œuvre. batchOptimizeTours et les autres méthodes répondent par un 404. Unmap sert seulement la liaison REST (JSON sur HTTPS) : une bibliothèque cliente qui parle gRPC ne se connectera pas. Utilisez son transport REST si elle en a un, ou appelez le point de terminaison avec un client HTTP ordinaire.

Changer l'identifiant

Google authentifie cette API avec des jetons d'accès OAuth 2.0 liés à un compte Google Cloud. Unmap utilise une clé API tirée de votre tableau de bord, sans échange de jeton OAuth. Enregistrez la requête dans request.json et définissez UNMAP_API_KEY avec votre clé avant d'exécuter l'exemple Unmap :

curl -X POST "https://routeoptimization.googleapis.com/v1/projects/my-project:optimizeTours" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  --data @request.json

Unmap accepte aussi X-Goog-Api-Key, X-API-Key et ?key=. Si une bibliothèque cliente gère les identifiants OAuth automatiquement, configurez son transport REST pour envoyer une clé Unmap, ou utilisez un client HTTP ordinaire. Changer l'hôte seul ne remplace pas les identifiants Google. Voir Authentification.

Ce qui reste pareil

  • Les noms et l'imbrication des champs, en camelCase ou en snake_case, les durées comme "300s", les horodatages en RFC 3339 ou { seconds, nanos }, et les entiers de 64 bits en chaînes.
  • La réponse : routes avec visits, transitions, metrics, routeCosts et routePolyline; skippedShipments avec les codes de raison de Google; et metrics avec la ventilation des coûts sous les mêmes clés.
  • solvingMode: VALIDATE_ONLY, qui répond validationErrors sans résoudre.
  • Les erreurs dans la forme de Google, { "error": { "code", "message", "status", "details" } }, avec les mêmes noms de statut (INVALID_ARGUMENT, FAILED_PRECONDITION, RESOURCE_EXHAUSTED et ainsi de suite). Unmap ajoute sa propre chaîne code à côté de error.

Ce qui échoue clairement

Unmap refuse ce qu'il ne sait pas faire. Un plan qui abandonnerait en silence une fenêtre horaire ou une capacité aurait l'air correct et serait faux; chaque contrainte non prise en charge est donc une erreur que vous voyez dès la première requête :

  • Les champs pas encore pris en charge sont un 400 avec FIELD_NOT_SUPPORTED_YET quand ils ont une valeur autre que celle par défaut : limites de durée souples quadratiques, loadDemands sur une visite, types d'envois et règles de précédence, solutions injectées, maxActiveVehicles, Vehicle.ignore et d'autres. Les valeurs pas encore prises en charge sont VALUE_NOT_SUPPORTED_YET : plus d'une option de ramassage ou de livraison par envoi, une deuxième fenêtre de départ ou d'arrivée de véhicule, travelMode: WALKING, et les modes de résolution DETECT_SOME_INFEASIBLE_SHIPMENTS et TRANSFORM_AND_RETURN_REQUEST. Comme les limites de durée souples quadratiques, routeDistanceLimit.costPerKilometerBelowSoftMax est refusé, mais pour de bon et avec INVALID_VALUE, parce que GMPRO ne le prend pas en charge non plus. Les champs pris en charge donnent la liste complète, générée à partir du validateur.
  • Les identifiants de lieu (arrivalWaypoint.placeId, startWaypoint.placeId, endWaypoint.placeId) sont PLACE_ID_NOT_SUPPORTED. Un identifiant de lieu renvoie à la base de données de Google, et deviner un emplacement pour lui mènerait au mauvais endroit. Géocodez l'adresse une fois avec /geocode/search et envoyez des coordonnées.
  • Les URI Cloud Storage (gs://) n'ont nulle part où aller : aucun champ d'optimizeTours n'en prend, et les méthodes par lots qui les lisent ne sont pas offertes (elles répondent par un 404). Le code GCS_URI_NOT_SUPPORTED leur est réservé; rien ne le renvoie aujourd'hui. Envoyez le corps de la requête directement.
  • Les champs inconnus, fautes de frappe comprises, sont UNKNOWN_FIELD plutôt qu'ignorés.
  • Un envoi obligatoire qui ne peut pas être servi est un 400 FAILED_PRECONDITION qui le nomme, là où Google peut répondre 200 en le laissant de côté et en le comptant dans skippedMandatoryShipmentCount. Donnez un penaltyCost à un envoi qui peut être laissé de côté.

Passez d'abord vos vraies requêtes par VALIDATE_ONLY. Il signale les erreurs de validation des champs jusqu'à maxValidationErrors et ne coûte rien. Il ne vérifie ni l'accessibilité routière ni la faisabilité pour le parc de véhicules; exécutez ensuite une résolution. L'authentification, la taille du corps et les limites du nombre d'envois ou de véhicules s'appliquent toujours.

Ce qui est accepté et ignoré

Unmap accepte plusieurs champs sans les appliquer. Une valeur autre que celle par défaut produit un avertissement dans l'en-tête X-Unmap-Optimize-Warnings : considerRoadTraffic, parent, populateTransitionPolylines, allowLargeDeadlineDespiteInterruptionRisk, ainsi que location.heading, sideOfRoad et vehicleStopover d'un point de passage. Consultez ces avertissements à chaque réponse. Les réglages de trafic et de points de passage ignorés peuvent changer l'utilité du plan pour vos activités. Le corps de la réponse suit le format de Google.

Les tournées et les coûts vont différer

Pour les champs de coût pris en charge, Unmap utilise fixedCost une fois par véhicule utilisé, costPerHour sur la durée de chaque tournée, costPerTraveledHour sur son temps de conduite, costPerKilometer sur sa distance, et penaltyCost pour chaque envoi facultatif écarté, à l'exclusion des envois ignorés. Ces coûts figurent sous les mêmes clés dans metrics.costs. Ce qui entre dans la formule diffère :

  • Les temps de trajet viennent d'un autre réseau routier. Unmap calcule les temps de conduite à partir des données OpenStreetMap, sur son propre graphe routier canadien, en circulation fluide et sans trafic (considerRoadTraffic est ignoré). Les mêmes arrêts reçoivent d'autres temps de trajet que chez Google; les tournées, les heures d'arrivée et totalCost diffèrent donc aussi.
  • Le solveur est différent. Même avec des temps de trajet identiques (vos propres durationDistanceMatrices), deux solveurs qui disposent de quelques secondes chacun peuvent rendre des plans différents de coût semblable.
  • La couverture routière est le Canada. Pour des arrêts ailleurs, envoyez vos propres matrices ou utilisez useGeodesicDistances.

Ne jugez donc pas une migration en comparant totalCost à la dernière réponse de Google. Vérifiez que les plans sont réalisables et que leur coût est raisonnable pour vos activités, puis comparez sur vos propres données de trajet.

Limites et facturation

Des limites par forfait s'appliquent aux envois, aux véhicules, aux lieux, au temps de résolution et aux résolutions simultanées : Hobby permet 25 envois, Growth 2 000. Un timeout plus long que celui du forfait est ramené à la limite, pas refusé. La facturation compte un appel par envoi réellement servi, et résoudre de nouveau les mêmes envois dans les 24 heures est gratuit. La page API Optimize donne les chiffres.

Liste de vérification

  1. Utilisez https://api.unmap.dev comme hôte, en conservant un chemin Google pris en charge ou en utilisant /optimize.
  2. Remplacez le jeton OAuth par une clé API Unmap.
  3. Envoyez une vraie requête avec solvingMode: VALIDATE_ONLY et corrigez ce qu'elle signale.
  4. Remplacez les identifiants de lieu par des coordonnées tirées de /geocode/search.
  5. Consultez X-Unmap-Optimize-Warnings à chaque réponse pour repérer les champs ignorés et les avertissements de trajet.
  6. Comparez les limites du forfait à votre plus grosse requête.
  7. Exécutez une résolution et vérifiez les heures de visite, les charges, les envois écartés et les coûts.