Calculate distance between 2 points in Google maps

Asked

Viewed 6,781 times

4

I don’t have much experience with javascript and have no idea how to get the result of this script and move to a field <input text>. This script calculates the distance and time between two points. So I wanted to take time and distance and then save it in a database.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Calcular distancia entre cidades (mapas e rotas)</title>
<script src="http://code.jquery.com/jquery-1.8.1.js" type="text/javascript"></script>
</head>
<body>
<!-- Parâmetro sensor é utilizado somente em dispositivos com GPS -->
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
    function CalculaDistancia() {
        $('#litResultado').html('Aguarde...');
        //Instanciar o DistanceMatrixService
        var service = new google.maps.DistanceMatrixService();
        //executar o DistanceMatrixService
        service.getDistanceMatrix(
          {
              //Origem
              origins: [$("#txtOrigem").val()],
              //Destino
              destinations: [$("#txtDestino").val()],
              //Modo (DRIVING | WALKING | BICYCLING)
              travelMode: google.maps.TravelMode.DRIVING,
              //Sistema de medida (METRIC | IMPERIAL)
              unitSystem: google.maps.UnitSystem.METRIC
              //Vai chamar o callback
          }, callback);
    }
    //Tratar o retorno do DistanceMatrixService
    function callback(response, status) {
        //Verificar o Status
        if (status != google.maps.DistanceMatrixStatus.OK)
            //Se o status não for "OK"
            $('#litResultado').html(status);
        else {
            //Se o status for OK
            //Endereço de origem = response.originAddresses
            //Endereço de destino = response.destinationAddresses
            //Distância = response.rows[0].elements[0].distance.text
            //Duração = response.rows[0].elements[0].duration.text
            var x = response.rows[0].elements[0].distance.text;
            $('#litResultado').html("<strong>Origem</strong>: " +    
 response.originAddresses +
                "<br /><strong>Destino:</strong> " + response.destinationAddresses +
                "<br /><strong>Distância</strong>: " +  
 response.rows[0].elements[0].distance.text +
                " <br /><strong>Duração</strong>: " + 
 response.rows[0].elements[0].duration.text
                );
            //Atualizar o mapa
            $("#map").attr("src", "https://maps.google.com/maps?saddr=" + 
    response.originAddresses + "&daddr=" + response.destinationAddresses +  
    "&output=embed");
        }
    }
   </script>

   <table width="100%" cellspacing="0" cellpadding="0" border="0">
       <label for="txtOrigem"><strong>Endere&ccedil;o de origem</strong></label>
       <input type="text" id="txtOrigem" class="field" style="width: 400px" />
       <label for="txtDestino"><strong>Endere&ccedil;o de destino</strong></label>
       <input type="text" style="width: 400px" class="field" id="txtDestino" />
       <input type="button" value="Calcular dist&acirc;ncia"  onclick="CalculaDistancia()" class="btnNew" />
  <div><span id="litResultado">&nbsp;</span></div>

  <!------------------------------------------------------------------->
    <input type="text" value="<? Variavel distancia?>"  
    <input type="text" value="<? Variavel tempo?>"  
  <!------------------------------------------------------------------->

 <div style="padding: 10px 0 0; clear: both">
    <iframe width="750" scrolling="no" height="350" frameborder="0" id="map" 
  marginheight="0" marginwidth="0" src="https://maps.google.com/maps?saddr=são 
 paulo&daddr=rio de janeiro&output=embed"></iframe>
</div>
  • Just taking a look over, I saw there’s an element <table> unopened that does not contain rows and columns within it. Is that right? Also, your HTML is not complete as it does not have the </body> nor the </html>.

  • More Ta working yes. In fact it will not even have table

1 answer

9


I think I got it right.

First I fixed the problems with the malformed HTML: Missing </body> and the </html> at the end, which I added. You have an element <table> left that is useless, and I removed it. You are breaking line within the attribute src of <iframe> and that’s bad, and I didn’t break line there. Also, I added the <!DOCTYPE html> and the <meta charset="utf-8">. Finally, I took care of some of the escapes that were missing (â for &acirc; and ã for &atilde;).

Then I added the fields where the result will be placed. I also separated them from the fields where the search is performed. I made the result fields read-only to ensure that their result actually comes from Google (however, don’t trust it if you’re going to make it available to the general public). I put them all inside one <form> with a button Submit to send to the server later:

