Skip to content

Calcular distancias teniendo en cuenta la curvatura de la tierra

Cada ves son más los clientes que nos solicitan desarrollar aplicaciones de seguimiento y cálculos relacionados.

Uno de éstos cálculos, es obtener la distancia entre dos puntos de un mapa (con Latitud y Longitud).

SI dicho cálculo es dentro de una ciudad o territorio pequeño, es prácticamente exacto, pero si tenemos que obtener la distancia entre países muy lejanos, por ejemplo entre EEUU y China, el cálculo se complica, porque tenemos que tener en cuenta la curvatura de la tierra.

Si vamos a la matemática pura, la formula para calcular la distancia teniendo en cuenta la curvatura de la tierra, es la siguiente:

[Math]

Distance = Radio x arcos [ sin(OriginLat) x sin(DestinyLat) + cos(OriginLat) x cos(DestinyLat) x cos(DestinyLon-OriginLon) ]

.

Si traducimos la función anterior a Delphi nos queda la siguiente función:

Uses   System.Math;

...

Type
  TPoint = record
    Lat: Double;
    Lng: Double;
  end;
  TPointRad = record
    Lat: Extended;
    Lng: Extended;
  end;

...

function Distancia(Origin, Destiny: TPoint; Curvature: Boolean = False): Double;
var
  d, s, c: Double;
  OriginRad: TPointRad;
  DestinyRad: TPointRad;
  CurvatureAux: Double;
Const
  R = 6378137; // Medium earth radius in meter
begin

  OriginRad.Lat := DegToRad(Origin.Lat);
  OriginRad.Lng := DegToRad(Origin.Lng);

  DestinyRad.Lat := DegToRad(Detiny.Lat);
  DestinyRad.Lng := DegToRad(Detiny.Lng);

  if (OriginRad.Lng = DestinyRad.Lng) AND (OriginRad.Lat = DestinyRad.Lat) then
    d := 0
  else
  begin
    s := sin(OriginRad.Lat) * sin(DestinyRad.Lat);
    c := cos(OriginRad.Lat) * cos(DestinyRad.Lat) * cos(DestinyRad.Lng - OriginRad.Lng);

    if Curvature then
      CurvatureAux := Round((s + c) * 100000000) / 100000000
    else
      CurvatureAux := (s + c);

    if CurvatureAux <> 1 then
      d := R * arccos(s + c)
    else
      d := 0;
  end;
  Result := d;
end;

La function Distancia(Origin, Detiny: TPoint; Curvature: Boolean = False): Double; la hemos preparado para determinar, con el parámetro curvature, si tenemos en cuenta la curvatura del planeta tierra o no, por defecto se encuentra en False, utilizado para distancias cortas.