Versión 3 del API de JavaScript de Google Maps

Superposiciones

  1. Descripción general de las superposiciones
    1. Cómo añadir superposiciones
    2. Cómo eliminar superposiciones
  2. Símbolos
    1. Rutas predefinidas
  3. Marcadores
    1. Animaciones de marcador
    2. Cómo personalizar la imagen de marcador
      1. Iconos sencillos
      2. Iconos complejos
      3. Iconos vectoriales
  4. Polilíneas
    1. Opciones de polilíneas
    2. Conjuntos de polilíneas
    3. Símbolos en polilíneas
  5. Polígonos
    1. Opciones de polígonos
    2. Cierre automático de polígonos
    3. Conjuntos de polígonos
  6. Círculos y rectángulos
    1. Círculos
    2. Rectángulos
  7. Formas que pueden editar los usuarios
    1. Cómo editar eventos
  8. Biblioteca de dibujo
    1. Opciones de DrawingManager
    2. Cómo actualizar el control de las herramientas de dibujo
    3. Eventos de dibujo
  9. Ventanas de información
  10. Superposiciones de suelo
  11. Superposiciones personalizadas
    1. Cómo subclasificar una superposición
    2. Cómo inicializar una superposición personalizada
    3. Cómo dibujar una superposición personalizada
    4. Cómo eliminar una superposición personalizada
    5. Cómo mostrar y ocultar una superposición personalizada

Descripción general de las superposiciones

Las superposiciones son objetos del mapa que están vinculados a coordenadas de latitud y longitud, por lo que se mueven al arrastrar el mapa o aplicar el zoom sobre él. Las superposiciones son los objetos que "añades" al mapa para designar puntos, líneas, áreas o grupos de objetos.

Google Maps API incorpora varios tipos de superposiciones:

  • Los puntos en el mapa se muestran mediante marcadores. En algunas ocasiones, los marcadores pueden mostrar imágenes de iconos personalizados, que se denominan normalmente "iconos". Los marcadores e iconos son objetos de tipo Marker (para obtener más información, consulta las secciones Marcadores e Iconos que se incluyen más adelante).
  • Las líneas sobre el mapa se muestran mediante polilíneas, que representan una serie ordenada de ubicaciones. Las líneas son objetos de tipo Polyline (para obtener más información, consulta la sección Polilíneas).
  • Las áreas del mapa con forma irregular se muestran mediante polígonos, que son similares a las polilíneas. Al igual que las polilíneas, los polígonos representan una serie ordenada de ubicaciones; la diferencia estriba en que los polígonos definen la región que engloban (para obtener más información, consulta la sección Polígonos incluida más adelante).
  • Las capas de mapa se pueden visualizar mediante los tipos de mapas de superposición. Puedes crear un conjunto de mosaicos personalizado creando tipos de mapas personalizados que reemplacen los conjuntos de mosaicos de mapas base o se muestren sobre conjuntos de mosaicos de mapas base existentes en forma de superposiciones (para obtener más información, consulta Tipos de mapas personalizados).
  • La ventana de información es también un tipo de superposición especial para la visualización de contenido (normalmente texto o imágenes) en un globo emergente que se muestra sobre el mapa en una ubicación determinada (para obtener más información, consulta Ventanas de información).
  • Si quieres, también puedes implementar superposiciones personalizadas. Estas superposiciones personalizadas implementan la interfaz OverlayView (para obtener más información, consulta Superposiciones personalizadas).

Cómo añadir superposiciones

Las superposiciones se suelen añadir al mapa en el momento de su creación; todas las superposiciones definen un objeto Options que se utiliza durante la creación y que permite designar el mapa en el que deben aparecer. También puedes añadir una superposición mediante el método setMap() de la superposición, transmitiéndolo al mapa al que quieres añadir la superposición.

var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
  zoom: 4,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP,
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

var marker = new google.maps.Marker({
    position: myLatlng,
    title:"Hello World!"
});

// To add the marker to the map, call setMap();
marker.setMap(map);

Cómo eliminar superposiciones

Para eliminar una superposición de un mapa, ejecuta el método setMap() de la superposición, que transmite el valor null. Ten en cuenta que, al utilizar este método, la superposición no se elimina, sino que simplemente se suprime del mapa. Si lo que quieres es suprimir completamente la superposición, deberás eliminarla del mapa y, a continuación, establecerla en null.

Si quieres administrar varias superposiciones, deberás crear un conjunto que las incluya todas. Una vez creado este conjunto, podrás ejecutar setMap() en cada superposición del conjunto cuando necesites eliminarlas. Ten en cuenta que, al contrario de lo que ocurría en la versión 2, no existe ningún método clearOverlays(); es el usuario el que debe realizar un seguimiento de las superposiciones y eliminarlas del mapa cuando ya no sean necesarias. Para suprimir superposiciones, puedes eliminarlas del mapa y establecer el valor length del conjunto en 0, que elimina cualquier referencia hecha a las superposiciones.

En el ejemplo siguiente, se colocan marcadores en un mapa al hacer clic en él y los incluye en un conjunto. Después las superposiciones se pueden borrar, mostrar o suprimir:

var map;
var markersArray = [];

function initialize() {
  var haightAshbury = new google.maps.LatLng(37.7699298, -122.4469157);
  var mapOptions = {
    zoom: 12,
    center: haightAshbury,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };
  map =  new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  google.maps.event.addListener(map, 'click', function(event) {
    addMarker(event.latLng);
  });
}

function addMarker(location) {
  marker = new google.maps.Marker({
    position: location,
    map: map
  });
  markersArray.push(marker);
}

// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
  }
}

// Shows any overlays currently in the array
function showOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(map);
    }
  }
}

// Deletes all markers in the array by removing references to them
function deleteOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
    markersArray.length = 0;
  }
}

Ver ejemplo (overlay-remove.html)

Símbolos

Un elemento Symbol es una imagen basada en vectores que se puede mostrar tanto en un objeto Marker como Polyline. Los símbolos vienen definidos por una ruta (mediante la notación de ruta SVG) y las opciones que controlan cómo se mostrará el símbolo. Existen varios símbolos predefinidos que están disponibles a través de la clase SymbolPath. Aunque path es la única propiedad requerida, la clase Symbol admite gran variedad de propiedades que te permiten personalizar aspectos visuales, como el grosor y el color de fondo del trazo.

Para obtener más información sobre cómo mostrar o animar símbolos en una línea, consulta la documentación sobre símbolos en polilíneas. Para obtener más información sobre cómo utilizar una imagen de marcador, consulta la documentación sobre imágenes vectoriales que aparece a continuación.