EDIT: On 06/11/2018, more than three years after this question and answer were posted, Google changed the format of the API. Until then, it was possible to use the API for free without requiring a Key API. With the change, it becomes necessary to use a Key API, which can only be activated with a credit card. See more at this link, on this page and here. In the following codes, replace the API_KEY_AQUI value of your Key API. And to use your Key API, you must activate it.

    <form action="http://www.example.com/url" method="post">
      <div><span>Pesquisa:</span></div>
      <label for="txtOrigem"><strong>Endere&ccedil;o de origem</strong></label>
      <input name="pesquisaOrigem" type="text" id="txtOrigem" class="field" style="width: 400px" value="S&atilde;o Paulo" />
      <label for="txtDestino"><strong>Endere&ccedil;o de destino</strong></label>
      <input name="pesquisaDestino" type="text" id="txtDestino" class="field" style="width: 400px" value="Rio de Janeiro" />
      <input type="button" value="Calcular dist&acirc;ncia" onclick="CalculaDistancia()" class="btnNew" />
      <div><span id="litResultado">&nbsp;</span></div>

      <div><span>Resposta:</span></div>
      <label for="txtOrigemResultado"><strong>Endere&ccedil;o de origem</strong></label>
      <input name="resultadoOrigem" readonly="readonly" type="text" id="txtOrigemResultado" class="field" style="width: 400px" value="" />
      <label for="txtDestinoResultado"><strong>Endere&ccedil;o de destino</strong></label>
      <input name="resultadoDestino" readonly="readonly" type="text" id="txtDestinoResultado" class="field" style="width: 400px" value="" />
      <br />
      <label for="txtDistancia"><strong>Dist&acirc;ncia</strong></label>
      <input name="distancia" readonly="readonly" type="text" id="txtDistancia" value="" /> 
      <label for="txtTempo"><strong>Tempo</strong></label>
      <input name="tempo" readonly="readonly" type="text" id="txtTempo" value="" />
      <input type="submit" value="Enviar para o servidor" />
    </form>

I arranged the javascript to fill these fields in callback. I took the opportunity to remove the "wait" when the answer arrives and also translated the time to Portuguese.

      // Tratar o retorno do DistanceMatrixService
      function callback(response, status) {
        // Verificar o status.
        if (status != google.maps.DistanceMatrixStatus.OK) { // Se o status não for "OK".
            $("#litResultado").html(status);
        } else { // Se o status for "OK".
            $("#litResultado").html("&nbsp;"); // Remove o "aguarde".

            // Popula os campos.
            $("#txtOrigemResultado").val(response.originAddresses);
            $("#txtDestinoResultado").val(response.destinationAddresses);
            $("#txtDistancia").val(response.rows[0].elements[0].distance.text);
            var tempo = response.rows[0].elements[0].duration.text;
            tempo = tempo.replace("day", "dia").replace("hour", "hora").replace("min", "minuto");
            $("#txtTempo").val(tempo);

            //Atualizar o mapa.
            $("#map").attr("src", "https://maps.google.com/maps?saddr=" + response.originAddresses + "&daddr=" + response.destinationAddresses + "&output=embed&key=API_KEY_AQUI");
        }
      }

