A API Maps JavaScript v2 não está mais disponível desde 26 de maio de 2021. Como resultado, os mapas da v2 do seu site vão deixar de funcionar e vão retornar erros de JavaScript. Para continuar usando mapas no seu site, migre para a API Maps JavaScript v3. Este guia vai ajudar você no
processo.
  Visão geral
Cada aplicativo terá um processo de migração ligeiramente diferente.
  No entanto, há algumas etapas comuns a todos os projetos:
  - Peça uma nova chave. A API Maps JavaScript agora usa o console do Google Cloud para gerenciar chaves. Se você ainda estiver usando uma chave v2, confira se tem uma
    nova chave de API antes de começar a migração.
  
- Atualize o Bootstrap da API. A maioria dos aplicativos carrega a API Maps JavaScript v3 com o seguinte código:
 <script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script> 
- Atualize seu código. A quantidade de mudança necessária vai depender muito do seu aplicativo. Mudanças comuns incluem:
    
      - Sempre faça referência ao namespace google.maps. Na v3,
        todo o código da API Maps JavaScript é armazenado no
        namespaces google.maps.*em vez do namespace global. A maioria dos objetos também foi renomeada como parte desse
        processo. Por exemplo, em vez deGMap2, você
        vai carregargoogle.maps.Map.
- Remova todas as referências a métodos obsoletos. Vários
        métodos de utilitário de uso geral foram removidos, como
        GDownloadURLeGLog.
        Substitua essa funcionalidade por bibliotecas de utilitários de terceiros
        ou remova essas referências do código.
- (Opcional) Adicionar bibliotecas ao código. Muitos
        recursos foram externalizados em bibliotecas de utilitários para que cada
        app precise carregar apenas as partes da API que serão usadas.
      
- (Opcional) Configure seu projeto para usar as externas da v3.
        Os externos da v3 podem ser usados para ajudar a validar seu código com o
        Closure
        Compiler ou para acionar o preenchimento automático no seu ambiente de desenvolvimento integrado.
        Saiba mais sobre
        
          Compilação avançada e externos.
 
- Teste e itere. Neste ponto, você ainda terá algum trabalho a fazer, mas a boa notícia é que você estará no caminho para o novo aplicativo do Maps v3.
Mudanças na V3 da API Maps JavaScript
Antes de planejar a migração, entenda as diferenças entre a API Maps JavaScript v2 e a API Maps JavaScript v3. A versão mais recente da API Maps JavaScript foi
  criada do zero, com foco em técnicas modernas de programação em JavaScript, maior uso de bibliotecas e uma API simplificada.
  Muitos novos recursos foram adicionados à API, e vários
  recursos conhecidos foram modificados ou até removidos. Esta seção destaca
  algumas das principais diferenças entre as duas versões.
Algumas das mudanças na API v3 incluem:
  - Uma biblioteca principal otimizada. Muitas das funções suplementares foram
    movidas para
    bibliotecas,
    ajudando a reduzir os tempos de carregamento e análise da API Core, o que permite
    que o mapa seja carregado rapidamente em qualquer dispositivo.
- Melhoria no desempenho de vários recursos, como renderização de polígonos e posicionamento de marcadores.
- Uma nova abordagem para
    limites de uso
    do lado do cliente para acomodar melhor os endereços compartilhados usados por proxies
    móveis e firewalls corporativos.
- Foi adicionado suporte a vários navegadores
  modernos e de dispositivos móveis. O suporte para o Internet Explorer 6 foi
  removido.
- Muitas das classes auxiliares de finalidade geral foram removidas
  (
  
  GLogouGDownloadUrl). Atualmente, existem muitas
  bibliotecas JavaScript excelentes que oferecem funcionalidades semelhantes,
  como Closure ou
  jQuery.
- Uma implementação do Street View em HTML5 que pode ser carregada em qualquer dispositivo móvel.
- Panoramas personalizados do Street View com suas próprias fotos, permitindo que você compartilhe panoramas de pistas de esqui, casas à venda ou outros lugares interessantes.
- As personalizações dos mapas estilizados permitem mudar a exibição dos elementos no mapa de base para corresponder ao seu estilo visual exclusivo.
- Suporte a vários novos serviços, como o
    ElevationService
    e a Distance
    Matrix.
- Um serviço de trajetos aprimorado oferece rotas alternativas, otimização de rotas (soluções aproximadas para o 
  problema do vendedor viajante), trajetos de bicicleta (com a 
  camada de bicicleta), trajetos de transporte público e 
  trajetos arrastáveis.
