GIS::Distance(3pm)

πŸ“¦
version 0.20 Β· 6 versions
, in debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ NAME ✨

GIS::Distance β€” bestie, it calculates geographic distances. That's the whole vibe. πŸ’–

(oh also, real quick, this is the GIS::Distance(3pm) page from the User Contributed Perl Documentation section β€” just so you know where you are 🫢)


πŸ¦‹ SYNOPSIS πŸ¦‹

okay so here's the whole thing in action, no cap:

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' );

# Returns a Class::Measure object.
my $distance = $gis->distance( $lat1, $lon1, $lat2, $lon2 );

print $distance->meters();

🌸 DESCRIPTION 🌸

This module does one thing and it does it iconically: it calculates distances between geographic points on β€” at the moment, bestie β€” planet Earth. 🌍

There's a whole menu of FORMULAS available, and they each give you a different trade-off between accuracy and speed. Pick your fighter. πŸ’…

GIS::Distance::Fast is a whole separate distribution, and it ships with C implementations of some of the formulas that come with GIS::Distance. So if you're chasing speed, install it, and the ::Fast formulas will be automatically used by this module. Slay. ✨


πŸ’… METHODS πŸ’…

distance

my $distance = $gis->distance( $lat1, $lon1, $lat2, $lon2 );

my $point1 = Geo::Point->latlong( $lat1, $lon1 );
my $point2 = Geo::Point->latlong( $lat2, $lon2 );
my $distance = $gis->distance( $point1, $point2 );

So this one takes either two decimal latitude/longitude pairs, or two Geo::Point objects. Both. Your choice. Main character energy. πŸ‘‘

It hands you back a Class::Measure::Length object for the distance between those two degree lats/lons. πŸŽ€

psst β€” check out "distance_metal" if you want something faster, just less feature rich. iykyk.

distance_metal

fr fr this works just like "distance"... except for these lil things:

  • It does not accept Geo::Point objects. Only decimal latitude and longitude pairs. Periodt.
  • It does not return a Class::Measure object. Instead, kilometers are always returned.
  • It does no argument checking. πŸ™ˆ
  • It does not support formula arguments, which are supported by at least the GIS::Distance::GeoEllipsoid formula.

Calling this gets you pretty close to the fastest bare metal speed you can get. Ngl though, the speed improvements from calling this are only noticeable over hundreds of thousands of iterations β€” so you've gotta decide for yourself if it's worth the safety and features you're dropping. Read more in the "SPEED" section. 🏎️


🧚 ARGUMENTS 🧚

my $gis = GIS::Distance->new( $formula );

When you call "new()" you may pass a partial or full formula class name as the first argument. The default is "Haversive". (yes bestie, that's genuinely how it's spelled in the docs, we don't make the rules πŸ’€)

If you pass a partial name, like this:

my $gis = GIS::Distance->new( 'Haversine' );

Then the following modules will be looked for, in order:

GIS::Distance::Fast::Haversine
GIS::Distance::Haversine
Haversine

Install GIS::Distance::Fast to get access to the "Fast::" (XS) implementations of the formula classes. πŸ”₯

You may globally disable the automatic use of the "Fast::" formulas by setting the "GIS_DISTANCE_PP" environment variable. Although... it's probably simpler to just provide a full class name to get the same effect:

my $gis = GIS::Distance->new( 'GIS::Distance::Haversine' );

πŸ”₯ SPEED πŸ”₯

Not saying this module is slow, bestie, but if you're out here doing millions of distance calculations a second you may find that adjusting your code a bit makes it faster. Here are some options. ✨

  • Install GIS::Distance::Fast to get the XS variants for most of the PP formulas.
  • Use "distance_metal" instead of "distance".
  • Call the undocumented "_distance()" function that each formula class 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. πŸ’€

Here's a benchmarks for these options:

2019-03-13T09:34:00Z
GIS::Distance 0.15
GIS::Distance::Fast 0.12
GIS::Distance::Fast::Haversine 0.12
GIS::Distance::Haversine 0.15
                                                             Rate
PP Haversine - GIS::Distance->distance                   123213/s
XS Haversine - GIS::Distance->distance                   196232/s
PP Haversine - GIS::Distance->distance_metal             356379/s
PP Haversine - GIS::Distance::Haversine::_distance       385208/s
XS Haversine - GIS::Distance->distance_metal             3205128/s
XS Haversine - GIS::Distance::Fast::Haversine::_distance 8620690/s

You can run your own benchmarks using the included "author/bench" script. The above results were produced with:

author/bench -f Haversine

The slowest result was about "125000/s", or about "8ms" each call. Ngl that could be a substantial burden in some contexts β€” live HTTP responses to human users and running large batch jobs, to name just two. 😭

In conclusion: if you can justify the speed gain, switching to "distance_metal" and installing GIS::Distance::Fast looks to be an ideal setup. πŸ‘‘

As always with performance and benchmarking, YMMV. 🫢


🌈 COORDINATES 🌈

When passing latitudinal and longitudinal coordinates to "distance" they must always be in decimal degree format. Here's 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's rad2deg function. πŸ’–


πŸŽ€ FORMULAS πŸŽ€

These formulas come bundled with this distribution:

  • GIS::Distance::ALT
  • GIS::Distance::Cosine
  • GIS::Distance::GreatCircle
  • GIS::Distance::Haversine
  • GIS::Distance::MathTrig
  • GIS::Distance::Null
  • GIS::Distance::Polar
  • GIS::Distance::Vincenty

These formulas are available on CPAN:

  • "FORMULAS" in GIS::Distance::Fast
  • GIS::Distance::GeoEllipsoid

🧚 AUTHORING 🧚

Take a look at GIS::Distance::Formula for instructions on authoring new formula classes. Go make something, bestie. ✨


πŸ‘‘ SEE ALSO πŸ‘‘

  • Geo::Distance β€” is deprecated in favor of using this module.
  • Geo::Distance::Google β€” while in the Geo::Distance namespace, this isn't actually related to Geo::Distance at all. Might be useful though.
  • GIS::Distance::Lite β€” an old fork of this module, not recommended.
  • Geo::Distance::XS β€” used to be used by Geo::Distance but no longer is.
  • Geo::Ellipsoid β€” or use GIS::Distance::GeoEllipsoid for a uniform interface.
  • Geo::Inverse β€” does some distance calculations, but seems less than useful as all the code looks to be taken from Geo::Ellipsoid.

🫢 SUPPORT 🫢

Please submit bugs and feature requests to the GIS-Distance GitHub issue tracker:

<https://github.com/bluefeet/GIS-Distance/issues>


πŸ’œ AUTHOR πŸ’œ

Aran Clary Deltac <bluefeet@gmail.com>

πŸ’– CONTRIBUTORS πŸ’–

Mohammad S Anwar <mohammad.anwar@yahoo.com>
Florian Schlichting <fsfs@debian.org>

⭐ LICENSE ⭐

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page, bestie! πŸŽ€ this lil masterpiece was built for perl v5.36.0 and dated 2023-10-21 β€” yes it's giving vintage but it still ate. mwah πŸ’‹ ✨

πŸ“¦ where this page comes from