From: Frédéric Perrin Date: Tue, 20 Oct 2020 19:25:42 +0000 (+0100) Subject: Merge remote-tracking branch 'upstream/master' into fp-integration X-Git-Tag: v20.0.fp1~1 X-Git-Url: https://gitweb.fperrin.net/?p=GpsPrune.git;a=commitdiff_plain;h=9b2386d166007f68fefcaba8c27a1eefcd67af8b Merge remote-tracking branch 'upstream/master' into fp-integration --- 9b2386d166007f68fefcaba8c27a1eefcd67af8b diff --cc buildtools/build.sh index d2311b5,193244b..ee29ad8 mode 100755,100644..100755 --- a/buildtools/build.sh +++ b/buildtools/build.sh @@@ -1,7 -1,7 +1,8 @@@ +set -e # Build script + set -e # Version number - PRUNENAME=gpsprune_19.2 + PRUNENAME=gpsprune_20 # remove compile directory rm -rf compile # remove dist directory diff --cc src/tim/prune/App.java index 317064d,94e10e0..f76edb1 --- a/src/tim/prune/App.java +++ b/src/tim/prune/App.java @@@ -765,22 -755,24 +773,28 @@@ public class Ap _lastSavePosition = _undoStack.size(); _trackInfo.getSelection().clearAll(); _track.load(inLoadedTrack); - inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); - _trackInfo.getFileInfo().addSource(inSourceInfo); + if (inSourceInfo != null) + { + inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); + _trackInfo.getFileInfo().addSource(inSourceInfo); + } } // Update config before subscribers are told - boolean isRegularLoad = (inSourceInfo.getFileType() != FILE_TYPE.GPSBABEL); - Config.getRecentFileList().addFile(new RecentFile(inSourceInfo.getFile(), isRegularLoad)); + if (inSourceInfo != null) + { + boolean isRegularLoad = (inSourceInfo.getFileType() != FILE_TYPE.GPSBABEL); + Config.getRecentFileList().addFile(new RecentFile(inSourceInfo.getFile(), isRegularLoad)); + // Update status bar + UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + + " '" + inSourceInfo.getName() + "'"); + } UpdateMessageBroker.informSubscribers(); - // Update status bar - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") - + " '" + inSourceInfo.getName() + "'"); // update menu _menuManager.informFileLoaded(); + // recentre viewport on new file data + _viewport.recentreViewport(); + // update main window title + updateTitle(); // Remove busy lock _busyLoading = false; // load next file if there's a queue diff --cc src/tim/prune/FunctionLibrary.java index 4be286e,68303ed..58d049d --- a/src/tim/prune/FunctionLibrary.java +++ b/src/tim/prune/FunctionLibrary.java @@@ -110,10 -109,8 +109,9 @@@ public abstract class FunctionLibrar public static GenericFunction FUNCTION_DOWNLOAD_OSM = null; public static GenericFunction FUNCTION_ADD_TIME_OFFSET = null; public static GenericFunction FUNCTION_ADD_ALTITUDE_OFFSET = null; + public static GenericFunction FUNCTION_REMOVE_ALTITUDES = null; public static GenericFunction FUNCTION_CONVERT_NAMES_TO_TIMES = null; public static GenericFunction FUNCTION_DELETE_FIELD_VALUES = null; - public static GenericFunction FUNCTION_PASTE_COORDINATES = null; public static GenericFunction FUNCTION_FIND_WAYPOINT = null; public static GenericFunction FUNCTION_DUPLICATE_POINT = null; public static GenericFunction FUNCTION_CONNECT_TO_POINT = null; @@@ -191,10 -187,8 +188,9 @@@ FUNCTION_DOWNLOAD_OSM = new DownloadOsmFunction(inApp); FUNCTION_ADD_TIME_OFFSET = new AddTimeOffset(inApp); FUNCTION_ADD_ALTITUDE_OFFSET = new AddAltitudeOffset(inApp); + FUNCTION_REMOVE_ALTITUDES = new RemoveAltitudes(inApp); FUNCTION_CONVERT_NAMES_TO_TIMES = new ConvertNamesToTimes(inApp); FUNCTION_DELETE_FIELD_VALUES = new DeleteFieldValues(inApp); - FUNCTION_PASTE_COORDINATES = new PasteCoordinates(inApp); FUNCTION_FIND_WAYPOINT = new FindWaypoint(inApp); FUNCTION_DUPLICATE_POINT = new DuplicatePoint(inApp); FUNCTION_CONNECT_TO_POINT = new ConnectToPointFunction(inApp); diff --cc src/tim/prune/function/AddTimeOffset.java index 199ae50,115bfa5..ed75a5e --- a/src/tim/prune/function/AddTimeOffset.java +++ b/src/tim/prune/function/AddTimeOffset.java @@@ -129,9 -126,8 +129,9 @@@ public class AddTimeOffset extends Gene MouseAdapter mouseListener = new MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent arg0) { _okButton.setEnabled(getOffsetSecs() != 0L); - }; + } }; + _1024weekField.addKeyListener(keyListener); _dayField.addKeyListener(keyListener); _hourField.addKeyListener(keyListener); _minuteField.addKeyListener(keyListener); diff --cc src/tim/prune/function/srtm/LookupSrtmFunction.java index 947cca9,c48af01..8f4dc2e --- a/src/tim/prune/function/srtm/LookupSrtmFunction.java +++ b/src/tim/prune/function/srtm/LookupSrtmFunction.java @@@ -171,81 -170,52 +171,38 @@@ public class LookupSrtmFunction extend _progress.setMaximum(inTileList.size()); _progress.setValue(0); } - String errorMessage = null; - // Get urls for each tile - URL[] urls = TileFinder.getUrls(inTileList); - for (int t=0; t= 32768) {heights[i] -= 65536;} - } - } - // else { - // System.out.println("length not ok: " + entry.getSize()); - // } - // Close stream from url - inStream.close(); - } + errorMessage += "Tile "+tile.getTileName()+" not in cache!\n"; + continue; + } - if (entryOk) - { - numAltitudesFound += applySrtmTileToWholeTrack(tile, heights, inOverwriteZeros); - } - } - catch (IOException ioe) { - errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage(); - } + // Set progress + _progress.setValue(t); + + int[] heights; + try { + heights = srtmSource.getTileHeights(tile); + } + catch (SrtmSourceException e) + { + errorMessage += e.getMessage(); + e.printStackTrace(); + continue; } + int rowSize = srtmSource.getRowSize(tile); + if (rowSize <= 0) + { + errorMessage += "Tile "+tile.getTileName()+" is corrupted"; + } + - // Loop over all points in track, try to apply altitude from array - for (int p = 0; p < _track.getNumPoints(); p++) - { - DataPoint point = _track.getPoint(p); - if (needsAltitude(point, inOverwriteZeros)) - { - if (new SrtmTile(point).equals(tile)) - { - double x = (point.getLongitude().getDouble() - tile.getLongitude()) * (rowSize - 1); - double y = rowSize - (point.getLatitude().getDouble() - tile.getLatitude()) * (rowSize - 1); - int idx1 = ((int)y)*rowSize + (int)x; - try - { - int[] fouralts = {heights[idx1], heights[idx1+1], heights[idx1-rowSize], heights[idx1-rowSize+1]}; - int numVoids = (fouralts[0]==VOID_VAL?1:0) + (fouralts[1]==VOID_VAL?1:0) - + (fouralts[2]==VOID_VAL?1:0) + (fouralts[3]==VOID_VAL?1:0); - // if (numVoids > 0) System.out.println(numVoids + " voids found"); - double altitude = 0.0; - 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; - } - // 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) { - errorMessage += "Point not in tile? lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1+"\n"; - } - } - } - } ++ numAltitudesFound += applySrtmTimeToWholeTrack(tile, heights, rowSize, inOverwriteZeros); } _progress.dispose(); @@@ -277,6 -246,95 +234,64 @@@ } } - /** - * 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()); - } - + /** + * Given the height data read in from file, apply the given tile to all points + * in the track with missing altitude + * @param inTile tile being applied + * @param inHeights height data read in from file + * @param inOverwriteZeros true to overwrite zero altitude values + * @return number of altitudes found + */ - private int applySrtmTileToWholeTrack(SrtmTile inTile, int[] inHeights, boolean inOverwriteZeros) ++ private int applySrtmTimeToWholeTrack(SrtmTile inTile, int[] inHeights, int inRowSize, boolean inOverwriteZeros) + { + int numAltitudesFound = 0; + // Loop over all points in track, try to apply altitude from array + for (int p = 0; p < _track.getNumPoints(); p++) + { + DataPoint point = _track.getPoint(p); - if (!point.hasAltitude() - || (inOverwriteZeros && point.getAltitude().getValue() == 0)) ++ if (needsAltitude(point, inOverwriteZeros)) + { + if (new SrtmTile(point).equals(inTile)) + { - double x = (point.getLongitude().getDouble() - inTile.getLongitude()) * 1200; - double y = 1201 - (point.getLatitude().getDouble() - inTile.getLatitude()) * 1200; - int idx1 = ((int)y)*1201 + (int)x; ++ double x = (point.getLongitude().getDouble() - inTile.getLongitude()) * (inRowSize - 1); ++ double y = inRowSize - (point.getLatitude().getDouble() - inTile.getLatitude()) * (inRowSize - 1); ++ int idx1 = ((int)y)*inRowSize + (int)x; + try + { - int[] fouralts = {inHeights[idx1], inHeights[idx1+1], inHeights[idx1-1201], inHeights[idx1-1200]}; ++ int[] fouralts = {inHeights[idx1], inHeights[idx1+1], inHeights[idx1-inRowSize], inHeights[idx1-inRowSize+1]}; + int numVoids = (fouralts[0]==VOID_VAL?1:0) + (fouralts[1]==VOID_VAL?1:0) + + (fouralts[2]==VOID_VAL?1:0) + (fouralts[3]==VOID_VAL?1:0); + // if (numVoids > 0) System.out.println(numVoids + " voids found"); + double altitude = 0.0; + 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; ++ 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; + } + // 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("Point not in tile? lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1+"\n"); + } + } + } + } + return numAltitudesFound; + } + /** * Perform a bilinear interpolation on the given altitude array * @param inAltitudes array of four altitude values on corners of square (bl, br, tl, tr) diff --cc src/tim/prune/gui/MenuManager.java index d3386fe,d289b78..ed8474c --- a/src/tim/prune/gui/MenuManager.java +++ b/src/tim/prune/gui/MenuManager.java @@@ -34,10 -37,7 +37,11 @@@ import tim.prune.function.SearchOpenCac import tim.prune.function.browser.UrlGenerator; import tim.prune.function.browser.WebMapFunction; import tim.prune.function.search.SearchMapillaryFunction; +import tim.prune.function.srtm.DownloadSrtmFunction; +import tim.prune.function.srtm.SrtmGl1Source; +import tim.prune.function.srtm.Srtm3Source; +import tim.prune.function.srtm.SrtmViewfinderSource; + import tim.prune.function.settings.SaveConfig; /** * Class to manage the menu bar and tool bar, @@@ -95,10 -95,8 +100,8 @@@ public class MenuManager implements Dat private JMenu _browserMapMenu = null; private JMenuItem _routingGraphHopperItem = null; private JMenuItem _chartItem = null; - private JMenuItem _getGpsiesItem = null; - private JMenuItem _uploadGpsiesItem = null; private JMenuItem _lookupSrtmItem = null; - private JMenuItem _downloadSrtmItem = null; + private JMenu _downloadSrtmMenu = null; private JMenuItem _nearbyWikipediaItem = null; private JMenuItem _nearbyOsmPoiItem = null; private JMenuItem _showPeakfinderItem = null; @@@ -262,24 -260,9 +265,17 @@@ // SRTM _lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM, false); onlineMenu.add(_lookupSrtmItem); - _downloadSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_DOWNLOAD_SRTM, false); - onlineMenu.add(_downloadSrtmItem); + // Download SRTM sub-menu + _downloadSrtmMenu = new JMenu(I18nManager.getText("function.downloadsrtm")); + _downloadSrtmMenu.setEnabled(false); + JMenuItem downloadStrmGl1Item = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmGl1Source())); + _downloadSrtmMenu.add(downloadStrmGl1Item); + JMenuItem downloadStrmViewfinderItem = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmViewfinderSource())); + _downloadSrtmMenu.add(downloadStrmViewfinderItem); + JMenuItem downloadStrm3Item = makeMenuItem(new DownloadSrtmFunction(_app, new Srtm3Source())); + _downloadSrtmMenu.add(downloadStrm3Item); + onlineMenu.add(_downloadSrtmMenu); - // Get gpsies tracks - _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES, false); - onlineMenu.add(_getGpsiesItem); - // Upload to gpsies - _uploadGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_UPLOAD_GPSIES, false); - onlineMenu.add(_uploadGpsiesItem); - onlineMenu.addSeparator(); // browser submenu _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser")); @@@ -974,10 -963,9 +980,10 @@@ _reverseItem.setEnabled(hasRange); _addTimeOffsetItem.setEnabled(hasRange); _addAltitudeOffsetItem.setEnabled(hasRange); + _removeAltitudesItem.setEnabled(hasRange); _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints()); _deleteFieldValuesItem.setEnabled(hasRange); - _fullRangeDetailsItem.setEnabled(hasRange); + _viewFullDetailsItem.setEnabled(hasRange || hasPoint); _estimateTimeItem.setEnabled(hasRange); _learnEstimationParams.setEnabled(hasData && _track.hasTrackPoints() && _track.hasData(Field.TIMESTAMP) && _track.hasAltitudeData()); diff --cc src/tim/prune/lang/prune-texts_en.properties index 35ac13b,dbc4be4..fe5210c --- a/src/tim/prune/lang/prune-texts_en.properties +++ b/src/tim/prune/lang/prune-texts_en.properties @@@ -111,14 -112,8 +113,12 @@@ function.selectsegment=Select current s function.splitsegments=Split track into segments function.sewsegments=Sew track segments together function.createmarkerwaypoints=Create marker waypoints - function.getgpsies=Get Gpsies tracks - function.uploadgpsies=Upload track to Gpsies function.lookupsrtm=Get altitudes from SRTM function.downloadsrtm=Download SRTM tiles +function.downloadsrtm.SRTMGL1_v003=SRTM 1 arc-second tiles +function.downloadsrtm.SRTMGL1_v003.needsetup=An Earthdata account is necessary to download SRTM 1 arc-second tiles +function.downloadsrtm.SRTM3_v21=SRTM 3 arc-second tiles +function.downloadsrtm.SRTM_Viewfinder=Viewfinderpanoramas.org data function.getwikipedia=Get nearby Wikipedia articles function.searchwikipedianames=Search Wikipedia by name function.searchosmpois=Get nearby OSM points @@@ -581,12 -550,10 +557,15 @@@ dialog.displaysettings.wpicon.pin=Boar dialog.displaysettings.size.small=Small dialog.displaysettings.size.medium=Medium dialog.displaysettings.size.large=Large + dialog.displaysettings.windowstyle=Window style (requires restart) + dialog.displaysettings.windowstyle.default=Default + dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Confirm to download the raw OSM data for the specified area: +dialog.earthdataauth.intro=

Configure username and password to access your NASA Earthdata login account.

Create an account at https://urs.earthdata.nasa.gov/users/new.

+dialog.earthdataauth.user=Username +dialog.earthdataauth.password=Password +dialog.earthdataauth.authaccepted=Username and password accepted +dialog.earthdataauth.authrejected=Username and password rejected dialog.searchwikipedianames.search=Search for: dialog.weather.location=Location dialog.weather.update=Forecast updated