- Um formato atualizado de geocodificação que fornece informações de tipo mais precisas do que o valor accuracyda API Geocoding v2.
- Suporte a várias
  janelas de informações em um único mapa
Fazer upgrade do aplicativo
  
  
    Sua nova chave
    A API Maps JavaScript v3 usa um novo sistema de chaves da v2. Talvez você já esteja
      usando uma chave v3 com seu aplicativo. Nesse caso, nenhuma mudança é necessária. Para verificar, verifique o URL em que você carrega a API Maps JavaScript para o parâmetro key. Se o valor da chave começar com "ABQIAA", você está usando uma chave v2. Se você tiver uma chave v2, será necessário fazer upgrade para uma chave v3 como parte da migração,
      que:
    
  
    A chave é transmitida ao carregar a API Maps JavaScript v3.
    Saiba mais sobre como gerar chaves de API.
  
  
    Se você for cliente das APIs Maps for Work, talvez esteja usando um ID do cliente com o parâmetro client em vez de key. Os IDs de cliente ainda são aceitos na API Maps JavaScript v3 e não precisam passar pelo processo de upgrade de chave.
  
  Carregue a API
  A primeira modificação que você vai precisar fazer no código envolve
    como carregar a API. Na v2, você carrega a API Maps JavaScript
    com uma solicitação para
    http://maps.google.com/maps. Se você estiver carregando a API Maps JavaScript v3, vai precisar fazer as seguintes mudanças:
  - Carregar a API de //maps.googleapis.com/maps/api/js
- Remova o parâmetro file.
- Atualize o parâmetro keycom sua nova chave v3. Os clientes das APIs Maps for Work precisam usar um parâmetroclient.
- (Somente no plano Premium da Plataforma Google Maps) Verifique se o parâmetro clienté fornecido conforme explicado no 
    guia para desenvolvedores do plano Premium da Plataforma Google Maps.
- Remova o parâmetro vpara solicitar a
    versão lançada mais recente ou mude o valor de acordo com o
    esquema de controle de versão v3.
- (Opcional) Substitua o parâmetro hlporlanguagee preserve o valor dele.
- (Opcional) Adicione um parâmetro librariespara
    carregar bibliotecas
    opcionais.
No caso mais simples, o bootstrap v3 especifica apenas o parâmetro de chave de API:
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
O exemplo abaixo solicita a versão mais recente da API Maps JavaScript v2 em alemão:
<script src="//maps.google.com/maps?file=api&v=2.x&key=YOUR_API_KEY&hl=de"></script>
O exemplo abaixo é uma solicitação equivalente para a v3.
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&language=de"></script>
O namespace google.maps
Provavelmente, a mudança mais perceptível na API Maps JavaScript v3 é a
  introdução do namespace google.maps. A API v2 coloca
  todos os objetos no namespace global por padrão, o que pode resultar em colisões de
  nomes. Na v3, todos os objetos estão localizados no
  namespace google.maps.
Ao migrar seu aplicativo para a v3, você vai precisar mudar o código para
  usar o novo namespace. Infelizmente, pesquisar "G" e
  substituir por "google.maps." não vai funcionar completamente, mas é uma boa regra
  geral a ser aplicada ao revisar o código. Confira abaixo alguns exemplos de classes equivalentes na v2 e 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
 | 
  
  
    Remover código obsoleto
    A API Maps JavaScript v3 tem paralelos para a maioria das
      funcionalidades da v2. No entanto, algumas classes não têm mais
      suporte. Como parte da migração, substitua essas
      classes por bibliotecas de utilitários de terceiros ou remova essas
      referências do código. Existem muitas bibliotecas JavaScript excelentes que
      oferecem funcionalidades semelhantes, como Closure ou
      jQuery.
    As classes a seguir não têm paralelo na API Maps JavaScript 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 código
    Confira uma comparação de dois aplicativos criados com
      as APIs v2 e 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 você pode ver, há várias diferenças entre os dois
      aplicativos. As principais mudanças incluem:
    
      - O endereço de onde a API é carregada foi alterado.
- Os métodos GBrowserIsCompatible()eGUnload()não são mais necessários na v3 e foram removidos da
        API.
