I'm working on a GPS application for agriculture purposes. I need a way to calculate with precision the distance, and difference (X, Y) between two coordinates, using latitude, longitude, and altitude (altitude is given in meters). The points will be close to each other, something about 10m or less, the distance will be used in other calculations like area, and the difference (X, Y) will be used to render a 2D map.
My first thought was to use the right triangle to calculate the 2D (X, Y), and again to calculate the 3D distance.
Here a Script (in Javascript):
function xyDifference(lat1, lng1, lat2, lng2){
var xdif = (lng1 - lng2)/0.00000898; //value to convert decimal degrees difference to meters
var ydif = (lat1 - lat2)/0.00000898;
return [xdif,ydif];
}
function distanceBetween2D(lat1,lng1,lat2,lng2) {
var b = Math.abs(lat1 - lat2);
var c = Math.abs(lng1 - lng2);
var a = Math.sqrt(Math.pow(b,2) + Math.pow(c,2));
var dst = a / 0.00000898;
return dst;
}
function distanceBetween3D(lat1,lng1,alt1,lat2,lng2,alt2){
var dst = distanceBetween2D(lat1,lng1,lat2,lng2);
a = Math.abs(alt1 - alt2);
dst = Math.sqrt(Math.pow(dst,2) + Math.pow(a,2));
return dst;
}
console.log(distanceBetween(-24.09234566666,-52.5289494999999,588,-24.09231633333,-52.5288795,589));
//It prints 8.51m
//Using Haversine formula with these values it gives something about 7.82m
I want to know if this is a good way, or if there is a better way. I have seen the Haversine formula but I don't know how to use it with the altitudes difference, and how to get an (X,Y) difference to render the map.
Suggest using a geodesy library, in particular https://www.movable-type.co.uk/scripts/geodesy-library.html. Note that this libray offers a number of geodesy models to chose from ( eg, spherical vs elliptical ). In your particular case, I have selected two different modules to exemplify their use...
<script type="module">
import LatLonE from 'https://cdn.jsdelivr.net/npm/geodesy@2/latlon-ellipsoidal-vincenty.js';
import LatLon, { Cartesian, Vector3d, Dms } from 'https://cdn.jsdelivr.net/npm/geodesy@2/latlon-ellipsoidal.js';
let latlon0 = new LatLonE( -24.09234566666, -52.5289494999999 );
let latlon1 = new LatLonE( -24.09231633333, -52.5288795 );
let latlonDistance = latlon0.distanceTo( latlon1 );
console.log( `Lat/Lon distance from ${latlon0.toString()} to ${latlon1.toString()} is ${latlonDistance}m` );
let cart0 = new LatLon( -24.09234566666, -52.5289494999999, 588 ).toCartesian();
let cart1 = new LatLon( -24.09231633333, -52.5288795, 589 ).toCartesian();
let cartDistance = Math.sqrt( ( cart1.x - cart0.x ) ** 2 + ( cart1.y - cart0.y ) ** 2 + ( cart1.z - cart0.z ) ** 2 );
console.log( `Cartesian distance from ${cart0.toString()} to ${cart1.toString()} is ${cartDistance}m` );
</script>
Note that the Lat / Lon calculation results in the 7.824m that you observed in the Haversine formula. ( This is in line with @Bergi's comment too, in that the Haversine formula does not appear to take into account altitude. )
The conversion to cartesian coordinates and calculation of distance results in a value a touch bigger, specifically 7.88836m, as there is an elevation difference of 1m between the coordinates. A straight up calculation of the hypotenuse of right a triangle with sides of 7.824m and 1m results in a length of 7.88765m, very close to the result of the library. Bearing in mind that 1) the higher the altitude, the further apart the same Lat / Lon becomes and 2) the ellipsoidal shape of the earth affects the calculations too, then the result of the library is within reason...