set 07

Já tinha dado uma lida aqui, outra ali, mas hoje resolvi pôr a mão na massa definitivamente e fazer algo que alguns clientes vêm pedindo há algum tempo. Uma ferramenta simples onde pudesse colocar alguns endereços ordená-los como eu quiser e pedir ao google que trace as rotas entre os pontos.

1. Iniciando

Vamos começar com a estrutura básica e a inicialização do mapa.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps - Rotas</title>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" />

  <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
  <script type="text/javascript">
    var directionDisplay;
    var map;

    function initialize() {
      directionsDisplay = new google.maps.DirectionsRenderer();
      var saopaulo = new google.maps.LatLng(-23.5489433, -46.6388182);
      var myOptions = {
        zoom: 12,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center: saopaulo
      }
      map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
      directionsDisplay.setMap(map);
    }

  </script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="float:left;width:100%;height:100%;"></div>
</body>
</html>

2. Adicionando alguns controles

Certo. Vamos modificar um pouco e colocar um painel de controle a direita, para que possamos adicionar uma lista com endereços, para facilitar um pouco, vamos carregar o jQuery (1.6.2) e jQueryUI (1.8.16). Nosso HTML entre as tags <body></body> ficam assim.

<div id="map_canvas" style="float:left;width:70%;height:100%;"></div>
<div id="control_panel" style="float:right;width:30%;text-align:left;">
  <div style="padding:10px">
    <input type="text"   id="addr" name="address" />
    <input type="button" id="adic" name="adicionar" value="Adicionar à Rota" />

    <p>Dê um duplo clique para remover um endereço da rota</p>

    <ol id="route">
      <li id="1">R. Cipriano Barata, 200 - São Paulo</li>
      <li id="2">Av. Lacerda Franco, 400 - São Paulo</li>
    </ol>

    <input type="button" id="trace" name="trace" value="Traçar Rota" />
  </div>

</div>

E ao nosso JavaScript adicionamos:

    $(function(){

      //Adiciona endereço à lista
      $('#adic').click(function(){
        var ender = $('#addr').val();
        if (ender != '') {
          $('#addr').val('');
          var newid = new Date().getTime();
          $('#route').append('<li id="' + newid + '">' + ender + '</li>');
        }
      });

      //Habilita função de ordenação da lista
      $('#route').sortable({axis:'y'});

      //exclui no duplo clique
      $('#route').delegate('li', 'dblclick', function(){
        $(this).remove();
      });

    });

Legal, temos uma lista dinâmicas de endereços e um botão pra atualizar o mapa, que não faz nada ainda. Então…

3. Atualizando o mapa com as rotas

Começamos instanciando o objeto DirectionsService da API, para isso vamos adicionar a seguinte linha nas declarações iniciais do nosso bloco de JS.

var directionsService = new google.maps.DirectionsService();

E por fim no clique do botão “Traçar Rota”


      function getText(id) {
        return $('#'+id).text();
      }

      $('#trace').click(function () {
        var addresses = $('#route').sortable("toArray");
        var len       = addresses.length

        if (len < 2) {
          alert('Se liga... Não existe rota sem pelo menos dois endereços!');
          return false;
        }

        var start = getText(addresses[0]);
        var end   = getText(addresses[len - 1]);
        var waypts = [];
        for (var i = 1; i < len-1; i++) {
            waypts.push({
                location:getText(addresses[i]),
                stopover:true});
        }

        var request = {
            origin: start,
            destination: end,
            waypoints: waypts,
            optimizeWaypoints: false,
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };
        directionsService.route(request, function(response, status) {
          if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
          }
        });
      });

O resultado final, você pode ver aqui.

Acompanhe a evolução do código ou proponha melhorias no meu repositório do Git Hub

11 Responses to “Estudando a API do Google Mapas”

  1. Thiago Says:

    Olá,
    Estou com uma dúvida: pq não consigo inserir mais de 10 lugares para traçar a rota? Existem alguma limitação?

  2. Jam-Pow! Says:

    Oi Thiago

    Sim… tem um limite de 8 pontos intermediários mais o início e o fim, somando 10, mas esta soma pode chegar a 25 se você aderir ao Google Maps Premier, confira na documentação do Google Directions API

    Abs

  3. Eduardo Says:

    alguém sabe como adicionar um listener de evento de clique na rota?

  4. Jam-Pow! Says:

    Oi Eduardo

    O que você quer exatamente? adicionar um listener no clique da linha ou no clique do pino?

  5. Rafael Says:

    Gostaria de fazer essa função no flex, vc pode me ajudar?

  6. Jam-Pow! Says:

    Oi Rafael, usei pouco o flex, mas acho que você pode usar o webview (não sei se é esse o nome do componente) mas ele pode abrir um HTML dentro do flex. Se puder detalhar mais, posso tentar ajudar.

  7. Matheus Says:

    Bom dia , gostaria de saber se existe a possibilidade dessa API calcular a melhor rota, por exemplo, eu defino 3 endereços :

    A: R. Cipriano Barata, 200 – São Paulo
    B: Av. Lacerda Franco, 400 – São Paulo
    C: rua lima barreto – são paulo

    Existe a possibilidade de calcular a melhor rota ? no caso seria A – C – B, é possivel fazer isso via codigo ?

  8. Andre Says:

    Será que existe opção de traçar duas rotas, ou seja, tendo um veículo que sai do ponto A para o B, outro veículo que sai do ponto C para o ponto D?

  9. Andre Says:

    Estudando a API da Google vi que é possível, para tanto criei mais um DirectionsRenderer, colocando uma nova cor na linha de rota traçada conforme abaixo:
    var polylineOptionsActual2 = {
    strokeColor: ‘#F00000′,
    strokeOpacity: 1.0,
    strokeWeight: 6
    };
    Instanciando meu novo render conforme abaixo:
    new google.maps.DirectionsRenderer({polylineOptions: polylineOptionsActual2});

    Ao final fiz um set Map criado anteriormente.
    Depois é só calcular a rota e renderizar com esse novo dirRenderer.

  10. Jam-Pow! Says:

    Matheus,

    Mais ou menos, pelo o que lembro, você pode pedir pra ele otimizar a rota, deixando fixos só o início e o fim, ou seja, se a lista tiver quatro itens ou mais, e vc setar a opção “optimizeWaypoints: true” o google reordenará todos os pontos intermediário, mantendo fixos o início e o fim, pode ser que tenha um modo onde só o início fique fixo, mas desconheço. Dá uma olhada no código do GitHub, o link está no final do post, implementei a otimização opcional.

  11. Fernando Says:

    Show de bola, parabéns pelo post! Rapaz eu estou com um problema e queria ver contigo se pode me ajudar. Eu preciso traçar uma rota onde estoura facil até os 25 waypoints na licença para empresas… só da para fazer com waypoints ? eu vi na documentação da API que da para vc arrastar a rota (como neste ex: https://developers.google.com/maps/documentation/javascript/examples/directions-draggable?hl=pt-br) vc sabe me dizer se da para eu pegar a rota depois de modificada gravar no banco e remontar ela posteriormente sem usar os waypoints?
    Se não for este o caminho, poderia me direcionar pra onde correr?rs
    Se poder me ajudar vai me quebrar uma floresta inteira e não somente um galho…rs
    Vlw!!!!

Leave a Reply

 

preload preload preload