X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Ffunction%2Fsrtm%2FLookupSrtmFunction.java;h=15997448e038e6f4bb6e9f4b9437c99491b18a6e;hb=81843c3d8d0771bf00d0f26034a13aa515465c78;hp=30183d2d6cd13c0e780a018bc4ca6dd1ba2444b5;hpb=c0387c124840c9407e040600fda88f3c3e8f6aa6;p=GpsPrune.git diff --git a/tim/prune/function/srtm/LookupSrtmFunction.java b/tim/prune/function/srtm/LookupSrtmFunction.java index 30183d2..1599744 100644 --- a/tim/prune/function/srtm/LookupSrtmFunction.java +++ b/tim/prune/function/srtm/LookupSrtmFunction.java @@ -1,47 +1,47 @@ package tim.prune.function.srtm; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JProgressBar; +import javax.swing.JOptionPane; import tim.prune.App; import tim.prune.DataSubscriber; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.UpdateMessageBroker; +import tim.prune.config.Config; +import tim.prune.data.Altitude; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.Track; +import tim.prune.data.UnitSetLibrary; +import tim.prune.gui.ProgressDialog; +import tim.prune.tips.TipManager; import tim.prune.undo.UndoLookupSrtm; /** - * Class to provide a lookup function for point altitudes - * using the Space Shuttle's SRTM data files. - * HGT files are downloaded into memory via HTTP and point altitudes - * can then be interpolated from the 3m grid data. + * Class to provide a lookup function for point altitudes using the Space + * Shuttle's SRTM data files. HGT files are downloaded into memory via HTTP and + * point altitudes can then be interpolated from the 3m grid data. */ public class LookupSrtmFunction extends GenericFunction implements Runnable { - /** function dialog */ - private JDialog _dialog = null; - /** Progress bar for function */ - private JProgressBar _progressBar = null; - /** Cancel flag */ - private boolean _cancelled = false; + /** Progress dialog */ + private ProgressDialog _progress = null; + /** Track to process */ + private Track _track = null; + /** Flag for whether this is a real track or a terrain one */ + private boolean _normalTrack = true; + /** Flag set when any tiles had to be downloaded (rather than just loaded locally) */ + private boolean _hadToDownload = false; + /** Flag to check whether this function is currently running or not */ + private boolean _running = false; /** Expected size of hgt file in bytes */ private static final long HGT_SIZE = 2884802L; @@ -50,10 +50,9 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable /** * Constructor - * @param inApp App object + * @param inApp App object */ - public LookupSrtmFunction(App inApp) - { + public LookupSrtmFunction(App inApp) { super(inApp); } @@ -63,50 +62,37 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable } /** - * Begin the lookup + * Begin the lookup using the normal track */ - public void begin() - { - if (_dialog == null) - { - _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), false); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.getContentPane().add(makeDialogComponents()); - _dialog.pack(); - } - _progressBar.setMinimum(0); - _progressBar.setMaximum(100); - _progressBar.setValue(20); - _cancelled = false; - // start new thread for time-consuming part - new Thread(this).start(); + public void begin() { + begin(_app.getTrackInfo().getTrack(), true); } + /** + * Begin the lookup with an alternative track + * @param inAlternativeTrack + */ + public void begin(Track inAlternativeTrack) { + begin(inAlternativeTrack, false); + } /** - * Make the dialog components - * @return the GUI components for the dialog + * Begin the function with the given parameters + * @param inTrack track to process + * @param inNormalTrack true if this is a "normal" track, false for an artificially constructed one such as for terrain */ - private Component makeDialogComponents() + private void begin(Track inTrack, boolean inNormalTrack) { - JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BorderLayout()); - dialogPanel.add(new JLabel(I18nManager.getText("confirm.running")), BorderLayout.NORTH); - _progressBar = new JProgressBar(); - _progressBar.setPreferredSize(new Dimension(250, 30)); - dialogPanel.add(_progressBar, BorderLayout.CENTER); - // Cancel button at the bottom - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - _cancelled = true; - } - }); - buttonPanel.add(cancelButton); - dialogPanel.add(buttonPanel, BorderLayout.SOUTH); - return dialogPanel; + _running = true; + _hadToDownload = false; + if (_progress == null) { + _progress = new ProgressDialog(_parentFrame, getNameKey()); + } + _progress.show(); + _track = inTrack; + _normalTrack = inNormalTrack; + // start new thread for time-consuming part + new Thread(this).start(); } /** @@ -114,18 +100,44 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable */ public void run() { - _dialog.setVisible(true); // Compile list of tiles to get - Track track = _app.getTrackInfo().getTrack(); ArrayList tileList = new ArrayList(); - for (int i=0; i inTileList, boolean inOverwriteZeros) + { UndoLookupSrtm undo = new UndoLookupSrtm(_app.getTrackInfo()); int numAltitudesFound = 0; // Update progress bar - _progressBar.setMaximum(tileList.size()); - _progressBar.setIndeterminate(tileList.size() <= 1); - _progressBar.setValue(0); + if (_progress != null) + { + _progress.setMaximum(inTileList.size()); + _progress.setValue(0); + } + String errorMessage = null; // Get urls for each tile - URL[] urls = TileFinder.getUrls(tileList); - for (int t=0; t 0) System.out.println(numVoids + " voids found"); double altitude = 0.0; - switch (numVoids) { + switch (numVoids) + { case 0: altitude = bilinearInterpolate(fouralts, x, y); break; case 1: altitude = bilinearInterpolate(fixVoid(fouralts), x, y); break; case 2: case 3: altitude = averageNonVoid(fouralts); break; default: altitude = VOID_VAL; } - if (altitude != VOID_VAL) { + // Special case for terrain tracks, don't interpolate voids yet + if (!_normalTrack && numVoids > 0) { + altitude = VOID_VAL; + } + if (altitude != VOID_VAL) + { point.setFieldValue(Field.ALTITUDE, ""+altitude, false); + // depending on settings, this value may have been added as feet, we need to force metres + point.getAltitude().reset(new Altitude((int)altitude, UnitSetLibrary.UNITS_METRES)); numAltitudesFound++; } } catch (ArrayIndexOutOfBoundsException obe) { - //System.err.println("lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1); + // System.err.println("lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1); } } } } } } - catch (IOException ioe) { - //System.err.println("eek - " + ioe.getMessage()); + catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage(); } } } - _dialog.dispose(); + + _progress.dispose(); + if (_progress.isCancelled()) { + return; + } + if (numAltitudesFound > 0) { // Inform app including undo information - track.requestRescale(); + _track.requestRescale(); UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_ADDED_OR_REMOVED); - _app.completeFunction(undo, I18nManager.getText("confirm.lookupsrtm1") + " " + numAltitudesFound - + " " + I18nManager.getText("confirm.lookupsrtm2")); + // Don't update app if we're doing another track + if (_normalTrack) + { + _app.completeFunction(undo, + I18nManager.getTextWithNumber("confirm.lookupsrtm", numAltitudesFound)); + } + } + else if (errorMessage != null) { + _app.showErrorMessageNoLookup(getNameKey(), errorMessage); + } + else if (inTileList.size() > 0) { + _app.showErrorMessage(getNameKey(), "error.lookupsrtm.nonefound"); } else { - _app.showErrorMessage(getNameKey(), "error.lookupsrtm.none"); + _app.showErrorMessage(getNameKey(), "error.lookupsrtm.nonerequired"); + } + } + + /** + * See whether the SRTM file is already available locally first, then try online + * @param inUrl URL for online resource + * @return ZipInputStream either on the local file or on the downloaded zip file + */ + private ZipInputStream getStreamToHgtFile(URL inUrl) + throws IOException + { + 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.isFile() && srtmFile.canRead() + && srtmFile.length() > 400) + { + // System.out.println("Lookup: Using file " + srtmFile.getAbsolutePath()); + // File found, use this one + return new ZipInputStream(new FileInputStream(srtmFile)); + } + } } + // System.out.println("Lookup: Trying online: " + inUrl.toString()); + _hadToDownload = true; + // MAYBE: Only download if we're in online mode? + return new ZipInputStream(inUrl.openStream()); } /** @@ -250,7 +343,8 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable private static int[] fixVoid(int[] inAltitudes) { int[] fixed = new int[inAltitudes.length]; - for (int i=0; i