sábado, 15 de octubre de 2011

Google Maps: Geocodificación inversa y normal con la API v3

La geocodificación segun la API de Google Maps es el proceso de traducir una dirección humanamente legible a coordenadas geográficas (latitud y longitud).


La geocodificación inversa según la API de Google Maps es el proceso de obtener direcciones humanamente legibles a partir de coordenadas geográficas (latitud y longitud).


Mira este ejemplo de geocodificación inversa de Google Maps haciendo clic en este vínculo: http://maps.google.com/maps/api/geocode/json?latlng=19.4325231,-99.1332828&sensor=false

A continuación te pongo un código de ejemplo hecho por mí, para realizar simultáneamente ambos procesos. He usado la Versión 3 de Google Maps JavaScript API.


Si deseas ver un demo en vivo de este código puedes hacer clic en http://ultiminioramos.com/blogger_demos/google_maps/geocodificacion_inversa/mapas.php

Si deseas descargar el código de ejemplo, haz clic aquí: geocodificacion_inversa.zip

Primera parte.
Necesitamos cargar la API v3 desde Google Maps:
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>

Segunda parte.
Colocamos nuestro código Javascript con las funciones de creación y carga del mapa, así como las funciones para obtener la geocodificación normal e inversa.
<script type="text/javascript" charset="utf-8">
   var map = null;
   var marker = null;
   var geocoder = null;
   var infowindow = null;
   // posicion predeterminada
   var ini_lat = 19.360927;
   var ini_lng = -99.183325;

   // traducciones del tipo de localización
   var a_locations_type = new Array('APPROXIMATE', 'GEOMETRIC_CENTER', 'RANGE_INTERPOLATED', 'ROOFTOP');
   a_locations_type[a_locations_type[0]] = ['El resultado devuelto es aproximado.'];
   a_locations_type[a_locations_type[1]] = ['El resultado devuelto es el centro geométrico de un resultado como una línea (por ejemplo, una calle) o un polígono (una región).'];
   a_locations_type[a_locations_type[2]] = ['El resultado devuelto refleja una aproximación (normalmente en una carretera) interpolada entre dos puntos precisos (por ejemplo, intersecciones). Normalmente, los resultados interpolados se devuelven cuando los códigos geográficos de la parte superior no están disponibles para una dirección postal.'];
   a_locations_type[a_locations_type[3]] = ['El resultado devuelto refleja un código geográfico preciso.'];

   // traducciones del estatus de la geocodificación
   var a_geocode_status = new Array('ERROR', 'INVALID_REQUEST', 'OK', 'OVER_QUERY_LIMIT', 'REQUEST_DENIED', 'UNKNOWN_ERROR', 'ZERO_RESULTS');
   a_geocode_status[a_geocode_status[0]] = ['Se ha producido un error al establecer la comunicación con los servidores de Google.'];
   a_geocode_status[a_geocode_status[1]] = ['La solicitud GeocoderRequest no es válida.'];
   a_geocode_status[a_geocode_status[2]] = ['Indica que la respuesta contiene un valor GeocoderResponse válido.'];
   a_geocode_status[a_geocode_status[3]] = ['La página web ha superado el límite de solicitudes en un período de tiempo demasiado breve.'];
   a_geocode_status[a_geocode_status[4]] = ['No se permite que la página web utilice el geocoder.'];
   a_geocode_status[a_geocode_status[5]] = ['No se pudo procesar una solicitud de codificación geográfica debido a un error del servidor. Puede que la solicitud se realice correctamente si lo intentas de nuevo.'];
   a_geocode_status[a_geocode_status[6]] = ['No se ha encontrado ningún resultado para esta solicitud GeocoderRequest.'];

   // funciones para nuestro mapa
   function initGMaps() {
      // crear los objetos necesarios, primero el mapa
      map = new google.maps.Map(document.getElementById("map_canvas"), {
         'zoom': 4
         , 'center': new google.maps.LatLng(ini_lat, ini_lng)
         , 'mapTypeId': google.maps.MapTypeId.ROADMAP
         , 'scaleControl': true
         , 'scrollwheel': false
      });
      // el marcador (pin)
      marker = new google.maps.Marker({
         map: map
         , position: new google.maps.LatLng(ini_lat, ini_lng)
         , draggable: true
         , visible: false
      });
      // la ventana de info (globo)
      infowindow = new google.maps.InfoWindow();
      // el geocodificador
      geocoder = new google.maps.Geocoder();
      // crear los eventos para acciones del mouse sobre el marcador (pin)
      google.maps.event.addListener(marker, "dragend", function() {
         showLatLongPos();
      });
      google.maps.event.addListener(marker, "click", function() {
         showLatLongPos();
      });
   }

   function showAddress(address) {
      if (geocoder) {
         // obtener la Geo-Codificación Forward,
         // introduciendo un dato string (address)
         geocoder.geocode({'address': address, 'region': 'MX'}
         , function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
               if (results[0]) {
                  // preparar la info de la posición latitud y longitud
                  var input = results[0].geometry.location.toUrlValue();
                  var latlngStr = input.split(",", 2);
                  var lat_mx = parseFloat(latlngStr[0]);
                  var lng_mx = parseFloat(latlngStr[1]);
                  var latLong_mx = new google.maps.LatLng(lat_mx, lng_mx);
                  // centrar el mapa en la posición encontrada
                  map.setZoom(16);
                  map.setCenter(latLong_mx);
                  marker.setPosition(latLong_mx);
                  marker.setVisible(true);
                  //
                  google.maps.event.trigger(marker, 'click');
                  // llenar con la info de la codificación inversa, o sea, la dirección humanamente legible
                  var location_type_mx = results[0].geometry.location_type
                  infowindow.setContent('<b>' + results[0].formatted_address + '</b>' + '<br/><br/><i style="color: #777;">' + a_locations_type[location_type_mx] + '</i>');
                  infowindow.open(map, marker);
               } else {
                  alert(a_geocode_status[status]);
               }
            } else {
               alert(a_geocode_status[status]);
            }
         });
      } // endif
   }

   function showLatLongPos(){
      // preparar la info de la posición latitud y longitud
      var location = marker.getPosition().toUrlValue(7);
      var latlngStr = location.split(",", 2);
      var lat_mx = parseFloat(latlngStr[0]);
      var lng_mx = parseFloat(latlngStr[1]);
      var latLong_mx = new google.maps.LatLng(lat_mx, lng_mx);

      // obtener la Geo-Codificación Inversa, o sea, la dirección humanamente legible
      // introduciendo un dato latLong
      geocoder.geocode({'latLng': latLong_mx, 'region': 'MX'}
      , function(results) {
         var location_type_mx = results[0].geometry.location_type
         infowindow.setContent('<b>' + results[0].formatted_address + '</b>' + '<br/><br/><i style="color: #777;">' + a_locations_type[location_type_mx] + '</i>');
         infowindow.open(map, marker);
      });
      // llenar los campos de texto con los valores latitud y longitud respectivamente
      document.getElementById("latitud").value = lat_mx;
      document.getElementById("longitud").value = lng_mx;
   }

   // cargar el mapa automáticamente cuando se carga la página
   // es el equivalente a poner <body onload="initGMaps();">
   google.maps.event.addDomListener(window, 'load', initGMaps);
