segunda-feira, 12 de dezembro de 2011

Google Maps: Traçando Rotas

[EDITADO EM 03/04/2013: atualizado para Google Api v2]

Olá povo,

A API do Google Maps disponível para Android é muito bacana, e incorporar esse recurso na sua aplicação pode ser um bom atrativo. Em um dos projetos que trabalhei, precisava mostrar a rota entre dois pontos no mapa, e a Google disponibilizou em 27/07/12 uma API Web que retorna a rota entre duas coordenadas geográficas no formato JSON (ou XML se preferir).

Nesse arquivo, temos uma lista com as coordenadas geográficas que devem ser percorridas desde o ponto de partida até o destino. Com essas coordenadas lidas do JSON, criamos uma lista de LatLng que devem ser desenhadas no objeto GoogleMap através de uma PolyLine.

Não vou detalhar muito a configuração do Google Maps v2 no Android pois já falei nesse post aqui. Também não vou entrar em detalhes sobre leitura de JSON pois falei nesse post aqui. E se você tiver dúvidas sobre AsyncTask, dê uma olhada nesse post.

Vou começar pelo código da Activity mostrado abaixo. No onCreate pegamos a instância de GoogleMap e definimos a posição inicial no mapa e um zoom padrão. Em seguida iniciamos a AsyncTask passando a GoogleMap no construtor e informando a latitude e longitude de origem e destino.
public class TesteRotaMapaActivity 
  extends FragmentActivity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  
    SupportMapFragment fragment = 
      (SupportMapFragment)
        getSupportFragmentManager()
          .findFragmentById(R.id.map);

    GoogleMap map = fragment.getMap();

    LatLng latLng = new LatLng(-8.102739,-34.89917);
  
    map.animateCamera(
      CameraUpdateFactory.newLatLngZoom(latLng, 12.0f));
  
    new RotaAsyncTask(this, map).execute(
      // Latitude, Logintude de Origem
      latLng.latitude, latLng.longitude,    
      // Latitude, Longitude de Destino
      -23.604262,-46.676513);  
    }
}

A classe RotaAsyncTask é quem faz o trabalho de acessar o site do Google Maps, baixar o JSON com a informação da rota.
public class RotaAsyncTask extends 
  AsyncTask<Double, Void, Void>{

  private ProgressDialog dialog;
  private GoogleMap mapView;
  private Context context;
  private Route rota;

  public RotaAsyncTask(Context ctx, GoogleMap mapa) {
    mapView = mapa;
    context = ctx;
  }
 
  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    dialog = ProgressDialog.show(
      mapView.getContext(), "Aguarde", 
      "Calculando rota");
  }
 
  @Override
  protected Void doInBackground(Double... params) {

    rota = directions(
      new LatLng(params[0], params[1]), 
      new LatLng(params[2], params[3]));
    return null;
  }
 
  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    PolylineOptions options = new PolylineOptions()
      .width(5)
      .color(Color.RED)
      .visible(true);

    for (LatLng latlng : rota.getPoints()) {
      options.add(latlng);
    }

    mapView.addPolyline(options);
    dialog.dismiss();
  }
 
  private Route directions(
    final LatLng start, final LatLng dest) {
  
    // Formatando a URL com a latitude e longitude  
    // de origem e destino.  
    String urlRota = String.format(Locale.US,
      "http://maps.googleapis.com/maps/api/"+
      "directions/json?origin=%f,%f&"+
      "destination=%f,%f&" +
      "sensor=true&mode=driving",   
      start.latitude, 
      start.longitude, 
      dest.latitude, 
      dest.longitude); 
  
    GoogleParser parser;
    parser = new GoogleParser(urlRota);
    return parser.parse();
  }
}

Quem viu o post anterior pode notar que houveram algumas modificações. Delegamos o parse do JSON para a classe GoogleParser e exibimos as rotas utilizando a classe PoluLineOptions (da API v2) com ajuda da classe Route. Essas novas classes foram extraídas desse post aqui. Graças ao comentário do Hadson Gomes.
Eu peguei essas classes e deixei apenas o necessário. Vejamos elas abaixo.
public class Route {
  private final List<LatLng> points;
  private String polyline;

  public Route() {
    points = new ArrayList<LatLng>();
  }

  public void addPoints(final List<LatLng> points) {
    this.points.addAll(points);
  }

  public List<LatLng> getPoints() {
    return points;
  }

  public void setPolyline(String polyline) {
    this.polyline = polyline;
  }

  public String getPolyline() {
    return polyline;
  }
}
Note que a classe acima tem uma propriedade chamada polyline. Nesse JSON, a rota retorna algumas coordenadas "macro" digamos assim. Por isso os comentários abaixo informando que eram traçadas linhas retas no caminho. A rota com as coordenadas mas precisas estão codificadas em base64 no atributo polyline. A classe GoogleParser faz essa conversão de base64 para GeoPoint conforme abaixo.
public class GoogleParser {

  protected URL feedUrl;

  public GoogleParser(String feedUrl) {
    try {
      this.feedUrl = new URL(feedUrl);
    } catch (MalformedURLException e) {
    }
  }
 
  public Route parse() {
    // Cria uma rota vazia
    final Route route = new Route();
    try {
      // Obtém a String do JSON
      final String result = 
        convertStreamToString(
          feedUrl.openConnection()
            .getInputStream());

      // Transforma a string em JSON
      JSONObject json = new JSONObject(result);
      // Pega a primeira rota retornada
      JSONObject jsonRoute = 
        json.getJSONArray("routes")
          .getJSONObject(0);
      JSONObject leg = jsonRoute
        .getJSONArray("legs").getJSONObject(0);

      // Obtém os passos do caminho
      JSONArray steps = leg.getJSONArray("steps");

      final int numSteps = steps.length();
      /*
       * Itera através dos passos, decodificando 
       * a polyline e adicionando à rota.
       */
      JSONObject step;
      for (int i = 0; i < numSteps; i++) {
        // Obtém o passo corrente
        step = steps.getJSONObject(i);
        // Decodifica a polyline e adiciona à rota
        route.addPoints(
          decodePolyLine(
            step.getJSONObject("polyline")
              .getString("points")));
      }
    } catch (Exception e) {
    }
    return route;
  }

