package tim.prune.function.srtm; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import tim.prune.I18nManager; public class SrtmViewfinderSource extends SrtmSource { /** URL prefix for all tiles */ private static final String URL_PREFIX = "http://viewfinderpanoramas.org/"; private HashMap _tile_lookup = null; private HashMap _tile_sizes = null; public SrtmViewfinderSource() { _tile_lookup = new HashMap(); _tile_sizes = new HashMap(); } public String getNameKey() { return "function.downloadsrtm." + getName(); } public String getName() { return "SRTM_Viewfinder"; } protected String getSourceExtension() { return ".zip"; } /** * Read the dat file and get the contents * @return byte array containing file contents */ private void populateLookup() throws SrtmSourceException { BufferedReader in = null; try { // in = SrtmViewfinderSource.class.getResourceAsStream("viewfinder/tiles.db"); in = new BufferedReader(new InputStreamReader(SrtmViewfinderSource.class.getResourceAsStream("/tim/prune/function/srtm/viewfinder/tiles.dat"))); String line; while ((line = in.readLine()) != null) { String[] parts = line.split(" "); SrtmTile tile = new SrtmTile(Integer.parseInt(parts[0]), Integer.parseInt(parts[1])); _tile_lookup.put(tile, parts[2]); } } catch (Exception e) { throw new SrtmSourceException("Exception trying to read tiles.db: " + e); } finally { try { in.close(); } catch (Exception e) {} // ignore } } /** * Get the filename for the given tile */ private String tileFileName(SrtmTile inTile) throws SrtmSourceException { if (_tile_lookup.size() == 0) { populateLookup(); } String path = _tile_lookup.get(inTile); if (path == null) { // int key = inTile.hashCode(); // System.out.println("inTile hashcode " + key); // for (HashMap.Entry e : _tile_lookup.entrySet()) // { // System.out.println(e.getKey().getTileName() + " - " + e.getKey().hashCode() + " -> " + e.getValue()); // } throw new SrtmSourceException("tile not in database "+inTile.getTileName()); } return path + getSourceExtension(); } /** * Get the UTL for the given tile * @param inTile Tile to get * @return URL */ private URL buildUrl(SrtmTile inTile) throws SrtmSourceException { String filename = tileFileName(inTile); try { return new URL(URL_PREFIX + filename); } catch (MalformedURLException e) { e.printStackTrace(); throw new SrtmSourceException(e.getMessage()); } } public boolean isReadyToUse() { return true; } public boolean downloadTile(SrtmTile inTile) throws SrtmSourceException { URL tileUrl = buildUrl(inTile); InputStream inStream = getStreamToUrl(tileUrl); return readToFile(inStream, getCacheFileName(inTile)); } private ZipEntry advanceToEntry(ZipInputStream inStream, SrtmTile inTile) throws SrtmSourceException { while (true) { ZipEntry entry; try { entry = inStream.getNextEntry(); } catch (IOException e) { throw new SrtmSourceException("Tile file " + getCacheFileName(inTile) + " found in cache, but tile " + inTile.getTileName() + "not found inside ZIP archive"); } String entryName = entry.getName().toUpperCase(); if (entryName.contains(inTile.getTileName())) { // tile size is one of 1201; 3601 depending on // resolution if (entry.getSize() == 2 * 1201 * 1201) { _tile_sizes.put(inTile, 1201); } else if (entry.getSize() == 2 * 3601 * 3601) { _tile_sizes.put(inTile, 3601); } else { throw new SrtmSourceException("Tile file "+getCacheFileName(inTile)+" does not have the expected size, it is: " + entry.getSize()); } return entry; } } } public int[] getTileHeights(SrtmTile inTile) throws SrtmSourceException { File cacheFileName = getCacheFileName(inTile); if (cacheFileName == null) { throw new SrtmSourceException("Tile "+inTile.getTileName()+" not in cache"); } try { ZipInputStream inStream = new ZipInputStream(new FileInputStream(cacheFileName)); ZipEntry entry = advanceToEntry(inStream, inTile); int rowSize = getRowSize(inTile); return slurpTileHeigths(inStream, rowSize * rowSize); } catch (IOException e) { throw new SrtmSourceException("Failure opening "+cacheFileName+" for reading:"+e.getMessage()); } } public int getRowSize(SrtmTile inTile) { return _tile_sizes.get(inTile); } protected File getCacheFileName(SrtmTile inTile) { try { File fileName = new File(tileFileName(inTile)); return new File(getCacheDir(), fileName.getName()); } catch (SrtmSourceException e) { return null; } } }