# NAME GIS::Distance - Calculate geographic distances. # SYNOPSIS use GIS::Distance; # Use the GIS::Distance::Haversine formula by default: my $gis = GIS::Distance->new(); # Or choose a different formula: my $gis = GIS::Distance->new( 'Polar' ); my $distance = $gis->distance( $lat1,$lon1 => $lat2,$lon2 ); print $distance->meters(); # DESCRIPTION This module calculates distances between geographic points on, at the moment, planet Earth. Various ["FORMULAS"](#formulas) are available that provide different levels of accuracy versus speed. [GIS::Distance::Fast](https://metacpan.org/pod/GIS::Distance::Fast), a separate distribution, ships with C implmentations of some of the formulas shipped with GIS::Distance. If you're looking for speed then install it and the ::Fast formulas will be automatically used by this module. # METHODS ## distance my $distance = $gis->distance( $lat1,$lon1 => $lat2,$lon2 ); Returns a [Class::Measure::Length](https://metacpan.org/pod/Class::Measure::Length) object for the distance between the two degree lats/lons. See ["distance\_km"](#distance_km) and ["distance\_metal"](#distance_metal) to return raw kilometers instead. ## distance\_km This works just like ["distance"](#distance), but returns a raw kilometer measurement, and is faster when benchmarked over millions of iterations. ## distance\_metal This works just like ["distance\_km"](#distance_km), but does no argument checking and ignores any formula ["args"](#args). Calling this gets you pretty close to the fastest bare metal speed you can get. Again, like with ["distance\_km"](#distance_km), the speed improvements of calling this is noticeable over millions of iterations only and you've got to decide if its worth the safety and features you are dropping. # ATTRIBUTES ## formula Returns the formula name which was passed as the first argument to `new()`. The formula can be specified as a partial or full module name for that formula. For example, if the formula is set to `Haversine` as in: my $gis = GIS::Distance->new( 'Haversine' ); Then the following modules will be looked for in order: GIS::Distance::Fast::Haversine GIS::Distance::Haversine Haversine Note that a `Fast::` version of the class will be looked for first. By default the `Fast::` versions of the formulas, written in C, are not available and the pure perl ones will be used instead. If you would like the `Fast::` formulas then install [GIS::Distance::Fast](https://metacpan.org/pod/GIS::Distance::Fast) and they will be automatically used. You may disable the automatic use of the `Fast::` formulas by setting the `GIS_DISTANCE_PP` environment variable. ## args Returns the formula arguments, an array ref, containing the rest of the arguments passed to `new()` (anything passed after the ["formula"](#formula)). Most formulas do not take arguments. If they do it will be described in their respective documentation. ## module Returns the fully qualified module name that ["formula"](#formula) resolved to. # SPEED Not that this module is slow, but if you're doing millions of distance calculations you may find that adjusting your code a bit may make it faster. Here are some options. Install [GIS::Distance::Fast](https://metacpan.org/pod/GIS::Distance::Fast). Use ["distance\_km"](#distance_km) or ["distance\_metal"](#distance_metal) instead of ["distance"](#distance). Call the undocumented `distance()` function that each formula module has. For example you could bypass this module entirely and just do: use GIS::Distance::Fast::Haversine; my $km = GIS::Distance::Fast::Haversine::distance( @coords ); The above would be the ultimate speed demon (as shown in benchmarking) but throws away some flexibility and adds some foot-gun support. # COORDINATES When passing latitudinal and longitudinal coordinates to ["distance"](#distance) they must always be in decimal degree format. Here is some sample code for converting from other formats to decimal: # DMS to Decimal my $decimal = $degrees + ($minutes/60) + ($seconds/3600); # Precision Six Integer to Decimal my $decimal = $integer * .000001; If you want to convert from decimal radians to degrees you can use [Math::Trig](https://metacpan.org/pod/Math::Trig)'s rad2deg function. # FORMULAS These formulas come with this distribution: [GIS::Distance::Cosine](https://metacpan.org/pod/GIS::Distance::Cosine) [GIS::Distance::GreatCircle](https://metacpan.org/pod/GIS::Distance::GreatCircle) [GIS::Distance::Haversine](https://metacpan.org/pod/GIS::Distance::Haversine) [GIS::Distance::MathTrig](https://metacpan.org/pod/GIS::Distance::MathTrig) [GIS::Distance::Null](https://metacpan.org/pod/GIS::Distance::Null) [GIS::Distance::Polar](https://metacpan.org/pod/GIS::Distance::Polar) [GIS::Distance::Vincenty](https://metacpan.org/pod/GIS::Distance::Vincenty) These formulas are available on CPAN: [GIS::Distance::Fast::Cosine](https://metacpan.org/pod/GIS::Distance::Fast::Cosine) [GIS::Distance::Fast::GreatCircle](https://metacpan.org/pod/GIS::Distance::Fast::GreatCircle) [GIS::Distance::Fast::Haversine](https://metacpan.org/pod/GIS::Distance::Fast::Haversine) [GIS::Distance::Fast::Polar](https://metacpan.org/pod/GIS::Distance::Fast::Polar) [GIS::Distance::Fast::Vincenty](https://metacpan.org/pod/GIS::Distance::Fast::Vincenty) [GIS::Distance::GeoEllipsoid](https://metacpan.org/pod/GIS::Distance::GeoEllipsoid) # SEE ALSO [GIS::Distance::Lite](https://metacpan.org/pod/GIS::Distance::Lite) was long ago forked from GIS::Distance and modified to have less dependencies. Since then GIS::Distance itself has become tremendously lighter dep-wise, and is still maintained, I suggest you not use GIS::Distance::Lite. [Geo::Distance](https://metacpan.org/pod/Geo::Distance) has long been deprecated in favor of using this module. [Geo::Distance::XS](https://metacpan.org/pod/Geo::Distance::XS) used to be used by [Geo::Distance](https://metacpan.org/pod/Geo::Distance) but no longer does. [Geo::Inverse](https://metacpan.org/pod/Geo::Inverse) seems to do some distance calculation using [Geo::Ellipsoid](https://metacpan.org/pod/Geo::Ellipsoid) but if you look at the source code it clearly states that the entire meat of it is copied from Geo::Ellipsoid... so I'm not sure why it exists... just use Geo::Ellipsoid or [GIS::Distance::GeoEllipsoid](https://metacpan.org/pod/GIS::Distance::GeoEllipsoid) which wraps Geo::Ellipsoid into the GIS::Distance interface. [Geo::Distance::Google](https://metacpan.org/pod/Geo::Distance::Google) looks pretty neat. # TODO - Create a GIS::Coord class that represents a geographic coordinate. Then modify this module to accept input as either lat/lon pairs, or as GIS::Coord objects. This would make coordinate conversion as described in ["COORDINATES"](#coordinates) automatic. Maybe use [Geo::Point](https://metacpan.org/pod/Geo::Point). - Create some sort of equivalent to [Geo::Distance](https://metacpan.org/pod/Geo::Distance)'s closest() method. - Write a formula module called GIS::Distance::Geoid. Some very useful info is at [http://en.wikipedia.org/wiki/Geoid](http://en.wikipedia.org/wiki/Geoid). - Make [GIS::Distance::Google](https://metacpan.org/pod/GIS::Distance::Google) (or some such name) and wrap it around [Geo::Distance::Google](https://metacpan.org/pod/Geo::Distance::Google) (most likely). - Figure out why [GIS::Distance::Polar](https://metacpan.org/pod/GIS::Distance::Polar) has issues. # SUPPORT Please submit bugs and feature requests to the GIS-Distance GitHub issue tracker: [https://github.com/bluefeet/GIS-Distance/issues](https://github.com/bluefeet/GIS-Distance/issues) # AUTHORS Aran Clary Deltac # LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.