  private String convertStreamToString(
    final InputStream input) {

    final BufferedReader reader = 
      new BufferedReader(
        new InputStreamReader(input));
    final StringBuilder sBuf = new StringBuilder();

    String line = null;
    try {
      while ((line = reader.readLine()) != null) {
        sBuf.append(line);
      }
    } catch (IOException e) {
    } finally {
      try {
        input.close();
      } catch (IOException e) {
      }
    }
    return sBuf.toString();
  }

  private List<LatLng> decodePolyLine(final String poly) {
    int len = poly.length();
    int index = 0;
    List<LatLng> decoded = 
      new ArrayList<LatLng>();

    int lat = 0;
    int lng = 0;

    while (index < len) {
      int b;
      int shift = 0;
      int result = 0;
      do {
        b = poly.charAt(index++) - 63;
        result |= (b & 0x1f) << shift;
        shift += 5;
      } while (b >= 0x20);
      int dlat = 
        ((result & 1) != 0 ? 
          ~(result >> 1) : 
          (result >> 1));
      lat += dlat;

      shift = 0;
      result = 0;
      do {
        b = poly.charAt(index++) - 63;
        result |= (b & 0x1f) << shift;
        shift += 5;
      } while (b >= 0x20);

      int dlng = ((result & 1) != 0 ? 
        ~(result >> 1) : 
        (result >> 1));
      lng += dlng;

      decoded.add(
        new LatLng(
          (float)(lat / 1E5),
          (float)(lng / 1E5)));
    }
    return decoded;
  }
}
Quem viu o post anterior deve lembrar que a classe RouteOverlay não existe mais. Quem faz seu papel é a classe PolyLine da nova versão da Google Maps Api.
A imagem abaixo mostra nossa aplicação em execução.



Qualquer dúvida, deixem seus comentários.

4br4ç05,
nglauber

127 comentários:

Android disse...

Ola, gostava de saber se este código esta mesmo funcionando. Se o resultado final é o da figura.. cumprimentos

Nelson Glauber disse...

Caramba que orgulho estar "falando" com o próprio Android :)

Está funcionando sim, e como está descrito no postl, a imagem mostra a aplicação em execução.

4br4ç05,
nglauber

Android disse...

Ola, desculpa chamo-me duarte.
Contudo eu testei esse mesmo código e não esta funcionando. É possível enviar o cofigo fonte, ou é pedir mt..
cumprimentos

Nelson Glauber disse...

Oi Duarte,

Desculpa eu. Como o blog tem uma abordagem descontraída, brinquei com o nome que aparece no seu perfil.
Mas bem, o código de exemplo está disponível nesse link: https://sites.google.com/site/nglaubervasc/TesteRotaMapa.zip

Enjoy!

4br4ç05,
nglauber

Fernando Anselmo disse...

Nelson,

Nessa parte aqui do código: String urlRota = String.format(Locale.US,...
da classe RotaAsyncTask.java saiu errado está aparecendo os "&" que não tem no código.

[]´s
Fernando Anselmo

Nelson Glauber disse...

Oi Fernando Anselmo,

Obrigado pelo aviso. Acabei de corrigir.

4br4ç05,
nglauber

Thiago P. disse...

Glauber, parabéns pelo post! Ainda vou testar as dicas mas já vi que tá bem explicado. Me tira só uma dúvida: com essa rota traçada, é possível eu calcular/traçar uma segunda rota entre um #ponto_1 e um #ponto_2, de modo que esse #ponto_2 intersecte a primeira rota traçada? Espero que tenha entendido. xD Qual a melhor forma de fazer isso que estou querendo? Obrigado.

Nelson Glauber disse...

Oi Thiago,

Não sei se entendi sua dúvida. Mas vamos lá.
Nesse exemplo, se você colocar duas coordenadas muito distantes uma da outra, o arquivo XML só retornará parte do caminho.
O que deve ser feito é pegar a última longitude/latitude retornada e traçar a rota desse ponto até o final.
Esse processo deve ser repetido até que se chegue ao ponto desejado.

4br4ç05,
nglauber

Thiago P. disse...

Vou tentar simplificar: dado uma rota qualquer (ex: Recife-Caruaru) tem como eu pegar um ponto qualquer do mapa e saber se esse ponto intersecta a rota Recife-Caruaru?

Nelson Glauber disse...

Oi Thiago,

Nesse caso, você pode usar a classe android.location.Geocoder que tem um método getFromLocationName que você passa o nome do local e ele retorna uma List<Address>. Nesse objeto Address você pode pegar a latitude e longitude e passar para o método acima.
A classe (Geocoder) normalmente dá problema no emulador (Out of service), mas no aparelho funciona blz.

4br4ç05,
nglauber

Thiago P. disse...

Valeu Glauber, talvez isso me ajude. Vou tentar depois. abraço

Gleydson disse...

Valeu cara o exemplo me ajudou bastante. Dei uma olhada na API e fiquei com duvida sobre como configurar a rota para ela ser gerada especificando os modos de transporte. A pé, carro, ônibus. Valeu!

Pierry disse...

Muito obrigado mesmo! EXCELENTE POST!
Parabens!

marcio7 disse...

Boas, sou português, e estou a testar seu programa, mas não consigo, registar rotas aqui para portugal, queria perguntar porquê?

Nelson Glauber disse...

Oi Marcio,

Era pra funcionar, afinal estou usando longitude e latitude (que é universal)... Qual o problema que está acontecendo?

4br4ç05,
nglauber

marcio7 disse...

olá,

obrigado desde já pela atenção, é o seguinte, queria as rotas daqui em portugal, foi ao google tirar coordenas de dois pontos e depois queria a rota entre estes dois pontos e fiz o seguinte:

new AsyncTask_rotas(mapView).execute(
// Latitude, Logintude de Origem (estação de S. Bento)
-8.608904, 41.145070,
//Latitude, Longitude de Destino (Universidade de Aveiro)
-8.657444, 40.634866);

alterei as coordenadas que tinha por estas, pelo que percebi do seu programa, teria de me aparecer a rota entre estes dois pontos daqui de portugal, mas o que aparece é o mapa dos estados unidos perto do kansas, mas o seu programa funciona, mas com esta alteração que fiz não deu...por isso é que lhe perguntei, só alterei mesmo as coordenadas

cumprimentos

Nelson Glauber disse...

Oi marcio,

Acho que você estava colocando os valores invertidos. Testei com esses e funcionou:
// Latitude, Logintude de Origem
40.630142,-8.655639,
// Latitude, Longitude de Destino
41.145586,-8.609934);

