Note: The exercise files are free to all members. The code is commented to enhance your learning, but you will need database connectivity for some files to run as intended.
Skill Level Intermediate
- [David Powers] Hi, I'm David Powers, and welcome to this week's edition of PHP tips, tricks, and techniques designed to help you become a smarter, more productive PHP developer. This week's technique is finding the shortest distance between two locations. If you're wondering, why bother, there are several really practical applications for this technique on the web. You could use it to show users the closest delivery point to drop off or pick up packages. Or how about the closest pizza store? And I've used it to develop an app to find parking lots within a given radius.
Hopefully, that's whetted your appetite. So how do we go about it? As satellite technology and space travel have confirmed, the Earth is round, not perfectly so, but close enough. And as you probably know, drawing a straight line between two locations isn't the shortest route. To get the shortest distance, you need to follow the curvature of the Earth, and that's where some pretty horrendous calculations come in. There are several formulas you can use.
This is the one that I've chosen. It uses the spherical law of cosines. Now unless you're an expert with trigonometry, just looking at this is likely to send shivers down your spine. Certainly does for me. The good news is that PHP can take this type of calculation in its stride. In this formula, phi stands for latitude and theta stands for longitude. The delta means the difference between two values. So we multiply the sine of both latitudes, and add it to the cosine of both latitudes, multiply it by the cosine of the difference between the longitudes.
Get the arccosine of that calculation and multiply it by R, the radius of the Earth. So let's switch to my editing program to see how that translates into PHP code. In this script, which you can find in the exercise files for this video, I've defined a function called getDistance. It takes up to four arguments. The first two are required. They're both arrays containing the coordinates, the latitude and longitude of two locations.
The third argument, precision, has been set by default to zero. This will round the result to the closest number of miles or kilometers. The fourth argument, useMiles, has been set by default to true. If you want the result in kilometers, set this to false. Line four sets the value of radius to the Earth's approximate radius in miles or kilometers depending on the value of useMiles. Latitude and longitude are normally expressed as degrees, but the formula for calculating the distance needs them expressed as radians.
Now a radian is 180 degrees divided by pi, but we don't need to worry about the conversion formula because PHP has a convenient built-in function, this one deg2rad, that does the calculation for us. So lines six and seven extract the first elements of the coordinates of each location. In other words, the latitude and convert it to radians. Then on line nine, we get the difference between the two longitudes by subtracting one from the other and converting the result to radians.
Line 11 calculates the distance using the formula for the spherical law of cosines. And PHP has built-in functions for arccosine, sine, and cosine using the standard mathematical abbreviations. The result is likely to have a long, trailing decimal fraction so it's passed to the round function using precision as the second argument before we return the result. That completes the function definition.
To test it, I've stored the coordinates of several locations as arrays. The first two down here are for New York and Los Angeles. So let's try it out. So we'll echo then getDistance, and pass it New York, then LA. We don't need any of the other arguments. I'll use the precision of zero, the default, and use miles. So we need to concatenate onto the end of that miles.
So if we save that, and run this script by loading it into a browser, there's the result, 2,450 miles. Well let's see how accurate that is. I've got this other website here, which gives the distance from New York, U.S.A. to Los Angeles as 2,446.32 miles. That's pretty good, a difference of less than four miles on such a large distance. They're both big cities, so it depends where you're measuring from anyway.
But as I mentioned at the beginning, a practical use of this sort of calculation is more local. So let's go back to my editing program, and here I've got the coordinates for Trafalgar Square in London and for Buckingham Palace. And we can easily verify the distance between them 'cause it's just a straight walk or drive down The Mall. And they're not all that far apart, so we're going to need to set the precision to several decimal places. So let's just change New York to Trafalgar Square, and then other one to the Palace.
And then we'll have the third argument, set it to two decimal places. I'm gonna use miles again, so I'll just save that, go back to my browser, and refresh, and it tells me the distance is 0.79 miles. So let's see what Google Maps tells us. I've already got the map up here, from Trafalgar Square in London to Buckingham Palace and via The Mall, the direct route 0.8 miles.
There it is, you're walking down The Mall, straight from Trafalgar Square to Buckingham Palace, 0.8 miles. I think I'm pretty spot on with 0.79. So there you have a handy function to calculate the shortest distance between two locations. Just pass it the coordinates of each location as an array of the latitude and longitude. There are many resources on the web to get the coordinates of a location, just use your favorite search engine to find the latitude and longitude of an address.
I hope you found that useful. Until next time, this is David Powers saying, thanks for watching PHP tips, tricks, and techniques.