Mapa com vários marcadores - Google Maps API JavaScript v3 Como adicionar multiplos marcadores com Google Maps API v3

Mapa com vários marcadores - Google Maps API JavaScript v3

por sábado, 14 de dezembro de 2013

Adicionar vários marcadores a um mapa sem recorrer a uma base de dados pode ser limitado mas tem as suas vantagens, quando o número de marcadores é reduzido.
Quando pretendemos introduzir até 10 ou 15 marcadores num mapa poderá ser mais eficaz a sua inclusão numa variável junto do código que cria o próprio mapa.


Neste artigo não entrarei em detalhes quanto à criação de mapas, marcadores e Info Windows. Essa informação está disponível nos seguintes artigos:

Antes de iniciar o tutorial vê uma demonstração do mapa ou faz o download do código necessário para seguir este exemplo.

DEMO DOWNLOAD

Definir a informação dos marcadores

Primeiro é necessário definir a posição do marcador no mapa e o conteúdo da InfoWindow.
A informação é guardada numa variável Array de objectos com o nome markersData da seguinte forma:

JavaScript /map.jsmarnoto.com
var markersData = [
  {
      lat: 40.6386333,
      lng: -8.745,
      nome: "Parque de Campismo Praia da Barra",
      morada1:"Rua Diogo Cão, 125",
      morada2: "Praia da Barra",
      codPostal: "3830-772 Gafanha da Nazaré" // não colocar virgula no último item de cada marcador
   },
   {
      lat: 40.59955,
      lng: -8.7498167,
      nome: "Parque de Campismo da Costa Nova",
      morada1:"Quinta dos Patos, n.º 2",
      morada2: "Praia da Costa Nova",
      codPostal: "3830-453 Gafanha da Encarnação" // não colocar virgula no último item de cada marcador
   },
   {
      lat: 40.6247167,
      lng: -8.7129167,
      nome: "Parque de Campismo da Gafanha da Nazaré",
      morada1:"Rua dos Balneários do Complexo Desportivo",
      morada2: "Gafanha da Nazaré",
      codPostal: "3830-225 Gafanha da Nazaré" // não colocar virgula no último item de cada marcador
   } // não colocar vírgula no último marcador
];
Esta forma de guardar informação não é a mais eficaz do ponto de vista de performance do código JavaScript. Mas o que se pretende aqui é mostrar da forma mais clara possível como criar um procedimento para inserir múltiplos marcadores num mapa.

Como criar os marcadores

Para inserir os marcadores definidos anteriormente no mapa é necessário criar uma função (displayMarkers()) que vai percorrer cada item do array de objectos markersData e criar o respectivo marcador recorrendo à função (createMarker()).
Primeiro vamos dar uma vista de olhos no código:

JavaScript /map.jsmarnoto.com
// Esta função vai percorrer a informação contida na variável markersData
// e cria os marcadores através da função createMarker
function displayMarkers(){

   // esta variável vai definir a área de mapa a abranger e o nível do zoom
   // de acordo com as posições dos marcadores
   var bounds = new google.maps.LatLngBounds();

   // Loop que vai percorrer a informação contida em markersData 
   // para que a função createMarker possa criar os marcadores 
   for (var i = 0; i < markersData.length; i++){

      var latlng = new google.maps.LatLng(markersData[i].lat, markersData[i].lng);
      var nome = markersData[i].nome;
      var morada1 = markersData[i].morada1;
      var morada2 = markersData[i].morada2;
      var codPostal = markersData[i].codPostal;

      createMarker(latlng, nome, morada1, morada2, codPostal);

      // Os valores de latitude e longitude do marcador são adicionados à
      // variável bounds
      bounds.extend(latlng); 
   }

   // Depois de criados todos os marcadores,
   // a API, através da sua função fitBounds, vai redefinir o nível do zoom
   // e consequentemente a área do mapa abrangida de acordo com
   // as posições dos marcadores
   map.fitBounds(bounds);
}

Os comentários inseridos no código devem ser suficientes para a compreensão do funcionamento desta função. Esta função percorre cada item da variável markersData e faz uma chamada à função createMarker, passando a respectiva informação. Adicionalmente é criada uma variável bounds que vai passar à API a localização de cada marcador. A função fitBounds() vai adequar o nível do zoom do mapa a fim de mostrar todos os marcadores.

