Using the Haversine Formula in JavaScript

Using the Haversine Formula in Javascript

This code is working:

Number.prototype.toRad = function() {
return this * Math.PI / 180;
}

var lat2 = 42.741;
var lon2 = -71.3161;
var lat1 = 42.806911;
var lon1 = -71.290611;

var R = 6371; // km
//has a problem with the .toRad() method below.
var x1 = lat2-lat1;
var dLat = x1.toRad();
var x2 = lon2-lon1;
var dLon = x2.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;

alert(d);

Notice how I defined x1 and x2.
Play with it at: https://tinker.io/3f794

Calculate distance between two latitude-longitude points? (Haversine formula)

This link might be helpful to you, as it details the use of the Haversine formula to calculate the distance.

Excerpt:

This script [in Javascript] calculates great-circle distances between the two points –
that is, the shortest distance over the earth’s surface – using the
‘Haversine’ formula.

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)
}

How to calculate distance (NOT DISPLACEMENT) travelled using Haversine Formula?

Just record the displacement every x seconds or so, and sum the displacements. You will have a fairly good approximation. Or just record the points at different times first, and then do the calculation at the end.

var checkpoints = [],
interval = null;

function record() {
checkpoints.push( /* current position */ )
}

function distance(a, b) {
return /* your distance calculation */
}

function start() {
checkpoints = [];
interval = setInterval(record, 1000); // record current pos every second
}

function end() {
clearInterval(interval);

var distanceTravelled = checkpoints.reduce(function(x, current, i, checkpoints){
return x + distance(current, checkpoints[i-1]);
}, 0);

// do something nice with the distance
}

UPDATE

I just now realized you use watch with a callback. You can use following approach then,

var lastPoint = null,
travelled = 0;

function update(point) {
if (lastPoint != null)
travelled += calculateDistance(lastPoint.long, lastPoint.lat, point.long, point.lat);

lastPoint = point;
}

UPDATE 2
Working solution: http://jsfiddle.net/ymz3a5pb/

How to alter the Haversine formula to calculate distance between fixed point and user's location

What you want is to do your calculations in a callback function once navigator.getCurrentPosition() returns successfully. Furthermore, the toRad() function is not defined, so you'd need to define it first.

if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
navigator.geolocation.getCurrentPosition(function(position){
calcPosition(position.coords.latitude,position.coords.longitude)
});
function calcPosition(lat1, lon1){
var lat2 = 45.843295;
var lon2 = -87.020821; // 2 is location
var R = 3963.1676; // radius in mi
var x1 = lat2-lat1;
var dLat = x1.toRad();
var x2 = lon2-lon1;
var dLon = x2.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;
alert("You are"+" "+d+" "+"miles away from our school")
}

Here is a fiddle.

EDIT: Here is an answer with a performance-optimized version of the formula.

How to apply Haversine Formula with another condition?

You will have 4 parameters @member_id, @start_date, @end_date, @distance

You need to use JOIN to find out the mates of member = 1

Then you can find out if those mates doesn't overlap with the dates. The conditional in your link indicate overlap, you want the inverted conditional so add NOT.

Finally use check if the result of the formula is less than @distance

 SELECT *
FROM member M
JOIN the_schedule_table S
ON M.mate = S.id
WHERE NOT (S.start_date < @end_date AND S.end_date > @start_date)
AND ( { Haversine formula } ) < @distance
AND M.member = @member_id

Function to calculate distance between two coordinates

What you're using is called the haversine formula, which calculates the distance between two points on a sphere as the crow flies. The Google Maps link you provided shows the distance as 2.2 km because it's not a straight line.

Wolfram Alpha is a great resource for doing geographic calculations, and also shows a distance of 1.652 km between these two points.

Drive distance vs. straight line distance (red line mine).

If you're looking for straight-line distance (as the crow files), your function is working correctly. If what you want is driving distance (or biking distance or public transportation distance or walking distance), you'll have to use a mapping API (Google or Bing being the most popular) to get the appropriate route, which will include the distance.

Incidentally, the Google Maps API provides a packaged method for spherical distance, in its google.maps.geometry.spherical namespace (look for computeDistanceBetween). It's probably better than rolling your own (for starters, it uses a more precise value for the Earth's radius).

For the picky among us, when I say "straight-line distance", I'm referring to a "straight line on a sphere", which is actually a curved line (i.e. the great-circle distance), of course.



Related Topics



Leave a reply



Submit