Here is the full HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Calcular dist&acirc;ncia entre cidades (mapas e rotas)</title>
    <script src="http://code.jquery.com/jquery-1.8.1.js" type="text/javascript"></script>
  </head>
  <body>
    <!-- Parâmetro sensor é utilizado somente em dispositivos com GPS -->
    <script src="http://maps.google.com/maps/api/js?sensor=false&key=API_KEY_AQUI"></script>
    <script type="text/javascript">
      function CalculaDistancia() {
        $('#litResultado').html('Aguarde...');
        // Instancia o DistanceMatrixService.
        var service = new google.maps.DistanceMatrixService();
        // Executa o DistanceMatrixService.
        service.getDistanceMatrix({
            origins: [$("#txtOrigem").val()], // Origem
            destinations: [$("#txtDestino").val()], // Destino
            travelMode: google.maps.TravelMode.DRIVING, // Modo (DRIVING | WALKING | BICYCLING)
            unitSystem: google.maps.UnitSystem.METRIC // Sistema de medida (METRIC | IMPERIAL)
        }, callback); // Vai chamar o callback
      }

      // Tratar o retorno do DistanceMatrixService
      function callback(response, status) {
        // Verificar o status.
        if (status != google.maps.DistanceMatrixStatus.OK) { // Se o status não for "OK".
            $("#litResultado").html(status);
        } else { // Se o status for "OK".
            $("#litResultado").html("&nbsp;"); // Remove o "aguarde".

            // Popula os campos.
            $("#txtOrigemResultado").val(response.originAddresses);
            $("#txtDestinoResultado").val(response.destinationAddresses);
            $("#txtDistancia").val(response.rows[0].elements[0].distance.text);
            var tempo = response.rows[0].elements[0].duration.text;
            tempo = tempo.replace("day", "dia").replace("hour", "hora").replace("min", "minuto");
            $("#txtTempo").val(tempo);

            //Atualizar o mapa.
            $("#map").attr("src", "https://maps.google.com/maps?saddr=" + response.originAddresses + "&daddr=" + response.destinationAddresses + "&output=embed&key=API_KEY_AQUI");
        }
      }
    </script>

    <form action="http://www.example.com/url" method="post">
      <div><span>Pesquisa:</span></div>
      <label for="txtOrigem"><strong>Endere&ccedil;o de origem</strong></label>
      <input name="pesquisaOrigem" type="text" id="txtOrigem" class="field" style="width: 400px" value="S&atilde;o Paulo" />
      <label for="txtDestino"><strong>Endere&ccedil;o de destino</strong></label>
      <input name="pesquisaDestino" type="text" id="txtDestino" class="field" style="width: 400px" value="Rio de Janeiro" />
      <input type="button" value="Calcular dist&acirc;ncia" onclick="CalculaDistancia()" class="btnNew" />
      <div><span id="litResultado">&nbsp;</span></div>

      <div><span>Resposta:</span></div>
      <label for="txtOrigemResultado"><strong>Endere&ccedil;o de origem</strong></label>
      <input name="resultadoOrigem" readonly="readonly" type="text" id="txtOrigemResultado" class="field" style="width: 400px" value="" />
      <label for="txtDestinoResultado"><strong>Endere&ccedil;o de destino</strong></label>
      <input name="resultadoDestino" readonly="readonly" type="text" id="txtDestinoResultado" class="field" style="width: 400px" value="" />
      <br />
      <label for="txtDistancia"><strong>Dist&acirc;ncia</strong></label>
      <input name="distancia" readonly="readonly" type="text" id="txtDistancia" value="" /> 
      <label for="txtTempo"><strong>Tempo</strong></label>
      <input name="tempo" readonly="readonly" type="text" id="txtTempo" value="" />
      <input type="submit" value="Enviar para o servidor" />
    </form>

    <div style="padding: 10px 0 0; clear: both">
      <iframe width="750" scrolling="no" height="350" frameborder="0" id="map" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?saddr=S&atilde;o Paulo&daddr=Rio de Janeiro&output=embed"></iframe>
    </div>
  </head>
</html>

To use, you must proceed like this:

  1. You choose the desired locations and fill them in the search fields.
  2. Click on "Calculate Distance".
  3. Google will bring the result.
  4. Javascript will fill in the form fields with the results.
  5. You click on the "Send to server" button and the form data will be sent to the server.

On the server, you will receive a POST request containing the following form fields: pesquisaOrigem, pesquisaDestino, resultadoOrigem, resultadoDestino, distancia and tempo. The meaning of each of them is obvious. The URL responsible for receiving this service must be configured on your server and the field action of your <form> HTML must match it.

If you prefer, you can make the Google OK answer already submit the result via AJAX to your server automatically. Or you may want to put some more complex validation logic on your "Send to server" button. In this case, if you have any doubts about how to do this, it is already within the scope of another question, but nothing prevents you from adapting this process as it suits you.

Already on the server, you will run a Prepared statement with an SQL statement more or less like this:

INSERT INTO Distancias (pesquisaOrigem, pesquisaDestino, resultadoOrigem, resultadoDestino, distancia, tempo) VALUES (?, ?, ?, ?, ?, ?)

Or just like that:

INSERT INTO Distancias (origem, destino, distancia, tempo) VALUES (?, ?, ?, ?)

And then just fill in the parameters of your Prepared statement with the data received from the form. However, before doing so, you might want to pre-process them to convert all times into minutes, convert all distances into numerical values (eliminating the suffix " km"), and perhaps tidying up at source and destination if you want to eliminate information you deem unnecessary such as street number, zip code, case/lower case differences, or whatever you want.

  • 2

    very good what I saw here, I got the answer I was looking for!

  • i am using your code on a system, but I am having a problem, is returning an error after some tests I did, I waited 10 min and the error continues: OVER_QUERY_LIMIT

Browser other questions tagged

You are not signed in. Login or sign up in order to post.