package tim.prune.function.srtm;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
-import java.net.HttpURLConnection;
-import tim.prune.GpsPrune;
import tim.prune.I18nManager;
public class Srtm3Source extends SrtmSource {
return buffer;
}
}
- catch (java.io.IOException e) {
+ catch (IOException e) {
System.err.println("Exception trying to read srtmtiles.dat : " + e.getMessage());
}
finally
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
- 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());
- }
- return downloadToFile(inStream, outputFile);
- }
- catch (IOException e)
- {
- throw new SrtmSourceException("Error while downloading tile "+inTile.getTileName()+": "+e.getMessage());
- }
+ InputStream inStream = getStreamToUrl(tileUrl);
+ return readToFile(inStream, getCacheFileName(inTile));
}
public int getRowSize(SrtmTile inTile)
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.net.URL;
+import java.net.HttpURLConnection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+import tim.prune.GpsPrune;
+
+/**
+ * Abstract class implemented by each download source
+ */
public abstract class SrtmSource {
- // methods implemented by each source
+ /**
+ * Name of the source
+ * A string used to build function.downloadsrtm.getName() for getting
+ * the string shown to the user in menus and messages, also used to
+ * build cache directory
+ */
public abstract String getName();
+
+ /**
+ * Whether the source is ready to use
+ * @return true, or false if configuration is necessary
+ */
public abstract boolean isReadyToUse();
+
+ /**
+ * Download one tile of SRTM data to cache
+ * @param inTile the tile to get
+ */
public abstract boolean downloadTile(SrtmTile inTile)
throws SrtmSourceException;
- public abstract int getRowSize(SrtmTile inTile);
- protected abstract String getSourceExtension();
-
- protected boolean downloadToFile(InputStream inStream, File outputFile)
- throws IOException
- {
- FileOutputStream outStream = new FileOutputStream(outputFile);
-
- byte[] buffer = new byte[4096];
- int read = 0;
- while ((read = inStream.read(buffer)) != -1)
- {
- outStream.write(buffer, 0, read);
- }
- // Make sure streams are closed
- try {inStream.close();} catch (Exception e) {}
- try {outStream.close();} catch (Exception e) {}
- return true;
- }
+ /**
+ * Returns the number of rows of the tile
+ *
+ * Tiles from viewfinderpanoramas have different resolutions depending
+ * on the location.
+ * @param inTile the tile whose size we want
+ * @return number of rows; 1201 or 3601 in current implementation
+ */
+ public abstract int getRowSize(SrtmTile inTile);
- protected int[] slurpTileHeigths(ZipInputStream inStream, int tileSize)
- throws IOException
+ /**
+ * Whether the tile is cached
+ * @return true if the tile is in the cache and ready to be used
+ */
+ public boolean isCached(SrtmTile inTile)
{
- int[] heights = new int[tileSize];
- int dataSize = 2 * tileSize;
- byte[] buffer = new byte[dataSize];
- // Read entire file contents into one byte array
- int alreadyRead = 0;
- while (alreadyRead < dataSize)
- {
- alreadyRead += inStream.read(buffer, alreadyRead, dataSize - alreadyRead);
- }
- for (int i = 0; i < tileSize; i++)
- {
- // Bytes are signed. Cast high-order to int with sign
- // extension, and clamp low-order to its unsigned range
- heights[i] = buffer[2 * i] * 256 + (0xff & buffer[2 * i + 1]);
- }
- // Close stream
- inStream.close();
- return heights;
+ File cachedFileName = getCacheFileName(inTile);
+ return cachedFileName != null &&
+ getCacheFileName(inTile).exists();
}
+ /**
+ * Get the heigths for that tile
+ *
+ * @return an one-dimentional array of size {@link getRowSize ** 2}
+ * @throws SrtmSourceException notably if the tile is not cached yet
+ */
public int[] getTileHeights(SrtmTile inTile)
throws SrtmSourceException
{
}
+ // helpers used internally by the client classes
+ protected abstract String getSourceExtension();
+
+ /**
+ * Returns the cache directory for tiles, a sub-directory of the map
+ * cache
+ */
protected File getCacheDir()
{
return SrtmDiskCache.getCacheDir(getName());
}
+ /**
+ * Return the name of the filename for that tile
+ * For viewfinderpanoramas.org tiles, that might be a ZIP file
+ * containing several tiles
+ */
protected File getCacheFileName(SrtmTile inTile)
{
String fileName = inTile.getTileName() + getSourceExtension();
return new File(getCacheDir(), fileName);
}
- public boolean isCached(SrtmTile inTile)
+ protected InputStream getStreamToUrl(URL inTileUrl)
+ throws SrtmSourceException
{
- File cachedFileName = getCacheFileName(inTile);
- return cachedFileName != null &&
- getCacheFileName(inTile).exists();
+ try
+ {
+ HttpURLConnection conn = (HttpURLConnection) inTileUrl.openConnection();
+ conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
+ int status = conn.getResponseCode();
+ if (status == 200)
+ {
+ return 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());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new SrtmSourceException("Error while downloading tile from "+inTileUrl+": "+e.getMessage());
+ }
+ }
+
+ /**
+ * Helper for downloadTile()
+ * @param inStream Stream to read from, typically from HTTP connection
+ * @param outputFile Where to save the data being read
+ */
+ protected boolean readToFile(InputStream inStream, File outputFile)
+ throws SrtmSourceException
+ {
+ try
+ {
+ FileOutputStream outStream = new FileOutputStream(outputFile);
+
+ byte[] buffer = new byte[4096];
+ int read = 0;
+ while ((read = inStream.read(buffer)) != -1)
+ {
+ outStream.write(buffer, 0, read);
+ }
+ // 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 downloading tile:" + e.getMessage());
+ }
+ }
+
+ /**
+ * Helper for getTileHeights
+ * @param inStream Stream to read from, assumed to have been advanced
+ * to the appropriate tile
+ * @param tileSize the expected tileSize (square of getRowSize; assumed
+ * to have been checked by the caller)
+ * @return the tile heights
+ */
+ protected int[] slurpTileHeigths(ZipInputStream inStream, int tileSize)
+ throws IOException
+ {
+ int[] heights = new int[tileSize];
+ int dataSize = 2 * tileSize;
+ byte[] buffer = new byte[dataSize];
+ // Read entire file contents into one byte array
+ int alreadyRead = 0;
+ while (alreadyRead < dataSize)
+ {
+ alreadyRead += inStream.read(buffer, alreadyRead, dataSize - alreadyRead);
+ }
+ for (int i = 0; i < tileSize; i++)
+ {
+ // Bytes are signed. Cast high-order to int with sign
+ // extension, and clamp low-order to its unsigned range
+ heights[i] = buffer[2 * i] * 256 + (0xff & buffer[2 * i + 1]);
+ }
+ // Close stream
+ inStream.close();
+ return heights;
}
}
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 {
throws SrtmSourceException
{
URL tileUrl = buildUrl(inTile);
- System.out.println("Download: Need to download: " + tileUrl);
- try
- {
- HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection();
-
- // Define streams
- 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());
- }
-
- return downloadToFile(inStream, getCacheFileName(inTile));
- }
- catch (IOException e)
- {
- throw new SrtmSourceException("Error while downloading tile "+inTile.getTileName()+": "+e.getMessage());
- }
+ InputStream inStream = getStreamToUrl(tileUrl);
+ return readToFile(inStream, getCacheFileName(inTile));
}
private ZipEntry advanceToEntry(ZipInputStream inStream, SrtmTile inTile)