2017년 7월 18일 화요일

Finding distance between 2 coordinates - Haversine implementation


I'm writing a simple app to (amongst other things) show the distance between two GPS points.  This distance will typically be under 500m (locating a downed quadcopter), and I'm trying to implement the Haversine formula.  I've read through all of the previous mentions of this but haven't found the answer.

I'm using the formula here:
http://rosettacode.org/wiki/Haversine_formula#Python
Python version:
def haversine(lat1, lon1, lat2, lon2):
  R = 6372.8 # Earth radius in kilometers
  dLat = radians(lat2 - lat1)
  dLon = radians(lon2 - lon1)
  lat1 = radians(lat1)
  lat2 = radians(lat2)
  a = sin(dLat/2)**2 + cos(lat1)*cos(lat2)*sin(dLon/2)**2
  c = 2*asin(sqrt(a))
  return R * c
>>> haversine(36.12, -86.67, 33.94, -118.40)
2887.2599506071106


I convert the coordinates to radians before passing these values to the attached blocks, and as far as I can see, it's working ok until it gets to the lines calculating a,b,c.
(I split it up in order to try and trace the steps).  However, the values returned are nowhere near the example above, or other distances calculated (say) on google maps.
Can anyone see where I've gone wrong? 

--
you could compare your formula with the formula here http://www.movable-type.co.uk/scripts/latlong.html
also you can easily test the calculation on that page...

btw. an example of the bearing formula you can find here 

--
Using your own data
Note, this 2886 km compares favorably with the 2887 kilometers you posted using the online calculator Taifun mentioned    http://www.movable-type.co.uk/scripts/latlong.html
Your alogrithm appears to be working but the distance is LARGE.


Haversine is for SHORT distances.  To calculate distances like this (1793 miles if you convert); you should use a
Great Circle algorithm  or Vincenty's Algorithm.  

What distances are your other sources reporting?

Here is a Haversine calculation over a short distance with values to compare.... how does your algorithm compare?
--
Hi, thanks for the responses.

I tried my effort with the calculation of a short distance (which is its intended purpose) and got a result of 0.69435km, instead of 0.549 as seen in Steve's example.  Close - but no cigar, as I want this app to get me within around 25m of a downed quadcopter - at which point I'd be able to hear the beeper.

I was hoping that somebody might be able to spot an error in my implementation of the formula in my first post - I'm pretty certain that this formula is correct, and, if my coding of it accurate, should give closer results.  Either my replication in AI of the formula is still not quite right, or AI has some calculation issues...?

Thanks for the tip about bearing...however, my phone has no compass and therefore won't be able to provide azimuth - but I've got a workaround for that.

Thanks again - if I do manage to get it working correctly, I'll post the solution.

--
Hmmm.   Use an Earth's radius of 6363 instead of 6372.8  ..... see  http://andrew.hedges.name/experiments/haversine/  

Also, be aware, the LocationSensor has a property called Accuracy... read about it here http://appinventor.mit.edu/explore/ai2/location-sensor.html   The GPS receiver on the phone is never going to get you within 2 meters of where it says it is except occasionally.   The GPS can be off as much as 50 meters easily based on a single reading depending on......

Your Haversine code looks OK David (however my eyes just can not render those blocks any more and it is not clear what code you use in lat2rad or lon2rad.)

Try to calculate again with a skinnier Earth.  The Earth is not round, it is a geoid and generally an elllipsoid so the diameter of the Earth to use depends on your latitude... are you close to 39 degrees? or somewhere else   33 or 36?

You could calibrate your algorithm Earth radius by  measuring a distance on your side walk ... say 100 meters.  Note the start, note the end point using the GPS.  Note the start point coordinates, when you get to the 100 meter point, do your calculation.  If the answer is not 100, well, do what a guy's gotta' do.
Edit... OK I found this...

--
I think that I might have to try a different approach, and look into adapting the 'where's my car' tutorial.  I'd hoped to avoid the use of a data connection for google maps, but my current approach doesn't seem to be working and I'm short on time.  Meh, I hate it when I can't see where a problem lies...
I'm at about 53 degrees latitude btw (N.Wales, UK).

--
Finally cracked it.  The problem was that in all of my previous programming, the trig functions expected angles to be expressed in radians, whereas AI2 requires degrees.  By using the conversion functions, I've now got it working quite well, comparing the results against those from online calculators.  The attached snapshot shows the blocks of the calculation procedure, note that the coordinates have been converted to radians beforehand.  Also, the variable 'global b' is calculated in several steps because it's the only way that I could get the snapshot!


--

댓글 없음:

댓글 쓰기