Agora vejamos a função createMarker:

JavaScript /map.jsmarnoto.com
// Função que cria os marcadores e define o conteúdo de cada Info Window.
function createMarker(latlng, nome, morada1, morada2, codPostal){
   var marker = new google.maps.Marker({
      map: map,
      position: latlng,
      title: nome
   });

   // Evento que dá instrução à API para estar alerta ao click no marcador.
   // Define o conteúdo e abre a Info Window.
   google.maps.event.addListener(marker, 'click', function() {
      
      // Variável que define a estrutura do HTML a inserir na Info Window.
      var iwContent = '<div id="iw_container">' +
      '<div class="iw_title">' + nome + '</div>' +
      '<div class="iw_content">' + morada1 + '<br />' +
      morada2 + '<br />' +
      codPostal + '</div></div>';
      
      // O conteúdo da variável iwContent é inserido na Info Window.
      infoWindow.setContent(iwContent);

      // A Info Window é aberta com um click no marcador.
      infoWindow.open(map, marker);
   });
}
Os marcadores são adicionados ao mapa através da variável marker. Adicionalmente é definido o conteúdo da info window para cada marcador.

Estas duas funções não fazem sentido sem a função que inicializa a criação do mapa:

JavaScript /map.jsmarnoto.com
function initialize() {
   var mapOptions = {
      center: new google.maps.LatLng(40.601203,-8.668173),
      zoom: 9,
      mapTypeId: 'roadmap',
   };

   map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

   // Cria a nova Info Window com referência à variável infoWindow.
   // O conteúdo da Info Window é criado na função createMarker.
   infoWindow = new google.maps.InfoWindow();

   // Evento que fecha a infoWindow com click no mapa.
   google.maps.event.addListener(map, 'click', function() {
      infoWindow.close();
   });

   // Chamada para a função que vai percorrer a informação
   // contida na variável markersData e criar os marcadores a mostrar no mapa
   displayMarkers();
}
google.maps.event.addDomListener(window, 'load', initialize);
Ver exemplo do mapa.

Este exemplo mostra como adicionar múltiplos marcadores no mapa. Utiliza uma só Info Window para mostrar informação relativa a cada marcador.
Todas as dúvidas ou comentários são bem-vindos. Por favor, utilizar a secção de comentários para que todos partilhem da informação.


Download dos ficheiros necessários para este exemplo

Miguel Marnoto

A minha especialização no Google Maps e na sua API JavaScript v3 é uma consequência do gosto pelos mapas e o reconhecimento da importância que o serviço Google Maps tem hoje no dia-a-dia das pessoas.

58 comentários para ''Mapa com vários marcadores - Google Maps API JavaScript v3"

