por Cesar Cassiano Schimanco

Calcular distância entre dois endereços – Google Maps API

Use o formulário abaixo para descobrir a distância entre dois endereços.

 

 
 
 

Booking.com

 


No artigo de hoje vou mostrar como utilizar Google Maps API para calcular a distância entre dois destinos.


URL de exemplo:
http://maps.googleapis.com/maps/api/distancematrix/xml?origins=Porto Alegre&destinations=Sao Paulo&mode=driving&language=pt-BR&sensor=false

Descrição dos parâmetros:
Tipos de saídas: json e xml
origins: Porto Alegre
destinations: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:

<DistanceMatrixResponse>
  <status>OK</status>
  <origin_address>Porto Alegre - RS, República Federativa do Brasil</origin_address>
  <destination_address>São Paulo, República Federativa do Brasil</destination_address>
  <row>
    <element>
      <status>OK</status>
      <duration>
        <value>46388</value>
        <text>12 horas 53 minutos</text>
      </duration>
      <distance>
        <value>1139925</value>
        <text>1.140 km</text>
      </distance>
    </element>
  </row>
</DistanceMatrixResponse>


Tipos de Status
OK Retorno válido.
INVALID_REQUEST Requisição inválida.
MAX_ELEMENTS_EXCEEDED Origem ou destino ultrapassaram o numero máximo de caracteres..
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.

Mais sobre a documentação do Google Distance Matrix API
https://developers.google.com/maps/documentation/distancematrix/


XML - Exemplo de implementação do Google Maps API para calcular distância entre endereços com retorno XML
URL de exemplo para retornar XML:
http://maps.googleapis.com/maps/api/distancematrix/xml?origins=Porto Alegre&destinations=Sao Paulo&mode=driving&language=pt-BR&sensor=false

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DistancematrixXML.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 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>
        <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;
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/distancematrix/xml?origins={0}&destinations={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")
        {
            //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}",
                //Pegar endereço de origem
                xml.Element("origin_address").Value,
                //Pegar endereço de destino
                xml.Element("destination_address").Value,
                //Pegar duração
                xml.Element("row").Element("element").Element("duration").Element("text").Value,
                //Pegar distância ente os dois pontos
                xml.Element("row").Element("element").Element("distance").Element("text").Value
                );
        }
        else
        {
            //Se ocorrer algum erro
            litResultado.Text = String.Concat("Ocorreu o seguinte erro: ", xml.Element("status").Value);
        }
    }
}


Retorno do XML:

<DistanceMatrixResponse>
  <status>OK</status>
  <origin_address>Porto Alegre - RS, República Federativa do Brasil</origin_address>
  <destination_address>São Paulo, República Federativa do Brasil</destination_address>
  <row>
    <element>
      <status>OK</status>
      <duration>
        <value>46388</value>
        <text>12 horas 53 minutos</text>
      </duration>
      <distance>
        <value>1139925</value>
        <text>1.140 km</text>
      </distance>
    </element>
  </row>
</DistanceMatrixResponse>

 

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.
Mas, se preferir, pode utilizar o novo artigo Distância entre cidades - Google Maps JavaScript API V3 ou então utilize a versão XML.

 

JSON - Exemplo de implementação do Google Maps API para calcular distância entre endereços com retorno JSON.
URL de exemplo para retornar JSON:
http://maps.googleapis.com/maps/api/distancematrix/json?origins=Porto Alegre&destinations=Sao Paulo&mode=driving&language=pt-BR&sensor=false

A adaptação tem o objetivo de minimizar o impacto para os que utilizaram este exemplo, mas recomendo a migração para a nova versão (Distância entre cidades - Google Maps JavaScript API V3 ou então utilize a versão XML). 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;
        }
    }
}

Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DistancematrixJson.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 runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-1.8.1.js" type="text/javascript"></script>
    
</head>
<body>
    <form id="form1" runat="server">
    <script type="text/javascript">
        function CalculaDistancia() {
            var urlDistancematrix = "http://maps.googleapis.com/maps/api/distancematrix/json?origins={0}&destinations={1}&mode=driving&language=pt-BR&sensor=false";
            //Adicionar endereço de origem
            urlDistancematrix = urlDistancematrix.replace("{0}", $("#txtOrigem").val());
            //Adicionar endereço de destino
            urlDistancematrix = urlDistancematrix.replace("{1}", $("#txtDestino").val());
            //Pegar o retorno do distancematrix ##A linha abaixo foi atualizada##
            $.getJSON("webservice.ashx?url=" + escape(urlDistancematrix),
              function (data) {
                  if (data.status == "OK") {
                      $('#litResultado').html("<strong>Origem</strong>: " + data.origin_addresses +
                          "<br /><strong>Destino:</strong> " + data.destination_addresses +
                          "<br /><strong>Distância</strong>: " + data.rows[0].elements[0].distance.text +
                          " <br /><strong>Duração</strong>: " + data.rows[0].elements[0].duration.text
                          );
                  }
                  else
                      $('#litResultado').html('Ocorreu um erro');
              }
            );
        }
    </script>
        <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="CalculaDistancia()" />
            </div>
        </div>
        <span id="litResultado"></span>
    </form>
</body>
</html>


Retorno do JSON:

{
   "destination_addresses" : [ "São Paulo, República Federativa do Brasil" ],
   "origin_addresses" : [ "Porto Alegre - RS, República Federativa do Brasil" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "1.140 km",
                  "value" : 1139925
               },
               "duration" : {
                  "text" : "12 horas 53 minutos",
                  "value" : 46388
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}


 O que mudou?

Antes:

//Pegar o retorno do distancematrix
$.getJSON(urlDistancematrix,
  function (data) {

 

Depois:

//Pegar o retorno do distancematrix
$.getJSON("webservice.ashx?url=" + escape(urlDistancematrix),
  function (data) {

Também foi adicionada uma nova página webservice.ashx

 

Comentários

Carregando comentários

Postar um novo comentário



Processando...