segunda-feira, 28 de fevereiro de 2011

Traçando rotas com a versão 3 da API do Google Maps - Parte II

Traçar rotas usando a API do Google Maps é uma tarefa relativamente simples. Para o processo básico, basta criar instâncias de dois serviços existentes na API - um que calcula as rotas (DirectionsService) e outro que as exibe (DirectionsRenderer). Além, é claro, de fornecermos o endereço de origem e o de destino (ou pares latitude/longitude que correspondam aos locais desejados). Esse processo básico foi assunto de um outro post aqui no blog, onde foi apresentado um passo a passo para esse uso da API.

Rotas onde apenas dois pontos são especificados atendem uma gama grande de situações, mas nem sempre isso é suficiente. É o que ocorre quando há uma logística mais complexa envolvida no traçado da rota, como por exemplo, quando temos um ponto de origem e outro de destino mas queremos também estabelecer locais intermediários que devem constar da rota calculada.

Na realidade, o trabalho feito no post básico sobre rotas nos deixa bem próximos de atender também a necessidade de passar por outros pontos preestabelecidos. O que vai abaixo é parte do código explicado naquele outro post, justamente o trecho que traça a rota entre dois locais dados:
var directionsService, directionsRenderer;
var enderDe, enderAte;

directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);

enderDe = 'ALAMEDA SANTOS, 1000, SÃO PAULO - SP, 01418-9028';
enderAte =
'AVENIDA NAÇÕES UNIDAS, 17-17, BAURU - SP, 17013-035';

var request = {
origin:endDe,
destination:endPara,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};

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

A variável request nesse código é do tipo DirectionsRequest. De acordo com a documentação dessa classe, além das propriedades utilizadas no exemplo básico acima, ela possui uma outra chamada waypoints. A propriedade waypoints é um array de objetos do tipo DirectionsWaypoint, cada um contendo informações sobre um endereço intermediário que deve constar do trajeto final. Cada endereço pode ser informado como um texto - exatamente como fazemos para definir os pontos de origem e destino - ou ainda o par latidude/longitude que representa o local por onde a rota deve passar.

Com isso, podemos montar um novo exemplo para traçar a rota entre dois locais, passando obrigatoriamente por uma lista de outros locais, cujos endereços são fornecidos. É preciso apenas passar uma lista desses endereços usando a propriedade waypoints do objeto request:
var directionsService, directionsRenderer;
var enderDe, enderAte;

directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);

/* Endereço de origem e o de destino. */
enderDe = 'ALAMEDA SANTOS, 1000, SÃO PAULO - SP, 01418-9028';
enderAte =
'AVENIDA NAÇÕES UNIDAS, 17-17, BAURU - SP, 17013-035';

/* Locais intermediários por onde a rota deve passar. */
var local1, local, local3;
local1 = {location:'AV. 11 DE JUNHO, 52, SÃO PAULO - SP'};
local2 = {location:'RUA CEL. MURSA, 10, SÃO PAULO - SP'};
local3 = {location:'RUA CAMPOS SALLES, 214, BOTUCATU - SP'};

var request = {
origin:endDe,
destination:endPara,
travelMode: google.maps.DirectionsTravelMode.DRIVING
waypoints: new Array (local1, local2, local3)
};

Acrescentando esse valor do waypoints ao exemplo básico publicado no outro post, temos o mapa e a rota abaixo:

O HTML com este exemplo completo pode ser acessado neste link.

Veja que os endereços da lista não precisam estar na mesma cidade. Outro aspecto importante a se destacar é que a rota é traçada a partir do local de origem, passando pelos pontos extras na ordem exata em que eles foram incluídos na lista. Isto é, o serviço da API que traça as rotas não faz qualquer inferência a respeito da melhor ordem a seguir para obter a rota mais curta. Portanto, quando essa questão for um problema, é preciso prestar atenção ao construir o array waypoints para evitar que a rota resultante seja irracional.

Por fim, como a propriedade waypoints é do tipo Array, todos os métodos e propriedades dessa classe são aplicáveis, inclusive push, que permite acrescentar novos itens ao array depois que ele foi instanciado:
request.waypoints.push (
{location: 'AV. RODRIGUES ALVES, 14-10, BAURU - SP' }
);

A documentação para a classe Array está disponível neste link.

Mais Informações
Básico sobre rotas com a versão 3 da API do Google Maps, Documentação da classe DirectionsRequest, Documentação da classe DirectionsWaypoint

8 comentários:

  1. Muito bom essa explicação ... estou faz dois dias tentando aprender a fazer mapas e esse exemplo ajudou bastante. Consegui adiantar muita coisa mas ainda não consigo remover os marcadores. É possível remover os marcadores desse seu exemplo acima e só mostrar a rota em azul??Se sim, como?

    Obrigado, joão henrique

    ResponderExcluir
  2. João

    Há uma propriedade do DirectionsRenderer que permite configurar se os marcadores automáticos serão desenhados ou não. O nome dela é suppressMarkers; ajustando-a com valor true, os marcadores serão suprimidos do mapa.

    mapDisplay = new
    google.maps.DirectionsRenderer();
    mapDisplay.suppressMarkers = true;

    Todos os mapas que compartilharem esse renderer serão exibidos sem os marcadores. Lembre-se também que você pode criar marcadores manualmente mas esses continuarão a ser exibidos, não importa o valor de suppressMarkers.

    ResponderExcluir
  3. Muito obrigado amigo. Está funcionando agora como queria.

    joão henrique

    ResponderExcluir
  4. Depois de ter que implementar dessa maneira virando a documentação, fui pesquisar se tinha a sequência do post 2, depois que eu virei a noite acabei encontrando a versão 3 do tutorial, ainda bem que aprendi muito lendo a documentação do maps, pelo menos valeu as hrs acordadas,
    parabens pelo post

    ResponderExcluir
  5. Os dois artigos foram excelentes, me ajudou a concluir meu projeto, porém me surgiu uma outra tarefa que estou meio penando para conseguir fazer, e gostaria de saber se vc já fez algo do gênero.

    Eu tenho 1 endereço de origem e 1000 origens de destinatário, e eu só vou precisar desenhar no mapa somente a primeira OU às 3 rotas mas próximas.

    Já pesquise algumas coisas como calcular rota, usar o getdistance(), mais mesmo assim tá dificil.

    E novamente parabéns pelo post.

    ResponderExcluir
  6. Augusto

    Você pode usar o retorno da função route do directionsService para obter a distância entre a origem e o destino de cada rota e determinar quais são as 3 mais curtas.

    Veja na documentação que o parâmetro response da função que é passada para o route é do tipo DirectionsResult, que dá acesso à propriedade legs, um array de DirectionsLeg contendo informações sobre cada trecho da rota - incluindo sua distância em metros. Basta somar o comprimento de cada trecho pra obter a distância total do trajeto.

    []s

    ResponderExcluir
  7. Vlw, Luiz vou seguir suas instruções, dando certo ou não, eu retorno aqui para dizer.

    flws.

    ResponderExcluir

OBS: Este blog possui moderação de comentários; por isso, os comentários não são publicados imediatamente.