Por que eu devo ler este artigo:Vamos trabalhar neste artigo uma visão introdutória da Google Maps API, de modo que serão utilizados exemplos básicos, afim que venha a despertar a curiosidade e estimular o uso da mesma em nossas aplicações.
Google Maps API

O que é a Google Maps API?

É um serviço público e gratuito que qualquer pessoa pode usar em seus sites e aplicações. Desde que o usuário final não seja cobrado, pode usar este serviço, para isto existe a versão paga da API, mas não é o caso para este artigo que visa apenas o estudo e compreensão da mesma.

Na verdade o Google Maps possui várias API’s que podem ser incorporadas ao site/aplicação dependendo de cada caso. Vejamos na tabela abaixo essas API’s e suas descrições retiradas do site oficial da API.

API Descrição
Google Maps JavaScript APIIncorpore um mapa do Google em sua página da web usando JavaScript. Manipule o mapa e adicione conteúdo com a ajuda de vários serviços.
Google Maps API for FlashUse essa API ActionScript para incorporar um mapa do Google na sua página da web ou aplicativo baseado em Flash. Manipule o mapa em três dimensões e adicione conteúdo com a ajuda de vários serviços.
Google Earth APIIncorpore um verdadeiro globo digital em 3D à sua página da web. Leve os seus visitantes a qualquer lugar da Terra (até mesmo nas profundezas dos oceanos) sem tirá-los de sua página da web.
Google Static Maps APIIncorpore uma imagem simples e rápida do Google Maps em sua página da web ou site para celular sem precisar de códigos JavaScript ou qualquer carregamento dinâmico de página.
Serviços da webUse solicitações de URL para acessar informações de geocodificação, rotas, elevação e lugares dos aplicativos cliente e manipule os resultados em JSON ou XML.
Google Maps Data APIVisualize, armazene e atualize dados de mapa por meio de feeds da Google Data API, usado um modelo de elementos (marcadores, linhas e formas) e coleções de elementos.

Também temos a versão mobile que não difere muito do que estudaremos.

O que podemos fazer com a Google Maps API?

Nesse artigo o objeto de nosso estudo será a API em Javascript na sua terceira versão, com a qual podemos fazer todas aquelas coisas que você vê no Google Maps, marcar pontos como nossos ícones, desenhar círculos, polígonos, desenhar trajetos dentre outros.

A API é muito grande e seria impossível descrever toda ela aqui, então vamos trabalhar o que pode ser considerado como mais relevante para uma apresentação da API.

Antes de começarmos a brincar com nossos mapas, devemos obter uma chave de autenticação, sem ela não podemos incorporar a biblioteca JavaScript na página. Podemos conseguir a chave gratuitamente, porém ela tem suas limitações, mas nada que vá atrapalhar projetos pequenos. Podemos realizar até 25.000 requisições, está bom não é? Se você trabalha com rastreamento ferrenho, nesse caso você vai precisar da chave paga, mas aí são “outros quinhentos”.

Para obter a chave devemos:

  • Ter uma conta do Google.
  • Acessar esse link.
  • Ativar a Google Maps API v3.
  • A gora em API Access você pode pegar a sua chave, veja a Figura 1.
Chave de acesso aos serviços do Google
Figura 1: Chave de acesso aos serviços do Google.

Agora sim estamos prontos para começar, vamos lá.

Desenhando o mapa

Para desenhar o mapa temos que seguir basicamente três passos, são eles:

  • Incorporar a biblioteca da API do Google.
  • Designar um Elemento DOM, uma DIV, por exemplo, onde será desenhando o mapa.
  • Inserir o trecho de código JavaScript para definir as opções do mapa instanciando, por fim, um novo objeto.

Acompanhe o código da Listagem 1.

Listagem 1: Desenhando o mapa


<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
      html { height: 100% }
      body { height: 100%; margin: 0; padding: 0 }
      #map_canvas { height: 100% }
    </style>
    <script type="text/javascript"
      src="https://maps.googleapis.com/maps/api/js?key=coloque_sua_chave_aqui” >
    </script>
    <script type="text/javascript">
      function initialize() {
        var mapOptions = {
          center: new google.maps.LatLng(-34.397, 150.644),
          zoom: 8,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"),
            mapOptions);
      }
    </script>
  </head>
  <body onload="initialize()">
    <div id="map_canvas" style="width:100%; height:100%"></div>
  </body>
</html>   

Ao acessar um arquivo HTML com este código veremos o mapa do Google ocupado 100% da tela, isso por que definimos nossa div “map_canvas” com altura e largura iguais a 100%.

A URL que usamos para importar a biblioteca recebeu a chave como parâmetro, esse parâmetro é obrigatório, mas ela também recebe outros parâmetros que podem ser úteis em alguns casos.

O que temos no JavaScript é a criação do nosso mapa na instancia de “google.maps.Map”, que recebe o id DOM do elemento e as opções iniciais do mapa. Usamos “center” que recebe um objeto LatLng também da API do Google que será a coordenada central, o “zoom” define a altura inicial da visualização e por fim “mapTypeId” que também recebe um tipo da Google API e diz qual será o tipo de mapa (satélite, terreno etc).