El objeto Symbol admite las propiedades que se indican a continuación. Ten en cuenta que el comportamiento predeterminado de Symbol varía ligeramente en función de si aparece en un marcador o en una polilínea.

  • path (obligatoria) especifica la ruta que define la forma del símbolo. Puedes utilizar una de las rutas predefinidas en google.maps.SymbolPath o definir una ruta personalizada mediante la notación de ruta SVG. Nota: las rutas vectoriales en una polilínea deben estar incluidas en un cuadrado de 22x22 píxeles. Si tu ruta incluye puntos fuera de este cuadrado, tendrás que ajustar la propiedad de escala a un valor fraccional (por ejemplo, 0,2) para que el resultado de los puntos de la escala estén dentro del cuadrado.
  • anchor especifica la posición del símbolo en relación con el marcador o la polilínea. Las coordenadas X e Y del anclaje convierten las coordenadas de la ruta del símbolo en izquierda y arriba respectivamente. De forma predeterminada, los símbolos se anclan a elementos (0, 0). La posición se expresa en el mismo sistema de coordenadas que la ruta del símbolo.
  • fillColor especifica el color de relleno. Se admiten todos los colores CSS3 con excepción de los colores expresados mediante nombres. Para los marcadores de símbolos, el color predeterminado es el negro. Para los símbolos en polilíneas, el color predeterminado es el color de trazo de la polilínea correspondiente.
  • fillOpacity indica la opacidad del relleno del símbolo con un valor entre 0 y 1. El valor predeterminado es 0.
  • rotation especifica el ángulo de rotación del símbolo expresado en sentido de las agujas del reloj y en grados. De forma predeterminada, los marcadores de símbolos tienen una rotación de 0 y los símbolos en polilíneas definen su rotación según el ángulo del borde en el que se sitúan. Al establecer la rotación de un símbolo en una polilínea, se fijará la rotación del símbolo de forma que ya no pueda seguir la curva de la línea.
  • scale especifica la escala de tamaño que se aplica al símbolo. Para los marcadores de símbolos, el valor predeterminado es 1; una vez aplicada la escala, el símbolo puede tener cualquier tamaño. Para los símbolos en polilíneas, el valor predeterminado es el grosor del trazo de la polilínea; una vez aplicada la escala, el símbolo debe quedar comprendido en un cuadrado de 22x22 píxeles, centrado en el anclaje del símbolo.
  • strokeColor especifica el color de trazo del símbolo. Se admiten todos los colores CSS3 con excepción de los colores expresados mediante nombres. Para los marcadores de símbolos, el color predeterminado es el negro. Para los símbolos en polilíneas, el color predeterminado es el color de trazo de la polilínea.
  • strokeOpacity especifica la opacidad del trazo del símbolo con un valor entre 0 y 1. Para los marcadores de símbolos, el valor predeterminado es 1. Para los símbolos en polilíneas, el valor predeterminado de opacidad de trazo es el correspondiente a la opacidad de trazo de la polilínea.
  • strokeWeight especifica el grosor del trazo del símbolo. El valor predeterminado es el correspondiente al elemento scale del símbolo.

En el ejemplo que se muestra a continuación, se crea un símbolo con forma de estrella con un relleno amarillo claro y un borde grueso de color amarillo.

var goldStar = {
  path: 'M 125,5 155,90 245,90 175,145 200,230 125,180 50,230 75,145 5,90 95,90 z',
  fillColor: "yellow",
  fillOpacity: 0.8,
  scale: 1,
  strokeColor: "gold",
  strokeWeight: 14
};

var marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363, 131.044),
  icon: goldStar,
  map: map
});

Rutas predefinidas

El API de JavaScript de Google Maps ofrece algunos símbolos integrados que se pueden mostrar en marcadores o en polilíneas. Los símbolos predeterminados incluyen un círculo y dos tipos de flechas. Debido a que la orientación de un símbolo en una polilínea está fijada, están disponibles tanto las flechas que señalan hacia delante como hacia atrás. Se considera que la que la flecha que señala hacia delante sigue la dirección del final de la polilínea. Los símbolos que se incluyen son los siguientes:

Nombre Descripción Ejemplo
google.maps.SymbolPath.CIRCLE Un círculo
google.maps.SymbolPath.BACKWARD_CLOSED_ARROW Una flecha que señala hacia atrás y que está cerrada en todos sus lados
google.maps.SymbolPath.FORWARD_CLOSED_ARROW Una flecha que señala hacia delante y que está cerrada en todos sus lados
google.maps.SymbolPath.BACKWARD_OPEN_ARROW Una flecha que señala hacia atrás y que está abierta por un lado
google.maps.SymbolPath.FORWARD_OPEN_ARROW Una flecha que señala hacia delante y que está abierta por un lado

Puedes modificar el trazo o el relleno de los símbolos predefinidos utilizando cualquiera de las opciones predeterminadas del símbolo.

Marcadores

Los marcadores identifican ubicaciones en el mapa. De manera predeterminada, utilizan un icono estándar, aunque puedes establecer un icono personalizado dentro del constructor del marcador o mediante la ejecución de setIcon() en el marcador. El constructor google.maps.Marker toma un único objeto literal Marker options que especifica las propiedades iniciales del marcador. A continuación se indican algunos campos especialmente importantes que se suelen definir al crear un marcador.

  • position (obligatorio) especifica un valor de LatLng que identifica la ubicación inicial del marcador.
  • map (opcional) especifica el objeto Map en el que se sitúa el marcador.

Ten en cuenta que debes especificar el mapa en el que vas a añadir el marcador dentro del constructor Marker. Si no especificas este argumento, el marcador se creará, pero no se añadirá al mapa (o no mostrará). Puedes añadir el marcador más tarde mediante la ejecución del método setMap() del marcador. Para eliminar un marcador, ejecuta el método setMap() y transmite null como el argumento.

Los marcadores están diseñados para ser interactivos. De forma predeterminada, reciben eventos 'click', por ejemplo, y se suelen utilizar dentro de detectores de eventos para abrir ventanas de información. Puedes establecer la propiedad draggable de un marcador en true para que los usuarios puedan editar el marcador en el mapa.

En el siguiente ejemplo, se añade un marcador simple a un mapa de Uluru, en el centro de Australia:

  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var mapOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      title:"Hello World!"
  });

Este título de Marker se mostrará como información sobre la herramienta.

Si no quieres incluir ninguna opción del marcador (Marker options) en el constructor del marcador, incluye un objeto {} vacío en el último argumento del constructor.

Ver ejemplo (marker-simple.html)

Animaciones

También puedes animar los marcadores de forma que muestren un movimiento dinámico en numerosas circunstancias diferentes. La propiedad animation, del tipo google.maps.Animation, especifica la forma en que está animado un marcador. Actualmente, se admiten los siguientes valores Animation:

  • DROP indica que el marcador debe caer desde la parte superior del mapa hasta su ubicación definitiva en la que se colocase primero en el mapa. La animación finalizará una vez el marcador empiece a quedarse quieto y animation se restablezca a null. Este tipo de animación se suele especificar durante la creación del marcador (Marker).
  • BOUNCE indica que el marcador debe "rebotar" en el mismo sitio. Un marcador que rebota seguirá haciéndolo hasta que la propiedad animation se defina explícitamente en null.

Puedes iniciar una animación en un marcador existente ejecutando setAnimation() en el objeto Marker.

El siguiente ejemplo crea un marcador en Estocolmo (Suecia) con una animación DROP. Al hacer clic en el marcador, se alterna entre una animación BOUNCE o ninguna animación:

var stockholm = new google.maps.LatLng(59.32522, 18.07002);
var parliament = new google.maps.LatLng(59.327383, 18.06747);
var marker;
var map;

function initialize() {
  var mapOptions = {
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: stockholm
  };

  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  marker = new google.maps.Marker({
    map:map,
    draggable:true,
    animation: google.maps.Animation.DROP,
    position: parliament
  });
  google.maps.event.addListener(marker, 'click', toggleBounce);
}

