Calculate distance for multiple locations google map - javascript

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

Related

Calculating distance between two points in Google Maps for Ionic 2

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

Which one of these azimuth values is the right one? And why?

First of all, let's make clear that I want the Azimuth on the surface of the Earth, i.e. the angle between two locations, for example New York and Moscow.
I am testing some azimuth calculations with my JS functions (shown below). For the points A(-170, -89) to B(10, 89), I get ~90º.
JS function for Azimuth on sphere (from Wikipedia)
var dLon = lon2 - lon1;
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
var angle = Math.atan2(y, x) * 180 / Math.PI;
JS function for Azimuth on oblate spheroid (from Wikipedia)
var dLon = lon2 - lon1;
var f = 1 / 298.257223563; /* Flattening for WGS 84 */
var b = (1 - f) * (1 - f);
var tanLat2 = Math.tan(lat2);
var y = Math.sin(dLon);
var x;
if (lat1 === 0) {
var x = b * tanLat2;
} else {
var a = f * (2 - f);
var tanLat1 = Math.tan(lat1);
var c = 1 + b * tanLat2 * tanLat2;
var d = 1 + b * tanLat1 * tanLat1;
var t = b * Math.tan(lat2) / Math.tan(lat1) + a * Math.sqrt(c / d);
var x = (t - Math.cos(dLon)) * Math.sin(lat1);
}
var angle = Math.atan2(y, x) * 180 / Math.PI;
In Calculator 2, I get 90º.
In PostGIS, I get 270º
In Calculator 1, I get 180º.
I know the Azimuth gets more and more distorted near the Poles, but that's exactly why I am testing at these spots. This variety of different solutions are confusing me. Could you please help me getting the right answer for this?
It depends on the reference used for azimuth, e.g. map-types use 0° for North and positive is clockwise, while math-types uses 0° for East and positive is anticlockwise.
The pair of coordinates A(-170, -89) and B(10, 89) are antipodes which are a special case for finding minimum distances and azimuths. Your question can be answered with a thought exercise.
First note that the half-circumferences of the earth are:
Equatorial: 20037.5085 km
Meridional (north-to-south): 20003.93 km
For a pair of antipodes on the north and south poles, there are an infinite number of azimuths, since the distance is the same along each longitude. (What direction would you go from the south pole to the north pole?)
For a pair of antipodes on the equator, the shortest distances are north or south, since it is slightly shorter along the meridional direction.
For any other pair of antipodes, it is the same answer as from the equator: north or south.
Update
To investigate the problem a bit more with the PostGIS SQL query:
SELECT ST_Distance(A, B), degrees(ST_Azimuth(A, B))
FROM (
SELECT 'POINT(-170 -89)'::geography A, 'POINT(10 89)'::geography B
) f;
With PostGIS 2.0 and 2.1, the incorrect results are:
st_distance | degrees
-----------------+------------------
20003900.583699 | 270.005278779849
But with PostGIS 2.2 (and PROJ 4.9.1), the correct results are now:
st_distance | degrees
------------------+---------
20003931.4586255 | 180

Calculation between “my current geolocation” and other coordinates

How can I calculate the distance between “my current geolocation” (the coordinate I get using navigator.geolocation.watchPosition) and say 10 others (fixed) coordinates simultaneously?
I want to track the distance so if “my current geolocation” get within a specific radius of one the coordinates ==> something amazing happens.
Can I solve this problem using the Haversine Distance Formula?
All the calculations will be within a smaller area (a city) so I need to get the results in meters rather than kilometers.
Thank you for your time and input !
/a.
At the equator 5 decimal places in your coordinate(0.00001) = 1.1057 meters Latidude &1.1132 meters Longitude.
As the coordinates move from the equator to the poles the Longitude value decreases.
Degree| Latidude | Longitude
------------------------------
0° | 1.1057 m |1.1132 m
15° | 1.1064 m |1.0755 m
30° | 1.1085 m |0.9648 m
45° | 1.1113 m |0.7884 m
60° | 1.1141 m |0.5580 m
75° | 1.1161 m |0.2890 m
90° | 1.1169 m |0.0000 m
If your distances are small you can either use Pythagoras with correction for latidude or use Haversine.
The following code uses Haversine
var lat1 =55.00001;//Point 1 nearest
var lng1 =-2.00001 ;
//var lat1 =55.00002;//Point 2 nearest
//var lng1 =-2.00002 ;
//Array of points
var coordArray = [[55.00000,-2.00000],[55.00003,-2.00003],[55.00006,-2.00006],[55.00009,-2.00009],[55.00012,-2.00012]];
function toRad(Value) {
/** Converts numeric degrees to radians */
return Value * Math.PI / 180;
}
function Round(Number, DecimalPlaces) {
return Math.round(parseFloat(Number) * Math.pow(10, DecimalPlaces)) / Math.pow(10, DecimalPlaces);
}
function haversine(lat1,lat2,lng1,lng2){
rad = 6371000; // meters
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]);
var index = 0;
for (var i=1;i<coordArray.length;i++){
var ans = haversine(lat1,coordArray [i][0],lng1,coordArray [i][1]);
if (ans < result){
result = ans;
index++;
}
}
document.write("Result = " +Round(result,2)+ " Meters Point = "+ (index+1));
}
See Fiddle
The harvesine formula is just a special formula. But it works for your question. If you want better result you can try the vincenty formula. It uses an ellipsoid earth. Just loop over every point and compute the distance from it.

JavaScript function nearest geographical neighbor

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

How to find my distance to a known location in JavaScript

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

Categories