Buscar y trazar rutas con GMaps API v3 Buscar y trazar rutas con GMaps API v3

Posted by on Dec 16, 2011 in Código, Featured Articles | 18 comments


Si no tienes mucha experiencia o tienes dudas con respecto a algo que usemos en este post, puedes consultar los demás ejemplos que se han realizado anteriormente aquí.

En esta ocasión veremos un ejemplo buscado por muchos, y que puede llegar a tener gran utilidad dependiendo de nuestra aplicación, estamos hablando de trazar rutas… dije ¿rutas?, si, rutas, direcciones, un pequeño GPS en web.

Lo que haremos es bastante sencillo de entender y lo pondremos de la manera más básica, esto para darte la amplitud a que lo mejores y le pongas la cara que desees.

El proceso es entendido por todos, es proporcionar 2 puntos, un origen y un destino, a partir de esto, que nos proporcione una ruta para ir de un lado a otro. Sin más preámbulo manos a la obra.

Ver Demo Single InfoWindow

Lo primero (siempre usaremos los scripts de jQuery y GMaps) que haremos será crear el html sobre el cuál vamos a trabajar, para esto solamente requerimos 2 cajas de texto para escribir el origen y el destino, un botón para ejecutar el proceso, 2 combobox donde uno será para elegir el modo de viaje (auto, bicicleta, caminando) y el otro para elegir el sistema de medición (Métrico -mts, Km-, Imperial -ft, Mi-), por último 2 divs, uno para el espacio del mapa y otro para el panel de direcciones.

<div>
	<label for="origen">Origen</label>
	<input type="text" name="origen" id="origen" placeholder="calle, ciudad, estado..." />
	<br />
	<label for="destino">Destino</label>
	<input type="text" name="destino" id="destino" placeholder="calle, ciudad, estado..." />
	<br />
	<input type="button" id="buscar" value="Buscar ruta"  />
</div>
<br />
<h3>Opciones</h3>
<div id="rutaOps">
	<select id="modo_viaje" class="opciones_ruta">
		<option value="DRIVING" selected="selected">Auto</option>
      	<option value="BICYCLING">Bicicleta</option>
      	<option value="WALKING">Caminando</option>
  	</select>
  	<select id="tipo_sistema" class="opciones_ruta">
      	<option value="METRIC" selected="selected">Métrico</option>
      	<option value="IMPERIAL">Imperial</option>
  	</select>
</div>
<br />
<div>
	<div id="map_canvas" style="float:left; width:70%; height:500px"></div>
	<div id="panel_ruta" style="float:right; overflow: auto; width:30%; height: 500px"></div>
</div>

Una vez que tenemos el HTML nos enfocaremos en el la API y JS completamente, declaramos 2 objetos globales, uno es DirectionsRenderer y otro es DirectionsService. El primero nos dará las herramientas necesarias para que visualicemos en el navegador toda la información obtenida, el segundo es el servicio que buscará en las bases de datos de Google Maps tanto los puntos como la(s) rutas existentes.

var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();

Una vez hecho esto, escribimos el código para ya tener inicializado y dibujado el mapa en nuestra página, creamos una función con el nombre que nosotros queramos, dentro de ella, vamos a colocar lo siguiente:

var request = {
 origin: $('#origen').val(),
 destination: $('#destino').val(),
 travelMode: google.maps.DirectionsTravelMode[$('#modo_viaje').val()],
 unitSystem: google.maps.DirectionsUnitSystem[$('#tipo_sistema').val()],
 provideRouteAlternatives: true
 };

Línea por línea:

  1. Declaramos una variable con las opciones con las que se va a solicitar la información al objeto DirectionsServices, lo siguiente son parámetros para hacer la búsqueda de acuerdo a los datos introducidos.
  2. A origin se le asigna el valor de  la caja de texto origen estableciendo el punto de partida de la ruta.
  3. A destination se le asigna el valor de la caja de texto destino con el que se especifica el punto final de la ruta.
  4. En la opción travelMode se asigna la opción elegida para el modo de viaje (modo_viaje), por esta razón en el valor de cada opción se definió de acuerdo al valor asignado en la API.
  5. unitSystem se refiere al tipo de unidades que se utilizarán para mostrar distancias, obteniendo el valor del tipo_sistema.
  6. Con la opción provideRouteAlternatives establecemos en verdadero o falso (por default false), para indicar que puede ofrecernos más resultados para las rutas (rutas alternativas).

Una vez declarada la variable con el arreglo de los parámetros, con unas cuántas líneas vamos a hacer la solicitud y plasmar el resultado:

directionsService.route(request, function(response, status) {
	if (status == google.maps.DirectionsStatus.OK) {
		directionsDisplay.setMap(map);
		directionsDisplay.setPanel($("#panel_ruta").get(0));
		directionsDisplay.setDirections(response);
	} else {
	        alert("No existen rutas entre ambos puntos");
	}
});

