1# NAME
2
3GIS::Distance - Calculate geographic distances.
4
5# SYNOPSIS
6
7```perl
8use GIS::Distance;
9
10# Use the GIS::Distance::Haversine formula by default.
11my $gis = GIS::Distance->new();
12
13# Or choose a different formula.
14my $gis = GIS::Distance->new( 'Polar' );
15
16# Returns a Class::Measure object.
17my $distance = $gis->distance( $lat1, $lon1, $lat2, $lon2 );
18
19print $distance->meters();
20```
21
22# DESCRIPTION
23
24This module calculates distances between geographic points on, at the moment,
25planet Earth.  Various ["FORMULAS"](#formulas) are available that provide different levels
26of accuracy versus speed.
27
28[GIS::Distance::Fast](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFast), a separate distribution, ships with C implmentations of
29some of the formulas shipped with GIS::Distance.  If you're looking for speed
30then install it and the ::Fast formulas will be automatically used by this module.
31
32# METHODS
33
34## distance
35
36```perl
37my $distance = $gis->distance( $lat1, $lon1, $lat2, $lon2 );
38
39my $point1 = Geo::Point->latlong( $lat1, $lon1 );
40my $point2 = Geo::Point->latlong( $lat2, $lon2 );
41my $distance = $gis->distance( $point1, $point2 );
42```
43
44Takes either two decimal latitude and longitude pairs, or two [Geo::Point](https://metacpan.org/pod/Geo%3A%3APoint)
45objects.
46
47Returns a [Class::Measure::Length](https://metacpan.org/pod/Class%3A%3AMeasure%3A%3ALength) object for the distance between the
48two degree lats/lons.
49
50See ["distance\_metal"](#distance_metal) for a faster, but less feature rich, method.
51
52## distance\_metal
53
54This works just like ["distance"](#distance) except for:
55
56- Does not accept [Geo::Point](https://metacpan.org/pod/Geo%3A%3APoint) objects.  Only decimal latitude and longitude
57pairs.
58- Does not return a [Class::Measure](https://metacpan.org/pod/Class%3A%3AMeasure) object.  Instead kilometers are always
59returned.
60- Does no argument checking.
61- Does not support formula arguments which are supported by at least the
62[GIS::Distance::GeoEllipsoid](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AGeoEllipsoid) formula.
63
64Calling this gets you pretty close to the fastest bare metal speed you can get.
65The speed improvements of calling this is noticeable over hundreds of thousands of
66iterations only and you've got to decide if its worth the safety and features
67you are dropping.  Read more in the ["SPEED"](#speed) section.
68
69# ARGUMENTS
70
71```perl
72my $gis = GIS::Distance->new( $formula );
73```
74
75When you call `new()` you may pass a partial or full formula class name as the
76first argument.  The default is `Haversive`.
77
78If you pass a partial name, as in:
79
80```perl
81my $gis = GIS::Distance->new( 'Haversine' );
82```
83
84Then the following modules will be looked for in order:
85
86```
87GIS::Distance::Fast::Haversine
88GIS::Distance::Haversine
89Haversine
90```
91
92Install [GIS::Distance::Fast](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFast) to get access to the `Fast::` (XS) implementations
93of the formula classes.
94
95You may globally disable the automatic use of the `Fast::` formulas by setting
96the `GIS_DISTANCE_PP` environment variable.  Although, its likely simpler to
97just provide a full class name to get the same effect:
98
99```perl
100my $gis = GIS::Distance->new( 'GIS::Distance::Haversine' );
101```
102
103# SPEED
104
105Not that this module is slow, but if you're doing millions of distance
106calculations a second you may find that adjusting your code a bit may
107make it faster.  Here are some options.
108
109Install [GIS::Distance::Fast](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFast) to get the XS variants for most of the
110PP formulas.
111
112Use ["distance\_metal"](#distance_metal) instead of ["distance"](#distance).
113
114Call the undocumented `_distance()` function that each formula class
115has.  For example you could bypass this module entirely and just do:
116
117```perl
118use GIS::Distance::Fast::Haversine;
119my $km = GIS::Distance::Fast::Haversine::_distance( @coords );
120```
121
122The above would be the ultimate speed demon (as shown in benchmarking)
123but throws away some flexibility and adds some foot-gun support.
124
125Here's a benchmarks for these options:
126
127```
1282019-03-13T09:34:00Z
129GIS::Distance 0.15
130GIS::Distance::Fast 0.12
131GIS::Distance::Fast::Haversine 0.12
132GIS::Distance::Haversine 0.15
133                                                             Rate
134PP Haversine - GIS::Distance->distance                   123213/s
135XS Haversine - GIS::Distance->distance                   196232/s
136PP Haversine - GIS::Distance->distance_metal             356379/s
137PP Haversine - GIS::Distance::Haversine::_distance       385208/s
138XS Haversine - GIS::Distance->distance_metal             3205128/s
139XS Haversine - GIS::Distance::Fast::Haversine::_distance 8620690/s
140```
141
142You can run your own benchmarks using the included `author/bench`
143script.  The above results were produced with:
144
145```
146author/bench -f Haversine
147```
148
149The slowest result was about `125000/s`, or about `8ms` each call.
150This could be a substantial burden in some contexts, such as live HTTP
151responses to human users and running large batch jobs, to name just two.
152
153In conclusion, if you can justify the speed gain, switching to
154["distance\_metal"](#distance_metal) and installing [GIS::Distance::Fast](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFast) looks to be an
155ideal setup.
156
157As always with performance and benchmarking, YMMV.
158
159# COORDINATES
160
161When passing latitudinal and longitudinal coordinates to ["distance"](#distance)
162they must always be in decimal degree format.  Here is some sample code
163for converting from other formats to decimal:
164
165```perl
166# DMS to Decimal
167my $decimal = $degrees + ($minutes/60) + ($seconds/3600);
168
169# Precision Six Integer to Decimal
170my $decimal = $integer * .000001;
171```
172
173If you want to convert from decimal radians to degrees you can use [Math::Trig](https://metacpan.org/pod/Math%3A%3ATrig)'s
174rad2deg function.
175
176# FORMULAS
177
178These formulas come bundled with this distribution:
179
180- [GIS::Distance::ALT](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AALT)
181- [GIS::Distance::Cosine](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3ACosine)
182- [GIS::Distance::GreatCircle](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AGreatCircle)
183- [GIS::Distance::Haversine](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AHaversine)
184- [GIS::Distance::MathTrig](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AMathTrig)
185- [GIS::Distance::Null](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3ANull)
186- [GIS::Distance::Polar](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3APolar)
187- [GIS::Distance::Vincenty](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AVincenty)
188
189These formulas are available on CPAN:
190
191- ["FORMULAS" in GIS::Distance::Fast](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFast#FORMULAS)
192- [GIS::Distance::GeoEllipsoid](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AGeoEllipsoid)
193
194# AUTHORING
195
196Take a look at [GIS::Distance::Formula](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AFormula) for instructions on authoring
197new formula classes.
198
199# SEE ALSO
200
201- [Geo::Distance](https://metacpan.org/pod/Geo%3A%3ADistance) - Is deprecated in favor of using this module.
202- [Geo::Distance::Google](https://metacpan.org/pod/Geo%3A%3ADistance%3A%3AGoogle) - While in the Geo::Distance namespace, this isn't
203actually related to Geo::Distance at all.  Might be useful though.
204- [GIS::Distance::Lite](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3ALite) - An old fork of this module, not recommended.
205- [Geo::Distance::XS](https://metacpan.org/pod/Geo%3A%3ADistance%3A%3AXS) - Used to be used by [Geo::Distance](https://metacpan.org/pod/Geo%3A%3ADistance) but no longer is.
206- [Geo::Ellipsoid](https://metacpan.org/pod/Geo%3A%3AEllipsoid) - Or use [GIS::Distance::GeoEllipsoid](https://metacpan.org/pod/GIS%3A%3ADistance%3A%3AGeoEllipsoid) for a uniform
207interface.
208- [Geo::Inverse](https://metacpan.org/pod/Geo%3A%3AInverse) - Does some distance calculations, but seems less than useful
209as all the code looks to be taken from [Geo::Ellipsoid](https://metacpan.org/pod/Geo%3A%3AEllipsoid).
210
211# SUPPORT
212
213Please submit bugs and feature requests to the
214GIS-Distance GitHub issue tracker:
215
216[https://github.com/bluefeet/GIS-Distance/issues](https://github.com/bluefeet/GIS-Distance/issues)
217
218# AUTHORS
219
220```
221Aran Clary Deltac <bluefeet@gmail.com>
222Mohammad S Anwar <mohammad.anwar@yahoo.com>
223```
224
225# LICENSE
226
227This library is free software; you can redistribute it and/or modify
228it under the same terms as Perl itself.
229