function toggleBounce() {

  if (marker.getAnimation() != null) {
    marker.setAnimation(null);
  } else {
    marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}

Ver ejemplo (marker-animations.html)

Nota: si tienes varios marcadores, puede que no quieras utilizarlos todos a la vez en el mapa. Puedes utilizar setTimeout() para espaciar las animaciones de los marcadores mediante un patrón como el que se indica a continuación:

function drop() {
  for (var i =0; i < markerArray.length; i++) {
    setTimeout(function() {
      addMarkerMethod();
    }, i * 200);
  }
}

Ver ejemplo (marker-animations-iteration.html)

Cómo personalizar la imagen de marcador

Los marcadores permiten definir un icono para que se muestre en lugar del icono predeterminado. Para definir un icono, hay que establecer diferentes propiedades que definen el comportamiento visual del marcador.

Iconos sencillos

En el caso más básico, un icono puede simplemente indicar una imagen que se debe utilizar en lugar del icono predeterminado con forma de chincheta de Google Maps. Para ello se debe incluir la URL de una imagen en la propiedad icon del marcador. En este caso, el API de Google Maps definirá automáticamente el tamaño del icono.

El fragmento de código del siguiente ejemplo permite crear un icono para indicar la posición de Bondi Beach en Sídney, Australia:

function initialize() {
  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var mapOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var image = 'beachflag.png';
  var myLatLng = new google.maps.LatLng(-33.890542, 151.274856);
  var beachMarker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      icon: image
  });
}

Ver ejemplo (icon-simple.html)

Iconos complejos

Los iconos más complejos sirven para especificar formas complejas (que indican regiones en las que se puede hacer clic), para añadir imágenes de sombra y para especificar el "orden de apilamiento" en el que deben aparecer en relación a las demás superposiciones. Los iconos que se especifiquen de este modo deben establecer sus propiedades icon y shadow en un objeto del tipo MarkerImage.

Las imágenes de sombra deben crearse generalmente con un ángulo de 45 grados (hacia arriba y a la derecha) desde la imagen principal, y la esquina inferior izquierda de la imagen de sombra debe alinearse con la esquina inferior izquierda de la imagen del icono. Las imágenes de sombra deben ser imágenes PNG de 24 bits con transparencia alfa, de modo que los límites de la imagen se muestren correctamente en el mapa.

Los objetos MarkerImage no solo definen una imagen, sino que además definen el tamaño (size) y el origen (origin) del icono (por ejemplo, si la imagen en cuestión forma parte de una imagen más grande en un sprite), y el anclaje (anchor) donde debería encontrarse el punto de acceso del icono (que se basa en el origen).

El fragmento de código del ejemplo que aparece a continuación permite crear marcadores complejos que señalan playas cercanas a Sídney, Australia. Ten en cuenta que el anclaje anchor se ha establecido en (0,32) para que corresponda con la base del mástil de la bandera.

function initialize() {
  var mapOptions = {
    zoom: 10,
    center: new google.maps.LatLng(-33.9, 151.2),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"),
                                mapOptions);

  setMarkers(map, beaches);
}

/**
 * Data for the markers consisting of a name, a LatLng and a zIndex for
 * the order in which these markers should display on top of each
 * other.
 */
var beaches = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
  // Add markers to the map

  // Marker sizes are expressed as a Size of X,Y
  // where the origin of the image (0,0) is located
  // in the top left of the image.

  // Origins, anchor positions and coordinates of the marker
  // increase in the X direction to the right and in
  // the Y direction down.
  var image = new google.maps.MarkerImage('images/beachflag.png',
      // This marker is 20 pixels wide by 32 pixels tall.
      new google.maps.Size(20, 32),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0),
      // The anchor for this image is the base of the flagpole at 0,32.
      new google.maps.Point(0, 32));
  var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
      // The shadow image is larger in the horizontal dimension
      // while the position and offset are the same as for the main image.
      new google.maps.Size(37, 32),
      new google.maps.Point(0,0),
      new google.maps.Point(0, 32));
      // Shapes define the clickable region of the icon.
      // The type defines an HTML <area> element 'poly' which
      // traces out a polygon as a series of X,Y points. The final
      // coordinate closes the poly by connecting to the first
      // coordinate.
  var shape = {
      coord: [1, 1, 1, 20, 18, 20, 18 , 1],
      type: 'poly'
  };
  for (var i = 0; i < locations.length; i++) {
    var beach = locations[i];
    var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        shadow: shadow,
        icon: image,
        shape: shape,
        title: beach[0],
        zIndex: beach[3]
    });
  }
}

Ver ejemplo (icon-complex.html)

Iconos vectoriales

Los marcadores admiten la visualización tanto de imágenes de trama como de rutas vectoriales, denominadas Symbols. Para mostrar una ruta vectorial, transmite un objeto literal Symbol con la ruta deseada a la propiedad icon del marcador. Puedes utilizar una de las rutas predefinidas en google.maps.SymbolPath o definir una ruta personalizada mediante la notación de ruta SVG.

Para obtener más información sobre imágenes vectoriales en el API de JavaScript de Google Maps, consulta la documentación sobre símbolos.

El fragmento de código que se muestra en el siguiente ejemplo permite crear un icono mediante una de las rutas vectoriales predefinidas. Para obtener ejemplos más detallados, consulta la documentación sobre símbolos.

marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363882, 131.044922),
  icon: {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 10
  },
  draggable: true,
  map: map
});

Polilíneas

La clase Polyline define una superposición de segmentos lineales conectados sobre el mapa. Un objeto Polyline incluye un conjunto de ubicaciones LatLng y crea una serie de segmentos lineales que conectan dichas ubicaciones en una secuencia ordenada.

Opciones de polilíneas

El constructor Polyline toma un grupo de Polyline options que especifican las coordenadas LatLng de la línea y un conjunto de estilos que definen la forma en que se visualizará la polilínea.

Los objetos Polyline se representan en el mapa como una serie de líneas rectas. Puedes especificar colores, grosores y niveles de opacidad personalizados que se aplicarán al trazo de la línea en un objeto Polyline options al crear la línea, o bien cambiar estas propiedades después de su creación. A continuación se indican los estilos de trazo que admiten las polilíneas.

  • strokeColor especifica un color HTML hexadecimal del formato "#FFFFFF". La clase Polyline no admite colores con nombre.
  • strokeOpacity especifica un valor fraccional numérico entre 0.0 y 1.0 (predeterminado) correspondiente a la opacidad del color de la línea.
  • strokeWeight especifica el grosor del trazo de la línea en píxeles.

Por otra parte, la propiedad editable de una polilínea indica si esa forma pueden editarla los usuarios en el mapa.

El fragmento de código del siguiente ejemplo permite crear una polilínea de color rojo con un grosor de dos píxeles que conecta la ruta del primer vuelo sobre el Pacífico realizado por William Kingsford Smith entre Oakland (California, EE.UU.) y Brisbane (Australia):


function initialize() {
  var myLatLng = new google.maps.LatLng(0, -180);
  var mapOptions = {
    zoom: 3,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
  var flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892)
  ];
  var flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2
  });

  flightPath.setMap(map);
}

Ver ejemplo (polyline-simple.html)

Conjuntos de polilíneas

