X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=src%2Ftim%2Fprune%2Ffunction%2Fsrtm%2FSrtmViewfinderSource.java;fp=src%2Ftim%2Fprune%2Ffunction%2Fsrtm%2FSrtmViewfinderSource.java;h=17790ae2f2b1cc3cee89bc4d7cad52fcb3104ac2;hb=641d7703cc141e71696979992923f4bcbb1806a9;hp=0000000000000000000000000000000000000000;hpb=94113b9f5f037cd56c07cca5f69f7f56620d84ef;p=GpsPrune.git diff --git a/src/tim/prune/function/srtm/SrtmViewfinderSource.java b/src/tim/prune/function/srtm/SrtmViewfinderSource.java new file mode 100644 index 0000000..17790ae --- /dev/null +++ b/src/tim/prune/function/srtm/SrtmViewfinderSource.java @@ -0,0 +1,252 @@ +package tim.prune.function.srtm; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FileOutputStream; +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.net.HttpURLConnection; +import java.util.HashMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import tim.prune.GpsPrune; +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); + File outputFile = getCacheFileName(inTile); + System.out.println("Download: Need to download: " + tileUrl); + + try + { + HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection(); + + // Define streams + FileOutputStream outStream = null; + InputStream inStream = null; + + conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER); + + int status = conn.getResponseCode(); + if (status == 200) + { + inStream = conn.getInputStream(); + } + else if (status == 404) + { + throw new SrtmSourceException("Tile not found: "+conn.getURL()); + } + else + { + throw new SrtmSourceException("Invalid response from server: " +status+conn.getContent()); + } + + outStream = new FileOutputStream(outputFile); + + int c; + while ((c = inStream.read()) != -1) + { + outStream.write(c); + } + // Make sure streams are closed + try {inStream.close();} catch (Exception e) {} + try {outStream.close();} catch (Exception e) {} + return true; + } + catch (IOException e) + { + throw new SrtmSourceException("Error while downloading tile "+inTile.getTileName()+": "+e.getMessage()); + } + } + + 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; + } + } +}