I am looking for a way to find the distance between two coordinates that have elevation data as well, but I want the solution to take under account the TERRAIN between the two points i.e the shortest way between them on the ground and not "as the crow flies".
I have found and used the Haversine formula for the distance "in the air" but obviously it will not yield the real distance that a man would walk on the ground as in between the two points there might be a slope that goes up and / or down. The larger the distance between the points the bigger the error margin.
I have sampled a real .gpx file and converted its data into JSON format. it looks like this:
let jsonSample = [{
"lat": "57.107297", // 0
"lon": "-5.334734",
"ele": "957.00"
}, // distance between 0 and 1 => 169.1849929515954 m (as the crow flies) elevation difference: 50.210000000000036
{
"lat": "57.106590", // 1
"lon": "-5.332253",
"ele": "1007.21"
}, // distance between 1 and 2 => 162.49601252670058 m (as the crow flies) elevation difference: 23.789999999999964
{
"lat": "57.105537", // 2 (summit)
"lon": "-5.330387",
"ele": "1031.00"
}, // distance between 2 and 3 => 32.45395539826568 m (as the crow flies) elevation difference: -13
{
"lat": "57.105284", // 3
"lon": "-5.330119",
"ele": "1018.00"
}];
Real distances should be longer than the ones calculated with Haversine formula. But how do I calculate it?
Googling "haversine formula elevation" found me this Math.SE question and answer.
Heeding the comments, so long as the distances you're measuring aren't too far apart, using the Pythagorean Theorem, you can add the elevation deltas in.
I'd use Pythagoras: let d the Haversine distance and dh the difference in altitudes,
D=sqrt(d**2+dh**2)
.
Something like
function haversineWithAltitude(lat1, lon1, alt1, lat2, lon2, alt2) {
const groundDistanceInMeters = haversine(lat1, lon1, lat2, lon2);
const elevationDifferenceMeters = Math.abs(alt1 - alt2);
return Math.sqrt(groundDistanceInMeters * groundDistanceInMeters + elevationDifferenceInMeters * elevationDifferenceInMeters);
}
should thus work – but as said, this will inevitably become more inaccurate if the length between the points is very long. (At that point, I'd, not being a mathematician and not knowing better, segment the long leg and calculate each distance piecewise.)