- O objeto GMap2é substituído porgoogle.maps.Mapcomo o objeto central na API.
- Agora, as propriedades são carregadas por meio das classes Options. No exemplo
        acima, definimos as três propriedades necessárias para carregar um mapa:
        center,zoomemapTypeId- usando um objetoMapOptionsinline.
- Na v3, a IU padrão é ativada por padrão. Para desativar esse recurso,
        defina a propriedade disableDefaultUIcomo "true" no
        objetoMapOptions.
Resumo
    Neste ponto, você já terá uma ideia de alguns dos principais pontos envolvidos na migração da v2 para a v3 da API Maps JavaScript.
      Talvez você precise de mais informações, mas isso vai depender do seu
      aplicativo. Nas seções a seguir, incluímos instruções de migração para
      casos específicos que você pode encontrar. Além disso, há vários recursos
      que podem ser úteis durante o processo de upgrade.
    
    Se você tiver problemas ou dúvidas sobre este documento, use o link ENVIAR FEEDBACK na parte de cima da página.
  
  
  Esta seção oferece uma comparação detalhada dos recursos mais usados da v2 e da v3 da API Maps JavaScript. Cada
  seção da referência foi projetada para ser lida individualmente. Recomendamos
  que você não leia esta referência na íntegra. Em vez disso, use este
  material para ajudar na migração de cada caso.
  - Eventos - como registrar e tratar eventos.
- Controles: manipulação dos controles de navegação que aparecem no mapa.
- Sobreposições: adição e edição de objetos no mapa.
- Tipos de mapa - os blocos que compõem o mapa de base.
  
- Camadas: adição e edição de conteúdo como um grupo, como camadas KML ou de tráfego.
- Serviços: trabalhar com os serviços de geocodificação, direções ou do Street View do Google.
Eventos
O modelo de eventos da API Maps JavaScript v3 é semelhante ao usado na v2,
  embora muitas coisas tenham mudado em segundo plano.
  Novo evento para compatibilidade com MVC
A API v3 adiciona um novo tipo de evento para refletir as mudanças de estado de MVC. Agora há
  dois tipos de eventos:
  
    - Os eventos do usuário (como eventos de clique do mouse) são propagados do DOM para a API Maps JavaScript. Esses eventos são separados e
      diferentes dos eventos DOM padrão.
- As notificações de mudança de estado do MVC refletem mudanças nos objetos da API Maps
      e são nomeadas usando a convenção property_changed.
  Cada objeto da Maps API exporta vários eventos nomeados. Os aplicativos
  interessados em eventos específicos precisam registrar listeners de eventos
  para esses eventos e executar o código quando esses eventos forem recebidos. Esse mecanismo orientado a eventos é o mesmo nas APIs Maps JavaScript v2 e v3, exceto que o namespace mudou de GEvent para 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.');
});
     
    
   
  
  
    Remover listeners de eventos
    
      Por motivos de desempenho, é melhor remover um listener de eventos quando ele
      não for mais necessário. A remoção de um listener de eventos funciona da mesma forma na v2 e
      v3:
    
    
      - Quando você cria um listener de eventos, um objeto opaco (GEventListener
      na v2, MapsEventListener
      na v3) é retornado.
      
- Quando você quiser remover o listener de eventos, transmita esse objeto ao
      método removeListener()(GEvent.removeListener()na v2 ougoogle.maps.event.removeListener()na v3) para remover
      o listener de eventos.
Ouvir eventos do DOM
    Se você quiser capturar e responder a eventos do DOM (modelo de objeto de documento), a v3 oferece o método estático google.maps.event.addDomListener(), equivalente ao método GEvent.addDomListener() na v2.
  
  
    Usar argumentos transmitidos em eventos
    Os eventos da interface geralmente transmitem um argumento de evento que pode ser acessado pelo
      listener de eventos. A maioria dos argumentos de evento na v3 foi simplificada
      para ser mais consistente com os objetos na API. Consulte a
      referência da v3
      para mais detalhes.
    Não há argumento overlay em listeners de eventos da v3. Se você
      registrar um evento click em um mapa da v3, o callback só vai
      ocorrer quando o usuário clicar no mapa base. É possível registrar outros
      callbacks em sobreposições clicáveis se você precisar reagir a esses cliques.
    
    
      
      // 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
    A API Maps JavaScript mostra controles de interface que permitem a interação dos usuários com o mapa. É possível usar a API para personalizar a aparência desses controles.
    
      Alterações em tipos de controle
      Algumas mudanças nos tipos control foram introduzidas
        com a API v3.
      
        - A API v3 oferece suporte a outros tipos de mapa, incluindo mapas de terreno e a capacidade de adicionar tipos de mapa personalizados.
