Calcular distância entre dois pontos GPS

Olá, após um tempinho sem publicar trago uma função que serve para calcular a distância entre dois pontos GPS (com Latitude e Longitude cada). A função é bem simples de utilizar e retorna o resultado em metros.

  1. function distanciaPontosGPS($p1LA, $p1LO, $p2LA, $p2LO) {
  2.     $r = 6371.0;
  3.        
  4.     $p1LA = $p1LA * pi() / 180.0;
  5.     $p1LO = $p1LO * pi() / 180.0;
  6.     $p2LA = $p2LA * pi() / 180.0;
  7.     $p2LO = $p2LO * pi() / 180.0;
  8.        
  9.     $dLat = $p2LA$p1LA;
  10.     $dLong = $p2LO$p1LO;
  11.        
  12.     $a = sin($dLat / 2) * sin($dLat / 2) + cos($p1LA) * cos($p2LA) * sin($dLong / 2) * sin($dLong / 2);
  13.     $c = 2 * atan2(sqrt($a), sqrt(1$a));
  14.        
  15.     return round($r * $c * 1000); // resultado em metros.
  16. }

Como usar:

  1. echo distanciaPontosGPS(-26.91545, -49.063632, -26.917985, -49.061143);

Resultado será: 375

Comments

34 Responses to “Calcular distância entre dois pontos GPS”

  1. Ícaro Souza on julho 20th, 2009 2:13

    Olá desculpe incomodar axei bastate interessante e util pra mim, gostaria de saber pro resultado sair em milhas nauticas como seria?

  2. Cesar Bagatoli on julho 20th, 2009 8:35

    Olá Ícaro, 1 milha náutica equivale a 1828 metros, o resultado da função retorna em metros, então seria somente fazer a conversão. Qualquer problema me avise, obrigado.

  3. Ícaro Souza on julho 21st, 2009 2:38

    Opa melhor não tinha pensado nisso, se me permitir irei usar pra calcular distancia entre aeroportos.

    Muito agradecido pela sua resposta e pelo seu script..

    Por acaso, já alguma class que calcular TEMPO a percorrer em tal distancia usando tal velocidade?
    Consegui fazer, mas não consegui passar pro PHP

    $d=500 //DISTANCIA EM NM
    $v=460 //VELOCIDADE EM KNOS
    $tempo = $d / $v;
    $tempo = $tempo * 60;
    //resutaldo 65 minutos

    Thanks

  4. Cesar Bagatoli on julho 21st, 2009 8:39

    Olá, pode usar o script sim, se possível só faça uma referência de autoria.
    Quanto a calcular o tempo é simples, basta dividir a distância pela velocidade, ex:
    $distancia = 5; // quilômetros
    $velocidade = 15; // km/h
    $tempoHoras = $distancia / $velocidade; // Resulta em 0.33 horas
    $tempoMinutos = $tempoHoras * 60; // Resulta em 20 minutos

    Se quiser em outras medidas é só fazer as conversões.
    Espero ter ajudado. Abraço.

  5. Ícaro Souza on julho 21st, 2009 9:42

    Eu fiz o esquema acima pondo milhas nauticas e velocidade em knots deu certo tambem.

    Vlw

  6. ALAN on setembro 7th, 2009 16:19

    Boa tarde Cesar.
    Estava olhando sua funcao acima, e queria perguntar se eu consigo implantar isso como se fosse um mapa do alto vale. Eu estudo em rio do sul, e o trab semestral e fazer o mapa do alto vale com dacastro das cidades, e depois o sistema devera mostrar a menor distancia entre duas cidades.

  7. Cesar Bagatoli on setembro 7th, 2009 21:57

    Você pode utilizar para calcular as distâncias sim, basta você passar as coordenadas para a função. Para isso você também pode utilizar a API do Google Maps, ela faz muita coisa automaticamente.

  8. Luiz Carlos do Lago on fevereiro 5th, 2010 12:30

    recebe do meu gps a seguinte informação
    $GPGGA,041217.00,2331.69924,S,04646.50307,W,1,09,1.12,730.2,M,-5.3,M,,*46

    Latitude: 2331.69924,S
    Longitude: 04646.50307,W

    Não me parece ser um valor que a sua função espera, você faz alguma conversão antes ?

  9. Cesar Bagatoli on fevereiro 5th, 2010 12:48

    Olá, para esta função deve-se utilizar o sistema em graus decimais (Wikipedia), ex: -22.906014 e -47.060571 para latitude e longitude.
    Obrigado.

  10. Cesar on junho 22nd, 2011 10:03

    César, antes de mais nada, muito obrigado por compartilhar essas informações, tenho certeza que será muito útil para toda a comunidade “programadora” rs. Amigo, deixe-me fazer uma pergunta.. Porque quando passo p1LA, p2LA, p2LO,p1LO.. Sendo as Latitudes e Longitude iguais, não me retorna o valor “0 metros”, informando que estou em cima do ponto? Ele me retorna 4 metros…

    Atenciosamente!

  11. Cesar Bagatoli on agosto 16th, 2011 11:05

    Desculpe a demora, tenho que verificar porque esta dando isto. Obrigado por reportar o erro.

  12. Fernando Villela on dezembro 21st, 2011 12:36

    Consertei a Função:

    Aqui está o novo código

    function distanciaPontosGPS($p1LA, $p1LO, $p2LA, $p2LO) {
    $r = 6371.0;

    $p1LA = $p1LA * pi() / 180.0;
    $p1LO = $p1LO * pi() / 180.0;
    $p2LA = $p2LA * pi() / 180.0;
    $p2LO = $p2LO * pi() / 180.0;
    $dLat = $p2LA + ($p1LA * -1);
    $dLong = $p2LO + ($p1LO * -1);

    $a = sin($dLat / 2) * sin($dLat / 2) + cos($p1LA) * cos($p2LA) * sin($dLong / 2) * sin($dLong / 2);
    $c = 2 * atan2(sqrt($a), sqrt(1 + ($a*-1)));

    return round($r * $c * 1000); // resultado em metros.

    }
    echo distanciaPontosGPS(-26.91545, -49.063632, -26.917985, -49.061143);

    O que eu preciso mesmo saber para completar meu projeto é como conseguir a latitude e longitude, se alguém souber por favor informe em detalhes, qual API do Google Maps? Tem algum exemplo p´ratico? Obrigado

  13. Cesar Bagatoli on fevereiro 3rd, 2012 10:45

    Obrigado, assim que der eu atualizo o post.

  14. mariohollanda@hotmail.com on março 26th, 2014 19:55

    Estou passando os parametros como variavel e não esta calculando corretamente. Qual seria o problema? ex: da chamada:

    while ($row = ibase_fetch_row($query))
    {
    $distancia = distanciaPontosGPS($lat, $long, $row[0], $row[1]);

    }

  15. Cesar Bagatoli on abril 2nd, 2014 8:15

    Olá, teria que ver se os valores que estão sendo passados ao método estão no formato aceito pela classe.

  16. Paulo Barbosa on abril 2nd, 2014 8:22

    é possivel conseguir latitude e longitude de CEPS no Webservice do site http://www.mapacep.com.br

  17. Renato on agosto 13th, 2015 6:27

    Olá, eu fiz um teste em casa medindo com fita métrica (risos) só pra ter uma “certeza” da exatidão.
    Só que nesta parte do código:

    return round($r * $c * 1000); // resultado em metros.

    Eu troquei para:

    return round($r * $c * 2340, 2); // resultado em metros.

    Eu sei que o número 1000, é referente a metragem para se calcular em metros.
    A dúvida é, eu posso ter mais dados inconsistentes usando o “1000” ou usando “2340”?

    Muito obrigado desde já.

  18. Cesar Bagatoli on agosto 13th, 2015 9:32

    Olá Renato, qual seria a inconsistência utilizando 1000? Pois esta classe está sendo utilizada por mais pessoas e não me foi reportado nada até agora. Obrigado.

  19. Dala on novembro 6th, 2015 0:07

    Boa noite.
    Gostaria de saber pq foi utilizado c = 2 * atan2(sqrt(a), sqrt(1-a));??
    a formula de Haversine não utiliza c = 2 * asin2(sqrt(a)).

  20. Cesar Bagatoli on novembro 6th, 2015 7:19

    Olá, bom dia, esta fórmula foi passada por um amigo meu na época que publiquei o artigo, não saberia responder sua dúvida no momento. Caso tenha alguma problema com a função ou se estiver retornando dados que não são reais, não hesite em me contactar. Obrigado.

  21. Felipe on maio 3rd, 2016 8:55

    Olá

    Eu tenho um “quadrado” de 15km x 15km, com a coordenada central. É possível eu conseguir eu meus limites?

    OBS – Só tenho uma latitude e 1 longitude. Ex: Lat -35.05 e Lon -75.05.

    Obrigado

  22. Cesar Bagatoli on junho 23rd, 2016 8:26

    Olá Felipe, desculpe a demora. Não sei se teria como calcular o “quadrado” a partir de um ponto central, talvez até dê mas acho que seria um cálculo complexo, e se for um “circulo” acredito que seria mais simples, porém pra lhe dar os limites a função teria que lhe passar um array com N valores, de acordo com a precisão que você quisesse, acho que seria mais facil você usar a API do Google Maps para fazer isso pois ela tem muitos recursos desde tipo e já mostra no próprio mapa deles. Espero ter ajudado. Obrigado.

  23. Raimundo Miranda on agosto 15th, 2016 8:32

    Amigo poderia fazer de forma simplificado?? ou seja efetuando as contas!!!!

  24. Cesar Bagatoli on agosto 17th, 2016 7:55

    Olá Raimundo, não entendi sua solicitação, a função está pronta para ser utilizada. Se tiver alguma dúvida é só entrar em contato. Obrigado.

  25. Messiasa Hakme on outubro 17th, 2016 10:55

    Para coletar “Latitude e Longitude” há um aplicativo bom para Android “Status do GPS e Toolbox” Desenvolvedor “MobiWIA – EclipSim”.

  26. Cesar Bagatoli on outubro 18th, 2016 9:53

    Obrigado pela dica!

  27. Adriano Okama on novembro 18th, 2016 19:36

    Olá Cesar, parabéns pelo post. Estava a alguns dias tentando calcular essa distância e nenhum exemplo que encontrei trouxe de forma tão clara e simples como fez. Consegui implementar sua função no meu aplicativo para calcular a distância percorrida e velocidade. Obrigado.

  28. Cesar Bagatoli on novembro 19th, 2016 8:14

    Obrigado por utilizar.

  29. OSMAN LUIZ RODRIGUES on janeiro 26th, 2017 21:28

    BOA NOITE SR. CESAR BAGATOLI.

    QUERIA UMA INFORMAÇAO SE POSIVEL,, TRABALHO COM REDE DE ALTA TENSAO,, FAÇO MINHAS MEDIDAS TUDO NA TRENA E TEM LOCAIS MUITO SUJO E DIFICIL DE PASSAR,, TENHO UM GPS (AQUARIUS DISCOVERY) QUERIA SABER DO SENHOR SE TEM COMO EU MARCAR AS COORDENADAS COM ELE E SABER AS MEDIDAS ENTRE DOIS OU MAIS PONTOS?

    OBRIGADO E FIQUE COM DEUS.

  30. Cesar Bagatoli on janeiro 27th, 2017 7:14

    Olá Osman, obrigado por entrar no blog. Quanto à sua pergunta, não conheço seu GPS, mas se ele tiver uma opção para mostrar sua latitude e longitude atuais talvez funcione, vai depender da precisão do seu GPS e também da distância entre os 2 ou mais pontos.

  31. Marcos Paulo on julho 25th, 2017 18:37

    Tenho uma dúvida.
    Um Webservice me retorna um par de coordenadas de um veículo a cada 10 segundos. É comum um interferência elevar esse valor para 30 segundos ou até mais. Sendo conhecido a última leitura, a atual, e o tempo entre elas, consigo interpolar pontos intermediários entre esses dois pontos varíavel no tempo? Isto é, se eu quiser fazer a cada segundo ou mesmo a cada 10 segundos?

  32. Cesar Bagatoli on julho 26th, 2017 7:38

    Olá Marcos, se o seu GPS estiver lendo a cada 1 segundo e todas com sucesso seria possível, mas se ele lê a cada 10 segundos e às vezes demora mais pra ler não é possível “adivinhar” onde estava a posição em determinado tempo, a não ser que seja em linha reta entre as 2 leituras, ou seja, você leu o primeiro ponto e 40 segundos depois você teve a leitura do segundo ponto, baseado no tempo entre elas você consegue colocar pontos em linha reta distribuídos entre as duas leituras “quentes”.
    Espero ter ajudado. Obrigado pela visita.

  33. Sérgio Xavier on maio 23rd, 2019 12:43

    Olá Cesar, coloquei sua formula em minha procedure, com os dados:

    -23.097268 -48.902738
    -23.101846 -48.923954

    E como resultado me da 2.250 metros.

    Porem este pontos são referentes ao comprimento do terreno de minha casa.

    Que tem aproximadamente entre 15 e 20 metros.

    Como resolver ?

    Antecipadamente, agradeço.

    Sérgio

  34. Cesar Bagatoli on maio 23rd, 2019 13:45

    Boa tarde Sérgio, coloquei estas coordenadas no google maps e uma é bem longe da outra, por isto está retornando 2.250 metros conforme você falou. Verifique a precisão os pontos GPS que você informou, um deles deve estar errado. Qualquer coisa é só postar aqui novamente. Abraço e obrigado pelo contato.

Leave a Reply