]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/function/srtm/SrtmViewfinderSource.java
Use data from viewfinderpanoramas.org
[GpsPrune.git] / src / tim / prune / function / srtm / SrtmViewfinderSource.java
diff --git a/src/tim/prune/function/srtm/SrtmViewfinderSource.java b/src/tim/prune/function/srtm/SrtmViewfinderSource.java
new file mode 100644 (file)
index 0000000..17790ae
--- /dev/null
@@ -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<SrtmTile, String> _tile_lookup = null;
+       private HashMap<SrtmTile, Integer> _tile_sizes = null;
+
+       public SrtmViewfinderSource()
+       {
+               _tile_lookup = new HashMap<SrtmTile, String>();
+               _tile_sizes = new HashMap<SrtmTile, Integer>();
+       }
+
+       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<SrtmTile, String> 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;
+               }
+       }
+}