COMENTAR
  1. Me ajudou bastante! Excelente trabalho!

    ResponderEliminar
  2. olá sou o Junior Pereira
    estou com uma duvida, como fazer para por um icone diferente pra cada um dos varios marcadores pegando ja esse tutorial com varios marcadores ? é possivel isso? E ainda Podendo ver o que esta escrito dentro do infobox normalmente em cada um, poderia me ajudar? grato!

    ResponderEliminar
  3. Olá Junior Pereira,

    Sim, é possível definir uma imagem diferente para cada um dos marcadores. No artigo "Adicionar uma marcador com Google Maps" (http://www.marnoto.com/2013/09/adicionar-um-marcador-com-google-maps.html) eu mostro como fazer isso. Nesse exemplo só tem um marcador mas é fácil implementar essa função neste tutorial.

    Na varíavel "markersData = [..." adiciona uma nova propriedade para cada um dos marcadores: meuIcon: "url_para_a_sua_imagem.jpg"

    Na função "displayMarkers(){..." e logo abaixo de "var codPostal =..." adiciona uma nova variável "var novoIcon = markersData[i].meuIcon;".

    Logo abaixo adiciona o novo parametro na chamada da função "createMarker(latlng, nome, morada1, morada2, codPostal, novoIcon);"

    Não esqueça de fazer o mesmo na função "function createMarker(latlng, nome, morada1, morada2, codPostal, novoIcon){..."

    Depois, dentro da função "createMarker" só tem de adicionar a nova propriedade na variável "marker", dessa forma:
    var marker = new google.maps.Marker({
    map: map,
    position: latlng,
    title: nome,
    icon: novoIcon
    });

    Se tiver dificuldades com a adaptação do código me diga algo, eu posso fazer um exemplo completo para você.

    ResponderEliminar
    Respostas
    1. Olá amigo, estou desesperadamente precisando fazer várias marcações com ícones diferentes, as marcações já consegui fazendo seu tutorial, mas quando sigo as instruções acima pra colocar um ícone diferente pra cada marcação, o mapa simplesmente não carrega =( pode me ajudar?

      Eliminar
  4. Miguel, Parabéns, excelente tutorial!!
    Uma dúvida, tem como o click no marcador levar pra um link externo?
    Tipo ao clicar no marcador de uma loja ele redireciona pro site dela.

    ResponderEliminar
    Respostas
    1. Olá,

      Obrigado, fico contente sabendo que este tutorial está sendo útil para ti.

      O click no marcador para levar ao site da loja pode ser feito de duas formas:

      1. window.location.href = 'http://www.websitedaloja.com'; // isto abre uma nova página na mesma janela/separador.
      2. window.open('http://www.websitedaloja.com', '_blank'); // isto abre uma nova página em uma nova janela/separador.

      Utiliza uma desta funções dentro do google.maps.event.addListener(marker, 'click', function() {...

      Fiz um exemplo para ti: http://maps.marnoto.com/markerclickurl/exemplo.html

      Depois diz-me se deu resultado.

      Eliminar
  5. Olá Miguel, parabéns pelo tutorial, muito bem escrito!!
    Tenho uma duvida, estou usando o postgresql e escrevendo um programa usando django, tem como eu dar um select em todos os pontos(objetos com lat e long) de um determinado dia/hora/momento no meu banco de dados e fazer com que o google maps plote no meu mapa a posição de cada um? No caso seria mais do que um marcador.
    Desde já agradeço.
    Abraços!!

    ResponderEliminar
    Respostas
    1. Olá, obrigado. De momento não tenho nada preparado que te possa passar relacionado com postgresql e django. No meu projecto http://www.viveraveiro.pt estou a usar MySQL, PHP. O XML faz a ligação entre o PHP e a API JavaScript. Depois de passar os dados para XML ou JSON, a parte de JavaScript funciona sempre da mesma maneira. Se quiseres manda-me uma mensagem através do formulário de contacto com o teu e-mail, poderei mostrar-te como funciona o JavaScript sobre o XML. Talvez isso te ajude.
      Abraço.

      Eliminar
    2. Miguel estou estudando a API para implementar em um projeto meu, depois de muito procurar e estudar encontrei seu site e dicas, fiquei impressionado com a qualidade e boa vontade para com seus seguidores, estou precisando justamente do que implementou no seu projeto "http://www.viveraveiro.pt", \o/. Estou usando MySQL, PHP, ajax e jQuery JSON no meu projeto. Tem o exemplo de como implementar da forma que fez com essas tecnologias. Obrigado!

      Eliminar
  6. Bom dia!
    Miguel, ótima explicação!
    Tenho uma pergunta, gostaria de capturar o valor da coordenada ao clicar no mapa, inserindo ao método:
    google.maps.event.addListener(map, 'click', function() {

    });

    ResponderEliminar
    Respostas
    1. Olá Julio,
      Obrigado pelo teu comentário.
      Para capturar o valor da coordenada com um click no mapa, e utilizando o método indicado por ti, que é o método correcto, basta fazer o seguinte:

      google.maps.event.addListener(map, "click", function(event) {
      var lat = event.latLng.lat().toFixed(6);
      var lng = event.latLng.lng().toFixed(6);
      });

      Os métodos event.latLng.lat() e event.latLng.lng() retornam as respectivas coordenadas. A função toFixed(6) é utilizada para limitar o número de casas decimais para 6. O Google Maps não utiliza mais de 6 casas decimais mas aqueles métodos retornam coordenadas com mais de 6 casas decimais.

      Podes ver uma explicação mais detalhada sobre estes métodos no seguinte artigo http://www.marnoto.com/2013/12/obter-coordenadas-no-novo-google-maps.html.

      Eliminar
  7. google.maps.event.addListener(map, 'click', function(e) {
    var LatE = e.latLng.lat();
    var LongE = e.latLng.lng();
    insereNo(novoPonto,LatE,LongE);

    novoPonto++;
    });

    ResponderEliminar
  8. Cara como inserir um gerador de rota para que eu poça colocar um endereço e clicar num dos marcadores para gerar a rota.

    ResponderEliminar
    Respostas
    1. André K, esse tema está na calha para um novo artigo que será publicado em breve. Entretanto deixo aqui o link para a documentação do Google Maps API v3 (https://developers.google.com/maps/documentation/javascript/directions).
      Se ainda assim tiveres dúvidas, contacta comigo através do formulário de contacto.

      Eliminar
  9. Eu vi a documentação porem n consegui resolver meu problema quando sai o novo artigo?

    ResponderEliminar
    Respostas
    1. Ainda não tem data marcada. Diz-me em concreto qual é o problema, e se possível envia um link para algum exemplo.

      Eliminar
  10. Eu tenho um mapa com uns 10 marcadores. Esse mapa quero colocar em site porem quando eu exporto ele não aparece a ferramenta de gerar rota exemplo o cara digita o seu endereço e clica em um marcador pra gerar o trajeto, distância esse mapa eu fiz no my maps quero ver se n tem nada pronto na api do google

    ResponderEliminar
    Respostas
    1. Olá André, de momento não tenho nenhum exemplo de rota com a API do Google Maps. Se essa funcionalidade é importante para o teu projecto, talvez eu possa ajudar, contacta-me.

      Eliminar
  11. E muito importante....qual seu e-mail?

    ResponderEliminar
  12. Tenho um mapa real time que ele atualize sozinho de tempos em tempos?

    ResponderEliminar
  13. bom dia, tenho em banco de dados mySql alguns endereço com posição de longitude e latitude e gostaria de colocar essas marcações em mapa api v3 do google você se e possivel e se teria uma ideia de como isso e feito. obrigado

    ResponderEliminar
    Respostas
    1. Desculpe a demora na resposta mas estive de férias. Eu comecei por estudar os tutoriais disponíveis no site da própria Google que são Using PHP/MySQL with Google Maps e Creating a Store Locator with PHP, MySQL & Google Maps, Estes tutoriais foram a base do meu trabalho no meu projecto www.viveraveiro.pt.

      Eliminar
  14. Miguel, muito obrigada pela ajuda com a API! Li quase todos os artigos e gostei muito! Achei bem dinâmico e bem explicado. Parabéns!

    ResponderEliminar
    Respostas
    1. Olá Daniela, muito obrigado pelo comentário. Boa sorte para os seus projectos.

      Eliminar
  15. Bom Dia Miguel, parabéns pelo tutorial. Como eu poderia remover esses marcadores sem atualizar o mapa, teria alguma forma de fazer isso

    ResponderEliminar
  16. Miguel, cara adorei o seu post, aqui rodou certinho... só tenho uma duvida, em outro post, vc ensinou a como colocar um marcador com imagem no mapa, tentei fazer a mesma coisa com esse porém nao tive o resultado esperado, vc pode explicar como fazer isso?

    Desde já agradeço!!! E mais uma vez Obrigado!!!

    ResponderEliminar
    Respostas
    1. Olá, obrigado pelo teu comentário!
      Para colocar um marcador com imagem só necessitas de indicar qual a imagem que queres utilizar. Ou seja, na função createMarker deves indicar a opção "icon: tua_imagem_aqui.jpg"

      function createMarker(latlng, nome, morada1, morada2, codPostal){

      var tuaImagem = 'images/tua_imagem_aqui.jpg';

      var marker = new google.maps.Marker({
      map: map,
      position: latlng,
      title: nome,
      icon: tuaImagem // define a nova imagem do marcador
      });

      Eliminar
  17. Prezado boa noite!
    Cara ótimo tutorial, bem explicado, e justamente pelo jeito com vc o criou me chamou atenção, eu tenho um código que varre um cadastro de apontamentos, só para exemplificar um determinado municipio eu tenho 140 registros, e eu noto que os apontadores não aparecem todos, então eu executo novamente a rotina e percebo que aparecem mais registros, é como se a API do GM não conseguisse processar tudo da forma como estou enviando ou seja eu faço uma consulta no banco e de acordo com o numero de registros vou iterando sobre cada um deles e chamando uma função para adicionar o marcador, vc já teve experiencia com este comportamento? só para efeito eu coloquei uma interação entre cada registro e neste caso os marcadores aparecem.

    ResponderEliminar
    Respostas
    1. Olá, obrigado pelo seu comentário. O problema exposto nunca me aconteceu, você tem algum exemplo que eu possa verificar? Obrigado.

      Eliminar
    2. Olá Sr. Miguel bom dia!
      Cara obrigado por responder, bem minha esperança estava no fato da quantidade de registros ser o problema, então eu coloquei uma parada da rotina (como se eu estivesse debugando) entre cada apontador e notei que com isto os apontadores aparecem, bem quanto a um exemplo eu não tenho, estou em desenvolvimento não tenho o sistema publicado, o único jeito seria por Team Viewer no PC

      Eliminar
    3. Olá, podes retirar o Sr. antes de Miguel? Obrigado ;)

      Envia-me uma mensagem através da página "CONTACTO", para eu ficar com o teu email. Não publiques o teu email aqui nos comentários. Logo encontramos uma forma de eu poder verificar o teu código.

      Eliminar
    4. Olá bom dia!
      Prezado passei um tempo sem mexer no projeto, tava ficando stressado com a situação, hoje resolvi colocar um else no código que usa o serviço GEOCODER para o caso de não retornar Ok bem veio diversas mensagens com este retorno OVER_QUERY_LIMIT, no meu caso a consulta com locais do municipio de Recife tem 80 registros apenas, como me saio desta?

      Eliminar
    5. O serviço de geocoder tem um limite de cerca de 10 pedidos consecutivos, depois do 11º o serviço faz uma parada de cerca de 150 milisegundos. Isto para evitar abusos e consequente sobrecarga dos servidores, o que poderá degradar a velocidade do serviço. Este serviço não serve para fazer conversão de grandes quantidades de marcadores.
      Mesmo assim, se quiseres utilizar o serviço dessa forma, só necessitas de parar o teu código com setTimeout, quando o retorno para OVER_QUERY_LIMIT é verdadeiro tens de parar o código em cerca de 150ms.
      Este serviço deve ser utilizado para 1 ou 2 pedidos e nunca para conversões em massa.

      Eliminar
  18. Miguel, tenho um projeto que mostra no mapa as marcações dos clientes são mais de 20 clientes, esses clientes são cadastrados no mysql, e realizo um select e apresento eles no mapa, no entanto só aparecem 11 registros marcados no mapa, e tenho mais 20, tem alguma limite de marcação para essa api????

    ResponderEliminar
    Respostas
    1. Jader boa noite, prezado é o mesmo que está acontecendo comigo, será que a gente não se ajuda?
      Eu coloquei uma parada entre cada registro, um alert e noto que assim todos marcadores aparecem.

      Eliminar
  19. Boa tarde Miguel, estou com duvida, poderia me ajudar, como exemplo nesse link http://hpneo.github.io/gmaps/examples/static_markers.html , gostaria de saber se ha essa opçao de modificar os marcadores?
    Grato

    ResponderEliminar
  20. Miguel Marnoto, Boa Noite.
    Cara eu só estudante de TI curso Sistemas de informação
    gostaria de uma ajuda sua
    to cursando a diciplina projeto integrado
    tenho que desenvolver um sistemas simples,mais to apanhando muito
    resumuir pra ti

    um sistemas que encontra guinchos no mapa e traça a routa para o mais proximo
    se caso ele n tiver em usu
    e um cadastro para adicionar mais pontos no mapa como se foce mais guinchos..
    Agradeço dês de já
    abração

    caso tenha disponibilidade de me ajuda
    me add no zap (61)92525184
    ja tenho alguma coisa pronta se quizer da uma olhada!!
    abraçao de novo !!!

    ResponderEliminar
  21. Olá Miguel boa tarde!
    Tenho uma API sincronizando geolocalização, em uma base de dados em MySql + PHP com 20 mil registros e essa sincronização está demorando muito tempo , mais de duas horas, VOCE SABERIA ME DAR UMA DICA PARA MELHORAR ISSO? Obrigado, Octavio.

    ResponderEliminar
  22. oi como eu coloco uma fototinha em vez de marcador.. tipo cada lugar eu ponho uma fotinho diferente. um endereço tal uma foto outro endereço outra foto

    ResponderEliminar
    Respostas
    1. Olá Bianca, segue um link de ajuda http://webdesign.tutsplus.com/pt/tutorials/how-to-add-branded-branch-locations-to-google-maps--cms-20457

      Eliminar
  23. Bom dia Marnoto, estou tendo dificuldades em ler o arquivo texto para exibição dos marcadores, pois criei um mapa para gravar os dados e outro que quero ler os marcadores cadastrados, porém o javascript que desenvolvi interfere diretamente na api google maps e não exibe nada, vc consegue me dar um norte de ajuda amigo, estou meio sem saber como proceder, caso queira checar o desenvolvimento de uma olhada em http://cbhpp.org/mapa/mapa4/mapa.html

    ResponderEliminar
  24. Boa Tarde, Marmoto!

    Tenho um sistema que traça uma rota para vários pontos e gostaria que os marcadores de cada ponto ao invés de aparecer letras, aparecesse números. Isso é muito difícil de fazer? estou setando os pontos da seguinte maneira. Teria como me ajudar por gentileza?

    function carregaMapa() {
    var enderecoPartida = '-22.8086177,-43.3524389';
    var enderecoChegada = '-22.8086177,-43.3524389';

    var request = {
    origin: enderecoPartida,
    destination: enderecoChegada,
    waypoints: [
    {location: '-22.8917638,-43.2690359'},
    {location: '-22.9043971,-43.1093638'},
    {location: '-22.8691619,-43.2689049'}
    ],
    travelMode: google.maps.TravelMode.DRIVING

    };

    directionsService.route(request, function (result, status) {
    if (status === google.maps.DirectionsStatus.OK) {
    directionsDisplay.setDirections(result);
    }
    });
    };

    ResponderEliminar
  25. Boa tarde marnoto.
    Tem algum exemplo com todo o código em um único HTML?

    ResponderEliminar
  26. Olá Miguel,
    Inicialmente parabéns pelo artigo.
    Tenho uma mapa onde irei marcar vários estabelecimentos ambos com o mesmo ícone porém esse mapa também tem geolocalização porém o ícone na geolocalização seria outro, como poderia resolver isso?

    ResponderEliminar
  27. Preciso marcar no mapa os pontos de cada carro em movimento. Como faço para Marcar vários pontos no Mapa ao mesmo tempo.

    ResponderEliminar
  28. Boa noite. No caso de eu ter apenas uma lista de endereços (sem latitude e longitude) é possivel marcar?

    ResponderEliminar
  29. Boa noite. O mapa só funciona localmente. Quando coloco no servidor web ele da erro de JS. O que pode estar acontecendo? Para lhe mostrar, fiz o download da pasta múltiplos_marcadores, e coloquei do mesmo jeito no servidor. Veja que não funciona: http://uang.com.br/multiplos_marcadores/mapa.html.

    ResponderEliminar
    Respostas
    1. Luiz isso acontecia comigo aqui quando eu não estava Usando uma Chave API Google válida para que a aplicação rodasse na web.

      Eliminar
  30. Miguel Marnoto parabéns pelo seu trabalho e por ajudar as pessoas.
    Estou desenvolvendo uma aplicação que eu ploto vários marcadores no mapa e utilizo funções para alterar o ícone e para traçar uma polyline entre o marcador e a origem de onde ele veio.
    O que não consigo fazer é mudar o ícone do marcador qu estou selecionando toda vez que seleciono um marcador outro marcador que muda o icone.
    Como eu faço para setar o SetIcon para o marcador selecionado?
    Obrigado!

    ResponderEliminar
  31. Estou aqui no Brasil, precisamente no Rio de Janeiro. Muito bom seu material. Parabens!

    ResponderEliminar
  32. Boa tarde, estou com um problema que o mapa começa a mostrar as informações e logo depois me dá um aviso de erro no carregamento e pede para verificar o código do js o que posso fazer?

    ResponderEliminar
  33. Como colocar a geolocalização do usuário?

    ResponderEliminar
  34. Ola! muito top, esse esquema minha dúvida, é possível remover os outros marcadores de referencia acho que é assim que chama, ex. "os nomes de restaurantes, praças, etc... só deixando os que eu informar"

    Obrigado!

    ResponderEliminar