Is there a way to calculate the travelled distance in Mapbox?
For example: if a user clicks the start button it'll record the travelled path and calculate the distance. I know it's possible to calculate a distance between two geopoints described here, however a user can go off-road and therefore won't choose to walk the fastest/most suited route between two geopoints. I would like to sum ALL walked kilometers.
Monitor position
navigator.geolocation.watchPosition(function(position) {
document.getElementById('distance').innerHTML =
calculateDistance(startPos.coords.latitude, startPos.coords.longitude,
position.coords.latitude, position.coords.longitude);
});
Calculate distance
function calculateDistance(lat1, lon1, lat2, lon2) {
var R = 6371; // km
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
EDIT: one possible solution could be that every time I get a new location I calculate distance between previous geopoint and new geopoint and use that to calculate distance. If I want to see total distance I sum all the distances between previous points. I can also use that data to plot a line between all stored geopoints. Does this makes sense? Is there a more efficient way to do this since this is a pure javascript solution (maybe there is a more related to Mapbox solution?)
Related
I need to calculate the distance between two latitude and longitude points. I found this javascript code which I suppose I want.
Here comes the problem. I add the two positions lat and lng values in, and sometimes it just gives random output. What happens is two points literally next to other are sometimes like 8000 meters away, but two other much furthest points return only 1500 meters for example.
function degreesToRadians(degrees) {
return degrees * Math.PI / 180;
}
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
const distanceR = getDistanceFromLatLonInKm(userLat, userLng, solLat, solLng)
Lat: 68.00757101804007, lng: -49.306640625
to
lat: 73.26312194058698 lng: -23.535461425781254
is 1143 kilometres, but these two points are next to each other.
lat: 66.75724984139227, lng: -16.259765625000004
to
lat: 71.99597405683693 lng:-42.31933593750001
is 1161 metres and the points are much farther then the previus one.
Here I think it calculates fine, unlike the two previous lat and lng points.
I've tested the examples you provided and did a few on my own and I believe your implementation is working fine. I did however get different results using your examples and code.
The first example returns approx. 1102km, which seems close to the distance using a visualizer.
The second example returns 1161 kilometres which visualized again seems about right.
Please note: the images in the links were constructed using gpsvisualizer.com which uses a Vincenty formula to calculate distance, hence the slight variation in distance numbers.
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}
const e1 = {
lat1: 68.00757101804007,
lon1: -49.306640625,
lat2: 73.26312194058698,
lon2: -23.535461425781254
}
const e2 = {
lat1: 66.75724984139227,
lon1: -16.259765625000004,
lat2: 71.99597405683693,
lon2: -42.31933593750001
}
const dist1 = getDistanceFromLatLonInKm(e1.lat1, e1.lon1, e1.lat2, e1.lon2);
const dist2 = getDistanceFromLatLonInKm(e2.lat1, e2.lon1, e2.lat2, e2.lon2);
console.log(`Example 1 distance: ${dist1}km. Example 2 distance: ${dist2}km`);
I can not reproduce the issue you are having so I believe your error lies in your visualization of coordinates.
I'm having an issue with calculating distances.
I have installed postgis, and I'm saving Lng/Lat points in the database
CREATE TABLE geo (gid serial PRIMARY KEY, geo geography)
For inserting a record, this is what I do:
INSERT INTO geo (geo) VALUES (ST_MAKEPOINT(Lng,Lat)::geography))
When I do the following query with some Lng/Lat variables, I get the following output:
SELECT gid, ST_DISTANCE(geo, ST_MAKEPOINT(Lng2,Lat2)::geography) FROM geo;
----
OUTPUT: 1 424.02930940m
Secondly, when I do the exact same calculation with the following formula (haversine formula in javascript), I get a slightly different output.
/*
const coords1/2 = {
lat: // latitude,
lng: // longitude
};
*/
export const haversine = (coords1, coords2) => {
var R = 6371000;
var x1 = coords2.lat - coords1.lat;
var dLat = x1.toRad();
var x2 = coords2.lng - coords1.lng;
var dLon = x2.toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(coords1.lat.toRad()) * Math.cos(coords2.lat.toRad()) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
----
OUTPUT: 422.20392010m
It's a difference of 2 meters, but I need the most accurate of the 2. It's for an app for geocaching.
I'm currently using the haversine formula in my app, but I'm thinking about switching to postgis because it would simplify my queries a lot.
Which one can I rely on the most?
I am trying to work out he distance between two postcodes. One post code coordinates are generic however the other postcode is stored in the database which i need to get. This code below doesn't work out the distance between the generic postcode and the one i have inputted.
var x = getDistanceFromLatLonInKm(52.482799000000000, -2.000643000000000, 52.48463500000000, -1.980759000000000);
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2){
console.log(lat1, lon1, lat2, lon2);
var distanceFromSpecificPoint = getDistanceFromLatLonInKm.bind(null, 52.486637, -1.890952);
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}
document.getElementById('result').textContent = x;
console.log(x)
</script>
As per above, you can simply get the value from the database on the server side and use whatever server side web framework you wish. The example I've given here is Classic ASP, purely as an example to show you where the values are entered. Then on the server side, the database values are constants and you only enter the lat/lon for one point and get the distance from the database lat/lon (the constants LAT1/LON1 here). dbModel would be some object on the server side which is populated from the database. You can then grab the latitude/longitude values from this object for insertion into the web page via server side scripting.
function getDistanceFromLatLonInKm(lat, lon) {
const EARTH_RADIUS = 6371; // Radius of the earth in km
// Here's where you would add the value dynamically from the DB.
// I'm using classic ASP here just as an example. You'll have to
// amend for your particular server side web framework, be it
// JSP, MVC, etc.
const LAT1 = <%=dbModel.getLatitude()%>;
const LON1 = <%=dbModel.getLongitude()%>;
console.log(LAT1, LON1, lat, lon);
var dLat = deg2rad(lat - LAT1);
var dLon = deg2rad(lon - LON1);
var a = Math.pow(Math.sin(dLat / 2), 2) + Math.cos(deg2rad(LAT1)) * Math.cos(deg2rad(LON1)) * Math.pow(Math.sin(dLon / 2), 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = EARTH_RADIUS * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
Or, if you don't require it to be dynamic like this, just grab the static values from the database and enter them here as the values for LAT1 and LON1.
E.g.
const LAT1 = 52.482799;
const LON1 = -2.000643;
Then just call your function like this...
var distance = getDistanceFromLatLonInKm(52.48463500000000, -1.980759000000000);
To do PAF lookups:
FreeMapTools
Google Maps. Just search your postcode, then grab the latitude/longitude from the URL.
I want to make a location-based academic website(bootstrap project ) where a said question will be visible only to those present in the pre-specified radius. I can code in HTML,CSS and currently learning JavaScript and PHP. Anyone willing to give me some pointers? (code resources, relevant templates or useful literature)
You can find the distances beteen locations using the Haversine formula. The following javascript functions are used to calculate the distance between the geolocated coordinates and that of the center location. Only if the distance is less than radius allow access.
function deg2rad(degrees){
radians = degrees * (Math.PI/180);
return radians;
}
function Haversine(lat1,lon1,lat2,lon2) {
deltaLat = lat2 - lat1 ;
deltaLon = lon2 - lon1 ;
earthRadius = 3959; // in miles 6371 in meters.
alpha = deltaLat/2;
beta = deltaLon/2;
a = Math.sin(deg2rad(alpha)) * Math.sin(deg2rad(alpha)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(deg2rad(beta)) * Math.sin(deg2rad(beta)) ;
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
distance = earthRadius * c;
return distance.toFixed(2);
}
I have a list of adresses in my database that i can put into array in JS, but from now I want to display distance between me and them, like
me: Warsaw
array[0]: Berlin
array[1]: Moscov
array[2]: Amsterdam
array[3]: London
(array elements contains precise adresses, examples above are just like pseudocode)
I already made a script that can get distance between 2 points on map, but I am rendering map to do this, and this takes some time so it is not acceptable way if I want to display 20 distance entries at once
It don't have to be distance data as this can be overhelming question, but I just want to know how to fetch any data without waiting the time of map rendering.
Why are you using the map at all for this? There are other approaches you can use.
See here: http://www.movable-type.co.uk/scripts/latlong.html
I've used the "haversine" method myself:
function haversine() {
var radians = Array.prototype.map.call(arguments, function(deg) { return deg/180.0 * Math.PI; });
var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3];
var R = 6372.8; // km
var dLat = lat2 - lat1;
var dLon = lon2 - lon1;
var a = Math.sin(dLat / 2) * Math.sin(dLat /2) + Math.sin(dLon / 2) * Math.sin(dLon /2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
console.log(haversine(36.12, -86.67, 33.94, -118.40));