Existem muitas outras opções para iniciar o mapa e também métodos que podem alterá-las mesmo depois do mapa criado, como setZoom(), por exemplo.

Colocando um Marker

Marker’s são pontos no mapa, eles são definidos por uma posição geográfica e o ícone, sendo que este último não é obrigatório, caso não passarmos, a API colocará um padrão.

Listagem 2: Desenhando um Marker


//nova posição
var ponto = new google.maps.LatLng(-25.363882,131.044922);
var marker = new google.maps.Marker({
      position: ponto,//seta posição
      map: map,//Objeto mapa
      title:"Hello World!"//string que será exibida quando passar o mouse no marker
      //icon: caminho_da_imagem
  });

O processo não difere de desenhar um mapa, devemos definir as opções iniciais e instanciar um novo objeto Marker.

Da mesma forma que no mapa, existem muitas opções e métodos para usarmos com os marker’s.

Bem, pessoal, ficamos por aqui, mas não antes de passar os links para a documentação.

Inserindo os pontos no mapa

Para podermos inserir os pontos no mapa, precisamos de no mínimo a latitude e a longitude desses pontos. No meu caso, irei criar um arquivo JSON que irá conter esses pontos, mas você pode armazená-los onde achar melhor. De início, o nosso mapa terá 3 pontos: Um no estado de Minas Gerais, outro em São Paulo e outro no Rio de Janeiro. A latitude e longitude desses pontos eu peguei na demo de busca de endereço no Google Maps.

Depois de criado, o nosso arquivo pontos.json ficará assim:


  [
    {
        "Latitude": -19.212355602107472,
        "Longitude": -44.20234468749999
    },
    {
        "Latitude": -22.618827234831404,
        "Longitude": -42.57636812499999
    },
    {
        "Latitude": -22.57825604463875,
        "Longitude": -48.68476656249999
    }
]

Em seguida, criaremos uma função para colocar esses três pontos no mapa:


function carregarPontos() {
 
    $.getJSON('js/pontos.json', function(pontos) {
 
        $.each(pontos, function(index, ponto) {
 
            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(ponto.Latitude, ponto.Longitude),
                title: "Meu ponto personalizado! :-D",
                map: map
            });
 
        });
 
    });
 
}
 
carregarPontos();

Notem que estou usando jQuery para obter o arquivo JSON e devido a isso nós temos que incluir a biblioteca jQuery na nossa página.

O código acima é simples:

  1. Uso o $.getJSON para pegar todos os pontos;
  2. Usando o $.each, pego cada ponto e vou colocando-os no mapa, definindo sua posição (position), título (title) e qual mapa (map) ele pertence.

O próximo passo é personalizar esses pontos, trocando o marcador padrão do Google Maps e exibir uma caixa de informação personalizada ao clicar em cada marcador do mapa.

Personalizando os marcadores

Primeiro de tudo, vamos alterar o ícone do marcador, colocando um personalizado. Aqui você tem, basicamente, duas opções: Criar um ícone próprio ou pegar um pronto. Caso queira pegar um pronto, recomendo o site Icon Finder. No meu caso, usarei esse marcador.

Depois que você escolher o marcador, nos parâmetros do google.maps.Marker, passe o parâmetro icon com o valor do endereço do seu marcador. Ficará assim:


...
 
var marker = new google.maps.Marker({
    position: new google.maps.LatLng(ponto.Latitude, ponto.Longitude),
    title: "Meu ponto personalizado! :-D",
    map: map,
    icon: 'img/marcador.png'
});
 
...

Está começando a ficar bonito! Agora vamos criar o balão de informação de cada ponto, que será exibido ao clicar nos marcadores dentro do mapa.

Personalizando a caixa de informação

É interessante para o usuário poder clicar nos marcadores do mapa e ver alguma informação relacionada ao marcador em questão. Para exibir essas informações de cada marcador, temos duas opções:

Utilizar a caixa de informação padrão

Nesse tutorial não irei utilizar a caixa padrão do Google Maps, mas se caso ela atenda as suas necessidades, deixo abaixo o código para implementá-la.