Una polilínea define una serie de coordenadas como un conjunto de objetos LatLng. Para recuperar estas coordenadas, ejecuta el objeto getPath() de Polyline, que devuelve un conjunto de tipo MVCArray. A continuación se indican una serie de operaciones que permiten manipular e inspeccionar estos conjuntos.

  • getAt() devuelve el objeto LatLng como un valor de índice basado en cero determinado.
  • insertAt() inserta un objeto LatLng transmitido en un valor de índice basado en cero determinado. Ten en cuenta que cualquier coordenada que exista en ese valor de índice se desplazará hacia delante.
  • removeAt() elimina un objeto LatLng de un valor de índice basado en cero determinado.

Nota: el elemento i de un conjunto no se puede eliminar simplemente mediante la sintaxis mvcArray[i], sino que debes utilizar mvcArray.getAt(i).

El fragmento de código que aparece a continuación permite crear un mapa interactivo que genera una polilínea basada en los clics del usuario. Ten en cuenta que la polilínea solo se muestra cuando la propiedad path contiene dos coordenadas LatLng.


var poly;
var map;

function initialize() {
  var chicago = new google.maps.LatLng(41.879535, -87.624333);
  var mapOptions = {
    zoom: 7,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

  var polyOptions = {
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3
  }
  poly = new google.maps.Polyline(polyOptions);
  poly.setMap(map);

  // Add a listener for the click event
  google.maps.event.addListener(map, 'click', addLatLng);
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * @param {MouseEvent} mouseEvent
 */
function addLatLng(event) {

  var path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(event.latLng);

  // Add a new marker at the new plotted point on the polyline.
  var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + path.getLength(),
    map: map
  });
}

Ver ejemplo (polyline-complex.html)

Símbolos en polilíneas

Puedes añadir imágenes basadas en vectores a una polilínea en forma de símbolo. Para mostrar símbolos en una polilínea, establece la propiedad icons[] del objeto PolylineOptions. El conjunto icons[] toma uno o más objetos literales IconSequence que se definen como se indica a continuación:

  • icon (obligatorio) indica el icono que se debe representar en la línea. Para obtener más información sobre cómo personalizar un símbolo, consulta la documentación sobre símbolos.
  • offset indica la distancia desde el inicio de la línea en la que se debe representar el icono. Esta distancia se puede expresar como un porcentaje de longitud de línea (por ejemplo, "50%") o en píxeles (por ejemplo, "50px"). El valor predeterminado es "100%".
  • repeat indica la distancia entre iconos consecutivos situados en la línea. Esta distancia se puede expresar como un porcentaje de longitud de línea (por ejemplo, "50%") o en píxeles (por ejemplo, "50px"). Para inhabilitar la repetición del icono, especifica "0". El valor predeterminado es 0.

Si tu polilínea es geodésica, las distancias especificadas para la compensación y la repetición se calculan en metros de forma predeterminada. Si estableces un valor en píxeles para la compensación o la repetición, las distancias se calcularán en píxeles en la pantalla.

Con una combinación de símbolos y la clase PolylineOptions, puedes controlar en gran medida el aspecto de las polilíneas en tu mapa. A continuación se proporcionan algunos ejemplos de personalizaciones que puedes aplicar.

Flechas

Utiliza la propiedad IconSequence.offset para añadir flechas al principio o al final de tu polilínea. En este ejemplo, al establecer la compensación en 100%, la flecha se coloca al final de la línea.

JavaScript
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: lineSymbol,
    offset: '100%'
  }],
  map: map
});
Demostración

Líneas discontinuas

Puedes conseguir un efecto de línea discontinua estableciendo la opacidad de tu polilínea en el 0% y dibujando un símbolo opaco a intervalos regulares.

JavaScript
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: 'M 0,-1 0,1',
  strokeOpacity: 1,
  scale: 4
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  strokeOpacity: 0,
  icons: [{
    icon: lineSymbol,
    offset: '0',
    repeat: '20px'
  }],
  map: map
});
Demostración

Rutas personalizadas

Los símbolos personalizados te permiten añadir muchas formas diferentes a una polilínea.

JavaScript
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var symbolOne = {
  path: 'M -2,0 0,-2 2,0 0,2 z',
  strokeColor: '#F00',
  fillColor: '#F00',
  fillOpacity: 1
};

var symbolTwo = {
  path: 'M -2,-2 2,2 M 2,-2 -2,2',
  strokeColor: '#292',
  strokeWeight: 4
};

var symbolThree = {
  path: 'M -1,0 A 1,1 0 0 0 -3,0 1,1 0 0 0 -1,0M 1,0 A 1,1 0 0 0 3,0 1,1 0 0 0 1,0M -3,3 Q 0,5 3,3',
  strokeColor: '#00F',
  rotation: 0
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: symbolOne,
    offset: '0%'
    },{
      icon: symbolTwo,
      offset: '50%'
    },{
      icon: symbolThree,
      offset: '100%'
    }
  ],
  map: map
});
Demostración

Símbolos animados

Los símbolos se pueden animar a lo largo de una ruta mediante una función setTimeout() para cambiar la compensación de un símbolo a intervalos fijos.

JavaScript
var line;

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(20.291, 153.027),
    zoom: 6,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  
  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
      
  var lineCoordinates = [
    new google.maps.LatLng(22.291, 153.027),
    new google.maps.LatLng(18.291, 153.027)
  ];

  var lineSymbol = {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 8,
    strokeColor: '#393'
  };

  line = new google.maps.Polyline({
    path: lineCoordinates,
    icons: [{
      icon: lineSymbol,
      offset: '100%'
    }],
    map: map
  });
}

function animateCircle() {
    var count = 0;
    offsetId = window.setInterval(function() {
      count = (count + 1) % 200;

      var icons = line.get('icons');
      icons[0].offset = (count / 2) + '%';
      line.set('icons', icons);
  }, 20);
}
Demostración

Polígonos

Los objetos Polygon son similares a los objetos Polyline en el sentido de que constan de una serie de coordenadas en una secuencia ordenada. No obstante, en lugar de tener los extremos abiertos, los polígonos están diseñados para definir las regiones con un bucle cerrado. De forma similar a lo que ocurre con las polilíneas, es posible definir el trazo, lo cual afecta al contorno del polígono; sin embargo, al contrario de lo que ocurre con las polilíneas, estos últimos permiten definir una región de relleno en su interior.

Por otro lado, los objetos Polygon ofrecen la posibilidad de mostrar formas complejas, que incluyen discontinuidades (varios polígonos definidos como uno solo), "donuts" (en los aparecen áreas poligonales dentro del polígono como si fueran "islas") e intersecciones entre uno o más polígonos. Por esta razón, un solo polígono puede definir varias rutas.

Opciones de polígonos

Al igual que ocurre con las polilíneas, puedes definir colores, grosores y niveles de opacidad personalizados para el borde del polígono (el "trazo"), así como colores y opacidades personalizados para el área que engloba (el "relleno"). Los colores se deben indicar en estilo HTML numérico hexadecimal.

Dado que un área poligonal puede incluir varios trazados diferentes, la propiedad paths del objeto Polygon especifica un "conjunto de conjuntos" (cada uno de ellos de tipo MVCArray), donde cada conjunto define una secuencia diferente de coordenadas LatLng ordenadas.

Sin embargo, en el caso de los polígonos simples que constan de una sola ruta, puedes construir un objeto Polygon con un único conjunto de coordenadas LatLng para una mayor comodidad. El API de Google Maps convierte este conjunto simple en un "conjunto de conjuntos" después de su creación al almacenarlo en la propiedad paths de Polygon. De la misma forma, el API proporciona métodos getPath() sencillos para polígonos simples que solo consten de una ruta.

