Hace unos días que estoy para escribir este artículo pero por una cosa u otra se me queda en el tintero. Pero de hoy no pasa así que aquí va.
A raiz de intentar incluir el módulo GMap de Drupal, en un proyecto reciente, me vi en la necesidad de generar una nueva clave para incluir un mapa de google. Cual fué mi sorpresa al ver que esto ya no era posible desde la publicación de la versión 3 de la API de Google Maps. Tras dar alguna que otra vuelta por la documentación de esta conseguí crear el ejemplo básico de un mapa de Google usando API v3 ( lo cierto es que es bastante sencillo de crear y nos evitan el tener que crear la clave para cada dominio donde alojemos el mapa).
Pero me quedó el gusanillo de poder tener un mapa con varios puntos así que me puse a ello: teniendo un documento XML con los puntos y sus localizaciones:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <!-- http://geoco.org/espana-es.html --> <puntos> <punto> <titulo><![CDATA[Santander]]></titulo> <desc><![CDATA[Santander, home sweet home]]></desc> <url>http://www.ayto-santander.es</url> <latitud>43.464</latitud> <longitud>-3.8</longitud> </punto> <punto> <titulo><![CDATA[Barcelona]]></titulo> <desc><![CDATA[Barcelona, capital de Cataluña]]></desc> <url>http://www.bcn.es/</url> <latitud>41.38</latitud> <longitud>2.18</longitud> </punto> <punto> <titulo><![CDATA[Mérida]]></titulo> <desc><![CDATA[Cuidad monumental y arqueológica]]></desc> <url>http://www.merida.es/</url> <latitud>38.92</latitud> <longitud>-6.33</longitud> </punto> </puntos>
los cargaría con javascript ( la primera opción, no os mentiré, fue hacerlo con Prototype -porque tenía un ejemplo de lectura de un XML hecho con él, y luego con jQuery) y los mostraría en un sencillo documento HTML.
Carga de los datos con Prototype.
Si véis el contenido del fichero javascrpipt que realiza el proceso, xml.js , veréis algo como esto:
function obtenerPuntos( ) { var url = 'js/puntos.xml'; var myAjax = new Ajax.Request( url, { method: 'get', onComplete: renderResultsPuntos }); }
Que no es otra cosa que la lectura del fichero XML, con los datos, mediante Ajax y la asignación de esta lectura al objeto myAjax que se utiliza en la función que pinta el mapa, renderResultsPuntos().
function renderResultsPuntos(responseXMLSec) { var myZona = new Array(); var marker = new Array(); var contentString = new Array(); var infowindow = new Array(); var xml = responseXMLSec.responseXML.documentElement; var miDiv = document.getElementById('puntos-place'); var ptoMadrid = new google.maps.LatLng(40, -3.5); // Centramos el mapa en Madrid. var myOptions = { zoom: 6, center: ptoMadrid, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); for (i = 0; i < xml.getElementsByTagName('punto').length; i++) { var item = xml.getElementsByTagName('punto')[i]; // Accedemos al objeto XML seccion var urlDir = item.getElementsByTagName('url')[0].firstChild.data; var titulo = item.getElementsByTagName('titulo')[0].firstChild.data; var texto = limpiaStr(item.getElementsByTagName('desc')[0].firstChild.data); myZona[i] = new google.maps.LatLng( item.getElementsByTagName('latitud')[0].firstChild.data, item.getElementsByTagName('longitud')[0].firstChild.data); contentString[i] = '<div class="google-content">'+ '<h2>' + titulo + '</h2>'+ '<div class="bodyContent">'+ '<p>' + texto + '</p>'+ '<p>URL: <a href="'+urlDir+'">' + urlDir + '</a></p>'+ '</div>'+ '</div>'; infowindow[i] = new google.maps.InfoWindow({ content: contentString[i] }); marker[i] = new google.maps.Marker({ position: myZona[i], map: map, title: titulo }); eval ( "google.maps.event.addListener( marker[" + i + "], 'click', function() { infowindow["+i+"].open( map, marker["+i+"] ); })"); } }
Con lo que la creación de un mapa de Goole con Prototype queda completa.
Carga de los datos con jQuery.
En el caso de crear el mapa de Google con jQuery, ejecutamos el proceso dentro de la función, pintaMapa(), que realiza la petición Ajax al fichero de datos y, cuando esta se haya completado, pinta el mapa, ver fichero jquery.xml.
var myZona = new Array(); var marker = new Array(); var contentString = new Array(); var infowindow = new Array(); $(document).ready(function() { pintaMapa("map_canvas"); }); // general options for all ajax request $.ajaxSetup({ type: "GET", statusCode: { 404: function() { alert("page not found"); }, 500: function() { alert("Server error"); } } }); function pintaMapa(destID) { if ( $('#' + destID).length = 0 ) { return;} $.ajax({ dataType: 'text html', url: 'js/puntos.xml' }) .done(function(data){ xmlDoc = $.parseXML( data ); $xml = $( xmlDoc ); $puntos = $xml.find( "punto" ); if ( $puntos.length > 0 ) { var ptoCentro = new google.maps.LatLng(40, -3.5); // Madrid, aprox!!! var myOptions = { zoom: 6, center: ptoCentro, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById(destID), myOptions); var i = 0; $.each ( $puntos, function() { var titulo = $(this).find("titulo").text(); var url = $(this).find("url").text(); myZona[i] = new google.maps.LatLng($(this).find("latitud").text(), $(this).find("longitud").text()); contentString[i] = '<div class="google-content">'+ '<h2>' + titulo + '</h2>'+ '<div class="bodyContent">'+ '<p>' + $(this).find("desc").text() + '</p>'+ '<p>URL: <a href="'+url+'">' + url + '</a></p>'+ '</div>'+ '</div>'; infowindow[i] = new google.maps.InfoWindow({ content: contentString[i] }); marker[i] = new google.maps.Marker({ position: myZona[i], map: map, title: titulo }); eval ( "google.maps.event.addListener( marker[" + i + "], 'click', function() { infowindow["+i+"].open( map, marker["+i+"] ); })"); i++; }); } }); }
Una de las diferencias entre generar el mapa con Prototype o con jQuery es que en este segundo caso las variables donde se almacenan los puntos deben ser globales a todos el script. Antes de acabar deciros que seguro que el codigo fuente es muy mejorable pero por lo menos funciona.
Excelente aporte muchas gracias ayudo bastante. Si puedes has un articulo de como cambiar el marker
saludos y nuevamente gracias…
Hola Jonathan,
leyendo lo que dicen en la propia documentación [1], el cambio del marker no parece demasiado complicado. Si lo pruebas nos lo confirmas 🙂 Por cierto, aquí [2] tienes un montón de iconos para los marcadores
[1] https://developers.google.com/maps/documentation/javascript/overlays#Icons
[2] http://mapicons.nicolasmollet.com/
Hola Jorge,
Gracias y enhorabuena por el artículo, me ha servido de mucha ayuda, he utilizado la versión en JQuery, pero tengo un problema cuando se trata de IE (tanto en versión 8 cómo 9) y es que no me carga el mapa de GMaps.
He probado tu ejemplo, y sucede lo mismo.
http://www.nosoynadie.net/experimentos/gmap/jquery/
¿Conoces alguna solución?
Muchas Gracias.
Saludos.
Hola Victor,
a raiz de tu comentario, y de lo que comentan en Stackoverflow [1], he añadido las etiquetas <![CDATA[ ]]>, en el XML, para que no de problemas con los caracteres no convertidos a entidades HTML. Prueba ahora que ya debiera funcionar el ejemplo.
[1] http://stackoverflow.com/questions/10791551/google-map-v3-wont-load-in-ie9
🙁 No me funciona… veo varios .js pero al colocarlos en sus carpetas /js/xml.js no me aparece nada. tienes todo el codigo completo para descarga? 🙂 necesito poner 10 puntos
Saludos!!!
me aparece el error // page not found O.o
Hola Fernando,
¿qué versión estás utilizando? ¿La de jQuery o la de prototype? Al decir hablar del fichero xml.js me imagino que estés con la versión de prototype. Sin ver tu implementación en marcha no puedo saber qué está pasando así que te he comprimido el código de los dos ejemplos:
Ejemplo con prototype: http://www.nosoynadie.net/wp-content/uploads/2014/10/map-with-prototype.zip
Ejemplo con jQuery: http://www.nosoynadie.net/wp-content/uploads/2014/10/map-with-jquery.zip
Espero que esto te ayude.
🙂 Ya ví el problema, me faltaba llamar el jquery…min y ponerlo en el subdirectorio /../../ ya que estoy usando WP. Gracias por los ejemplos, ya nada mas me falta crear el XML para los 10 puntos de manera automatica. Saludos desde Mexico!