I'm testing out different formulas for finding specific points on the earth within a given radius from a given latitude/longitude. I've been using the 'spherical law of cosines' and what I believe to be an implementation of Haversine.
For the following formulas, these are the variables:
[$lat/$lon] = point of origin
[latitude/longitude] = second point
[$radius] = radius
Spherical law of cosines
3959 * acos( cos( radians('.$lat.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$lon.') ) + sin( radians('.$lat.') ) * sin( radians( latitude ) ) ) ) <= '.$radius.';
Haversine (at least I think it is!)
3959*3.1415926*sqrt((latitude-'.$lat.')*(latitude-'.$lat.') + cos(latitude/57.29578)*cos('.$lat.'/57.29578)*(longitude-'.$lon.')*(longitude-'.$lon.'))/180) <= '.$radius.';';
I initially came across a lot of information saying that Haversine was the gold standard as far as accuracy. However, there also seems to be an opinion that the spherical law of cosines is more accurate than Haversine, as long as the distance being measured is greater than 5 metres or so. Furthermore, some say that Vincenty is said to trump both in accuracy.
Three questions:
Is my Haversine formula actually Haversine or it something else?
Any thoughts on which wins out for most accurate?
Can anyone provide me with a formulation for Vincenty along the lines of the above forumlas?
thanks!
Your so-called Haversine formula is totally incorrect.
Firstly it contains 7 left parentheses and 8 right parentheses.
Secondly conversion from degrees to radians is done in some cases by dividing by 57.29578 then there's a constant pi up the front and a constant 180 down the back.
Thirdly haversine(x) = sin(x / 2) ** 2 and I don't see the / 2 anywhere.
Fourthly there should be an asin function call near the front.
Correct formula here
My answer will be more Specific for your first and second answer
Q1: Is my Haversine formula actually Haversine or it something else?
I Don not understand Your haversine formula you made it
The write one or exactly the SQl query for haversine Formula is that
From Google Developer Site Click Here For Details
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
This SQL statement that will find the closest 20 locations that are within a radius of 25 miles to the 37, -122 coordinate. It calculates the distance based on the latitude/longitude of that row and the target latitude/longitude, and then asks for only rows where the distance value is less than 25, orders the whole query by distance, and limits it to 20 results. To search by kilometers instead of miles, replace 3959 with 6371.
You can make your Changes for this SQL query To be exactly What you want to.
Q2: Any thoughts on which wins out for most accurate?
There is no final answer for who can win?!, But we can deal with that:
1.Haversine is More Faster.
2.Spherical law of cosines is more accurate for Small distances.
And About Q3 I Know that the vincenty Formula is the most accurate But it is the slowest One
Related
I am trying to calculate distance between two geographical coordinates and I want to convert geographical coordinates to the km. Therefore I used deg2km function. However, I realise that it is not convert points properly.
For instance, I used these two points.
p_x=[5; 10]; %degree
p_y=[8; 16]; %degree
pos_y=deg2km(p_y,6378);
pos_x=deg2km(p_x,6378);
It returns as:
pos_x= [556.58549846099 1113.17099692198]
pos_y= [890.536797537587 1781.07359507517]
When I calculate distance ( sqrt((556.5-1113.2)^2+(890.5368-1781.1)^2) ) between these points I obtained distance as : 1050.2464
However I checked it google map and also other websites it should be 1042 km.
Do you have any suggestion to calculate distance and also points as kilometers properly?
Thanks in advance!
edited as :
I've points(deg)and I need to convert them km and calculate distance between points.
LAT=[41.000173;41.010134]*pi/180;
LON=[28.995882;28.995584]*pi/180;
I used this code to calculate distance. It calculates properly.
But I can not convert my points to kilometers.
LAT=[41.000173;41.010134]*pi/180;
LON=[28.995882;28.995584]*pi/180;
R=6378; %km
for i=1:length(LAT)-1
psi(i,1) = atan2( sin (LON(i+1)-LON(i)) * cos (LAT(i+1)) , cos (LAT(i)) *sin (LAT(i+1)) - sin (LAT(i)) * cos (LAT(i+1)) * cos (LON(i+1)-LON(i)) );
a=(sin((LAT(i+1)-LAT(i))/2))^2+cos(LAT(i))*cos(LAT(i+1))*(sin((LON(i+1)-LON(i))/2))^2;
c=2*atan2(sqrt(a),sqrt(1-a));
d(i,1)=R*c;
end
I am new to Power BI and DAX, so I hope you can help me.
I have two tables without any relationship:
Table A contains lat/lng and date of tracked positions.
Table B contains lat/lng and names of all stadiums.
I want to find the closest stadium near the tracked position. Also if possible I want to validate, if the position was in a specific radius of that stadium.
Any help greatly appreciated.
Here's one possible approach:
First, calculate the minimal distance using the Haversine function.
Add this as a calculated column to your Tracked table.
Nearest =
MINX(Stadiums,
ROUND(2 * 3959 *
ASIN(SQRT(
SIN((Stadiums[Lat] - Tracked[Lat]) * PI()/360)^2 +
COS(Tracked[Lat] * PI()/180) * COS(Stadiums[Lat] * PI()/180) *
SIN((Stadiums[Lon] - Tracked[Lon]) * PI()/360)^2)), 1))
In this formula, 3959 is the radius of the Earth in miles.
We can now match up distances to find the nearest stadium:
Stadium = CALCULATE(MAX(Stadiums[Stadium]),
FILTER(Stadiums,
ROUND(2 * 3959 *
ASIN(SQRT(
SIN((Stadiums[Lat] - Tracked[Lat]) * PI()/360)^2 +
COS(Tracked[Lat] * PI()/180) * COS(Stadiums[Lat] * PI()/180) *
SIN((Stadiums[Lon] - Tracked[Lon]) * PI()/360)^2)), 1)
= Tracked[Nearest]))
Note: I rounded the values to avoid not matching from possible floating point errors. This may or may not be necessary.
So, I need to calculate distances betweeen two points (lat-lon pairs). I've read about Haversine formula and Equirectangular approximation in Movable Type Scripts.
Since I only want to calculate short distances (less than 4 KM), is the Equirectangular formula a good approximation?
Also, I've read about lat-lon storage in MySQL databases in Google Developers documentation and they implement the Haversine formula like this:
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
My last question is, is there any big performance differences between filtering the points in the sql query (as in the example) and filtering them by code?.
When I tested haversine v equirectangular over much larger distances (1000km, within the UK), the difference was on the order of 0.1%. So for distances of 4km or less you might as well use equirectangular for speed unless you have a need for maximum accuracy.
I have 2 coordinates and would like to do something seemingly straightforward. I want to figure out, given:
1) Coordinate A
2) Course provided by Core Location
3) Coordinate B
the following:
1) Distance between A and B (can currently be done using distanceFromLocation) so ok on that one.
2) The course that should be taken to get from A to B (different from course currently traveling)
Is there a simple way to accomplish this, any third party or built in API?
Apple doesn't seem to provide this but I could be wrong.
Thanks,
~Arash
EDIT:
Thanks for the fast responses, I believe there may have been some confusion, I am looking to get the course (bearing from point a to point b in degrees so that 0 degrees = north, 90 degrees = east, similar to the course value return by CLLocation. Not trying to compute actual turn by turn directions.
I have some code on github that does that. Take a look at headingInRadians here. It is based on the Spherical Law of Cosines. I derived the code from the algorithm on this page.
/*-------------------------------------------------------------------------
* Given two lat/lon points on earth, calculates the heading
* from lat1/lon1 to lat2/lon2.
*
* lat/lon params in radians
* result in radians
*-------------------------------------------------------------------------*/
double headingInRadians(double lat1, double lon1, double lat2, double lon2)
{
//-------------------------------------------------------------------------
// Algorithm found at http://www.movable-type.co.uk/scripts/latlong.html
//
// Spherical Law of Cosines
//
// Formula: θ = atan2( sin(Δlong) * cos(lat2),
// cos(lat1) * sin(lat2) − sin(lat1) * cos(lat2) * cos(Δlong) )
// JavaScript:
//
// 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 brng = Math.atan2(y, x).toDeg();
//-------------------------------------------------------------------------
double dLon = lon2 - lon1;
double y = sin(dLon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
return atan2(y, x);
}
See How to get angle between two POI?
Depending on how much work you want to put in this one, I would suggest looking at Tree Traversal Algorithms (check the column on the right), things like A* alpha star, that you can use to find your find from one point to another, even if obstacles are in-between.
If I understand you correctly, you have the current location and you have some other location. You want to find the distance (as the crow flies) between the two points, and to find a walking path between the points.
To answer your first question, distanceFromLocation will find the distance across the earth's surface between 2 points, that is it follows the curvature of the earth, but it will give you the distance as the crow flies. So I think you're right about that.
The second question is a much harder. What you want to do is something called path-finding. Path finding, require's not only a search algorithm that will decide on the path, but you also need data about the possible paths. That is to say, if you want to find a path through the streets, the computer has to know how the streets are connected to each other. Furthermore, if you're trying to make a pathfinder that takes account for traffic and the time differences between taking two different possible paths, you will need a whole lot more data. It is for this reason that we usually leave these kinds of tasks up to big companies, with lots of resources, like Google, and Yahoo.
However, If you're still interested in doing it, check this out
http://www.youtube.com/watch?v=DoamZwkEDK0
I just trying know how to implement in objective c an equation that gave my position in lat, long and the position of a point in lat,long returns the relative angle to the azimuth so I will be able to know when to paint this point knowing the azimuth. I also know more or less the equation but I don´t know how to do it in objective c:
b = arccos ( cos (90 - lat2) * cos (90 - lat1) + sin (90 - lat2) * sin (90 - lat1) * cos (lon2 - lon1) )
A = arcsin ( sin (90 - lat2) * sin (lon2 - lon1) / sin (b) )
Regarding turning that equation into Objecive-C.
'man cos' and 'man sin' say they take radians, so you'll have to convert your degree values to radians. The common method seems to be this, (90 * M_PI/180), where 90 is the degree value being converted.
The functions for arccos and arcsin are acos and asin respectively. I assume they to take radians. Their man pages don't explicitly say.
Read the man pages to learn which version of the above functions are appropriate for your case. For instance, sin has; sin(), sinl(), sinf().