Marcas de Google Maps con menu contextual

En un post anterior hablaba de como añadir un tooltip personalizado a nuestras marcas de google maps, que permitia mostrar cualquier objeto DOM como si fuese un tooltip de la marca.

Siguiendo la misma idea, podemos hacer un menu contextual para las marcas, que se active al hacer click sobre ellas, y contenga acciones a ejecutar sobre la marca en cuestion.

Para ello seguiremos los siguientes pasos:

  1. Crear el menu y sus acciones
  2. Asignar el menu a la marca, y una referencia de la marca al menu para poder ejecutar acciones sobre ella
  3. Mostrar el menu con el evento onclick y ocultarlo al seleccionar una opción

ver ejemplo

Leave a Comment

Marcas de Google Maps con tooltip personalizado

Al situar el ratón encima de una imagen o cualquier elemento del DOM, éste es capaz de mostrar en un tooltip el texto de su atributo 'title',

ejemplo

En las marcas de Google Maps este efecto puede conseguirse especificando el atributo 'title' en el constructor de la marca.

  1. var coords = new GLatLng(41.647471, -0.885569);
  2. var mark = new GMarker(coords,  {title:'texto de ejemplo'})

ver ejemplo

El problema es que esta opción es muy limitada, ya que se restringe al uso de texto plano. Lo ideal sería poder mostrar cualquier elemento del DOM que queramos, con su HTML y su CSS.
Para conseguirlo vamos a seguir estos pasos:

  1. Crear el nodo del DOM que queramos mostrar o coger un nodo ya existente y ponerlo como un atributo de la marca
  2. Al escuchar el evento mouseover de la marca, añadir el nodo al div contenedor del mapa en el la posición en la que se encuentra la marca
  3. Al escuchar el evento mouseout de la marca, eliminar el nodo del div contenedor del mapa para ocultarlo.

ver ejemplo

Leave a Comment

Cómo limitar el zoom y el desplazamiento en Google Maps

En ocasiones nos interesa restringir el desplazamiento del usuario sobre el mapa a un área determinada, o limitar los niveles de zoom máximo y mínimo.

En el caso del zoom la solución es bastante sencilla. Solo hay que sobreescribir los métodos getMinimumResolution() y getMaximumResolution() de cada uno de los tipos de mapas GMapType presentes en nuestro mapa.
Para el caso del desplazamiento, la solución es algo más compleja. Consiste en escuchar el evento move, que es lanzado por el objeto GMap cuando hay un desplazamiento, y comprobar las coordenadas del mapa tras el desplazamiento. Si estas coordenadas quedan fuera del área a la que queremos limitar el desplazamiento, usamos el metodo GMap.setCenter para que el mapa quede dentro de nuesta área.

Esta clase implementa la funcionalidad deseada:

  1. /******  TRestricter  **********************************************/
  2.  
  3. // Constructor
  4. TRestricter = function (map) {
  5. this.map = map;
  6. }
  7. // Función que activa la limitación del desplazamiento entre la esquina inferior izquierda
  8. // y la esquina superior derecha
  9. TRestricter.prototype.restrict = function (sw, ne) {
  10. this.map._allowedBounds = new GLatLngBounds(sw, ne);
  11. GEvent.addListener(this.map, 'move', this.checkBounds);
  12. }
  13. // Función que desactiva la limitación del desplazamiento
  14. TRestricter.prototype.unrestrict = function () {
  15. this.map._allowedBounds = null;
  16. }
  17. // Listener encargado de comprobar el desplazamiento
  18. TRestricter.prototype.checkBounds = function() {
  19. if (!this._allowedBounds || this._allowedBounds.contains(this.getCenter())) return;
  20. var x = Math.min(Math.max(this.getCenter().lng(), this._allowedBounds.getSouthWest().lng()), this._allowedBounds.getNorthEast().lng());
  21. var y = Math.min(Math.max(this.getCenter().lat(), this._allowedBounds.getSouthWest().lat()), this._allowedBounds.getNorthEast().lat());
  22. this.setCenter(new GLatLng(y,x));
  23. }
  24. // Establece los límites de zoom del mapa
  25. TRestricter.prototype.zoomLevels = function (min, max) {
  26. var array = this.map.getMapTypes() || [];
  27. for (var i=0; i
  28. array[i].getMinimumResolution = function () { return min };
  29. array[i].getMaximumResolution = function () { return max };
  30. }
  31. }

Y aquí tenemos un ejemplo de la clase en acción

Leave a Comment

Problemas con Google Maps

Como siempre que se desarrolla una aplicación, aparecen errores que nos dan multitud de quebraderos de cabeza.
Ahí van unos cuantos con los que me he enfrentado trabajando con Google Maps.

  • El fondo del mapa se ve totalmente en gris
    Casi seguro es porque alguna propiedad css está interfiriendo con el mapa. Un caso en el que aparece es con la propiedada overflow:hidden.
  • El fondo del mapa se ve parcialmente gris, y el centro se sitúa en la esquina superior izquierda
    Esto ocurre porque cuando la api de google maps carga el mapa, el div contenedor que ha sido pasado como argumento al constructor GMap2 tiene tamaño cero. El trozo de mapa que se ve es realmente el trozos que queda fuera de los limites de visión pero es cargado para mejorar el rendimiento al desplazar el mapa.
    Que el div contendor tenga tamaño cero, suele ocurrir cuando está dentro de una tabla o tiene el tamaño especificado con porcentajes. Hasta que el DOM no se carga completamente, el div no adquiere un tamaño definido, y en el momento en el que se carga el mapa aun no tiene su tamaño final.
    Se puede solucionar especificando el ancho (width) y alto (height) del contendor sin porcentajes o especificando directamente el tamaño del mapa con un argumento en el constructor GMap2:

    new GMap2(container, {size:new GSize(width,  height)})
  • Object cannot be created in this context" code: "9" ... (NS_ERROR_DOM_NOT_SUPPORTED_ERR)
    Este error suele aparecer en firefox cuando el mapa se inserta en una pagina JSF con Facelets.Es debido a que el objeto 'document' de javascript creado por firefox cuando el mime type es 'application/xhtml+xml', no tiene el metodo write().
    Para solucionarlo tienes que establecer el content type de la pagina como text/html. Con JSF se puede hacer añadiendo el tag

    		<f contenttype="text/html" />

    en la página que contenga el mapa (No afecta a facelets ni al funcionamiento de la pagina).

Leave a Comment