File Coverage

blib/lib/Geo/GeoPo.pm
Criterion Covered Total %
statement 37 37 100.0
branch 2 2 100.0
condition 2 2 100.0
subroutine 8 8 100.0
pod 2 2 100.0
total 51 51 100.0


line stmt bran cond sub pod time code
1             package Geo::GeoPo;
2              
3 3     3   197455 use strict;
  3         7  
  3         102  
4 3     3   165 use warnings;
  3         6  
  3         78  
5 3     3   15 use Carp;
  3         9  
  3         446  
6              
7 3     3   2871 use version; our $VERSION = '0.0.1';
  3         17030  
  3         20  
8 3     3   286 use vars qw(@ISA @EXPORT);
  3         6  
  3         190  
9 3     3   18 use Exporter;
  3         5  
  3         1447  
10             @ISA = qw(Exporter);
11             @EXPORT = qw(latlng2geopo geopo2latlng);
12              
13             # 64characters (number + big and small letter + hyphen + underscore)
14             my $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
15              
16             # GeoPo Encode in Perl
17             sub latlng2geopo {
18 6     6 1 28499 my ( $lat, $lng, $scale, $arg ) = @_;
19 6         13 my $geopo = "";
20 6   100     29 $arg ||= {};
21              
22             # Change a degree measure to a decimal number
23 6         162 $lat = ($lat + 90) / 180 * 8 ** 10;
24 6         15 $lng = ($lng + 180) / 360 * 8 ** 10;
25              
26             # Compute a GeoPo code from head and concatenate
27 6         24 for( my $i = 0; $i < $scale; $i++) {
28 38         143 $geopo .= substr($chars, int($lat / 8 ** (9 - $i) % 8) + int($lng / 8 ** (9 - $i) % 8) * 8, 1);
29             }
30            
31 6 100       23 $geopo = "http://geopo.at/$geopo" if ($arg->{as_url});
32              
33 6         30 return $geopo;
34             }
35              
36             # GeoPo Decode in Perl
37             sub geopo2latlng {
38 6     6 1 25497 my $geopo = shift;
39              
40 6         22 $geopo =~ s!http://geopo.at/!!;
41 6         16 my ( $lat, $lng, $scale ) = ( 0, 0, length($geopo) );
42            
43 6         26 for ( my $i = 0; $i < $scale; $i++ ) {
44             # What number of character that equal to a GeoPo code (0-63)
45 38         74 my $order = index($chars, substr($geopo, $i, 1));
46            
47             # Lat/Lng plus geolocation value of scale
48 38         70 $lat += $order % 8 * 8 ** (9 - $i);
49 38         268 $lng += int($order / 8) * 8 ** (9 - $i);
50             }
51              
52             # Change a decimal number to a degree measure, and plus revised value that shift center of area
53 6         19 $lat = $lat * 180 / 8 ** 10 - 90 + 180 / 8 ** $scale / 2;
54 6         13 $lng = $lng * 360 / 8 ** 10 - 180 + 360 / 8 ** $scale / 2;
55              
56 6         24 return ( $lat, $lng, $scale );
57             }
58              
59             1;
60             __END__