From 4891d3eb6337b7b814485cab78583b0608183554 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20Perrin?= Date: Thu, 30 Jan 2020 14:01:20 +0000 Subject: [PATCH] Refactor and add comments --- src/tim/prune/function/srtm/Srtm3Source.java | 38 +--- .../prune/function/srtm/SrtmGl1Source.java | 3 +- src/tim/prune/function/srtm/SrtmSource.java | 186 +++++++++++++----- .../function/srtm/SrtmViewfinderSource.java | 36 +--- 4 files changed, 148 insertions(+), 115 deletions(-) diff --git a/src/tim/prune/function/srtm/Srtm3Source.java b/src/tim/prune/function/srtm/Srtm3Source.java index cc0da79..7e869f1 100644 --- a/src/tim/prune/function/srtm/Srtm3Source.java +++ b/src/tim/prune/function/srtm/Srtm3Source.java @@ -1,14 +1,11 @@ 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 { @@ -59,7 +56,7 @@ 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 @@ -111,37 +108,8 @@ public class Srtm3Source extends SrtmSource { 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) diff --git a/src/tim/prune/function/srtm/SrtmGl1Source.java b/src/tim/prune/function/srtm/SrtmGl1Source.java index f8639b7..0a74043 100644 --- a/src/tim/prune/function/srtm/SrtmGl1Source.java +++ b/src/tim/prune/function/srtm/SrtmGl1Source.java @@ -84,7 +84,6 @@ public class SrtmGl1Source extends SrtmSource { { URL tileUrl = buildUrl(inTile); File outputFile = getCacheFileName(inTile); - System.out.println("Download: Need to download: " + tileUrl); try { HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection(); @@ -129,7 +128,7 @@ public class SrtmGl1Source extends SrtmSource { } } - return downloadToFile(inStream, outputFile); + return readToFile(inStream, outputFile); } catch (IOException e) { diff --git a/src/tim/prune/function/srtm/SrtmSource.java b/src/tim/prune/function/srtm/SrtmSource.java index 6e49ad1..220aed7 100644 --- a/src/tim/prune/function/srtm/SrtmSource.java +++ b/src/tim/prune/function/srtm/SrtmSource.java @@ -5,59 +5,65 @@ import java.io.FileInputStream; 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 { @@ -85,21 +91,113 @@ public abstract class SrtmSource { } + // 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; } } diff --git a/src/tim/prune/function/srtm/SrtmViewfinderSource.java b/src/tim/prune/function/srtm/SrtmViewfinderSource.java index a25e9c4..b1b7a54 100644 --- a/src/tim/prune/function/srtm/SrtmViewfinderSource.java +++ b/src/tim/prune/function/srtm/SrtmViewfinderSource.java @@ -2,20 +2,16 @@ 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 { @@ -130,36 +126,8 @@ 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) -- 2.43.0