Insérer les coordonnées d’une adresse en BDD

Dans cette démo de l’Api Google Map, nous allons voir un exemple parmi d’autres de l’utilisation de la classe Geocoder pour récupérer les coordonnées d’un point puis insérer ces dernières dans une base de données.

Pour cette application, un appel AJAX sera nécessaire pour appeler le script PHP chargé de l’insertion des coordonnées de l’adresse en base de données. Il faudra donc penser à créer l’objet XMLHttpRequest ou alors charger un fichier tiers comme la librairie JQuery par exemple.

Source et Explications

SECTION HTML

<html>
<head>
...
...
/* Appel API Google Map et fichier tiers pour appel AJAX */ 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/
jquery.min.js"></script>
...
...
</head>
<body>

/* Formulaire HTML */ 
<input type="text" id="adresse" value="saisissez votre adresse à géolocaliser" />
<input type="button" onclick="geolocalise()" value="géolocaliser" />
Latitude : <input type="text" id="lat" value="" />
Longitude : <input type="text" id="lng" value="" />
/* Div où s'affichera le retour de l'appel AJAX (non obligatoire) */ 
<div id="answer">Réponse de l'appel AJAX :</div>

...
...

SCRIPT DE L'APPLICATION

<script type="text/javascript">

 /* Déclaration des variables globales */ 
 var geocoder = new google.maps.Geocoder();
 var addr, latitude, longitude;

 /* Fonction chargée de géolocaliser l'adresse */ 
 function geolocalise(){
  /* Récupération du champ "adresse" */ 
  addr = document.getElementById('adresse').value;
  /* Tentative de géocodage */ 
  geocoder.geocode( { 'address': addr}, function(results, status) {
   /* Si géolocalisation réussie */ 
   if (status == google.maps.GeocoderStatus.OK) {
    /* Récupération des coordonnées */ 
    latitude = results[0].geometry.location.lat();
    longitude = results[0].geometry.location.lng();
    /* Insertion des coordonnées dans les input text */ 
    document.getElementById('lat').value = latitude;
    document.getElementById('lng').value = longitude;
    /* Appel AJAX pour insertion en BDD */ 
    var sendAjax = $.ajax({
     type: "POST",
     url: 'insert-in-bdd.php',
     data: 'lat='+latitude+'&lng='+longitude+'&adr='+addr,
     success: handleResponse
    });
   }
   function handleResponse(){
    $('#answer').get(0).innerHTML = sendAjax.responseText;
   }
  });
 }

</script>

</body>
</html>

SECTION PHP (fichier insert-in-bdd.php)

