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:
Ola, gostava de saber se este código esta mesmo funcionando. Se o resultado final é o da figura.. cumprimentos
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
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
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
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
Oi Fernando Anselmo,
Obrigado pelo aviso. Acabei de corrigir.
4br4ç05,
nglauber
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.
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
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?
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
Valeu Glauber, talvez isso me ajude. Vou tentar depois. abraço
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!
Muito obrigado mesmo! EXCELENTE POST!
Parabens!
Boas, sou português, e estou a testar seu programa, mas não consigo, registar rotas aqui para portugal, queria perguntar porquê?
Oi Marcio,
Era pra funcionar, afinal estou usando longitude e latitude (que é universal)... Qual o problema que está acontecendo?
4br4ç05,
nglauber
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
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
era mesmo isso obrigado
cumprimentos
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
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
ok, obrigado irei testar...sim se conseguir postarei aqui...mais uma vez obrigado, estou a iniciar android, ainda sou novato
cumprimentos
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.
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
ó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...
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
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);
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
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
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
Oi marcio7,
Acho que isso aqui vai te ajudar:
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html
4br4ç05,
nglauber
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
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
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
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
Oi marcio7,
Que bom que concluiu o projeto. Se quiser, pode mandar pro meu email.
4br4ç05,
nglauber
Muito bom!
Ótima iniciativa, funciona muito bem, fácil entendimento.
Obrigado por compartilhar.
Muito bom
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?
Oi Ricardo,
Pra fazer isso, é só remover o overlay anterior ao clicar no mapa.
mapView.getOverlays().clear()
4br4ç05,
nglauber
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?
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
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%
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
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.
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
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
Ola glauber,
Então, estou debugando e a variável coordenadasStr recebe um valor nulo, ou seja, o getfirstchild() esta retornando nulo.
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
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
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
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
Oi Nelson,
Muito bom este seu post.
Eu procurava por uma explicação detalhada como esta a algum tempo.
Valeu!
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
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,
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
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
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
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.
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
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
Bom dia , gostaria se o código acima resolveu o problema de seguir as ruas corretamente ?
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 ?
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
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
Mt bom meu velho!!!
E valeu pela referência do meu post sobre o AsyncTask =)
Pra refrescar a memória sou eu wolverine ;)
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.
oi joaohsenger,
Dá uma olhada nesse post:
http://nglauber.blogspot.com.br/2011/10/google-maps-e-gps.html
4br4ç05,
nglauber
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 ?
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!
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
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!
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!
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!
Parabens pela aplicaçao, gostaria de saber se vc tem ela para download ?
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?
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
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!
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??
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
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!
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
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!
Aló Glauber, muitoooo obrigado por esse post. Mim ajudou muito =D.
O exemplo pra download está diferente do código do post. Muito obrigado.
Oi Diogo,
Não tem de que. Estamos aqui pra ajudar. Ah! Acabei de atualizar o post.
4br4ç05,
nglauber
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.
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
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.
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
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?
Oi Lucas,
Agora que vi que a classe Route estava retornando uma List ao invés de uma List.
Post corrigido.
4br4ç05,
nglauber
Ola Gostaria de saber como faço pra transformar as coordenadas em nome de rua e vice versa?
Oi Renan,
O pessoal já perguntou isso nos comentários acima. Dá uma procurada em GeoCoder. Essa classe realiza essa tarefa.
4br4ç05,
nglauber
Gostaria de saber como é o funcionamento da classe SupportMapFragment ?
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
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?
Oi Anônimo,
Acabei de corrigir o post. Dá uma olhada.
4br4ç05,
nglauber
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ç!!
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
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..
Oi Anônimo,
Qual erro está acontecendo? Dá uma olhada no logcat.
4br4ç05,
nglauber
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!!!
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
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.
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
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)
Oi Tedesco,
É sim... Basta usar apenas o webservice do Google Maps.
4br4ç05,
nglauber
Muito obrigado pelo post. Funcionou perfeitamente aqui.
Olá,
Estou com um problema. Como faço para abrir um arquivo .kml que já está salvo em uma pasta do aplicativo?
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
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
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
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
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!
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
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?
Oi Anônimo,
Deve ser problema com a chave que você cadastra no site.
4br4ç05,
nglauber
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
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?
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
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.
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
nglauber pode me disponibilizar o link de seu livro?
Oi Reinaldo,
Segue abaixo.
http://novatec.com.br/livros/dominandoandroid/
Em breve sairá a segunda edição.
4br4ç05,
nglauber
muito bem explicado, gostei bastante do post!!!
Parabéns mano.
Olá Glauber,
Como eu faço para adicionar waypoints na rota??
Oi Wesley,
Pelo que eu sei, para cada trajeto você deve fazer uma nova consulta ao webservice.
4br4ç05,
nglauber
Postar um comentário