4br4ç05,
nglauber

marcio7 disse...

era mesmo isso obrigado


cumprimentos

marcio7 disse...

olá,

não sei se me pode ajudar, num problema que estou aqui, queria fazer uma bússola que aponta para um geopoint no map, em vez de aponta para o norte magnético, mas não tenho ideia como fazer isso, pensei em adaptar a bussola que aponta para o norte magnético, mas parece me que não será fácil de ser feito, pode até nem ser uma bússola se for uma seta apontar para o geopoint já seria bom e depois atualizava consoante a minha posição

Nelson Glauber disse...

Olá marcio7,

Vê só... o que você pode tentar é o seguinte: você tem 2 coordenadas C1 e C2. Onde C1 é a posição onde o mapa está exibido e C2 a posição para onde você quer que a bússola aponte.

Dadas essas coordenadas, você pode obter um objeto Projection (mapView.getProjection()) e obter as posições X e Y de C1 e C2 com o método toPixels(GeoPoint).

Depois, você usa as posições x1, y1, x2 e y2 para calcular o ângulo:
a = arctn ((x2-x1) / (y2-y1))

Com isso é só mandar rotacionar a imagem com o ângulo calculado.
Se tiver sucesso posta aqui.

Referência:
http://code.google.com/intl/pt-BR/android/add-ons/google-apis/reference/com/google/android/maps/Projection.html

4br4ç05,
nglauber

marcio7 disse...

ok, obrigado irei testar...sim se conseguir postarei aqui...mais uma vez obrigado, estou a iniciar android, ainda sou novato


cumprimentos

Herivelton Andreassa disse...

Nelson, estou procurando por uma solução para o problema: Como mudar uma rota definida? (Ex.: A rota traçada, aí clico num determinado ponto e arrasto até onde pretendo que a rota passe). Isso é possível?

Obrigado desde já, e parabéns pelo seu blog.

Nelson Glauber disse...

Oi Herivelton,

Se eu entendi bem, você tem os ponto A e B. E quando clicar em um local no mapa, mostre o trajeto A->X->B.
O que você pode fazer é chamar o método acima passando A e X; e depois X e B.
Note que no método usamos GeoPoint e você irá clicar no mapa e obter um Point (x e y da tela). Para converter X e Y em latitude/longitude use a classe Projection do MapView (vide comentário anterior para marcio7).

4br4ç05,
nglauber

Cassiano disse...

ótimo post.. se todos fossem assim estaríamos muito melhor...
só uma questão que não consegui resolver: apagar a rota... é que eu crio uma rota, mas existem vários pontos na minha aplicação, e gostaria de apagar a rota para poder criar outra... nesse exemplo eu crio uma em cima da outra... tem como fazer isso??? desde já agradeço e parabenizo...

Nelson Glauber disse...

Oi Cassiano,

A rota é traçada em um overlay (um camada) por sobre o mapa. Para remover, basta chamar mapView.getOverlays().clear().

4br4ç05,
nglauber

marcio7 disse...

boa tarde, estou quase a conseguir fazer a bússola só estou com problemas em converter geopoint em location, está em baixo o location é uma classe que está declarada com private nomeclass location;, a localização desta class é do tipo geopoint, mas preciso de converter para Location, tenho o método getLocation(), na classe que designei nomeclass e para fazer essa conversão, fiz o seguinte código embaixo, espero que me possa ajudar já tentei de várias maneiras, mas nada como sou novato nisto tenho algumas dificuldades, como combinado depois colocarei aqui a bussola feita apontar para um ponto de interesse, só não lhe enviei pk não a consegui colocar a funcionar

cumprimentos
marcio7


double latitude = location.getLocation().getLatitudeE6() / 1E6;
double longitude = location.getLocation().getLongitudeE6() / 1E6;

Location local = null;
local.setLatitude(latitude);
local.setLongitude(longitude);

Nelson Glauber disse...

Olá marcio7,

Para fazer a conversão de GeoPoint para Pixels, você pode usar a o método toPixels da classe Projection

Projection proj = mapView.getProjection();

Point ponto = proj.toPixels(geoPoint, null);

4br4ç05,
nglauber

marcio7 disse...

olá, boa tarde, obrigado pela resposta,

no meu caso não poderá ser conversão de geopoint em point mas sim conversão de GeoPoint em Location, porque preciso de usar um método em que o argumento que passo tem do tipo Location e não do tipo GeoPoint

float bearing = currentLocation.bearingTo(local);

o currentLocation é minha localizaão do tipo Location

conversão que tento fazer mas dá null

double latitude = location.getLocation().getLatitudeE6() / 1E6;
double longitude = location.getLocation().getLongitudeE6() / 1E6;

Location local = null;
local.setLatitude(latitude);
local.setLongitude(longitude);

location é do tipo Geopoint e preciso de passar a tipo Location, e uso a conversão acima, só que dá sempre null o getLocation()é um método que está noutra classe que devolve GeoPoint location

há algo aqui que me está a escapar, mas n sei o que é, já tentei de várias maneiras e nada

muito obrigado pela disponibilidade

cumprimentos
Márcio Fernandes

marcio7 disse...

olá, bom dia, já resolvi o problema, obrigado pela disponibilidade, agora estou a ver um pequeno pormenor, depois disponibilizarei o código que fiz para a bussola

