1
+ /*
2
+ * Licensed to GraphHopper GmbH under one or more contributor
3
+ * license agreements. See the NOTICE file distributed with this work for
4
+ * additional information regarding copyright ownership.
5
+ *
6
+ * GraphHopper GmbH licenses this file to you under the Apache License,
7
+ * Version 2.0 (the "License"); you may not use this file except in
8
+ * compliance with the License. You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ package com .graphhopper .reader .dem ;
19
+
20
+ import com .graphhopper .storage .DAType ;
21
+ import com .graphhopper .storage .DataAccess ;
22
+ import com .graphhopper .storage .Directory ;
23
+ import com .graphhopper .storage .GHDirectory ;
24
+ import com .graphhopper .util .Downloader ;
25
+ import org .slf4j .Logger ;
26
+ import org .slf4j .LoggerFactory ;
27
+
28
+ import java .awt .image .Raster ;
29
+ import java .io .File ;
30
+ import java .io .IOException ;
31
+ import java .net .SocketTimeoutException ;
32
+ import java .util .HashMap ;
33
+ import java .util .Map ;
34
+
35
+ /**
36
+ * Provides basic methods that are usually used in an ElevationProvider that reads tiff files.
37
+ *
38
+ * @author Robin Boldt
39
+ */
40
+ public abstract class AbstractTiffElevationProvider implements ElevationProvider {
41
+ final Logger logger = LoggerFactory .getLogger (getClass ());
42
+ final Map <String , HeightTile > cacheData = new HashMap <String , HeightTile >();
43
+ protected Downloader downloader ;
44
+ File cacheDir ;
45
+ String baseUrl ;
46
+ private Directory dir ;
47
+ private DAType daType = DAType .MMAP ;
48
+ boolean calcMean = false ;
49
+ boolean autoRemoveTemporary = true ;
50
+ long sleep = 2000 ;
51
+
52
+ public AbstractTiffElevationProvider (String baseUrl , String cacheDir , String downloaderName ) {
53
+ this .baseUrl = baseUrl ;
54
+ this .cacheDir = new File (cacheDir );
55
+ downloader = new Downloader (downloaderName ).setTimeout (10000 );
56
+ }
57
+
58
+ @ Override
59
+ public void setCalcMean (boolean eleCalcMean ) {
60
+ calcMean = eleCalcMean ;
61
+ }
62
+
63
+ void setSleep (long sleep ) {
64
+ this .sleep = sleep ;
65
+ }
66
+
67
+ /**
68
+ * Creating temporary files can take a long time as we need to unpack tiff as well as to fill
69
+ * our DataAccess object, so this option can be used to disable the default clear mechanism via
70
+ * specifying 'false'.
71
+ */
72
+ public void setAutoRemoveTemporaryFiles (boolean autoRemoveTemporary ) {
73
+ this .autoRemoveTemporary = autoRemoveTemporary ;
74
+ }
75
+
76
+ public void setDownloader (Downloader downloader ) {
77
+ this .downloader = downloader ;
78
+ }
79
+
80
+ @ Override
81
+ public ElevationProvider setCacheDir (File cacheDir ) {
82
+ if (cacheDir .exists () && !cacheDir .isDirectory ())
83
+ throw new IllegalArgumentException ("Cache path has to be a directory" );
84
+ try {
85
+ this .cacheDir = cacheDir .getCanonicalFile ();
86
+ } catch (IOException ex ) {
87
+ throw new RuntimeException (ex );
88
+ }
89
+ return this ;
90
+ }
91
+
92
+ protected File getCacheDir () {
93
+ return cacheDir ;
94
+ }
95
+
96
+ @ Override
97
+ public ElevationProvider setBaseURL (String baseUrl ) {
98
+ if (baseUrl == null || baseUrl .isEmpty ())
99
+ throw new IllegalArgumentException ("baseUrl cannot be empty" );
100
+
101
+ this .baseUrl = baseUrl ;
102
+ return this ;
103
+ }
104
+
105
+ @ Override
106
+ public ElevationProvider setDAType (DAType daType ) {
107
+ this .daType = daType ;
108
+ return this ;
109
+ }
110
+
111
+
112
+ @ Override
113
+ public void release () {
114
+ cacheData .clear ();
115
+
116
+ // for memory mapped type we create temporary unpacked files which should be removed
117
+ if (autoRemoveTemporary && dir != null )
118
+ dir .clear ();
119
+ }
120
+
121
+ /**
122
+ * Download a file at the provided url and save it as the given downloadFile if the downloadFile does not exist.
123
+ */
124
+ protected void downloadFile (File downloadFile , String url ) throws IOException {
125
+ if (!downloadFile .exists ()) {
126
+ int max = 3 ;
127
+ for (int trial = 0 ; trial < max ; trial ++) {
128
+ try {
129
+ downloader .downloadFile (url , downloadFile .getAbsolutePath ());
130
+ return ;
131
+ } catch (SocketTimeoutException ex ) {
132
+ if (trial >= max - 1 )
133
+ throw new RuntimeException (ex );
134
+ try {
135
+ Thread .sleep (sleep );
136
+ } catch (InterruptedException ignored ) {
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+
143
+ protected void fillDataAccessWithElevationData (Raster raster , DataAccess heights , int dataAccessWidth ) {
144
+ final int height = raster .getHeight ();
145
+ final int width = raster .getWidth ();
146
+ int x = 0 ;
147
+ int y = 0 ;
148
+ try {
149
+ for (y = 0 ; y < height ; y ++) {
150
+ for (x = 0 ; x < width ; x ++) {
151
+ short val = (short ) raster .getPixel (x , y , (int []) null )[0 ];
152
+ if (val < -1000 || val > 12000 )
153
+ val = Short .MIN_VALUE ;
154
+
155
+ heights .setShort (2 * (y * dataAccessWidth + x ), val );
156
+ }
157
+ }
158
+ heights .flush ();
159
+
160
+ // TODO remove tifName and zip?
161
+ } catch (Exception ex ) {
162
+ throw new RuntimeException ("Problem at x:" + x + ", y:" + y , ex );
163
+ }
164
+ }
165
+
166
+ protected Directory getDirectory () {
167
+ if (dir != null )
168
+ return dir ;
169
+
170
+ logger .info (this .toString () + " Elevation Provider, from: " + baseUrl + ", to: " + cacheDir + ", as: " + daType );
171
+ return dir = new GHDirectory (cacheDir .getAbsolutePath (), daType );
172
+ }
173
+ }
0 commit comments