Los mismos mapas de excelente calidad, además de un acuerdo de servicio, asistencia y control sobre los anuncios.
Las superposiciones son objetos del mapa vinculados a coordenadas de latitud y longitud, por lo que se mueven al arrastrar o aplicar el acercamiento sobre el mapa. Las superposiciones representan objetos que se añaden al mapa para designar puntos, líneas o zonas.
El API de Google Maps incorpora varios tipos de superposiciones:
GMarker y pueden utilizar el tipo GIcon.GPolyline.GTileLayerOverlay o mediante la creación de tu propio tipo de mapa con GMapType.GInfoWindow adjunto en cada mapa.Cada superposición implementa la interfaz GOverlay. Las superposiciones se pueden añadir al mapa mediante el método GMap2.addOverlay() y se pueden eliminar mediante el método GMap2.removeOverlay(). (Ten en cuenta que la ventana de información se añade al mapa de forma predeterminada).
Los marcadores identifican puntos del mapa. De forma predeterminada, utilizan G_DEFAULT_ICON, pero es posible especificar un icono personalizado. El constructor de GMarker utiliza GLatLng y un objeto opcional GMarkerOptions como argumentos.
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.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
map.addOverlay(new GMarker(point));
}
Ver ejemplo (marker-simple.html)
Los marcadores son objetos interactivos en los que puedes hacer clic para arrastrarlos a una nueva ubicación. En este ejemplo, colocamos un marcador arrastrable en el mapa y detectamos algunos de los eventos más sencillos. Los marcadores que se pueden arrastrar implementan cuatro tipos de eventos: click, dragstart, drag and dragend to indicate their drag status. De forma predeterminada, es posible hacer clic en los marcadores pero no arrastrarlos, por lo que es necesario inicializarlos con la opción de marcador adicional draggable definida como verdadera. Los marcadores que se pueden arrastrar también son animados de forma predeterminada. Si no te gusta este comportamiento, define la opción bouncy como falsa y desaparecerán sin hacer ruido.
var map = new GMap2(document.getElementById("map_canvas"));
var center = new GLatLng(37.4419, -122.1419);
map.setCenter(center, 13);
var marker = new GMarker(center, {draggable: true});
GEvent.addListener(marker, "dragstart", function() {
map.closeInfoWindow();
});
GEvent.addListener(marker, "dragend", function() {
marker.openInfoWindowHtml("Just bouncing along...");
});
map.addOverlay(marker);
Ver ejemplo (marker-drag.html)
Los marcadores pueden definir un icono para que se muestre en lugar del predeterminado. La definición de un icono es una tarea compleja, debido a la cantidad de imágenes diferentes que forman un icono en el API de Google Maps. Como mínimo, un icono debe definir la imagen en primer plano, el tamaño del tipo GSize y un desplazamiento de icono para determinar su posición.
Los iconos más sencillos se basan en el tipo G_DEFAULT_ICON. La creación de un icono basado en este tipo permite modificar rápidamente el icono predeterminado modificando únicamente unas pocas propiedades.
En el ejemplo siguiente, creamos un icono mediante el tipo G_DEFAULT_ICON y luego lo modificamos para utilizar una imagen diferente. (Ten cuidado al usar imágenes diferentes, ya que es necesario configurarlas con el tamaño de la imagen predeterminada para que se muestren correctamente).
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Create our "tiny" marker icon
var blueIcon = new GIcon(G_DEFAULT_ICON);
blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png";
// Set up our GMarkerOptions object
markerOptions = { icon:blueIcon };
// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
map.addOverlay(new GMarker(point, markerOptions));
}
Ver ejemplo (icon-simple.html)
La mayoría de los iconos contienen una imagen en primer plano y una imagen de sombra. La imagen de sombra debe crearse con un ángulo de 45 grados (hacia arriba y a la derecha) desde la imagen en primer plano, y la esquina inferior izquierda de la imagen de sombra debe alinearse con la esquina inferior izquierda de la imagen en primer plano 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.
En este ejemplo se va a crear un nuevo tipo de icono, con "mini" marcadores de Google Ride Finder como ejemplo. Tenemos que especificar la imagen de primer plano, la imagen de sombra y los puntos en los que vamos a anclar el icono al mapa y la ventana de información al icono. Ten en cuenta que el icono se pasa en las opciones definidas en el objeto GMarkerOptions.
var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Create our "tiny" marker icon
var tinyIcon = new GIcon();
tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
tinyIcon.iconSize = new GSize(12, 20);
tinyIcon.shadowSize = new GSize(22, 20);
tinyIcon.iconAnchor = new GPoint(6, 20);
tinyIcon.infoWindowAnchor = new GPoint(5, 1);
// Set up our GMarkerOptions object literal
markerOptions = { icon:tinyIcon };
// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
map.addOverlay(new GMarker(point, markerOptions));
}
Observa que la definición de los objetos GMarkerOptions demuestra el uso de la notación de objetos literales. No se crea una instancia del objeto mediante un constructor; en su lugar, simplemente se declara con pares nombre-valor.
Ver ejemplo (icon-complex.html)
Los objetos GIcon también tienen varias propiedades adicionales que debes definir para lograr la máxima compatibilidad con el navegador y funcionalidad de los iconos. Por ejemplo, la propiedad imageMap especifica la forma de las partes no transparentes de la imagen del icono. Si no defines esta propiedad en tu icono, la imagen completa del icono (incluida la transparencia) permitirá hacer clic en Firefox/Mozilla. Consulta las referencias sobre la clase GIcon para obtener más información.
En muchos casos, los iconos pueden tener distintos fondos, pero la misma forma y la misma sombra. La forma más sencilla de lograr este comportamiento es utilizar el constructor de copias de la clase GIcon, que copia todas las propiedades en un nuevo icono que posteriormente se puede personalizar.
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Create a base icon for all of our markers that specifies the
// shadow, icon dimensions, etc.
var baseIcon = new GIcon(G_DEFAULT_ICON);
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
// Creates a marker whose info window displays the letter corresponding
// to the given index.
function createMarker(point, index) {
// Create a lettered icon for this point using our icon class
var letter = String.fromCharCode("A".charCodeAt(0) + index);
var letteredIcon = new GIcon(baseIcon);
letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
// Set up our GMarkerOptions object
markerOptions = { icon:letteredIcon };
var marker = new GMarker(point, markerOptions);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml("Marker <b>" + letter + "</b>");
});
return marker;
}
// Add 10 markers to the map at random locations
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
map.addOverlay(createMarker(point, i));
}
Ver ejemplo (icon-custom.html)
La adición de un gran número de marcadores a un mapa de Google Maps puede reducir la velocidad del procesamiento del mapa y provocar muchos defectos visuales, especialmente con determinados niveles de acercamiento. La utilidad del administrador de marcadores proporciona una solución para ambos problemas, permite una visualización eficaz de cientos de marcadores en el mismo mapa y ofrece la posibilidad de especificar los niveles de zoom de los marcadores.
La utilidad del administrador de marcadores se proporciona con la biblioteca de utilidades de Google Maps. Esta biblioteca es de código abierto y ofrece utilidades que no forman parte del núcleo del API de Google Maps. Para añadir utilidades incluidas en esta biblioteca, basta con añadir el código JavaScript directamente mediante una etiqueta <script>.
<script src="http://gmaps-utility-library.googlecode.com/svn/trunk/markermanager/release/src/markermanager.js">
El objeto MarkerManager de la biblioteca markermanager.js descarga la administración de los marcadores registrados con la utilidad, realizando un seguimiento de los marcadores visibles en determinados niveles de acercamiento de la vista actual y pasando sólo estos marcadores al mapa a efectos de presentación. El administrador supervisa la vista y nivel de acercamiento actual del mapa, añadiendo o eliminando marcadores de forma dinámica del mapa a medida que pasan a estar activos. Además, al permitir a los marcadores especificar los niveles de acercamiento en los que deben mostrarse, los programadores pueden implementar el procesamiento de marcadores en clúster. Este tipo de administración permite aumentar enormemente la velocidad de representación y reducir el desorden visual.
Para usar un administrador de marcadores, crea un objeto MarkerManager. En el caso más sencillo, basta con pasarle un mapa.
var map = new GMap2(document.getElementById("map_canvas"));
var mgr = new MarkerManager(map);
También puedes especificar varias opciones para ajustar de forma precisa el rendimiento del administrador de marcadores. Estas opciones se pasan mediante un objeto MarkerManagerOptions, que contiene los siguientes campos:
maxZoom: especifica el nivel máximo de zoom supervisado por este administrador de marcadores. El valor predeterminado es el nivel de acercamiento máximo admitido por Google Maps.borderPadding: especifica el relleno adicional, en píxeles, supervisado por el administrador fuera de la ventana gráfica actual. Esto permite mostrar en el mapa marcadores que están fuera del área visible por muy poco, mejorando el desplazamiento en intervalos pequeños. El valor predeterminado es 100.trackMarkers: especifica si el administrador de marcadores debe realizar un seguimiento del movimiento de los movimientos de los marcadores. Si deseas administrar los marcadores que cambian de posición mediante el método setPoint(), define este valor en true. De forma predeterminada, esta marca se define como false. Ten en cuenta que si mueves los marcadores con este valor definido como false, aparecerán tanto en la ubicación original como en las nuevas.El objeto MarkerManagerOptions es un objeto literal, por lo que basta con declarar el objeto, no es necesario un constructor:
var map = new GMap2(document.getElementById("map_canvas"));
var mgrOptions = { borderPadding: 50, maxZoom: 15, trackMarkers: true };
var mgr = new MarkerManager(map, mgrOptions);
Una vez creado un administrador, desearás añadirle marcadores. MarkerManager admite la adición de marcadores individuales con el método addMarker() o un conjunto con el método addMarkers(). Los marcadores únicos añadidos mediante addMarker() aparecerán de inmediato en el mapa, siempre que cumplan los requisitos de la vista actual y el nivel de acercamiento especificado.
Recomendamos añadir los marcadores de forma colectiva mediante addMarkers(), ya que es un método más eficaz. Los marcadores añadidos mediante el método addMarkers() no se mostrarán en el mapa hasta que llames de forma explícita al método refresh() de MarkerManager, que añade al mapa todos los marcadores de la vista actual y la región de desplazamiento del borde. Después de esta presentación inicial, MarkerManager se encarga de todas las actualizaciones visuales, supervisando todos los eventos "moveend" del mapa.
En el siguiente ejemplo creamos un falso mapa meteorológico de Europa. Con el nivel de acercamiento 3, se muestran 20 iconos de clima con una distribución aleatoria. Con el nivel 6, que muestra las 200 ciudades que tienen una población superior a 300.000 habitantes, aparecen 200 marcadores adicionales. Finalmente, en el nivel 8, se muestran 1.000 marcadores. (Nota: para simplificar el ejemplo, los marcadores se añaden en posiciones aleatorias).
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(41, -98), 4);
window.setTimeout(setupWeatherMarkers, 0);
}
}
function getWeatherMarkers(n) {
var batch = [];
for (var i = 0; i < n; ++i) {
batch.push(new GMarker(getRandomPoint(), { icon: getWeatherIcon() }));
}
return batch;
}
function setupWeatherMarkers() {
mgr = new MarkerManager(map);
mgr.addMarkers(getWeatherMarkers(20), 3);
mgr.addMarkers(getWeatherMarkers(200), 6);
mgr.addMarkers(getWeatherMarkers(1000), 8);
mgr.refresh();
}
El administrador de marcadores también puede realizar una agrupación sencilla en clústeres de los marcadores. Aunque no se realiza automáticamente, puedes lograr el efecto deseado definiendo el nivel mínimo y máximo de acercamiento con el que se muestra un marcador determinado. En este ejemplo creamos un mapa de las oficinas de Google en Norteamérica. En el nivel más elevado, mostramos indicadores de los países en los que se encuentran las oficinas. En los niveles del 3 al 7 mostramos iconos en los núcleos de población en los que tenemos una o varias oficinas. En los niveles 8 y los superiores, mostramos marcadores individuales para cada oficina.
var officeLayer = [
{
"zoom": [0, 3],
"places": [
{ "name": "US Offices", "icon": ["us", "flag-shadow"], "posn": [40, -97] },
{ "name": "Canadian Offices", "icon": ["ca", "flag-shadow"], "posn": [58, -101] }
]
},
...
};
function setupOfficeMarkers() {
var mgr = new MarkerManager(map);
for (var i in officeLayer) {
var layer = officeLayer[i];
var markers = [];
for (var j in layer["places"]) {
var place = layer["places"][j];
var icon = getIcon(place["icon"]);
var posn = new GLatLng(place["posn"][0], place["posn"][1]);
markers.push(new GMarker(posn, { title: place["name"], icon: icon }));
}
mgr.addMarkers(markers, layer["zoom"][0], layer["zoom"][1]);
}
mgr.refresh();
}
Ver ejemplo (google_northamerica_offices.html)
Para obtener más información, consulta la documentación de referencia del administrador de marcadores de código abierto.
Los objetos GPolyline crean una superposición lineal en el mapa. Un objeto GPolyline consta de una serie de puntos y crea segmentos de líneas que conectan dichos puntos en una secuencia ordenada.
Las polilíneas se dibujan como una serie de segmentos rectos en el mapa. Puedes especificar valores personalizados de color, densidad y opacidad para las líneas. Los colores deben indicarse con códigos HTML hexadecimales (por ejemplo, #ff0000 en lugar de red). GPolyline no entiende los colores expresados mediante nombres.
Los objetos GPolyline utilizan las funciones de representación de vectores del navegador, si están disponibles. En Internet Explorer, Google Maps utiliza VML (consulta XHTML y VML) para dibujar polilíneas. En otros navegadores, se utiliza SVG si está disponible. En cualquier otra circunstancia, solicitamos una imagen de la línea de los servidores de Google y superponemos esa imagen en el mapa, actualizando la imagen según sea necesario a medida que el usuario arrastre el mapa o modifique el nivel de acercamiento.
El siguiente fragmento de código crea una polilínea roja de 10 píxeles de ancho entre dos puntos:
var polyline = new GPolyline([ new GLatLng(37.4419, -122.1419), new GLatLng(37.4519, -122.1519) ], "#ff0000", 10); map.addOverlay(polyline);
Ver ejemplo (polyline-simple.html)
Las polilíneas representadas en el mapa son líneas rectas respecto a la proyección actual. Es decir, se muestran rectas en el mapa, pero probablemente no tendrán en cuenta correctamente la curvatura de la Tierra. Si quieres dibujar una polilínea geodésica (un segmento de un gran círculo que represente la distancia más corta entre dos puntos de la superficie de la Tierra), deberás pasar geodesic:true en el argumento GPolylineOptions de GPolyline.
El argumento GPolylineOptions es un ejemplo de objeto literal. Los objetos literales no se construyen. En lugar de ello, se pasan los argumentos como una serie de pares de nombres y valores entre llaves. Los objetos literales se suelen utilizar en los casos en los que no es necesario generar instancias de los objetos.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(45.828799,-105.292969), 2);
// Create GPolylineOptions argument as an object literal.
// Note that we don't use a constructor.
var polyOptions = {geodesic:true};
var polyline = new GPolyline([
new GLatLng(40.65642, -73.7883),
new GLatLng(61.1699849, -149.944496)
], "#ff0000", 10, 1, polyOptions);
map.addOverlay(polyline);
Ver ejemplo (polyline-geodesic.html)
El objeto GPolyline de un mapa de Google Maps denota una línea como serie de puntos, haciendo que resulte sencilla de utilizar, pero no necesariamente compacta. Las líneas largas y complejas requieren una gran cantidad de memoria y puede ser necesario más tiempo para dibujarlas. Además, los segmentos individuales dentro de una polilínea no codificada se dibujan en el mapa, sea cual sea su resolución en niveles mayores de acercamiento.
El API de Google Maps permite representar rutas mediante polilíneas codificadas, que expresan una serie de puntos de una GPolyline mediante un formato comprimido de caracteres ASCII. La polilínea codificada también permite especificar grupos de niveles de acercamiento que deben omitirse al dibujar segmentos de líneas. Al hacerlo, podrás especificar el nivel de detalle que debe tener una polilínea en un nivel de acercamiento determinado. Aunque son más difíciles de configurar, las polilíneas codificadas hacen que las superposiciones se dibujen de forma mucho más eficaz.
Por ejemplo, un objeto GPolyline de 3 puntos (2 segmentos de línea) se representa normalmente del modo siguiente:
var polyline = new GPolyline([
new GLatLng(37.4419, -122.1419),
new GLatLng(37.4519, -122.1519),
new GLatLng( 37.4619, -122.1819)
], "#FF0000", 10);
map.addOverlay(polyline);
A continuación, observa un objeto GPolyline codificado con los mismos puntos (de momento, no te preocupes por los aspectos concretos del algoritmo de codificación).
var encodedPolyline = new GPolyline.fromEncoded({
color: "#FF0000",
weight: 10,
points: "yzocFzynhVq}@n}@o}@nzD",
levels: "BBB",
zoomFactor: 32,
numLevels: 4
});
map.addOverlay(encodedPolyline);
Hay dos cosas que debes tener en cuenta sobre este código.
GPolyline básico se emplean los valores habituales de latitud y longitud. El algoritmo para crear los puntos como una serie de valores ASCII codificados se documenta aquí. Este algoritmo es necesario si deseas calcular polilíneas codificadas sobre la marcha mediante un proceso de servidor, por ejemplo. No obstante, si únicamente deseas convertir puntos existentes a partir de latitudes y longitudes determinadas, puedes emplear nuestra utilidad interactiva.
GPolyline no codificados y resulta especialmente útil para que los dibujos se realicen rápidamente con niveles de acercamiento elevados, en los que los detalles de algunos segmentos de líneas pueden no ser relevantes. Por ejemplo, una polilínea codificada que represente un itinerario en coche de Nueva York a Chicago no debe tener en cuenta los segmentos de líneas que representen calles concretas cuando el acercamiento del mapa esté en el nivel del estado.
Ver ejemplo (polyline-encoding.html)
Utilidad de codificación de polilíneas interactiva
Consulta Algoritmo de polilíneas para obtener información sobre la superposición del algoritmo de polilíneas codificado.
Los objetos GPolygon se parecen a los objetos GPolyline en que consisten en una serie de puntos en una secuencia ordenada. No obstante, en lugar de tener extremos abiertos, los polígonos están diseñados para definir las regiones con un bucle cerrado. Al igual que con las polilíneas, es posible definir valores personalizados de color, peso y opacidad para el borde del polígono (la línea) y de color y opacidad para el relleno de la región delimitada. Los colores se deben indicar en formato HTML con códigos hexadecimales.
Los objetos GPolygon, al igual que los objetos GPolyline, utilizan las funciones de representación de vectores del navegador, si están disponibles.
El siguiente fragmento de código crea un cuadro de 10 píxeles de ancho entre cuatro puntos: Ten en cuenta que este polígono se "cierra" mediante la devolución de la ruta de segmento a su punto inicial; debes cerrar siempre los polígonos para evitar un comportamiento no definido.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.addControl(new GSmallMapControl());
GEvent.addListener(map, 'click', function(overlay, latlng) {
var lat = latlng.lat();
var lon = latlng.lng();
var latOffset = 0.01;
var lonOffset = 0.01;
var polygon = new GPolygon([
new GLatLng(lat, lon - lonOffset),
new GLatLng(lat + latOffset, lon),
new GLatLng(lat, lon + lonOffset),
new GLatLng(lat - latOffset, lon),
new GLatLng(lat, lon - lonOffset)
], "#f33f00", 5, 1, "#ff0000", 0.2);
map.addOverlay(polygon);
});
Ver ejemplo (polygon-simple.html)
Los polígonos son superposiciones útiles para representar zonas de tamaño arbitrario, pero no pueden mostrar imágenes. Si tienes una imagen que deseas colocar en un mapa, puedes utilizar un objeto GGroundOverlay. El constructor de
GGroundOverlay requiere una dirección URL de imagen y el objeto GLatLngBounds de la imagen como parámetros.
En el siguiente ejemplo, colocamos un mapa antiguo de Newark (Nueva Jersey) en el mapa en forma de superposición:
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(40.740, -74.18), 12);
// ground overlay
var boundaries = new GLatLngBounds(new GLatLng(40.716216,-74.213393), new GLatLng(40.765641,-74.139235));
var oldmap = new GGroundOverlay("http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg", boundaries);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.addOverlay(oldmap);
Ver ejemplo (groundoverlay-simple.html)
Dentro del API de Google Maps, el mapa consta de un conjunto de teselas que cubren la superficie completa de la Tierra en cada nivel de acercamiento. Existen mosaicos para cada tipo de mapa que se utilice: G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, and G_PHYSICAL_MAP. Los mosaicos no cubren todas las regiones en todos los niveles de zoom. Muchas zonas del océano Pacífico no se muestran en los niveles de acercamiento superiores, por ejemplo.
En el nivel de acercamiento inferior (nivel 0), un mosaico representa todo el planeta:
Cada nivel de acercamiento sucesivo divide el mapa en 4 teselas N, donde N hace referencia al nivel de acercamiento. Por ejemplo, en el nivel de acercamiento 1, Google Maps divide el mundo en una cuadrícula de 2 x 2, con un total de 4 teselas. En el nivel de acercamiento 2, Google Maps divide el mundo en una cuadrícula de 4 x 4, con un total de 16.
Si deseas modificar la presentación de estas teselas, tienes dos opciones:
GTileLayerOverlay.GMapType.El primer caso es mucho más sencillo, pero su uso es más limitado, mientras que el segundo permite un control superior sobre la visualización dentro de la aplicación. Cada caso se describe a continuación, aunque la implementación completa de un tipo de mapa personalizado escapa al alcance de esta documentación.
Cada caso requiere la implementación de tres métodos abstractos de la interfaz de GTileOverlay:
getTileUrl() devuelve al mapa una dirección URL que contiene la imagen del mosaico, a partir de los datos de GPoint y el nivel de acercamiento pasados.isPng() devuelve al mapa Boolean, que indica si la imagen es un archivo PNG (que se puede mostrar de forma invisible). Si el valor es true, se considera que la imagen es un archivo PNG.getOpacity() devuelve un valor entre 0,0 y 1,0 que indica el nivel de opacidad que debe mostrar la imagen.En las próximas dos secciones describiremos los distintos enfoques.
Si deseas que una superposición se muestre en un tipo de mapa existente, utiliza el objeto GTileLayerOverlay. Este objeto requiere crear un GCopyrightCollection y adjuntarlo a la capa del mosaico para indicar los permisos para utilizar las imágenes.
El siguiente código muestra una capa sencilla transparente en cada mosaico en todos los niveles de acercamiento, denotando el contorno de las teselas entre los retículos flotantes.
// Set up the copyright information
// Each image used should indicate its copyright permissions
var myCopyright = new GCopyrightCollection("© ");
myCopyright.addCopyright(new GCopyright('Demo',
new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)),
0,'©2007 Google'));
// Create the tile layer overlay and
// implement the three abstract methods
var tilelayer = new GTileLayer(myCopyright);
tilelayer.getTileUrl = function() { return "../include/tile_crosshairs.png"; };
tilelayer.isPng = function() { return true;};
tilelayer.getOpacity = function() { return 1.0; }
var myTileLayer = new GTileLayerOverlay(tilelayer);
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.addOverlay(myTileLayer);
Ver ejemplo (tileoverlay-simple.html)
Nota: este es un tema avanzado.
Si consideras que GTileLayerOverlay tiene demasiados límites, puedes definir tu propio tipo de mapa personalizado y desarrollar un paradigma de visualización totalmente nuevo. Para ello, construye un objeto GMapType y añádelo al mapa mediante el método GMap2.addMapType().
La creación de un tipo de mapa desde cero es un proceso muy complejo. Deberás crear un modo de definir y recuperar datos dinámicos para mostrar en el mapa a partir de las coordenadas actuales y tendrás que determinar el modo de generar referencias a imágenes de mosaico y mostrarlas. El modo en que decidas hacer todo esto depende de ti, pero podemos ayudarte un poco explicando cómo implementa Google Maps las referencias a mosaicos.
El API de Google Maps utiliza tres sistemas de coordenadas:
A continuación describiremos cada uno de los sistemas.
Cada tesela de Google Maps consta de 256 x 256 píxeles. Por lo tanto, es posible hacer referencia a una tesela concreto mediante un par de coordenadas x,y de GPoint. El origen (0,0) de cada tesela es la esquina noroeste del mosaico. Por lo tanto, para el mosaico que representa la Tierra completa, el origen está definido en el Polo Norte con una longitud de -180 grados, donde se observa Alaska. Los valores x (longitud) aumentan hacia el este, mientras que los valores y (latitud) aumentan hacia el sur, hasta llegar al punto más al sureste (255,255).
En los niveles de acercamiento superiores, el espacio de píxeles se expande al hacer clic en las direcciones x e y. Por ejemplo, en el nivel de acercamiento 1, el mapa consta de 4 teselas de 256 x 256 píxeles, generando un espacio de píxeles de 512 x 512. En el nivel de zoom 19, se puede hacer referencia a cada x y y píxel del mapa con un valor comprendido entre 0 y 256 * 219.
En muchas ocasiones, hacer referencia a un punto único en el mapa no resulta práctico. En los niveles de acercamiento superiores, el API de Google Maps no podría utilizar un único archivo de imagen para mostrar toda la Tierra. Por lo tanto, resulta útil determinar el mosaico de imagen que se está utilizando y procesar las coordenadas de píxeles en relación al origen de dicho mosaico. Cualquier mapa personalizado que implementes tendrá que realizar la misma evaluación.
Las teselas de Google Maps se numeran desde el mismo origen que los píxeles, de modo que la tesela de origen siempre se encuentre en la esquina noroeste del mapa. Las teselas se indexan mediante las coordenadas x,y desde dicho origen. Por ejemplo, en el nivel de acercamiento 2, cuando la Tierra se divide en 16 teselas, se puede hacer referencia a cada una de ellas mediante un par x,y exclusivo:
El indexado de un punto concreto en un nivel de acercamiento específico puede emplear dos valores GPoint: uno para hacer referencia al mosaico utilizado y otro para las coordenadas del píxel de la tesela en la imagen de 256 x 256.
La implementación de una superposición de mosaico en más de unos pocos niveles de acercamiento sencillos puede ser una tarea muy exigente, ya que sería necesario añadir lógica para determinar la imagen de mosaico concreto que debe servirse. El API de Google Maps permite construir un objeto GTileLayer pasando un argumento GTileLayerOptions como un objeto literal. El argumento GTileLayerOptions contiene una propiedad tileUrlTemplate que asigna las solicitudes de mosaicos de mapas a direcciones URL a partir de las coordenadas de mosaicos. El constructor de una superposición buscaría código similar al siguiente:
var tileLayerOverlay = new GTileLayerOverlay(
new GTileLayer(null, null, null, {
tileUrlTemplate: 'http://domain.com/myimage_{Z}_{X}_{Y}.png',
isPng:true,
opacity:1.0
})
);
map.addOverlay(tlo);
Este esquema de plantilla permite determinar la dirección de un conjunto de imágenes de teselas nombradas con las coordenadas de las teselas, de forma similar al funcionamiento de Google Maps.
Los mapas suelen incluir imágenes adquiridas, generadas o empleadas con licencia de entidades externas. A menudo estas imágenes requieren información de derechos de autor para que esté permitido mostrarlas y, en algunos casos (como los datos de satélite), las imágenes pueden proceder de distintos orígenes en distintas ubicaciones del mapa. Para proporcionar la capacidad de mostrar información de derechos de autor dinámica en los tipos de mapas personalizados, el API de Google Maps proporciona varios objetos que alojan la información de derechos de autor y ofrece métodos e interfaces para implementar la recuperación de esta información a partir de la vista y el nivel de acercamiento en cada momento.
GCopyright es un objeto sencillo que aloja información básica de derechos de autor. Las propiedades minZoom y bounds de este objeto definen los límites dentro de los cuales es válida esta información de derechos de autor. text contiene la cadena de derechos de autor que se mostrará bajo estas condiciones.
Los conjuntos de objetos GCopyright se recopilan en un objeto GCopyrightCollection. El constructor GCopyrightCollection permite definir un prefijo de texto (por ejemplo, "Imagery © 2007") para añadirlo a todos los avisos de derechos de autor. Ten en cuenta que no puedes añadir derechos de autor a GCopyrightCollection directamente desde el constructor. Debes llamar al método addCopyright para añadir objetos GCopyright individuales al conjunto una vez construido.
La interfaz de GTileLayer requiere un argumento copyrights en su constructor. Las clases que gestionan estas capas de mosaicos (como GTileLayerOverlay y GMapType) necesitan crear un objeto GCopyrightCollection de forma anticipada y pasarlo al constructor de la capa de mosaico.
El API de Google Maps implementa los métodos descritos a continuación para mostrar información de derechos de autor. Puedes omitirlos para ofrecer un comportamiento personalizado.
GMapType.getCopyrights() ejecuta GTileLayer.getCopyright() en todas sus capas de mosaicos secundarias.GTileLayer.getCopyright() ejecuta GCopyrightCollection.getCopyrightNotice() en su recopilación de derechos de autor.GCopyrightCollection.getCopyrightNotice() devuelve los avisos de derechos de autor adjuntos al objeto, comprobando si se aplican los valores de bounds y zoom proporcionados a cada uno de los objetos GCopyright hijos.Cada uno de estos métodos contiene parámetros bounds y zoom que puedes omitir e inspeccionar para decidir la información de derechos de autor que se debe mostrar.
De forma predeterminada, siempre que el API de Google Maps muestra una capa de mosaico en un tipo de mapa, recupera los derechos de autor utilizados mediante el método GTileLayer.getCopyright(). Algunos tipos de mapas pueden incluir varias capas de mosaicos, lo que puede significar que es necesario mostrar la información de varios objetos GCopyrightCollection al mismo tiempo. (El tipo de mapa G_HYBRID_MAP, por ejemplo, implementa una capa de satélite y una de mapa). Esta información simultánea se muestra encadenando avisos de derechos de autor de distintos conjuntos.
La Tierra es una esfera, mientras que un mapa es un objeto bidimensional plano. El mapa que ves en el API de Google Maps es una proyección de esa esfera en una superficie plana. Las proyecciones del API de Google Maps se implementan mediante la interfaz de GProjection. Actualmente sólo se implementa una proyección en el API de Google Maps: GMercatorProjection. En términos sencillos, una proyección se puede definir como una correspondencia uno a uno de valores GLatLng de coordenadas del mapa y la interfaz GProjection que proporciona utilidades de conversión para este fin.
El método GProjection.fromLatLngToPixel() convierte un valor de GLatLng en una coordenada de píxeles en un nivel de acercamiento determinado. De forma similar, el método GProjection.fromPixelToLatLng() convierte una coordenada de píxeles en un nivel de acercamiento determinado en un valor de GLatLng. Estos métodos resultan útiles al implementar un tipo de mapa, ya que permiten determinar el mosaico que se debe mostrar, el modo de mostrarlo y el desplazamiento que se debe emplear para ello.
El siguiente ejemplo gestiona los eventos de clic calculando las coordenadas de píxeles en el nivel de acercamiento actual y devuelve las coordenadas de píxeles y las de mosaico de la ubicación:
Ver ejemplo (tile-detector.html)
Para obtener más información acerca de la implementación de tipos de mapas, consulta las referencias sobre GMapType.
Los objetos GLayer se superponen a los objetos que almacenan un conjunto de información geográfica externa. Las capas son conjuntos de funciones relacionadas geográficamente que comparten alguna función común y que aparecen en un mapa en grupo. Google proporciona estos conjuntos de los datos obtenidos de otras fuentes y los agrupa dentro de una única capa.
Las capas suelen constar de varios elementos, por lo general marcadores, polilíneas y polígonos, aunque no se consideran objeto independientes. La capa en sí (y todos sus componentes) se considera una única superposición al API de Google Maps y se añade al mapa a través del método addOverlay() estándar. La capa también puede ser interactiva, lo que permite realizar acciones en sus componentes como, por ejemplo, abrir ventanas de información.
Cada capa contiene una ID de espacio de nombre única, de modo que se pueda hacer referencia a ella rápidamente y dirigirla de forma exclusiva. Esta ID de espacio de nombre se basa actualmente en el dominio de la capa de origen. La capa en inglés de artículos de Wikipedia © con identificadores geográficos, por ejemplo, tiene una ID de espacio de nombre igual a "org.wikipedia.en".
El API de Google Maps actualmente tiene acceso a estas capas públicas. Periódicamente, se irán añadiendo nuevas capas al API de Google Maps. Realizaremos el mantenimiento de esta lista en esta hoja de cálculo.
El siguiente fragmento de código añade una capa de Wikipedia en inglés a Greenwich Village, Cuidad de Nueva York:
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(40.730885,-73.997383), 15);
var myLayer = new GLayer("org.wikipedia.en");
map.addOverlay(myLayer);
}
}
Ver ejemplo (layer-simple.html)
El API de Google Maps también permite crear objetos de superposiciones personalizados implementando la interfaz GOverlay. El API de Google Maps proporciona varios servicios como, por ejemplo, los objetos GTrafficOverlay,GGeoXml y GStreetviewPanorama, mediante la implementación de la interfaz GOverlay. (Estos servicios están documentados en la sección Servicios).
La interfaz de GOverlay requiere la implementación de cuatro métodos abstractos:
initialize() llamado como respuesta a GMap2.addOverlay()remove() llamado como respuesta a GMap2.removeOverlay()copy() para permitir la generación de la plantilla de la nueva superposiciónredraw() llamado como respuesta a un cambio de visualización en el mapaLas interfaces del API de Google Maps se implementan en JavaScript a través de la asignación de la propiedad prototype a una instancia del objeto heredado. Por ejemplo, un objeto Rectangle heredaría de la interfaz de GOverlay mediante el siguiente código:
OverlaySubclass.prototype = new GOverlay();
La implementación de los métodos abstractos en la interfaz de GOverlay se facilita a través de la asignación de estos métodos en la característica prototype del objeto:
OverlaySubclass.prototype.initialize = myInitializeMethod; OverlaySubclass.prototype.remove = myRemoveMethod; OverlaySubclass.prototype.copy = myCopyMethod; OverlaySubclass.prototype.redraw = myRedrawMethod;
En el siguiente ejemplo, creamos una superposición Rectangle que muestra un contorno sobre una región geográfica del mapa. La clase Rectangle define los cuatro métodos que requiere la interfaz GOverlay. Concretamente, observa el método initialize(), que crea los elementos DOM que representan la superposición, y el método redraw(), que coloca la superposición en el mapa y le asigna un tamaño a partir de la proyección y el nivel de acercamiento de ese momento.
Cada elemento DOM que genera una superposición existe en un panel de mapa que define el orden z en el que se dibujará. Por ejemplo, las polilíneas son planas respecto al mapa, por lo que se dibujan en el G_MAP_MAP_PANE más bajo. Los marcadores colocan las sombras en el G_MAP_MARKER_SHADOW_PANE y los fondos en el G_MAP_MARKER_PANE. La colocación de los elementos de superposición en los paneles correctos garantizará que las polilíneas se dibujen bajo las sombras de los marcadores y que la ventana de información se dibuje sobre las demás superposiciones del mapa. En este ejemplo, nuestra superposición es plana respecto al mapa, por lo que la añadimos al panel de orden z más bajo, G_MAP_MAP_PANE, al igual que GPolyline. Consulta la referencia sobre la clase para obtener una lista completa de los paneles de mapa.
// A Rectangle is a simple overlay that outlines a lat/lng bounds on the
// map. It has a border of the given weight and color and can optionally
// have a semi-transparent background color.
function Rectangle(bounds, opt_weight, opt_color) {
this.bounds_ = bounds;
this.weight_ = opt_weight || 2;
this.color_ = opt_color || "#888888";
}
Rectangle.prototype = new GOverlay();
// Creates the DIV representing this rectangle.
Rectangle.prototype.initialize = function(map) {
// Create the DIV representing our rectangle
var div = document.createElement("div");
div.style.border = this.weight_ + "px solid " + this.color_;
div.style.position = "absolute";
// Our rectangle is flat against the map, so we add our selves to the
// MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
// below the marker shadows)
map.getPane(G_MAP_MAP_PANE).appendChild(div);
this.map_ = map;
this.div_ = div;
}
// Remove the main DIV from the map pane
Rectangle.prototype.remove = function() {
this.div_.parentNode.removeChild(this.div_);
}
// Copy our data to a new Rectangle
Rectangle.prototype.copy = function() {
return new Rectangle(this.bounds_, this.weight_, this.color_,
this.backgroundColor_, this.opacity_);
}
// Redraw the rectangle based on the current projection and zoom level
Rectangle.prototype.redraw = function(force) {
// We only need to redraw if the coordinate system has changed
if (!force) return;
// Calculate the DIV coordinates of two opposite corners of our bounds to
// get the size and position of our rectangle
var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Now position our DIV based on the DIV coordinates of our bounds
this.div_.style.width = Math.abs(c2.x - c1.x) + "px";
this.div_.style.height = Math.abs(c2.y - c1.y) + "px";
this.div_.style.left = (Math.min(c2.x, c1.x) - this.weight_) + "px";
this.div_.style.top = (Math.min(c2.y, c1.y) - this.weight_) + "px";
}
var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
// Display a rectangle in the center of the map at about a quarter of
// the size of the main map
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngDelta = (northEast.lng() - southWest.lng()) / 4;
var latDelta = (northEast.lat() - southWest.lat()) / 4;
var rectBounds = new GLatLngBounds(
new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
map.addOverlay(new Rectangle(rectBounds));