Using JavaScript in the browser, how can I determine the distance from my current location to another location for which I have the latitude and longitude?
If your code runs in a browser, you can use the HTML5 geolocation API:
window.navigator.geolocation.getCurrentPosition(function(pos) {
console.log(pos);
var lat = pos.coords.latitude;
var lon = pos.coords.longitude;
})
Once you know the current position and the position of your "target", you can calculate the distance between them in the way documented in this question: Calculate distance between two latitude-longitude points? (Haversine formula).
So the complete script becomes:
function distance(lon1, lat1, lon2, lat2) {
var R = 6371; // Radius of the earth in km
var dLat = (lat2-lat1).toRad(); // Javascript functions in radians
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; // Distance in km
return d;
}
/** Converts numeric degrees to radians */
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
window.navigator.geolocation.getCurrentPosition(function(pos) {
console.log(pos);
console.log(
distance(pos.coords.longitude, pos.coords.latitude, 42.37, 71.03)
);
});
Apparently I am 6643 meters from the center of Boston, MA right now (that's the hard-coded second location).
See these links for more information:
http://html5demos.com/geo
http://diveintohtml5.info/geolocation.html
Calculate distance between two latitude-longitude points? (Haversine formula)
toRad() Javascript function throwing error
Related
Suppose a single page application that consumes rest services is loaded in Singapore and there are two possible locations hosting the REST / edge services that the application consumes, one in New York and one in Singapore. Anyone know of a javascript framework that would allow the app to select the closest data center (In this case it would be Singapore)?
Onload of application get data centers lat lon in http rest call.
Get your current device lat lon position by Cordova geolocation or any other plugin
Use this algorithm to calculate distance in your device itself between all the list of data centers and device current location then shortlist the distance and pick shortest
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)
}
I am having trouble starting with this new feature that I have to implement on an application that I am working on. So the application works like this; A user inputs a point on the map by pressing a button and gets a latlng for source. Another modal opens and then they have to do the same for destination. What I want to do is to calculate the distance between two points and show a route on the map. I have been trying to find tutorials on this but have had no luck. Anyone knows how to do this or have any working example repo that I can have a look at it? Would be of great help. Thanks!
Have you seen this:
https://stackoverflow.com/a/27943/52160
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)
}
}
I am trying to work out the distance between a user and the coordinates below, I am not sure what I have done wrong, but I get the response 'NaN' (not a number)
HTML:
<h3>Come visit</h3>
<p>You're only <span class="distance"> </span>km away</p>
JS File:
// Location
if($('#content').hasClass('contact_page')) {
var localSearch = new GlocalSearch();
var sharp_hq = {
lat: 53.639993,
lng: -1.782354
};
// calculate the distance between me and thee
var calculate_distance = function(location) {
return Math.round(3959 * 1.609344
* Math.acos(Math.cos(0.0174532925 * location.y)
* Math.cos(0.0174532925 * sharp_hq.lat)
* Math.cos((0.0174532925 * sharp_hq.lng) - (location.x * 0.0174532925))
+ Math.sin(0.0174532925 * location.y)
* Math.sin(0.0174532925 * sharp_hq.lat)));
};
// geo location
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//display in .distance <span>
$('.distance', '.location').html(calculate_distance(initialLocation));
$('p', '.location').css({ display: 'block' });
});
}
}
this works for me;
$(document).ready(function(){
var sharp_hq = {
lat: 53.639993,
lng: -1.782354
};
// geo location
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
$('.distance').html( gc(position.coords.latitude,position.coords.longitude,sharp_hq.lat,sharp_hq.lng).toFixed(2) );
$('p', '.location').css({ display: 'block' });
});
}
} ) ;
/** Converts numeric degrees to radians */
if (typeof (Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function () {
return this * (Math.PI / 180);
}
};
function gc(lat1, lon1, lat2, lon2) {
// returns the distance in km between the pair of latitude and longitudes provided in decimal degrees
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;
}
A google.maps.LatLng object doesn't have .x or .y properties
Looks like you might still be expecting the Google Maps Javascript API v2 to work (it has been replaced by a wrapper for v3).
Instead of location.x/location.y use location.lat() for the latitude and location.lng() for the longitude. Or make your own anonymous object with .x and .y properties (but don't expect it to be interchangeable with a google.maps.LatLng object).
Note: the Google Maps Javascript API v3 has a library to calculate distance.
You can use a function called google.maps.geometry.computeDistanceBetween() that finds the distance between two latlng objects.
https://developers.google.com/maps/documentation/javascript/geometry
Replace the call to the calculate_distance function with
var distance = google.maps.geometry.spherical.computeDistanceBetween(
new google.maps.LatLng(sharp_hq.lat, sharphq.lng),
initialLocation
) / 1000;
$('.distance').text(distance);
Returns the distance in meters so divide by 1000.
In your formula, the value of (0.0174532925 * sharp_hq.lng) - (location.x * 0.0174532925) could be < 0 causing NaN.
You need to pre-process it to 0 if it is <0 to avoid the exception.
I wish this resolves your issue without changing the whole formula.
I am looking for a JavaScript function who returns the nearest neighbor of a number. e.g: I am having a coordinate 12,323432/12,234223 and i want to know the nearest coordinate of a set of 20 other coordinates in a database.
How to handle that?
The following 3 functions find the nearest coordinate from a javascript array using the Haversine formula.
function toRad(Value) {
/** Converts numeric degrees to radians */
return Value * Math.PI / 180;
}
function haversine(lat1,lat2,lng1,lng2){
rad = 6372.8; // for km Use 3961 for miles
deltaLat = toRad(lat2-lat1);
deltaLng = toRad(lng2-lng1);
lat1 = toRad(lat1);
lat2 = toRad(lat2);
a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + Math.sin(deltaLng/2) * Math.sin(deltaLng/2) * Math.cos(lat1) * Math.cos(lat2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return rad * c;
}
function calculate(){
var result = haversine(lat1,coordArray [0][0],lng1,coordArray [0][1]);
for (var i=1;i<coordArray.length;i++){
var ans = haversine(lat1,coordArray [i][0],lng1,coordArray [i][1]);
if (ans < result){//nearest
result = ans;
}
}
document.write("Result " +result);
}
Less rounding errors with the Vincenty formula
The Haversine formula suffers from rounding errors for the special (and somewhat unusual) case of antipodal points (on opposite ends of the sphere).
A better choice is therefore the Vincenty formula for the special case of a sphere. It is computationally not more demanding, but suffers less from machine rounding errors.
Here is my Python3 implementation, which runs in any browser using Brython or which one can easily manually transcode to JavaScript:
from math import radians, sin, cos, atan2, sqrt
def vincenty_sphere(lat1,lat2,lon1,lon2):
lat1 = radians(lat1)
lat2 = radians(lat2)
delta_lon = radians(lon2-lon1)
term1 = (cos(lat2) * sin(delta_lon))**2
term2 = (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon))**2
numerator = sqrt(term1 + term2)
denominator = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(delta_lon)
central_angle = atan2(numerator, denominator)
radius = 6372.8 # km
return radius * central_angle
def station_near(geo):
lat = geo['latitude']
lon = geo['longitude']
nearest = 40042.0 # km
for s in range(len(STATIONS)):
distance = vincenty_sphere(lat, STATIONS[s].lat, lon, STATIONS[s].lon)
if(distance < nearest):
nearest = distance
station = s
return station
Assume I have 3 locations namely Kallang(A), Paya Lebar(B) and Bedok(C). I try to do a A->B + B->C but the distance always return me A->C. Why is this so ??
kallang to paya lebar(A-B) -> 2.5914199062350742 km
paya lebar to bedok(B-C) -> 4.4403012109180775 km
total (A-B-C) -> 7.03 km
kallang to bedok (A-C) -> 6.88 km
below are my codes:
var R = 6371;
var dLat = toRad(location3.lat()-location2.lat()) + toRad(location2.lat()-location1.lat());
var dLon = toRad(location3.lng()-location2.lng()) + toRad(location2.lng()-location1.lng());
var dLat1 = toRad(location1.lat());
var dLat2 = toRad(location2.lat());
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(dLat1) * Math.cos(dLat1) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
document.getElementById("distance_direct").innerHTML = "<br/><br/><br/>The distance between the five points (in a straight line) is: "+d +" km.";
}
function toRad(deg)
{
return deg * Math.PI/180;
}
Is it something wrong with my adding and subtracting calculation statement ??? Thanks
You can just use the built in computeDistanceBetween method from the geometry library
Yep, the problem is with adding and substracting the same thing. Since toRad() is just a multiplication, it's associative respective to + and - and therefore
var dLat = toRad(location3.lat()-location2.lat())
+ toRad(location2.lat()-location1.lat());
is exactly the same as
var dLat = toRad(location3.lat()-location1.lat());
so you end up calculating the straight distance between the first and last point.
If you are using the Google Maps JavaScript API V3, you can just load the Geometry Library and do this:
var indirect_distance =
google.maps.geometry.spherical.computeDistanceBetween(location1, location2)
+ google.maps.geometry.spherical.computeDistanceBetween(location2, location3);