line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Geo::Coordinates::Converter; |
2
|
8
|
|
|
8
|
|
498027
|
use strict; |
|
8
|
|
|
|
|
16
|
|
|
8
|
|
|
|
|
264
|
|
3
|
8
|
|
|
8
|
|
39
|
use warnings; |
|
8
|
|
|
|
|
13
|
|
|
8
|
|
|
|
|
325
|
|
4
|
|
|
|
|
|
|
use Class::Accessor::Lite ( |
5
|
8
|
|
|
|
|
58
|
rw => [qw/ source current /], |
6
|
8
|
|
|
8
|
|
6616
|
); |
|
8
|
|
|
|
|
9576
|
|
7
|
|
|
|
|
|
|
|
8
|
8
|
|
|
8
|
|
1001
|
use 5.008001; |
|
8
|
|
|
|
|
52
|
|
|
8
|
|
|
|
|
415
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.13'; |
11
|
|
|
|
|
|
|
|
12
|
8
|
|
|
8
|
|
38
|
use Carp; |
|
8
|
|
|
|
|
14
|
|
|
8
|
|
|
|
|
795
|
|
13
|
8
|
|
|
8
|
|
9983
|
use String::CamelCase qw( camelize ); |
|
8
|
|
|
|
|
6560
|
|
|
8
|
|
|
|
|
623
|
|
14
|
8
|
|
|
8
|
|
10453
|
use Module::Load (); |
|
8
|
|
|
|
|
10620
|
|
|
8
|
|
|
|
|
1393
|
|
15
|
|
|
|
|
|
|
|
16
|
8
|
|
|
8
|
|
4331
|
use Geo::Coordinates::Converter::Point; |
|
8
|
|
|
|
|
24
|
|
|
8
|
|
|
|
|
8846
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $DEFAULT_CONVERTER = 'Geo::Coordinates::Converter::Datum'; |
19
|
|
|
|
|
|
|
our $DEFAULT_FORMAT = [qw/ Degree Dms Milliseconds ISO6709 /]; |
20
|
|
|
|
|
|
|
our $DEFAULT_INETRNAL_FORMAT = 'degree'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub add_default_formats { |
23
|
0
|
|
|
0
|
0
|
0
|
my($class, @formats) = @_; |
24
|
0
|
|
|
|
|
0
|
my %default_formats = map { $_ => 1 } @{ $DEFAULT_FORMAT }, @formats; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
25
|
0
|
|
|
|
|
0
|
$DEFAULT_FORMAT = [ keys %default_formats ]; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub new { |
29
|
68
|
|
|
68
|
1
|
725185
|
my($class, %opt) = @_; |
30
|
|
|
|
|
|
|
|
31
|
68
|
|
33
|
|
|
564
|
my $converter = delete $opt{converter} || $DEFAULT_CONVERTER; |
32
|
68
|
50
|
|
|
|
256
|
unless (ref $converter) { |
33
|
68
|
|
|
|
|
361
|
Module::Load::load($converter); |
34
|
68
|
50
|
|
|
|
11070
|
$converter = $converter->new unless ref $converter; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
68
|
|
33
|
|
|
408
|
my $internal_format = delete $opt{internal_format} || $DEFAULT_INETRNAL_FORMAT; |
38
|
68
|
|
|
|
|
2288
|
my $formats = delete $opt{formats}; |
39
|
68
|
|
66
|
|
|
690
|
my $source = delete $opt{point} || Geo::Coordinates::Converter::Point->new(\%opt); |
40
|
|
|
|
|
|
|
|
41
|
68
|
|
|
|
|
2729
|
my $self = bless { |
42
|
|
|
|
|
|
|
source => $source, |
43
|
|
|
|
|
|
|
formats => {}, |
44
|
|
|
|
|
|
|
converter => $converter, |
45
|
|
|
|
|
|
|
internal_format => $internal_format, |
46
|
|
|
|
|
|
|
}, $class; |
47
|
|
|
|
|
|
|
|
48
|
68
|
|
|
|
|
112
|
my @plugins = @{ $DEFAULT_FORMAT }; |
|
68
|
|
|
|
|
321
|
|
49
|
68
|
50
|
|
|
|
1182
|
push @plugins, @{ $formats } if ref $formats eq 'ARRAY'; |
|
0
|
|
|
|
|
0
|
|
50
|
68
|
|
|
|
|
153
|
for my $plugin (@plugins) { |
51
|
272
|
|
|
|
|
2375
|
$self->load_format($plugin); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
68
|
50
|
|
|
|
322
|
$self->format_detect($self->source) unless $source->format; |
55
|
68
|
|
|
|
|
401
|
$self->normalize($self->source); |
56
|
68
|
|
|
|
|
249
|
$self->reset; |
57
|
|
|
|
|
|
|
|
58
|
68
|
|
|
|
|
785
|
$self; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub load_format { |
62
|
272
|
|
|
272
|
0
|
414
|
my($self, $format) = @_; |
63
|
|
|
|
|
|
|
|
64
|
272
|
50
|
|
|
|
629
|
unless (ref $format) { |
65
|
272
|
50
|
|
|
|
672
|
if ($format =~ s/^\+//) { |
66
|
0
|
|
|
|
|
0
|
Module::Load::load($format); |
67
|
|
|
|
|
|
|
} else { |
68
|
272
|
|
|
|
|
486
|
my $name = $format; |
69
|
272
|
|
|
|
|
967
|
$format = sprintf '%s::Format::%s', ref $self, camelize($name); |
70
|
272
|
|
|
|
|
5623
|
Module::Load::load($format); |
71
|
|
|
|
|
|
|
} |
72
|
272
|
|
|
|
|
21066
|
$format = $format->new; |
73
|
|
|
|
|
|
|
} |
74
|
272
|
|
|
|
|
1482
|
$self->formats($format->name, $format); |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub formats { |
78
|
932
|
|
|
932
|
1
|
3167
|
my($self, $format, $plugin) = @_; |
79
|
932
|
100
|
|
|
|
2617
|
$self->{formats}->{$format} = $plugin if $plugin; |
80
|
932
|
100
|
|
|
|
7091
|
wantarray ? keys %{ $self->{formats} } : $self->{formats}->{$format}; |
|
68
|
|
|
|
|
318
|
|
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub format_detect { |
84
|
68
|
|
|
68
|
0
|
1919
|
my($self, $point) = @_; |
85
|
|
|
|
|
|
|
|
86
|
68
|
|
|
|
|
241
|
for my $format ($self->formats) { |
87
|
174
|
|
|
|
|
593
|
my $name = $self->formats($format)->detect($point); |
88
|
174
|
100
|
|
|
|
14213
|
next unless $name; |
89
|
68
|
|
|
|
|
209
|
$point->format($name); |
90
|
68
|
|
|
|
|
2666
|
last; |
91
|
|
|
|
|
|
|
} |
92
|
68
|
|
|
|
|
239
|
$point->format; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
0
|
0
|
0
|
sub normaraiz { goto &normalize; } # alias for backward compatibility. |
96
|
|
|
|
|
|
|
sub normalize { |
97
|
68
|
|
|
68
|
0
|
393
|
my($self, $point) = @_; |
98
|
68
|
|
|
|
|
192
|
$self->formats($point->format)->normalize($point); |
99
|
68
|
|
|
|
|
915
|
$point; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub convert { |
103
|
10
|
|
|
10
|
1
|
167
|
my($self, @opt) = @_; |
104
|
10
|
50
|
|
|
|
33
|
return $self->point unless @opt; |
105
|
|
|
|
|
|
|
|
106
|
10
|
|
|
|
|
46
|
my $point = $self->source->clone; |
107
|
10
|
|
|
|
|
46
|
my $format = $point->format; |
108
|
10
|
|
|
|
|
92
|
$self->format($self->{internal_format}, $point); |
109
|
10
|
|
|
|
|
35
|
for my $type (@opt) { |
110
|
12
|
100
|
|
|
|
32
|
if ($self->formats($type)) { |
111
|
8
|
100
|
|
|
|
43
|
$format = $type unless $format eq $type; |
112
|
|
|
|
|
|
|
} else { |
113
|
4
|
|
|
|
|
6
|
eval { $self->datum($type, $point) }; |
|
4
|
|
|
|
|
17
|
|
114
|
4
|
50
|
|
|
|
27
|
croak "It dosen't correspond to the $type format/datum: $@" if $@; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
} |
117
|
10
|
|
|
|
|
35
|
$self->format($format, $point); |
118
|
|
|
|
|
|
|
|
119
|
10
|
|
|
|
|
79
|
$point->$_( $self->$_($point) ) for qw/ lat lng /; |
120
|
10
|
|
|
|
|
106
|
$self->current($point->clone); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
for my $meth (qw/ lat lng /) { |
124
|
8
|
|
|
8
|
|
76
|
no strict 'refs'; |
|
8
|
|
|
|
|
12
|
|
|
8
|
|
|
|
|
5786
|
|
125
|
|
|
|
|
|
|
*{__PACKAGE__ . "::$meth"} = sub { |
126
|
136
|
|
|
136
|
|
62752
|
my $self = shift; |
127
|
136
|
|
66
|
|
|
631
|
my $point = shift || $self->current; |
128
|
136
|
|
|
|
|
3262
|
$self->formats($point->format)->round($point->$meth); |
129
|
|
|
|
|
|
|
}; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
sub height { |
132
|
13
|
|
|
13
|
0
|
4382
|
my $self = shift; |
133
|
13
|
|
33
|
|
|
48
|
my $point = shift || $self->current; |
134
|
13
|
|
|
|
|
115
|
$point->height; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub datum { |
138
|
22
|
|
|
22
|
1
|
4262
|
my $self = shift; |
139
|
|
|
|
|
|
|
|
140
|
22
|
100
|
|
|
|
63
|
if (my $datum = shift) { |
141
|
9
|
|
66
|
|
|
41
|
my $point = shift || $self->current; |
142
|
9
|
100
|
|
|
|
56
|
return $self if $point->datum eq $datum; |
143
|
|
|
|
|
|
|
|
144
|
8
|
|
|
|
|
64
|
my $format = $point->format; |
145
|
8
|
|
|
|
|
64
|
$self->format($self->{internal_format}, $point); |
146
|
8
|
|
|
|
|
75
|
$self->{converter}->convert($point => $datum); |
147
|
8
|
|
|
|
|
26
|
$self->format($format, $point); |
148
|
|
|
|
|
|
|
|
149
|
8
|
|
|
|
|
38
|
return $self; |
150
|
|
|
|
|
|
|
} else { |
151
|
13
|
|
|
|
|
33
|
return $self->current->datum; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub format { |
156
|
89
|
|
|
89
|
1
|
27718
|
my $self = shift; |
157
|
|
|
|
|
|
|
|
158
|
89
|
100
|
|
|
|
262
|
if (my $fmt = shift) { |
159
|
72
|
50
|
|
|
|
168
|
croak "It dosen't correspond to the $fmt format" unless $self->formats($fmt); |
160
|
72
|
|
66
|
|
|
288
|
my $point = shift || $self->current; |
161
|
72
|
100
|
|
|
|
366
|
return $self if $point->format eq $fmt; |
162
|
|
|
|
|
|
|
|
163
|
58
|
|
|
|
|
417
|
$self->formats($point->format)->to($point); |
164
|
58
|
|
|
|
|
159
|
$self->formats($fmt)->from($point); |
165
|
58
|
|
|
|
|
167
|
$point->format($fmt); |
166
|
|
|
|
|
|
|
|
167
|
58
|
|
|
|
|
372
|
return $self; |
168
|
|
|
|
|
|
|
} else { |
169
|
17
|
|
|
|
|
92
|
return $self->current->format; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub round { |
174
|
14
|
|
|
14
|
0
|
18
|
my($self, $point) = @_; |
175
|
14
|
|
|
|
|
35
|
my $fmt = $self->formats($point->format); |
176
|
14
|
|
|
|
|
56
|
$point->$_($fmt->round($point->$_)) for (qw/ lat lng /); |
177
|
14
|
|
|
|
|
111
|
$point; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub point { |
181
|
14
|
|
|
14
|
1
|
39
|
my($self, $point) = @_; |
182
|
14
|
|
33
|
|
|
50
|
$point ||= $self->current; |
183
|
14
|
|
|
|
|
91
|
$self->round($point->clone); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub reset { |
187
|
68
|
|
|
68
|
0
|
108
|
my $self = shift; |
188
|
68
|
|
|
|
|
195
|
$self->current($self->source->clone); |
189
|
68
|
|
|
|
|
468
|
$self; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
1; |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
__END__ |