1Geo::Distance(3)      User Contributed Perl Documentation     Geo::Distance(3)
2
3
4

NAME

6       Geo::Distance - Calculate Distances and Closest Locations
7

SYNOPSIS

9         use Geo::Distance;
10         my $geo = new Geo::Distance;
11         $geo->formula('hsin');
12         $geo->reg_unit( 'toad_hop', 200120 );
13         $geo->reg_unit( 'frog_hop' => 6 => 'toad_hop' );
14         my $distance = $geo->distance( 'unit_type', $lon1,$lat1 => $lon2,$lat2 );
15         my $locations = $geo->closest(
16           dbh => $dbh,
17           table => $table,
18           lon => $lon,
19           lat => $lat,
20           unit => $unit_type,
21           distance => $dist_in_unit
22         );
23

DESCRIPTION

25       This perl library aims to provide as many tools to make it as simple as
26       possible to calculate distances between geographic points, and anything
27       that can be derived from that.  Currently there is support for finding
28       the closest locations within a specified distance, to find the closest
29       number of points to a specified point, and to do basic point-to-point
30       distance calculations.
31

DECOMMISSIONED

33       The GIS::Distance module is being worked on as a replacement for this
34       module.  In the near future Geo::Distance will become a lightweight
35       wrapper around GIS::Distance so that legacy code benefits from fixes to
36       GIS::Distance through the old Geo::Distance API.  For any new
37       developement I suggest that you look in to GIS::Distance.
38

STABILITY

40       The interface to Geo::Distance is fairly stable nowadays.  If this
41       changes it will be noted here.
42
43       0.10 - The closest() method has a changed argument syntax and no longer
44       supports array searches.  0.09 - Changed the behavior of the reg_unit
45       function.  0.07 - OO only, and other changes all over.
46

PROPERTIES

48   UNITS
49       All functions accept a unit type to do the computations of distance
50       with.  By default no units are defined in a Geo::Distance object.  You
51       can add units with reg_unit() or create some default units with
52       default_units().
53
54   LATITUDE AND LONGITUDE
55       When a function needs a longitude and latitude, they must always be in
56       decimal degree format.  Here is some sample code for converting from
57       other formats to decimal:
58
59         # DMS to Decimal
60         my $decimal = $degrees + ($minutes/60) + ($seconds/3600);
61
62         # Precision Six Integer to Decimal
63         my $decimal = $integer * .000001;
64
65       If you want to convert from decimal radians to degrees you can use
66       Math::Trig's rad2deg function.
67

METHODS

69   new
70         my $geo = new Geo::Distance;
71         my $geo = new Geo::Distance( no_units=>1 );
72
73       Returns a blessed Geo::Distance object.  The new constructor accepts
74       one optional argument.
75
76         no_units - Whether or not to load the default units. Defaults to 0 (false).
77                    kilometer, kilometre, meter, metre, centimeter, centimetre, millimeter,
78                    millimetre, yard, foot, inch, light second, mile, nautical mile,
79                    poppy seed, barleycorn, rod, pole, perch, chain, furlong, league,
80                    fathom
81
82   formula
83         if($geo->formula eq 'hsin'){ ... }
84         $geo->formula('cos');
85
86       Allows you to retrieve and set the formula that is currently being used
87       to calculate distances.  The available formulas are hsin, polar, cos
88       and mt. hsin is the default and mt/cos are deprecated in favor of hsin.
89       Polar should be used when calculating coordinates near the poles.
90
91   reg_unit
92         $geo->reg_unit( $radius, $key );
93         $geo->reg_unit( $key1 => $key2 );
94         $geo->reg_unit( $count1, $key1 => $key2 );
95         $geo->reg_unit( $key1 => $count2, $key2 );
96         $geo->reg_unit( $count1, $key1 => $count2, $key2 );
97
98       This method is used to create custom unit types.  There are several
99       ways of calling it, depending on if you are defining the unit from
100       scratch, or if you are basing it off of an existing unit (such as
101       saying 12 inches = 1 foot ).  When defining a unit from scratch you
102       pass the name and rho (radius of the earth in that unit) value.
103
104       So, if you wanted to do your calculations in human adult steps you
105       would have to have an average human adult walk from the crust of the
106       earth to the core (ignore the fact that this is impossible).  So,
107       assuming we did this and we came up with 43,200 steps, you'd do
108       something like the following.
109
110         # Define adult step unit.
111         $geo->reg_unit( 43200, 'adult step' );
112         # This can be read as "It takes 43,200 adult_steps to walk the radius of the earth".
113
114       Now, if you also wanted to do distances in baby steps you might think
115       "well, now I gotta get a baby to walk to the center of the earth".
116       But, you don't have to!  If you do some research you'll find (no
117       research was actually conducted) that there are, on average, 4.7 baby
118       steps in each adult step.
119
120         # Define baby step unit.
121         $geo->reg_unit( 4.7, 'baby step' => 'adult step' );
122         # This can be read as "4.7 baby steps is the same as one adult step".
123
124       And if we were doing this in reverse and already had the baby step unit
125       but not the adult step, you would still use the exact same syntax as
126       above.
127
128   distance
129         my $distance = $geo->distance( 'unit_type', $lon1,$lat1 => $lon2,$lat2 );
130
131       Calculates the distance between two lon/lat points.
132
133   closest
134         my $locations = $geo->closest(
135           dbh => $dbh,
136           table => $table,
137           lon => $lon,
138           lat => $lat,
139           unit => $unit_type,
140           distance => $dist_in_unit
141         );
142
143       This method finds the closest locations within a certain distance and
144       returns an array reference with a hash for each location matched.
145
146       The closest method requires the following arguments:
147
148         dbh - a DBI database handle
149         table - a table within dbh that contains the locations to search
150         lon - the longitude of the center point
151         lat - the latitude of the center point
152         unit - the unit of measurement to use, such as "meter"
153         distance - the distance, in units, from the center point to find locations
154
155       The following arguments are optional:
156
157         lon_field - the name of the field in the table that contains the longitude, defaults to "lon"
158         lat_field - the name of the field in the table that contains the latitude, defaults to "lat"
159         fields - an array reference of extra field names that you would like returned with each location
160         where - additional rules for the where clause of the sql
161         bind - an array reference of bind variables to go with the placeholders in where
162         sort - whether to sort the locations by their distance, making the closest location the first returned
163         count - return at most these number of locations (implies sort => 1)
164
165       This method uses some very simplistic calculations to SQL select out of
166       the dbh.  This means that the SQL should work fine on almost any
167       database (only tested on MySQL and SQLite so far) and this also means
168       that it is fast.  Once this sub set of locations has been retrieved
169       then more precise calculations are made to narrow down the result set.
170       Remember, though, that the farther out your distance is, and the more
171       locations in the table, the slower your searches will be.
172