em relação ás rotas no mapa, agora estava a pensar colocar o ponto de origem a minha localização atual e na destino o ponto que estou interessado, é possível fazer isso, sem ser com os valores de teste?


cumprimentos
marcio7

Nelson Glauber disse...

Oi marcio7,

Acho que isso aqui vai te ajudar:
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html

4br4ç05,
nglauber

marcio7 disse...

olá,boa tarde

obrigado, ajudou até apliquei na bússola, ainda n consegui desenhar a seta, porque á uma lado que me aparece a null a localização, mas deve ser algo pequeno, parece me que estou perto...

cumprimentos
marcio7

Bruno disse...

Opa, tudo bem Nelson?

Primeiramente parabéns pelo post, ta bem explicado. Estou tentando testa-lo e estou pegando o seguinte erro:
"
Description Resource Path Location Type
The method getTextContent() is undefined for the type Node RotaAsyncTask.java /TesteRotaMapaActivity/src/ngvl/android/rota line 83 Java Problem "

O erro esta na seguinte linha de código:

String coordenadasStr = coordenadasXML.getTextContent();

Procurei na internet como resolver esse erro mas não tive muito sucesso. Sabo o que pode estar acontecendo?


Agradesço desde ja pela atenção.

Bruno Henrique de Souza

Nelson Glauber disse...

Oi Bruno,

O problema é que usei a API 2.3 do Android. Nas versões anteriores, você deve usar getFirstChild().getNodeValue() ao invés do getTextContent().

4br4ç05,
nglauber

PS.: Esse problema já tinha sido descrito aqui :)
http://nglauber.blogspot.com.br/2011/11/lendo-rss-no-android.html

marcio7 disse...

olá boa tarde, coloquei a bússola em funcionamento, com valores de teste, como quer que lhe envie o código?

como estava combinado, desde já agradeço a sua disponibilidade para me ajudar

cumprimentos
marcio7

Nelson Glauber disse...

Oi marcio7,

Que bom que concluiu o projeto. Se quiser, pode mandar pro meu email.

4br4ç05,
nglauber

Anônimo disse...

Muito bom!
Ótima iniciativa, funciona muito bem, fácil entendimento.
Obrigado por compartilhar.

Eric Augusto disse...

Muito bom

Unknown disse...

E ae, beleza?
Cara, muito obrigado pelo tutorial.
Estou com uma duvida, criei um projeto que traça a rota entre eu o um ponto que clicar no mapa... o problema aparece que eu não consigo apagar do mapa a rota se ele clicar em outro ponto, entendeu?
Então o mapa vai ficando cheio de rotas traçadas..
Alguém pode me ajudar?

Nelson Glauber disse...

Oi Ricardo,

Pra fazer isso, é só remover o overlay anterior ao clicar no mapa.
mapView.getOverlays().clear()

4br4ç05,
nglauber

Unknown disse...

Entao cara, esqueci de dizer q quando faço isso a minha localização e os outros overlays do mapa somem... eu usei a api do google place para aparecer os outros lugares (overlays).... desde ja agradeço sua ajuda... mas como posso resolver esse problema? Pode por favor me ajudar a eliminar a rota quando clico em outro overlay?

Nelson Glauber disse...

Oi Ricardo,

Bem, o que você pode fazer é armazenar em uma variável temporária (do tipo GeoPoint) o seu local atual. Aí quando você clicar em um outro do mapa você traça a rota do seu local atual (que está na variável temporária) até o local onde você clicou.

4br4ç05,
nglauber

Anônimo disse...

opa nao sei c reparou pq em rotas grandes por ex. de porto alegre a sp
ele traça apenas um pedaço..nao chega a completar ela tipow ele traça 20%

Nelson Glauber disse...

Oi José Carlos,

Percebi sim. Inclusive pensava que tinha colocado no post. Isso é uma limitação da API do Google Maps. O que você deve fazer é tentar pegar a última coordenada do arquivo XML e fazer a busca do XML novamente a partir desse local até o local de destino, e repetir isso até que a localização seja encontrada.

4br4ç05,
nglauber

Williams disse...

Grande Nelson, muito obrigado pelo post!
Mas estou com um probleminha, estou desenvolvendo um aplicativo para o android 2.1, já alterei o código trocando
String coordenadasStr coordenadasXML.getTextContent();
por String coordenadasStr = coordenadasXML.getFirstChild().getNodeValue();
Feito isso, o código para de acusar erro mas após compilar ocorre um erro quando está calculando rota.
Por favor, estou precisando muito rodar no 2.1.

Nelson Glauber disse...

Oi Willams,

Tenta colocar um log ou coloca um breakpoint e faz o debug pra ver o que essa tag está retornando. Teoricamente ela deve retornar o mesmo conteúdo do getTextContent.

4br4ç05,
nglauber

Glauber Lobo disse...

Nelson,
boa tarde.

Primeiro gostaria de parabenizar pelo excelente artigo.

Estou criando uma app que coleta localizações e em seguida deveria mostrar o percurso entre o primeiro e o último ponto. Tentei usar sua solução aqui, mas sem sucesso. O retorno da url é um html cheio de javascript e não localiza a tag LineString dando erro no parse.

Tens alguma idéia se o código ainda está ok, ou o Google mudou o retorno ?

Grato

Williams disse...

Ola glauber,
Então, estou debugando e a variável coordenadasStr recebe um valor nulo, ou seja, o getfirstchild() esta retornando nulo.

Nelson Glauber disse...

Oi Glauber,

A URL do serviço mudou e o XML também, consequentemente o parser terá que mudar. A nova URL é essa:
http://maps.googleapis.com/maps/api/directions/xml?origin=40.630142,-8.655639&destination=41.145586,-8.609934&sensor=true

Mais informações aqui:
https://developers.google.com/maps/documentation/directions/

Em breve devo estar atualizando o post.

4br4ç05,
nglauber

Nelson Glauber disse...

Oi Willams e Glauber,

Acabei de atualizar o POST. Apenas a classe RotaAsyncTask foi impactada. Testem e me dêem um feedback :)

4br4ç05,
nglauber

Julio Neves disse...