- O controle hierárquico v2,
          GHierarchicalMapTypeControl, não está mais disponível.
          É possível conseguir um efeito semelhante usando o
           controlegoogle.maps.MapTypeControlStyle.HORIZONTAL_BAR.
- O layout horizontal fornecido por GMapTypeControlna v2 não está disponível na v3.
Adicionar controles ao mapa
    Com a API Maps JavaScript v2, você adiciona controles ao seu mapa usando o método addControl() do objeto de mapa. Na v3, em vez de acessar ou modificar controles diretamente,
      você modifica o objeto MapOptions associado. O exemplo abaixo mostra como personalizar o mapa para adicionar os seguintes controles:
    
    
     - botões que permitem o usuário alternar entre os tipos de mapas disponíveis
- uma 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 no mapa
    O posicionamento de controles mudou bastante na v3. Na v2, o método addControl() aceita um segundo parâmetro opcional que permite especificar a posição do controle em relação aos cantos do mapa.
    
    Na v3, você define a posição de um controle pela
      propriedade position das opções de controle. O posicionamento desses controles não é absoluto. Em vez disso, a API os exibe de forma inteligente, "fluindo" em torno de elementos do mapa existentes dentro de restrições específicas (como o tamanho do mapa).
      Esse layout garante que os controles padrão sejam compatíveis com os seus.
      Consulte Controle
      de posicionamento na v3 para mais informações.
    
    O código a seguir reposiciona os controles dos exemplos acima:
    
      
        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
    Use a API Maps JavaScript para criar controles de navegação personalizados.
      Para personalizar controles com a API v2, você precisa criar uma subclasse da
      classe GControl e definir processadores para os
      métodos initialize() e getDefaultPosition().
      Não há um equivalente à classe GControl na v3. Em vez disso,
      os controles são representados como elementos DOM. Para adicionar um controle personalizado
      com a API v3, crie uma estrutura DOM para o controle em um
      contrutor como filho de um Node (por exemplo, um
      elemento <div>) e adicione listeners de eventos para processar qualquer
      evento DOM. Envie Node para a matriz controls[position] dos mapas para adicionar uma instância do controle personalizado ao mapa.
    
    Considerando uma implementação de classe HomeControl que adere
      aos requisitos de interface mencionados acima (consulte a
      documentação de controles
      personalizados para mais detalhes), os exemplos de código a seguir mostram
      como adicionar um controle personalizado a um 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);
       
      
     
  
  
    Sobreposições
    As sobreposições refletem objetos que você "adiciona" ao mapa para designar pontos, linhas, áreas ou coleções de objetos.
 
   Adicionar e remover sobreposições
  Os tipos de objetos representados
  por uma sobreposição são os mesmos entre a v2 e a v3, mas são processados
  de maneira diferente.
  As sobreposições na API v2 foram adicionadas e removidas do mapa usando os métodos addOverlay() e removeOverlay() do objeto GMap2. Na v3, você atribui um mapa a uma sobreposição usando
  a propriedade map da classe de opções de sobreposição associada.
  Também é possível adicionar ou remover uma sobreposição diretamente chamando o
  método setMap() do objeto de sobreposição e especificando o mapa que você quer. Defina a propriedade do mapa como null para remover a sobreposição.
    Não há método clearOverlays() na v3.
  Se você quiser gerenciar um conjunto de sobreposições, crie uma matriz para
  armazená-las. Usando essa matriz, você pode chamar
  setMap() em cada sobreposição na matriz (transmitindo
  null se precisar removê-las).
  
  
    Marcadores arrastáveis
    Por padrão, os marcadores são clicáveis, mas não arrastáveis. Os dois exemplos a seguir adicionam um marcador arrastável:
    
      
        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
});
       
      
     
  
  
    Ícones
  Você pode definir um ícone personalizado para exibi-lo em vez do marcador padrão.
  Para usar uma imagem personalizada na v2, crie uma instância
  GIcon a partir da G_DEFAULT_ICON type e modifique-a. Se
  a imagem for maior ou menor que o ícone padrão, ela precisa
  ser especificada com uma instância GSize.
  A API v3 simplifica um pouco esse processo.
  Basta definir a propriedade icon do marcador como o URL da sua imagem personalizada, e a API vai dimensionar o ícone automaticamente.
  A API Maps JavaScript também oferece suporte a ícones complexos.
    Um ícone complexo pode incluir vários blocos, formas complexas
    ou especificar a "ordem de pilha" de como as imagens devem aparecer em relação
     a outras sobreposições. Para adicionar uma forma a um marcador na v2, é necessário especificar a propriedade adicional em cada instância GIcon e transmiti-la como uma opção para um construtor GMarker. Na v3, os ícones especificados dessa forma precisam definir as propriedades icon como um objeto do tipo Icon.
    A v3 não permite sombra de marcadores.
    Os exemplos a seguir mostram uma bandeira de praia na Praia de Bondi, na
  Austrália, com a parte transparente do ícone não clicável:
    
    
      
        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
});
       
      
     
  
  
    Polilinhas
    Uma polilinha consiste em uma matriz de LatLngs e uma série de segmentos de linha que conectam esses locais em uma sequência ordenada.
  Criar e mostrar um objeto Polyline na v3 é semelhante
  a usar um objeto GPolyline na v2. Os exemplos a seguir desenham uma polilinha geodésica semitransparente de 3 pixels de largura de Zurique a Sydney passando por Singapura:
    
      
      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);
       
      
     
    Polilinhas codificadas
    Não há suporte na v3 para a criação de objetos Polyline
      diretamente de polígonos
      codificados. Em vez disso, a biblioteca de geometria fornece métodos para codificar e decodificar polilinhas. Consulte Bibliotecas na API Maps v3 para mais informações sobre como carregar essa biblioteca.
    
    Os exemplos abaixo desenham a mesma poligonal codificada. O código da v3 usa o método decodePath() do namespace 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
    Um polígono define uma região em um loop fechado. Assim como o
  objeto Polyline, os objetos Polygon
  consistem em uma série de pontos em uma sequência ordenada. A classe Polygon
  do v3 é muito semelhante à classe GPolygon
  do v2, com a exceção de que
  você não precisa mais repetir o vértice inicial no final do
  caminho para fechar o loop. A API v3 vai fechar automaticamente todos os polígonos, desenhando um traço que conecta a última coordenada à primeira. Os snippets de código abaixo criam um polígono que representa o Triângulo das 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 editáveis pelos usuários
    As polilinhas e os polígonos podem ser editáveis pelos usuários. Os snippets de código abaixo são equivalentes:
    
    
      
        map.addOverlay(polyline);
