]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/function/srtm/DownloadSrtmFunction.java
d0d92bb152062a7515a67410746643397a715173
[GpsPrune.git] / tim / prune / function / srtm / DownloadSrtmFunction.java
1 package tim.prune.function.srtm;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.net.URL;
8 import java.net.URLConnection;
9 import java.util.ArrayList;
10
11 import javax.swing.JOptionPane;
12
13 import tim.prune.App;
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;
20
21 /**
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.
24  */
25 public class DownloadSrtmFunction extends GenericFunction implements Runnable
26 {
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;
31
32
33         /**
34          * Constructor
35          * @param inApp  App object
36          */
37         public DownloadSrtmFunction(App inApp) {
38                 super(inApp);
39         }
40
41         /** @return name key */
42         public String getNameKey() {
43                 return "function.downloadsrtm";
44         }
45
46         /**
47          * Begin the download
48          */
49         public void begin()
50         {
51                 _running = true;
52                 if (_progress == null) {
53                         _progress = new ProgressDialog(_parentFrame, getNameKey());
54                 }
55                 _progress.show();
56                 // start new thread for time-consuming part
57                 new Thread(this).start();
58         }
59
60         /**
61          * Run method using separate thread
62          */
63         public void run()
64         {
65                 // Compile list of tiles to get
66                 ArrayList<SrtmTile> tileList = new ArrayList<SrtmTile>();
67
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());
75
76                 for (int lon=minLon; lon<= maxLon; lon++)
77                 {
78                         for (int lat=minLat; lat <= maxLat; lat++)
79                         {
80                                 SrtmTile tile = new SrtmTile(lat, lon);
81                                 boolean alreadyGot = false;
82                                 for (int t = 0; t < tileList.size(); t++)
83                                 {
84                                         if (tileList.get(t).equals(tile)) {
85                                                 alreadyGot = true;
86                                         }
87                                 }
88                                 if (!alreadyGot) {tileList.add(tile);}
89                         }
90                 }
91
92                 downloadTiles(tileList);
93                 // Finished
94                 _running = false;
95         }
96
97
98         /**
99          * Download the tiles of SRTM data
100          * @param inTileList list of tiles to get
101          */
102         private void downloadTiles(ArrayList<SrtmTile> inTileList)
103         {
104                 // Update progress bar
105                 if (_progress != null)
106                 {
107                         _progress.setMaximum(inTileList.size());
108                         _progress.setValue(0);
109                 }
110
111                 String errorMessage = null;
112
113                 // Check the cache is ok
114                 final String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
115                 if (diskCachePath != null)
116                 {
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");
121                         }
122                 }
123                 else {
124                         // no cache set up
125                         errorMessage = I18nManager.getText("error.downloadsrtm.nocache");
126                 }
127
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++)
132                 {
133                         if (urls[t] != null)
134                         {
135                                 // Define streams
136                                 FileOutputStream outStream = null;
137                                 InputStream inStream = null;
138                                 try
139                                 {
140                                         // Set progress
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)
145                                         {
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
152                                                 int c;
153                                                 while ((c = inStream.read()) != -1)
154                                                 {
155                                                         outStream.write(c);
156                                                 }
157
158                                                 numDownloaded++;
159                                         }
160                                         // else System.out.println("Don't need to download: " + urls[t].getFile());
161                                 }
162                                 catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
163                                 }
164                                 // Make sure streams are closed
165                                 try {inStream.close();} catch (Exception e) {}
166                                 try {outStream.close();} catch (Exception e) {}
167                         }
168                 }
169
170                 _progress.dispose();
171                 if (_progress.isCancelled()) {
172                         return;
173                 }
174
175                 if (errorMessage != null) {
176                         _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
177                 }
178                 else if (numDownloaded == 1)
179                 {
180                         JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm.1", numDownloaded),
181                                 I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
182                 }
183                 else if (numDownloaded > 1)
184                 {
185                         JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm", numDownloaded),
186                                 I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
187                 }
188                 else if (inTileList.size() > 0) {
189                         _app.showErrorMessage(getNameKey(), "confirm.downloadsrtm.none");
190                 }
191         }
192
193         /**
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
197          */
198         private static File getFileToWrite(URL inUrl)
199         {
200                 String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
201                 if (diskCachePath != null)
202                 {
203                         File srtmDir = new File(diskCachePath, "srtm");
204                         if (srtmDir.exists() && srtmDir.isDirectory() && srtmDir.canRead())
205                         {
206                                 File srtmFile = new File(srtmDir, new File(inUrl.getFile()).getName());
207                                 if (!srtmFile.exists() || !srtmFile.canRead() || srtmFile.length() <= 1) {
208                                         return srtmFile;
209                                 }
210                         }
211                 }
212                 return null;
213         }
214
215         /**
216          * @return true if a thread is currently running
217          */
218         public boolean isRunning()
219         {
220                 return _running;
221         }
222 }