I have mysql query to calculate distance between given longitudes and latitude within 50 meter radius. Here I want to know that by performance, speed and distance accuracy wise which one is better, haversine or pythagorean?
Related
Given two lat, lng points that I know that the distance between those is maximum 10KM, do I have to use haversine formula to calculate the distance between the points or is there a simpler way (assume earth is flat) that would get me to almost the same result but in better performance?
Are you just "calculating" distance of a few items? Or are you "searching for all within 10km? There is a huge difference.
The latter is really an algorithm problem of how to shoehorn a 2D problem into a 1D indexing mechanism.
Plan A: No relevant index -- must check all rows.
Plan B: INDEX(lat), INDEX(lng) and use a "bounding box": WHERE lat BETWEEN... AND lng BETWEEN... -- The optimizer will pick one or the other index.
Plan C: If you have millions of rows, say so; there is a faster (but more complex) way.
I have not answered your question because it is the least important part of the algorithm. But I will answer it now.
Haversine takes about twice as long as flat-earth plus Pythagoras. But that is just for the computation; fetching the rows is far more significant in the processing.
Haversine is not necessary for such a small distance. I think it even works 'correctly' when crossing the dateline or a pole. I suspect flat-earth has trouble at those edge cases.
With flat-earth, be sure to divide longitude difference by COS(RADIANS(deg)). (1 degree longitude is half as far in Helsinki (at 60deg latitude) as at the Equator.)
Which is better for calculating the distance between two latitude/longitude points, The Haversine Formula or The Vincenty's Formula? Why?
The distance is obviously being calculated on Earth. Does WGS84 vs GCJ02 coordinates impact the calculation or distance (The Vincenty's formula takes the WGS84 axis into consideration)?
For example, in Android, the Haversine Formula is used in Google Map Utils, but the Vincenty Formula is used by the android.Location object (Location.distanceBetween()).
Haversine and Vincenty are two algorithms for solving different
problems. Haversine computes the great circle distance on a sphere
while Vincenty computes the shortest (geodesic) distance on the surface of an
ellipsoid of revolution. So the answer to your question can be broken
into 2 parts:
Do you want to compute the distance on a sphere on an ellipsoid?
How accurate is Haversine or Vincenty at calculating the given problem?
For terrestrial applications, an ellipsoid of revolution is a reasonable
approximation to "mean sea level"; the error is ± 100 m. The
flattening of this ellipsoid is small, about 1/300, and so can be
approximated by a sphere (of equal volume, for example).
Great circle distances differ from geodesic distances by up to 0.5%. In
some applications, e.g., what's the distance from the Cape to Cairo?,
this error can be neglected. In other applications, e.g., determining
maritime boundaries, it is far too large (it's 5 m over a distance of 1
km). In general, you're safer using the geodesic distance.
If you're interested is distance traveled (by car, boat, or plane),
there are lots of constraints on the path taken and neither the great
circle or geodesic distance, which measure the length of shortest paths
on an ideal surface, would be appropriate.
On the question of whether the algorithms are accurate:
Haversine is accurate to round-off unless the points are nearly
antipodal. Better formulas are given in the
Wikipedia article on great-circle distances.
Vincenty is usually accurate to about 0.1 mm. However if the points are
nearly antipodal, the algorithm fails to converge and the error is
much larger. I give a better algorithm for solving the geodesic problem
in Algorithms for geodesics. See also the
Wikipedia article on geodesics on an ellipsoid.
Solving the geodesic problem is slower than solving for the
great-circle. But it's still very fast (about 1 μs per calculation), so
this shouldn't be a reason to prefer great circle distances.
ADENDUM
Here is the Java package which implements my algorithm
for finding geodesic distances. Unlike Vincenty's method, this is accurate
to round-off and converges everywhere.
Haversine is a simpler computation but it does not provide the high accuracy Vincenty offers.
Vincenty is more accurate but is also more computationally intensive and will therefore perform slower and increase battery usage.
As with anything "better" is a matter of your particular application. For your application, Vincenty may be a "better" choice than Haversine, but for a different application, Haversine may be a better choice. You will have to look at the particulars of your use cases and make a determination based upon what you find there.
I've got courier tracking android app, which posts every 30s gps coords of the courier to a postgis database.
We need to calculate how many kilometers couriers do in order to provide them gas(petrol) refund.
How would you do that, fellow developers?
Sum the great-circle distances between consecutive measurement points to get an approximation (lower bound actually) for the distance traveled.
You can probably also get away (and get better numerical stability) with calculating the 3D ECEF positions from the spherical coordinates and summing the Euclidean distances between these points because it's pretty much impossible to cover a significant curvature on Earth in 30 seconds.
I need some help, I've never done my own SQL search before and I'm trying to do this:
I have a database of names and locations (the locations are listed with a Latitude record and a Longitude record). Then, a user can search by entering their zip code (which is converted to longitude and latitude) and a distance they're willing to travel (in miles, which I can convert to lon/lat distance).
How can I return the results ordered by the distance away from their ZipCode?
Please keep in mind, I haven't ever done anything like this before.
There's a mathematical formula for figuring the shortest distance between two points on a sphere. The formula and a JS implementation of it are here:
http://www.movable-type.co.uk/scripts/latlong.html
A T-SQL implementation is here:
http://weblogs.asp.net/jimjackson/archive/2009/02/13/calculating-distances-between-latitude-and-longitude-t-sql-haversine.aspx
I would like to store thousands of latitude/longitude points in a MySQL db. I was successful at setting up the tables and adding the data using the geospatial extensions where the column 'coord' is a Point(lat, lng).
Problem:
I want to quickly find the 'N' closest entries to latitude 'X' degrees and longitude 'Y' degrees. Since the Distance() function has not yet been implemented, I used GLength() function to calculate the distance between (X,Y) and each of the entries, sorting by ascending distance, and limiting to 'N' results. The problem is that this is not calculating shortest distance with spherical geometry. Which means if Y = 179.9 degrees, the list of closest entries will only include longitudes of starting at 179.9 and decreasing even though closer entries exist with longitudes increasing from -179.9.
How does one typically handle the discontinuity in longitude when working with spherical geometries in databases? There has to be an easy solution to this, but I must just be searching for the wrong thing because I have not found anything helpful.
Should I just forget the GLength() function and create my own function for calculating angular separation? If I do this, will it still be fast and take advantage of the geospatial extensions?
Thanks!
josh
UPDATE:
This is exactly what I am describing above. However, it is only for SQL Server. Apparently SQL Server has a Geometry and Geography datatypes. The geography does exactly what I need. Is there something similar in MySQL?
How does one typically handle the discontinuity in longitude when working with spherical geometries in databases?
Not many people use MySQL for this, because it's geospatial extensions aren't really up to snuff.
From the docs:
"All calculations are done assuming Euclidean (planar) geometry."
The solution is usually to roll your own.
Alternatively, you can fake it -- if your distances are less than a 500 miles or so, then you can treat your latitude and longitude as rectangular coordinates and just use the euclidean distance formula (sqrt(a^2 + b^2)).