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