File Coverage

blib/lib/Geo/LocaPoint.pm
Criterion Covered Total %
statement 67 68 98.5
branch 11 16 68.7
condition 4 6 66.6
subroutine 15 15 100.0
pod 8 8 100.0
total 105 113 92.9


line stmt bran cond sub pod time code
1             package Geo::LocaPoint;
2              
3 6     6   386390 use warnings;
  6         13  
  6         182  
4 6     6   30 use strict;
  6         12  
  6         157  
5 6     6   31 use Carp;
  6         12  
  6         442  
6              
7 6     6   5514 use version; our $VERSION = qv('0.0.4');
  6         40980  
  6         38  
8 6     6   574 use vars qw(@ISA @EXPORT @EXPORT_OK);
  6         10  
  6         343  
9 6     6   31 use Exporter;
  6         13  
  6         2102  
10             @ISA = qw(Exporter);
11             @EXPORT = qw(latlng2locapoint locapoint2latlng);
12             @EXPORT_OK = qw(latlng2locaporterbase locaporterbase2latlng);
13              
14 6     6   5941 use Math::Round qw(nhimult);
  6         100584  
  6         6787  
15              
16             my @devider = (1757600,67600,6760,260,10,1);
17              
18             # Internal methods
19              
20             sub int2code {
21 96     96 1 143 my ($value,$count,$precision,$islocapo) = @_;
22 96         155 my $this = int($value / $devider[$count]);
23 96         134 my $low = $value % $devider[$count];
24 96 100 100     374 $this = pack "C", 65 + $this if (!$islocapo || ($count % 3 != 2));
25 96 100       205 if ($count < $precision - 1) {
26 76         174 $this .= int2code($low,$count+1,$precision,$islocapo);
27             }
28 96         210 return $this;
29             }
30              
31             sub code2int {
32 96     96 1 124 my ($value,$count) = @_;
33 96         132 my $this = substr($value,0,1);
34 96         115 my $low = substr($value,1);
35 96 100       300 $this = unpack("C",$this) - 65 if ($this =~ /^[A-Z]$/);
36 96         122 $this *= $devider[$count];
37 96 100       171 if ($low ne '') {
38 76         164 $this += code2int($low,$count+1);
39             }
40 96         153 return $this;
41             }
42              
43             sub latlng2code {
44 10     10 1 25 my ($lat,$lng,$precision,$islocapo) = @_;
45              
46 10         50 $lat = int(($lat + 90) * 2284880 / 9);
47 10         29 $lng = int(($lng + 180) *1142440 / 9);
48              
49 10         24 foreach ($lat,$lng) {
50 20   33     125 while (($_ < 0) || ($_ > 45697599)) {
51 0 0       0 $_ = $_ < 0 ? $_ + 45697600 : $_ - 45697600;
52             }
53 20         49 $_ = int2code($_,0,$precision,$islocapo);
54             }
55            
56 10         32 return ($lat,$lng);
57             }
58              
59             sub code2latlng {
60 10     10 1 17 my ($lat,$lng) = @_;
61              
62 10         19 foreach ($lat,$lng) {
63 20         44 $_ = code2int($_,0);
64             }
65              
66 10         52 $lat = nhimult(.000001,$lat * 9 / 2284880 - 90);
67 10         160 $lng = nhimult(.000001,$lng * 9 / 1142440 - 180);
68              
69 10         83 return ($lat,$lng);
70             }
71              
72             # Export methods
73              
74             sub latlng2locapoint {
75 2     2 1 10644 my ($lat,$lng) = @_;
76              
77 2         8 ($lat,$lng) = latlng2code($lat,$lng,6,1);
78            
79 2         16 my $locapo = sprintf("%s.%s.%s.%s",substr($lat,0,3),substr($lng,0,3),substr($lat,3,3),substr($lng,3,3));
80 2         12 return $locapo;
81             }
82              
83             sub locapoint2latlng {
84 2     2 1 9387 my $locapo = shift;
85            
86 2 50       16 $locapo =~ /^([A-Z][A-Z][0-9])\.([A-Z][A-Z][0-9])\.([A-Z][A-Z][0-9])\.([A-Z][A-Z][0-9])$/ or croak "Argument $locapo is not locapoint!!";
87 2         9 my $lat = $1.$3;
88 2         6 my $lng = $2.$4;
89              
90 2         7 return code2latlng($lat,$lng);
91             }
92              
93             sub latlng2locaporterbase {
94 8     8 1 30550 my ($lat,$lng,$precision) = @_;
95              
96 8         24 ($lat,$lng) = latlng2code($lat,$lng,$precision);
97 8         21 $lng = lc($lng);
98              
99 8 50       41 return wantarray ? ($lat, $lng) : $lat.$lng;
100             }
101              
102             sub locaporterbase2latlng {
103 8     8 1 23931 my ($lat,$lng) = @_;
104              
105 8 50       28 unless (defined($lng)) {
106 8         42 ($lat,$lng) = $lat =~ /^([A-Z]+)([a-z]+)$/;
107             }
108              
109 8         20 $lng = uc($lng);
110              
111 8         20 return code2latlng($lat,$lng);
112             }
113              
114             1; # Magic true value required at end of module
115             __END__