| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Geo::Elevation::HGT; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
52734
|
use 5.010; |
|
|
1
|
|
|
|
|
3
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
17
|
|
|
5
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
20
|
|
|
6
|
1
|
|
|
1
|
|
402
|
use POSIX (); |
|
|
1
|
|
|
|
|
5046
|
|
|
|
1
|
|
|
|
|
24
|
|
|
7
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
578
|
|
|
8
|
|
|
|
|
|
|
# set the version for version checking |
|
9
|
|
|
|
|
|
|
our $VERSION = '0.08'; |
|
10
|
|
|
|
|
|
|
# file-private lexicals |
|
11
|
|
|
|
|
|
|
my $grid_size; # .hgt grid size = 3601x3601 for 1-minute DEMs or 7201x7201 for 0.5-minute DEMs or 1201x1201 for 3-minute DEMs |
|
12
|
|
|
|
|
|
|
my @DEMnames; |
|
13
|
|
|
|
|
|
|
my @default_DEMs; |
|
14
|
|
|
|
|
|
|
my @want_DEMnames; |
|
15
|
|
|
|
|
|
|
my $status_descr; |
|
16
|
|
|
|
|
|
|
my $url; |
|
17
|
|
|
|
|
|
|
my $folder; |
|
18
|
|
|
|
|
|
|
my $cache_folder; |
|
19
|
|
|
|
|
|
|
my $debug; |
|
20
|
|
|
|
|
|
|
my $bicubic; |
|
21
|
|
|
|
|
|
|
my $bicubic_current; |
|
22
|
|
|
|
|
|
|
my $bicubic_mixed; |
|
23
|
|
|
|
|
|
|
my $switch; |
|
24
|
|
|
|
|
|
|
my $cache; |
|
25
|
|
|
|
|
|
|
my $fail; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub new { |
|
28
|
0
|
|
|
0
|
1
|
|
my ($class, %params) = @_; |
|
29
|
0
|
|
|
|
|
|
%params = ( |
|
30
|
|
|
|
|
|
|
url => "https://elevation-tiles-prod.s3.amazonaws.com/skadi", # info at https://registry.opendata.aws/terrain-tiles/ |
|
31
|
|
|
|
|
|
|
folder => "https://elevation-tiles-prod.s3.amazonaws.com/skadi", |
|
32
|
|
|
|
|
|
|
cache_folder => "", |
|
33
|
|
|
|
|
|
|
debug => 0, |
|
34
|
|
|
|
|
|
|
bicubic => 0, |
|
35
|
|
|
|
|
|
|
bicubic_current => 0, |
|
36
|
|
|
|
|
|
|
bicubic_mixed => 0, |
|
37
|
|
|
|
|
|
|
%params |
|
38
|
|
|
|
|
|
|
); |
|
39
|
0
|
|
|
|
|
|
my $self = {}; |
|
40
|
0
|
|
|
|
|
|
while ( my($key,$value) = each %params ) { |
|
41
|
0
|
|
|
|
|
|
$self->{$key} = $value; |
|
42
|
|
|
|
|
|
|
} |
|
43
|
0
|
|
|
|
|
|
bless $self, $class; |
|
44
|
0
|
|
|
|
|
|
return $self; |
|
45
|
|
|
|
|
|
|
} |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub get_elevation_batch_hgt { |
|
48
|
0
|
|
|
0
|
1
|
|
my ($self, $batch_latlon) = @_; |
|
49
|
0
|
|
|
|
|
|
my @elegeh; |
|
50
|
0
|
|
|
|
|
|
for my $latlon ( @$batch_latlon ) { |
|
51
|
0
|
|
|
|
|
|
my ($lat, $lon) = @$latlon; |
|
52
|
0
|
|
|
|
|
|
push (@elegeh, $self->get_elevation_hgt ($lat, $lon)); |
|
53
|
|
|
|
|
|
|
} |
|
54
|
0
|
|
|
|
|
|
return \@elegeh; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub get_elevation_hgt { |
|
58
|
0
|
|
|
0
|
1
|
|
my ($self, $lat, $lon) = @_; |
|
59
|
0
|
|
|
|
|
|
$folder = $self->{folder}; |
|
60
|
0
|
|
|
|
|
|
$url = $self->{url}; |
|
61
|
0
|
|
|
|
|
|
$cache_folder = $self->{cache_folder}; |
|
62
|
0
|
|
|
|
|
|
$debug = $self->{debug}; |
|
63
|
0
|
|
|
|
|
|
$bicubic = $self->{bicubic}; |
|
64
|
0
|
|
|
|
|
|
$bicubic_current = $self->{bicubic_current}; |
|
65
|
0
|
|
|
|
|
|
$bicubic_mixed = $self->{bicubic_mixed}; |
|
66
|
0
|
|
|
|
|
|
$status_descr = "Memory"; |
|
67
|
0
|
0
|
|
|
|
|
say STDERR "get_elevation_hgt" if $debug; |
|
68
|
0
|
0
|
|
|
|
|
say STDERR " Parameters: folder=>'$folder', url=>'$url', cache_folder=>'$cache_folder', debug=>$debug, bicubic=>$bicubic" if $debug; |
|
69
|
0
|
0
|
|
|
|
|
say STDERR " Input lat lon: $lat $lon" if $debug; |
|
70
|
0
|
|
|
|
|
|
my $flat = POSIX::floor $lat; |
|
71
|
0
|
|
|
|
|
|
my $flon = POSIX::floor $lon; |
|
72
|
0
|
0
|
|
|
|
|
my $ns = $flat < 0 ? "S" : "N"; |
|
73
|
0
|
0
|
|
|
|
|
my $ew = $flon < 0 ? "W" : "E"; |
|
74
|
0
|
|
|
|
|
|
my $lt = sprintf ("%02s", abs($flat)); |
|
75
|
0
|
|
|
|
|
|
my $ln = sprintf ("%03s", abs($flon)); |
|
76
|
0
|
|
|
|
|
|
my $DEMname = "$ns$lt$ew$ln"; |
|
77
|
0
|
0
|
|
|
|
|
say STDERR " Tile lat lon: $flat $flon" if $debug; |
|
78
|
|
|
|
|
|
|
# read DEM unless already defined |
|
79
|
0
|
0
|
0
|
|
|
|
say STDERR " Using DEM in memory: '$flat $flon'" if ($debug and defined $self->{DEMs}{$DEMname}{DEM}); |
|
80
|
0
|
|
0
|
|
|
|
$self->{DEMs}{$DEMname}{DEM} //= $self->_readDEM($DEMname); # //= Logical Defined-Or Assignment Operator |
|
81
|
0
|
|
|
|
|
|
my $dem = $self->{DEMs}{$DEMname}{DEM}; |
|
82
|
0
|
0
|
|
|
|
|
say STDERR " Status: $status_descr" if $debug; |
|
83
|
0
|
|
|
|
|
|
$self->{lat} = $lat; |
|
84
|
0
|
|
|
|
|
|
$self->{lon} = $lon; |
|
85
|
0
|
|
|
|
|
|
$self->{status_descr} = $status_descr; |
|
86
|
0
|
|
|
|
|
|
$self->{switch} = $switch; |
|
87
|
0
|
|
|
|
|
|
$self->{cache} = $cache; |
|
88
|
0
|
|
|
|
|
|
$self->{fail} = $fail; |
|
89
|
0
|
|
|
|
|
|
$self->{DEMname} = $DEMname; |
|
90
|
0
|
0
|
|
|
|
|
if (ref($dem) eq "") { |
|
91
|
0
|
0
|
|
|
|
|
say STDERR " No data in DEM: '$flat $flon' returning elevation 0" if $debug; |
|
92
|
0
|
|
|
|
|
|
$self->{grid_size} = 0; |
|
93
|
0
|
|
|
|
|
|
$self->{elevation} = 0; |
|
94
|
0
|
|
|
|
|
|
return $self->{elevation}; |
|
95
|
|
|
|
|
|
|
} |
|
96
|
0
|
|
|
|
|
|
$grid_size = sqrt (length ($$dem)/2); # grid size of DEM |
|
97
|
0
|
0
|
0
|
|
|
|
unless ($grid_size == 3601 or $grid_size == 7201 or $grid_size == 1201) { |
|
|
|
|
0
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
croak "Unknown tile format for '$self->{DEMs}{$DEMname}{DEMpath}': grid size is '$grid_size', should be 3601 or 7201 or 1201"; |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
# the DEMs start in the NW corner with $grid_size - 1 intervals |
|
101
|
0
|
|
|
|
|
|
my $ilat = (1 - ($lat - $flat)) * ($grid_size - 1); |
|
102
|
0
|
|
|
|
|
|
my $ilon = ($lon - $flon) * ($grid_size - 1); |
|
103
|
0
|
0
|
|
|
|
|
say STDERR " Grid size lat lon: $grid_size $ilat $ilon" if $debug; |
|
104
|
0
|
|
|
|
|
|
$self->{grid_size} = $grid_size; |
|
105
|
0
|
0
|
|
|
|
|
$self->{elevation} = $bicubic ? _interpolate_bicubic ($dem, $ilat, $ilon) : _interpolate_bilinear ($dem, $ilat, $ilon); |
|
106
|
0
|
|
|
|
|
|
return $self->{elevation}; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _interpolate_bicubic { |
|
110
|
1
|
|
|
1
|
|
6
|
use List::Util qw( min max ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
888
|
|
|
111
|
0
|
|
|
0
|
|
|
my ($f, $x, $y) = @_; |
|
112
|
0
|
|
|
|
|
|
my $x1 = POSIX::floor $x; |
|
113
|
0
|
|
|
|
|
|
my $x2 = POSIX::ceil $x; |
|
114
|
0
|
|
|
|
|
|
my $x0 = max ($x1-1, 0); |
|
115
|
0
|
|
|
|
|
|
my $x3 = min ($x2+1, $grid_size-1); |
|
116
|
0
|
|
|
|
|
|
my $y1 = POSIX::floor $y; |
|
117
|
0
|
|
|
|
|
|
my $y2 = POSIX::ceil $y; |
|
118
|
0
|
|
|
|
|
|
my $y0 = max ($y1-1, 0); |
|
119
|
0
|
|
|
|
|
|
my $y3 = min ($y2+1, $grid_size-1); |
|
120
|
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
my $f00 = unpack ("s>*", substr ($$f, 2*($x0*$grid_size+$y0), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
122
|
0
|
|
|
|
|
|
my $f01 = unpack ("s>*", substr ($$f, 2*($x0*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
123
|
0
|
|
|
|
|
|
my $f02 = unpack ("s>*", substr ($$f, 2*($x0*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
124
|
0
|
|
|
|
|
|
my $f03 = unpack ("s>*", substr ($$f, 2*($x0*$grid_size+$y3), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
125
|
|
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
my $f10 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y0), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
127
|
0
|
|
|
|
|
|
my $f11 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
128
|
0
|
|
|
|
|
|
my $f12 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
129
|
0
|
|
|
|
|
|
my $f13 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y3), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
130
|
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
my $f20 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y0), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
132
|
0
|
|
|
|
|
|
my $f21 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
133
|
0
|
|
|
|
|
|
my $f22 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
134
|
0
|
|
|
|
|
|
my $f23 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y3), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
135
|
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
|
my $f30 = unpack ("s>*", substr ($$f, 2*($x3*$grid_size+$y0), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
137
|
0
|
|
|
|
|
|
my $f31 = unpack ("s>*", substr ($$f, 2*($x3*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
138
|
0
|
|
|
|
|
|
my $f32 = unpack ("s>*", substr ($$f, 2*($x3*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
139
|
0
|
|
|
|
|
|
my $f33 = unpack ("s>*", substr ($$f, 2*($x3*$grid_size+$y3), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
140
|
|
|
|
|
|
|
|
|
141
|
0
|
0
|
|
|
|
|
say STDERR " Grid corners: ($x0,$y0) ($x1,$y1) ($x2,$y2) ($x3,$y3)" if $debug; |
|
142
|
|
|
|
|
|
|
# say STDERR " Elevation at corners: $f11 $f21 $f12 $f22" if $debug; |
|
143
|
0
|
0
|
|
|
|
|
say STDERR " Elevation at corners: $f00 $f01 $f02 $f03" if $debug; |
|
144
|
0
|
0
|
|
|
|
|
say STDERR " Elevation at corners: $f10 $f11 $f12 $f13" if $debug; |
|
145
|
0
|
0
|
|
|
|
|
say STDERR " Elevation at corners: $f20 $f21 $f22 $f23" if $debug; |
|
146
|
0
|
0
|
|
|
|
|
say STDERR " Elevation at corners: $f30 $f31 $f32 $f33" if $debug; |
|
147
|
|
|
|
|
|
|
# Bicubic interpolation as per https://www.paulinternet.nl/?page=bicubic |
|
148
|
|
|
|
|
|
|
# using the simplifying fact that ($x2-$x1)==1 and ($y2-$y1)==1 |
|
149
|
0
|
|
|
|
|
|
my $xx = $x - $x1; |
|
150
|
0
|
|
|
|
|
|
my $yy = $y - $y1; |
|
151
|
0
|
|
|
|
|
|
my $f0 = _bicubic ($f00, $f01, $f02, $f03, $yy); |
|
152
|
0
|
|
|
|
|
|
my $f1 = _bicubic ($f10, $f11, $f12, $f13, $yy); |
|
153
|
0
|
|
|
|
|
|
my $f2 = _bicubic ($f20, $f21, $f22, $f23, $yy); |
|
154
|
0
|
|
|
|
|
|
my $f3 = _bicubic ($f30, $f31, $f32, $f33, $yy); |
|
155
|
0
|
0
|
|
|
|
|
say STDERR " bicubic interpolated elevation: "._bicubic ($f0, $f1, $f2, $f3, $xx) if $debug; |
|
156
|
0
|
|
|
|
|
|
return _bicubic ($f0, $f1, $f2, $f3, $xx); |
|
157
|
|
|
|
|
|
|
} |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub _bicubic { |
|
160
|
0
|
|
|
0
|
|
|
my ($f0, $f1, $f2, $f3, $x) = @_; |
|
161
|
0
|
0
|
|
|
|
|
if ($bicubic_current) { |
|
|
|
0
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
return $f1 + $x*($f1 - $f0 + $x*(2.0*$f0 - 5.0*$f1 + 4.0*$f2 - $f3 + $x*(3.0*($f1 - $f2) + $f3 - $f0))); # use slope of a line between the previous and the «current» point as the derivative at a point, that is (p1-p0) and (p3-p2) |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
elsif ($bicubic_mixed) { |
|
165
|
0
|
|
|
|
|
|
return $f1 + 0.75 * $x*($f2 - $f0 + $x*(2.0*$f0 - 5.0*$f1 + 4.0*$f2 - $f3 + $x*(3.0*($f1 - $f2) + $f3 - $f0))); # use «current» and «next» point «mixed» slope |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
else { |
|
168
|
0
|
|
|
|
|
|
return $f1 + 0.5 * $x*($f2 - $f0 + $x*(2.0*$f0 - 5.0*$f1 + 4.0*$f2 - $f3 + $x*(3.0*($f1 - $f2) + $f3 - $f0))); # use slope of a line between the previous and the «next» point as the derivative at a point, that is (p2-p0)/2 and (p3-p1)/2 |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub _interpolate_bilinear { |
|
173
|
0
|
|
|
0
|
|
|
my ($f, $x, $y) = @_; |
|
174
|
0
|
|
|
|
|
|
my $x1 = POSIX::floor $x; |
|
175
|
0
|
|
|
|
|
|
my $x2 = POSIX::ceil $x; |
|
176
|
0
|
|
|
|
|
|
my $y1 = POSIX::floor $y; |
|
177
|
0
|
|
|
|
|
|
my $y2 = POSIX::ceil $y; |
|
178
|
0
|
|
|
|
|
|
my $f11 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
179
|
0
|
|
|
|
|
|
my $f21 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y1), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
180
|
0
|
|
|
|
|
|
my $f12 = unpack ("s>*", substr ($$f, 2*($x1*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
181
|
0
|
|
|
|
|
|
my $f22 = unpack ("s>*", substr ($$f, 2*($x2*$grid_size+$y2), 2)); # unpack signed big-endian 16-bit integer to elevation value |
|
182
|
0
|
0
|
|
|
|
|
say STDERR " Grid corners: ($x1,$y1) ($x2,$y1) ($x1,$y2) ($x2,$y2)" if $debug; |
|
183
|
0
|
0
|
|
|
|
|
say STDERR " Elevation at corners: $f11 $f21 $f12 $f22" if $debug; |
|
184
|
|
|
|
|
|
|
# bilinear interpolation as per https://github.com/racemap/elevation-service/blob/master/hgt.js |
|
185
|
|
|
|
|
|
|
# using the simplifying fact that ($x2-$x1)==1 and ($y2-$y1)==1 |
|
186
|
0
|
|
|
|
|
|
my $xx = $x - $x1; |
|
187
|
0
|
|
|
|
|
|
my $yy = $y - $y1; |
|
188
|
0
|
|
|
|
|
|
my $f1 = _avg ($f11, $f21, $xx); |
|
189
|
0
|
|
|
|
|
|
my $f2 = _avg ($f12, $f22, $xx); |
|
190
|
0
|
0
|
|
|
|
|
say STDERR " bilinear interpolated elevation: "._avg ($f1, $f2, $yy) if $debug; |
|
191
|
0
|
|
|
|
|
|
return _avg ($f1, $f2, $yy); |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub _avg { |
|
195
|
0
|
|
|
0
|
|
|
my ($f1, $f2, $x) = @_; |
|
196
|
0
|
|
|
|
|
|
return $f1 + ($f2 - $f1) * $x; |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub _readDEM { |
|
200
|
1
|
|
|
1
|
|
1157
|
use IO::Uncompress::AnyUncompress qw(anyuncompress $AnyUncompressError); |
|
|
1
|
|
|
|
|
66880
|
|
|
|
1
|
|
|
|
|
106
|
|
|
201
|
1
|
|
|
1
|
|
1161
|
use HTTP::Tiny; |
|
|
1
|
|
|
|
|
27942
|
|
|
|
1
|
|
|
|
|
464
|
|
|
202
|
0
|
|
|
0
|
|
|
my ($self, $DEMname) = @_; |
|
203
|
0
|
|
|
|
|
|
my $nslt = substr($DEMname,0,3); |
|
204
|
0
|
|
|
|
|
|
my $path_to_hgt_gz = "$nslt/$DEMname.hgt.gz"; |
|
205
|
0
|
|
|
|
|
|
$switch = 0; |
|
206
|
0
|
|
|
|
|
|
$cache = 0; |
|
207
|
0
|
|
|
|
|
|
$fail = 0; |
|
208
|
0
|
|
|
|
|
|
@default_DEMs = ("$path_to_hgt_gz", "$DEMname.zip"); |
|
209
|
0
|
|
|
|
|
|
@want_DEMnames = ("$DEMname.hgt.gz", "$DEMname.zip"); |
|
210
|
0
|
|
|
|
|
|
my $dem; |
|
211
|
0
|
0
|
|
|
|
|
$status_descr = -d $folder ? "Folder" : "Url"; |
|
212
|
0
|
0
|
|
|
|
|
my $path = -d $folder ? _findDEM ($folder) : "$folder/$path_to_hgt_gz"; |
|
213
|
0
|
0
|
|
|
|
|
if (-e $path) { |
|
214
|
0
|
0
|
|
|
|
|
say STDERR " Reading DEM '$path'" if $debug; |
|
215
|
0
|
|
|
|
|
|
$self->{DEMs}{$DEMname}{DEMpath}=$path; |
|
216
|
0
|
0
|
|
|
|
|
anyuncompress $path => \$dem or croak "anyuncompress failed on '$path': $AnyUncompressError"; |
|
217
|
0
|
|
|
|
|
|
return \$dem; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
0
|
0
|
|
|
|
|
unless ($path =~ m/^https?:\/\//) { |
|
220
|
0
|
0
|
|
|
|
|
say STDERR " DEM '$path' not found -> switch to '$url'" if $debug; |
|
221
|
0
|
|
|
|
|
|
$status_descr .= "->Switch"; |
|
222
|
0
|
|
|
|
|
|
$switch = 1; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
0
|
0
|
|
|
|
|
my $cache_path = $cache_folder ne "" ? _findDEM ($cache_folder) : undef; |
|
225
|
0
|
0
|
0
|
|
|
|
if (defined $cache_path and -e $cache_path) { |
|
226
|
0
|
0
|
|
|
|
|
say STDERR " Reading DEM from cache '$cache_path'" if $debug; |
|
227
|
0
|
|
|
|
|
|
$self->{DEMs}{$DEMname}{DEMpath}=$cache_path; |
|
228
|
0
|
|
|
|
|
|
$status_descr .= "->Cached"; |
|
229
|
0
|
|
|
|
|
|
$cache = 1; |
|
230
|
0
|
0
|
|
|
|
|
anyuncompress $cache_path => \$dem or croak "anyuncompress failed on '$cache_path': $AnyUncompressError"; |
|
231
|
0
|
|
|
|
|
|
return \$dem; |
|
232
|
|
|
|
|
|
|
} |
|
233
|
0
|
|
|
|
|
|
$path = "$url/$path_to_hgt_gz"; |
|
234
|
0
|
0
|
|
|
|
|
say STDERR " Getting DEM '$path'" if $debug; |
|
235
|
0
|
0
|
|
|
|
|
$status_descr .= "->Url" unless ($status_descr eq "Url"); |
|
236
|
0
|
|
|
|
|
|
my $response = HTTP::Tiny->new->get($path); # get gzip archive file .hgt.gz |
|
237
|
0
|
0
|
|
|
|
|
unless ($response->{success}) { |
|
238
|
|
|
|
|
|
|
# no success |
|
239
|
0
|
|
|
|
|
|
carp " DEM '$path'- $response->{status} $response->{reason}. All of its elevations will read as 0"; |
|
240
|
0
|
|
|
|
|
|
$status_descr .= "->Failed"; |
|
241
|
0
|
|
|
|
|
|
$fail = 1; |
|
242
|
0
|
|
|
|
|
|
return 0; |
|
243
|
|
|
|
|
|
|
} |
|
244
|
0
|
0
|
0
|
|
|
|
if ($cache_folder ne "" and -d $cache_folder) { |
|
245
|
0
|
0
|
|
|
|
|
unless (-d "$cache_folder/$nslt") {mkdir "$cache_folder/$nslt", 0755} |
|
|
0
|
|
|
|
|
|
|
|
246
|
0
|
0
|
|
|
|
|
open my $file_handle, '>', "$cache_path" or croak "'$cache_path' error opening: $!"; |
|
247
|
0
|
|
|
|
|
|
binmode $file_handle; |
|
248
|
0
|
|
|
|
|
|
print $file_handle $response->{content}; |
|
249
|
0
|
|
|
|
|
|
close $file_handle; |
|
250
|
0
|
|
|
|
|
|
$status_descr .= "->Saved"; |
|
251
|
0
|
0
|
|
|
|
|
say STDERR " Saved DEM cache file '$cache_path'" if $debug; |
|
252
|
|
|
|
|
|
|
} |
|
253
|
0
|
|
|
|
|
|
$self->{DEMs}{$DEMname}{DEMpath}=$path; |
|
254
|
0
|
0
|
|
|
|
|
anyuncompress \$response->{content} => \$dem or croak "anyuncompress failed on '$path': $AnyUncompressError"; |
|
255
|
0
|
|
|
|
|
|
return \$dem; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub _findDEM { |
|
259
|
1
|
|
|
1
|
|
8
|
use File::Find; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
199
|
|
|
260
|
0
|
|
|
0
|
|
|
my ($folder) = @_; |
|
261
|
0
|
|
|
|
|
|
for my $default (@default_DEMs) { |
|
262
|
0
|
0
|
0
|
|
|
|
say STDERR " Found default DEM '$folder/$default'" if ($debug and -e "$folder/$default"); |
|
263
|
0
|
0
|
|
|
|
|
return "$folder/$default" if (-e "$folder/$default"); |
|
264
|
|
|
|
|
|
|
} |
|
265
|
0
|
|
|
|
|
|
splice (@DEMnames,0); |
|
266
|
0
|
|
|
|
|
|
find(\&_wanted, $folder); |
|
267
|
0
|
0
|
0
|
|
|
|
say STDERR " Found wanted DEM '$DEMnames[0]'" if ($debug and defined $DEMnames[0]); |
|
268
|
0
|
|
0
|
|
|
|
return $DEMnames[0] // "$folder/$default_DEMs[0]"; |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub _wanted { |
|
272
|
1
|
|
|
1
|
|
13
|
use List::Util 'any'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
119
|
|
|
273
|
0
|
|
|
0
|
|
|
my $filename = $_; |
|
274
|
0
|
0
|
|
0
|
|
|
push (@DEMnames, $File::Find::name) if any {$_ =~ m/^$filename$/i} @want_DEMnames; # add file to list if matched |
|
|
0
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
} |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
1; # End of Geo::Elevation::HGT |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
__END__ |