<?php
 header('Content-type: text/html; charset=ISO-8859-1');
 if(isset($_POST['lat']) && isset($_POST['lng'])){
  $lat = addslashes($_POST['lat']);
  $lng = addslashes($_POST['lng']);
  $adr = addslashes($_POST['adr']);
  $db = mysql_connect(SERVER, USER, PASSWORD);
  $select = mysql_select_db(DATABASE, $db);
  mysql_query('INSERT INTO ma_table (lat,lng,adresse)
               VALUES ("'.$lat.'","'.$lng.'","'.$adr.'")');
  echo 'Vos coordonnées ont bien été insérées en base de données.';
 }else
   echo 'Problème rencontré dans les valeurs passées en paramètres';
?>

Adresses au format JSON

Dans cet exemple d’application, nous allons lire un fichier JSON contenant un ensemble d’adresses postales généré au préalable à l’aide d’un langage comme le PHP par exemple.

L’idée est donc de récupérer les adresses au format JSON, d’évaluer l’objet à l’aide de la fonction eval puis pour chacune de ces adresses, nous tenterons de les géolocaliser au moyen de la classe Geocoder de l’API Google Map.

Pour les adresses dont la géolocalisation aura réussie, nous étendrons les limites de la carte afin que le zoom final soit calculé automatiquement en fonction de ces points à l’aide de la classe LatLngBounds et des méthodes extend et fitBounds.

NB : L’application nécessitant un appel AJAX, un fichier tiers sera appelé pour créer l’objet XMLHttpRequest et traiter le retour de cet appel. Il faudra donc inclure ce fichier dans la page.

Voir un exemple de l’utilisation de la méthode fitBounds.

Source et Explications

CONTENU DU FICHIER fichier-json.json LISTANT LES ADRESSES
({
 "adresses": [ {
  "adresse": "rue rivoli paris"
  },{
  "adresse": "rue daumesnil 75012 paris"
  },{
  "adresse": "porte de versailles paris"
 } ]
} )

/* Appel API Google Map et fichier tiers pour appel AJAX */ 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="utils.js"></script>

/* Script de l'application */ 
<script type="text/javascript">

 /* Déclaration des variables globales */ 
 var map = document.getElementById('map');
 var i = 0;
 /* Servira à stocker temporairement les coordonnées de l'adresse */ 
 var coords;
 /* Déclaration de l'objet de type Geocoder */ 
 var geocoder = new google.maps.Geocoder();
 /* Déclaration de l'objet de type LatLngBounds qui définira les limites de la carte */ 
 var bounds = new google.maps.LatLngBounds();

 /* Déclaration des options de la map */ 
 var options = {
  disableDefaultUI: true,
  mapTypeId: google.maps.MapTypeId.HYBRID
 }

 /* Instanciation de l'objet de type Map */ 
 var map = new google.maps.Map(map, options);

 /* Appel de la fonction chargée de lancer l'application */ 
 addMarkers();

 /* Fonction chargée de lancer l'application */ 
 /* Elle appelle la fonction "downloadUrl" pour aller lire
  le fichier fichier-json.json en AJAX*/ 
 function addMarkers(){
  downloadUrl('fichier-json.json', function(data){
   /* Evaluation du retour AJAX au format JSON */ 
   var response = eval(data);
   var nombreAdresse = response.adresses.length;

   /* Tant que l'on a des adresses, on tente de les géolocaliser */ 
   for(i = 0; i < nombreAdresse; i++){
    if(response.adresses[i].adresse)
     /* Appel de la fonction de Géocodage avec l'adresse postale en paramètre */ 
     geocodeAddress(response.adresses[i].adresse);
   }
  });
 } 

 /* Fonction de géocodage d'une adresse */ 
 function geocodeAddress(addr){
  geocoder.geocode( { 'address': addr}, function(results, status) {
   /* Si la géolocalisation réussit */
   if (status == google.maps.GeocoderStatus.OK) {
    /* On récupère les coordonnées de l'adresse */
    coords = results[0].geometry.location;
    /* On étend les limites de la carte afin d'y inclure ce nouveau point */
    bounds.extend(coords);
    /* On déclare le marker associé */
    var marker = new google.maps.Marker({
     position: coords
    });
    /* On l'ajoute à la carte */
    marker.setMap(map);
    /* On affiche la carte avec un zoom adapté afin de voir tous nos markers */
    map.fitBounds(bounds);
   }
  });
 }

</script>

Filtrer les markers par rapport à un périmètre

Dans cet exemple d’application, nous utiliserons principalement la méthode new google.maps.Circle ainsi qu’une fonction nommée “distance” qui se chargera de calculer la distance entre 2 points.

L’idée est donc la suivante :

Au premier click sur la map, on définit le centre du cercle. Apparaît alors un picto rouge sous forme de punaise.

Au second click, on affiche un second picto rouge. La distance entre ces 2 points définira le rayon du cercle, ou plutôt dans notre cas, du périmètre.

La méthode new google.maps.Circle est alors appelée avec comme options le rayon et le centre.

Au même instant, nous comparons la distance entre tous nos markers et le centre du cercle afin de vérifier que cette distance est bien inféreure au rayon du cercle.

Si tel est le cas, nous affichons le marker (de facto à l’intérieur de notre cercle), le cas échéant on le supprime de la map s’il y figurait.

NB : il est possible de déplacer les markers rouges définissant le cercle afin de faire varier son centre ou son rayon.

Récupérer le département ou le pays d’une adresse

Le service de geocodage : geocoder de l’api Google Map permet de récupérer les coordonnées d’une adresse ou inversement, une adresse à partir de ses coordonnées.

La réponse retournée par l’api contient plusieurs informations comme par exemple le code postal, la région, le département ou encore le pays (exemple de retour Json google Map).

Dans cet exemple, 2 utilisations sont abordées :

  • Obtenir la ville, le code postal, le département et le pays à l’aide des coordonnées
  • Obtenir le code postal, le département et le pays à l’aide de l’adresse

Récupération du code postal, du département et du pays à partir d’une adresse ou de ses coordonnées

Code source de l’application

<script type="text/javascript">

  /* Déclaration des variables  */
  var geocoder;
  var map;
  var infowindow = new google.maps.InfoWindow();
  var marker;

  /* Fonction d'initialisation de la map appelée au chargement de la page  */
  function initialize() {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(48.8566667, 2.3509871);
    var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  }

  /* Fonction chargée de géocoder l'adresse  */
  function codeAddress() {
    var address = document.getElementById("adr").value;
    geocoder.geocode( { 'address': address + ' France'}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        var coords = results[0].geometry.location
        map.setCenter(coords);
        var marker = new google.maps.Marker({
          map: map,
          position: coords
        });
        document.getElementById('latlng').value = coords.lat()+','+coords.lng();
        codeLatLng(coords.lat()+','+coords.lng());
      } else {
        alert("Le geocodage n\'a pu etre effectue pour la raison suivante: " + status);
      }
    });
  }

  /* Fonction de géocodage inversé (en fonction des coordonnées de l'adresse)  */
  function codeLatLng(input) {
    var latlngStr = input.split(",",2);
    var lat = parseFloat(latlngStr[0]);
    var lng = parseFloat(latlngStr[1]);
    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if (results[0]) {
          map.setZoom(11);
          marker = new google.maps.Marker({
            position: latlng,
            map: map
          });
          var elt = results[0].address_components;
          for(i in elt){
            if(elt[i].types[0] == 'postal_code')
            document.getElementById('cp').value = elt[i].long_name;
            if(elt[i].types[0] == 'locality')
            document.getElementById('adr').value = elt[i].long_name;
            if(elt[i].types[0] == 'administrative_area_level_2')
            document.getElementById('dpt').value = elt[i].long_name;
            if(elt[i].types[0] == 'country')
            document.getElementById('pays').value = elt[i].long_name;
          }
          infowindow.setContent(results[0].formatted_address);
          infowindow.open(map, marker);
          map.setCenter(latlng);
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  }

  function retrieve(){
    var input = document.getElementById("latlng").value;
    codeLatLng(input);
  }

  ## CODE HTML

  <body onload="initialize()">

    <div>
      latitude, longitude : <input id="latlng" type="text" value="48.3906042,-4.4869013">
     <input type="button" value="Obtenir la ville..." onclick="retrieve()">
      Ville / adresse : <input id="adr" type="text" value="">
      <input type="button" value="Obtenir le code postal..." onclick="codeAddress()">
      code postal : <input id="cp" type="text" value="">
      département : <input id="dpt" type="text" value="">
      pays : <input id="pays" type="text" value="">
    </div>

    <div id="map_canvas"></div>

  </body>

</script>

Exemple de retour JSON de l’api Google Map

	{
  "status": "OK",
  "results": [ {
    "types": [ "street_address" ],
    "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
    "address_components": [ {
      "long_name": "1600",
      "short_name": "1600",
      "types": [ "street_number" ]
    }, {
      "long_name": "Amphitheatre Pkwy",
      "short_name": "Amphitheatre Pkwy",
      "types": [ "route" ]
    }, {
      "long_name": "Mountain View",
      "short_name": "Mountain View",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "California",
      "short_name": "CA",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    }, {
      "long_name": "94043",
      "short_name": "94043",
      "types": [ "postal_code" ]
    } ],
    "geometry": {
      "location": {
        "lat": 37.4219720,
        "lng": -122.0841430
      },
      "location_type": "ROOFTOP",
      "viewport": {
        "southwest": {
          "lat": 37.4188244,
          "lng": -122.0872906
        },
        "northeast": {
          "lat": 37.4251196,
          "lng": -122.0809954
        }
      }
    }
  } ]
}