File: DownloadSrtmFunction.java

package info (click to toggle)
gpsprune 17-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,984 kB
  • ctags: 5,218
  • sloc: java: 39,403; sh: 25; makefile: 17; python: 15
file content (222 lines) | stat: -rw-r--r-- 5,998 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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() <= 1) {
					return srtmFile;
				}
			}
		}
		return null;
	}

	/**
	 * @return true if a thread is currently running
	 */
	public boolean isRunning()
	{
		return _running;
	}
}