polyline.enableEditing();
       
      
        polyline.setMap(map);
polyline.setEditable(true);
       
      
     
    Para recursos de desenho mais avançados, consulte a
      Biblioteca de desenhos
      na documentação da v3.
  
  
    Janelas de informações
    Um InfoWindow mostra conteúdo em uma janela flutuante acima do mapa. Há algumas diferenças importantes entre as janelas de informações na v2 e na v3:
    
    
      - A API v2 oferece suporte apenas a GInfoWindowpor mapa, enquanto a API v3 oferece suporte a váriasInfoWindows simultâneas em cada mapa.
- O InfoWindowda v3 vai permanecer aberto quando você clicar no mapa. OGInfoWindowda v2 é fechado automaticamente quando você clica no mapa. É possível emular o comportamento da v2
        adicionando um listenerclickno objetoMap.
- A API v3 não oferece suporte integrado para uma InfoWindowcom guias.
Sobreposições de solo
    Para colocar uma imagem em um mapa, use um objeto GroundOverlay. O construtor de um
      GroundOverlay é essencialmente o mesmo na v2 e na v3: ele
      especifica um URL de uma imagem e os limites da imagem como
      parâmetros.
    O exemplo a seguir coloca um mapa antigo de Newark, NJ, como uma sobreposição:
    
      
        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 mapa
Os tipos de mapa disponíveis na v2 e na v3 são um pouco diferentes, mas todos os tipos de mapa básicos estão disponíveis nas duas versões da API. Por padrão, a v2
usa blocos de mapa de vias "pintados" padrão. No entanto, a v3 exige que um tipo de mapa específico seja fornecido ao criar um objeto google.maps.Map.
  Tipos de mapa comuns
Os quatro tipos de mapa básicos estão disponíveis na v2 e na v3:
  - MapTypeId.ROADMAP(substitui- G_NORMAL_MAP)
    mostra a visualização de mapa de vias.
