Le monde numérique est formidable : instantanéité de l’information, mutualisation des moyens, etc… et cela dans beaucoup de domaines : réseaux sociaux, commerce, presse, loisirs… Toutefois, il est une tendance ces derniers temps, la recherche de la proximité. En effet, le social manque de contact humain, à tel point que certains prédisent la fin des réseaux purement numériques. Du côté du commerce, la distance se paie sur les transports, donc l’empreinte écologique mais également les prix surtout avec l’envolée des prix des carburants. Pour la presse, le désintérêt des gens pour l’information est proportionnel à la distance qui les séparent du lieu de l’information. Depuis quelques années les services sur Internet essayant de favoriser la proximité de l’utilisateur, d’où le plébiscite grandissant des API cartographiques. En quelques lignes, je vais vous présenter comment intégrer des fonctionnalités cartographiques rudimentaires mais qui fonctionneront sur toutes les plateformes, mêmes les hébergements mutualisés. Il suffit de suivre la recette…
L’entrée, avoir ses données géolocalisées
Tout d’abord, il faut avoir des données avec les coordonnées géographiques pour pourvoir les requêter. Généralement, il est rare d’avoir la latitude et la longitude dans un système d’information quelconque. Il est beaucoup plus courant d’avoir uniquement d’adresse, le code postal et la ville. Il faut donc faire appel à un service de géolocalisation comme le service de Google, qui renvoie les précieuses coordonnées.
http://maps.googleapis.com/maps/api/geocode/json?address=4%20all%C3%A9e%20du%20trait%20d%E2%80%99union%20%E2%80%93%2077127%20Lieusaint&sensor=false
{ "results" : [ { "address_components" : [ { "long_name" : "Trait d'Union", "short_name" : "Trait d'Union", "types" : [ "route" ] }, { "long_name" : "Lieusaint", "short_name" : "Lieusaint", "types" : [ "locality", "political" ] }, { "long_name" : "Seine-et-Marne", "short_name" : "77", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "Île-de-France", "short_name" : "IDF", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "France", "short_name" : "FR", "types" : [ "country", "political" ] }, { "long_name" : "77127", "short_name" : "77127", "types" : [ "postal_code" ] } ], "formatted_address" : "Trait d'Union, 77127 Lieusaint, France", "geometry" : { "bounds" : { "northeast" : { "lat" : 48.6225783, "lng" : 2.5466443 }, "southwest" : { "lat" : 48.6122244, "lng" : 2.5399211 } }, "location" : { "lat" : 48.617318, "lng" : 2.543222000000001 }, "location_type" : "GEOMETRIC_CENTER", "viewport" : { "northeast" : { "lat" : 48.6225783, "lng" : 2.5466443 }, "southwest" : { "lat" : 48.6122244, "lng" : 2.5399211 } } }, "partial_match" : true, "types" : [ "route" ] } ], "status" : "OK" }
Le mieux est d’appeler ce service juste avant l’enregistrement en base, cela permet de lisser les appels au service de géolocalisation, qui possèdent bien entendu des mesures de contrôle de congestion, donc qu’il faut pas requêter de manière trop dense sous peine de se faire inscrire sur une liste noire. Les solutions les plus élégantes que j’ai vu consistent en l’adjonction de comportements (« behavior ») directement sur l’ORM si vous en disposez un. Toutefois, ces services ne sont pas infaillibles, et peuvent échouer sur des adresses exotiques, comme des cedex, des boîtes postales, des zones d’activité commerciale, des zones industrielles, ou encore des nouvelles voies. D’expérience, il faut compter entre 5 et 10 % de mauvaises géolocalisations, c’est pourquoi il faut permettre aux administrateurs de changer les coordonnées, soit en éditant les coordonnées directement, ce qui est peu pratique, soit de faire une petite utilisation d’une API javascript de cartographie, avec un petit marqueur déplaçable sur la carte.
Le plat de résistance, sélectionner et ordonner ses données
La méprise la plus commune est de croire qu’il faut alors une base de données ou des extensions spécialisées dans les calculs géographiques. Effectivement, cela ouvre plus de possibilités et de performances, mais ce n’est pas obligatoire dans la plupart des cas, les volumes de données en jeu dépassant rarement la dizaine de milliers, et les requêtes étant généralement une sélection avec condition de distance maximale, et un tri par proximité. En effet, à partir des coordonnées géographiques, il est possible de calculer ce qui intéresse directement les utilisateurs finaux à savoir la distance entre deux points à la surface du globe, aussi appelé la distance du grand cercle. On peut alors tout à fait directement l’utiliser dans une reqûete SQL :
6378137 * 2 * ATAN( SQRT( POW( SIN( ( RADIANS(latitude2) – RADIANS(latitude1) ) / 2 ), 2 ) + COS( RADIANS(latitude1) ) * COS( RADIANS(latitude2) ) * POW( SIN( ( RADIANS(longitude2) – RADIANS(longitude1) ) / 2 ), 2 ) ) )
Il est également possible, toujours sans avoir d’extension SQL spécialisée, utiliser des formules d’appartenance à des enveloppes concaves pour vérifier l’inclusion d’un point dans une forme différente de celle d’un cercle. Il suffira alors pour vérifier si un point A est dans l’enveloppe concave, de vérifier pour chacun des segments MN si le produit vectoriel est AMxMN est toujours de même signe, ce qui peut se fabriquer avec une requête SQL imbriquée. Il est même possible de composer plusieurs fois cette distance du grand cercle pour calculer un chemin avec détour, en calculant la distance d’un point A à un point B puis à un point C.
Le dessert, représenter ses données
Une fois ces données sélectionnées, il faut alors les présenter à l’utilisateur. Il y a quelques années, il n’y avait quasiment que l’API Google, mais aujourd’hui Bing, Yahoo, Openlayers + Openstreetmap , Geoportail ( cocorico:) ) et d’autres encore, permettent d’afficher un fond de carte personnalisable, centré sur un point, avec un niveau de zoom donnée, sur lequel il est possible de rajouter des marqueurs, des lignes droites (selon la projection utilisée) ou géodésiques (la ligne à la surface du globle), des trajets, des polygones en les personnalisant à loisir.
function initialize() { var mapOptions = { zoom: 3, center: new google.maps.LatLng(48.2, 2.3), mapTypeId: google.maps.MapTypeId.TERRAIN }; var map = new google.maps.Map(document.getElementById('lieusaint-orleans-map-canvas'), mapOptions); var flightPlanCoordinates = [ new google.maps.LatLng(47.8980525,1.9097171), new google.maps.LatLng(48.6156306,2.5426611) ]; var flightPath = new google.maps.Polyline({ path: flightPlanCoordinates, geodesic: true, strokeColor: '#FF0000', strokeOpacity: 1.0, strokeWeight: 2 }); flightPath.setMap(map); }
Conclusion
Je n’aurais qu’un seul conseil par rapport à toutes ces technologies / api / services : faites juste attention à leurs conditions d’utilisation et ne mettez jamais tous vos œufs dans le même panier. En effet, Google a prouvé plusieurs fois par le passé qu’il pouvait grandement restreindre l’accès à certains services, voire les discontinuer sans autre forme de procédure. Des initiatives comme Mapstraction, qui comme son nom l’indique, permet une couche d’abstraction au dessus des API javascript, et ainsi de basculer vers telle ou telle API, s’il y avait un problème ou des projets libres comme Openlayers, Openstreetmap, Mapnik, mod_tile, gdal, ogr sont à privilégier lors du choix initial des technologies à intégrer dans votre site. Sources : http://www.01net.com/editorial/612558/scenario-catastrophe-facebook-va-t-il-disparaitre-en-2017/ http://fr.wikipedia.org/wiki/Distance_du_grand_cercle http://propelorm.org/Propel/cookbook/geocodable-behavior.html https://github.com/KnpLabs/DoctrineBehaviors#geocodable http://dev.mysql.com/doc/refman/5.0/fr/gis-introduction.html http://postgis.net/ http://mapnik.org/ http://openlayers.org/ http://www.openstreetmap.org/ https://developers.google.com/maps/documentation/javascript/?hl=fr-FR&csw=1 http://msdn.microsoft.com/en-us/library/gg427610.aspx http://developer.yahoo.com/maps/ http://mapstraction.com/ https://developers.google.com/maps/documentation/geocoding/?hl=FR