</script>

4 comentarios:

  1. Hola, estoy realizando un proyecto donde ocupo Google Maps y tengo algunas dudas, me podrias ayudar, te dejo mi contacto. Quiza me estoy pillando la cola, pero al cambiar los datos de origen de los marcadores no los actualiza, los extraigo sin problema de la base de datos, pero siempre carga los primeros.

    ResponderEliminar
  2. tks my friend tis doc is very important to my

    ResponderEliminar
  3. Hola, además de extraer Longitud y Latitud, puede extraer el codigo postal?? O cualquier dato que reporte el doc json??

    Gracias anticipadas

    Mi correo es info[arroba]tdcp.es

    ResponderEliminar
  4. Hola, muchas gracias por tan buen video, porfix mandame ccorreo a: emoxolandia@hotmail.com porque quiero preguntate unas cosas que de verdad necesito ayuda

    ResponderEliminar

Datos personales

Mi foto
Podrás encontrar códigos recursos y artículos sobre PHP, JavaScript, jQuery, MooTools, Ajax, CSS, HTML, UML, RUP, AUP, XP (eXtreme Programming), Six-Sigma, CMMI, FrameWorks, Zend Framework, Magento, CodeIgniter, CakePHP, Joomla 1.5, Doctrine, Active Record, ORM, POO, MVC, MySql, PostgreSql. Este espacio está destinado a ayudar y compartir un poco de lo mucho que he recibido de la comunidad en la Red.