Keep It Simple, Stupid PerlMonks

Finding the Distance between longitude and latitude pairs

by cacharbe (Curate)
 on Mar 07, 2002 at 16:37 UTC Need Help??
 Category: Miscellaneous Author/Contact Info Chuck Charbeneau (cacharbe) ccharbeneau@lear.com Description: A while back my younger sister asked me to help her with homework from her college trig course. She had to solve a Great Circle Distance problem. After showing her the steps, it got me to thinking, and then reading, and then finally coding. What I found was quite interesting, and from that research spawned an application to find the distances between to corporate locations from their zip codes that I implemented on our intranet. There are actually a couple of different methods for determining the distance between 2 long/lat pairs and you need to be aware of the accuracy of each. The Great Circle method is the least accurate IIRC, but is the most accessible, as it is a part of Math::Trig. I wrote some code to do this using the various methods. As I mentioned, it finds the distances between two zip codes for which the long/lat pairs are known, but I've removed the database interface for brevity and just given the pertinent code. You should also read: this, this and (my favorite) this article. I was pretty explicit in my code so that my non-programming sister could understand it when I showed it too her to explain the different algorithms, but I think it gets the point across. C-. ```use strict; use Math::Trig qw(deg2rad pi great_circle_distance asin acos); ############################ ## Distances are in Miles ## ############################ my (\$lat1, \$long1); my (\$lat2, \$long2); print "Haversine : ". &Haversine(\$lat1, \$long1, \$lat2, \$long2) ."\n" +; print "Law Cosines : ". &LawCosines(\$lat1, \$long1, \$lat2, \$long2)."\n" +; print "Flat-Earth : ". &FlatEarth(\$lat1, \$long1, \$lat2, \$long2) ."\n" +; print "Great Circle: ". &GreatCircle(\$lat1, \$long1, \$lat2, \$long2)."\n +"; sub LawCosines { my (\$lat1, \$long1, \$lat2, \$long2) = @_; my \$r=3956; my \$dist = acos(sin(deg2rad(\$lat1))* sin(deg2rad(\$lat2))+ cos(deg2rad(\$lat1))* cos(deg2rad(\$lat2))* cos(deg2rad(\$long2)- deg2rad(\$long1))) * \$r; return \$dist; } sub FlatEarth { my (\$lat1, \$long1, \$lat2, \$long2) = @_; my \$r=3956; my \$a = (pi/2)- deg2rad(\$lat1); my \$b = (pi/2)- deg2rad(\$lat2); my \$c = sqrt(\$a**2 + \$b**2 - 2 * \$a *\$b *cos(deg2rad(\$long2)-deg2rad(\$long1))); my \$dist = \$c * \$r; return \$dist; } sub Haversine { my (\$lat1, \$long1, \$lat2, \$long2) = @_; my \$r=3956; \$dlong = deg2rad(\$long1) - deg2rad(\$long2); \$dlat = deg2rad(\$lat1) - deg2rad(\$lat2); \$a = sin(\$dlat/2)**2 +cos(deg2rad(\$lat1)) * cos(deg2rad(\$lat2)) * sin(\$dlong/2)**2; \$c = 2 * (asin(sqrt(\$a))); \$dist = \$r * \$c; return \$dist; } sub GreatCircle { my (\$lat1, \$long1, \$lat2, \$long2) = @_; my \$r=3956; my @zip1 = (deg2rad(\$long1), deg2rad(90-\$lat1)); my @zip2 = (deg2rad(\$long2), deg2rad(90-\$lat2)); my \$dist = great_circle_distance(@zip1, @zip2,\$r); return \$dist; } ```
Replies are listed 'Best First'.
•Re: Finding the Distance between longitude and latitude pairs
by merlyn (Sage) on Mar 07, 2002 at 19:24 UTC
Also - WWW::MapBlast by Lee Goddard. He's going to be using some of my code shown above in his next release.

C-.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://150054]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2024-09-19 10:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
The PerlMonks site front end has:

Results (25 votes). Check out past polls.

Notices?
 • erzuuli ‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.