Oi Glauber, eu nem sou o Willams nem o Glauber, mas vou te responder rsrsrs
eu também estava usando seu código que funcionava muito bem, mas desde o ultimo sábado 28/07 percebi que a rota não estava mais sendo traçada no mapa, dava uma exceção no parse do xml.
Agora sim, voltou a funcionar, só que no teste inicial que fiz a rota ficou muito "fora" da estrada, como se o intervalo de pontos estivesse muito alto gerando uma rota em "linha reta".
Depois vou tentar entender o porque e vê se dá pra melhorar, se consegui alguma coisa eu aviso

Nelson Glauber disse...

Oi Julio,

Valeu pelas informações. A URL e a estrutura do XML mudaram. Aí fiz um ajuste bem rápido e para o que eu tinha testado, funcionou. Mas se você tiver uma solução melhor, pode mandar que eu ajusto aqui no post.

4br4ç05,
nglauber

Jailson Jan disse...

Oi Nelson,
Muito bom este seu post.
Eu procurava por uma explicação detalhada como esta a algum tempo.
Valeu!

Glauber Lobo disse...

Meu caro,
obrigado pelo retorno.

Fiz os ajustes por aqui e está ok.

O único senão é que alguns pontos coletados pelo GPS ficaram um pouco fora da via e ao traçar a rota o serviço dá uma volta no quarteirão ao lado da via por exemplo, ficando um pouco estranho, mas vou tentar ajustar aqui.

Obrigado e parabéns por compartilhar o conhecimento.

Abraços,
Glauber

Marcos Vinicius disse...

Glauber,
Fui seu aluno na Especializa e estou com algumas dúvidas urgentes e se puder me ajudar agradeço!

Tenho um projeto que é para traçar rota no Mapa!

Tenho um mapa já com pontos de Destinos(Lojas) e quero traçar a rota do meu local atual para a loja que é um overlay no mapa.
Minha dúvida é......

Não consigo pegar as coordenadas da minha posição atual e nem traçar a rota!

Grato,

Nelson Glauber disse...

Oi Marcos,

Esse post aqui pode te ajudar, ele mostra como pegar a posição do GPS.
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html

Para pegar a última posição conhecida do GPS, você pode usar esse método aqui.
http://developer.android.com/reference/android/location/LocationManager.html#getProvider(java.lang.String)

4br4ç05,
nglauber

Jayme disse...

Olá Nelson, estive testando seu código porém tive um pequeno problema, ele gera a rota, porém entre os pontos que ele busca no google, ele traça caminhos retos e não seguindo o mapa, ficando fora da estrada.
Tem idéia do que possa ser?

Abraços

Nelson Glauber disse...

Oi Jayme,

Eu não testei intesivamente esse código. Como comentei, a API do Google mudou recentemente, então tive que fazer um ajuste no post.
Mas para você debugar, é só pegar a URL das linhas 25/28 e abrir no browser. O endereço retorna um XML, então você deve fazer o parser dele.

4br4ç05,
nglauber

Jayme disse...

Obrigado pela atenção Nelson,

estou revirando o código até agora e ainda não tive sucesso.

Verifiquei como indicou, porém o XML vem correto e o parser também faz a leitura da forma correta.

Creio que o problema aqui seja referente a maneira como é traçado o caminho, pois temos 2 pontos originais que depois se transformam em vários pontos, porém quando o android tenta traçar uma linha entre 2 pontos, sera uma reta, não fazendo a logica ao mapa.

Tenho uma dúvida agora, que ainda não entendi, como era feito antes essa linha? Você apenas indicava os 2 pontos e ele traçava uma linha que se adaptava às ruas do mapa?

Grato novamente e desculpas por estar tomando seu tempo.

Unknown disse...

36Olá, meu nome é Fillipe e estou enfrentando o mesmo problema com o desenho da rota. Por algum motivo não está ficando nas ruas, vcs já conseguiram resolver esse problema?

Parabéns seu post está ótimo

Jayme disse...

Olá Nelson, apenas estou passando aqui para mostrar a solução que acabei de encontrar para o meu problema. No caso ali, acho que o problema esta referente a decodificação dos pontos para exibir no mapa, com o código que é mostrado aqui:
http://stackoverflow.com/questions/11323500/google-maps-api-version-difference/11357351#11357351
É possível conseguir o mesmo resultado.

Depois verei como fazer para continuar utilizando o XML.

Obrigado

Anônimo disse...

Bom dia , gostaria se o código acima resolveu o problema de seguir as ruas corretamente ?

Matheus Augusto disse...

Boa tarde , estou tentando fazer uma rota baseado no seu código , mais aconteceu o mesmo erro das pessoas acima, a rota que ele traca fica fora das ruas , eu vi que o Jayme postou um link , tentei fazer como ensina esse link mais não consegui , sera que alguem pode me dar uma ajudinha ?

Hadson Marcelo Gomes disse...

Boa noite pessoal, achei esse blog na net ha alguns dias, implementei esse codigo e tb obtive o mesmo erro que o pessoal tem relatado, entao a partir desse codigo comecei a efetuar outras soluçoes e encontrei :).

Agora estou a melhorá-lo. Agradecido desde já
Segue Link

http://stackoverflow.com/questions/11745314/why-retrieving-google-directions-for-android-using-kml-data-is-not-working-anymo/11745316#11745316

Nelson Glauber disse...

Oi Hadson,

Valeu pela contribuição. A solução que você indicou funciona bem. Quando a distância é longa, ainda fica lento, mas a gente vai aprimorando.

4br4ç05,
nglauber

Anderson Gomes disse...

Mt bom meu velho!!!
E valeu pela referência do meu post sobre o AsyncTask =)
Pra refrescar a memória sou eu wolverine ;)

joaohsenger disse...

Ola, primeiramente parabéns pelo post.
estou com uma dúvida, como faço para traçar uma rota a partir do meu ponto de oriigem, tenho que capturar a minha longitude e latidude atual, e traçar a rota até uma String, sendo que tenho que converter a String para latidude e longitude tbm, se possivel gostaria que me desse opções de rota, por ser uma String o desdino.