var marker = new google.maps.Marker({...
 
var infowindow = new google.maps.InfoWindow(), marker;
 
google.maps.event.addListener(marker, 'click', (function(marker, i) {
    return function() {
        infowindow.setContent("Conteúdo do marcador.");
        infowindow.open(map, marker);
    }
})(marker))

Utilizar uma caixa de informação personalizada

Para criar uma caixa de informação totalmente personalizada, irei utilizar o InfoBox, o qual faz parte do Google Maps Utility Library v3.

Vamos baixar o InfoBox e referenciá-lo na nossa página HTML. Em seguida, escreveremos um pouco de código para exibir o InfoBox ao clicar nos marcadores do nosso mapa.

Identificadores únicos em cada ponto

Iremos garantir que no nosso mapa nós teremos apenas um ponto aberto por vez, ou seja, ao clicar em um marcador, se houver algum InfoBox aberto, iremos fechá-lo e abrir o InfoBox do marcador clicado. Para isso, vamos editar o arquivo pontos.json e colocar um identificador único em cada ponto, pois será com ele que faremos essa verificação.


[
    {
        "Id": 1,
        "Latitude": -19.212355602107472,
        "Longitude": -44.20234468749999
    }
    ...
]

Relacionando cada marcador com o InfoBox

Para cada marcador que colocamos no mapa, temos que fazer uma referência ao InfoBox, criando um objeto do tipo InfoBox, referenciando qual é o seu marcador e um listener para garantir a abertura do InfoBox no evento clique do marcador.


...
var idInfoBoxAberto;
var infoBox = [];
 
function abrirInfoBox(id, marker) {
    if (typeof(idInfoBoxAberto) == 'number' && typeof(infoBox[idInfoBoxAberto]) == 'object') {
        infoBox[idInfoBoxAberto].close();
    }
 
    infoBox[id].open(map, marker);
    idInfoBoxAberto = id;
}
 
function carregarPontos() {
    ...
 
    var myOptions = {
        content: "<p>Conteúdo do InfoBox</p>",
        pixelOffset: new google.maps.Size(-150, 0)
    };
 
    infoBox[ponto.Id] = new InfoBox(myOptions);
    infoBox[ponto.Id].marker = marker;
 
    infoBox[ponto.Id].listener = google.maps.event.addListener(marker, 'click', function (e) {
        abrirInfoBox(ponto.Id, marker);
    });
}

Definindo o visual do InfoBox

Por último, vamos personalizar o visual do nosso InfoBox através da CSS:


.infoBox { background-color: #FFF; width: 300px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; border: 2px solid #3fa7d8; border-radius: 3px; margin-top: 10px }
.infoBox p { padding: 0 15px }
.infoBox:before { border-left: 10px solid transparent; border-right: 10px solid transparent; border-bottom: 10px solid #3fa7d8; top: -10px; content: ""; height: 0; position: absolute; width: 0; left: 138px }

Agrupando pontos próximos

Imagine que tenhamos muitos marcadores em uma determinada rua da cidade de Campinas. Ao carregar o mapa com pouco zoom (como estamos fazendo atualmente), iremos ver um ponto em cima do outro, dificultando assim o clique nos marcadores para visualizar suas informações.

Para resolver esse problema, iremos agrupar esses marcadores quando o mapa estiver com pouco zoom, e conforme aumentarmos o zoom, iremos separar esses marcadores, de tal forma que eles fiquem claramente separados. Para fazer esse processo, utilizaremos o Marker Clusterer Plus, do Google Maps Utility Library v3.

Primeiro de tudo, baixe o Marker Clusterer Plus e referencie-o em nossa página HTML. Após isso, basta criar um array markers, o qual irá conter cada um dos marcadores, e passá-los para o MarkerClusterer:


...
var markers = [];
 
function carregarPontos() {
    $.getJSON('js/pontos.json', function(pontos) {
 
        $.each(pontos, function(index, ponto) {
 
            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(ponto.Latitude, ponto.Longitude),
                title: "Meu ponto personalizado! :-D",
                icon: 'img/marcador.png'
            });
 
            ...
 
            markers.push(marker);
        });
 
        var markerCluster = new MarkerClusterer(map, markers);
    });  
};

Agora o MarkerClusterer irá agrupar automaticamente os marcadores muito próximos um do outro. Perceba que no lugar dos marcadores, ele exibe um ícone e um número, que indica a quantidade de marcadores agrupados. Clicando em cima desse número, o mapa aumenta o zoom nesse ponto, e conforme os pontos vão se separando, esse número vai diminuindo.

Zoom automático para caber todos os pontos na tela

O nosso mapa agora possui marcadores personalizados, agrupamento de marcadores e caixas de informação totalmente estilizadas por CSS. O último passo é, ao carregar o mapa pela primeira vez, colocar um zoom automático de forma com que todos os marcadores sejam exibidos na tela do usuário, sem esconder nenhum ponto.

Para fazer isso, utilizaremos o google.maps.LatLngBounds() e fitBounds:


...
 
    $.getJSON('js/pontos.json', function(pontos) {
 
        var latlngbounds = new google.maps.LatLngBounds();
 
        ...
 
            markers.push(marker);
 
            latlngbounds.extend(marker.position);
 
        });
 
        var markerCluster = new MarkerClusterer(map, markers);
 
        map.fitBounds(latlngbounds);
 
    });
 
...

O mapa carregará com um zoom de modo a exibir todos os pontos no mapa: Os que havíamos colocados previamente no Brasil, e um outro no extremo norte do mapa, na Colômbia.


Saiu na DevMedia!

  • Dê o próximo passo após o HTML/CSS!:
    Nesta série falamos sobre o que vem depois do HTML/CSS. Saiba o que é requisição, resposta e se prepare para os seus primeiros passos na programação back-end.

Saiba mais sobre API ;)

  • Por que eu criaria/usaria uma API?:
    Nesta série falamos sobre como trabalhar com API, começando com um bate papo sobre nossas experiência com projetos desenvolvidos dessa forma.