La versión 2 de la API de Maps JavaScript dejó de estar disponible el 26 de mayo de 2021. Como resultado, los mapas v2 de tu sitio dejarán de funcionar y mostrarán errores de JavaScript. Para seguir usando mapas en tu sitio, migra a la versión 3 de la API de Maps JavaScript. Esta guía te ayudará a realizar el proceso.
Descripción general
Cada aplicación tendrá un proceso de migración ligeramente diferente.
Sin embargo, hay algunos pasos que son comunes a todos los proyectos:
- Obtén una clave nueva. La API de Maps JavaScript ahora usa la consola de Google Cloud para administrar las claves. Si aún usas una clave de la versión 2, asegúrate de obtener tu clave de API nueva antes de comenzar la migración.
- Actualiza el bootstrap de tu API. La mayoría de las aplicaciones cargarán la versión 3 de la API de Maps JavaScript con el siguiente código:
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
- Actualiza tu código. La cantidad de cambios necesarios dependerá mucho de tu aplicación. Entre los cambios comunes, se incluyen los siguientes:
- Siempre haz referencia al espacio de nombres google.maps. En la versión 3, todo el código de la API de Maps JavaScript se almacena en el espacio de nombres
google.maps.*
en lugar del espacio de nombres global. La mayoría de los objetos también cambiaron de nombre como parte de este proceso. Por ejemplo, en lugar de GMap2
, ahora cargarás google.maps.Map
.
- Quita las referencias a métodos obsoletos. Se quitaron varios métodos de utilidad general, como
GDownloadURL
y GLog
.
Reemplaza esta funcionalidad con bibliotecas de utilidades de terceros o quita estas referencias de tu código.
- (Opcional) Agrega bibliotecas a tu código. Muchas funciones se externalizaron en bibliotecas de utilidad para que cada app solo tenga que cargar las partes de la API que se usarán.
- (Opcional) Configura tu proyecto para usar los objetos externos de la versión 3.
Los elementos externos de v3 se pueden usar para validar tu código con el compilador de Closure o para activar el autocompletado en tu IDE.
Obtén más información sobre
la compilación avanzada y los objetos externos.
- Prueba y itera. En este punto, aún tendrás trabajo por hacer, pero la buena noticia es que estarás bien encaminado hacia tu nueva aplicación de mapas de la versión 3.
Cambios en la versión 3 de la API de Maps JavaScript
Antes de planificar tu migración, debes tomarte el tiempo para comprender las diferencias entre la API de Maps JavaScript v2 y la API de Maps JavaScript v3. La versión más reciente de la API de Maps JavaScript se escribió desde cero, con un enfoque en las técnicas de programación modernas de JavaScript, un mayor uso de bibliotecas y una API simplificada.
Se agregaron muchas funciones nuevas a la API, y se cambiaron o incluso quitaron varias funciones conocidas. En esta sección, se destacan algunas de las diferencias clave entre las dos versiones.
Entre algunos de los cambios en la API v3 se incluyen los siguientes:
- Una biblioteca central simplificada. Muchas de las funciones complementarias se movieron a bibliotecas, lo que ayuda a reducir los tiempos de carga y análisis de la API de Core, lo que permite que tu mapa se cargue rápidamente en cualquier dispositivo.
- Se mejoró el rendimiento de varias funciones, como la renderización de polígonos y la ubicación de marcadores.
- Un nuevo enfoque de los límites de uso del cliente para adaptarse mejor a las direcciones compartidas que usan los proxies móviles y los firewalls corporativos.
- Se agregó compatibilidad con varios navegadores modernos y navegadores para dispositivos móviles. Se quitó la compatibilidad con Internet Explorer 6.
- Se quitaron muchas de las clases de ayuda de uso general (
GLog
o
GDownloadUrl
). Actualmente, existen muchas bibliotecas de JavaScript excelentes que proporcionan funciones similares, como Closure o jQuery.
- Una implementación de Street View HTML5 que se carga en cualquier dispositivo móvil.
- Panorámicas personalizadas de Street View con tus propias fotos, que te permiten compartir panorámicas de pistas de esquí, casas en venta y otros lugares interesantes.
- Personalizaciones de mapas con diseños que te permiten cambiar la visualización de los elementos del mapa base para que coincidan con tu estilo visual único.
- Compatibilidad con varios servicios nuevos, como ElevationService y Distance Matrix.
- Un servicio de instrucciones mejoradas proporciona rutas alternativas, optimización de rutas (soluciones aproximadas al
problema del viajante), instrucciones para ir en bicicleta (con
capa de ciclismo), instrucciones para ir en transporte público y
instrucciones para arrastrar.
- Un formato de Geocoding actualizado que proporciona información de type más precisa que el valor
accuracy
de la versión 2 de la API de Geocoding.
- Compatibilidad con varias ventanas de información en un solo mapa
Tu clave nueva
La versión 3 de la API de Maps JavaScript usa un nuevo sistema de claves de la versión 2. Es posible que ya uses una clave de la versión 3 con tu aplicación, en cuyo caso no es necesario realizar ningún cambio. Para verificarlo, revisa la URL desde la que cargas la API de Maps JavaScript en busca de su parámetro key
. Si el valor de la clave comienza con "ABQIAA", estás usando una clave de v2. Si tienes una clave de v2, debes actualizar a una clave de v3 como parte de la migración, lo que hará lo siguiente:
La clave se pasa cuando se carga la API de Maps JavaScript v3.
Obtén más información para generar claves de API.
Ten en cuenta que, si eres cliente de las APIs de Google Maps for Work, es posible que uses un ID de cliente con el parámetro client
en lugar del parámetro key
. Los IDs de cliente aún son compatibles con la versión 3 de la API de Maps JavaScript y no es necesario que pasen por el proceso de actualización de claves.
Cómo cargar la API
La primera modificación que deberás realizar en tu código implica la carga de la API. En la versión 2, cargas la API de Maps JavaScript a través de una solicitud a http://maps.google.com/maps
. Si cargas la versión 3 de la API de Maps JavaScript, deberás realizar los siguientes cambios:
- Carga la API desde
//maps.googleapis.com/maps/api/js
- Quita el parámetro
file
.
- Actualiza el parámetro
key
con tu nueva clave de la versión 3. Los clientes de las APIs de Google Maps for Work deben usar un parámetro client
.
- (Solo para el plan premium de Google Maps Platform) Asegúrate de que se proporcione el parámetro
client
como se explica en la
Guía para desarrolladores del plan premium de Google Maps Platform.
- Quita el parámetro
v
para solicitar la versión publicada más reciente o cambia su valor según el esquema de control de versiones v3.
- (Opcional) Reemplaza el parámetro
hl
por language
y conserva su valor.
- (Opcional) Agrega un parámetro
libraries
para cargar bibliotecas opcionales.
En el caso más simple, el inicio de la v3 solo especificará tu parámetro de clave de API:
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
En el siguiente ejemplo, se solicita la versión más reciente de la v2 de la API de Maps JavaScript en alemán:
<script src="//maps.google.com/maps?file=api&v=2.x&key=YOUR_API_KEY&hl=de"></script>
El siguiente ejemplo es una solicitud equivalente para v3.
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&language=de"></script>
Presentación del espacio de nombres google.maps
Probablemente, el cambio más notable en la API de Maps JavaScript v3 es la introducción del espacio de nombres google.maps
. La API de v2 coloca todos los objetos en el espacio de nombres global de forma predeterminada, lo que puede generar colisiones de nombres. En la versión 3, todos los objetos se encuentran dentro del espacio de nombres google.maps
.
Cuando migres tu aplicación a la versión 3, deberás cambiar el código para usar el nuevo espacio de nombres. Lamentablemente, buscar "G" y reemplazarlo por "google.maps" no funcionará por completo, pero es una buena regla general que puedes aplicar cuando revises tu código. A continuación, se muestran algunos ejemplos de las clases equivalentes en la v2 y la v3.
v2 |
v3 |
GMap2 |
google.maps.Map |
GLatLng |
google.maps.LatLng |
GInfoWindow |
google.maps.InfoWindow |
GMapOptions |
google.map.MapOptions |
G_API_VERSION |
google.maps.version |
GPolyStyleOptions |
google.maps.PolygonOptions or
google.maps.PolylineOptions |
Quitar el código obsoleto
La versión 3 de la API de Maps JavaScript tiene paralelismos para la mayoría de las funciones de la versión 2. Sin embargo, hay algunas clases que ya no son compatibles. Como parte de la migración, debes reemplazar estas clases por bibliotecas de utilidades de terceros o quitar estas referencias de tu código. Existen muchas bibliotecas de JavaScript excelentes que proporcionan funcionalidades similares, como Closure o jQuery.
Las siguientes clases no tienen un equivalente en la versión 3 de la API de Maps JavaScript:
GBounds | GLanguage |
GBrowserIsCompatible | GLayer |
GControl | GLog |
GControlAnchor | GMercatorProjection |
GControlImpl | GNavLabelControl |
GControlPosition | GObliqueMercator |
GCopyright | GOverlay |
GCopyrightCollection | GPhotoSpec |
GDownloadUrl | GPolyEditingOptions |
GDraggableObject | GScreenOverlay |
GDraggableObjectOptions | GStreetviewFeatures |
GFactualGeocodeCache | GStreetviewLocation |
GGeoAddressAccuracy | GStreetviewOverlay |
GGeocodeCache | GStreetviewUserPhotosOptions |
GGoogleBar | GTileLayerOptions |
GGoogleBarAdsOptions | GTileLayerOverlayOptions |
GGoogleBarLinkTarget | GTrafficOverlayOptions |
GGoogleBarListingTypes | GUnload |
GGoogleBarOptions | GXml |
GGoogleBarResultList | GXmlHttp |
GInfoWindowTab | GXslt |
GKeyboardHandler |
|
Comparar el código
Comparemos dos aplicaciones bastante simples que se escribieron con las APIs de v2 y v3.
<!DOCTYPE html>
<html>
<head>
<script src="//maps.google.com/maps?file=api&v=2&key=YOUR_API_KEY"></script>
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
<script>
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(
document.getElementById('map'));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.setUIToDefault();
map.addOverlay(new GMarker(new GLatLng(37.4419, -122.1419)));
}
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
<script>
function initialize() {
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(37.4419, -122.1419),
map: map
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
Como puedes ver, hay varias diferencias entre las dos aplicaciones. Entre los cambios destacados se incluyen los siguientes:
- Se modificó la dirección desde la cual se carga la API.
- Los métodos
GBrowserIsCompatible()
y GUnload()
ya no son obligatorios en la versión 3 y se quitaron de la API.
- El objeto
GMap2
se reemplaza por google.maps.Map
como el objeto central de la API.
- Ahora, las propiedades se cargan a través de las clases de Options. En el ejemplo anterior, configuramos las tres propiedades necesarias para cargar un mapa:
center
, zoom
y mapTypeId
a través de un objeto MapOptions
intercalado.
- En la v3, se encuentra habilitado el valor predeterminado de la IU. Para inhabilitarlo, configura la propiedad
disableDefaultUI
como verdadera en el objeto MapOptions
.
Resumen
En este punto, tendrás una idea de algunos de los puntos clave involucrados en la migración de la versión 2 a la 3 de la API de Maps JavaScript.
Hay más información que podrías necesitar, pero dependerá de tu aplicación. En las siguientes secciones, incluimos instrucciones de migración para casos específicos que podrías encontrar. Además, hay varios recursos que podrían serte útiles durante el proceso de actualización.
Si tienes algún problema o pregunta sobre este artículo, usa el vínculo ENVIAR COMENTARIOS que se encuentra en la parte superior de esta página.
En esta sección, se proporciona una comparación detallada de las funciones más populares de la v2 y la v3 de la API de Maps JavaScript. Cada sección de la referencia está diseñada para leerse de forma individual. Te recomendamos que no leas esta referencia en su totalidad. En su lugar, usa este material para facilitar la migración según cada caso.
- Eventos: Registra y controla eventos.
- Controles: Manipula los controles de navegación que aparecen en el mapa.
- Superposiciones: Agrega y edita objetos en el mapa.
- Tipos de mapas: Son las tarjetas que conforman el mapa base.
- Capas: Agrega y edita contenido como un grupo, como capas de KML o de tráfico.
- Servicios: Trabajar con los servicios de geocodificación, instrucciones sobre cómo llegar o Street View de Google
Eventos
El modelo de eventos de la versión 3 de la API de Maps JavaScript es similar al que se usa en la versión 2, aunque mucho cambió en el código.
Evento nuevo para la asistencia MVC
La API v3 agrega un nuevo tipo de evento para reflejar los cambios de estado de MVC. Ahora hay dos tipos de eventos:
- Los eventos de usuario (como los eventos de "clic" del mouse) se propagan del DOM a la API de Maps JavaScript. Estos eventos son independientes y diferentes de los eventos estándares del DOM.
- Las notificaciones de cambio de estado de MVC reflejan cambios en los objetos de la API de Maps y se nombran mediante una convención
property_changed
.
Cada objeto de la Google Maps API exporta un número de eventos con nombre. Las aplicaciones que estén interesadas en eventos específicos deben registrar objetos de escucha de eventos para esos eventos y ejecutar código cuando se reciban. Este mecanismo orientado a eventos es el mismo en la API de Maps JavaScript v2 y v3, excepto que el espacio de nombres cambió de GEvent
a google.maps.event
:
GEvent.addListener(map, 'click', function() {
alert('You clicked the map.');
});
google.maps.event.addListener(map, 'click', function() {
alert('You clicked the map.');
});
Cómo eliminar receptores de eventos
Por motivos de rendimiento, es mejor quitar un objeto de escucha de eventos cuando ya no sea necesario. Quitar un objeto de escucha de eventos funciona de la misma manera en la versión 2 y la 3:
- Cuando creas un objeto de escucha de eventos, se muestra un objeto opaco (GEventListener en la versión 2, MapsEventListener en la versión 3).
- Cuando quieras quitar el objeto de escucha de eventos, pasa este objeto al método
removeListener()
(GEvent.removeListener()
en la versión 2 o google.maps.event.removeListener()
en la versión 3) para quitarlo.
Cómo escuchar eventos del DOM
Si deseas capturar y responder a eventos de DOM (Modelo de objetos del documento), la versión 3 proporciona el método estático google.maps.event.addDomListener()
, equivalente al método GEvent.addDomListener()
de la versión 2.
Usar argumentos pasados en eventos
Los eventos de la IU suelen pasar un argumento de evento al que puede acceder el objeto de escucha de eventos. La mayoría de los argumentos de eventos en la versión 3 se simplificaron para que sean más coherentes con los objetos de la API. (Consulta la referencia de v3 para obtener más información).
No existe ningún argumento overlay
en los objetos de escucha de eventos de la versión 3. Si registras un evento click
en un mapa v3, la devolución de llamada solo se realizará cuando el usuario haga clic en el mapa base. Puedes registrar devoluciones de llamada adicionales en superposiciones en las que se puede hacer clic si necesitas reaccionar a esos clics.
// Passes an overlay argument when clicking on a map
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();
GEvent.addListener(map,'click', function(overlay, latlng) {
if (latlng) {
var marker = new GMarker(latlng);
map.addOverlay(marker);
}
});
// Passes only an event argument
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
google.maps.event.addListener(map, 'click', function(event) {
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
});
Controles
La API de Maps JavaScript muestra controles de la IU que permiten que los usuarios interactúen con tu mapa. Puedes usar la API para personalizar cómo aparecen estos controles.
Cambios en los tipos de control
Se introdujeron algunos cambios en los tipos de control
con la API de v3.
- La API de la versión 3 admite tipos de mapas adicionales, incluidos los mapas de terreno y la capacidad de agregar tipos de mapas personalizados.
- El control jerárquico v2,
GHierarchicalMapTypeControl
, ya no está disponible.
Puedes lograr un efecto similar con el control google.maps.MapTypeControlStyle.HORIZONTAL_BAR
.
- El diseño horizontal que proporciona
GMapTypeControl
en la versión 2 no está disponible en la versión 3.
Cómo agregar controles al mapa
Con la API de Maps JavaScript v2, agregarías controles a tu mapa a través del método addControl()
de tu objeto de mapa. En la versión 3, en lugar de acceder a los controles o modificarlos directamente, debes modificar el objeto MapOptions
asociado. En el siguiente ejemplo, se muestra cómo personalizar el mapa para agregar los siguientes controles:
- botones que permiten al usuario activar o desactivar los tipos de mapas disponibles;
- una escala de mapa.
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
// Add controls
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// Add controls
mapTypeControl: true,
scaleControl: true
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
Posicionar controles en el mapa
El posicionamiento de controles ha cambiado mucho en la v3. En la versión 2, el método addControl()
toma un segundo parámetro opcional que te permite especificar la posición del control en relación con las esquinas del mapa.
En la versión 3, configuras la posición de un control a través de la propiedad position
de las opciones de control. El posicionamiento de estos controles no es absoluto. En cambio, la API los distribuye de manera inteligente alrededor de los elementos existentes del mapa, o de otros controles, con determinadas limitaciones (como el tamaño del mapa).
Esto asegura que los controles predeterminados sean compatibles con los tuyos.
Consulta Control de posicionamiento en v3 para obtener más información.
El siguiente código cambia el posicionamiento de los controles de los ejemplos anteriores:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
// Add map type control
map.addControl(new GMapTypeControl(), new GControlPosition(
G_ANCHOR_TOP_LEFT, new GSize(10, 10)));
// Add scale
map.addControl(new GScaleControl(), new GControlPosition(
G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 20)));
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// Add map type control
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.TOP_LEFT
},
// Add scale
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_RIGHT
}
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
Controles personalizados
La API de Maps JavaScript te permite crear controles de navegación personalizados.
Para personalizar los controles con la API de v2, crearías una subclase de la clase GControl
y definirías controladores para los métodos initialize()
y getDefaultPosition()
.
No hay un equivalente a la clase GControl
en la versión 3. En su lugar, los controles se representan como elementos DOM. Para agregar un control personalizado con la API de la versión 3, crea una estructura de DOM para el control en un constructor como elemento secundario de un Node
(p.ej., un elemento <div>
) y agrega objetos de escucha de eventos para controlar cualquier evento de DOM. Envía el Node
al array controls[position]
de los mapas para agregar una instancia del control personalizado a tu mapa.
Dada una implementación de clase HomeControl
que cumpla con los requisitos de interfaz mencionados anteriormente (consulta la documentación de Controles personalizados para obtener más información), en los siguientes ejemplos de código, se muestra cómo agregar un control personalizado a un mapa.
map.addControl(new HomeControl(),
GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
var homeControlDiv = document.createElement('DIV');
var homeControl = new HomeControl(homeControlDiv, map);
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(
homeControlDiv);
Superposiciones
Las superposiciones reflejan los objetos que "agregas" al mapa para designar puntos, líneas, áreas o conjuntos de objetos.
Agregar y quitar superposiciones
Los tipos de objetos representados por una superposición son los mismos entre la versión 2 y la 3. Sin embargo, se manejan de manera diferente.
Las superposiciones de la API de v2 se agregaron y quitaron del mapa con los métodos addOverlay()
y removeOverlay()
del objeto GMap2
. En la versión 3, asignas un mapa a una superposición a través de la propiedad map
de la clase de opciones de superposición asociada.
También puedes agregar o quitar una superposición directamente llamando al método setMap()
del objeto de superposición y especificando el mapa deseado. Si configuras la propiedad del mapa en null
, se quitará la superposición.
No existe un método clearOverlays()
en la versión 3.
Si deseas administrar un conjunto de superposiciones, debes crear un array que las contenga. Con este array, luego puedes llamar a setMap()
en cada superposición del array (pasa null
si necesitas quitarlas).
Marcadores arrastrables
De forma predeterminada, los marcadores son seleccionables, pero no arrastrables. En los siguientes
dos ejemplos, se agrega un marcador arrastrable:
var myLatLng = new GLatLng(-25.363882, 131.044922);
var map = new GMap2(document.getElementById('map'));
map.setCenter(myLatLng, 4);
var marker = new GMarker(latLng, {
draggable: true
});
map.addOverlay(marker);
var myLatLng = new google.maps.LatLng(-25.363882, 131.044922);
var map = new google.maps.Map(
document.getElementById('map'), {
center: myLatLng,
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: myLatLng,
draggable: true,
map: map
});
Íconos
Puedes definir un ícono personalizado que se mostrará en lugar del marcador predeterminado.
Para usar una imagen personalizada en la versión 2, puedes crear una instancia de GIcon
a partir de G_DEFAULT_ICON type
y modificarla. Si la imagen es más grande o más pequeña que el ícono predeterminado, debes especificarla con una instancia de GSize
.
La API v3 ofrece una ligera simplificación de este proceso.
Solo debes establecer la propiedad icon
del marcador en la URL de tu imagen personalizada, y la API ajustará el tamaño del ícono automáticamente.
La API de Maps JavaScript también admite íconos complejos.
Un ícono complejo puede incluir varias tarjetas, formas complejas o especificar el "orden de pila" de cómo deben mostrarse las imágenes en relación con otras superposiciones. Para agregar una forma a un marcador en la versión 2, debes especificar la propiedad adicional en cada instancia de GIcon
y pasarla como una opción a un constructor GMarker
. En la versión 3, los íconos especificados de esta manera deben establecer sus propiedades icon
en un objeto de tipo Icon
.
Las sombras de marcadores no se admiten en la v3.
En los siguientes ejemplos, se muestra una bandera de playa en Bondi Beach, Australia, en la que no se puede hacer clic en la parte transparente del ícono:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();
var flagIcon = new GIcon(G_DEFAULT_ICON);
flagIcon.image = '/images/beachflag.png';
flagIcon.imageMap = [1, 1, 1, 20, 18, 20, 18 , 1];
var bbLatLng = new GLatLng(-33.890542, 151.274856);
map.addOverlay(new GMarker(bbLatLng, {
icon: flagIcon
}));
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
var bbLatLng = new google.maps.LatLng(-33.890542, 151.274856);
var bbMarker = new google.maps.Marker({
icon: '/images/beachflag.png'
shape: shape,
position: bbLatLng,
map: map
});
Polilíneas
Una polilínea consta de un array de LatLng
, además de una serie de segmentos de líneas que conectan esas ubicaciones en una secuencia ordenada.
Crear y mostrar un objeto Polyline
en v3 es similar a usar un objeto GPolyline
en v2. En los siguientes ejemplos, se dibuja una polilínea geodésica semitransparente de 3 píxeles de ancho desde Zúrich hasta Sídney a través de Singapur:
var polyline = new GPolyline(
[
new GLatLng(47.3690239, 8.5380326),
new GLatLng(1.352083, 103.819836),
new GLatLng(-33.867139, 151.207114)
],
'#FF0000', 3, 0.5, {
geodesic: true
});
map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
path: [
new google.maps.LatLng(47.3690239, 8.5380326),
new google.maps.LatLng(1.352083, 103.819836),
new google.maps.LatLng(-33.867139, 151.207114)
],
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 3,
geodesic: true
});
polyline.setMap(map);
Polilíneas codificadas
En la versión 3, no se admite la creación de objetos Polyline
directamente a partir de polilíneas codificadas. En su lugar, la biblioteca de geometría proporciona métodos para codificar y decodificar polilíneas. Consulta Bibliotecas en la API de Maps v3 para obtener más información sobre cómo cargar esta biblioteca.
En los siguientes ejemplos, se dibuja el mismo polilínea codificado. El código de la versión 3 usa el método decodePath()
del espacio de nombres google.maps.geometry.encoding
.
var polyline = new GPolyline.fromEncoded({
points: 'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H',
levels: 'PPP',
zoomFactor: 2,
numLevels: 18,
color: '#ff0000',
opacity: 0.8,
weight: 3
});
map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
path: google.maps.geometry.encoding.decodePath(
'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H'),
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 3,
});
polyline.setMap(map);
Polígonos
Un polígono define una región dentro de un bucle cerrado. Al igual que el objeto Polyline
, los objetos Polygon
consisten en una serie de puntos en una secuencia ordenada. La clase Polygon
de la v3 es muy similar a la clase GPolygon
de la v2, con la notable excepción de que ya no tienes que repetir el vértice inicial al final de la ruta para cerrar el bucle. La API de la versión 3 cerrará automáticamente cualquier polígono dibujando un trazo que conecte la última coordenada con la primera. Los siguientes fragmentos de código
crean un polígono que representa el Triángulo de las Bermudas:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(24.886436, -70.268554), 5);
var bermudaTriangle = new GPolygon(
[
new GLatLng(25.774252, -80.190262),
new GLatLng(18.466465, -66.118292),
new GLatLng(32.321384, -64.75737),
new GLatLng(25.774252, -80.190262)
],
'#FF0000', 2, 0.8, '#FF0000', 0.35);
map.addOverlay(bermudaTriangle);
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(24.886436, -70.268554),
mapTypeId: google.maps.MapTypeId.TERRAIN,
zoom: 5
});
var bermudaTriangle = new google.maps.Polygon({
paths: [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737)
],
strokeColor: '#FF0000',
strokeWeight: 2,
strokeOpacity: 0.8,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
Formas que el usuario puede editar
Es posible hacer que los usuarios puedan editar polilíneas y polígonos. Los siguientes fragmentos de código
son equivalentes:
map.addOverlay(polyline);
polyline.enableEditing();
polyline.setMap(map);
polyline.setEditable(true);
Para obtener funciones de dibujo más avanzadas, consulta la biblioteca de dibujo en la documentación de la versión 3.
Ventanas de información
Un InfoWindow
muestra contenido en una ventana flotante sobre el mapa. Hay algunas diferencias claves entre las ventanas de información de la v2 y la v3:
- La API de v2 solo admite
GInfoWindow
por mapa, mientras que la API de v3 admite varios InfoWindow
simultáneos en cada mapa.
- El
InfoWindow
de v3 permanecerá abierto cuando hagas clic en el mapa. El GInfoWindow
de la versión 2 se cierra automáticamente cuando haces clic en el mapa. Para emular el comportamiento de la v2, agrega un objeto de escucha click
en el objeto Map
.
- La API de v3 no proporciona compatibilidad nativa con un
InfoWindow
con pestañas.
Superposiciones de suelo
Para colocar una imagen en un mapa, debes usar un objeto GroundOverlay
. El constructor de un GroundOverlay
es, en esencia, el mismo en la v2 y la v3: especifica la URL de una imagen y los límites de la imagen como parámetros.
En el siguiente ejemplo, se coloca un mapa antiguo de Newark, Nueva Jersey, en el mapa como una superposición:
var bounds = new GLatLngBounds(
new GLatLng(40.716216, -74.213393),
new GLatLng(40.765641, -74.139235));
var overlay = new GGroundOverlay(
'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
bounds);
map.addOverlay(overlay);
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.716216, -74.213393),
new google.maps.LatLng(40.765641, -74.139235));
var overlay = new google.maps.GroundOverlay(
'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
bounds);
overlay.setMap(map);
Tipos de mapas
Los tipos de mapas disponibles en la v2 y la v3 son ligeramente diferentes, pero todos los tipos de mapas básicos están disponibles en ambas versiones de la API. De forma predeterminada, la v2 usa tarjetas de mapas viales "pintadas" estándar. Sin embargo, la v3 requiere que se proporcione un tipo de mapa específico cuando se crea un objeto google.maps.Map
.
Tipos de mapa comunes
Los cuatro tipos de mapa básicos se encuentran disponibles en la v2 y la v3:
MapTypeId.ROADMAP
(reemplaza a G_NORMAL_MAP
) muestra la vista del mapa de ruta.
MapTypeId.SATELLITE
(reemplaza a G_SATELLITE_MAP
) muestra imágenes satelitales de Google Earth.
MapTypeId.HYBRID
(reemplaza a G_HYBRID_MAP
) muestra una combinación de vistas normales y satelitales.
MapTypeId.TERRAIN
(reemplaza a G_PHYSICAL_MAP
) muestra un mapa físico basado en la información del terreno.
A continuación, se muestra un ejemplo de la v2 y la v3 en el que se fija el mapa en la vista de terreno:
map.setMapType(G_PHYSICAL_MAP);
map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
La versión 3 de la API de Maps JavaScript también realizó algunos cambios en los tipos de mapas menos comunes:
- Los mosaicos de mapas de cuerpos celestes distintos de la Tierra no están disponibles como tipos de mapas en la API de v3, pero se puede acceder a ellos como tipos de mapas personalizados, como se muestra en este ejemplo.
- No hay un tipo de mapa especial en la versión 3 que reemplace el tipo
G_SATELLITE_3D_MAP
de la versión 2. En su lugar, puedes integrar el complemento de Google Earth en tus mapas de v3 con esta biblioteca.
Imágenes con zoom máximo
Las imágenes satelitales no están disponibles a niveles de zoom elevados. Si quieres conocer el nivel de zoom más alto disponible antes de configurarlo, usa la clase google.maps.MaxZoomService
. Esta clase reemplaza el método GMapType.getMaxZoomAtLatLng()
de la versión 2.
var point = new GLatLng(
180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new GMap2(document.getElementById("map"));
map.setUIToDefault();
map.setCenter(point);
map.setMapType(G_HYBRID_MAP);
map.getCurrentMapType().getMaxZoomAtLatLng(point,
function(response) {
if (response.status) {
map.setZoom(response.zoom);
} else {
alert("Error in Max Zoom Service.");
}
});
var myLatlng = new google.maps.LatLng(
180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new google.maps.Map(
document.getElementById("map"),{
zoom: 0,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.HYBRID
});
var maxZoomService = new google.maps.MaxZoomService();
maxZoomService.getMaxZoomAtLatLng(
myLatlng,
function(response) {
if (response.status == google.maps.MaxZoomStatus.OK) {
map.setZoom(response.zoom);
} else {
alert("Error in Max Zoom Service.");
}
});
Imágenes de perspectiva aérea
Cuando se habilitan las imágenes aéreas en la versión 3, los controles son similares al control GLargeZoomControl3D
de la versión 2, con un control de rotación intersticial adicional para rotar a través de las direcciones admitidas.
Puedes hacer un seguimiento de las ciudades en las que las imágenes a 45° están disponibles en este mapa. Cuando las imágenes de 45° están disponibles, se agrega una opción de submenú al botón Satélite de la API de Maps.
Capas
Las capas son objetos del mapa que constan de una o más superposiciones. Se pueden manipular como una sola unidad y, por lo general, reflejan colecciones de objetos.
Capas admitidas
La API v3 proporciona acceso a varias capas diferentes. Estas capas se superponen con la clase GLayer
de v2 en las siguientes áreas:
-
El objeto
KmlLayer
renderiza elementos KML y GeoRSS en superposiciones de v3, lo que proporciona el equivalente para la capa GeoXml
de v2.
- El objeto
TrafficLayer
renderiza una capa que representa las condiciones de tráfico, similar a la superposición GTrafficOverlay
de la v2.
Estas capas se diferencian respecto de la v2. Las diferencias se describen a continuación. Para agregarlas a un mapa, llama a setMap()
y pásale el objeto Map
en el que se debe mostrar la capa.
Hay más información sobre las capas admitidas en la documentación de capas.
Capas KML y GeoRSS
La API de Maps JavaScript admite los formatos de datos KML y GeoRSS para mostrar información geográfica. Los archivos KML o GeoRSS deben ser de acceso público si deseas incluirlos en un mapa. En la versión 3, estos formatos de datos se muestran con una instancia de KmlLayer
, que reemplaza al objeto GGeoXml
de la versión 2.
La API de la versión 3 es más flexible cuando renderiza KML, lo que te permite suprimir InfoWindows y modificar la respuesta de clic. Consulta la documentación de Capas KML y GeoRSS de la versión 3 para obtener más detalles.
Cuando se renderiza un KmlLayer
, se aplican restricciones de tamaño y complejidad. Consulta la documentación de KmlLayer para obtener más información.
En los siguientes ejemplos se compara la manera de cargar un archivo KML.
geoXml = new GGeoXml(
'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml');
map.addOverlay(geoXml);
var layer = new google.maps.KmlLayer(
'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml', {
preserveViewport: true
});
layer.setMap(map);
Capa de tráfico
La versión 3 te permite agregar información del tráfico en tiempo real (cuando se admite) a tus mapas con el objeto TrafficLayer
. La información de tráfico se proporciona para el momento en que se realiza la solicitud. En estos ejemplos, se muestra la información de tráfico de Los Ángeles:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(34.0492459, -118.241043), 13);
map.setUIToDefault();
var trafficOptions = {incidents:false};
trafficInfo = new GTrafficOverlay(trafficOptions);
map.addOverlay(trafficInfo);
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(34.0492459, -118.241043),
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 13
});
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
A diferencia de la v2, no existen opciones para el constructor TrafficLayer
en la v3. Los incidentes no están disponibles en la v3.
Servicios
Geocoding
La API de Maps JavaScript proporciona un objeto geocoder
para geocodificar direcciones de forma dinámica a partir de la entrada del usuario. Si deseas geocodificar direcciones conocidas y estáticas, consulta la documentación de la API de Geocoding.
La API de Geocoding se actualizó y mejoró significativamente, se agregaron funciones nuevas y se cambió la forma en que se representan los datos.
GClientGeocoder
en la API de la versión 2 proporcionaba dos métodos diferentes para la geocodificación directa y inversa, así como métodos adicionales para influir en la forma en que se realizaba la geocodificación. Por el contrario, el objeto Geocoder
de la versión 3 solo proporciona un método geocode()
, que toma un literal de objeto que contiene los términos de entrada (en forma de objeto Geocoding Requests) y un método de devolución de llamada. Según si la solicitud contiene un atributo address
textual o un objeto LatLng
, la API de Geocoding mostrará una respuesta de geocodificación directa o inversa. Puedes influir en la forma en que se realiza la geocodificación pasando campos adicionales a la solicitud de geocodificación:
- Si incluyes un
address
textual, se activa la geocodificación directa, que equivale a llamar al método getLatLng()
.
- Si incluyes un objeto
latLng
, se activa la codificación geográfica inversa, que equivale a llamar al método getLocations()
.
- La inclusión del atributo
bounds
habilita el sesgo del viewport, que equivale a llamar al método setViewport()
.
- Si incluyes el atributo
region
, se habilita la polarización del código de región, que equivale a llamar al método setBaseCountryCode()
.
Las respuestas de geocodificación en la v3 son muy diferentes de las de la v2. La API de v3 reemplaza la estructura anidada que usa v2 por una estructura más plana que es más fácil de analizar. Además, las respuestas de la v3 son más detalladas: cada resultado tiene varios componentes de dirección que ayudan a dar una mejor idea de la resolución de cada resultado.
El siguiente código toma una dirección textual y muestra el primer resultado de la geocodificación:
var geocoder = new GClientGeocoder();
var infoPanel;
var map;
var AccuracyDescription = [
'Unknown accuracy', 'country level accuracy',
'region level accuracy', 'sub-region level accuracy',
'town level accuracy', 'post code level accuracy',
'street level accuracy', 'intersection level accuracy',
'address level accuracy', 'premise level accuracy',
];
function geocode_result_handler(response) {
if (!response || response.Status.code != 200) {
alert('Geocoding failed. ' + response.Status.code);
} else {
var bounds = new GLatLngBounds(new GLatLng(
response.Placemark[0].ExtendedData.LatLonBox.south,
response.Placemark[0].ExtendedData.LatLonBox.west
), new GLatLng(
response.Placemark[0].ExtendedData.LatLonBox.north,
response.Placemark[0].ExtendedData.LatLonBox.east
));
map.setCenter(bounds.getCenter(),
map.getBoundsZoomLevel(bounds));
var latlng = new GLatLng(
response.Placemark[0].Point.coordinates[1],
response.Placemark[0].Point.coordinates[0]);
infoPanel.innerHTML += '<p>1st result is <em>' +
// No info about location type
response.Placemark[0].address +
'</em> of <em>' +
AccuracyDescription[response.Placemark[0].
AddressDetails.Accuracy] +
'</em> at <tt>' + latlng + '</tt></p>';
var marker_title = response.Placemark[0].address +
' at ' + latlng;
map.clearOverlays();
var marker = marker = new GMarker(
latlng,
{'title': marker_title}
);
map.addOverlay(marker);
}
}
function geocode_address() {
var address = document.getElementById('input-text').value;
infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
geocoder.getLocations(address, geocode_result_handler);
}
function initialize() {
map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(38, 15), 2);
map.setUIToDefault();
infoPanel = document.getElementById('info-panel');
}
var geocoder = new google.maps.Geocoder();
var infoPanel;
var map;
var marker;
function geocode_result_handler(result, status) {
if (status != google.maps.GeocoderStatus.OK) {
alert('Geocoding failed. ' + status);
} else {
map.fitBounds(result[0].geometry.viewport);
infoPanel.innerHTML += '<p>1st result for geocoding is <em>' +
result[0].geometry.location_type.toLowerCase() +
'</em> to <em>' +
result[0].formatted_address + '</em> of types <em>' +
result[0].types.join('</em>, <em>').replace(/_/, ' ') +
'</em> at <tt>' + result[0].geometry.location +
'</tt></p>';
var marker_title = result[0].formatted_address +
' at ' + latlng;
if (marker) {
marker.setPosition(result[0].geometry.location);
marker.setTitle(marker_title);
} else {
marker = new google.maps.Marker({
position: result[0].geometry.location,
title: marker_title,
map: map
});
}
}
}
function geocode_address() {
var address = document.getElementById('input-text').value;
infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
geocoder.geocode({'address': address}, geocode_result_handler);
}
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(38, 15),
zoom: 2,
mapTypeId: google.maps.MapTypeId.HYBRID
});
infoPanel = document.getElementById('info-panel');
}
Instrucciones
La API de Maps JavaScript v3 reemplaza la clase GDirections
de la v2 por la clase DirectionsService
para calcular las instrucciones sobre cómo llegar.
El método route()
en la versión 3 reemplaza los métodos load()
y loadFromWaypoints()
de la API de v2. Este método toma un solo literal de objeto DirectionsRequest
que contiene los términos de entrada y un método de devolución de llamada para ejecutar al recibir la respuesta. Las opciones se pueden proporcionar en este literal de objeto, similar al literal de objeto GDirectionsOptions
en la versión 2.
En la versión 3 de la API de Maps JavaScript, la tarea de enviar solicitudes de instrucciones se separó de la tarea de renderizar solicitudes, que ahora se controla con la clase DirectionsRenderer
. Puedes vincular un objeto DirectionsRenderer
a cualquier mapa o objeto DirectionsResult
a través de sus métodos setMap()
y setDirections()
. Debido a que el renderizador es un MVCObject
, detectará cualquier cambio en sus propiedades y actualizará el mapa cuando cambien las instrucciones asociadas sobre cómo llegar a un lugar.
En el siguiente código, se muestra cómo solicitar instrucciones sobre cómo llegar a pie a una ubicación específica mediante rutas peatonales desde una dirección. Ten en cuenta que solo la versión 3 puede proporcionar instrucciones sobre cómo caminar por el sendero peatonal del zoológico de Dublín.
var map;
var directions;
var directionsPanel;
function initialize() {
var origin = new google.maps.LatLng(53.348172, -6.297285);
var destination = new google.maps.LatLng(53.355502, -6.30557);
directionsPanel = document.getElementById("route");
map = new GMap2(document.getElementById('map'));
map.setCenter(origin, 10);
map.setUIToDefault();
directions = new GDirections(map, directionsPanel);
directions.loadFromWaypoints(
[origin, destination], {
travelMode: 'G_TRAVEL_MODE_WALKING',
});
}
var map;
var directionsRenderer;
var directionsService = new google.maps.DirectionsService();
function initialize() {
var origin = new google.maps.LatLng(53.348172, -6.297285);
var destination = new google.maps.LatLng(53.355502, -6.30557);
directionsRenderer = new google.maps.DirectionsRenderer();
map = new google.maps.Map(
document.getElementById('map'), {
center: origin,
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
directionsRenderer.setPanel(document.getElementById("route"));
directionsRenderer.setMap(map);
directionsService.route({
origin: origin,
destination: destination,
travelMode: google.maps.DirectionsTravelMode.WALKING
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(result);
}
});
}
Street View
Google Street View proporciona vistas interactivas de 360° de ubicaciones designadas dentro de su área de cobertura. La API de la versión 3 admite Street View de forma nativa en el navegador, a diferencia de la versión 2, que requería el complemento Flash® para mostrar imágenes de Street View.
Las imágenes de Street View se admiten mediante el objeto StreetViewPanorama
en la versión 3 o el objeto GStreetviewPanorama
en la versión 2. Estas clases tienen interfaces diferentes, pero cumplen el mismo rol: conectar el contenedor div
con las imágenes de Street View y permitirte especificar la ubicación y el POV (punto de vista) de la panorámica de Street View.
function initialize() {
var fenwayPark = new GLatLng(42.345573, -71.098326);
panoramaOptions = {
latlng: fenwayPark,
pov: {
heading: 35,
pitch: 5,
zoom: 1
}
};
var panorama = new GStreetviewPanorama(
document.getElementById('pano'),
panoramaOptions);
GEvent.addListener(myPano, "error", handleNoFlash);
}
function handleNoFlash(errorCode) {
if (errorCode == FLASH_UNAVAILABLE) {
alert('Error: Your browser does not support Flash');
return;
}
}
function initialize() {
var fenway = new google.maps.LatLng(42.345573, -71.098326);
var panoramaOptions = {
position: fenway,
pov: {
heading: 35,
pitch: 5,
zoom: 1
}
};
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'),
panoramaOptions);
}
El acceso directo a los datos de Street View es posible a través del objeto StreetViewService
en la versión 3 o del objeto GStreetviewClient
similar en la versión 2. Ambas proporcionan interfaces similares para recuperar o verificar la disponibilidad de los datos de Street View y permitir la búsqueda por ubicación o ID de panorama.
En la v3, Street View viene habilitada de forma predeterminada. El mapa aparecerá con un control de hombrecito naranja de Street View, y la API reutilizará el div del mapa para mostrar panorámicas de Street View. En el siguiente código, se muestra cómo emular el comportamiento de la versión 2 separando los panoramas de Street View en un div independiente.
var marker;
var panoClient = new GStreetviewClient();
function initialize() {
if (GBrowserIsCompatible()) {
var myPano = new GStreetviewPanorama(
document.getElementById('pano'));
GEvent.addListener(myPano, 'error', handleNoFlash);
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(42.345573, -71.098326), 16);
map.setUIToDefault();
GEvent.addListener(map, 'click', function(overlay, latlng) {
if (marker) {
marker.setLatLng(latlng);
} else {
marker = new GMarker(latlng);
map.addOverlay(marker);
}
var nearestPano = panoClient.getNearestPanorama(
latlng, processSVData);
});
function processSVData(panoData) {
if (panoData.code != 200) {
alert("Panorama data not found for this location.");
}
var latlng = marker.getLatLng();
var dLat = latlng.latRadians()
- panoData.location.latlng.latRadians();
var dLon = latlng.lngRadians()
- panoData.location.latlng.lngRadians();
var y = Math.sin(dLon) * Math.cos(latlng.latRadians());
var x = Math.cos(panoData.location.latlng.latRadians()) *
Math.sin(latlng.latRadians()) -
Math.sin(panoData.location.latlng.latRadians()) *
Math.cos(latlng.latRadians()) * Math.cos(dLon);
var bearing = Math.atan2(y, x) * 180 / Math.PI;
myPano.setLocationAndPOV(panoData.location.latlng, {
yaw: bearing
});
}
function handleNoFlash(errorCode) {
if (errorCode == FLASH_UNAVAILABLE) {
alert('Error: Your browser does not support Flash');
return;
}
}
}
}
// Load the API with libraries=geometry
var map;
var marker;
var panorama;
var sv = new google.maps.StreetViewService();
function radians(degrees) { return Math.PI * degrees / 180.0 };
function initialize() {
panorama = new google.maps.StreetViewPanorama(
document.getElementById("pano"));
map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(42.345573, -71.098326),
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 16
});
google.maps.event.addListener(map, 'click', function(event) {
if (!marker) {
marker = new google.maps.Marker({
position: event.latLng,
map: map
});
} else {
marker.setPosition(event.latLng);
}
sv.getPanoramaByLocation(event.latLng, 50, processSVData);
});
}
function processSVData(panoData, status) {
if (status == google.maps.StreetViewStatus.OK) {
alert("Panorama data not found for this location.");
}
var bearing = google.maps.geometry.spherical.computeHeading(
panoData.location.latLng, marker.getPosition());
panorama.setPano(panoData.location.pano);
panorama.setPov({
heading: bearing,
pitch: 0,
zoom: 1
});
panorama.setVisible(true);
marker.setMap(panorama);
}