Use o formulário abaixo para gerar a rota entre dois endereços.
Baseado no artigo Calcular distância entre dois endereços, vou mostrar hoje como utilizar Google Directions API para calcular as direções entre localizações, ou seja, vai calcular a rota.
URL de exemplo:
http://maps.googleapis.com/maps/api/directions/xml?origin=Porto Alegre&destination=Sao Paulo&mode=driving&language=pt-BR&sensor=false
Descrição dos parâmetros:
Tipos de saídas: json e xml
origin: Porto Alegre
destination:São Paulo
mode: driving (driving - walking - bicycling )
language : pt-BR
sensor: (true – false) para aplicações que usam GPS...
units=metric (metric - imperial ) Retorna distância em quilômetros ou milhas.
Resultado:
<?xml version="1.0" encoding="UTF-8"?>
<DirectionsResponse>
<status>OK</status>
<route>
<summary>Av. Osvaldo Aranha</summary>
<leg>
<step>
<travel_mode>DRIVING</travel_mode>
<start_location>
<lat>-30.0320800</lat>
<lng>-51.2209500</lng>
</start_location>
<end_location>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</end_location>
<polyline>
<points>nshvD|aswHUpBYnCp@jAn@hA</points>
</polyline>
<duration>
<value>31</value>
<text>1 min</text>
</duration>
<html_instructions>Siga na direção <b>oeste</b> na <b>Av. Osvaldo Aranha</b> em direção à <b>Av. João Pessoa</b><div style="font-size:0.9em">O destino estará à direita</div></html_instructions>
<distance>
<value>217</value>
<text>0,2 km</text>
</distance>
</step>
<duration>
<value>31</value>
<text>1 min</text>
</duration>
<distance>
<value>217</value>
<text>0,2 km</text>
</distance>
<start_location>
<lat>-30.0320800</lat>
<lng>-51.2209500</lng>
</start_location>
<end_location>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</end_location>
<start_address>Avenida Osvaldo Aranha, 100 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil</start_address>
<end_address>Avenida Osvaldo Aranha, 10 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil</end_address>
</leg>
<copyrights>Dados cartográficos ©2013 Google, MapLink</copyrights>
<overview_polyline>
<points>nshvD|aswHo@`G`BtC</points>
</overview_polyline>
<bounds>
<southwest>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</southwest>
<northeast>
<lat>-30.0318400</lat>
<lng>-51.2209500</lng>
</northeast>
</bounds>
</route>
</DirectionsResponse>
Tipos de Status
OK Retorno válido.
NOT_FOUND Algum local ou ponto informado, não foi localizado.
ZERO_RESULTS Nenhum resultado encontrado.
MAX_WAYPOINTS_EXCEEDED Excesso de waypointss na consulta.
INVALID_REQUEST Requisição inválida.
OVER_QUERY_LIMIT Aplicação excedeu o número máximo de requisições em um determinado período.
REQUEST_DENIED Sua aplicação bloqueou o uso do Distance Matrix.
UNKNOWN_ERROR Erro no servidor. Tente novamente que pode funcionar.
Alguns limites de uso:
- 2,500 requisições diárias
- As URLs de requisição não podem ultrapassar 2048 characteres
Mais sobre a documentação do Google Directions API
https://developers.google.com/maps/documentation/directions
XML - Exemplo de implementação do Google Maps API para gerar rota automaticamente entre endereços com retorno XML
URL de exemplo para retornar XML:
http://maps.googleapis.com/maps/api/directions/xml?origin=Porto%20Alegre,%20Osvaldo%20Aranha,%20100&destination=Porto%20Alegre,%20Osvaldo%20Aranha,%2010&sensor=false
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<label for="txtOrigem">Origem</label>
<asp:TextBox runat="server" ID="txtOrigem" ClientIDMode="Static" />
</td>
</tr>
<tr>
<td>
<label for="txtDestino">Destino</label>
<asp:TextBox runat="server" ID="txtDestino" ClientIDMode="Static" />
</td>
</tr>
</table>
<asp:Button Text="Calcular" ID="btnCalcular" runat="server"
onclick="btnCalcular_Click" />
</div>
</div>
<div style="padding:10px">
<iframe id="map" runat="server" width="750" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?saddr=porto+alegre&daddr=São paulo&output=embed"></iframe>
</div>
<asp:Literal ID="litResultado" runat="server" />
</form>
</body>
</html>
Defautl.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.Xml.Linq;
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCalcular_Click(object sender, EventArgs e)
{
//URL do distancematrix - adicionando endereço de origem e destino
string url = string.Format("http://maps.googleapis.com/maps/api/directions/xml?origin={0}&destination={1}&mode=driving&language=pt-BR&sensor=false",
txtOrigem.Text, txtDestino.Text);
//Carregar o XML via URL
XElement xml = XElement.Load(url);
//Verificar se o status é OK
if (xml.Element("status").Value == "OK")
{
string rota = string.Empty;
//Pegar os detalhes de cada passo da rota
foreach (var item in xml.Element("route").Element("leg").Elements("step"))
{
//Pegar as instruções da rota em HTML
rota += item.Element("html_instructions").Value + "<br />";
//Pegar a distância deste trecho
rota += item.Element("distance").Element("text").Value + "<br />";
}
//Formatar a resposta
litResultado.Text = string.Format("<strong>Origem</strong>: {0} <br /><strong>Destino:</strong> {1} <br /><strong>Distância</strong>: {2} <br /><strong>Duração</strong>: {3} <br /><strong>Como chegar ao destino</strong>:<br /> {4}",
//Pegar endereço de origem
xml.Element("route").Element("leg").Element("start_address").Value,
//Pegar endereço de destino
xml.Element("route").Element("leg").Element("end_address").Value,
//Pegar duração
xml.Element("route").Element("leg").Element("duration").Element("text").Value,
//Pegar a distância
xml.Element("route").Element("leg").Element("distance").Element("text").Value,
//Adicionar a rota gerada logo acima
rota
);
//Atualizar o mapa
map.Src = "https://maps.google.com/maps?saddr=" + xml.Element("route").Element("leg").Element("start_address").Value + "&daddr=" + xml.Element("route").Element("leg").Element("end_address").Value + "&output=embed";
}
else
{
//Se ocorrer algum erro
litResultado.Text = String.Concat("Ocorreu o seguinte erro: ", xml.Element("status").Value);
}
}
}
Retorno do XML:
<?xml version="1.0" encoding="UTF-8"?>
<DirectionsResponse>
<status>OK</status>
<route>
<summary>Av. Osvaldo Aranha</summary>
<leg>
<step>
<travel_mode>DRIVING</travel_mode>
<start_location>
<lat>-30.0320800</lat>
<lng>-51.2209500</lng>
</start_location>
<end_location>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</end_location>
<polyline>
<points>nshvD|aswHUpBYnCp@jAn@hA</points>
</polyline>
<duration>
<value>31</value>
<text>1 min</text>
</duration>
<html_instructions>Siga na direção <b>oeste</b> na <b>Av. Osvaldo Aranha</b> em direção à <b>Av. João Pessoa</b><div style="font-size:0.9em">O destino estará à direita</div></html_instructions>
<distance>
<value>217</value>
<text>0,2 km</text>
</distance>
</step>
<duration>
<value>31</value>
<text>1 min</text>
</duration>
<distance>
<value>217</value>
<text>0,2 km</text>
</distance>
<start_location>
<lat>-30.0320800</lat>
<lng>-51.2209500</lng>
</start_location>
<end_location>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</end_location>
<start_address>Avenida Osvaldo Aranha, 100 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil</start_address>
<end_address>Avenida Osvaldo Aranha, 10 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil</end_address>
</leg>
<copyrights>Dados cartográficos ©2013 Google, MapLink</copyrights>
<overview_polyline>
<points>nshvD|aswHo@`G`BtC</points>
</overview_polyline>
<bounds>
<southwest>
<lat>-30.0323300</lat>
<lng>-51.2229900</lng>
</southwest>
<northeast>
<lat>-30.0318400</lat>
<lng>-51.2209500</lng>
</northeast>
</bounds>
</route>
</DirectionsResponse>
Atenção: A versão do Google Maps JavaScript V2 utilizada neste artigo foi descontinuada pelo Google. Então oi necessário fazer uma adaptação para o exemplo (JSON) voltar a funcionar. O artigo já está atualizado e funcionando e no final explico o que mudou.
A adaptação tem o objetivo de minimizar o impacto para os que utilizaram este exemplo. A solução mostrada aqui consiste em criada uma interface que vai se comunicar com a API, processar os dados e retornar a versão JSON correspondente. Abaixo está o novo webservice deve receber como parâmetro a URL original do Google Maps.
webservice.ashx:
<%@ WebHandler Language="C#" Class="webservice" %>
using System;
using System.Web;
public class webservice : IHttpHandler {
public void ProcessRequest (HttpContext context) {
//Pegar a URL enviada como Parâmetro
string url = context.Request.QueryString["url"];
//Instanciar o WebClient
System.Net.WebClient wc = new System.Net.WebClient();
//Definir a codificação como UTF8
wc.Encoding = System.Text.Encoding.UTF8;
//Obter o conteúdo (JSON) da URL
string json = wc.DownloadString(HttpUtility.UrlDecode(url));
//Retornar o JSON
context.Response.Write(json);
//Definie o ContentType = JSON
context.Response.ContentType = "application/json";
}
public bool IsReusable {
get {
return false;
}
}
}
JSON - Exemplo de implementação do Google Maps API para traçar rota entre endereços com retorno JSON.
URL de exemplo para retornar JSON:
http://maps.googleapis.com/maps/api/directions/json?origin=Porto%20Alegre,%20Osvaldo%20Aranha,%20100&destination=Porto%20Alegre,%20Osvaldo%20Aranha,%2010&sensor=false
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script src="http://code.jquery.com/jquery-1.8.1.js" type="text/javascript"></script>
<script type="text/javascript">
function CalculaRota() {
var urlDirections = "http://maps.googleapis.com/maps/api/directions/json?origin={0}&destination={1}&mode=driving&language=pt-BR&sensor=false";
//Adicionar endereço de origem
urlDirections = urlDirections.replace("{0}", $("#txtOrigem").val());
//Adicionar endereço de destino
urlDirections = urlDirections.replace("{1}", $("#txtDestino").val());
$('#litResultado').html('Aguarde...');
$.getJSON("webservice.ashx?url=" + escape(urlDirections ),
function (data) {
//Verificar se o Status está OK
if (data.status == "OK") {
var rota = "";
for (var i = 0; i < data.routes[0].legs[0].steps.length; i++) {
//Pegar as instruções da rota em HTML
rota += data.routes[0].legs[0].steps[i].html_instructions + "<br />";
//Pegar a distância deste trecho
rota += data.routes[0].legs[0].steps[i].distance.text + "<br />";
}
//Retornar o resultado na página
$('#litResultado').html(
//Pegar endereço de origem
"<strong>Origem</strong>: " + data.routes[0].legs[0].start_address +
//Pegar endereço de destino
"<br /><strong>Destino:</strong> " + data.routes[0].legs[0].end_address +
//Pegar a distância
"<br /><strong>Distância</strong>: " + data.routes[0].legs[0].distance.text +
//Pegar duração
" <br /><strong>Duração</strong>: " + data.routes[0].legs[0].duration.text +
//Adicionar a rota gerada logo acima
" <br /><strong>Como chegar ao destino</strong>:<br /> " + rota
);
//Atualizar o mapa
$("#map").attr("src", "https://maps.google.com/maps?saddr=" + data.routes[0].legs[0].start_address +"&daddr=" + data.routes[0].legs[0].end_address + "&output=embed");
}
//Se o Status não for OK
else
$('#litResultado').html('Ocorreu um erro');
}
).error(function () { $('#litResultado').html('Ocorreu um erro!'); });
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<label for="txtOrigem">Origem</label>
<input type="text" id="txtOrigem" />
</td>
</tr>
<tr>
<td>
<label for="txtDestino">Destino</label>
<input type="text" id="txtDestino" />
</td>
</tr>
</table>
<input type="button" value="Calcular distância" onclick="CalculaRota()" />
</div>
</div>
<div style="padding:10px">
<iframe id="map" width="750" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?saddr=porto+alegre&daddr=São paulo&output=embed"></iframe>
</div>
<span id="litResultado"></span>
</form>
</body>
</html>
Retorno do JSON:
{
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : -30.031840,
"lng" : -51.220950
},
"southwest" : {
"lat" : -30.03233000000001,
"lng" : -51.222990
}
},
"copyrights" : "Dados cartográficos ©2013 Google, MapLink",
"legs" : [
{
"distance" : {
"text" : "0,2 km",
"value" : 217
},
"duration" : {
"text" : "1 min",
"value" : 31
},
"end_address" : "Avenida Osvaldo Aranha, 10 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil",
"end_location" : {
"lat" : -30.03233000000001,
"lng" : -51.222990
},
"start_address" : "Avenida Osvaldo Aranha, 100 - Centro, Porto Alegre - RS, 90035-190, República Federativa do Brasil",
"start_location" : {
"lat" : -30.032080,
"lng" : -51.220950
},
"steps" : [
{
"distance" : {
"text" : "0,2 km",
"value" : 217
},
"duration" : {
"text" : "1 min",
"value" : 31
},
"end_location" : {
"lat" : -30.03233000000001,
"lng" : -51.222990
},
"html_instructions" : "Siga na direção \u003cb\u003eoeste\u003c/b\u003e na \u003cb\u003eAv. Osvaldo Aranha\u003c/b\u003e em direção à \u003cb\u003eAv. João Pessoa\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003eO destino estará à direita\u003c/div\u003e",
"polyline" : {
"points" : "nshvD|aswHUpBYnCp@jAn@hA"
},
"start_location" : {
"lat" : -30.032080,
"lng" : -51.220950
},
"travel_mode" : "DRIVING"
}
],
"via_waypoint" : []
}
],
"overview_polyline" : {
"points" : "nshvD|aswHo@`G`BtC"
},
"summary" : "Av. Osvaldo Aranha",
"warnings" : [],
"waypoint_order" : []
}
],
"status" : "OK"
}
O que mudou?
Antes:
$('#litResultado').html('Aguarde...');
$.getJSON(urlDirections,
function (data) {
Depois:
$('#litResultado').html('Aguarde...');
$.getJSON("webservice.ashx?url=" + escape(urlDistance),
function (data) {
Também foi adicionada uma nova página webservice.ashx