- MapTypeId.SATELLITE(substitui- G_SATELLITE_MAP)
    mostra imagens de satélite do Google Earth.
- O MapTypeId.HYBRID(substituiG_HYBRID_MAP)
    mostra uma combinação de visualizações normal e de satélite.
- MapTypeId.TERRAIN(substitui- G_PHYSICAL_MAP)
    mostra um mapa físico com base nas informações do terreno.
Veja a seguir um exemplo de definição do mapa para visualização de terreno na v2 e na v3:
  
    map.setMapType(G_PHYSICAL_MAP);
    
   
  
    map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
    
   
  
 
A API Maps JavaScript v3 também fez algumas mudanças nos tipos de mapa menos comuns:
  - Os blocos de mapa para corpos celestes diferentes da Terra não estão disponíveis como tipos de mapa na API v3, mas podem ser acessados como tipos de mapa personalizados. Confira um exemplo em Tipos de mapa personalizados.
  
- Não há um tipo de mapa especial na v3 que substitua o tipo G_SATELLITE_3D_MAPda v2. Em vez disso,
    você pode integrar o plug-in do Google Earth nos mapas v3 usando
    esta
    biblioteca.
Maximum Zoom Imagery
As imagens de satélite nem sempre estão disponíveis em níveis altos de zoom. Se você quiser
  saber o nível de zoom mais alto disponível antes de definir o nível de zoom,
  use a classe google.maps.MaxZoomService. Essa classe substitui
  o método GMapType.getMaxZoomAtLatLng() da v2.
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.");
    }
});
 
 
  Imagens de perspectivas aéreas
Ao ativar as imagens aéreas na v3, os controles são semelhantes ao controle GLargeZoomControl3D da v2, com um controle de rotação intersticial adicional para girar nas direções compatíveis.
 É possível acompanhar as cidades em que as imagens em 45° estão disponíveis no mapa de cidades com suporte. Quando as imagens de 45° estão disponíveis, uma opção de submenu é adicionada
 ao botão "Satélite" da API Maps.
  Camadas
  As camadas são objetos no mapa que consistem em uma ou mais
    sobreposições. Eles podem ser manipulados como uma única unidade e geralmente refletem
    coleções de objetos.
  
    Camadas permitidas
  A API v3 permite acesso a diversas camadas diferentes. Essas camadas
    se sobrepõem à classe GLayer
    v2 nas seguintes áreas:
  
   - 
    O objeto KmlLayerrenderiza elementos KML e GeoRSS em
    sobreposições v3, fornecendo o equivalente à camadaGeoXmlv2.
- O objeto TrafficLayerrenderiza uma camada que mostra as condições de trânsito, semelhante à sobreposiçãoGTrafficOverlayda v2.
Essas camadas são diferentes da v2. Confira as diferenças abaixo. Elas podem ser adicionadas a um mapa chamando setMap(), passando o objeto Map em que a camada vai aparecer.
  Mais informações sobre as camadas com suporte estão disponíveis na
  documentação de camadas.
  
  
    Camadas KML e GeoRSS
    A API Maps JavaScript é compatível com os formatos de dados KML e GeoRSS para
    mostrar informações geográficas. Os arquivos KML ou GeoRSS precisam ser de acesso público se você quiser incluí-los em um mapa. Na v3, esses
    formatos de dados são mostrados usando uma instância de KmlLayer,
    que substitui o objeto GGeoXml da v2.
    A API v3 é mais flexível ao renderizar KML, permitindo que você
      suprima as InfoWindows e modifique a resposta do clique. Consulte a documentação Camadas KML e GeoRSS para obter mais detalhes.
    Ao renderizar um KmlLayer,
      restrições de tamanho e complexidade são aplicadas. Consulte a
      documentação da KmlLayer
      para mais detalhes.
    
    Os exemplos a seguir comparam o carregamento de um arquivo 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);
       
      
     
  
  
    Camada Trânsito
    
     Na v3, é possível adicionar informações de trânsito em tempo real (quando compatível) aos seus mapas usando o objeto TrafficLayer. As informações de trânsito são fornecidas no momento em que a solicitação é feita. Estes exemplos mostram as informações de tráfego de Los Angeles:
    
    
      
        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);
       
      
     
    Ao contrário da v2, não há opções para o construtor TrafficLayer
     na v3. Incidentes não estão disponíveis na v3.
    
  
  Serviços
  
    Geocodificação
    A API Maps JavaScript fornece um objeto geocoder para geocodificar endereços de forma dinâmica com base na entrada do usuário. Se você quiser geocodificar endereços estáticos e conhecidos, consulte a documentação da API Geocoding.
    A API Geocoding foi
      atualizada e aprimorada significativamente, adicionando novos recursos e mudando
      a forma como os dados são representados.
    
    GClientGeocoder na API v2 oferecia dois métodos diferentes para a geocodificação direta e inversa, além de outros métodos para influenciar a forma como a geocodificação era realizada. Por outro lado, o objeto Geocoder do v3 fornece apenas um método geocode(), que recebe um literal de objeto contendo os termos de entrada (na forma de um objeto Geocoding Requests) e um método de callback. Dependendo se a solicitação contém um atributo address textual ou um objeto LatLng, a API Geocoding vai retornar uma resposta de geocodificação direta ou reversa. É possível influenciar a forma como a geocodificação é realizada transmitindo campos adicionais para a solicitação de geocodificação:
    
    
      - A inclusão de um addresstextual aciona a geocodificação direta, o que é equivalente a chamar o métodogetLatLng().