Nota: aunque crees un polígono de esta forma, sigue siendo necesario que recuperes valores del polígono mediante la manipulación de la ruta como un objeto MVCArray.

Por otra parte, la propiedad editable de un polígono indica si esa forma pueden editarla los usuarios en el mapa.

El siguiente fragmento de código permite crear un polígono que representa el Triángulo de las Bermudas:


function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var mapOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737),
    new google.maps.LatLng(25.774252, -80.190262)
  ];

  // Construct the polygon
  // Note that we don't specify an array or arrays, but instead just
  // a simple array of LatLngs in the paths property
  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);
}

Ver ejemplo (polygon-simple.html)

Cierre automático de polígonos

El objeto Polygon del objeto anterior consta de cuatro coordenadas, pero fíjate en que la primera y la última coordenada corresponden a la misma ubicación, lo cual permite definir la región que engloba. Sin embargo, en la práctica, dado que lo polígonos definen áreas cerradas, no es necesario que definas esta última coordenada. El API de Google Maps "cierra" automáticamente cualquier polígono dibujando un trazo que une la última coordenada con la primera coordenada de una determinada ruta.

El ejemplo siguiente es idéntico al primero, con la excepción de la última coordenada, que se ha omitido.

Ver ejemplo (polygon-autoclose.html)

Conjuntos de polígonos

Un polígono especifica su serie de coordenadas como un conjunto de conjuntos, donde cada conjunto es de tipo MVCArray. Cada conjunto de "página" es un conjunto de coordenadas LatLng que especifican una única ruta. Para recuperar estas coordenadas, ejecuta el método getPaths() de Polygon. Dado que el conjunto es un objeto MVCArray, debes manipularlo e inspeccionarlo mediante las operaciones siguientes:

  • getAt() devuelve el objeto LatLng como un valor de índice basado en cero determinado.
  • insertAt() inserta un objeto LatLng transmitido en un valor de índice basado en cero determinado. Ten en cuenta que cualquier coordenada que exista en ese valor de índice se desplazará hacia delante.
  • removeAt() elimina un objeto LatLng de un valor de índice basado en cero determinado.

Nota: el elemento i de un conjunto no se puede eliminar simplemente mediante la sintaxis mvcArray[i], sino que debes utilizar mvcArray.getAt(i).

El siguiente fragmento de código permite procesar los eventos de clic en el polígono mostrando información sobre las coordenadas del polígono:


var map;
var infoWindow;

function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var mapOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737)
  ];

  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);

  // Add a listener for the click event
  google.maps.event.addListener(bermudaTriangle, 'click', showArrays);

  infowindow = new google.maps.InfoWindow();
}

function showArrays(event) {

  // Since this Polygon only has one path, we can call getPath()
  // to return the MVCArray of LatLngs
  var vertices = this.getPath();

  var contentString = "<b>Bermuda Triangle Polygon</b><br />";
  contentString += "Clicked Location: <br />" + event.latLng.lat() + "," + event.latLng.lng() + "<br />";

  // Iterate over the vertices.
  for (var i =0; i < vertices.length; i++) {
    var xy = vertices.getAt(i);
    contentString += "<br />" + "Coordinate: " + i + "<br />" + xy.lat() +"," + xy.lng();
  }

  // Replace our Info Window's content and position
  infowindow.setContent(contentString);
  infowindow.setPosition(event.latLng);

  infowindow.open(map);
}

Ver ejemplo (polygon-arrays.html)

Círculos y rectángulos

Además de una clase Polygon genérica, el API de JavaScript de Google Maps incluye clases específicas para Circle y Rectangle a fin de simplificar su construcción.

Círculos

Un círculo (Circle) es similar a un polígono (Polygon) en que puedes definir colores, grosores y niveles de opacidad personalizados para el borde del círculo (el "trazo"), así como colores y opacidades personalizados para el área que engloba (el "relleno"). Los colores se deben indicar en estilo HTML numérico hexadecimal.

A diferencia de un polígono (Polygon), no se definen rutas (paths) para un círculo (Circle); en su lugar, un círculo tiene dos propiedades adicionales que definen su forma:

  • center especifica los valores de latitud y longitud en Google Maps (google.maps.LatLng) del centro del círculo.
  • radius especifica el radio del círculo, en metros.

Por otra parte, la propiedad editable de un círculo indica si esa forma pueden editarla los usuarios en el mapa.

El siguiente fragmento de código permite crear un círculo que representa poblaciones de Estados Unidos:


// Create an object containing LatLng, population.
var citymap = {};
citymap['chicago'] = {
  center: new google.maps.LatLng(41.878113, -87.629798),
  population: 2842518
};
citymap['newyork'] = {
  center: new google.maps.LatLng(40.714352, -74.005973),
  population: 8143197
};
citymap['losangeles'] = {
  center: new google.maps.LatLng(34.052234, -118.243684),
  population: 3844829
}
var cityCircle;

