1package Geo::Distance::XS;
2
3use strict;
4use warnings;
5
6use Carp qw(croak);
7use Geo::Distance;
8use XSLoader;
9
10our $VERSION    = '0.13';
11our $XS_VERSION = $VERSION;
12$VERSION = eval $VERSION;
13
14XSLoader::load(__PACKAGE__, $XS_VERSION);
15
16my ($orig_distance_sub, $orig_formula_sub);
17BEGIN {
18    $orig_distance_sub = \&Geo::Distance::distance;
19    $orig_formula_sub  = \&Geo::Distance::formula;
20}
21
22my %formulas; @formulas{qw(hsin cos mt tv gcd polar alt)} = (1, 2, 2..6);
23our @FORMULAS = sort keys %formulas;
24
25sub import {
26    no warnings qw(redefine);
27    no strict qw(refs);
28
29    *Geo::Distance::distance = \&{__PACKAGE__.'::distance'};
30    *Geo::Distance::formula = sub {
31        my $self = shift;
32        if (@_) {
33            my $formula = shift;
34            croak "Invalid formula: $formula"
35                unless exists $formulas{$formula};
36            $self->{formula} = $formula;
37            $self->{formula_index} = $formulas{$formula};
38        }
39        return $self->{formula};
40    };
41}
42
43# Fall back to pure perl after calling 'no Geo::Distance::XS'.
44sub unimport {
45    no warnings qw(redefine);
46
47    *Geo::Distance::formula  = $orig_formula_sub;
48    *Geo::Distance::distance = $orig_distance_sub;
49}
50
51
521;
53
54__END__
55
56=head1 NAME
57
58Geo::Distance::XS - speed up Geo::Distance
59
60=head1 SYNOPSIS
61
62    use Geo::Distance::XS;
63
64    my $geo = Geo::Distance->new;
65    my $distance = $geo->distance(mile => $lon1, $lat1 => $lon2, $lat2);
66
67=head1 DESCRIPTION
68
69The C<Geo::Distance::XS> module provides faster C implementations of the
70distance calculations found in C<Geo::Distance>.  See the documentation for
71that module for usage.
72
73NOTE: As of version 0.13, Geo::Distance automatically uses this module if
74it is installed.
75
76=head1 FORMULAS
77
78In addition to the formulas offered in C<Geo::Distance>, this module
79implements the additional formulas:
80
81=head2 alt: Andoyer-Lambert-Thomas Formula
82
83This is faster than the Vincenty formula, but trades a bit of accuracy.
84
85=head1 PERFORMANCE
86
87This distribution contains a benchmarking script which compares
88C<Geo::Distance::XS> with C<Geo::Distance> and C<GIS::Distance::Fast>. These
89are the results on a MacBook 2GHz with Perl 5.14.2:
90
91    ---- [ Formula: hsin ] ------------------------------------
92    perl     - distance from LA to NY: 2443.08796228363 miles
93    xs       - distance from LA to NY: 2443.08796228363 miles
94    gis_fast - distance from LA to NY: 2443.08796228363 miles
95
96                Rate gis_fast     perl       xs
97    gis_fast   24802/s       --     -70%     -98%
98    perl       81919/s     230%       --     -92%
99    xs       1003704/s    3947%    1125%       --
100
101    ---- [ Formula: tv ] ------------------------------------
102    perl     - distance from LA to NY: 2448.24135235512 miles
103    xs       - distance from LA to NY: 2448.2413523656 miles
104    gis_fast - distance from LA to NY: 2448.24135235512 miles
105
106                Rate     perl gis_fast       xs
107    perl      18101/s       --     -19%     -95%
108    gis_fast  22330/s      23%       --     -94%
109    xs       345717/s    1810%    1448%       --
110
111    ---- [ Formula: polar ] ------------------------------------
112    perl     - distance from LA to NY: 2766.02509696782 miles
113    xs       - distance from LA to NY: 2766.02509696782 miles
114    gis_fast - distance from LA to NY: 2766.02509696782 miles
115
116                Rate gis_fast     perl       xs
117    gis_fast   19200/s       --     -78%     -98%
118    perl       87682/s     357%       --     -93%
119    xs       1214700/s    6227%    1285%       --
120
121    ---- [ Formula: cos ] ------------------------------------
122    perl     - distance from LA to NY: 2443.08796228363 miles
123    xs       - distance from LA to NY: 2443.08796228363 miles
124    gis_fast - distance from LA to NY: 2443.08796228363 miles
125
126                Rate gis_fast     perl       xs
127    gis_fast   24435/s       --     -69%     -98%
128    perl       78913/s     223%       --     -93%
129    xs       1147836/s    4597%    1355%       --
130
131    ---- [ Formula: gcd ] ------------------------------------
132    perl     - distance from LA to NY: 2443.08796228363 miles
133    xs       - distance from LA to NY: 2443.08796228363 miles
134    gis_fast - distance from LA to NY: 2443.08796228363 miles
135
136                Rate gis_fast     perl       xs
137    gis_fast   18270/s       --     -75%     -98%
138    perl       74472/s     308%       --     -93%
139    xs       1102769/s    5936%    1381%       --
140
141    ---- [ Formula: mt ] ------------------------------------
142    perl     - distance from LA to NY: 2443.08796228363 miles
143    xs       - distance from LA to NY: 2443.08796228363 miles
144    gis_fast - distance from LA to NY: 2443.08796228363 miles
145
146                Rate gis_fast     perl       xs
147    gis_fast   17935/s       --     -75%     -98%
148    perl       71739/s     300%       --     -94%
149    xs       1135525/s    6231%    1483%       --
150
151This distribution contains another benchmarking script which compares
152only the XS formulas over several different coordinates:
153
154            Rate    tv  hsin   alt   cos    mt   gcd polar
155    tv     16906/s    --  -90%  -90%  -91%  -91%  -91%  -92%
156    hsin  165414/s  878%    --   -4%   -8%  -10%  -13%  -17%
157    alt   172032/s  918%    4%    --   -5%   -7%   -9%  -14%
158    cos   180326/s  967%    9%    5%    --   -2%   -5%  -10%
159    mt    184357/s  991%   11%    7%    2%    --   -3%   -8%
160    gcd   189253/s 1019%   14%   10%    5%    3%    --   -6%
161    polar 200386/s 1085%   21%   16%   11%    9%    6%    --
162
163    Calculated length for short distance:
164        alt  : 40.3740136064528 miles
165        cos  : 40.3095459813536 miles
166        gcd  : 40.3095459813294 miles
167        hsin : 40.3095459813294 miles
168        mt   : 40.3095459813536 miles
169        polar: 46.7467797109043 miles
170        tv   : 40.3740136384531 miles
171
172    Calculated length for long distance:
173        alt  : 2448.24135691376 miles
174        cos  : 2443.08796228363 miles
175        gcd  : 2443.08796228363 miles
176        hsin : 2443.08796228363 miles
177        mt   : 2443.08796228363 miles
178        polar: 2766.02509696782 miles
179        tv   : 2448.2413523656 miles
180
181    Calculated length for nearly antipodes:
182        alt  : 12340.6455133245 miles
183        cos  : 12340.327635068 miles
184        gcd  : 12340.327635068 miles
185        hsin : 12340.327635068 miles
186        mt   : 12340.327635068 miles
187        polar: 12368.4764642469 miles
188        tv   : 12340.7483034002 miles
189
190    Calculated length for antipodes:
191        alt  : 12429.86673988 miles
192        cos  : 219.005548031861 miles
193        gcd  : 12438.0476860875 miles
194        hsin : 12438.0475680956 miles
195        mt   : 219.005548031861 miles
196        polar: 12438.0476860875 miles
197        tv   : 12370.1885059814 miles
198
199    Calculated length for polar antipodes:
200        alt  : 12429.86673988 miles
201        cos  : 12438.0476860875 miles
202        gcd  : 12438.0476860875 miles
203        hsin : 12438.0476860875 miles
204        mt   : 12438.0476860875 miles
205        polar: 12438.0476860875 miles
206        tv   : 12429.8667398787 miles
207
208=head1 SEE ALSO
209
210L<Geo::Distance>
211
212L<http://blogs.esri.com/esri/apl/2010/09/28/fast-times-at-geodesic-high/>
213
214=head1 REQUESTS AND BUGS
215
216Please report any bugs or feature requests to
217L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Geo-Distance-XS>. I will be
218notified, and then you'll automatically be notified of progress on your bug as
219I make changes.
220
221=head1 SUPPORT
222
223You can find documentation for this module with the perldoc command.
224
225    perldoc Geo::Distance::XS
226
227You can also look for information at:
228
229=over
230
231=item * GitHub Source Repository
232
233L<http://github.com/gray/geo-distance-xs>
234
235=item * AnnoCPAN: Annotated CPAN documentation
236
237L<http://annocpan.org/dist/Geo-Distance-XS>
238
239=item * CPAN Ratings
240
241L<http://cpanratings.perl.org/d/Geo-Distance-XS>
242
243=item * RT: CPAN's request tracker
244
245L<http://rt.cpan.org/Public/Dist/Display.html?Name=Geo-Distance-XS>
246
247=item * Search CPAN
248
249L<http://search.cpan.org/dist/Geo-Distance-XS/>
250
251=back
252
253=head1 COPYRIGHT AND LICENSE
254
255Copyright (C) 2009-2014 gray <gray at cpan.org>, all rights reserved.
256
257This library is free software; you can redistribute it and/or modify it
258under the same terms as Perl itself.
259
260=head1 AUTHOR
261
262gray, <gray at cpan.org>
263
264=cut
265