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