1 package tim.prune.function.srtm;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
8 import java.net.URLConnection;
9 import java.util.ArrayList;
11 import javax.swing.JOptionPane;
14 import tim.prune.GenericFunction;
15 import tim.prune.GpsPrune;
16 import tim.prune.I18nManager;
17 import tim.prune.config.Config;
18 import tim.prune.data.DoubleRange;
19 import tim.prune.gui.ProgressDialog;
22 * Class to provide a download function for the Space Shuttle's SRTM data files.
23 * HGT files are downloaded into memory via HTTP and stored in the map cache.
25 public class DownloadSrtmFunction extends GenericFunction implements Runnable
27 /** Progress dialog */
28 private ProgressDialog _progress = null;
29 /** Flag to check whether this function is currently running or not */
30 private boolean _running = false;
35 * @param inApp App object
37 public DownloadSrtmFunction(App inApp) {
41 /** @return name key */
42 public String getNameKey() {
43 return "function.downloadsrtm";
52 if (_progress == null) {
53 _progress = new ProgressDialog(_parentFrame, getNameKey());
56 // start new thread for time-consuming part
57 new Thread(this).start();
61 * Run method using separate thread
65 // Compile list of tiles to get
66 ArrayList<SrtmTile> tileList = new ArrayList<SrtmTile>();
68 // First, loop to see which tiles are needed
69 DoubleRange lonRange = _app.getTrackInfo().getTrack().getLonRange();
70 DoubleRange latRange = _app.getTrackInfo().getTrack().getLatRange();
71 final int minLon = (int) Math.floor(lonRange.getMinimum());
72 final int maxLon = (int) Math.floor(lonRange.getMaximum());
73 final int minLat = (int) Math.floor(latRange.getMinimum());
74 final int maxLat = (int) Math.floor(latRange.getMaximum());
76 for (int lon=minLon; lon<= maxLon; lon++)
78 for (int lat=minLat; lat <= maxLat; lat++)
80 SrtmTile tile = new SrtmTile(lat, lon);
81 boolean alreadyGot = false;
82 for (int t = 0; t < tileList.size(); t++)
84 if (tileList.get(t).equals(tile)) {
88 if (!alreadyGot) {tileList.add(tile);}
92 downloadTiles(tileList);
99 * Download the tiles of SRTM data
100 * @param inTileList list of tiles to get
102 private void downloadTiles(ArrayList<SrtmTile> inTileList)
104 // Update progress bar
105 if (_progress != null)
107 _progress.setMaximum(inTileList.size());
108 _progress.setValue(0);
111 String errorMessage = null;
113 // Check the cache is ok
114 final String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
115 if (diskCachePath != null)
117 File srtmDir = new File(diskCachePath, "srtm");
118 if (!srtmDir.exists() && !srtmDir.mkdir()) {
119 // can't create the srtm directory
120 errorMessage = I18nManager.getText("error.downloadsrtm.nocache");
125 errorMessage = I18nManager.getText("error.downloadsrtm.nocache");
128 // Get urls for each tile
129 URL[] urls = TileFinder.getUrls(inTileList);
130 int numDownloaded = 0;
131 for (int t=0; t<inTileList.size() && !_progress.isCancelled(); t++)
136 FileOutputStream outStream = null;
137 InputStream inStream = null;
141 _progress.setValue(t);
142 // See if we've already got this tile or not
143 File outputFile = getFileToWrite(urls[t]);
144 if (outputFile != null)
146 // System.out.println("Download: Need to download: " + urls[t]);
147 outStream = new FileOutputStream(outputFile);
148 URLConnection conn = urls[t].openConnection();
149 conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
150 inStream = conn.getInputStream();
151 // Copy all the bytes to the file
153 while ((c = inStream.read()) != -1)
160 // else System.out.println("Don't need to download: " + urls[t].getFile());
162 catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
164 // Make sure streams are closed
165 try {inStream.close();} catch (Exception e) {}
166 try {outStream.close();} catch (Exception e) {}
171 if (_progress.isCancelled()) {
175 if (errorMessage != null) {
176 _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
178 else if (numDownloaded == 1)
180 JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm.1", numDownloaded),
181 I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
183 else if (numDownloaded > 1)
185 JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm", numDownloaded),
186 I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
188 else if (inTileList.size() > 0) {
189 _app.showErrorMessage(getNameKey(), "confirm.downloadsrtm.none");
194 * See whether the SRTM file is already available locally
195 * @param inUrl URL for online resource
196 * @return file object to write to, or null if already there
198 private static File getFileToWrite(URL inUrl)
200 String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
201 if (diskCachePath != null)
203 File srtmDir = new File(diskCachePath, "srtm");
204 if (srtmDir.exists() && srtmDir.isDirectory() && srtmDir.canRead())
206 File srtmFile = new File(srtmDir, new File(inUrl.getFile()).getName());
207 if (!srtmFile.exists() || !srtmFile.canRead() || srtmFile.length() <= 400) {
216 * @return true if a thread is currently running
218 public boolean isRunning()