Commande Géolocalisation Suppliers

Objectif & besoins

Amélioration de la gestion des transports, la cliente souhaite désormais visualiser plus facilement la localisation géographique de ses fournisseurs. L’objectif est de pouvoir identifier, selon l’adresse de départ du devis, les fournisseurs les plus proches de cette adresse.

Système de géocodage automatique des adresses fournisseurs

Ajout des champs à la base de données

Dans le cadre du développement de nouvelles fonctionnalités, j’ai dû ajouter deux champs supplémentaires, latitude et longitude, à la table suppliers de la base de données. Ces champs serviront à stocker les coordonnées GPS des fournisseurs. Pour cela, j’ai utilisé Portainer afin d’accéder au terminal du conteneur Docker dans lequel le projet CakePHP est exécuté. Comme le projet ne tourne pas directement sur la machine hôte, mais dans un conteneur isolé nommé generator-8-2. Ce conteneur contient tous les outils nécessaires au bon fonctionnement du projet (PHP, MySQL, Composer, CakePHP, etc.).


Je me suis positionnée dans le répertoire racine du projet : /var/www/dahan, où se trouvent tous les fichiers de l’application CakePHP. J’ai ensuite exécuté la commande suivante pour générer une migration : bin/cake bake migration AddLatitudeAndLongitudeToSuppliers latitude:decimal[10,6] longitude:decimal[10,6] -p ProjectDahan/Dahan


Après avoir vérifié la création du fichier de migration dans config/migrations, j’ai appliqué la migration avec : bin/cake migrations migrate -p ProjectDahan/Dahan Puis j’ai vidé le cache de l’application : bin/cake cache clear_all


Les champs latitude et longitude ont bien été ajoutés à la table suppliers. Ils sont de type decimal(10,6) (équivalent à float) et sont définis comme nullable, ce qui signifie qu’ils ne sont pas obligatoires.


header-debut

Récupérer les coordonnées GPS des Suppliers (Latitude - Longitude)

Pour cette deuxième étape, Il s'agit ici de géolocaliser automatiquement un fournisseur (Supplier) avant qu'il ne soit sauvegardé en base de données. C'est à dire vérifier si il y a une adresse ou si elle a été modifiée puis récupérer les coordonnées GPS via l'API et ajouter ses coordonnées aux champs de la table avant l'enregistrement.


Nous avons créé une fonction appelée getCoordinatesFromAddress, qui prend en paramètre l'adresse d'un fournisseur (supplier). Cette adresse est ensuite utilisée pour appeler une API de géolocalisation. L'URL de cette API contient l'adresse en question, et la réponse renvoyée est au format JSON. Nous devons donc la parser pour en extraire les coordonnées GPS (latitude et longitude). Si les coordonnées sont récupérées avec succès, elles sont automatiquement ajoutées à l'objet fournisseur avant qu'il ne soit enregistré en base de données. Nous avons appelé la fonction sleep() ici pour ne pas surcharger l'API et lui laisser le temps de traiter la réponse toute les secondes. C'est pourquoi nous envoyons une requête toute les 1 seconde.



Dans cette partie du code, nous appelons la fonction SupplierGeoloc qui prend en paramètre la variable $model, représentant ici une table de la base de données. Si ce modèle correspond à la table Suppliers, nous attachons un événement beforeSave via le getEventManager(). Cet événement permet d’exécuter du code juste avant l’enregistrement d’un fournisseur en base de données.

Dans ce bloc, nous vérifions d’abord si l’adresse du fournisseur existe ou si elle a été modifiée.
Si c’est le cas, nous appelons la fonction getCoordinatesFromAddress pour récupérer les coordonnées GPS correspondantes. Si la récupération réussit, les champs latitude et longitude de l’entité fournisseur sont automatiquement renseignés avant l’enregistrement.

Ce code a été placé dans une classe nommée SupplierGeoloc pour regrouper toute la logique liée à la géolocalisation des fournisseurs dans un seul endroit. Cela permet de mieux organiser le projet, de faciliter la maintenance et de rendre cette fonctionnalité réutilisable si besoin dans d'autres parties du code ou du projet.


Pour le débogage de mon code côté back-end, j’ai utilisé la commande Log::error. Elle permet d’écrire des messages dans les fichiers de log, et de suivre l’exécution du code pour repérer d’éventuelles erreurs ou blocages. Les messages sont enregistrés dans le fichier error.log, situé dans le répertoire Dahan/Log.


Commande pour mettre à jour les coordonnées GPS de la table Suppliers

A la demande de mon tuteur, il a fallu mettre en place une commande qui sera lancée seulement une fois mais qui permettra de mettre à jour toutes les coordonnées GPS de la table Supplier.


Ceci est un premier jet de test pour savoir si le code fonctionne.


Code final pour trier les suppliers qui ont une adresse renseignée ou vide pour pouvoir compléter.


Pour ce faire, nous avons créé une fonction appelée SupplierGeolocCommand. Cette fonction appelle également la méthode SupplierGeoloc et l’applique à la table Suppliers. Ensuite, nous récupérons dans la table les champs id, address, latitude et longitude pour chaque fournisseur (supplier). Comme nous devons tout mettre à jour, nous utilisons une boucle foreach pour parcourir toute la table. Cela permet aussi de vérifier si tout fonctionne correctement et de tester le code. Pour faire ces tests, nous avons utilisé la console du conteneur "generator 8.2" sur Portainer, en lançant la commande suivante : bin/cake project_dahan/dahan.supplier_geoloc. Pour le débogage, nous avons utilisé des appels à $io->success() afin d'afficher des messages à différents moments de l'exécution. Le but de ce script est de mettre à jour les fournisseurs qui n'ont pas de coordonnées GPS ou qui ont des valeurs à zéro.


Résultat dans la console en lançant la commande bin/cake project_dahan/dahan.supplier_geoloc :

Exemple Front - Création et modification d'un Supplier

Dans la page fournisseurs je clic sur ajouter un fournisseur et je complète le formulaire, en retrant un nouveau nom et une nouvelle adresse.



Et le nouveau supplier s'est bien enregistré dans la base avec sa latitude et sa longitude :




Même chose si je décide de modifier l'adresse de mon supplier.