I get some GPS coordinates from Google Maps and I need to find the distance between them using Objective C. I have implemented the formula but I get results that are way to big.
I have tested the values from Google Maps by passing them back into Google Earth and a Geocoding service on the internet and everything checks out. Im now beginning to suspect that the cosine law demands I do some sort of conversion with the coordinates before I pass them in.
I did a similar implementation of the Haversine formula, but this also gave me to big results. I then switched to the cosine since it was easier to debug and I don't need very high precision.
Hope someone could shed a little light on this one, or use the code:)
- (CGFloat) calculateDistanceBetweenPoints:(CGPoint) origin andDestination:(CGPoint) destination {
//To convert kilometers to miles, divide by 1.609
// x = latitude
// y = longitude
/* example:
Dubai : 25.248665, 55.352917
Amsterdam : 52.309071, 4.763385
Approx dist: 5,182.62 KM
Calc. dist : 8,253.33
*/
CGFloat toRad = (M_PI / 180);
CGFloat R = 6371.0f; //earth's mean radius in Km
CGFloat sinePart = sinf( origin.x * toRad ) * sinf( destination.x * toRad );
CGFloat cosinePart = cosf( origin.x * toRad ) * cosf( destination.x * toRad );
CGFloat deltaCosinePart = cosf( ( destination.y - origin.y ) * toRad );
CGFloat delta = acosf( sinePart + cosinePart * deltaCosinePart) * R;
return delta;
}
Above calculated from links referenced here:stackoverflow question
There are a number of questions that might help, including:
Given the two positions, you create a spherical triangle corners A at Amsterdam, B at Dubai and C at the North Pole, with sides a = 90° - ϕAms, b = 90° - ϕDub, and angle C = Δλ = λDub - λAms. The required answer is the side c.
Using some material from my answer to SO 389211.
(This is a radically revised answer - my previous attempt used the wrong spherical triangle, and therefore got the wrong answer.)
ASCII art at its worst:
+ C (North Pole)
/|
b/ |
/ |
(Amsterdam) A + | a
\ |
c\ |
\|
+ B (Dubai)
The basic Cosine Law for Spherical Triangles is:
cos c = cos a . cos b + sin a . sin b . cos C
Noting that cos (90º - x) = sin x and sin (90º - x) = cos x, we can write:
cos c = sin ϕAms . sin ϕDub + cos ϕAms . cos ϕDub . cos Δλ
The angle c in radians is then converted to a distance by multiplying by the radius of the Earth.
Applying this to your data:
Dubai: ϕDub = 25.248665°N, λDub = 55.352917°E
Amsterdam: ϕAms = 52.309071°N, λAms = 4.763385°E
Δλ = 50.589532°
Working to 6 decimal places for the trigonometry:
cos c = 0.426548 × 0.791320 + 0.904465 × 0.611402 × 0.634872
= 0.337536 + 0.351079
= 0.688615
Whence:
c = 46.479426°
= 0.811219 radians
Multiplying this by 6371 km as the nominal radius of the earth yields
c = 5168 km
Hence, for R = 6371 km, the distance is 0.811219 × 6371 = 5168 km (to 4 s.f.).
TrueKnowledge says it should be about 5155 km. The positional data it says it used is comparable to the values you specified, and Wikipedia confirms the radius you provided. This is reasonably close - redoing the calculation with identical coordinates and more digits in the calculation would yield a better answer, but close to this one.
Have you considered using the method provided in CLLocation:
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With