function initialize() {
  var mapOptions = {
    zoom: 4,
    center: new google.maps.LatLng(37.09024, -95.712891),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  for (var city in citymap) {
    // Construct the circle for each value in citymap. We scale population by 20.
    var populationOptions = {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      center: citymap[city].center,
      radius: citymap[city].population / 20
    };
    cityCircle = new google.maps.Circle(populationOptions);
  }
}

Ver ejemplo (circle-simple.html)

Rectángulos

Un círculo (Rectangle) es similar a un polígono (Polygon) en que puedes definir colores, grosores y niveles de opacidad personalizados para el borde del rectángulo (el "trazo"), así como colores y opacidades personalizados para el área que engloba (el "relleno"). Los colores se deben indicar en estilo HTML numérico hexadecimal.

A diferencia de un polígono (Polygon), no se definen rutas (paths) para un rectángulo (Rectangle); en su lugar, un rectángulo tiene una propiedad bounds adicional que define su forma:

  • bounds especifica google.maps.LatLngBounds del rectángulo.

Por otra parte, la propiedad editable de un rectángulo indica si esa forma pueden editarla los usuarios en el mapa.

El siguiente ejemplo crea un rectángulo a partir de la ventana gráfica previa de cualquier evento 'zoom_changed':


function initialize() {

  var coachella = new google.maps.LatLng(33.6803003, -116.173894);
  var rectangle;

  var mapOptions = {
    zoom: 11,
    center: coachella,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  rectangle = new google.maps.Rectangle();

  google.maps.event.addListener(map, 'zoom_changed', function() {

    // Get the current bounds, which reflect the bounds before the zoom.
    var rectOptions = {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      bounds: map.getBounds()
    };
    rectangle.setOptions(rectOptions);
  });
}

Ver ejemplo (rectangle-simple.html)

Formas que pueden editar los usuarios

Todos los tipos de superposiciones de formas (polilíneas, polígonos, círculos y rectángulos) se pueden configurar como formas que pueden editar los usuarios estableciendo editable en true en las opciones de la forma correspondiente.

Para que los marcadores se puedan arrastrar, se debe establecer draggable en true en las opciones del marcador correspondiente.

var circleOptions = {
  center: new google.maps.LatLng(-34.397, 150.644),
  radius: 25000,
  map: map,
  editable: true
};
var circle = new google.maps.Circle(circleOptions);

Cuando una superposición de forma se configura para que puedan editarla los usuarios, se añaden a esa forma una serie de "controles" que permiten que los usuarios cambien la ubicación, la forma y el tamaño de la figura en cuestión directamente en el mapa.

Ver ejemplo (user-editable-shapes.html)

Los cambios realizados por los usuarios en los objetos no se conservan de una sesión a otra. Para guardar los cambios realizados en los polígonos, la información se debe obtener y almacenar manualmente.

Cómo editar eventos

Cuando se edita una forma, se activa un evento una vez finalizada la edición. A continuación se muestra una tabla de formas y eventos.

Forma Eventos
Círculo radius_changed
center_changed
Polígono insert_at
remove_at
set_at

El detector se debe establecer en la ruta del polígono. Si el polígono tiene varias rutas, se debe establecer un detector en cada una.

Polilínea insert_at
remove_at
set_at

El detector se debe establecer en la ruta de la polilínea.

Rectángulo bounds_changed
google.maps.event.addListener(circle, 'radius_changed', function() {
  radius = circle.getRadius();
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  print('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  print('Vertex removed from inner path.');
});

Biblioteca de dibujo

Los conceptos que se incluyen en este documento hacen referencia a recursos que solo están disponibles dentro de la biblioteca google.maps.drawing. Al cargar el API de JavaScript de Google Maps, esta biblioteca no cargará de forma predeterminada, pero se debe especificar explícitamente mediante la utilización de un parámetro de inicialización libraries.

http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing

Para obtener más información, consulta la documentación sobre las bibliotecas de la versión 3 del API de Google Maps.

La clase DrawingManagerproporciona una interfaz gráfica que permite que los usuarios dibujen polígonos, rectángulos, polilíneas, círculos y marcadores en el mapa. A continuación se indica cómo se puede crear un objeto DrawingManager:

var drawingManager = new google.maps.drawing.DrawingManager();
drawingManager.setMap(map);

Opciones de DrawingManager

El constructor de DrawingManagerutiliza un conjunto de opciones que definen el conjunto de controles que se deben mostrar, su posición y el estado de dibujo inicial.

  • La propiedad drawingMode de DrawingManager define el estado de dibujo inicial de DrawingManager. Esta propiedad acepta una constante google.maps.drawing.OverlayType. El valor predeterminado es null, que hace que el cursor se encuentre en modo de no dibujo cuando se inicializa DrawingManager.
  • La propiedad drawingControl de DrawingManager define la visibilidad de la interfaz de selección de herramientas de dibujo en el mapa. Esta propiedad admite un valor booleano.
  • También puedes definir la posición del control y los tipos de superposiciones que se deben representar en él mediante la propiedad drawingControlOptions de DrawingManager.
    • position define la posición del control de dibujo en el mapa y acepta una constante google.maps.ControlPosition.
    • drawingModesrepresenta un conjunto de constantes google.maps.drawing.OverlayType y define los tipos de superposiciones que se deben incluir en el selector de forma del control de dibujo. Siempre aparecerá el icono con forma de mano, que permite que el usuario interactúe con el mapa sin dibujar.
  • A cada tipo de superposición se le puede asignar un conjunto de propiedades predeterminadas que permite definir la apariencia de la superposición cuando se crea por primera vez. Estas propiedades se definen en la propiedad {overlay}Options de cada superposición (donde {overlay} representa el tipo de superposición). Por ejemplo, la posibilidad de hacer clic, la propiedad zIndex, las propiedades de trazo y las propiedades de relleno de un círculo se pueden definir con la propiedad circleOptions. Si se incluyen valores de mapa, ubicación o tamaño, se ignorarán. Para obtener información detallada sobre cuáles son las propiedades que se pueden definir, consulta la documentación de referencia del API.

    Sugerencia: para hacer que los usuarios puedan editar una forma una vez creada, se debe establecer la propiedad editable en true.

var drawingManager = new google.maps.drawing.DrawingManager({
  drawingMode: google.maps.drawing.OverlayType.MARKER,
  drawingControl: true,
  drawingControlOptions: {
    position: google.maps.ControlPosition.TOP_CENTER,
    drawingModes: [google.maps.drawing.OverlayType.MARKER, google.maps.drawing.OverlayType.CIRCLE]
  },
  markerOptions: {
    icon: new google.maps.MarkerImage('http://www.example.com/icon.png')
  },
  circleOptions: {
    fillColor: '#ffff00',
    fillOpacity: 1,
    strokeWeight: 5,
    clickable: false,
    zIndex: 1,
    editable: true
  }
});
drawingManager.setMap(map);

Ver ejemplo (drawing-tools.html)

Cómo actualizar el control de las herramientas de dibujo

Una vez creado, el objeto DrawingManager, se puede actualizar realizando una llamada al método setOptions() y especificando nuevos valores.

drawingManager.setOptions({
  drawingControlOptions: {
    position: google.maps.ControlPosition.BOTTOM_LEFT,
    drawingModes: [google.maps.drawing.OverlayType.MARKER]
  }
});

El siguiente fragmento de código permite mostrar u ocultar el control de las herramientas de dibujo:

// To hide:
drawingManager.setOptions({
  drawingControl: false
});

// To show:
drawingManager.setOptions({
  drawingControl: true
});

El siguiente fragmento de código permite eliminar el control de las herramientas de dibujo del objeto map:

drawingManager.setMap(null);

Al ocultar el control de dibujo, no aparece el control de las herramientas de dibujo, pero siguen estando disponibles todas las funciones de la clase DrawingManager. De esa forma, si quieres, puedes implementar tu propio control. Al eliminar DrawingManager del objeto map, se inhabilitan todas las funciones de dibujo. Para restaurar estas funciones, habrá que volver a asociarlo al mapa con drawingManager.setMap(map) o crear un nuevo objeto DrawingManager.

Eventos de dibujo

Cuando se crea una superposición de forma, se activan dos eventos:

  • un evento {overlay}complete (donde {overlay} representa el tipo de superposición, como circlecomplete, polygoncomplete, etc. y se transmite una referencia a la superposición como un argumento),
  • un evento overlaycomplete (un objeto literal, que contiene el elemento OverlayType y una referencia a la superposición, se transmite como un argumento).
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
  var radius = circle.getRadius();
});

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
  if (event.type == google.maps.drawing.OverlayType.CIRCLE) {
    var radius = event.overlay.getRadius();
  }
});

Ventanas de información

Las ventanas de información (InfoWindow) muestran contenido en una ventana flotante situada encima del mapa. La ventana de información tiene un aspecto ligeramente parecido al de los bocadillos de los cómics. Tiene un área de contenido y un pico afilado, cuyo extremo se encuentra en una ubicación especificada en el mapa. Puedes ver cómo funcionan las ventanas de información si haces clic en los marcadores de negocios de Google Maps.

El constructor InfoWindow utiliza un objeto InfoWindow options , que especifica un conjunto de parámetros iniciales para la visualización de la ventana de información. La ventana de información no se añade al mapa cuando se crea. Para mostrar la ventana de información, necesitas ejecutar el método open() en el objeto InfoWindow, transmitir el mapa (Map) en el que se va a abrir y, opcionalmente, el marcador (Marker) en el que se va a anclar. En caso de que no se especifique ningún marcador, la ventana de información se abrirá en su propiedad position.