FORMULAS

174       Currently Geo::Distance only has spherical and flat type formulas.  If
175       you have any information concerning ellipsoid and geoid formulas, the
176       author would much appreciate some links to this information.
177
178   tv: Thaddeus Vincenty Formula
179       This is a highly accurate ellipsoid formula.  For most applications
180       hsin will be faster and accurate enough.  I've read that this formula
181       can be accurate to within a few millimeters.
182
183       This formula is still considered alpha quality.  It has not been tested
184       enough to be used in production.
185
186   hsin: Haversine Formula
187         dlon = lon2 - lon1
188         dlat = lat2 - lat1
189         a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
190         c = 2 * atan2( sqrt(a), sqrt(1-a) )
191         d = R * c
192
193       The hsin formula is the new standard formula for Geo::Distance because
194       of it's improved accuracy over the cos formula.
195
196   polar: Polar Coordinate Flat-Earth Formula
197         a = pi/2 - lat1
198         b = pi/2 - lat2
199         c = sqrt( a^2 + b^2 - 2 * a * b * cos(lon2 - lon1) )
200         d = R * c
201
202       While implimented, this formula has not been tested much.  If you use
203       it PLEASE share your results with the author!
204
205   cos: Law of Cosines for Spherical Trigonometry
206         a = sin(lat1) * sin(lat2)
207         b = cos(lat1) * cos(lat2) * cos(lon2 - lon1)
208         c = arccos(a + b)
209         d = R * c
210
211       Although this formula is mathematically exact, it is unreliable for
212       small distances because the inverse cosine is ill-conditioned.
213
214   gcd: Great Circle Distance.
215         c = 2 * asin( sqrt(
216           ( sin(( lat1 - lat2 )/2) )^2 +
217           cos( lat1 ) * cos( lat2 ) *
218           ( sin(( lon1 - lon2 )/2) )^2
219         ) )
220
221       Similar notes to the mt and cos formula, not too terribly accurate.
222
223   mt: Math::Trig great_circle_distance
224       This formula uses Meth::Trig's great_circle_distance function which at
225       this time uses math almost exactly the same as the cos formula.  If you
226       want to use the cos formula you may find that mt will calculate faster
227       (untested assumption).  For some reason mt and cos return slight
228       differences at very close distances. The mt formula has the same
229       drawbacks as the cos formula.
230
231       This is the same formula that was previously the only one used by
232       Geo::Distance (ending at version 0.06) and was wrongly called the "gcd"
233       formula.
234
235       Math::Trig states that the formula that it uses is:
236
237         lat0 = 90 degrees - phi0
238         lat1 = 90 degrees - phi1
239         d = R * arccos(cos(lat0) * cos(lat1) * cos(lon1 - lon01) + sin(lat0) * sin(lat1))
240

NOTES

242       If Geo::Distance::XS is installed, this module will use it. You can
243       stick with the pure Perl version by setting the GEO_DISTANCE_PP
244       environment variable before using this module.
245

TODO

247       ·   A second pass should be done in closest before distance
248           calculations are made that does an inner radius simplistic
249           calculation to find the locations that are obviously within the
250           distance needed.
251
252       ·   Tests!  We need more tests!
253
254       ·   For NASA-quality accuracy a geoid forumula.
255
256       ·   The closest() method needs to be more flexible and (among other
257           things) allow table joins.
258

SEE ALSO

260       Math::Trig - Inverse and hyperbolic trigonemetric Functions.
261
262       <http://www.census.gov/cgi-bin/geo/gisfaq?Q5.1> - A overview of
263       calculating distances.
264
265       <http://williams.best.vwh.net/avform.htm> - Aviation Formulary.
266

AUTHOR

268       Aran Clary Deltac <bluefeet@cpan.org>
269

CONTRIBUTORS

271       gray, <gray at cpan.org>
272

LICENSE

274       This library is free software; you can redistribute it and/or modify it
275       under the same terms as Perl itself.
276
277
278
279perl v5.28.1                      2012-10-19                  Geo::Distance(3)
Impressum