Calculando distâncias com PHP

Calculando distâncias com PHP

Neste artigo vamos ver como é possível calcular a distância entre duas coordenadas utilizando PHP. Existem várias formas de fazer este cálculo, neste artigo vamos focar num método chamado fórmula de Harvesine.

A fórmula de Haversine é equação utilizada em navegação, fornecendo distância entre 2 pontos de uma esfera, a partir de suas latitudes e longitudes. Esta fórmula é um caso especial de uma fórmula mais geral de trigonometria esférica, a lei dos haversines, que relaciona os lados e ângulos de um triângulo contido em uma superfície esférica.

Devemos ter em mente que a Terra não é uma esfera perfeita, ela é ligeiramente achatada nos polos. Por causa disso, o raio de nosso planeta é variável. Na região do Equador o radio possui o valor de 6378 km, mas nos pólos o seu valor é de 6357 km. Como você deve ter percebido, os valores aumentam a medida que nos aproximamos dos pólos.

Para facilitar o nosso cálculo, vamos considerar que o raio da Terra é de 6371 km.

As etapas que precisamos seguir para fazer este complexo cálculo são as seguintes:

1 - Converter as latitudes e longitudes de origem em destino em radianos.

2 - Com as latitudes que serão utilizadas devidamente convertidas em radianos, multiplicar o coseno da latitude de origem com o coseno da latitude de destino e depois com o coseno da diferença entre longitude de destino - longitude de origem.

3 - Pegar este resultado e somar com o resultado do  seno da latitude de origem multiplicado pelo seno da latitude de destino.

4 - Vamos retornar o inverso do cosseno deste resultado.

5 - Para concluir, vamos multiplicar o resultado desta operação por 6371, que é o valor que vamos utilizar como raio da Terra em kilometros. 

O resultado desta operação será em kilômetros.

Para nos ajudar em nossa implementação da fórmula de Harvesine, vamos precisar utilizar as seguintes funções do PHP.

 

* Acos - Retorna o arco cosseno de um número informado em radianos. Arco cosseno é a função inversa de cosseno

* Cos - Retorna o cosseno de um número informado em radianos.  O cosseno é a razão entre a medida do cateto oposto sobre o valor da hipotenusa.

* Deg2rad - Converte um número em graus para radianos. O radiano é a razão entre o comprimento de um arco e o seu raio.

* Sin - Retorna o seno de um número informado em radianos. O seno é a razão entre o cateto oposto e a hipotenusa de um triângulo retângulos

Vamos implementar nossa fórmula no PHP. No exemplo a seguir, as coordenadas de origem se referem a cidade de Adamantina e as coordenadas de destino se referem a cidade de Presidente Prudente. Ambas as cidades ficam no estado de São Paulo.

 

Origem - Adamantina

Latitude: -21.682

Longitude: -51.0737

 

Destino - Presidente Prudente

Latitude: -22.1207

Longitude: -51.3925

 

$lat1 = "-21.682";

$lat2 = "-22.1207";

$lon1 = "-51.0737";

$lon2 = "-51.3925";

$lat1 = deg2rad($lat1);

$lat2 = deg2rad($lat2);

$lon1 = deg2rad($lon1);

$lon2 = deg2rad($lon2);

$distancia = (6371 * acos(cos($lat1) * cos($lat2) * cos($lon2 - $lon1) + sin($lat1) * sin($lat2)));

$distancia = number_format($distancia, 2, ".", "");

echo $distancia;

 

Perceba que ao implementar este cálculo, utilizamos a função number_format para retornar o resultado em kilometros com duas casas decimais. 

O resultado da operação foi 58.83 kilometros, que é a distância que separa as cidades de Adamantina e Presidente Prudente.

Agora que temos a distância entre as duas cidades, temos um outro problema para resolver. Perceba que se estamos na cidade de Adamantina e queremos ir para a cidade de Presidente Prudente, precisamos de mais uma informação além da distância. É necessário saber para qual direção ir. Não temos como saber se a cidade fica ao norte ou ao sul por exemplo.

Para nos ajudar com isso, podemos fazer o seguinte cálculo:

 