Nelson Glauber disse...

oi joaohsenger,

Dá uma olhada nesse post:
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html

4br4ç05,
nglauber

Anônimo disse...

Otimo post cara , eu tinha olhado o post antigo e rota ficou fora das ruas devido a mudança da API , dai tambem segui esse post e consegui , minha duvida agora é como traçar a rota mais rapida ? eu consigo por muitos pontos e fazer muitas rota , mais como definir a mais rapida ?

Diego disse...

Olá! Muito bom seu post! Estou tentando executar o seu código fonte diretamente do meu celular (Xperia NEO V), ele traça a rota porém o mapa não é exibido. Por favor, pode me dizer o que pode ser? Estou com o 3G ligado e no meu manifest eu inclui a lib com.google.android.maps. Obrigado!

Nelson Glauber disse...

Oi Anônimo,

O problema provavelmente é a permissão de INTERNET ou a chave do Google Maps que está errada. Note que essa chave é por arquivo debug.keystore.
Testa isso aqui: http://nglauber.blogspot.com.br/2009/09/google-maps-com-android-15.html

4br4ç05,
nglauber

Unknown disse...

Olá Nelson!

Ainda estou com problemas na exibição do mapa.

Rodei sua aplicação no emulador e no celular e em ambos o mapa não aparece =/

Eu coloquei a versão do aplicativo pra google api pois na versão que estava dava erro.

Será que está faltando alguma coisa? Vc importou o jar do maps?

Obrigado!

Unknown disse...

Olá Glauber! Resolvi o problema do mapa. Por algum motivo a key que gerei anteriormente ficou inválida e o google não estava aceitando. Gerei uma nova e deu certo! []'s e parabéns pelo blog! Me ajudou muito!

Anônimo disse...

Pessoal, alguém saberia me dizer, ou me passar algum link, onde tenha algum exemplo de como desenhar uma polyline de um ponto ao outro na API do Google Maps para Android? ja pesquisei mas eu só acho isso em javascript, para aquelas aplicações que rodam nos navegadores, não estou conseguindo encontrar algum exemplo pronto para a API do Android em que eu possa me basear. Eu consegui rodar o exemplo do site, mas no momento eu não preciso calcular a Rota, só fazer o desenho como se fosse um "Grafo" de determinado bairro. Muito Obrigado!

Unknown disse...

Parabens pela aplicaçao, gostaria de saber se vc tem ela para download ?

Anônimo disse...

Pessoal, eu consegui fazer o desenho das rotas funcionar, mas meu mapa esta estranho, ele não carrega corretamente, fica aparecendo alguns quadrados com um x no meio, partes carregam normal, e outras ficam com esse quadrado. O que poderia ser?

Nelson Glauber disse...

Olá Anônimo,

Isso acontece normalmente quando vc dá um zoom muito grande em uma determinada área. Nem todos os locais suportam o zoom máximo.

4br4ç05,
nglauber

Anônimo disse...

Muito Obrigado Nelson, eu consegui arrumar de uma maneira diferente o problemas do x que estava aparecendo em alguns lugares em vez do mapa, eu passei minha aplicação para a versão do google maps API 2.3.3 e o problema sumiu, meio, estranho isso, mas ja esta funcionando normalmente. Valeu!

Henrique disse...

Olá, pelo código, a marcação de rota respeita o sentido das ruas, pois está como rota pra carro, e se quiser habilitar uma rota pra pedestre? como faço??

Nelson Glauber disse...

Olá Henrique,

Você pode acessar a documentação completa aqui:
https://developers.google.com/maps/documentation/directions/?hl=pt-br

Para pegar a rota a pé, você pode passar o parâmetro mode=walking na URL.

4br4ç05,
nglauber

Henrique disse...

Olá de novo, li a documentação, tao simples né, rsrsrsrs, ótimo blog, continue assim ajudando iniciantes, rsrsrs, outra duvida, que venho batendo cabeca a mt tempo: tenho 1 ponto marcado no mapa, e gostaria de clicar nele e abrir um dialog, algo em que descreva aquele mapa, usando um xml! vc saberia? abraços!

Nelson Glauber disse...

OI Henrique,

Esse tutorial acho que faz o q você quer:

https://developers.google.com/maps/documentation/android/hello-mapview

O método onTap do OverlayItem faz isso.

4br4ç05,
nglauber

Henrique disse...

Bom dia novamente, no meu mapa tem a minha localização(GPS) e varios pontos marcados no mapa, quando eu clico nesses pontos marcados no mapa, o metodo onTap() é executado, abrindo um Dialog na tela com um botao Marcar Rota até o ponto escolhido, mas está dando um erro, e já estou ficando maluco, kkkkkkk, me ajudem!

Unknown disse...

Aló Glauber, muitoooo obrigado por esse post. Mim ajudou muito =D.
O exemplo pra download está diferente do código do post. Muito obrigado.

Nelson Glauber disse...

Oi Diogo,

Não tem de que. Estamos aqui pra ajudar. Ah! Acabei de atualizar o post.

4br4ç05,
nglauber

Unknown disse...

Olá, em relação as rotas, gostaria de saber se é possível criar a própria rota, e não o caminho que o Google mostra, tipo.. eu gravar o caminho que é pra aparecer do inicio ao destino.. como por exemplo dentro de uma cidade, ponto inicial minha casa e ponto final uma loja.

Nelson Glauber disse...

Oi Fausto,

Não sei se entendi a pergunta, mas você pode fazer a pesquisa pelos locais de origem e destino usando a classe GeoCoder.

http://developer.android.com/reference/android/location/Geocoder.html

Ela permite você fazer uma busca pelo nome do local e te retorna a latitude e a longitude.
Daí é só usar o código desse post.

4br4ç05,
nglauber

Michaeloc disse...

Olá..Pessoal. Estava estudando o código disponibilizado e estou encontrando um problema pois não consigo fazer um conversão de LatLng para GeoPoint.

Nelson Glauber disse...

Olá Fundamentos de Programação,

Basta multiplicar a latitude e longitude do objeto LatLng por 1E6 e passar para o construtor da classe GeoPoint.