El objeto InfoWindow options es un objeto literal que contiene los siguientes campos:

  • content contiene una cadena de texto o un nodo DOM que se mostrará cuando se abra la ventana de información.
  • pixelOffset contiene una compensación de la punta de la ventana de información con relación a la ubicación en la que dicha ventana está anclada. En la práctica, no debe ser necesario modificar este campo.
  • position contiene el objeto LatLng en el que se ancla esta ventana de información. Ten en cuenta que este valor se actualiza automáticamente con una nueva posición cuando se abre la ventana de información en un marcador.
  • maxWidth especifica la anchura máxima en píxeles de la ventana de información. De forma predeterminada, las ventanas de información se amplían para ajustarse a su contenido y ajustan el texto automáticamente si la ventana de información se amplía hasta cubrir el mapa. Si implementas un elemento maxWidth, la ventana de información se ajustará de manera automática para respetar el ancho en píxeles. Cuando se alcanza el ancho máximo, la ventana de información se puede expandir verticalmente si la pantalla dispone de espacio real.

El contenido de InfoWindow puede incluir una cadena de texto, un fragmento HTML o un elemento DOM. Para especificar este contenido, puedes trasmitirlo al constructor InfoWindow options o ejecutar setContent() explícitamente en el objeto InfoWindow. Si quieres especificar explícitamente el tamaño del contenido, puedes utilizar elementos <div> y, si quieres, habilitar el desplazamiento. Ten en cuenta que si no habilitas el desplazamiento y el contenido excede el espacio disponible en una ventana de información, dicho contenido puede salirse de la ventana de información.

Las ventanas de información (InfoWindow) pueden adjuntarse a objetos Marker (en cuyo caso su posición se basa en la ubicación del marcador) o al propio mapa en un objeto LatLng especificado. Si quieres que solo se muestre simultáneamente una ventana de información (como suele ocurrir en Google Maps), crea únicamente una ventana de información, que podrás reasignar a diferentes ubicaciones o marcadores en función de los eventos del mapa (por ejemplo, los clics del usuario). Sin embargo, a diferencia de lo que sucedía en la versión 2 del API de Google Maps, los mapas ahora pueden mostrar varios objetos InfoWindow, si así lo indicas.

Para cambiar la ubicación de la ventana de información, puedes ejecutar setPosition() explícitamente en la ventana de información o bien adjuntarla a un nuevo marcador mediante el método InfoWindow.open(). Ten en cuenta que si ejecutas open() sin transmitir un marcador, la ventana de información (InfoWindow) utilizará la posición especificada en la construcción mediante el objeto InfoWindow options.

El fragmento de código que aparece a continuación permite mostrar un marcador en el centro de Australia. Al hacer clic en el marcador, aparece la ventana de información.

var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
  zoom: 4,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

var contentString = '<div id="content">'+
    '<div id="siteNotice">'+
    '</div>'+
    '<h2 id="firstHeading" class="firstHeading">Uluru</h2>'+
    '<div id="bodyContent">'+
    '<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
    'sandstone rock formation in the southern part of the '+
    'Northern Territory, central Australia. It lies 335 km (208 mi) '+
    'south west of the nearest large town, Alice Springs; 450 km '+
    '(280 mi) by road. Kata Tjuta and Uluru are the two major '+
    'features of the Uluru - Kata Tjuta National Park. Uluru is '+
    'sacred to the Pitjantjatjara and Yankunytjatjara, the '+
    'Aboriginal people of the area. It has many springs, waterholes, '+
    'rock caves and ancient paintings. Uluru is listed as a World '+
    'Heritage Site.</p>'+
    '<p>Attribution: Uluru, <a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">'+
    'http://en.wikipedia.org/w/index.php?title=Uluru</a> (last visited June 22, 2009).</p>'+
    '</div>'+
    '</div>';

var infowindow = new google.maps.InfoWindow({
    content: contentString
});

var marker = new google.maps.Marker({
    position: myLatlng,
    map: map,
    title:"Uluru (Ayers Rock)"
});

google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map,marker);
});

Ver ejemplo (infowindow-simple.html)

A continuación aparece un ejemplo en el que el elemento maxWidth de la ventana de información se ha establecido en 200 píxeles:

Ver ejemplo (infowindow-simple-max.html)

Superposiciones de suelo

Los polígonos son superposiciones que resultan útiles para representar zonas de tamaño irregular, pero no permiten mostrar imágenes. Si tienes una imagen que quieres colocar en un mapa, puedes utilizar un objeto GroundOverlay. El constructor de un objeto GroundOverlay permite especificar la URL de una imagen y el objeto LatLngBounds de la imagen en forma de parámetros. La imagen se mostrará en el mapa, dentro de los límites establecidos y de acuerdo con la proyección del mapa.

En el ejemplo siguiente, se superpone un mapa antiguo de Newark (Nueva Jersey, EE.UU.) sobre uno reciente:

var newark = new google.maps.LatLng(40.740, -74.18);
var imageBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.716216,-74.213393),
    new google.maps.LatLng(40.765641,-74.139235));