1 - Converter as coordenadas em radianos.

2 - Calcular a diferença entre as coordenadas longitudinais

3 - Calcular a tangente da seguinte operação: Metade da latitude de destino mais a soma de PI dividido por quatro. 

4 - Calcular a tangente da seguinte operação: Metade da latitude de origem mais a soma de PI dividido por quatro. 

5 - Extrair o log da divisão entre os itens 3 e 4 (latitudes)

6 - Se o resultado do cálculo 2 (longitudes) for maior que a constante PI, recalcular da seguinte forma: (2 * pi() - cálculo das longitudes) * -1

7 - Calcular a tangente inversa dos resultados obtidos para as latitudes e longitudes e converter o resultado em graus.

7 - Com base neste resultado, somar 360 e retornar o resto da divisão por 360.

O resultado desta operação vai ser em graus.

Para nos ajudar, vamos precisar utilizar as seguintes funções do PHP:

 

* Abs - Retorna o valor absoluto (positivo) de um número.

* Atan2 - Calcula a tangente inversa entre dois números, seu retorno é um número em radianos.

* Log - Retorna o logaritmo natural de um número.

* Pi - Retorna o valor da constante de Pi, é uma proporção numérica definida pela relação entre o perímetro de uma circunferência e seu diâmetro.

* Rad2deg - Converte um valor em radianos para um valor em graus.

* Round - Arredonda um número, se o número de digitos decimais de precisão não for informado se utiliza o valor zero.

* Tan - Retorna a tangente de um número informado em radianos.  Tangente é a razão entre o cateto oposto e o cateto adjacente.

Nossa implementação do cálculo da direção e dos pontos cardeais ficaria da seguinte forma:

 

$lat1 = "-21.682";

$lat2 = "-22.1207";

$lon1 = "-51.0737";

$lon2 = "-51.3925";

$dLon = deg2rad($lon2) - deg2rad($lon1);

$dPhi = log(tan(deg2rad($lat2) / 2 + pi() / 4) / tan(deg2rad($lat1) / 2 + pi() / 4));

if(abs($dLon) > pi()) {

if($dLon > 0) {

  $dLon = (2 * pi() - $dLon) * -1;

} else {

  $dLon = 2 * pi() + $dLon;

}

}

$direcao = (rad2deg(atan2($dLon, $dPhi)) + 360) % 360;

$pontos_cardeais = array("N", "NE", "E", "SE", "S", "SW", "W", "NW", "N");

echo "Direção:" . $direcao;

echo (" * ");

echo $pontos_cardeais[round($direcao/45)];

 

Desta forma, descobrimos que a cidade de Presidente Prudente fica a 213 graus da cidade de Adamantina, ou seja, ela fica ao Sudoeste da cidade de Adamantina.

Veja que em nosso array de pontos cardeais nós inserimos os pontos cardeais e os pontos colaterais, que são aqueles que ficam entre os pontos cardeais. Como a circurferência possui 360 graus, dividimos o resultado em graus da direção por 45. Dividir a circunferência por 45 vai dar 8, que é o número de pontos cardeais e colaterais. 

Com base na última operação, podemos descobrir que a cidade de Presidente Prudente fica ao sudoeste da cidade de Adamantina.

 

Encerramento

 

Este artigo mostrou como calcular a distância entre duas coordenadas com PHP.

Se você deseja se aprofundar neste assunto e ver como fazer isso utilizando um banco de dados SQL eu recomendo muito a leitura do artigo a seguir:

 

Calculando distâncias com SQL

 

Outros conteudos que podem ser de seu interesse

Validando CPF e CNPJ com PHP
03/10/2021PHP

Validando CPF e CNPJ com PHP

Veja como validar o número destes dois documentos com PHP

Saiba mais...
Máscaras para CPF, CNPJ e outros tipos de dados com PHP
23/05/2021PHP

Máscaras para CPF, CNPJ e outros tipos de dados com PHP

Neste artigo você vai ver exemplos de como aplicar máscaras em dados utilizando PHP

Saiba mais...

Conteúdo sobre banco de dados sem complicação!