PHP function to calculate bearing between latitudes and longitudes
I need to be able to calculate the bearing between two latitude and longitude pairs, in PHP. They are decimal degrees, and since we are in Australia, our points we are working with are negative latitude, positive longitude. eg. -29.54546 Latitude and 149.68756 longitude.
I have tried this:
$bearingradians = atan2(asin($long1-$long2)*cos($lat2),
cos($lat1)*sin($lat2) - sin($lat1)*cos($lat2)*cos($long1-$long2));
$bearingdegrees = rad2deg($bearing);
This seems to work, but on closer inspection, it gets east and west mixed up! ie: When I know that a point should be west of a certain point, it comes up with say, 88degrees, which is obviously east! I am putting the lats and longs around the right way, so thats not the problem. I am trying to make a function which will take the four numbers and spit out the bearing between them, like this:
Just a note: The function I wrote takes values that are the coordinates of the longitude and latitude pairs. The bearing angle is the angle on the plane that is tangent to the surface of the earth, assuming the two point are close enough. Computing the angle bearing relative to the center of the earth would involve a little more.
Cheers.
Long
0
The revolutionary project management tool is here! Plan visually with a single glance and make sure your projects get done.
#test the function
// Grafton NSW
$lat1 = -29.6844;
$long1 = 152.9325;
//Coffs Harbour NSW, about 170 degrees from grafton
$lat2 = -30.31319;
$long2 = 153.13753;
echo "The bearing from Grafton to Coffs Harbour is ".getbearing($long1,$lat1,$long2,$lat2);
-------------------------------------------------------------------------------------------------------------
This returns -0.212214774169, which is wrong.... Should be about 170 or so. Can you see anything wrong?
Jeez we're close now, worked perfectly for grafton to Coffs Harbour, but then was -108.95732909deg for Grafton to Armidale, which should be 233.2deg.
So you can check:
Grafton -29.6844,152.9325
Coffs Harbour -30.31319,153.13753 (should be 164deg from Grafton, we got 164)
Armidale -30.51194,151.6675 (Should be 233deg from Grafton, we got -109)
Ballina -28.87398,153.56237 (Should be 34deg from Grafton, we got 34)
Tenterfield -29.05639, 152.01806 (should be 309deg, we got -60)
Looks like westerly directions are out.... if I add 360 degrees to them to get a positive value it is still out by a fair way...
You are good at this, what have we missed?
Adding 360 is the correct way to get the number rightly orientated. But since the numbers are still out, I can't think of any otherway. I compute this purely on mathematically point of view, that is, assuming the earth is perfectly round, and angle are measured as though you are standing to the origin, which is Grafton, of the x-y coordinate.
Where do you get the measurements from?
The reason I am asking is that the formula I used is based on the tangent plane that touch the earth the origin where the angle is located. If your measure is on the flat map, the angle might not come out accurate. If you get your data out of a table, can you tell me where the source is? If I can understand what the data you have really meant what they meant.
Coffs Harbour:
x2-x1=-0.62879
y2-y1=0.20502999999999
The bearing from Grafton to Coffs Harbour: 164.04275769504
Armidale:
x2-x1=-0.82754
y2-y1=-1.265
The bearing from Grafton to Armidale: 251.04267091014 [233]
Ballina:
x2-x1=0.81042
y2-y1=0.62986999999998
The bearing from Grafton to Ballina: 34.734391266122
Tenderfield:
x2-x1=0.62801
y2-y1=-0.91444000000001
The bearing from Grafton to Tenderfield: 299.21742521454 [309]
You can see that the larger the change in the latitude in the negative direction (more south), the worse it appears in the difference between your data and the formula results.
I think this is a matter of practical values, and theoretical values.
If you want to dig more into this, just let me know.
1. function bearing($lat1, $long1, $lat2, $long2){
2. $bearingradians = atan2(asin($long1-$long2)*
3. cos($lat1)*sin($lat2) - sin($lat1)*cos($lat2)*cos(
4. $bearingdegrees = rad2deg($bearing);
5. return $bearingdegrees
6. }
On line 3, the first term and second term are not of the same unit. You cannot do subtraction between the two term.
If you can tell me how you derive this formular, you can help you right away.