File Coverage

blib/lib/Geo/Coordinates/ETRSTM35FIN.pm
Criterion Covered Total %
statement 115 117 98.2
branch 12 16 75.0
condition 14 18 77.7
subroutine 13 13 100.0
pod 4 8 50.0
total 158 172 91.8


line stmt bran cond sub pod time code
1             package Geo::Coordinates::ETRSTM35FIN;
2              
3 4     4   129707 use 5.008006;
  4         13  
  4         180  
4 4     4   27 use strict;
  4         10  
  4         184  
5 4     4   22 use warnings;
  4         16  
  4         772  
6 4     4   26 use Carp;
  4         12  
  4         435  
7 4     4   15325 use Math::Trig;
  4         117033  
  4         10898  
8              
9             our $VERSION = '0.01';
10              
11             sub new {
12 4     4 0 52 my $class = shift;
13            
14 4         9 my $self = {};
15              
16 4         14 bless($self, $class);
17              
18             # Constants used in calculations transforming between WGS84 and ETRS-TM35FIN
19 4         23 add_constant($self, 'Ca', 6378137.0);
20 4         12 add_constant($self, 'Cb', 6356752.314245);
21 4         28 add_constant($self, 'Cf', 1.0 / 298.257223563);
22 4         10 add_constant($self, 'Ck0', 0.9996);
23 4         26 add_constant($self, 'Clo0', Math::Trig::deg2rad(27.0));
24 4         12 add_constant($self, 'CE0', 500000.0);
25 4         19 add_constant($self, 'Cn', get_c($self, 'Cf') / (2.0 - get_c($self, 'Cf')));
26 4         15 add_constant($self, 'CA1', get_c($self, 'Ca') / (1.0 + get_c($self, 'Cn')) * (1.0 + (get_c($self, 'Cn') ** 2.0) / 4.0 + (get_c($self, 'Cn') ** 4.0) / 64.0));
27 4         16 add_constant($self, 'Ce', sqrt(2.0 * get_c($self, 'Cf') - get_c($self, 'Cf') ** 2.0));
28 4         11 add_constant($self, 'Ch1', 1.0/2.0 * get_c($self, 'Cn') - 2.0/3.0 * (get_c($self, 'Cn') ** 2.0) + 37.0/96.0 * (get_c($self, 'Cn') ** 3.0) - 1.0/360.0 * (get_c($self, 'Cn') ** 4.0));
29 4         12 add_constant($self, 'Ch2', 1.0/48.0 * (get_c($self, 'Cn') ** 2.0) + 1.0/15.0 * (get_c($self, 'Cn') ** 3.0) - 437.0/1440.0 * (get_c($self, 'Cn') ** 4.0));
30 4         11 add_constant($self, 'Ch3', 17.0/480.0 * (get_c($self, 'Cn') ** 3.0) - 37.0/840.0 * (get_c($self, 'Cn') ** 4.0));
31 4         12 add_constant($self, 'Ch4', 4397.0/161280.0 * (get_c($self, 'Cn') ** 4.0));
32 4         11 add_constant($self, 'Ch1p', 1.0/2.0 * get_c($self, 'Cn') - 2.0/3.0 * (get_c($self, 'Cn') ** 2.0) + 5.0/16.0 * (get_c($self, 'Cn') ** 3.0) + 41.0/180.0 * (get_c($self, 'Cn') ** 4.0));
33 4         12 add_constant($self, 'Ch2p', 13.0/48.0 * (get_c($self, 'Cn') ** 2.0) - 3.0/5.0 * (get_c($self, 'Cn') ** 3.0) + 557.0/1440.0 * (get_c($self, 'Cn') ** 4.0));
34 4         12 add_constant($self, 'Ch3p', 61.0/240.0 * (get_c($self, 'Cn') ** 3.0) - 103.0/140.0 * (get_c($self, 'Cn') ** 4.0));
35 4         13 add_constant($self, 'Ch4p', 49561.0/161280.0 * (get_c($self, 'Cn') ** 4.0));
36              
37             # WGS84 bounds (ref. http://spatialreference.org/ref/epsg/3067/)
38 4         34 add_constant($self, 'WGS84_min_la', "59.3000");
39 4         10 add_constant($self, 'WGS84_max_la', "70.1300");
40 4         12 add_constant($self, 'WGS84_min_lo', "19.0900");
41 4         9 add_constant($self, 'WGS84_max_lo', "31.5900");
42              
43             # ETRS-TM35FIN bounds (ref. http://spatialreference.org/ref/epsg/3067/)
44 4         8 add_constant($self, 'ETRSTM35FIN_min_x', "6582464.0358");
45 4         10 add_constant($self, 'ETRSTM35FIN_max_x', "7799839.8902");
46 4         9 add_constant($self, 'ETRSTM35FIN_min_y', "50199.4814");
47 4         9 add_constant($self, 'ETRSTM35FIN_max_y', "761274.6247");
48            
49 4         88 return $self;
50             }
51              
52             sub add_constant {
53 100     100 0 210 my ($class, $constant_name, $constant_value) = @_;
54            
55 100         212 $class->{$constant_name} = $constant_value;
56            
57 100         130 return;
58             }
59              
60             sub get_constant {
61 512     512 0 625 my ($class, $constant_name) = @_;
62            
63 512         2607 return $class->{$constant_name};
64             }
65              
66             # Alias for get_constant
67              
68             sub get_c {
69 512     512 0 848 my ($class, $constant_name) = @_;
70            
71 512         826 return get_constant($class, $constant_name);
72             }
73              
74             sub is_defined_ETRSTM35FINxy {
75 22     22 1 8548 my @params = @_;
76 22         59 my ($class, $etrs_x, $etrs_y) = @params;
77            
78 22 50       56 if (scalar(@params) != 3) {
79 0         0 croak 'Geo::Coordinates::ETRSTM35FIN::is_defined_ETRSTM35FINxy needs two arguments';
80             }
81              
82 22 50 100     58 if (($etrs_x >= get_c($class, 'ETRSTM35FIN_min_x')) and ($etrs_x <= get_c($class, 'ETRSTM35FIN_max_x')) and
      66        
      66        
83             ($etrs_y >= get_c($class, 'ETRSTM35FIN_min_y')) and ($etrs_y <= get_c($class, 'ETRSTM35FIN_max_y'))) {
84             # Is in bounds
85 14         134 return 1;
86             }
87            
88 8         27 return;
89             }
90              
91             sub is_defined_WGS84lalo {
92 22     22 1 2023 my @params = @_;
93 22         62 my ($class, $wgs_la, $wgs_lo) = @params;
94            
95 22 50       55 if (scalar(@params) != 3) {
96 0         0 croak 'Geo::Coordinates::ETRSTM35FIN::is_defined_WGS84lalo needs two arguments';
97             }
98              
99 22 50 100     47 if (($wgs_la >= get_c($class, 'WGS84_min_la')) and ($wgs_la <= get_c($class, 'WGS84_max_la')) and
      66        
      66        
100             ($wgs_lo >= get_c($class, 'WGS84_min_lo')) and ($wgs_lo <= get_c($class, 'WGS84_max_lo'))) {
101             # Is in bounds
102 14         53 return 1;
103             }
104            
105 8         27 return;
106             }
107            
108             sub ETRSTM35FINxy_to_WGS84lalo {
109 14     14 1 5854 my @params = @_;
110 14         30 my ($class, $etrs_x, $etrs_y) = @params;
111              
112 14 100       47 if (scalar(@params) != 3) {
113 3         35 croak 'Geo::Coordinates::ETRSTM35FIN::ETRSTM35FINxy_to_WGS84lalo needs two arguments'
114             }
115              
116 11 100       28 if (!is_defined_ETRSTM35FINxy($class,$etrs_x, $etrs_y)) {
117 4         21 return (undef, undef);
118             }
119            
120 7         18 my $E = $etrs_x / (get_c($class,'CA1') * get_c($class,'Ck0'));
121 7         23 my $nn = ($etrs_y - get_c($class,'CE0')) / (get_c($class,'CA1') * get_c($class,'Ck0'));
122            
123 7         19 my $E1p = get_c($class,'Ch1') * sin(2.0 * $E) * Math::Trig::cosh(2.0 * $nn);
124 7         90 my $E2p = get_c($class,'Ch2') * sin(4.0 * $E) * Math::Trig::cosh(4.0 * $nn);
125 7         64 my $E3p = get_c($class,'Ch3') * sin(6.0 * $E) * Math::Trig::cosh(6.0 * $nn);
126 7         62 my $E4p = get_c($class,'Ch4') * sin(8.0 * $E) * Math::Trig::cosh(8.0 * $nn);
127 7         58 my $nn1p = get_c($class,'Ch1') * cos(2.0 * $E) * Math::Trig::sinh(2.0 * $nn);
128 7         75 my $nn2p = get_c($class,'Ch2') * cos(4.0 * $E) * Math::Trig::sinh(4.0 * $nn);
129 7         69 my $nn3p = get_c($class,'Ch3') * cos(6.0 * $E) * Math::Trig::sinh(6.0 * $nn);
130 7         64 my $nn4p = get_c($class,'Ch4') * cos(8.0 * $E) * Math::Trig::sinh(8.0 * $nn);
131 7         69 my $Ep = $E - $E1p - $E2p - $E3p - $E4p;
132 7         16 my $nnp = $nn - $nn1p - $nn2p - $nn3p - $nn4p;
133 7         23 my $be = Math::Trig::asin(sin($Ep) / Math::Trig::cosh($nnp));
134            
135 7         138 my $Q = Math::Trig::asinh(Math::Trig::tan($be));
136 7         167 my $Qp = $Q + get_c($class,'Ce') * Math::Trig::atanh(get_c($class,'Ce') * Math::Trig::tanh($Q));
137 7         188 $Qp = $Q + get_c($class,'Ce') * Math::Trig::atanh(get_c($class,'Ce') * Math::Trig::tanh($Qp));
138 7         161 $Qp = $Q + get_c($class,'Ce') * Math::Trig::atanh(get_c($class,'Ce') * Math::Trig::tanh($Qp));
139 7         152 $Qp = $Q + get_c($class,'Ce') * Math::Trig::atanh(get_c($class,'Ce') * Math::Trig::tanh($Qp));
140            
141 7         152 my $wgs_la = Math::Trig::rad2deg(Math::Trig::atan(Math::Trig::sinh($Qp)));
142 7         155 my $wgs_lo = Math::Trig::rad2deg(get_c($class,'Clo0') + Math::Trig::asin(Math::Trig::tanh($nnp) / cos($be)));
143              
144 7         216 return ($wgs_la, $wgs_lo);
145             }
146              
147             sub WGS84lalo_to_ETRSTM35FINxy {
148 14     14 1 23246 my @params = @_;
149 14         58 my ($class, $wgs_la, $wgs_lo) = @params;
150            
151 14 100       53 if (scalar(@params) != 3) {
152 3         21 croak 'Geo::Coordinates::ETRSTM35FIN::WGS84lalo_to_ETRSTM35FINxy needs two arguments'
153             }
154              
155 11 100       32 if (!is_defined_WGS84lalo($class, $wgs_la, $wgs_lo)) {
156 4         13 return (undef, undef);
157             }
158            
159 7         32 my $la = Math::Trig::deg2rad($wgs_la);
160 7         88 my $lo = Math::Trig::deg2rad($wgs_lo);
161            
162 7         65 my $Q = Math::Trig::asinh(Math::Trig::tan($la)) - get_c($class,'Ce') * Math::Trig::atanh(get_c($class,'Ce') * sin($la));
163 7         66 my $be = Math::Trig::atan(Math::Trig::sinh($Q));
164 7         98 my $nnp = Math::Trig::atanh(cos($be) * sin($lo - get_c($class,'Clo0')));
165 7         68 my $Ep = Math::Trig::asin(sin($be) * Math::Trig::cosh($nnp));
166 7         97 my $E1 = get_c($class,'Ch1p') * sin(2.0 * $Ep) * Math::Trig::cosh(2.0 * $nnp);
167 7         60 my $E2 = get_c($class,'Ch2p') * sin(4.0 * $Ep) * Math::Trig::cosh(4.0 * $nnp);
168 7         59 my $E3 = get_c($class,'Ch3p') * sin(6.0 * $Ep) * Math::Trig::cosh(6.0 * $nnp);
169 7         56 my $E4 = get_c($class,'Ch4p') * sin(8.0 * $Ep) * Math::Trig::cosh(8.0 * $nnp);
170            
171 7         60 my $nn1 = get_c($class,'Ch1p') * cos(2.0 * $Ep) * Math::Trig::sinh(2.0 * $nnp);
172 7         69 my $nn2 = get_c($class,'Ch2p') * cos(4.0 * $Ep) * Math::Trig::sinh(4.0 * $nnp);
173 7         65 my $nn3 = get_c($class,'Ch3p') * cos(6.0 * $Ep) * Math::Trig::sinh(6.0 * $nnp);
174 7         63 my $nn4 = get_c($class,'Ch4p') * cos(8.0 * $Ep) * Math::Trig::sinh(8.0 * $nnp);
175 7         65 my $E = $Ep + $E1 + $E2 + $E3 + $E4;
176 7         14 my $nn = $nnp + $nn1 + $nn2 + $nn3 + $nn4;
177            
178 7         19 my $etrs_x = get_c($class,'CA1') * $E * get_c($class,'Ck0');
179 7         22 my $etrs_y = get_c($class,'CA1') * $nn * get_c($class,'Ck0') + get_c($class,'CE0');
180              
181 7         31 return ($etrs_x, $etrs_y);
182             }
183              
184             1;
185              
186             __END__