Recordemos que al inicio declaramos 2 objetos, teniendo en cuenta su función, les explico línea a línea:

  1. directionsService.route hace la solicitud a la API con los datos que previamente establecimos (request), creamos una una función interna, que recibe los parámetros de respuesta (response) que es donde vendrían contenidos los datos y un estatus (status) que indica si fue exitosa la solicitud.
  2. Si el estatus es OK procedemos, si no, mandamos un mensaje de error diciendo que no se pudo encontrar ruta entre ambos puntos. Existe una serie de estatus distintos, sin embargo y para efectos prácticos solamente usamos aquí el OK (para ver más tipos de status, hay que ir directamente a la documentación de la API).
  3. directionsDisplay.setMap(map) establece el mapa sobre el cuál será trazada la ruta, la variable map debe ser un objeto tipo Mapa, además de global.
  4. directionsDisplay.setPanel($(“#panel_ruta”).get(0)) indica dónde van a ser escritas las indicaciones de la ruta, aquí es necesario indicar un div disponible (panel_ruta).
  5. directionsDisplay.setDirections(response) hace la magia, imprime en el mapa la ruta y escribe las indicaciones de acuerdo a las 2 instrucciones anteriores.

Por último solamente creamos un par de funciones para que al hacer click en el botón busque la ruta o la redibuje si se eligen diferentes opciones, esto es opcional, si no lo quieren así hay que hacer que indicar que al hacer click, la función central se ejecute, para mi caso, la función la llamé rockAndRoll  :D

$('#buscar').live('click', function(){
	rockAndRoll();
});

$('.opciones_ruta').live('change', function(){
	rockAndRoll();
});

Ver Demo Single InfoWindow

Es todo por esta ocasión, espero les ayude en sus proyectos o simplemente para jugar un rato, si quieren verlo en función denle click en el botón verde, dudas y comentarios son bien recibidos, o pueden encontrarme en twitter @jafrancov

Enjoy this Life!!

Quizá también te interese...


18 Responses to “Buscar y trazar rutas con GMaps API v3”

  1. Hola,

    Muy interesante, gran aporte.

    Sabes si se puede pasar el destino en un parametro, poniendo unas coordenadas? Es decir que el usuario solo ponga el origen para saber donde se va a un sitio que le muestro yo?

    Por otro lado, como puedo hacer para mostrar la herramienta print para que asi se pueda imprimir las indicaciones para ir al sitio?

    Con este gadget sale el print.

    http://maps.google.com/help/maps/gadgets/directions/

    Muchas Gracias

    Saludos!

    • @Marc gracias por el coment y te comento a lo que preguntas:

      -”se puede pasar el destino en un parametro, poniendo unas coordenadas … el usuario solo ponga el origen para saber donde se va a un sitio que le muestro yo”
      Si, si se puede, como lo comenté, puedes poner coordenadas o direcciones, la API los entenderá, además el destino puede estar anclado a lo que tú digas, así el usuario solamente pone su dirección origen.

      -”mostrar la herramienta print para que así se pueda imprimir las indicaciones”
      Para esto no hay opción con la API, necesitarías generar por tu cuenta la impresión, en esta liga hay un ejemplo de cómo hacerlo de manera sencilla, puedes intentarlo.

      Saludos…

      • Hola Alex, tengo un problema que me está volviendo loco. tengo hecho un programa como el tuyo que me muestra una ruta desde una localidad a otra, pero una de las localidades siempre tiene que ser Oña, pueblecito de la provincia de Burgos. Supongo que por la ñ siempre me aparece el error de que no hay rutas. Como podría hacerlo para poner las coordenadas en vez del nombre del pueblo, o solucionar el tema del nombre para poner la ñ en el nombre.

        Me estoy volviendo loco con el tema, y ya no se que hacer. Me harias un gran favor si me das alguna pista.

      • @Roberto muy sencillo, el error que tienes es por la configuración del tipo de entrada en tu html utf-8, latin, etc. pero, es mejor con las coordenadas, ve a maps.google.com y en los labs (están ahora en el engrane para configuración arriba a la derecha) activa una función que se llama “Marcador lat.-long.” con esa herramienta, en el punto que quieres en el mapa, das un click secundario y selecciona “Visualizador Lat. Lng.” esto te pondrá una especie de tool-tip con las coordenadas, solo cambia las comas por puntos, excepto la que separa la Lat. de Lng., listo, ya tienes tus coordenadas ;)

      • Hola, perdoname, lo estoy haciendo desde flash y tengo una linea que me crea la rura, el from lo coge de un cuadro de texto y el destino lo pongo yo a mano.

        direcciones.load(“from: ” + ciudad.text + ” to: Oña”)

        Como puedo poner en el destino las coordenadas, o como la harias tu, desde javascript.

        Muchisimas gracias por todo, estoy atascado con la ñ.

      • Eureka, ya lo he conseguido, MUCHAS GRACIAS ALEX, ya me funciona, he puesto la linea así

        direcciones.load(“from: ” + ciudad.text + ” to: 42.736, -3.415″ )

        y ya va.

  2. Madness says:

    Que tal, bastante interesante y util el tutorial, pero espero puedas ayudarme, he leido poco de la api, pero no he encontrado algun metodo o funcion que me permita recorrer cada uno de los marcadores y obtener o cambiar algunas de sus propiedades en “vivo”. Dado que al crear los marcadores no hay un id o algo que me permita identificarlos en el mapa a traves de un bakcend, tienes algun ejemplo o idea de como hacerlo? gracias por tu tiempo.
    Saludos

    • @Madness no sé exactamente lo que tratas de hacer, sin embargo, lo que yo hago es lo siguiente, esto suponiendo los marcadores los envías como un array desde el backend, transformado en un json o un xml para leerlos con JS (y jQuery) y colocarlos en el mapa:
      Puedes recorrer el array con un un $.each (usando jQuery), esto te da un key o identificador de cada elemento que vas leyendo, algo como:

      //variables globales de la clase o del JS
      marker = [];
      //La función recibe el array JSON que llamaremos items
      function printMarkers(items){
         //key es el identificador del elemento
         //item es la info (lat, lng, name, image, por ejemplo)
         $.each(items, function(key, item){
            marker[key] = new google.maps.Marker({
               map: map,
               position: new google.maps.LatLng(item.lat, item.lng),
               icon: item.image
            });
            //Aquí ya cualquier otro proceso como abrir infowindows con el nombre
         });
      }
      

      Espero esto te ayude, mucha suerte, saludos!

  3. Hola buenas,

    Hay alguna forma que en una web para moviles, mediante la api nos indique como llegar a unas coordenadas? Me refiero tal como lo hace la app de google.

    Sino no nos puede guiar, se podria hacer que cada ciertos segundos actualize nuestra nueva posición para asi mostrarla en el mapa y asi poder ver donde estamos respeto el destino?

    Muchas Gracias

    Saludos!

    • @Marc Pues es la misma API, todo dependerá de cómo esté implementado tu diseño para funcionar con móviles, ahora, para hacer un seguimiento o tracking de la posición requerirás del uso de la API de Geolocalización de HTML5, que tengo agendado ese post para el fin de semana, sin embargo, tiene sus desventajas, ya que tendrá un uso mayor en tus datos y sobre todo en la pila de los dispositivos, ya que constantemente usará el GPS.

      En cuanto tenga el post, lo comparto en todas las redes donde ando, o si quieres busca sobre la API de HTML5, está bastante sencillo en realidad, saludos!!!

  4. Muchas gracias.

    Pero la API de Geolocalizacion de HTML5 solo me dara las coordenadas donde esta el movil, però la ruta y las indicaciones para llegar me las tiene qe dar google pasandole yo el origen y destino no?

    Saludos!

    • @Marc Es correcto, así funciona, con la API de Geolocalización de HTML5 obtienes la ubicación del usuario, una vez obtenida juegas con ellas con la API de Google Maps

      • Muchas gracias, me espero a ver el nuevo post!

        Buscare a ver si encuentro algun ejemplo por la red!

        Saludos!

  5. Hola, muchas gracias por el ejemplo, está bien explicado.
    Hice la prueba usando un proyectito de ejemplo en VWD 2010, lo probé y cheque la consola del navegador (en mi caso uso FF). En la consola me aparece un warning:

    El uso de atributos ‘specified el atributo es obsoleto. Siempre regresa verdadero.

    Se que no es la gran cosa pero no me quería quedar con la duda, ¿sábes a que se deberá? ¿será la versión de jQuery que uso 1.4.1?

    • @Ivan en qué parte o qué función es donde te regresa ese warning?

      • En la parte de la variable request. Creo que es cuando se define el TravelMode. Comente esa linea y ovbiamente me marco error. La volví a descomentar y se fue el error pero aparece el warning.

        var request = {
        origin: $(‘#origen’).val(),
        destination: $(‘#destino’).val(),
        travelMode: google.maps.DirectionsTravelMode[$('#modo_viaje').val()],
        unitSystem: google.maps.DirectionsUnitSystem[$('#tipo_sistema').val()],
        provideRouteAlternatives: true
        };

      • @Ivan ahhhh… es que debes tener un combo o algún elemento donde pueda extraer el dato, puede ser DRIVING, BICYCLING, WALKING, al igual que también te marcaría error en el unitSystem que debe ser METRIC o IMPERIAL, si no obtiene valores o no los colocas por default, generará alertas, porque hace falta ese parámetro

      • Si tengo los ComboBox o DropDown List, así como lo pusiste en el ejemplo:

        <select id="modo_viaje" class="opciones_ruta">
                <option value="DRIVING" selected="selected">Auto</option>
                <option value="BICYCLING">Bicicleta</option>
                <option value="WALKING">Caminando</option>
            </select>
            <select id="tipo_sistema" class="opciones_ruta">
                <option value="METRIC" selected="selected">Métrico</option>
                <option value="IMPERIAL">Imperial</option>
            </select>

Leave a Reply