var mapOptions = {
  zoom: 13,
  center: newark,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

var oldmap = new google.maps.GroundOverlay(
    "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg",
    imageBounds);
oldmap.setMap(map);

Ver ejemplo (groundoverlay-simple.html)

Superposiciones personalizadas

La versión 3 del API de Google Maps proporciona una clase OverlayView para crear tus propias superposiciones personalizadas. OverlayView es una clase base que proporciona diferentes métodos que debes implementar cuando crees tus superposiciones. Esta clase también proporciona algunos métodos que hacen posible la conversión entre las coordenadas de pantalla y las ubicaciones del mapa.

Para crear una superposición personalizada:

  • En la propiedad prototype del objeto define una nueva instancia de google.maps.OverlayView(). Esto establecerá eficazmente la clase de superposición como subclase.
  • Crea un constructor para tu superposición personalizada y, dentro de dicho constructor, establece las propiedades personalizadas en los parámetros de inicialización.
  • Implementa un método onAdd() en tu prototipo y adjunta la superposición al mapa. Se ejecutará OverlayView.onAdd() cuando el mapa esté preparado para que se le adjunte la superposición.
  • Implementa un método draw() en tu prototipo y define la visualización de tu objeto. OverlayView.draw() también se ejecutará cuando se muestre el objeto por primera vez.
  • También debes implementar un método onRemove() para eliminar cualquier elemento añadido en la superposición.

A continuación seguimos con la explicación.

Cómo subclasificar una superposición

Utilizaremos OverlayView para crear una superposición de imagen sencilla (de forma similar a GGroundOverlay en la versión 2 del API). Crearemos un objeto USGSOverlay que contenga una imagen del USGS de una zona en cuestión y los límites de la imagen.

var overlay;

function initialize() {
  var myLatLng = new google.maps.LatLng(62.323907, -150.109291);
  var mapOptions = {
    zoom: 11,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var swBound = new google.maps.LatLng(62.281819, -150.287132);
  var neBound = new google.maps.LatLng(62.400471, -150.005608);
  var bounds = new google.maps.LatLngBounds(swBound, neBound);

  // Photograph courtesy of the U.S. Geological Survey
  var srcImage = 'images/talkeetna.png';
  overlay = new USGSOverlay(bounds, srcImage, map);
}

A continuación, crearemos un constructor para esta clase e iniciaremos los parámetros trasmitidos como propiedades del nuevo objeto. Además, necesitaremos establecer como subclase explícita el objeto USGSOverlay de OverlayView. Para llevar a cabo esta acción, se establece la propiedad prototype de la nueva clase en una instancia de la clase principal (definimos el prototipo como una instancia en vez de definir la propia clase principal, puesto que no queremos modificar la clase principal).

function USGSOverlay(bounds, image, map) {

  // Now initialize all properties.
  this.bounds_ = bounds;
  this.image_ = image;
  this.map_ = map;

  // We define a property to hold the image's
  // div. We'll actually create this div
  // upon receipt of the add() method so we'll
  // leave it null for now.
  this.div_ = null;

  // Explicitly call setMap() on this overlay
  this.setMap(map);
}

USGSOverlay.prototype = new google.maps.OverlayView();

Todavía no podemos adjuntar esta superposición al mapa en el constructor de la superposición. En concreto, tenemos que asegurarnos de que todos los paneles del mapa (que especifican el orden en el que se muestran los objetos en un mapa) estén disponibles. De manera oportuna, el API proporciona un método ayudante para indicar que esto sucede así. Abordaremos este método en la próxima sección.

Cómo inicializar una superposición

Cuando la superposición ya se ha creado y está preparada para mostrarse, tenemos que adjuntarla al mapa mediante el DOM del navegador. El API indica que la superposición se ha añadido al mapa al ejecutar el método onAdd() de la superposición. Para procesar este método, hay que crear un elemento <div> para alojar nuestra imagen, añadir un elemento <img>, adjuntarlo al elemento <div> y, por último, adjuntar la superposición a uno de los paneles del mapa, que son nodos dentro del árbol DOM.

Este conjunto de paneles del tipo MapPanes especifica el orden de apilado de las diferentes capas del mapa. A continuación se muestran posibles paneles que están enumerados en el orden en que están apilados de abajo arriba:

  • MapPanes.mapPane
  • MapPanes.overlayLayer
  • MapPanes.overlayShadow
  • MapPanes.overlayImage
  • MapPanes.floatShadow
  • MapPanes.overlayMouseTarget
  • MapPanes.floatPane

Dado que nuestra imagen es una "superposición de suelo", utilizaremos el panel de mapa overlayLayer. Una vez tengamos el panel, le asociaremos nuestro objeto como objeto secundario.

USGSOverlay.prototype.onAdd = function() {

  // Note: an overlay's receipt of onAdd() indicates that
  // the map's panes are now available for attaching
  // the overlay to the map via the DOM.

  // Create the DIV and set some basic attributes.
  var div = document.createElement('div');
  div.style.border = "none";
  div.style.borderWidth = "0px";
  div.style.position = "absolute";

  // Create an IMG element and attach it to the DIV.
  var img = document.createElement("img");
  img.src = this.image_;
  img.style.width = "100%";
  img.style.height = "100%";
  div.appendChild(img);

  // Set the overlay's div_ property to this DIV
  this.div_ = div;

  // We add an overlay to a map via one of the map's panes.
  // We'll add this overlay to the overlayImage pane.
  var panes = this.getPanes();
  panes.overlayLayer.appendChild(div);
}

Cómo dibujar una superposición

Ten en cuenta que en realidad no hemos ejecutado todavía ninguna visualización especial. El API ejecuta un método draw() independiente en la superposición siempre que necesite dibujar la superposición en el mapa (incluso cuando se añade por primera vez).

Por tanto, implementaremos este método draw(), recuperaremos el objeto MapCanvasProjection de la superposición mediante getProjection() y calcularemos las coordenadas exactas en las que anclar los puntos inferior izquierdo y superior derecho del objeto, desde los que volveremos a definir el tamaño del elemento <div>, que a su vez define el tamaño de la imagen para que coincida con los límites que especificamos en el constructor de la superposición.

USGSOverlay.prototype.draw = function() {

  // Size and position the overlay. We use a southwest and northeast
  // position of the overlay to peg it to the correct position and size.
  // We need to retrieve the projection from this overlay to do this.
  var overlayProjection = this.getProjection();

  // Retrieve the southwest and northeast coordinates of this overlay
  // in latlngs and convert them to pixels coordinates.
  // We'll use these coordinates to resize the DIV.
  var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Resize the image's DIV to fit the indicated dimensions.
  var div = this.div_;
  div.style.left = sw.x + 'px';
  div.style.top = ne.y + 'px';
  div.style.width = (ne.x - sw.x) + 'px';
  div.style.height = (sw.y - ne.y) + 'px';
}

Cómo eliminar una superposición

Añadimos también un método onRemove() para eliminar perfectamente la superposición del mapa. Este método se ejecutará automáticamente desde el API si alguna vez establecemos la propiedad map de la superposición como null.

USGSOverlay.prototype.onRemove = function() {
  this.div_.parentNode.removeChild(this.div_);
  this.div_ = null;
}

Ver ejemplo (overlay-simple.html)

Cómo mostrar y ocultar una superposición

Si quieres ocultar o mostrar una superposición en lugar de simplemente crearla o eliminarla, puedes implementar tus propios métodos hide() y show() para ajustar la visibilidad de la superposición. También puedes desvincular la superposición del DOM del mapa, aunque el coste de esta operación es algo más elevado. Ten en cuenta que si vuelves a vincular la superposición al elemento DOM del mapa, se volverá a ejecutar el método onAdd() de la superposición.

En el siguiente ejemplo se añaden los métodos hide() (ocultar) y show() (mostrar) al prototipo de la superposición que alterna la visibilidad del elemento <div> del contenedor. Además, se añade un método toogleDOM() que vincula la superposición al mapa o la desvincula de este. Ten en cuenta que si se establece la visibilidad en "hidden" y, a continuación, se desvincula el mapa del elemento DOM a través de toggleDOM(), la superposición volverá a ser visible si volvemos a vincular el mapa, ya que se vuelve a crear el <div> contenedor en el método onAdd() de la superposición.

// Note that the visibility property must be a string enclosed in quotes
USGSOverlay.prototype.hide = function() {
  if (this.div_) {
    this.div_.style.visibility = "hidden";
  }
}

USGSOverlay.prototype.show = function() {
  if (this.div_) {
    this.div_.style.visibility = "visible";
  }
}

USGSOverlay.prototype.toggle = function() {
  if (this.div_) {
    if (this.div_.style.visibility == "hidden") {
      this.show();
    } else {
      this.hide();
    }
  }
}

USGSOverlay.prototype.toggleDOM = function() {
  if (this.getMap()) {
    this.setMap(null);
  } else {
    this.setMap(this.map_);
  }
}
// Now we add an input button to initiate the toggle method
// on the specific overlay
<div id ="toolbar" width="100%; height:20px;" style="text-align:center">
  <input type="button" value="Toggle Visibility" onclick="overlay.toggle();"></input>
  <input type="button" value="Toggle DOM Attachment" onclick="overlay.toggleDOM();"></input>
</div>
<div id="map_canvas" style="width: 100%; height: 95%;"></div>

Ver ejemplo (overlay-hideshow.html)

Autenticación obligatoria

Tienes que acceder a Google+ para realizar esta acción.

Acceder a...

Desarrolladores de Google necesita tu permiso para realizar esta acción.