La API de Maps JavaScript versión 2 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 API de Maps JavaScript v3. Esta guía te ayudará durante 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 Google Cloud Console para administrar claves. Si aún usas una clave v2, asegúrate de obtener tu clave de API nueva antes de comenzar la migración.
- Actualiza el inicio de la API. La mayoría de las aplicaciones cargan la API de Maps JavaScript v3 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:
- Haz referencia siempre 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
, cargarás google.maps.Map
.
- Quita todas las referencias a métodos obsoletos. Se quitaron varios métodos de utilidad generales, como
GDownloadURL
y GLog
.
Reemplaza esta funcionalidad por 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 utilidades para que cada app solo tenga que cargar las partes de la API que se usarán.
- (Opcional) Configura tu proyecto para usar los elementos externalizados de la v3.
Los externalizados de la v3 se pueden usar para validar tu código con Closure
Compiler o activar el autocompletado en tu IDE.
Obtén más información sobre la compilación avanzada y los elementos externos.
- Prueba y repite. En este punto, aún debes trabajar, pero la buena noticia es que estarás en camino a la nueva aplicación de mapas v3.
Cambios en la V3 de la API de Maps JavaScript
Antes de planificar tu migración, debes tomarte un 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 técnicas modernas de programación de JavaScript, un mayor uso de bibliotecas y una API simplificada.
Se agregaron muchas funciones nuevas a la API y se modificaron o incluso quitaron algunas 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 trasladaron a bibliotecas, lo que ayuda a reducir los tiempos de carga y análisis de la API principal, lo que permite que el mapa se cargue con rapidez en cualquier dispositivo.
- Se mejoró el rendimiento de varias funciones, como la renderización de polígonos y la ubicación de los marcadores.
- Un enfoque nuevo para los límites de uso del cliente, a fin de 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 auxiliares de uso general (
GLog
o GDownloadUrl
). En la actualidad, existen muchas bibliotecas de JavaScript excelentes que proporcionan una funcionalidad similar, como Closure o jQuery.
- Una implementación de Street View HTML5 que se carga en cualquier dispositivo móvil.
- Panorámicas de Street View personalizadas con tus propias fotos, lo que te permite compartir panoramas de pistas de esquí, casas en venta u otros lugares interesantes.
- Personalizaciones de mapas con ajustes de estilo que te permiten cambiar la visualización de los elementos en el mapa base para que coincidan con tu estilo visual único.
- Compatibilidad con varios servicios nuevos, como ElevationService y Distance Matrix
- Un servicio mejorado de instrucciones sobre cómo llegar proporciona rutas alternativas, optimización de rutas (soluciones aproximadas para el problema de un vendedor que viaja), instrucciones sobre cómo llegar en bicicleta (con capa para andar en bicicleta), instrucciones sobre cómo llegar en transporte público y instrucciones sobre cómo llegar.
- Un formato de Geocoding actualizado que proporciona información de type más precisa que el valor
accuracy
de la Geocoding API v2.
- Compatibilidad con varias ventanas de información en un solo mapa
Tu clave nueva
La Maps JavaScript API v3 utiliza un nuevo sistema de claves de la v2. Es posible que ya uses una clave v3 con tu aplicación, en cuyo caso no se necesita ningún cambio. Para verificar, verifica la URL desde la que cargas la API de Maps JavaScript para obtener el parámetro key
. Si el valor de la clave comienza con "ABQIAA", debes usar una clave v2. Si tienes una clave v2, debes actualizar a una clave v3 como parte de la migración, lo que hará lo siguiente:
La clave se pasa cuando se carga la Maps JavaScript API v3.
Obtén más información sobre cómo generar claves de API.
Ten en cuenta que, si eres cliente de Google Maps API for Work, es posible que uses un ID de cliente con el parámetro client
en lugar de key
. Los ID de cliente aún son compatibles con la API de Maps JavaScript v3 y no necesitan pasar por el proceso de actualización de claves.
Cargando la API
La primera modificación que deberás realizar en tu código implica cómo se carga la API. En la versión 2, se carga la API de Maps JavaScript mediante una solicitud a http://maps.google.com/maps
. Si cargas la API de Maps JavaScript v3, 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 clave v3 nueva. Los clientes de Google Maps APIs for Work deben usar un parámetro client
.
- (Solo en el plan Premium de Google Maps Platform) Asegúrate de que el parámetro
client
se proporcione 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 más reciente o cambia su valor según el esquema de control de versiones v3.
- Reemplaza el parámetro
hl
por language
y conserva su valor (opcional).
- Agrega un parámetro
libraries
para cargar bibliotecas opcionales (opcional).
En el caso más simple, el arranque de la v3 especificará solo 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 última versión de la API de Maps JavaScript v2 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 v2 coloca todos los objetos en el espacio de nombres global de forma predeterminada, lo que puede generar conflictos de nombres. En la versión 3, todos los objetos se encuentran en el espacio de nombres google.maps
.
Cuando migres tu aplicación a la versión 3, deberás cambiar el código para usar el espacio de nombres nuevo. Lamentablemente, buscar "G" y reemplazarlo por "google.maps." no funcionará por completo; sin embargo, es una buena regla general que se debe aplicar al revisar el código. A continuación, se muestran algunos ejemplos de las clases equivalentes en v2 y 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 Maps JavaScript API v3 tiene paralelismo para la mayoría de las funcionalidades de la v2; sin embargo, hay algunas clases que ya no son compatibles. Como parte de tu 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 una funcionalidad similar, como Closure o jQuery.
Las siguientes clases no tienen paralelismo en la Maps JavaScript API v3:
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 API 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 necesarios 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 de tu migración de la v2 a la v3 de la API de Maps JavaScript.
Hay más información que debes conocer, pero dependerá de tu aplicación. En las siguientes secciones, incluimos instrucciones de migración para casos específicos que puedes encontrar. Además, hay varios recursos que pueden resultarte útiles durante el proceso de actualización.
Si tienes problemas o preguntas 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 versión 2 y la 3 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 el caso.
- Eventos: cómo registrar y administrar eventos
- Controles: Manipula los controles de navegación que aparecen en el mapa.
- Superposiciones: Se agregan y editan objetos en el mapa.
- Tipos de mapas: Son los mosaicos que componen el mapa base.
- Capas: Agrega y edita contenido en grupo, como las capas KML o Traffic.
- Servicios: trabajo con la codificación geográfica, las instrucciones sobre cómo llegar o los servicios de Street View de Google.
Eventos
El modelo de evento para la API de Maps JavaScript v3 es similar al que se usa en la v2, aunque muchos aspectos no visibles han cambiado.
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 mouse) se propagan del DOM a la API de Maps JavaScript. Estos eventos son independientes y distintos de los eventos de DOM estándar.
- Las notificaciones de cambio de estado de MVC reflejan cambios en los objetos de la API de Google 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 interesadas en eventos específicos deben registrar objetos de escucha de eventos de esos eventos y ejecutar código cuando se reciben. Este mecanismo controlado por eventos es el mismo en las 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 razones de rendimiento, es mejor quitar un objeto de escucha de eventos cuando ya no es necesario. Quitar un objeto de escucha de eventos funciona de la misma manera en la v2 y la v3:
- 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 desees quitar el objeto de escucha de eventos, pasa este objeto al método
removeListener()
(GEvent.removeListener()
en la v2 o google.maps.event.removeListener()
en la v3) para quitar el objeto de escucha de eventos.
Cómo escuchar eventos de DOM
Si deseas capturar y responder a eventos de DOM (Modelo de objeto del documento), v3 proporciona el método estático google.maps.event.addDomListener()
, que equivale al método GEvent.addDomListener()
en v2.
Usar argumentos pasados en eventos
A menudo, los eventos de la IU pasan un argumento de evento al que luego puede acceder el objeto de escucha de eventos. La mayoría de los argumentos de eventos en la v3 se simplificaron para ser más coherentes con los objetos de la API. (Consulta la referencia de la versión 3 para obtener más detalles).
No hay ningún argumento overlay
en los objetos de escucha de eventos v3. Si registras un evento click
en un mapa de la versión 3, la devolución de llamada solo se producirá 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 ante 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 los controles de la IU que permiten a los usuarios interactuar 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 v3.
- La API de v3 admite tipos de mapas adicionales, incluidos los mapas de relieve y la capacidad de agregar tipos de mapas personalizados.
- El control jerárquico de la 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 v2 no está disponible en la v3.
Cómo agregar controles al mapa
Con la versión 2 de la API de Maps JavaScript, puedes agregar controles al mapa a través del método addControl()
del objeto de mapa. En la versión 3, en lugar de acceder a los controles o modificarlos directamente, modifica 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 v2, 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 v3, se establece 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 su lugar, la API los diseñará de manera inteligente mediante el flujo y los elementos alrededor del mapa existentes dentro de ciertas restricciones (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 v2, debes crear una subclase de la clase GControl
y definir los controladores para los métodos initialize()
y getDefaultPosition()
.
No hay equivalente a la clase GControl
en la v3. En su lugar, los controles se representan como elementos del DOM. A fin de agregar un control personalizado con la API v3, 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 elemento Node
al arreglo controls[position]
de mapas para agregar una instancia del control personalizado a tu mapa.
Dada una implementación de la clase HomeControl
que cumple con los requisitos de la interfaz mencionados anteriormente (consulta la documentación de Controles personalizados para obtener más detalles), en las siguientes muestras 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 colecciones de objetos.
Cómo agregar y quitar superposiciones
Los tipos de objetos representados por una superposición son los mismos entre la v2 y la v3, pero se manejan de manera diferente.
Las superposiciones en la API v2 se agregaron al mapa y se quitaron del mapa usando los métodos addOverlay()
y removeOverlay()
del objeto GMap2
. En la versión 3, se asigna 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 estableces la propiedad del mapa en null
, se quitará la superposición.
No existe el método clearOverlays()
en la v3.
Si deseas administrar un conjunto de superposiciones, debes crear un arreglo para contener las superposiciones. Con este arreglo, puedes llamar a setMap()
en cada superposición del arreglo (y pasar 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 v2, puedes crear una instancia de GIcon
a partir de G_DEFAULT_ICON type
y modificarla. Si tu 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 Maps JavaScript API también proporciona compatibilidad con íconos complejos.
Un ícono complejo puede incluir varios mosaicos y formas complejas, o especificar el orden de presentación de las imágenes respecto de otras superposiciones. Para agregar una forma a un marcador en la v2, debes especificar la propiedad adicional en cada instancia de GIcon
y pasarla como una opción a un constructor GMarker
. En la v3, los íconos especificados de esta manera deberían establecer sus propiedades de 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, y 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 consiste en un arreglo 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 la v3 es similar a usar un objeto GPolyline
en la 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 y 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
La v3 no admite la creación de objetos Polyline
directamente a partir de polilíneas codificadas. En cambio, la biblioteca de geometría proporciona métodos para codificar y decodificar las polilíneas. Consulta Bibliotecas en la versión 3 de la API de Google Maps para obtener más información sobre cómo cargar esta biblioteca.
En los siguientes ejemplos, se dibuja la misma polilínea codificada; el código v3 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
v3 es muy similar a la clase GPolygon
v2, con la excepción notable de que ya no tienes que repetir el vértice de inicio al final de la ruta para cerrar el bucle. La API v3 cerrará de manera automática cualquier polígono dibujando un trazo que conecte la última coordenada con la primera. Con los siguientes fragmentos de código, se crea 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 dibujos en la documentación de la v3.
Ventanas de información
Un elemento InfoWindow
muestra contenido en una ventana flotante encima del mapa. Hay algunas diferencias claves entre las ventanas de información de la v2 y la v3:
- La API v2 admite solo
GInfoWindow
por mapa, mientras que la API v3 admite varias InfoWindow
simultáneas en cada mapa.
- La versión 3 de
InfoWindow
permanecerá abierta cuando hagas clic en el mapa. La GInfoWindow
v2 se cierra automáticamente cuando haces clic en el mapa. Puedes emular el comportamiento de la v2 si agregas 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
. En esencia, el constructor de un GroundOverlay
es el mismo en v2 y v3: especifica una URL de una imagen y los límites de la imagen como parámetros.
En el siguiente ejemplo, se ubica un mapa antiguo de Newark, NJ, 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 mosaicos de mapas de ruta estándares pintados. Sin embargo, en la v3 se requiere 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 las 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 Maps JavaScript API v3 también realizó algunos cambios en los tipos de mapa menos comunes:
- Los mosaicos de mapas para cuerpos celestes que no sean de Earth no están disponibles como tipos de mapas en la API 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 v3 que reemplace el tipo
G_SATELLITE_3D_MAP
de la v2. En su lugar, puedes integrar el complemento de Google Earth en tus mapas 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 v3, los controles son similares al control GLargeZoomControl3D
de la v2, con un control de rotación intersticial adicional para rotar las instrucciones compatibles.
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 a 45° están disponibles, se agrega una opción de submenú al botón Satélite de la API de Google Maps.
de la imagen
Las capas son objetos en el mapa que consisten en 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
v2 en las siguientes áreas:
-
El objeto
KmlLayer
procesa elementos KML y GeoRSS en superposiciones de la versión 3, lo que proporciona un equivalente para la capa GeoXml
de la versión 2.
- El objeto
TrafficLayer
procesa una capa que representa las condiciones de tráfico, similar a la superposición v2 GTrafficOverlay
.
Estas capas se diferencian respecto de la v2. Las diferencias se describen a continuación. Se pueden agregar a un mapa llamando a setMap()
y pasándole el objeto Map
en el que se mostrará la capa.
Para obtener más información sobre las capas compatibles, consulta la documentación sobre 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 v3, estos formatos de datos se muestran mediante una instancia de KmlLayer
, que reemplaza el objeto GGeoXml
de la v2.
La API v3 es más flexible al procesar KML, lo que te permite suprimir InfoWindows y modificar la respuesta de clics. Consulta la documentación de las capas de KML y GeoRSS v3 para obtener más detalles.
Cuando se procesa un KmlLayer
, se aplican restricciones de tamaño y complejidad. Consulta la documentación de KmlLayer para obtener más detalles.
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 v3 te permite agregar información del tráfico en tiempo real (cuando sea compatible) a tus mapas con el objeto TrafficLayer
. La información del tráfico se proporciona para el momento en que se realiza la solicitud. En estos ejemplos, se muestra la información de tráfico para 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 hay 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 manera dinámica a partir de las entradas 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ó de forma significativa, lo que agregó nuevas funciones y cambió la forma en que se representan los datos.
GClientGeocoder
en la API v2 proporcionaba dos métodos diferentes para la geocodificación hacia adelante y atrás, así como métodos adicionales para influir en cómo se realizaba la codificación geográfica. Por el contrario, el objeto Geocoder
de la v3 proporciona solo un método geocode()
, que toma un literal de objeto que contiene los términos de entrada (en forma de un objeto Solicitudes de geocodificación) 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 hacia adelante o atrás. Puedes influir en cómo se realiza la geocodificación pasando campos adicionales a la solicitud de geocodificación:
- Incluir un
address
textual activa la geocodificación hacia adelante, lo que equivale a llamar al método getLatLng()
.
- Incluir un objeto
latLng
activa la geocodificación inversa, lo que equivale a llamar al método getLocations()
.
- Incluir el atributo
bounds
habilita la Restricción de viewports, que equivale a llamar al método setViewport()
.
- Incluir el atributo
region
habilita la Restricción de código regional, que equivale a llamar al método setBaseCountryCode()
.
Las respuestas de codificación geográfica en la v3 son muy diferentes de las respuestas de la v2. La API v3 reemplaza la estructura anidada que usa la 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 tener 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 su 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');
}
Directions
La API de Maps JavaScript v3 reemplaza la clase GDirections
de la v2 con la clase DirectionsService
para calcular las instrucciones sobre cómo llegar.
El método route()
en la v3 reemplaza los métodos load()
y loadFromWaypoints()
de la API v2. Este método toma un único 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. Se pueden proporcionar opciones en este literal de objeto, similar al literal de objeto GDirectionsOptions
en v2.
En la API de Maps JavaScript v3, la tarea de enviar solicitudes de instrucciones sobre cómo llegar se separó de la tarea de procesar solicitudes, que ahora se maneja 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 procesador es un MVCObject
, detectará cualquier cambio en sus propiedades y actualizará el mapa cuando cambien las instrucciones asociadas.
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 v3 puede proporcionar instrucciones sobre cómo llegar a pie en 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 en 360° de las ubicaciones designadas dentro de su área de cobertura. La API v3 admite Street View de forma nativa dentro del navegador, a diferencia de la v2, que requería que el complemento Flash® mostrara las imágenes de Street View.
Las imágenes de Street View se admiten mediante el objeto StreetViewPanorama
en la v3 o el objeto GStreetviewPanorama
en la v2. Estas clases tienen interfaces diferentes, pero tienen la misma función: conectar el contenedor div
con las imágenes de Street View y permitirte especificar la ubicación y el punto de vista del panorama 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 v3 o el objeto GStreetviewClient
similar en la v2. Ambas proporcionan interfaces similares para recuperar o verificar la disponibilidad de los datos de Street View y permiten buscar por ubicación o ID de panorámica.
En la v3, Street View viene habilitada de forma predeterminada. El mapa aparecerá con un control del hombrecito naranja de Street View y la API volverá a usar el elemento div del mapa para mostrar panoramas de StreetView. En el siguiente código, se ilustra cómo emular el comportamiento de la versión 2 mediante la separación de las panorámicas de Street View en un div separado.
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);
}