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.