Distância entre pontos georeferenciados
Autor: Lucas | Publicado: 2013-12-09T15:05:00-02:00


A seguir está uma macro para calcular a distância geodésica (em quilômetros) entre dois pontos no globo dadas suas posições geográficas (latitude e longitude). Assumimos aqui que a terra é esférica com raio 6.371 km (raio médio).

A macro recebe cinco parâmetros:  LAT1G e LONG1G são, respectivamente, a latitude e longitude (em graus) do primeiro ponto. LAT2G e LONG2G são a latitude e longitude (também em graus) do segundo ponto e o parâmetro SAIDA define o nome da variável a ser criada com a informação da distância entre os pontos.



DEFINE !CALCULA_DISTANCIA(LAT1G = !TOKENS(1)/LONG1G = !TOKENS(1)/LAT2G = !TOKENS(1)/LONG2G = !TOKENS(1)/SAIDA=!TOKENS(1))

   * Define constantes (pi e raio da terra - esférica).
   COMPUTE #PI = 3.1415926535898.
   COMPUTE #RAIO = 6371.

   * Converte coordenadas para radianos.
   COMPUTE #LAT1 = !LAT1G * #PI / 180.
   COMPUTE #LAT2 = !LAT2G * #PI / 180.
   COMPUTE #LONG1 = !LONG1G * #PI / 180.
   COMPUTE #LONG2 = !LONG2G * #PI / 180.

   * Calcula diferença entre as coordenadas.
   COMPUTE #DLAT = #LAT2 - #LAT1.
   COMPUTE #DLONG = #LONG2 - #LONG1.

   * Calcula função de Haversine.
   COMPUTE #A = SIN(#DLAT/2)**2 + COS(#LAT1)*COS(#LAT2)*(SIN(#DLONG/2)**2).
   COMPUTE #X = SQRT(1 - #A).
   COMPUTE #Y = SQRT(#A).

   DO IF #X > 0.
      COMPUTE #B = ARTAN(#Y / #X).
   ELSE IF #Y >= 0 AND #X < 0.
      COMPUTE #B = ARTAN(#Y / #X) + #PI.
   ELSE IF #Y < 0 AND #X < 0.
      COMPUTE #B = ARTAN(#Y / #X) - #PI.
   ELSE IF #Y > 0 AND #X = 0.
      COMPUTE #B = #PI / 2.
   ELSE IF #Y < 0 AND #X = 0.
      COMPUTE #B = -(#PI / 2).
   ELSE.
      COMPUTE #B = $sysmis.
   END IF.

   COMPUTE !SAIDA = 2 * #RAIO * #B.

   FORMATS
      !SAIDA(F6.4).

!ENDDEFINE.




A macro não lê o banco de dados, logo para que a variável de saída seja criada é necessário executar explicitamente um comando EXECUTE ou outro comando que faça a leitura dos dados.


Como exemplo, suponha que temos uma base de dados com latitude e longitude nas variáveis LAT e LONG, respectivamente, queremos calcular a distância de cada um dos casos ao ponto localizado nas coordenadas (latitude, longitude) = (-23.591471,-46.688852). A execução do código a seguir calcula a distância na variável DISTANCIA. Note que criamos duas variáveis temporárias com as coordenadas do ponto ao qual queremos calcular a distância.


COMPUTE #LATtemp = -23.591471.
COMPUTE #LONGtemp = -46.688852.
!CALCULA_DISTANCIA LAT1G=LAT LONG1G=LONG LAT2G=#LATtemp LONG2G=#LONGtemp SAIDA=DISTANCIA.
EXECUTE.



Para quem deseja mais informações sobre o cálculo da distância recomendo a leitura deste artigo. Segue, de brinde, a mesma função para SQLServer (versão 2008).



CREATE FUNCTION CALCULA_DISTANCIA
(
 @LAT1G FLOAT,
 @LONG1G FLOAT,
 @LAT2G FLOAT,
 @LONG2G FLOAT
)
RETURNS FLOAT
AS
BEGIN

 -- Converte ângulos em radianos
 DECLARE @LAT1 FLOAT;
 DECLARE @LONG1 FLOAT;
 DECLARE @LAT2 FLOAT;
 DECLARE @LONG2 FLOAT;

 SET @LAT1 = @LAT1G * PI() / 180.0;
 SET @LAT2 = @LAT2G * PI() / 180.0;
 SET @LONG1 = @LONG1G * PI() / 180.0;
 SET @LONG2 = @LONG2G * PI() / 180.0;

 -- Define raio da terra
 DECLARE @RAIO_TERRA FLOAT;
 SET @RAIO_TERRA = 6371.0; -- em km

 -- Calcula variação da latitude e longitude entre os pontos
 DECLARE @DLAT FLOAT;
 DECLARE @DLONG FLOAT;
 
 SET @DLAT = @LAT2 - @LAT1;
 SET @DLONG = @LONG2 - @LONG1;
  
 -- Aplica função de Haversine
 DECLARE @A FLOAT;
 SET @A =SQUARE(SIN(@DLAT/2.0))+COS(@LAT1)*COS(@LAT2)*SQUARE(SIN(@DLONG/2.0));

 -- Calcula a distância entre os pontos
 DECLARE @DIST FLOAT;
 SET @DIST = 2.0 * @RAIO_TERRA * ATN2(SQRT(@A), SQRT(1.0 - @A));
 
 RETURN @DIST;

END




Abraços,Lucas Rodrigues