4br4ç05,
nglauber

Lucas disse...

Olá. Estou com um problema, no trecho a seguir estou recebendo a mensagem de Type mismatch: cannot convert from element type GeoPoint to LatLng

for (LatLng latlng : rota.getPoints()) {
options.add(latlng);
}

Alguma sugestão do que posso fazer?

Nelson Glauber disse...

Oi Lucas,

Agora que vi que a classe Route estava retornando uma List ao invés de uma List.
Post corrigido.

4br4ç05,
nglauber

Anônimo disse...

Ola Gostaria de saber como faço pra transformar as coordenadas em nome de rua e vice versa?

Nelson Glauber disse...

Oi Renan,

O pessoal já perguntou isso nos comentários acima. Dá uma procurada em GeoCoder. Essa classe realiza essa tarefa.

4br4ç05,
nglauber

Anônimo disse...

Gostaria de saber como é o funcionamento da classe SupportMapFragment ?

Nelson Glauber disse...

Oi Anônimo,

O SupportMapFragment serve para podermos utilizar o Fragment de Mapas em versões anteriores a 3.0 (API Level 11). Mais informações você pode obter na documentação da classe.

http://developer.android.com/reference/com/google/android/gms/maps/SupportMapFragment.html

4br4ç05,
nglauber

Anônimo disse...

Opa, estou com problema no Geopoint da class RotaAsync, ele recebe um objeto do tipo LatLng e não reconhece como faço pra converter esse objeto pra Geopoint ou se tem como criar direto como LatLng?

Nelson Glauber disse...

Oi Anônimo,

Acabei de corrigir o post. Dá uma olhada.

4br4ç05,
nglauber

JR disse...

Oi nelson.....se no lugar dessa Latitude de origem eu quizer colocar a localização do meu gps(celular), como eu faço para pegar essa localização e traçar a rota...


abç!!

Nelson Glauber disse...

Oi Zeca,

Você pode usar o método getLastKnownLocation da classe LocationManager: http://developer.android.com/reference/android/location/LocationManager.html#getLastKnownLocation(java.lang.String)

Qualquer dúvida, dá uma olhada aqui:
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html

4br4ç05,
nglauber

Anônimo disse...

Boa Tarde Glauber




Gostaria de saber se esse projeto https://sites.google.com/site/nglaubervasc/TesteRotaMapa.zip - funciona com api v2,
Pois estou enfrentando problemas com a rota.. implementei tudo certo,aparece o mapa e a rota, mais a aplicação fecha inesperadamente, não permanece on, diferente desde projeto TesteRotaMapa.zip que fica "ligado' e podemos navegar no mapa a vontade, gostaria de uma ajuda sua, pois necessito no meu projeto que seja traçada a rota e a aplicação permaneça on, pleace...pleace..

Nelson Glauber disse...

Oi Anônimo,

Qual erro está acontecendo? Dá uma olhada no logcat.

4br4ç05,
nglauber

Antônio disse...

Boa Tarde Glauber sou o antônio, que anteriormente postei um comentário como anônimo, errei na hora de colocar meu nome....


A aplicação aparentemente não tem erro de compilação, mais ele fecha inesperadamente, a mensagem que da no logcat é a seguinte...

10-04 16:28:23.250: E/Trace(1031): error opening trace file: No such file or directory (2)
10-04 16:28:25.980: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:25.999: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:26.009: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:26.029: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:26.039: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:26.159: W/GooglePlayServicesUtil(1031): Google Play Store is missing.
10-04 16:28:26.170: D/AndroidRuntime(1031): Shutting down VM
10-04 16:28:26.170: W/dalvikvm(1031): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
10-04 16:28:26.269: E/AndroidRuntime(1031): FATAL EXCEPTION: main
10-04 16:28:26.269: E/AndroidRuntime(1031): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testemapas/com.example.testemapas.MainActivity}: java.lang.NullPointerException: CameraUpdateFactory is not initialized
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.os.Handler.dispatchMessage(Handler.java:99)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.os.Looper.loop(Looper.java:137)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread.main(ActivityThread.java:5041)
10-04 16:28:26.269: E/AndroidRuntime(1031): at java.lang.reflect.Method.invokeNative(Native Method)
10-04 16:28:26.269: E/AndroidRuntime(1031): at java.lang.reflect.Method.invoke(Method.java:511)
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-04 16:28:26.269: E/AndroidRuntime(1031): at dalvik.system.NativeStart.main(Native Method)
10-04 16:28:26.269: E/AndroidRuntime(1031): Caused by: java.lang.NullPointerException: CameraUpdateFactory is not initialized
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.google.android.gms.internal.ac.a(Unknown Source)
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.google.android.gms.maps.CameraUpdateFactory.aV(Unknown Source)
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.google.android.gms.maps.CameraUpdateFactory.newLatLngZoom(Unknown Source)
10-04 16:28:26.269: E/AndroidRuntime(1031): at com.example.testemapas.MainActivity.onCreate(MainActivity.java:23)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.Activity.performCreate(Activity.java:5104)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
10-04 16:28:26.269: E/AndroidRuntime(1031): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
10-04 16:28:26.269: E/AndroidRuntime(1031): ... 11 more
10-04 16:28:26.399: D/dalvikvm(1031): GC_CONCURRENT freed 233K, 13% free 2588K/2952K, paused 7ms+32ms, total 209ms



Pleace, pleace....preciso muito dessa rota....grato!!!


Nelson Glauber disse...

oi Antônio,

Por acaso você está usando o emulador nativo do Android? Se sim, você não vai conseguir rodar mesmo. Isso porque, essa API precisa do Google Play pra funcionar.
Uma sugestão seria você usar o Genymotion (http://www.genymotion.com/).

4br4ç05,
nglauber

Unknown disse...

Olá Nelson, parabéns pelo Blog e pela interação com as pessoas que curtem o seu trabalho.

Estou desenvolvendo um aplicativo que precisa calcular rotas que não tem no Google Maps. Existe uma forma de eu criar essas rotas?

É um aplicativo utilizando Google Maps V2 que da a posição e rota para chegar os prédios de uma faculdade.

No aguardo, obrigado.

Nelson Glauber disse...

Oi Daniel,

Depois que escrevi esse post, virei sumidade em traçar rotas com Google Maps :)
Pelo menos é o que o pessoal pensa...

