]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/function/srtm/SrtmViewfinderSource.java
17790ae2f2b1cc3cee89bc4d7cad52fcb3104ac2
[GpsPrune.git] / src / tim / prune / function / srtm / SrtmViewfinderSource.java
1 package tim.prune.function.srtm;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileReader;
6 import java.io.FileOutputStream;
7 import java.io.InputStream;
8 import java.io.IOException;
9 import java.io.BufferedReader;
10 import java.io.InputStreamReader;
11 import java.net.MalformedURLException;
12 import java.net.URL;
13 import java.net.HttpURLConnection;
14 import java.util.HashMap;
15 import java.util.zip.ZipEntry;
16 import java.util.zip.ZipInputStream;
17
18 import tim.prune.GpsPrune;
19 import tim.prune.I18nManager;
20
21 public class SrtmViewfinderSource extends SrtmSource {
22         /** URL prefix for all tiles */
23         private static final String URL_PREFIX = "http://viewfinderpanoramas.org/";
24         private HashMap<SrtmTile, String> _tile_lookup = null;
25         private HashMap<SrtmTile, Integer> _tile_sizes = null;
26
27         public SrtmViewfinderSource()
28         {
29                 _tile_lookup = new HashMap<SrtmTile, String>();
30                 _tile_sizes = new HashMap<SrtmTile, Integer>();
31         }
32
33         public String getNameKey()
34         {
35                 return "function.downloadsrtm." + getName();
36         }
37
38         public String getName()
39         {
40                 return "SRTM_Viewfinder";
41         }
42
43         protected String getSourceExtension()
44         {
45                 return ".zip";
46         }
47
48         /**
49          * Read the dat file and get the contents
50          * @return byte array containing file contents
51          */
52         private void populateLookup()
53                 throws SrtmSourceException
54         {
55                 BufferedReader in = null;
56                 try
57                 {
58                         // in = SrtmViewfinderSource.class.getResourceAsStream("viewfinder/tiles.db");
59                         in = new BufferedReader(new InputStreamReader(SrtmViewfinderSource.class.getResourceAsStream("/tim/prune/function/srtm/viewfinder/tiles.dat")));
60                         String line;
61                         while ((line = in.readLine()) != null)
62                         {
63                                 String[] parts = line.split(" ");
64                                 SrtmTile tile = new SrtmTile(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
65                                 _tile_lookup.put(tile, parts[2]);
66                         }
67                 }
68                 catch (Exception e) {
69                         throw new SrtmSourceException("Exception trying to read tiles.db: " + e);
70                 }
71                 finally
72                 {
73                         try {
74                                 in.close();
75                         }
76                         catch (Exception e) {} // ignore
77                 }
78         }
79
80         /**
81          * Get the filename for the given tile
82          */
83         private String tileFileName(SrtmTile inTile)
84                 throws SrtmSourceException
85         {
86                 if (_tile_lookup.size() == 0)
87                 {
88                         populateLookup();
89                 }
90                 String path = _tile_lookup.get(inTile);
91                 if (path == null)
92                 {
93                         // int key = inTile.hashCode();
94                         // System.out.println("inTile hashcode " + key);
95                         // for (HashMap.Entry<SrtmTile, String> e : _tile_lookup.entrySet())
96                         // {
97                         //      System.out.println(e.getKey().getTileName() + " - " + e.getKey().hashCode() + " -> " + e.getValue());
98                         // }
99                         throw new SrtmSourceException("tile not in database "+inTile.getTileName());
100                 }
101                 return path + getSourceExtension();
102         }
103
104         /**
105          * Get the UTL for the given tile
106          * @param inTile Tile to get
107          * @return URL
108          */
109         private URL buildUrl(SrtmTile inTile)
110                 throws SrtmSourceException
111         {
112                 String filename = tileFileName(inTile);
113                 try
114                 {
115                         return new URL(URL_PREFIX + filename);
116                 }
117                 catch (MalformedURLException e)
118                 {
119                         e.printStackTrace();
120                         throw new SrtmSourceException(e.getMessage());
121                 }
122         }
123
124         public boolean isReadyToUse()
125         {
126                 return true;
127         }
128
129         public boolean downloadTile(SrtmTile inTile)
130                 throws SrtmSourceException
131         {
132                 URL tileUrl = buildUrl(inTile);
133                 File outputFile = getCacheFileName(inTile);
134                 System.out.println("Download: Need to download: " + tileUrl);
135
136                 try
137                 {
138                         HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection();
139
140                         // Define streams
141                         FileOutputStream outStream = null;
142                         InputStream inStream = null;
143
144                         conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
145
146                         int status = conn.getResponseCode();
147                         if (status == 200)
148                         {
149                                 inStream = conn.getInputStream();
150                         }
151                         else if (status == 404)
152                         {
153                                 throw new SrtmSourceException("Tile not found: "+conn.getURL());
154                         }
155                         else
156                         {
157                                 throw new SrtmSourceException("Invalid response from server: " +status+conn.getContent());
158                         }
159
160                         outStream = new FileOutputStream(outputFile);
161
162                         int c;
163                         while ((c = inStream.read()) != -1)
164                         {
165                                 outStream.write(c);
166                         }
167                         // Make sure streams are closed
168                         try {inStream.close();} catch (Exception e) {}
169                         try {outStream.close();} catch (Exception e) {}
170                         return true;
171                 }
172                 catch (IOException e)
173                 {
174                         throw new SrtmSourceException("Error while downloading tile "+inTile.getTileName()+": "+e.getMessage());
175                 }
176         }
177
178         private ZipEntry advanceToEntry(ZipInputStream inStream, SrtmTile inTile)
179                 throws SrtmSourceException
180         {
181                 while (true)
182                 {
183                         ZipEntry entry;
184                         try
185                         {
186                                 entry = inStream.getNextEntry();
187                         }
188                         catch (IOException e)
189                         {
190                                 throw new SrtmSourceException("Tile file " + getCacheFileName(inTile) + " found in cache, but tile " + inTile.getTileName() + "not found inside ZIP archive");
191                         }
192                         String entryName = entry.getName().toUpperCase();
193                         if (entryName.contains(inTile.getTileName()))
194                         {
195                                 // tile size is one of 1201; 3601 depending on
196                                 // resolution
197                                 if (entry.getSize() == 2 * 1201 * 1201)
198                                 {
199                                         _tile_sizes.put(inTile, 1201);
200                                 }
201                                 else if (entry.getSize() == 2 * 3601 * 3601)
202                                 {
203                                         _tile_sizes.put(inTile, 3601);
204                                 }
205                                 else
206                                 {
207                                         throw new SrtmSourceException("Tile file "+getCacheFileName(inTile)+" does not have the expected size, it is: " + entry.getSize());
208                                 }
209                                 return entry;
210                         }
211                 }
212         }
213
214         public int[] getTileHeights(SrtmTile inTile)
215                 throws SrtmSourceException
216         {
217                 File cacheFileName = getCacheFileName(inTile);
218                 if (cacheFileName == null)
219                 {
220                         throw new SrtmSourceException("Tile "+inTile.getTileName()+" not in cache");
221                 }
222                 try
223                 {
224                         ZipInputStream inStream = new ZipInputStream(new FileInputStream(cacheFileName));
225                         ZipEntry entry = advanceToEntry(inStream, inTile);
226                         int rowSize = getRowSize(inTile);
227                         return slurpTileHeigths(inStream, rowSize * rowSize);
228                 }
229                 catch (IOException e)
230                 {
231                         throw new SrtmSourceException("Failure opening "+cacheFileName+" for reading:"+e.getMessage());
232                 }
233
234         }
235
236         public int getRowSize(SrtmTile inTile)
237         {
238                 return _tile_sizes.get(inTile);
239         }
240
241         protected File getCacheFileName(SrtmTile inTile)
242         {
243                 try {
244                         File fileName = new File(tileFileName(inTile));
245                         return new File(getCacheDir(), fileName.getName());
246                 }
247                 catch (SrtmSourceException e)
248                 {
249                         return null;
250                 }
251         }
252 }