File Coverage

blib/lib/Geo/Calc/XS.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             package Geo::Calc::XS;
2              
3             require 5.4.0;
4              
5 1     1   498 use strict;
  1         1  
  1         31  
6 1     1   3 use warnings;
  1         2  
  1         27  
7 1     1   10 use utf8;
  1         1  
  1         5  
8              
9 1     1   25 use Exporter;
  1         2  
  1         50  
10 1     1   7 use XSLoader;
  1         1  
  1         221  
11              
12             our @ISA = qw( Exporter DynaLoader );
13              
14             our %EXPORT_TAGS = ( 'all' => [ 'new', 'distance_to' ] );
15             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
16             our @EXPORT = ();
17             our $VERSION = '0.33';
18              
19             XSLoader::load 'Geo::Calc::XS', $VERSION;
20              
21             # Copyright 2011-2014 by Sorin Alexandru Pop.
22             # For other contributors see ChangeLog.
23             # See the manual pages for details on the licensing terms.
24              
25             =head1 NAME
26              
27             Geo::Calc::XS - simple geo calculator for points and distances
28              
29             =head1 SYNOPSIS
30              
31             use Geo::Calc::XS;
32              
33             my $gc = Geo::Calc::XS->new( lat => 40.417875, lon => -3.710205 );
34             my $lan = $gc->get_lan();
35             my $lon = $gc->get_lon();
36             my $radius = $gc->get_radius();
37             my $units = $gc->get_units();
38             my $distance = $gc->distance_to( { lat => 40.422371, lon => -3.704298 }, -6 );
39             my $brng = $gc->bearing_to( { lat => 40.422371, lon => -3.704298 }, -6 );
40             my $f_brng = $gc->final_bearing_to( { lat => 40.422371, lon => -3.704298 }, -6 );
41             my $midpoint = $gc->midpoint_to( { lat => 40.422371, lon => -3.704298 }, -6 );
42             my $destination = $gc->destination_point( 90, 1, -6 );
43             my $bbox = $gc->boundry_box( 3, 4, -6 );
44             my $r_distance = $gc->rhumb_distance_to( { lat => 40.422371, lon => -3.704298 }, -6 );
45             my $r_brng = $gc->rhumb_bearing_to( { lat => 40.422371, lon => -3.704298 }, -6 );
46             my $r_destination = $gc->rhumb_destination_point( 30, 1, -6 );
47             my $point = $gc->intersection( 90, { lat => 40.422371, lon => -3.704298 }, 180, -6 );
48              
49             =head1 DESCRIPTION
50              
51             B implements a variety of calculations for latitude/longitude points
52              
53             All these formulas are for calculations on the basis of a spherical earth
54             (ignoring ellipsoidal effects), which is accurate enough for most purposes.
55              
56             [ In fact, the earth is very slightly ellipsoidal; using a spherical model
57             gives errors typically up to 0.3% ].
58              
59             Benchmarking this module and L I found out that this module is sometimes
60             more than 8000 times faster.
61              
62             This module is designed to be thread-safe, although, of course,
63             interpreter-based threads are officially discouraged (see
64             L).
65              
66             =head1 CAVEATS
67              
68             This is not a drop-in replacement for L, see the COMPATIBILITY
69             section further down.
70              
71             =head1 Geo::Calc::XS->new()
72              
73             $gc = Geo::Calc::XS->new( lat => 40.417875, lon => -3.710205 ); # Somewhere in Madrid
74             $gc = Geo::Calc::XS->new( lat => 51.503269, lon => 0, units => 'k-m' ); # The O2 Arena in London
75              
76             Creates a new Geo::Calc::XS object from a latitude and longitude. The default
77             decimal precision is -6 for all functions => meaning by default it always
78             returns the results with 6 decimals.
79              
80             The default unit distance is 'm' (meter), but you cand define another unit using C.
81             Accepted values are: 'm' (meters), 'k-m' (kilometers), 'yd' (yards), 'ft' (feet) and 'mi' (miles)
82              
83             If a C parameter is passed, it is ignored.
84              
85             Returns a reference to a C object.
86              
87             =head2 Parameters
88              
89             Each of these parameters can be accessed after construction using C,
90             C, C or C.
91              
92             =over 4
93              
94             =item lat
95              
96             => latitude of the point ( required )
97              
98             =item lon
99              
100             => longitude of the point ( required )
101              
102             =item radius
103              
104             => earth radius in km ( defaults to 6371 )
105              
106             =item units
107              
108             => the distance unit received and output by this object ( defaults to 'm' )
109              
110             =back
111              
112             =cut
113              
114             =head1 METHODS
115              
116             =head2 distance_to
117              
118             $gc->distance_to( $point[, $precision] )
119             $gc->distance_to( { lat => 40.422371, lon => -3.704298 } )
120             $gc->distance_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ) )
121              
122             This uses the "haversine" formula to calculate great-circle distances between
123             the two points - that is, the shortest distance over the earth's surface -
124             giving an `as-the-crow-flies` distance between the points (ignoring any hills!)
125              
126             The haversine formula `remains particularly well-conditioned for numerical
127             computation even at small distances` - unlike calculations based on the spherical
128             law of cosines. It was published by R W Sinnott in Sky and Telescope, 1984,
129             though known about for much longer by navigators. (For the curious, c is the
130             angular distance in radians, and a is the square of half the chord length between
131             the points).
132              
133             Returns with the distance using the precision defined or -6
134             ( -6 = 6 decimals ( eg 4.000001 ) ), in this object's distance unit.
135              
136             =cut
137              
138             =head2 bearing_to
139              
140             $gc->bearing_to( $point[, $precision] );
141             $gc->bearing_to( { lat => 40.422371, lon => -3.704298 }, -6 );
142             $gc->bearing_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ), -6 );
143              
144             In general, your current heading will vary as you follow a great circle path
145             (orthodrome); the final heading will differ from the initial heading by varying
146             degrees according to distance and latitude (if you were to go from say 35N,45E
147             (Baghdad) to 35N,135E (Osaka), you would start on a heading of 60 and end up on
148             a heading of 120!).
149              
150             This formula is for the initial bearing (sometimes referred to as forward
151             azimuth) which if followed in a straight line along a great-circle arc will take
152             you from the start point to the end point
153              
154             Returns the (initial) bearing from this point to the supplied point, in degrees
155             with the specified pricision
156              
157             See L
158              
159             =cut
160              
161             =head2 final_bearing_to
162              
163             my $f_brng = $gc->final_bearing_to( $point[, $precision] );
164             my $f_brng = $gc->final_bearing_to( { lat => 40.422371, lon => -3.704298 } );
165             my $f_brng = $gc->final_bearing_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ) );
166              
167             Returns final bearing (in degrees) arriving at supplied destination point from
168             this point; the final bearing will differ from the initial bearing by varying
169             degrees according to distance and latitude
170              
171             =cut
172              
173             =head2 midpoint_to
174              
175             $gc->midpoint_to( $point[, $precision] );
176             $gc->midpoint_to( { lat => 40.422371, lon => -3.704298 } );
177             $gc->midpoint_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ) );
178              
179             Returns the midpoint along a great circle path between the initial point and
180             the supplied point.
181              
182             See L for derivation
183              
184             =cut
185              
186             =head2 destination_point
187              
188             $gc->destination_point( $bearing, $distance[, $precision] );
189             $gc->destination_point( 90, 1 );
190              
191             Returns the destination point and the final bearing using Vincenty inverse
192             formula for ellipsoids.
193              
194             C<$bearing> must be specified in degrees, where 0 is north and 90 is east, and
195             C<$distance> must be specified in this object's distance unit.
196              
197             =cut
198              
199             =head2 boundry_box
200              
201             $gc->boundry_box( $width[, $height[, $precision]] );
202             $gc->boundry_box( 3, 4 ); # will generate a 3x4m box around the point, assuming the object's distance unit is meters
203             $gc->boundry_box( 1 ); # will generate a 2x2m box around the point (radius), assuming the object's distance unit is meters
204              
205             Returns the boundry box min/max having the initial point defined as the center
206             of the boundry box, given the width and height.
207              
208             If only one dimension has been specified, than that dimension is considered a
209             radius.
210              
211             Dimensions should be specified in the object's distance unit.
212              
213             =cut
214              
215             =head2 rhumb_distance_to
216              
217             $gc->rhumb_distance_to( $point[, $precision] );
218             $gc->rhumb_distance_to( { lat => 40.422371, lon => -3.704298 } );
219             $gc->rhumb_distance_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ) );
220              
221             Returns the distance from this point to the supplied point, in the object's
222             distance unit, travelling along a rhumb line.
223              
224             A 'rhumb line' (or loxodrome) is a path of constant bearing, which crosses all
225             meridians at the same angle.
226              
227             Sailors used to (and sometimes still) navigate along rhumb lines since it is
228             easier to follow a constant compass bearing than to be continually adjusting
229             the bearing, as is needed to follow a great circle. Rhumb lines are straight
230             lines on a Mercator Projection map (also helpful for navigation).
231              
232             Rhumb lines are generally longer than great-circle (orthodrome) routes. For
233             instance, London to New York is 4% longer along a rhumb line than along a
234             great circle . important for aviation fuel, but not particularly to sailing
235             vessels. New York to Beijing . close to the most extreme example possible
236             (though not sailable!) . is 30% longer along a rhumb line.
237              
238             See L
239              
240             =cut
241              
242             =head2 rhumb_bearing_to
243              
244             $gc->rhumb_bearing_to( $point[, $precision] );
245             $gc->rhumb_bearing_to( { lat => 40.422371, lon => -3.704298 } );
246             $gc->rhumb_bearing_to( Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ) );
247              
248             Returns the bearing from this point to the supplied point along a rhumb line,
249             in degrees
250              
251             =cut
252              
253             =head2 rhumb_destination_point
254              
255             $gc->rhumb_destination_point( $brng, $distance[, $precision] );
256             $gc->rhumb_destination_point( 30, 1 );
257              
258             Returns the destination point from this point having travelled the given
259             distance (in the object's distance unit) on the given bearing along a rhumb
260             line.
261              
262             =cut
263              
264             =head2 intersection
265              
266             $gc->intersection( $brng1, $point, $brng2[, $precision] );
267             $gc->intersection( 90, { lat => 40.422371, lon => -3.704298 }, 180 );
268             $gc->intersection( 90, Geo::Calc::XS->new( lat => 40.422371, lon => -3.704298 ), 180 );
269              
270             Returns the point of intersection of two paths defined by point and bearing
271              
272             See L
273              
274             =cut
275              
276             =head2 distance_at
277              
278             Returns the distance in meters for 1deg of latitude and longitude at the
279             specified latitude.
280              
281             my $m_distance = $self->distance_at([$precision]);
282             my $m_distance = $self->distance_at();
283             # at lat 2 with precision -6 returns { m_lat => 110575.625009, m_lon => 111252.098718 }
284              
285             Note that this method always returns distances in meters, unlike all the other
286             methods which use the object's distance unit. This is kept as it is for backwards
287             compatibility.
288              
289             =head1 COMPATIBILITY
290              
291             A B object does not have the same interface as a L
292             object, despite the similarities.
293              
294             Here are the currently known differences:
295              
296             =over 4
297              
298             =item
299              
300             C is provided by L but not by this module.
301              
302             =item
303              
304             The constructor for L accepts a C parameter, but this module ignores it.
305              
306             =item
307              
308             Methods with identicial names perform similar functions but may return
309             different results after a few decimal places.
310              
311             =item
312              
313             It's undocumented whether L is thread-safe, whereas this module does
314             intend to be thread-safe.
315              
316             =back
317              
318             =head1 SEE ALSO
319              
320             L is the original implementation, which is abandoned at time of
321             writing (Aug 2014).
322              
323             =head1 REPOSITORY
324              
325             L
326              
327             =head1 BUGS
328              
329             All complex software has bugs lurking in it, and this module is no
330             exception.
331              
332             Please report any bugs through the web interface at L.
333              
334             =head1 AUTHOR
335              
336             Sorin Alexandru Pop C<< >>
337              
338             =head1 THANKS
339              
340             Marius Crisan C<< >>
341              
342             David D Lowe C<< >>
343              
344             Chris Hughes C<< >>
345              
346             =head1 LICENSE
347              
348             This program is free software; you can redistribute it and/or
349             modify it under the same terms as Perl itself.
350              
351             See L
352              
353             =cut
354              
355             __END__