Cara realmente não sei te responder, mas se você tem a Lat/Lng dos dois pontos, a API do Google traça a rota pra você.

4br4ç05,
nglauber

Tedesco disse...

Boa tarde,
é possível usar essas rotas do google api sem mostrar o mapa?
eu gostaria de calcular apenas as distâncias de pontos determinados em relação ao meu ponto atual e mostrar um número (ex. 100 metros)

Nelson Glauber disse...

Oi Tedesco,

É sim... Basta usar apenas o webservice do Google Maps.

4br4ç05,
nglauber

motta disse...

Muito obrigado pelo post. Funcionou perfeitamente aqui.

Unknown disse...

Olá,
Estou com um problema. Como faço para abrir um arquivo .kml que já está salvo em uma pasta do aplicativo?

Unknown disse...

Oi Boa tarde!

Primeiramente parabéns, e obrigado por compartilhar o seu conhecimento conosco.

Sua solução funcionou perfeitamente, muito legal!

Mas eu gostaria de saber se tem como eu obter a distancia em KM entre esses dois pontos da rota?

Abraços

Nelson Glauber disse...

Oi Anderson,

Que bom que conseguiu. Para pegar a distância, você pode ler o atributo "distance" do JSON de retorno.
Dá uma olhada nesse link:
https://developers.google.com/maps/documentation/directions/?hl=pt-br#DirectionsResponses

4br4ç05,
nglauber

Unknown disse...

Ola Nelson , me chamo Breno , bom estou com dificuldade de implementar o Gps no codigo da Rota vc tem alguma sugestão e meu main activity não reconhece geopoint , MapController

Nelson Glauber disse...

Oi Breno,

Essas duas classes que você falou é da antiga API do Google Maps. Recomendo você utilizar a v2.
http://www.nglauber.com.br/2012/12/android-google-maps-v2.html

E quanto a rota, você pode ver nesse outro post aqui:
http://www.nglauber.com.br/2011/10/google-maps-tracando-rotas.html

4br4ç05,
nglauber

Rodrigo Gomes disse...

Parabéns pelo tutorial. Em exemplo, eu peço um taxi e gostaria de visualizar em tempo real o trajeto que ele está percorrendo até chegar onde estou. Tem como fazer isso? Estou começando agora não tenho muito conhecimento. Tipo eu pensei que teria que ficar atualizando o banco com a localização do motorista e no lado do cliente eu buscaria esses dados e mostraria. Seria isso?

Obrigado pelo post!

Nelson Glauber disse...

Oi Rodrigo,

Tem um exemplo com isso no meu livro. Basicamente é uma evolução desse post.
Inclusive fiz uma correção sobre ele, pois a API mudou poucos dias depois que o livro foi impresso.
http://www.nglauber.com.br/2015/01/dominando-o-android-atualizacao-1.html

4br4ç05,
nglauber

Anônimo disse...

bom dia meu caro!
bom estou com um pequeno problema, eu baixei o teu codigo, mas ao testar ele nao aparece nada, so a rota determinada, sera que e problema na hora de executar o app?

Nelson Glauber disse...

Oi Anônimo,

Deve ser problema com a chave que você cadastra no site.

4br4ç05,
nglauber

Unknown disse...

Caro Nelson, juntamente com meus amigos do IFMS estamos utilizando do seu código como base de um aplicativo que utiliza google maps, entretanto, encontramos o seguinte erro: O mapa não aparece, mas, apenas a rota sem este.

Poderia nos ajudar nisso?
Atenciosamente: Nayara

Reinaldo disse...

Bom dia, baixei o teu codigo mas quando executo aparece o seguinte erro...
Estilos ausentes. É o tema escolhido para esta correto layout? Use a caixa de combinação do tema acima do layout para escolher um layout diferente , ou corrigir as referências de estilo tema . Não foi possível encontrar estilo ' mapViewStyle ' no tema atual

o problema pode ser falta de atualização do meu compilador?

Nelson Glauber disse...

Oi Reinaldo,

Em tempo de projeto não vai aparecer mesmo... Se rodar e funcionar tá tudo bem :)
Qualquer dúvida, dá uma conferida no código do meu livro. Tá disponível no GitHub.

4br4ç05,
nglauber

Unknown disse...

Olá Nelson, estou tendo um problema com meu app. A rota está funcionando certinho quando coloco para aparecer pela primeira vez, mas quando coloco pela segunda vez em um lugar diferente, é atualizado apenas o marcador mas a rota continua no antigo lugar. Estou seguindo o exemplo de seu livro (que por sinal é ótimo). Abraços.

Nelson Glauber disse...

Oi Cínthia,

Eu respondi seu email, mas para registrar aqui também :)
A questão da rota é que você precisa fazer uma nova requisição para a API de Directions com os novos pontos de origem e destino. Essa implementação está nas classes RotaHttp e RotaTask.
Com a lista de LatLng que é retornada pelo método carregarRota(LatLng,LatLng) você atualiza o atributo mRota da MainActivity e chama o método atualizarMapa().

4br4ç05,
nglauber

Unknown disse...

nglauber pode me disponibilizar o link de seu livro?

Nelson Glauber disse...

Oi Reinaldo,

Segue abaixo.
http://novatec.com.br/livros/dominandoandroid/

Em breve sairá a segunda edição.

4br4ç05,
nglauber

Thiago Ferracini disse...
Este comentário foi removido por um administrador do blog.
Unknown disse...

muito bem explicado, gostei bastante do post!!!
Parabéns mano.

Wesley disse...

Olá Glauber,

Como eu faço para adicionar waypoints na rota??

Nelson Glauber disse...

Oi Wesley,

Pelo que eu sei, para cada trajeto você deve fazer uma nova consulta ao webservice.

4br4ç05,
nglauber