From e7660043365a5c61c90cfd284deb11f65a956412 Mon Sep 17 00:00:00 2001 From: activityworkshop Date: Thu, 21 Jan 2021 21:33:03 +0100 Subject: [PATCH] Configure SRTM sources for 1-sec option --- src/tim/prune/config/Config.java | 3 +- .../function/srtm/ConfigureSrtmSources.java | 228 ++++++++++++++++++ src/tim/prune/gui/MenuManager.java | 4 + src/tim/prune/lang/prune-texts_de.properties | 15 +- .../prune/lang/prune-texts_de_CH.properties | 15 +- src/tim/prune/lang/prune-texts_en.properties | 12 + 6 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 src/tim/prune/function/srtm/ConfigureSrtmSources.java diff --git a/src/tim/prune/config/Config.java b/src/tim/prune/config/Config.java index a5226b3..68f72cc 100644 --- a/src/tim/prune/config/Config.java +++ b/src/tim/prune/config/Config.java @@ -111,7 +111,8 @@ public abstract class Config public static final String KEY_TIMEZONE_ID = "prune.timezoneid"; /** Last used latlon range */ public static final String KEY_LATLON_RANGE = "prune.latlonrange"; - + /** Username/password to the Earthdata server for SRTM 1-arcsecond tiles */ + public static final String KEY_EARTHDATA_AUTH = "prune.earthdataauth"; /** Initialise the default properties */ static diff --git a/src/tim/prune/function/srtm/ConfigureSrtmSources.java b/src/tim/prune/function/srtm/ConfigureSrtmSources.java new file mode 100644 index 0000000..a8a73c7 --- /dev/null +++ b/src/tim/prune/function/srtm/ConfigureSrtmSources.java @@ -0,0 +1,228 @@ +package tim.prune.function.srtm; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Base64; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.function.browser.BrowserLauncher; + +/** + * Configure SRTM sources, including authentication for the NASA Earthdata systems + * @author fperrin, activityworkshop + */ +public class ConfigureSrtmSources extends GenericFunction +{ + private JDialog _dialog = null; + private JCheckBox _oneSecondCheck = null; + private boolean _oneSecondOriginallyOn = false; + private String _authString = null; + private JButton _okButton = null; + + + /** + * Constructor + * @param inApp App object + */ + public ConfigureSrtmSources(App inApp) { + super(inApp); + } + + /** @return name key */ + public String getNameKey() { + return "function.configuresrtmsources"; + } + + /** + * Function entry point + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + // Create Gui and show it + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + prefillCurrentAuth(); + _dialog.setVisible(true); + } + + /** + * Make the dialog components + * @return the GUI components for the dialog + */ + private JPanel makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout()); + + // Make a central panel with boxes for each of 3-second and 1-second sources + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + JPanel introPanel = new JPanel(); + introPanel.setLayout(new BoxLayout(introPanel, BoxLayout.Y_AXIS)); + introPanel.add(new JLabel(I18nManager.getText("dialog.configuresrtm.intro1"))); + introPanel.add(new JLabel(I18nManager.getText("dialog.configuresrtm.intro2"))); + mainPanel.add(introPanel); + mainPanel.add(Box.createRigidArea(new Dimension(0, 10))); + + // 3-second source + JPanel threeSecondPanel = new JPanel(); + threeSecondPanel.setBorder(BorderFactory.createTitledBorder("")); + threeSecondPanel.setLayout(new BoxLayout(threeSecondPanel, BoxLayout.Y_AXIS)); + JCheckBox threeSecondCheck = new JCheckBox(I18nManager.getText("dialog.configuresrtm.threesecond")); + threeSecondCheck.setSelected(true); + threeSecondCheck.setEnabled(false); + threeSecondPanel.add(threeSecondCheck); + threeSecondPanel.add(new JLabel(I18nManager.getText("dialog.configuresrtm.threesecond.desc"))); + + mainPanel.add(threeSecondPanel); + mainPanel.add(Box.createRigidArea(new Dimension(0, 10))); + + // 1-second source + JPanel oneSecondPanel = new JPanel(); + oneSecondPanel.setBorder(BorderFactory.createTitledBorder("")); + oneSecondPanel.setLayout(new BoxLayout(oneSecondPanel, BoxLayout.Y_AXIS)); + + _oneSecondCheck = new JCheckBox(I18nManager.getText("dialog.configuresrtm.onesecond")); + _oneSecondCheck.setSelected(true); + oneSecondPanel.add(_oneSecondCheck); + _oneSecondCheck.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent inEvent) { + if (_oneSecondCheck.isSelected()) { + setupEarthdataAuth(); + } + _okButton.setEnabled(_oneSecondCheck.isSelected() != _oneSecondOriginallyOn); + } + }); + oneSecondPanel.add(new JLabel(I18nManager.getText("dialog.configuresrtm.onesecond.desc1"))); + oneSecondPanel.add(new JLabel(I18nManager.getText("dialog.configuresrtm.onesecond.desc2"))); + + mainPanel.add(oneSecondPanel); + mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + + // ok / cancel buttons at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + finish(); + } + }); + buttonPanel.add(_okButton); + JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + _dialog.dispose(); + } + }); + buttonPanel.add(cancelButton); + dialogPanel.add(buttonPanel, BorderLayout.SOUTH); + dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); + return dialogPanel; + } + + /** + * User has activated the 1-second checkbox, so we need to ask for username / password details + * and save the result + */ + private void setupEarthdataAuth() + { + Object[] buttonTexts = {I18nManager.getText("button.yes"), I18nManager.getText("button.no")}; + int showWebsiteAnswer = JOptionPane.showOptionDialog(_parentFrame, + I18nManager.getText("dialog.configuresrtm.showregistrationwebsite"), + I18nManager.getText(getNameKey()), JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, null, buttonTexts, buttonTexts[1]); + if (showWebsiteAnswer == JOptionPane.YES_OPTION) { + BrowserLauncher.launchBrowser("https://urs.earthdata.nasa.gov/users/new"); + } + // Now get the registered user id + Object userId = JOptionPane.showInputDialog(_app.getFrame(), + I18nManager.getText("dialog.configuresrtm.userid"), + I18nManager.getText(getNameKey()), + JOptionPane.QUESTION_MESSAGE, null, null, ""); + if (userId == null || userId.equals("")) + { + _oneSecondCheck.setSelected(false); + return; + } + Object password = JOptionPane.showInputDialog(_app.getFrame(), + I18nManager.getText("dialog.configuresrtm.password"), + I18nManager.getText(getNameKey()), + JOptionPane.QUESTION_MESSAGE, null, null, ""); + if (password == null || password.equals("")) + { + _oneSecondCheck.setSelected(false); + return; + } + String authString = Base64.getEncoder().encodeToString((userId.toString() + ":" + password.toString()).getBytes()); + if (isAuthValid(authString)) { + _authString = authString; + } + else + { + JOptionPane.showMessageDialog(_dialog, I18nManager.getText("dialog.configuresrtm.loginfailed"), + I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); + _oneSecondCheck.setSelected(false); + } + } + + /** + * React to 'OK' being pressed, to save the config + */ + private void finish() + { + if (_oneSecondCheck.isSelected()) + { + if (_authString != null) { + Config.setConfigString(Config.KEY_EARTHDATA_AUTH, _authString); + } + } + else { + Config.setConfigString(Config.KEY_EARTHDATA_AUTH, null); + } + _dialog.dispose(); + } + + /** + * Init the dialog according to the saved authentication config + */ + private void prefillCurrentAuth() + { + _oneSecondCheck.setSelected(isAuthValid(Config.getConfigString(Config.KEY_EARTHDATA_AUTH))); + _authString = null; + _oneSecondOriginallyOn = _oneSecondCheck.isSelected(); + _okButton.setEnabled(false); + } + + /** + * Check the given config string for successful authentication using the NASA server + */ + private boolean isAuthValid(String inConfigString) + { + // TODO: Use this string to login to NASA server and check success or failure + return inConfigString != null && !inConfigString.isEmpty(); + } +} diff --git a/src/tim/prune/gui/MenuManager.java b/src/tim/prune/gui/MenuManager.java index a584815..6a0c280 100644 --- a/src/tim/prune/gui/MenuManager.java +++ b/src/tim/prune/gui/MenuManager.java @@ -38,6 +38,7 @@ import tim.prune.function.browser.UrlGenerator; import tim.prune.function.browser.WebMapFunction; import tim.prune.function.search.SearchMapillaryFunction; import tim.prune.function.settings.SaveConfig; +import tim.prune.function.srtm.ConfigureSrtmSources; /** * Class to manage the menu bar and tool bar, @@ -97,6 +98,7 @@ public class MenuManager implements DataSubscriber private JMenuItem _routingGraphHopperItem = null; private JMenuItem _chartItem = null; private JMenuItem _lookupSrtmItem = null; + private JMenuItem _configureSrtmItem = null; private JMenuItem _nearbyWikipediaItem = null; private JMenuItem _nearbyOsmPoiItem = null; private JMenuItem _showPeakfinderItem = null; @@ -260,6 +262,8 @@ public class MenuManager implements DataSubscriber // SRTM _lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM, false); onlineMenu.add(_lookupSrtmItem); + _configureSrtmItem = makeMenuItem(new ConfigureSrtmSources(_app), true); + onlineMenu.add(_configureSrtmItem); onlineMenu.addSeparator(); // browser submenu diff --git a/src/tim/prune/lang/prune-texts_de.properties b/src/tim/prune/lang/prune-texts_de.properties index 2b69afb..26d4a8e 100644 --- a/src/tim/prune/lang/prune-texts_de.properties +++ b/src/tim/prune/lang/prune-texts_de.properties @@ -113,6 +113,7 @@ function.splitsegments=In Trackabschnitte schneiden function.sewsegments=Trackabschnitte zusammenf\u00fcgen function.createmarkerwaypoints=Wegpunkte im bestimmten Abstand kreieren function.lookupsrtm=H\u00f6hendaten von SRTM nachschlagen +function.configuresrtmsources=SRTM Quellen konfigurieren function.getwikipedia=Wikipediaartikel in der N\u00e4he nachschlagen function.searchwikipedianames=Wikipedia nach Namen durchsuchen function.searchosmpois=OpenStreetMap nach Punkten durchsuchen @@ -595,8 +596,20 @@ dialog.markers.halves=Punkte auf halben Weg dialog.markers.half.distance=Halbe Distanz dialog.markers.half.climb=Halber Aufstieg dialog.markers.half.descent=Halber Abstieg -dialog.projectpoint.desc=Geben Sie die Azimut und Distanz f\u00fcr die Projizierung +dialog.projectpoint.desc=Geben Sie die Azimut und Distanz f\u00fcr die Projizierung ein dialog.projectpoint.bearing=Azimut (Grad von N) +dialog.projectcircle.desc=Geben Sie die Distanz von diesem Punkt zum Kreis ein +dialog.configuresrtm.intro1=SRTM-H\u00f6hendaten k\u00f6nnen entweder vom groben Dataset ohne Login kommen, +dialog.configuresrtm.intro2=oder nach Registrierung bei NASA von Daten h\u00f6herer Aufl\u00f6sung +dialog.configuresrtm.threesecond=Niedrige Aufl\u00f6sung (3 Winkelsekunden) +dialog.configuresrtm.threesecond.desc=Grobe Daten ist immer aktiv ohne Registrierung oder Login +dialog.configuresrtm.onesecond=Hohe Aufl\u00f6sung (1 Winkelsekunde) +dialog.configuresrtm.onesecond.desc1=Daten h\u00f6herer Aufl\u00f6sung ben\u00f6tigt Registrierung bei NASA Earthdata. +dialog.configuresrtm.onesecond.desc2=Profil bitte hier kreieren: https://urs.earthdata.nasa.gov/users/new +dialog.configuresrtm.showregistrationwebsite=NASA Webseite jetzt f\u00fcr Registrierung \u00f6ffnen? +dialog.configuresrtm.userid=Username bei NASA Earthdata +dialog.configuresrtm.password=Passwort bei NASA Earthdata +dialog.configuresrtm.loginfailed=Username und Passwort wurden vom Earthdata Server abgelehnt # 3d window dialog.3d.title=GpsPrune-3D-Ansicht diff --git a/src/tim/prune/lang/prune-texts_de_CH.properties b/src/tim/prune/lang/prune-texts_de_CH.properties index ec3c91c..503de28 100644 --- a/src/tim/prune/lang/prune-texts_de_CH.properties +++ b/src/tim/prune/lang/prune-texts_de_CH.properties @@ -38,7 +38,6 @@ menu.view.showsidebars=Seiteleischten aazeige menu.view.browser=Karte inem Browser menu.settings=Iistellige menu.settings.onlinemode=Karten uusem Internet lade -dialog.displaysettings.antialias=Kantegl\u00e4ttig aa menu.settings.autosave=Iistellige automatisch speichere menu.help=Hilfe # Popup menu for map @@ -111,6 +110,7 @@ function.splitsegments=In Tracksegm\u00e4nte schniide function.sewsegments=Tracksegm\u00e4nte z\u00e4mef\u00fcge function.createmarkerwaypoints=Waypoints inem bestimmten Abstand kreiere function.lookupsrtm=H\u00f6hendate vonem SRTM hole +function.configuresrtmsources=SRTM Qu\u00e4lle konfiguriere function.getwikipedia=Im Wikipedia in dr N\u00f6chi naaluege function.searchwikipedianames=Wikipedia nachem Namen durasueche function.searchosmpois=OpenStreetMap na P\u00fcnkt durasueche @@ -532,6 +532,7 @@ dialog.diskcache.deleted=Es sin %d Files uusem Ordner gl\u00f6scht worde dialog.deletefieldvalues.intro=W\u00e4hlet Sie s F\u00e4ld uus zum l\u00f6sche dialog.deletefieldvalues.nofields=Es sin kei F\u00e4lder z'l\u00f6sche f\u00fcr dere Beriich dialog.displaysettings.linewidth=Dicke vonen Linien in Pixeln (1-4) +dialog.displaysettings.antialias=Kantegl\u00e4ttig aa dialog.displaysettings.waypointicons=Waypoint Ikons dialog.displaysettings.wpicon.default=P\u00fcnktli dialog.displaysettings.wpicon.ringpt=Rundes Schild @@ -592,6 +593,18 @@ dialog.markers.half.climb=Halber Uufstieg dialog.markers.half.descent=Halber Abstieg dialog.projectpoint.desc=Richtig und Distanz iigeh, mit dene s zu projizieren isch dialog.projectpoint.bearing=Azimut (Grad vo N) +dialog.projectcircle.desc=Distanz iigeh vo dem Punkt zum Kreis +dialog.configuresrtm.intro1=SRTM-H\u00f6chidate k\u00f6nnet entweder vom groben Dataset ohni Login cho, +dialog.configuresrtm.intro2=oder na Registrierig bidr NASA vo Daten h\u00f6herer Uufl\u00f6sig +dialog.configuresrtm.threesecond=Niedrigi Uufl\u00f6sig (3 Winkelsekunden) +dialog.configuresrtm.threesecond.desc=Grobi Daten isch immer aktiv ohni Registrierig oder Login +dialog.configuresrtm.onesecond=Hohe Uufl\u00f6sig (1 Winkelsekunde) +dialog.configuresrtm.onesecond.desc1=Date vo h\u00f6herer Uufl\u00f6sig bruucht Registrierig bidr NASA Earthdata. +dialog.configuresrtm.onesecond.desc2=Profil bitte do kreiere: https://urs.earthdata.nasa.gov/users/new +dialog.configuresrtm.showregistrationwebsite=NASA Websiite etzt f\u00fcrd Registrierig \u00f6ffne? +dialog.configuresrtm.userid=Username bi NASA Earthdata +dialog.configuresrtm.password=Passwort bi NASA Earthdata +dialog.configuresrtm.loginfailed=Username und Passwort sin vonem Earthdata Server abglehnt wore # 3d window dialog.3d.title=GpsPrune Dr\u00fc\u00fc-d Aasicht diff --git a/src/tim/prune/lang/prune-texts_en.properties b/src/tim/prune/lang/prune-texts_en.properties index 71a5425..eb4e914 100644 --- a/src/tim/prune/lang/prune-texts_en.properties +++ b/src/tim/prune/lang/prune-texts_en.properties @@ -113,6 +113,7 @@ function.splitsegments=Split track into segments function.sewsegments=Sew track segments together function.createmarkerwaypoints=Create marker waypoints function.lookupsrtm=Get altitudes from SRTM +function.configuresrtmsources=Configure SRTM sources function.getwikipedia=Get nearby Wikipedia articles function.searchwikipedianames=Search Wikipedia by name function.searchosmpois=Get nearby OSM points @@ -602,6 +603,17 @@ dialog.markers.half.descent=Half descent dialog.projectpoint.desc=Enter the direction and distance to project this point dialog.projectpoint.bearing=Bearing (degrees from N) dialog.projectcircle.desc=Enter the distance from this point to the surrounding circle +dialog.configuresrtm.intro1=Altitudes from SRTM can come either from the low-resolution data without login, +dialog.configuresrtm.intro2=or by registering at NASA for high-resolution data +dialog.configuresrtm.threesecond=Low resolution data (three arc seconds) +dialog.configuresrtm.threesecond.desc=Low resolution data is always enabled without registration or login +dialog.configuresrtm.onesecond=High resolution data (one arc second) +dialog.configuresrtm.onesecond.desc1=High resolution data requires registration and login to NASA Earthdata. +dialog.configuresrtm.onesecond.desc2=Create an account at https://urs.earthdata.nasa.gov/users/new +dialog.configuresrtm.showregistrationwebsite=Go now to NASA website for registration? +dialog.configuresrtm.userid=Username registered at NASA Earthdata +dialog.configuresrtm.password=Password registered at NASA Earthdata +dialog.configuresrtm.loginfailed=Username and password were rejected by the Earthdata server # 3d window dialog.3d.title=GpsPrune Three-d view -- 2.43.0