--- /dev/null
+package tim.prune.function.srtm;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+
+import javax.swing.JOptionPane;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.GpsPrune;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.data.DoubleRange;
+import tim.prune.gui.ProgressDialog;
+
+/**
+ * Class to provide a download function for the Space Shuttle's SRTM data files.
+ * HGT files are downloaded into memory via HTTP and stored in the map cache.
+ */
+public class DownloadSrtmFunction extends GenericFunction implements Runnable
+{
+ /** Progress dialog */
+ private ProgressDialog _progress = null;
+ /** Flag to check whether this function is currently running or not */
+ private boolean _running = false;
+
+
+ /**
+ * Constructor
+ * @param inApp App object
+ */
+ public DownloadSrtmFunction(App inApp) {
+ super(inApp);
+ }
+
+ /** @return name key */
+ public String getNameKey() {
+ return "function.downloadsrtm";
+ }
+
+ /**
+ * Begin the download
+ */
+ public void begin()
+ {
+ _running = true;
+ if (_progress == null) {
+ _progress = new ProgressDialog(_parentFrame, getNameKey());
+ }
+ _progress.show();
+ // start new thread for time-consuming part
+ new Thread(this).start();
+ }
+
+ /**
+ * Run method using separate thread
+ */
+ public void run()
+ {
+ // Compile list of tiles to get
+ ArrayList<SrtmTile> tileList = new ArrayList<SrtmTile>();
+
+ // First, loop to see which tiles are needed
+ DoubleRange lonRange = _app.getTrackInfo().getTrack().getLonRange();
+ DoubleRange latRange = _app.getTrackInfo().getTrack().getLatRange();
+ final int minLon = (int) Math.floor(lonRange.getMinimum());
+ final int maxLon = (int) Math.floor(lonRange.getMaximum());
+ final int minLat = (int) Math.floor(latRange.getMinimum());
+ final int maxLat = (int) Math.floor(latRange.getMaximum());
+
+ for (int lon=minLon; lon<= maxLon; lon++)
+ {
+ for (int lat=minLat; lat <= maxLat; lat++)
+ {
+ SrtmTile tile = new SrtmTile(lat, lon);
+ boolean alreadyGot = false;
+ for (int t = 0; t < tileList.size(); t++)
+ {
+ if (tileList.get(t).equals(tile)) {
+ alreadyGot = true;
+ }
+ }
+ if (!alreadyGot) {tileList.add(tile);}
+ }
+ }
+
+ downloadTiles(tileList);
+ // Finished
+ _running = false;
+ }
+
+
+ /**
+ * Download the tiles of SRTM data
+ * @param inTileList list of tiles to get
+ */
+ private void downloadTiles(ArrayList<SrtmTile> inTileList)
+ {
+ // Update progress bar
+ if (_progress != null)
+ {
+ _progress.setMaximum(inTileList.size());
+ _progress.setValue(0);
+ }
+
+ String errorMessage = null;
+
+ // Check the cache is ok
+ final String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
+ if (diskCachePath != null)
+ {
+ File srtmDir = new File(diskCachePath, "srtm");
+ if (!srtmDir.exists() && !srtmDir.mkdir()) {
+ // can't create the srtm directory
+ errorMessage = I18nManager.getText("error.downloadsrtm.nocache");
+ }
+ }
+ else {
+ // no cache set up
+ errorMessage = I18nManager.getText("error.downloadsrtm.nocache");
+ }
+
+ // Get urls for each tile
+ URL[] urls = TileFinder.getUrls(inTileList);
+ int numDownloaded = 0;
+ for (int t=0; t<inTileList.size() && !_progress.isCancelled(); t++)
+ {
+ if (urls[t] != null)
+ {
+ // Define streams
+ FileOutputStream outStream = null;
+ InputStream inStream = null;
+ try
+ {
+ // Set progress
+ _progress.setValue(t);
+ // See if we've already got this tile or not
+ File outputFile = getFileToWrite(urls[t]);
+ if (outputFile != null)
+ {
+ // System.out.println("Download: Need to download: " + urls[t]);
+ outStream = new FileOutputStream(outputFile);
+ URLConnection conn = urls[t].openConnection();
+ conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
+ inStream = conn.getInputStream();
+ // Copy all the bytes to the file
+ int c;
+ while ((c = inStream.read()) != -1)
+ {
+ outStream.write(c);
+ }
+
+ numDownloaded++;
+ }
+ // else System.out.println("Don't need to download: " + urls[t].getFile());
+ }
+ catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
+ }
+ // Make sure streams are closed
+ try {inStream.close();} catch (Exception e) {}
+ try {outStream.close();} catch (Exception e) {}
+ }
+ }
+
+ _progress.dispose();
+ if (_progress.isCancelled()) {
+ return;
+ }
+
+ if (errorMessage != null) {
+ _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
+ }
+ else if (numDownloaded == 1)
+ {
+ JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm.1", numDownloaded),
+ I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
+ }
+ else if (numDownloaded > 1)
+ {
+ JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm", numDownloaded),
+ I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
+ }
+ else if (inTileList.size() > 0) {
+ _app.showErrorMessage(getNameKey(), "confirm.downloadsrtm.none");
+ }
+ }
+
+ /**
+ * See whether the SRTM file is already available locally
+ * @param inUrl URL for online resource
+ * @return file object to write to, or null if already there
+ */
+ private static File getFileToWrite(URL inUrl)
+ {
+ String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
+ if (diskCachePath != null)
+ {
+ File srtmDir = new File(diskCachePath, "srtm");
+ if (srtmDir.exists() && srtmDir.isDirectory() && srtmDir.canRead())
+ {
+ File srtmFile = new File(srtmDir, new File(inUrl.getFile()).getName());
+ if (!srtmFile.exists() || !srtmFile.canRead() || srtmFile.length() <= 400) {
+ return srtmFile;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return true if a thread is currently running
+ */
+ public boolean isRunning()
+ {
+ return _running;
+ }
+}