- A inclusão de um objeto latLngaciona a geocodificação reversa, o que é equivalente a chamar o métodogetLocations().
- A inclusão do atributo boundsativa a Viés de
      janela de visualização, equivalente a chamar o métodosetViewport().
- A inclusão do atributo regionativa a Predisposição
      de código de região, equivalente a chamar o
      métodosetBaseCountryCode().
      As respostas de geocodificação na v3 são muito diferentes das respostas da v2. A API v3
      substitui a estrutura aninhada usada pela v2 por uma estrutura mais simples,
      que é mais fácil de analisar. Além disso, as respostas da v3 são mais detalhadas: cada resultado tem vários componentes de endereço que ajudam a ter uma ideia melhor da resolução de cada resultado.
    
    
      O código a seguir recebe um endereço textual e mostra o primeiro resultado da geocodificação:
    
    
      
      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');
}
       
      
     
  
  
    Rotas
    A API Maps JavaScript v3 substitui a classe GDirections da v2 pela classe DirectionsService para calcular direções.
    
    O método route() na v3 substitui os métodos
      load() e loadFromWaypoints() da
      API v2. Esse método usa um único literal de objeto DirectionsRequest que contém os termos de entrada e um método de callback para execução no recebimento da resposta. As opções podem ser fornecidas neste literal de objeto,
      semelhante ao literal de objeto GDirectionsOptions na v2.
    
    
      Na API Maps JavaScript v3, a tarefa de enviar solicitações de direções foi separada da tarefa de renderizar solicitações, que agora é processada com a classe DirectionsRenderer. É possível vincular um objeto DirectionsRenderer a qualquer mapa ou objeto DirectionsResult usando os métodos setMap() e setDirections(). Como o renderizador é um
      MVCObject, ele vai detectar qualquer mudança nas propriedades e
      atualizar o mapa quando as direções associadas forem alteradas.
    
    O código a seguir demonstra como solicitar direções a pé para um local específico usando caminhos para pedestres a partir de um endereço. Somente o
      v3 pode fornecer instruções de caminhada no caminho de pedestres no
      zoológico de Dublin.
    
    
      
      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
    O Google Street View oferece vistas interativas em 360° de locais designados na área de cobertura. A API v3 oferece suporte ao Street View de forma nativa no navegador, diferente da v2, que exigia o plug-in Flash® para mostrar imagens do Street View.
    
    As imagens do Street View têm suporte por causa do objeto
      StreetViewPanorama na v3 ou do
      GStreetviewPanorama na v2. Essas classes têm interfaces diferentes, mas desempenham a mesma função: conectar o contêiner div às imagens do Street View e permitir que você especifique o local e o ponto de vista do panorama do 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);
}
       
      
     
    O acesso direto aos dados do Street View é possível pelo objeto StreetViewService na v3 ou pelo objeto GStreetviewClient semelhante na v2. Ambas oferecem interfaces semelhantes para extrair ou verificar a disponibilidade de dados do Street View e permitem a pesquisa por local ou ID de panorama.
    
    Na v3, o Street View é ativado por padrão. O mapa vai aparecer com um controle do Pegman do Street View, e a API vai reutilizar o div do mapa para mostrar panoramas do Street View. O código a seguir ilustra como emular o comportamento do v2 separando os panoramas do Street View em uma div separada.
    
    
      
      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);
}