]> gitweb.fperrin.net Git - GpsPrune.git/commitdiff
Merge branch 'fp-integration' into debian/sid
authorFrédéric Perrin <fred@fperrin.net>
Sat, 30 Nov 2019 22:27:30 +0000 (22:27 +0000)
committerFrédéric Perrin <fred@fperrin.net>
Sat, 30 Nov 2019 22:27:30 +0000 (22:27 +0000)
518 files changed:
.gitignore [new file with mode: 0644]
buildtools/MANIFEST.MF [new file with mode: 0644]
buildtools/build.sh [new file with mode: 0755]
buildtools/build.xml [new file with mode: 0644]
buildtools/howtobuild.txt [new file with mode: 0644]
buildtools/pom.xml [new file with mode: 0644]
buildtools/version.properties [new file with mode: 0644]
src/tim/prune/App.java [moved from tim/prune/App.java with 96% similarity]
src/tim/prune/DataStatus.java [moved from tim/prune/DataStatus.java with 100% similarity]
src/tim/prune/DataSubscriber.java [moved from tim/prune/DataSubscriber.java with 100% similarity]
src/tim/prune/ExternalTools.java [moved from tim/prune/ExternalTools.java with 100% similarity]
src/tim/prune/FileDropHandler.java [moved from tim/prune/FileDropHandler.java with 100% similarity]
src/tim/prune/FunctionLibrary.java [moved from tim/prune/FunctionLibrary.java with 97% similarity]
src/tim/prune/GenericFunction.java [moved from tim/prune/GenericFunction.java with 100% similarity]
src/tim/prune/GpsPrune.java [moved from tim/prune/GpsPrune.java with 100% similarity]
src/tim/prune/I18nManager.java [moved from tim/prune/I18nManager.java with 100% similarity]
src/tim/prune/UpdateMessageBroker.java [moved from tim/prune/UpdateMessageBroker.java with 100% similarity]
src/tim/prune/config/ColourScheme.java [moved from tim/prune/config/ColourScheme.java with 100% similarity]
src/tim/prune/config/ColourUtils.java [moved from tim/prune/config/ColourUtils.java with 100% similarity]
src/tim/prune/config/Config.java [moved from tim/prune/config/Config.java with 98% similarity]
src/tim/prune/config/ConfigException.java [moved from tim/prune/config/ConfigException.java with 100% similarity]
src/tim/prune/config/TimezoneHelper.java [moved from tim/prune/config/TimezoneHelper.java with 100% similarity]
src/tim/prune/copyright.txt [moved from tim/prune/copyright.txt with 100% similarity]
src/tim/prune/correlate/AudioCorrelator.java [moved from tim/prune/correlate/AudioCorrelator.java with 100% similarity]
src/tim/prune/correlate/AudioTimestampSelector.java [moved from tim/prune/correlate/AudioTimestampSelector.java with 100% similarity]
src/tim/prune/correlate/CardStack.java [moved from tim/prune/correlate/CardStack.java with 100% similarity]
src/tim/prune/correlate/Correlator.java [moved from tim/prune/correlate/Correlator.java with 100% similarity]
src/tim/prune/correlate/MediaPreviewTableModel.java [moved from tim/prune/correlate/MediaPreviewTableModel.java with 100% similarity]
src/tim/prune/correlate/MediaPreviewTableRow.java [moved from tim/prune/correlate/MediaPreviewTableRow.java with 100% similarity]
src/tim/prune/correlate/MediaSelectionTableModel.java [moved from tim/prune/correlate/MediaSelectionTableModel.java with 100% similarity]
src/tim/prune/correlate/MediaSelectionTableRow.java [moved from tim/prune/correlate/MediaSelectionTableRow.java with 100% similarity]
src/tim/prune/correlate/OptionsChangedListener.java [moved from tim/prune/correlate/OptionsChangedListener.java with 100% similarity]
src/tim/prune/correlate/PhotoCorrelator.java [moved from tim/prune/correlate/PhotoCorrelator.java with 100% similarity]
src/tim/prune/correlate/PointMediaPair.java [moved from tim/prune/correlate/PointMediaPair.java with 100% similarity]
src/tim/prune/correlate/TimeIndexPair.java [moved from tim/prune/correlate/TimeIndexPair.java with 100% similarity]
src/tim/prune/data/Altitude.java [moved from tim/prune/data/Altitude.java with 100% similarity]
src/tim/prune/data/AltitudeRange.java [moved from tim/prune/data/AltitudeRange.java with 100% similarity]
src/tim/prune/data/AudioClip.java [moved from tim/prune/data/AudioClip.java with 100% similarity]
src/tim/prune/data/AudioList.java [moved from tim/prune/data/AudioList.java with 100% similarity]
src/tim/prune/data/Checker.java [moved from tim/prune/data/Checker.java with 100% similarity]
src/tim/prune/data/Coordinate.java [moved from tim/prune/data/Coordinate.java with 100% similarity]
src/tim/prune/data/DataPoint.java [moved from tim/prune/data/DataPoint.java with 98% similarity]
src/tim/prune/data/Distance.java [moved from tim/prune/data/Distance.java with 100% similarity]
src/tim/prune/data/DoubleRange.java [moved from tim/prune/data/DoubleRange.java with 100% similarity]
src/tim/prune/data/Field.java [moved from tim/prune/data/Field.java with 100% similarity]
src/tim/prune/data/FieldList.java [moved from tim/prune/data/FieldList.java with 100% similarity]
src/tim/prune/data/FileInfo.java [moved from tim/prune/data/FileInfo.java with 91% similarity]
src/tim/prune/data/GradientCalculator.java [moved from tim/prune/data/GradientCalculator.java with 100% similarity]
src/tim/prune/data/IntegerRange.java [moved from tim/prune/data/IntegerRange.java with 100% similarity]
src/tim/prune/data/LatLonRectangle.java [moved from tim/prune/data/LatLonRectangle.java with 100% similarity]
src/tim/prune/data/Latitude.java [moved from tim/prune/data/Latitude.java with 100% similarity]
src/tim/prune/data/Longitude.java [moved from tim/prune/data/Longitude.java with 100% similarity]
src/tim/prune/data/MediaList.java [moved from tim/prune/data/MediaList.java with 100% similarity]
src/tim/prune/data/MediaObject.java [moved from tim/prune/data/MediaObject.java with 100% similarity]
src/tim/prune/data/MidpointData.java [moved from tim/prune/data/MidpointData.java with 100% similarity]
src/tim/prune/data/NumberUtils.java [moved from tim/prune/data/NumberUtils.java with 100% similarity]
src/tim/prune/data/Photo.java [moved from tim/prune/data/Photo.java with 100% similarity]
src/tim/prune/data/PhotoList.java [moved from tim/prune/data/PhotoList.java with 100% similarity]
src/tim/prune/data/PointCreateOptions.java [moved from tim/prune/data/PointCreateOptions.java with 100% similarity]
src/tim/prune/data/PointScaler.java [moved from tim/prune/data/PointScaler.java with 100% similarity]
src/tim/prune/data/RangeStats.java [moved from tim/prune/data/RangeStats.java with 100% similarity]
src/tim/prune/data/RecentFile.java [moved from tim/prune/data/RecentFile.java with 100% similarity]
src/tim/prune/data/RecentFileList.java [moved from tim/prune/data/RecentFileList.java with 100% similarity]
src/tim/prune/data/Selection.java [moved from tim/prune/data/Selection.java with 100% similarity]
src/tim/prune/data/SourceInfo.java [moved from tim/prune/data/SourceInfo.java with 100% similarity]
src/tim/prune/data/Speed.java [moved from tim/prune/data/Speed.java with 100% similarity]
src/tim/prune/data/SpeedCalculator.java [moved from tim/prune/data/SpeedCalculator.java with 100% similarity]
src/tim/prune/data/SpeedValue.java [moved from tim/prune/data/SpeedValue.java with 100% similarity]
src/tim/prune/data/TimeDifference.java [moved from tim/prune/data/TimeDifference.java with 100% similarity]
src/tim/prune/data/Timestamp.java [moved from tim/prune/data/Timestamp.java with 100% similarity]
src/tim/prune/data/TimestampLocal.java [moved from tim/prune/data/TimestampLocal.java with 100% similarity]
src/tim/prune/data/TimestampUtc.java [moved from tim/prune/data/TimestampUtc.java with 100% similarity]
src/tim/prune/data/Track.java [moved from tim/prune/data/Track.java with 98% similarity]
src/tim/prune/data/TrackExtents.java [moved from tim/prune/data/TrackExtents.java with 100% similarity]
src/tim/prune/data/TrackInfo.java [moved from tim/prune/data/TrackInfo.java with 100% similarity]
src/tim/prune/data/Unit.java [moved from tim/prune/data/Unit.java with 100% similarity]
src/tim/prune/data/UnitSet.java [moved from tim/prune/data/UnitSet.java with 100% similarity]
src/tim/prune/data/UnitSetLibrary.java [moved from tim/prune/data/UnitSetLibrary.java with 100% similarity]
src/tim/prune/data/sort/PhotoComparer.java [moved from tim/prune/data/sort/PhotoComparer.java with 100% similarity]
src/tim/prune/data/sort/SortMode.java [moved from tim/prune/data/sort/SortMode.java with 100% similarity]
src/tim/prune/data/sort/WaypointComparer.java [moved from tim/prune/data/sort/WaypointComparer.java with 100% similarity]
src/tim/prune/function/AboutScreen.java [moved from tim/prune/function/AboutScreen.java with 100% similarity]
src/tim/prune/function/AddAltitudeOffset.java [moved from tim/prune/function/AddAltitudeOffset.java with 100% similarity]
src/tim/prune/function/AddTimeOffset.java [moved from tim/prune/function/AddTimeOffset.java with 100% similarity]
src/tim/prune/function/AsyncMediaLoader.java [moved from tim/prune/function/AsyncMediaLoader.java with 100% similarity]
src/tim/prune/function/Cancellable.java [moved from tim/prune/function/Cancellable.java with 100% similarity]
src/tim/prune/function/CheckVersionScreen.java [moved from tim/prune/function/CheckVersionScreen.java with 100% similarity]
src/tim/prune/function/ChooseSingleParameter.java [moved from tim/prune/function/ChooseSingleParameter.java with 100% similarity]
src/tim/prune/function/ConnectToPointFunction.java [moved from tim/prune/function/ConnectToPointFunction.java with 100% similarity]
src/tim/prune/function/ConvertNamesToTimes.java [moved from tim/prune/function/ConvertNamesToTimes.java with 100% similarity]
src/tim/prune/function/CreateMarkerWaypointsFunction.java [moved from tim/prune/function/CreateMarkerWaypointsFunction.java with 100% similarity]
src/tim/prune/function/CropToSelection.java [moved from tim/prune/function/CropToSelection.java with 100% similarity]
src/tim/prune/function/DeleteBitOfTrackFunction.java [moved from tim/prune/function/DeleteBitOfTrackFunction.java with 100% similarity]
src/tim/prune/function/DeleteFieldValues.java [moved from tim/prune/function/DeleteFieldValues.java with 100% similarity]
src/tim/prune/function/DeleteSelectedRangeFunction.java [moved from tim/prune/function/DeleteSelectedRangeFunction.java with 100% similarity]
src/tim/prune/function/DisconnectAudioFunction.java [moved from tim/prune/function/DisconnectAudioFunction.java with 100% similarity]
src/tim/prune/function/DisconnectPhotoFunction.java [moved from tim/prune/function/DisconnectPhotoFunction.java with 100% similarity]
src/tim/prune/function/DiskCacheConfig.java [moved from tim/prune/function/DiskCacheConfig.java with 100% similarity]
src/tim/prune/function/DistanceTimeLimitFunction.java [moved from tim/prune/function/DistanceTimeLimitFunction.java with 100% similarity]
src/tim/prune/function/DownloadOsmFunction.java [moved from tim/prune/function/DownloadOsmFunction.java with 100% similarity]
src/tim/prune/function/DuplicatePoint.java [moved from tim/prune/function/DuplicatePoint.java with 100% similarity]
src/tim/prune/function/Export3dFunction.java [moved from tim/prune/function/Export3dFunction.java with 100% similarity]
src/tim/prune/function/FieldListModel.java [moved from tim/prune/function/FieldListModel.java with 100% similarity]
src/tim/prune/function/FindWaypoint.java [moved from tim/prune/function/FindWaypoint.java with 100% similarity]
src/tim/prune/function/FullRangeDetails.java [moved from tim/prune/function/FullRangeDetails.java with 100% similarity]
src/tim/prune/function/GetWikipediaFunction.java [moved from tim/prune/function/GetWikipediaFunction.java with 100% similarity]
src/tim/prune/function/GetWikipediaXmlHandler.java [moved from tim/prune/function/GetWikipediaXmlHandler.java with 100% similarity]
src/tim/prune/function/HelpScreen.java [moved from tim/prune/function/HelpScreen.java with 100% similarity]
src/tim/prune/function/IgnoreExifThumb.java [moved from tim/prune/function/IgnoreExifThumb.java with 100% similarity]
src/tim/prune/function/InterpolateFunction.java [moved from tim/prune/function/InterpolateFunction.java with 100% similarity]
src/tim/prune/function/OpenCachingDeXmlHandler.java [moved from tim/prune/function/OpenCachingDeXmlHandler.java with 100% similarity]
src/tim/prune/function/PasteCoordinates.java [moved from tim/prune/function/PasteCoordinates.java with 100% similarity]
src/tim/prune/function/PhotoPopupFunction.java [moved from tim/prune/function/PhotoPopupFunction.java with 100% similarity]
src/tim/prune/function/PlayAudioFunction.java [moved from tim/prune/function/PlayAudioFunction.java with 100% similarity]
src/tim/prune/function/RearrangeFunction.java [moved from tim/prune/function/RearrangeFunction.java with 100% similarity]
src/tim/prune/function/RearrangePhotosFunction.java [moved from tim/prune/function/RearrangePhotosFunction.java with 100% similarity]
src/tim/prune/function/RearrangeWaypointsFunction.java [moved from tim/prune/function/RearrangeWaypointsFunction.java with 100% similarity]
src/tim/prune/function/RemoveAltitudes.java [new file with mode: 0644]
src/tim/prune/function/RemoveAudioFunction.java [moved from tim/prune/function/RemoveAudioFunction.java with 100% similarity]
src/tim/prune/function/RemovePhotoFunction.java [moved from tim/prune/function/RemovePhotoFunction.java with 100% similarity]
src/tim/prune/function/RotatePhoto.java [moved from tim/prune/function/RotatePhoto.java with 100% similarity]
src/tim/prune/function/SearchOpenCachingDeFunction.java [moved from tim/prune/function/SearchOpenCachingDeFunction.java with 100% similarity]
src/tim/prune/function/SearchOsmPoisFunction.java [moved from tim/prune/function/SearchOsmPoisFunction.java with 100% similarity]
src/tim/prune/function/SearchOsmPoisXmlHandler.java [moved from tim/prune/function/SearchOsmPoisXmlHandler.java with 100% similarity]
src/tim/prune/function/SearchWikipediaNames.java [moved from tim/prune/function/SearchWikipediaNames.java with 100% similarity]
src/tim/prune/function/SelectSegmentFunction.java [moved from tim/prune/function/SelectSegmentFunction.java with 100% similarity]
src/tim/prune/function/SelectTimezoneFunction.java [moved from tim/prune/function/SelectTimezoneFunction.java with 100% similarity]
src/tim/prune/function/SelectTracksFunction.java [moved from tim/prune/function/SelectTracksFunction.java with 100% similarity]
src/tim/prune/function/ShowKeysScreen.java [moved from tim/prune/function/ShowKeysScreen.java with 100% similarity]
src/tim/prune/function/ShowThreeDFunction.java [moved from tim/prune/function/ShowThreeDFunction.java with 100% similarity]
src/tim/prune/function/SingleNumericParameterFunction.java [moved from tim/prune/function/SingleNumericParameterFunction.java with 100% similarity]
src/tim/prune/function/StopAudioFunction.java [moved from tim/prune/function/StopAudioFunction.java with 100% similarity]
src/tim/prune/function/autoplay/AutoplayFunction.java [moved from tim/prune/function/autoplay/AutoplayFunction.java with 100% similarity]
src/tim/prune/function/autoplay/PointInfo.java [moved from tim/prune/function/autoplay/PointInfo.java with 100% similarity]
src/tim/prune/function/autoplay/PointList.java [moved from tim/prune/function/autoplay/PointList.java with 100% similarity]
src/tim/prune/function/browser/BrowserLauncher.java [moved from tim/prune/function/browser/BrowserLauncher.java with 100% similarity]
src/tim/prune/function/browser/UrlGenerator.java [moved from tim/prune/function/browser/UrlGenerator.java with 100% similarity]
src/tim/prune/function/browser/WebMapFunction.java [moved from tim/prune/function/browser/WebMapFunction.java with 100% similarity]
src/tim/prune/function/cache/ManageCacheFunction.java [moved from tim/prune/function/cache/ManageCacheFunction.java with 100% similarity]
src/tim/prune/function/cache/RowInfo.java [moved from tim/prune/function/cache/RowInfo.java with 100% similarity]
src/tim/prune/function/cache/TileCacheModel.java [moved from tim/prune/function/cache/TileCacheModel.java with 100% similarity]
src/tim/prune/function/cache/TileFilter.java [moved from tim/prune/function/cache/TileFilter.java with 100% similarity]
src/tim/prune/function/cache/TileSet.java [moved from tim/prune/function/cache/TileSet.java with 100% similarity]
src/tim/prune/function/cache/TileSetTableModel.java [moved from tim/prune/function/cache/TileSetTableModel.java with 100% similarity]
src/tim/prune/function/charts/ChartSeries.java [moved from tim/prune/function/charts/ChartSeries.java with 100% similarity]
src/tim/prune/function/charts/Charter.java [moved from tim/prune/function/charts/Charter.java with 100% similarity]
src/tim/prune/function/compress/ClosePointsAlgorithm.java [moved from tim/prune/function/compress/ClosePointsAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/CompressTrackFunction.java [moved from tim/prune/function/compress/CompressTrackFunction.java with 100% similarity]
src/tim/prune/function/compress/CompressionAlgorithm.java [moved from tim/prune/function/compress/CompressionAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/DeleteMarkedPointsFunction.java [moved from tim/prune/function/compress/DeleteMarkedPointsFunction.java with 100% similarity]
src/tim/prune/function/compress/DouglasPeuckerAlgorithm.java [moved from tim/prune/function/compress/DouglasPeuckerAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/DuplicatePointAlgorithm.java [moved from tim/prune/function/compress/DuplicatePointAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/MarkAndDeleteFunction.java [moved from tim/prune/function/compress/MarkAndDeleteFunction.java with 100% similarity]
src/tim/prune/function/compress/MarkLiftsFunction.java [moved from tim/prune/function/compress/MarkLiftsFunction.java with 100% similarity]
src/tim/prune/function/compress/MarkPointsInRectangleFunction.java [moved from tim/prune/function/compress/MarkPointsInRectangleFunction.java with 100% similarity]
src/tim/prune/function/compress/SingleParameterAlgorithm.java [moved from tim/prune/function/compress/SingleParameterAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/SingletonAlgorithm.java [moved from tim/prune/function/compress/SingletonAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/SummaryLabel.java [moved from tim/prune/function/compress/SummaryLabel.java with 100% similarity]
src/tim/prune/function/compress/TrackDetails.java [moved from tim/prune/function/compress/TrackDetails.java with 100% similarity]
src/tim/prune/function/compress/WackyPointAlgorithm.java [moved from tim/prune/function/compress/WackyPointAlgorithm.java with 100% similarity]
src/tim/prune/function/compress/XYpoint.java [moved from tim/prune/function/compress/XYpoint.java with 100% similarity]
src/tim/prune/function/deletebydate/DateInfo.java [moved from tim/prune/function/deletebydate/DateInfo.java with 100% similarity]
src/tim/prune/function/deletebydate/DateInfoList.java [moved from tim/prune/function/deletebydate/DateInfoList.java with 100% similarity]
src/tim/prune/function/deletebydate/DeleteByDateFunction.java [moved from tim/prune/function/deletebydate/DeleteByDateFunction.java with 100% similarity]
src/tim/prune/function/deletebydate/DeletionTableModel.java [moved from tim/prune/function/deletebydate/DeletionTableModel.java with 100% similarity]
src/tim/prune/function/distance/DistanceFunction.java [moved from tim/prune/function/distance/DistanceFunction.java with 100% similarity]
src/tim/prune/function/distance/DistanceTableModel.java [moved from tim/prune/function/distance/DistanceTableModel.java with 100% similarity]
src/tim/prune/function/distance/FromTableModel.java [moved from tim/prune/function/distance/FromTableModel.java with 100% similarity]
src/tim/prune/function/distance/GenericTableModel.java [moved from tim/prune/function/distance/GenericTableModel.java with 100% similarity]
src/tim/prune/function/edit/EditFieldsTableModel.java [moved from tim/prune/function/edit/EditFieldsTableModel.java with 100% similarity]
src/tim/prune/function/edit/FieldEdit.java [moved from tim/prune/function/edit/FieldEdit.java with 100% similarity]
src/tim/prune/function/edit/FieldEditList.java [moved from tim/prune/function/edit/FieldEditList.java with 100% similarity]
src/tim/prune/function/edit/PointEditor.java [moved from tim/prune/function/edit/PointEditor.java with 96% similarity]
src/tim/prune/function/edit/PointNameEditor.java [moved from tim/prune/function/edit/PointNameEditor.java with 92% similarity]
src/tim/prune/function/estimate/EstimateTime.java [moved from tim/prune/function/estimate/EstimateTime.java with 100% similarity]
src/tim/prune/function/estimate/EstimationParameters.java [moved from tim/prune/function/estimate/EstimationParameters.java with 100% similarity]
src/tim/prune/function/estimate/LearnParameters.java [moved from tim/prune/function/estimate/LearnParameters.java with 100% similarity]
src/tim/prune/function/estimate/ParametersPanel.java [moved from tim/prune/function/estimate/ParametersPanel.java with 100% similarity]
src/tim/prune/function/estimate/jama/Maths.java [moved from tim/prune/function/estimate/jama/Maths.java with 100% similarity]
src/tim/prune/function/estimate/jama/Matrix.java [moved from tim/prune/function/estimate/jama/Matrix.java with 100% similarity]
src/tim/prune/function/estimate/jama/QRDecomposition.java [moved from tim/prune/function/estimate/jama/QRDecomposition.java with 100% similarity]
src/tim/prune/function/gpsies/FormPoster.java [moved from tim/prune/function/gpsies/FormPoster.java with 100% similarity]
src/tim/prune/function/gpsies/GetGpsiesFunction.java [moved from tim/prune/function/gpsies/GetGpsiesFunction.java with 100% similarity]
src/tim/prune/function/gpsies/GpsiesXmlHandler.java [moved from tim/prune/function/gpsies/GpsiesXmlHandler.java with 100% similarity]
src/tim/prune/function/gpsies/TrackListModel.java [moved from tim/prune/function/gpsies/TrackListModel.java with 100% similarity]
src/tim/prune/function/gpsies/UploadGpsiesFunction.java [moved from tim/prune/function/gpsies/UploadGpsiesFunction.java with 100% similarity]
src/tim/prune/function/search/GenericDownloaderFunction.java [moved from tim/prune/function/search/GenericDownloaderFunction.java with 100% similarity]
src/tim/prune/function/search/SearchMapillaryFunction.java [moved from tim/prune/function/search/SearchMapillaryFunction.java with 100% similarity]
src/tim/prune/function/search/SearchResult.java [moved from tim/prune/function/search/SearchResult.java with 100% similarity]
src/tim/prune/function/search/wikimedia_galleries.txt [moved from tim/prune/function/search/wikimedia_galleries.txt with 100% similarity]
src/tim/prune/function/settings/AddMapSourceDialog.java [moved from tim/prune/function/settings/AddMapSourceDialog.java with 100% similarity]
src/tim/prune/function/settings/MapSourceListModel.java [moved from tim/prune/function/settings/MapSourceListModel.java with 100% similarity]
src/tim/prune/function/settings/SaveConfig.java [moved from tim/prune/function/settings/SaveConfig.java with 100% similarity]
src/tim/prune/function/settings/SetAltitudeTolerance.java [moved from tim/prune/function/settings/SetAltitudeTolerance.java with 100% similarity]
src/tim/prune/function/settings/SetColours.java [moved from tim/prune/function/settings/SetColours.java with 100% similarity]
src/tim/prune/function/settings/SetDisplaySettings.java [moved from tim/prune/function/settings/SetDisplaySettings.java with 100% similarity]
src/tim/prune/function/settings/SetEarthdataAuthentication.java [new file with mode: 0644]
src/tim/prune/function/settings/SetLanguage.java [moved from tim/prune/function/settings/SetLanguage.java with 100% similarity]
src/tim/prune/function/settings/SetMapBgFunction.java [moved from tim/prune/function/settings/SetMapBgFunction.java with 100% similarity]
src/tim/prune/function/settings/SetPathsFunction.java [moved from tim/prune/function/settings/SetPathsFunction.java with 100% similarity]
src/tim/prune/function/sew/CandidateSorter.java [moved from tim/prune/function/sew/CandidateSorter.java with 100% similarity]
src/tim/prune/function/sew/SegmentEnd.java [moved from tim/prune/function/sew/SegmentEnd.java with 100% similarity]
src/tim/prune/function/sew/SewTrackSegmentsFunction.java [moved from tim/prune/function/sew/SewTrackSegmentsFunction.java with 100% similarity]
src/tim/prune/function/sew/SplitPoint.java [moved from tim/prune/function/sew/SplitPoint.java with 100% similarity]
src/tim/prune/function/sew/SplitSegmentsFunction.java [moved from tim/prune/function/sew/SplitSegmentsFunction.java with 100% similarity]
src/tim/prune/function/srtm/DownloadSrtmFunction.java [moved from tim/prune/function/srtm/DownloadSrtmFunction.java with 53% similarity]
src/tim/prune/function/srtm/LookupSrtmFunction.java [moved from tim/prune/function/srtm/LookupSrtmFunction.java with 58% similarity]
src/tim/prune/function/srtm/Srtm3Source.java [new file with mode: 0644]
src/tim/prune/function/srtm/SrtmDiskCache.java [new file with mode: 0644]
src/tim/prune/function/srtm/SrtmGl1Source.java [new file with mode: 0644]
src/tim/prune/function/srtm/SrtmSource.java [new file with mode: 0644]
src/tim/prune/function/srtm/SrtmSourceException.java [new file with mode: 0644]
src/tim/prune/function/srtm/SrtmTile.java [moved from tim/prune/function/srtm/SrtmTile.java with 85% similarity]
src/tim/prune/function/srtm/srtmtiles.dat [moved from tim/prune/function/srtm/srtmtiles.dat with 100% similarity]
src/tim/prune/function/weather/GetWeatherForecastFunction.java [moved from tim/prune/function/weather/GetWeatherForecastFunction.java with 100% similarity]
src/tim/prune/function/weather/IconRenderer.java [moved from tim/prune/function/weather/IconRenderer.java with 100% similarity]
src/tim/prune/function/weather/OWMCurrentHandler.java [moved from tim/prune/function/weather/OWMCurrentHandler.java with 100% similarity]
src/tim/prune/function/weather/OWMForecastHandler.java [moved from tim/prune/function/weather/OWMForecastHandler.java with 100% similarity]
src/tim/prune/function/weather/ResultSet.java [moved from tim/prune/function/weather/ResultSet.java with 100% similarity]
src/tim/prune/function/weather/SingleForecast.java [moved from tim/prune/function/weather/SingleForecast.java with 100% similarity]
src/tim/prune/function/weather/WeatherResults.java [moved from tim/prune/function/weather/WeatherResults.java with 100% similarity]
src/tim/prune/function/weather/WeatherTableModel.java [moved from tim/prune/function/weather/WeatherTableModel.java with 100% similarity]
src/tim/prune/gui/AudioListener.java [moved from tim/prune/gui/AudioListener.java with 100% similarity]
src/tim/prune/gui/BaseImageDefinitionPanel.java [moved from tim/prune/gui/BaseImageDefinitionPanel.java with 100% similarity]
src/tim/prune/gui/CombinedListAndModel.java [moved from tim/prune/gui/CombinedListAndModel.java with 100% similarity]
src/tim/prune/gui/DecimalNumberField.java [moved from tim/prune/gui/DecimalNumberField.java with 100% similarity]
src/tim/prune/gui/DetailsDisplay.java [moved from tim/prune/gui/DetailsDisplay.java with 100% similarity]
src/tim/prune/gui/DialogCloser.java [moved from tim/prune/gui/DialogCloser.java with 100% similarity]
src/tim/prune/gui/DisplayUtils.java [moved from tim/prune/gui/DisplayUtils.java with 96% similarity]
src/tim/prune/gui/FunctionLauncher.java [moved from tim/prune/gui/FunctionLauncher.java with 100% similarity]
src/tim/prune/gui/GenericDisplay.java [moved from tim/prune/gui/GenericDisplay.java with 100% similarity]
src/tim/prune/gui/GenericProgressDialog.java [moved from tim/prune/gui/GenericProgressDialog.java with 100% similarity]
src/tim/prune/gui/GuiGridLayout.java [moved from tim/prune/gui/GuiGridLayout.java with 100% similarity]
src/tim/prune/gui/IconManager.java [moved from tim/prune/gui/IconManager.java with 100% similarity]
src/tim/prune/gui/ImageUtils.java [moved from tim/prune/gui/ImageUtils.java with 100% similarity]
src/tim/prune/gui/MediaListModel.java [moved from tim/prune/gui/MediaListModel.java with 100% similarity]
src/tim/prune/gui/MenuManager.java [moved from tim/prune/gui/MenuManager.java with 97% similarity]
src/tim/prune/gui/MultiStateCheckBox.java [moved from tim/prune/gui/MultiStateCheckBox.java with 100% similarity]
src/tim/prune/gui/PhotoThumbnail.java [moved from tim/prune/gui/PhotoThumbnail.java with 100% similarity]
src/tim/prune/gui/ProgressDialog.java [moved from tim/prune/gui/ProgressDialog.java with 100% similarity]
src/tim/prune/gui/RecentFileTrigger.java [moved from tim/prune/gui/RecentFileTrigger.java with 100% similarity]
src/tim/prune/gui/SelectorDisplay.java [moved from tim/prune/gui/SelectorDisplay.java with 98% similarity]
src/tim/prune/gui/SidebarController.java [moved from tim/prune/gui/SidebarController.java with 100% similarity]
src/tim/prune/gui/StatusBar.java [moved from tim/prune/gui/StatusBar.java with 100% similarity]
src/tim/prune/gui/StatusIcon.java [moved from tim/prune/gui/StatusIcon.java with 100% similarity]
src/tim/prune/gui/TerrainDefinitionPanel.java [moved from tim/prune/gui/TerrainDefinitionPanel.java with 100% similarity]
src/tim/prune/gui/UndoManager.java [moved from tim/prune/gui/UndoManager.java with 100% similarity]
src/tim/prune/gui/Viewport.java [moved from tim/prune/gui/Viewport.java with 92% similarity]
src/tim/prune/gui/WaypointListModel.java [moved from tim/prune/gui/WaypointListModel.java with 100% similarity]
src/tim/prune/gui/WaypointNameMatcher.java [moved from tim/prune/gui/WaypointNameMatcher.java with 100% similarity]
src/tim/prune/gui/WholeNumberField.java [moved from tim/prune/gui/WholeNumberField.java with 100% similarity]
src/tim/prune/gui/WizardLayout.java [moved from tim/prune/gui/WizardLayout.java with 100% similarity]
src/tim/prune/gui/colour/AltitudeColourer.java [moved from tim/prune/gui/colour/AltitudeColourer.java with 100% similarity]
src/tim/prune/gui/colour/ColourChooser.java [moved from tim/prune/gui/colour/ColourChooser.java with 100% similarity]
src/tim/prune/gui/colour/ColourPatch.java [moved from tim/prune/gui/colour/ColourPatch.java with 100% similarity]
src/tim/prune/gui/colour/ColourerCaretaker.java [moved from tim/prune/gui/colour/ColourerCaretaker.java with 100% similarity]
src/tim/prune/gui/colour/ColourerFactory.java [moved from tim/prune/gui/colour/ColourerFactory.java with 100% similarity]
src/tim/prune/gui/colour/ColourerSelectorPanel.java [moved from tim/prune/gui/colour/ColourerSelectorPanel.java with 100% similarity]
src/tim/prune/gui/colour/ContinuousPointColourer.java [moved from tim/prune/gui/colour/ContinuousPointColourer.java with 100% similarity]
src/tim/prune/gui/colour/DateColourer.java [moved from tim/prune/gui/colour/DateColourer.java with 100% similarity]
src/tim/prune/gui/colour/DiscretePointColourer.java [moved from tim/prune/gui/colour/DiscretePointColourer.java with 100% similarity]
src/tim/prune/gui/colour/FileColourer.java [moved from tim/prune/gui/colour/FileColourer.java with 100% similarity]
src/tim/prune/gui/colour/GradientColourer.java [moved from tim/prune/gui/colour/GradientColourer.java with 100% similarity]
src/tim/prune/gui/colour/PatchListener.java [moved from tim/prune/gui/colour/PatchListener.java with 100% similarity]
src/tim/prune/gui/colour/PointColourer.java [moved from tim/prune/gui/colour/PointColourer.java with 100% similarity]
src/tim/prune/gui/colour/ProfileDataColourer.java [moved from tim/prune/gui/colour/ProfileDataColourer.java with 100% similarity]
src/tim/prune/gui/colour/SegmentColourer.java [moved from tim/prune/gui/colour/SegmentColourer.java with 100% similarity]
src/tim/prune/gui/colour/SpeedColourer.java [moved from tim/prune/gui/colour/SpeedColourer.java with 100% similarity]
src/tim/prune/gui/colour/VertSpeedColourer.java [moved from tim/prune/gui/colour/VertSpeedColourer.java with 100% similarity]
src/tim/prune/gui/images/add_photo_icon.png [moved from tim/prune/gui/images/add_photo_icon.png with 100% similarity]
src/tim/prune/gui/images/add_textfile_icon.png [moved from tim/prune/gui/images/add_textfile_icon.png with 100% similarity]
src/tim/prune/gui/images/autopan.gif [moved from tim/prune/gui/images/autopan.gif with 100% similarity]
src/tim/prune/gui/images/autopan_on.gif [moved from tim/prune/gui/images/autopan_on.gif with 100% similarity]
src/tim/prune/gui/images/cut_and_move.gif [moved from tim/prune/gui/images/cut_and_move.gif with 100% similarity]
src/tim/prune/gui/images/delete_point_icon.gif [moved from tim/prune/gui/images/delete_point_icon.gif with 100% similarity]
src/tim/prune/gui/images/delete_range_icon.gif [moved from tim/prune/gui/images/delete_range_icon.gif with 100% similarity]
src/tim/prune/gui/images/drag_points_icon.gif [moved from tim/prune/gui/images/drag_points_icon.gif with 100% similarity]
src/tim/prune/gui/images/drag_points_icon_on.gif [moved from tim/prune/gui/images/drag_points_icon_on.gif with 100% similarity]
src/tim/prune/gui/images/edit_point_icon.gif [moved from tim/prune/gui/images/edit_point_icon.gif with 100% similarity]
src/tim/prune/gui/images/entry_invalid.gif [moved from tim/prune/gui/images/entry_invalid.gif with 100% similarity]
src/tim/prune/gui/images/entry_none.gif [moved from tim/prune/gui/images/entry_none.gif with 100% similarity]
src/tim/prune/gui/images/entry_valid.gif [moved from tim/prune/gui/images/entry_valid.gif with 100% similarity]
src/tim/prune/gui/images/link.gif [moved from tim/prune/gui/images/link.gif with 100% similarity]
src/tim/prune/gui/images/map_icon.gif [moved from tim/prune/gui/images/map_icon.gif with 100% similarity]
src/tim/prune/gui/images/map_icon_on.gif [moved from tim/prune/gui/images/map_icon_on.gif with 100% similarity]
src/tim/prune/gui/images/pause.png [moved from tim/prune/gui/images/pause.png with 100% similarity]
src/tim/prune/gui/images/play.png [moved from tim/prune/gui/images/play.png with 100% similarity]
src/tim/prune/gui/images/play_audio.gif [moved from tim/prune/gui/images/play_audio.gif with 100% similarity]
src/tim/prune/gui/images/points_arrows.png [moved from tim/prune/gui/images/points_arrows.png with 100% similarity]
src/tim/prune/gui/images/points_connected.png [moved from tim/prune/gui/images/points_connected.png with 100% similarity]
src/tim/prune/gui/images/points_disconnected.png [moved from tim/prune/gui/images/points_disconnected.png with 100% similarity]
src/tim/prune/gui/images/points_hidden.png [moved from tim/prune/gui/images/points_hidden.png with 100% similarity]
src/tim/prune/gui/images/rewind.png [moved from tim/prune/gui/images/rewind.png with 100% similarity]
src/tim/prune/gui/images/rotate_left_icon.png [moved from tim/prune/gui/images/rotate_left_icon.png with 100% similarity]
src/tim/prune/gui/images/rotate_right_icon.png [moved from tim/prune/gui/images/rotate_right_icon.png with 100% similarity]
src/tim/prune/gui/images/save_icon.gif [moved from tim/prune/gui/images/save_icon.gif with 100% similarity]
src/tim/prune/gui/images/scalebar.gif [moved from tim/prune/gui/images/scalebar.gif with 100% similarity]
src/tim/prune/gui/images/scalebar_on.gif [moved from tim/prune/gui/images/scalebar_on.gif with 100% similarity]
src/tim/prune/gui/images/set_end_icon.png [moved from tim/prune/gui/images/set_end_icon.png with 100% similarity]
src/tim/prune/gui/images/set_start_icon.png [moved from tim/prune/gui/images/set_start_icon.png with 100% similarity]
src/tim/prune/gui/images/show_details_icon.gif [moved from tim/prune/gui/images/show_details_icon.gif with 100% similarity]
src/tim/prune/gui/images/stop_audio.gif [moved from tim/prune/gui/images/stop_audio.gif with 100% similarity]
src/tim/prune/gui/images/undo_icon.gif [moved from tim/prune/gui/images/undo_icon.gif with 100% similarity]
src/tim/prune/gui/images/weather-clear-day.png [moved from tim/prune/gui/images/weather-clear-day.png with 100% similarity]
src/tim/prune/gui/images/weather-clear-night.png [moved from tim/prune/gui/images/weather-clear-night.png with 100% similarity]
src/tim/prune/gui/images/weather-clouds-day.png [moved from tim/prune/gui/images/weather-clouds-day.png with 100% similarity]
src/tim/prune/gui/images/weather-clouds-night.png [moved from tim/prune/gui/images/weather-clouds-night.png with 100% similarity]
src/tim/prune/gui/images/weather-clouds.png [moved from tim/prune/gui/images/weather-clouds.png with 100% similarity]
src/tim/prune/gui/images/weather-extreme.png [moved from tim/prune/gui/images/weather-extreme.png with 100% similarity]
src/tim/prune/gui/images/weather-fog.png [moved from tim/prune/gui/images/weather-fog.png with 100% similarity]
src/tim/prune/gui/images/weather-hail.png [moved from tim/prune/gui/images/weather-hail.png with 100% similarity]
src/tim/prune/gui/images/weather-lightrain.png [moved from tim/prune/gui/images/weather-lightrain.png with 100% similarity]
src/tim/prune/gui/images/weather-rain.png [moved from tim/prune/gui/images/weather-rain.png with 100% similarity]
src/tim/prune/gui/images/weather-snow.png [moved from tim/prune/gui/images/weather-snow.png with 100% similarity]
src/tim/prune/gui/images/weather-storm.png [moved from tim/prune/gui/images/weather-storm.png with 100% similarity]
src/tim/prune/gui/images/window_icon_128.png [moved from tim/prune/gui/images/window_icon_128.png with 100% similarity]
src/tim/prune/gui/images/window_icon_16.png [moved from tim/prune/gui/images/window_icon_16.png with 100% similarity]
src/tim/prune/gui/images/window_icon_20.png [moved from tim/prune/gui/images/window_icon_20.png with 100% similarity]
src/tim/prune/gui/images/window_icon_22.png [moved from tim/prune/gui/images/window_icon_22.png with 100% similarity]
src/tim/prune/gui/images/window_icon_24.png [moved from tim/prune/gui/images/window_icon_24.png with 100% similarity]
src/tim/prune/gui/images/window_icon_32.png [moved from tim/prune/gui/images/window_icon_32.png with 100% similarity]
src/tim/prune/gui/images/window_icon_36.png [moved from tim/prune/gui/images/window_icon_36.png with 100% similarity]
src/tim/prune/gui/images/window_icon_48.png [moved from tim/prune/gui/images/window_icon_48.png with 100% similarity]
src/tim/prune/gui/images/window_icon_64.png [moved from tim/prune/gui/images/window_icon_64.png with 100% similarity]
src/tim/prune/gui/images/window_icon_72.png [moved from tim/prune/gui/images/window_icon_72.png with 100% similarity]
src/tim/prune/gui/images/window_icon_96.png [moved from tim/prune/gui/images/window_icon_96.png with 100% similarity]
src/tim/prune/gui/images/wpicon_default_m.png [moved from tim/prune/gui/images/wpicon_default_m.png with 100% similarity]
src/tim/prune/gui/images/wpicon_pin_l.png [moved from tim/prune/gui/images/wpicon_pin_l.png with 100% similarity]
src/tim/prune/gui/images/wpicon_pin_m.png [moved from tim/prune/gui/images/wpicon_pin_m.png with 100% similarity]
src/tim/prune/gui/images/wpicon_pin_s.png [moved from tim/prune/gui/images/wpicon_pin_s.png with 100% similarity]
src/tim/prune/gui/images/wpicon_plectrum_l.png [moved from tim/prune/gui/images/wpicon_plectrum_l.png with 100% similarity]
src/tim/prune/gui/images/wpicon_plectrum_m.png [moved from tim/prune/gui/images/wpicon_plectrum_m.png with 100% similarity]
src/tim/prune/gui/images/wpicon_plectrum_s.png [moved from tim/prune/gui/images/wpicon_plectrum_s.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ring_l.png [moved from tim/prune/gui/images/wpicon_ring_l.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ring_m.png [moved from tim/prune/gui/images/wpicon_ring_m.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ring_s.png [moved from tim/prune/gui/images/wpicon_ring_s.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ringpt_l.png [moved from tim/prune/gui/images/wpicon_ringpt_l.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ringpt_m.png [moved from tim/prune/gui/images/wpicon_ringpt_m.png with 100% similarity]
src/tim/prune/gui/images/wpicon_ringpt_s.png [moved from tim/prune/gui/images/wpicon_ringpt_s.png with 100% similarity]
src/tim/prune/gui/images/zoom_in.gif [moved from tim/prune/gui/images/zoom_in.gif with 100% similarity]
src/tim/prune/gui/images/zoom_out.gif [moved from tim/prune/gui/images/zoom_out.gif with 100% similarity]
src/tim/prune/gui/map/DiskTileCacher.java [moved from tim/prune/gui/map/DiskTileCacher.java with 100% similarity]
src/tim/prune/gui/map/MapCanvas.java [moved from tim/prune/gui/map/MapCanvas.java with 91% similarity]
src/tim/prune/gui/map/MapPosition.java [moved from tim/prune/gui/map/MapPosition.java with 98% similarity]
src/tim/prune/gui/map/MapSource.java [moved from tim/prune/gui/map/MapSource.java with 98% similarity]
src/tim/prune/gui/map/MapSourceLibrary.java [moved from tim/prune/gui/map/MapSourceLibrary.java with 100% similarity]
src/tim/prune/gui/map/MapTile.java [moved from tim/prune/gui/map/MapTile.java with 100% similarity]
src/tim/prune/gui/map/MapTileManager.java [moved from tim/prune/gui/map/MapTileManager.java with 98% similarity]
src/tim/prune/gui/map/MapUtils.java [moved from tim/prune/gui/map/MapUtils.java with 100% similarity]
src/tim/prune/gui/map/MemTileCacher.java [moved from tim/prune/gui/map/MemTileCacher.java with 100% similarity]
src/tim/prune/gui/map/MffMapSource.java [moved from tim/prune/gui/map/MffMapSource.java with 100% similarity]
src/tim/prune/gui/map/OsmMapSource.java [moved from tim/prune/gui/map/OsmMapSource.java with 81% similarity]
src/tim/prune/gui/map/OverlayPanel.java [moved from tim/prune/gui/map/OverlayPanel.java with 100% similarity]
src/tim/prune/gui/map/ScaleBar.java [moved from tim/prune/gui/map/ScaleBar.java with 100% similarity]
src/tim/prune/gui/map/TileConsumer.java [moved from tim/prune/gui/map/TileConsumer.java with 100% similarity]
src/tim/prune/gui/map/TileDownloader.java [moved from tim/prune/gui/map/TileDownloader.java with 100% similarity]
src/tim/prune/gui/map/WpIconDefinition.java [moved from tim/prune/gui/map/WpIconDefinition.java with 100% similarity]
src/tim/prune/gui/map/WpIconLibrary.java [moved from tim/prune/gui/map/WpIconLibrary.java with 100% similarity]
src/tim/prune/gui/profile/AltitudeData.java [moved from tim/prune/gui/profile/AltitudeData.java with 100% similarity]
src/tim/prune/gui/profile/ArbitraryData.java [moved from tim/prune/gui/profile/ArbitraryData.java with 100% similarity]
src/tim/prune/gui/profile/GradientData.java [moved from tim/prune/gui/profile/GradientData.java with 100% similarity]
src/tim/prune/gui/profile/ProfileChart.java [moved from tim/prune/gui/profile/ProfileChart.java with 100% similarity]
src/tim/prune/gui/profile/ProfileData.java [moved from tim/prune/gui/profile/ProfileData.java with 100% similarity]
src/tim/prune/gui/profile/SpeedData.java [moved from tim/prune/gui/profile/SpeedData.java with 100% similarity]
src/tim/prune/gui/profile/VerticalSpeedData.java [moved from tim/prune/gui/profile/VerticalSpeedData.java with 100% similarity]
src/tim/prune/jpeg/InternalExifLibrary.java [moved from tim/prune/jpeg/InternalExifLibrary.java with 100% similarity]
src/tim/prune/jpeg/JpegData.java [moved from tim/prune/jpeg/JpegData.java with 100% similarity]
src/tim/prune/jpeg/drew/ByteArrayReader.java [moved from tim/prune/jpeg/drew/ByteArrayReader.java with 100% similarity]
src/tim/prune/jpeg/drew/ExifException.java [moved from tim/prune/jpeg/drew/ExifException.java with 100% similarity]
src/tim/prune/jpeg/drew/ExifReader.java [moved from tim/prune/jpeg/drew/ExifReader.java with 100% similarity]
src/tim/prune/jpeg/drew/ExifTiffHandler.java [moved from tim/prune/jpeg/drew/ExifTiffHandler.java with 100% similarity]
src/tim/prune/jpeg/drew/Rational.java [moved from tim/prune/jpeg/drew/Rational.java with 100% similarity]
src/tim/prune/jpeg/drew/TiffDataFormat.java [moved from tim/prune/jpeg/drew/TiffDataFormat.java with 100% similarity]
src/tim/prune/jpeg/drew/TiffProcessor.java [moved from tim/prune/jpeg/drew/TiffProcessor.java with 100% similarity]
src/tim/prune/lang/prune-texts_af.properties [moved from tim/prune/lang/prune-texts_af.properties with 100% similarity]
src/tim/prune/lang/prune-texts_cz.properties [moved from tim/prune/lang/prune-texts_cz.properties with 100% similarity]
src/tim/prune/lang/prune-texts_da.properties [moved from tim/prune/lang/prune-texts_da.properties with 100% similarity]
src/tim/prune/lang/prune-texts_de.properties [moved from tim/prune/lang/prune-texts_de.properties with 100% similarity]
src/tim/prune/lang/prune-texts_de_CH.properties [moved from tim/prune/lang/prune-texts_de_CH.properties with 100% similarity]
src/tim/prune/lang/prune-texts_en.properties [moved from tim/prune/lang/prune-texts_en.properties with 97% similarity]
src/tim/prune/lang/prune-texts_en_US.properties [moved from tim/prune/lang/prune-texts_en_US.properties with 100% similarity]
src/tim/prune/lang/prune-texts_es.properties [moved from tim/prune/lang/prune-texts_es.properties with 100% similarity]
src/tim/prune/lang/prune-texts_fa.properties [moved from tim/prune/lang/prune-texts_fa.properties with 100% similarity]
src/tim/prune/lang/prune-texts_fi.properties [moved from tim/prune/lang/prune-texts_fi.properties with 100% similarity]
src/tim/prune/lang/prune-texts_fr.properties [moved from tim/prune/lang/prune-texts_fr.properties with 100% similarity]
src/tim/prune/lang/prune-texts_hu.properties [moved from tim/prune/lang/prune-texts_hu.properties with 100% similarity]
src/tim/prune/lang/prune-texts_in.properties [moved from tim/prune/lang/prune-texts_in.properties with 100% similarity]
src/tim/prune/lang/prune-texts_it.properties [moved from tim/prune/lang/prune-texts_it.properties with 100% similarity]
src/tim/prune/lang/prune-texts_ja.properties [moved from tim/prune/lang/prune-texts_ja.properties with 100% similarity]
src/tim/prune/lang/prune-texts_ko.properties [moved from tim/prune/lang/prune-texts_ko.properties with 100% similarity]
src/tim/prune/lang/prune-texts_nl.properties [moved from tim/prune/lang/prune-texts_nl.properties with 100% similarity]
src/tim/prune/lang/prune-texts_no.properties [moved from tim/prune/lang/prune-texts_no.properties with 100% similarity]
src/tim/prune/lang/prune-texts_pl.properties [moved from tim/prune/lang/prune-texts_pl.properties with 100% similarity]
src/tim/prune/lang/prune-texts_pt.properties [moved from tim/prune/lang/prune-texts_pt.properties with 100% similarity]
src/tim/prune/lang/prune-texts_ro.properties [moved from tim/prune/lang/prune-texts_ro.properties with 100% similarity]
src/tim/prune/lang/prune-texts_ru.properties [moved from tim/prune/lang/prune-texts_ru.properties with 100% similarity]
src/tim/prune/lang/prune-texts_sv.properties [moved from tim/prune/lang/prune-texts_sv.properties with 100% similarity]
src/tim/prune/lang/prune-texts_tr.properties [moved from tim/prune/lang/prune-texts_tr.properties with 100% similarity]
src/tim/prune/lang/prune-texts_uk.properties [moved from tim/prune/lang/prune-texts_uk.properties with 100% similarity]
src/tim/prune/lang/prune-texts_zh.properties [moved from tim/prune/lang/prune-texts_zh.properties with 100% similarity]
src/tim/prune/license.txt [moved from tim/prune/license.txt with 100% similarity]
src/tim/prune/load/AudioFileFilter.java [moved from tim/prune/load/AudioFileFilter.java with 100% similarity]
src/tim/prune/load/AudioLoader.java [moved from tim/prune/load/AudioLoader.java with 100% similarity]
src/tim/prune/load/BabelFileFormats.java [moved from tim/prune/load/BabelFileFormats.java with 100% similarity]
src/tim/prune/load/BabelLoadFromFile.java [moved from tim/prune/load/BabelLoadFromFile.java with 100% similarity]
src/tim/prune/load/BabelLoadFromGps.java [moved from tim/prune/load/BabelLoadFromGps.java with 100% similarity]
src/tim/prune/load/BabelLoader.java [moved from tim/prune/load/BabelLoader.java with 100% similarity]
src/tim/prune/load/ByteScooper.java [moved from tim/prune/load/ByteScooper.java with 100% similarity]
src/tim/prune/load/ComponentHider.java [moved from tim/prune/load/ComponentHider.java with 100% similarity]
src/tim/prune/load/DelimiterInfo.java [moved from tim/prune/load/DelimiterInfo.java with 100% similarity]
src/tim/prune/load/FieldGuesser.java [moved from tim/prune/load/FieldGuesser.java with 100% similarity]
src/tim/prune/load/FieldSelectionTableModel.java [moved from tim/prune/load/FieldSelectionTableModel.java with 100% similarity]
src/tim/prune/load/FileCacher.java [moved from tim/prune/load/FileCacher.java with 100% similarity]
src/tim/prune/load/FileExtractTableModel.java [moved from tim/prune/load/FileExtractTableModel.java with 100% similarity]
src/tim/prune/load/FileLoader.java [moved from tim/prune/load/FileLoader.java with 100% similarity]
src/tim/prune/load/FileSplitter.java [moved from tim/prune/load/FileSplitter.java with 100% similarity]
src/tim/prune/load/GenericFileFilter.java [moved from tim/prune/load/GenericFileFilter.java with 100% similarity]
src/tim/prune/load/JpegFileFilter.java [moved from tim/prune/load/JpegFileFilter.java with 100% similarity]
src/tim/prune/load/JpegLoader.java [moved from tim/prune/load/JpegLoader.java with 100% similarity]
src/tim/prune/load/MediaHelper.java [moved from tim/prune/load/MediaHelper.java with 100% similarity]
src/tim/prune/load/MediaLinkInfo.java [moved from tim/prune/load/MediaLinkInfo.java with 100% similarity]
src/tim/prune/load/MediaLoadProgressDialog.java [moved from tim/prune/load/MediaLoadProgressDialog.java with 100% similarity]
src/tim/prune/load/MediaSorter.java [moved from tim/prune/load/MediaSorter.java with 100% similarity]
src/tim/prune/load/NmeaFileLoader.java [moved from tim/prune/load/NmeaFileLoader.java with 100% similarity]
src/tim/prune/load/NmeaMessage.java [moved from tim/prune/load/NmeaMessage.java with 100% similarity]
src/tim/prune/load/OneCharDocument.java [moved from tim/prune/load/OneCharDocument.java with 100% similarity]
src/tim/prune/load/TextFileLoader.java [moved from tim/prune/load/TextFileLoader.java with 100% similarity]
src/tim/prune/load/TrackNameList.java [moved from tim/prune/load/TrackNameList.java with 100% similarity]
src/tim/prune/load/babel/AddFilterDialog.java [moved from tim/prune/load/babel/AddFilterDialog.java with 100% similarity]
src/tim/prune/load/babel/BabelFilterPanel.java [moved from tim/prune/load/babel/BabelFilterPanel.java with 100% similarity]
src/tim/prune/load/babel/DiscardFilter.java [moved from tim/prune/load/babel/DiscardFilter.java with 100% similarity]
src/tim/prune/load/babel/DistanceFilter.java [moved from tim/prune/load/babel/DistanceFilter.java with 100% similarity]
src/tim/prune/load/babel/FilterDefinition.java [moved from tim/prune/load/babel/FilterDefinition.java with 100% similarity]
src/tim/prune/load/babel/InterpolateFilter.java [moved from tim/prune/load/babel/InterpolateFilter.java with 100% similarity]
src/tim/prune/load/babel/SimplifyFilter.java [moved from tim/prune/load/babel/SimplifyFilter.java with 100% similarity]
src/tim/prune/load/xml/GpxHandler.java [moved from tim/prune/load/xml/GpxHandler.java with 100% similarity]
src/tim/prune/load/xml/GpxTag.java [moved from tim/prune/load/xml/GpxTag.java with 100% similarity]
src/tim/prune/load/xml/GzipFileLoader.java [moved from tim/prune/load/xml/GzipFileLoader.java with 100% similarity]
src/tim/prune/load/xml/KmlHandler.java [moved from tim/prune/load/xml/KmlHandler.java with 100% similarity]
src/tim/prune/load/xml/XmlFileLoader.java [moved from tim/prune/load/xml/XmlFileLoader.java with 100% similarity]
src/tim/prune/load/xml/XmlHandler.java [moved from tim/prune/load/xml/XmlHandler.java with 100% similarity]
src/tim/prune/load/xml/ZipFileLoader.java [moved from tim/prune/load/xml/ZipFileLoader.java with 100% similarity]
src/tim/prune/readme.txt [moved from tim/prune/readme.txt with 100% similarity]
src/tim/prune/save/BaseImageConfigDialog.java [moved from tim/prune/save/BaseImageConfigDialog.java with 100% similarity]
src/tim/prune/save/BaseImageConsumer.java [moved from tim/prune/save/BaseImageConsumer.java with 100% similarity]
src/tim/prune/save/ExifSaver.java [moved from tim/prune/save/ExifSaver.java with 100% similarity]
src/tim/prune/save/FieldInfo.java [moved from tim/prune/save/FieldInfo.java with 100% similarity]
src/tim/prune/save/FieldSelectionTableModel.java [moved from tim/prune/save/FieldSelectionTableModel.java with 100% similarity]
src/tim/prune/save/FileSaver.java [moved from tim/prune/save/FileSaver.java with 100% similarity]
src/tim/prune/save/GpsSaver.java [moved from tim/prune/save/GpsSaver.java with 100% similarity]
src/tim/prune/save/GpxExporter.java [moved from tim/prune/save/GpxExporter.java with 100% similarity]
src/tim/prune/save/GroutedImage.java [moved from tim/prune/save/GroutedImage.java with 100% similarity]
src/tim/prune/save/ImageExporter.java [moved from tim/prune/save/ImageExporter.java with 100% similarity]
src/tim/prune/save/ImagePreviewPanel.java [moved from tim/prune/save/ImagePreviewPanel.java with 100% similarity]
src/tim/prune/save/KmlExporter.java [moved from tim/prune/save/KmlExporter.java with 100% similarity]
src/tim/prune/save/MapGrouter.java [moved from tim/prune/save/MapGrouter.java with 100% similarity]
src/tim/prune/save/ModelSegment.java [moved from tim/prune/save/ModelSegment.java with 100% similarity]
src/tim/prune/save/PhotoTableEntry.java [moved from tim/prune/save/PhotoTableEntry.java with 100% similarity]
src/tim/prune/save/PhotoTableModel.java [moved from tim/prune/save/PhotoTableModel.java with 100% similarity]
src/tim/prune/save/PointTypeSelector.java [moved from tim/prune/save/PointTypeSelector.java with 100% similarity]
src/tim/prune/save/PovExporter.java [moved from tim/prune/save/PovExporter.java with 100% similarity]
src/tim/prune/save/SettingsForExport.java [moved from tim/prune/save/SettingsForExport.java with 100% similarity]
src/tim/prune/save/UpDownToggler.java [moved from tim/prune/save/UpDownToggler.java with 100% similarity]
src/tim/prune/save/xml/ByteBuffer.java [moved from tim/prune/save/xml/ByteBuffer.java with 100% similarity]
src/tim/prune/save/xml/GpxCacher.java [moved from tim/prune/save/xml/GpxCacher.java with 100% similarity]
src/tim/prune/save/xml/GpxCacherList.java [moved from tim/prune/save/xml/GpxCacherList.java with 100% similarity]
src/tim/prune/save/xml/GpxSlicer.java [moved from tim/prune/save/xml/GpxSlicer.java with 100% similarity]
src/tim/prune/save/xml/TagReceiver.java [moved from tim/prune/save/xml/TagReceiver.java with 100% similarity]
src/tim/prune/save/xml/XmlUtils.java [moved from tim/prune/save/xml/XmlUtils.java with 100% similarity]
src/tim/prune/threedee/ImageDefinition.java [moved from tim/prune/threedee/ImageDefinition.java with 100% similarity]
src/tim/prune/threedee/Java3DWindow.java [moved from tim/prune/threedee/Java3DWindow.java with 100% similarity]
src/tim/prune/threedee/TerrainCache.java [moved from tim/prune/threedee/TerrainCache.java with 100% similarity]
src/tim/prune/threedee/TerrainDefinition.java [moved from tim/prune/threedee/TerrainDefinition.java with 100% similarity]
src/tim/prune/threedee/TerrainHelper.java [moved from tim/prune/threedee/TerrainHelper.java with 100% similarity]
src/tim/prune/threedee/TerrainPatch.java [moved from tim/prune/threedee/TerrainPatch.java with 100% similarity]
src/tim/prune/threedee/ThreeDException.java [moved from tim/prune/threedee/ThreeDException.java with 100% similarity]
src/tim/prune/threedee/ThreeDModel.java [moved from tim/prune/threedee/ThreeDModel.java with 100% similarity]
src/tim/prune/threedee/ThreeDWindow.java [moved from tim/prune/threedee/ThreeDWindow.java with 100% similarity]
src/tim/prune/threedee/WindowFactory.java [moved from tim/prune/threedee/WindowFactory.java with 100% similarity]
src/tim/prune/tips/TipDefinition.java [moved from tim/prune/tips/TipDefinition.java with 100% similarity]
src/tim/prune/tips/TipManager.java [moved from tim/prune/tips/TipManager.java with 100% similarity]
src/tim/prune/undo/UndoAddAltitudeOffset.java [moved from tim/prune/undo/UndoAddAltitudeOffset.java with 100% similarity]
src/tim/prune/undo/UndoAddTimeOffset.java [moved from tim/prune/undo/UndoAddTimeOffset.java with 100% similarity]
src/tim/prune/undo/UndoAppendPoints.java [moved from tim/prune/undo/UndoAppendPoints.java with 100% similarity]
src/tim/prune/undo/UndoConnectMedia.java [moved from tim/prune/undo/UndoConnectMedia.java with 100% similarity]
src/tim/prune/undo/UndoConvertNamesToTimes.java [moved from tim/prune/undo/UndoConvertNamesToTimes.java with 100% similarity]
src/tim/prune/undo/UndoCorrelateAudios.java [moved from tim/prune/undo/UndoCorrelateAudios.java with 100% similarity]
src/tim/prune/undo/UndoCorrelatePhotos.java [moved from tim/prune/undo/UndoCorrelatePhotos.java with 100% similarity]
src/tim/prune/undo/UndoCreatePoint.java [moved from tim/prune/undo/UndoCreatePoint.java with 100% similarity]
src/tim/prune/undo/UndoCutAndMove.java [moved from tim/prune/undo/UndoCutAndMove.java with 100% similarity]
src/tim/prune/undo/UndoDeleteAudio.java [moved from tim/prune/undo/UndoDeleteAudio.java with 100% similarity]
src/tim/prune/undo/UndoDeleteFieldValues.java [moved from tim/prune/undo/UndoDeleteFieldValues.java with 100% similarity]
src/tim/prune/undo/UndoDeleteMarked.java [moved from tim/prune/undo/UndoDeleteMarked.java with 100% similarity]
src/tim/prune/undo/UndoDeleteOperation.java [moved from tim/prune/undo/UndoDeleteOperation.java with 100% similarity]
src/tim/prune/undo/UndoDeletePhoto.java [moved from tim/prune/undo/UndoDeletePhoto.java with 100% similarity]
src/tim/prune/undo/UndoDeletePoint.java [moved from tim/prune/undo/UndoDeletePoint.java with 100% similarity]
src/tim/prune/undo/UndoDeleteRange.java [moved from tim/prune/undo/UndoDeleteRange.java with 100% similarity]
src/tim/prune/undo/UndoDisconnectMedia.java [moved from tim/prune/undo/UndoDisconnectMedia.java with 100% similarity]
src/tim/prune/undo/UndoEditPoint.java [moved from tim/prune/undo/UndoEditPoint.java with 100% similarity]
src/tim/prune/undo/UndoException.java [moved from tim/prune/undo/UndoException.java with 100% similarity]
src/tim/prune/undo/UndoInsert.java [moved from tim/prune/undo/UndoInsert.java with 100% similarity]
src/tim/prune/undo/UndoInterpolate.java [moved from tim/prune/undo/UndoInterpolate.java with 100% similarity]
src/tim/prune/undo/UndoLoad.java [moved from tim/prune/undo/UndoLoad.java with 100% similarity]
src/tim/prune/undo/UndoLoadAudios.java [moved from tim/prune/undo/UndoLoadAudios.java with 100% similarity]
src/tim/prune/undo/UndoLoadPhotos.java [moved from tim/prune/undo/UndoLoadPhotos.java with 100% similarity]
src/tim/prune/undo/UndoLookupSrtm.java [moved from tim/prune/undo/UndoLookupSrtm.java with 100% similarity]
src/tim/prune/undo/UndoMergeTrackSegments.java [moved from tim/prune/undo/UndoMergeTrackSegments.java with 100% similarity]
src/tim/prune/undo/UndoOperation.java [moved from tim/prune/undo/UndoOperation.java with 100% similarity]
src/tim/prune/undo/UndoRearrangePhotos.java [moved from tim/prune/undo/UndoRearrangePhotos.java with 100% similarity]
src/tim/prune/undo/UndoRearrangeWaypoints.java [moved from tim/prune/undo/UndoRearrangeWaypoints.java with 100% similarity]
src/tim/prune/undo/UndoRemoveAltitudes.java [new file with mode: 0644]
src/tim/prune/undo/UndoReorder.java [moved from tim/prune/undo/UndoReorder.java with 100% similarity]
src/tim/prune/undo/UndoReverseSection.java [moved from tim/prune/undo/UndoReverseSection.java with 100% similarity]
src/tim/prune/undo/UndoRotatePhoto.java [moved from tim/prune/undo/UndoRotatePhoto.java with 100% similarity]
src/tim/prune/undo/UndoSewSegments.java [moved from tim/prune/undo/UndoSewSegments.java with 100% similarity]
src/tim/prune/undo/UndoSplitSegments.java [moved from tim/prune/undo/UndoSplitSegments.java with 100% similarity]
src/tim/prune/undo/UndoStack.java [moved from tim/prune/undo/UndoStack.java with 100% similarity]
tim/prune/function/srtm/TileFinder.java [deleted file]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..8e9e794
--- /dev/null
@@ -0,0 +1,2 @@
+*.class
+*.jar
diff --git a/buildtools/MANIFEST.MF b/buildtools/MANIFEST.MF
new file mode 100644 (file)
index 0000000..23d5ed0
--- /dev/null
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0\r
+Main-Class: tim.prune.GpsPrune\r
+\r
diff --git a/buildtools/build.sh b/buildtools/build.sh
new file mode 100755 (executable)
index 0000000..c7fcf3d
--- /dev/null
@@ -0,0 +1,26 @@
+set -e
+# Build script
+# Version number
+PRUNENAME=gpsprune_19.2
+# remove compile directory
+rm -rf compile
+# remove dist directory
+rm -rf dist
+# create compile directory
+mkdir compile
+echo "building..."
+# compile java
+# TODO: If your java3d libraries are not under /usr/share/java, please edit the following line with the correct path
+javac -d compile -cp /usr/share/java/vecmath.jar:/usr/share/java/j3dutils.jar:/usr/share/java/j3dcore.jar $( find src -name "*.java" -print )
+# add other required resources
+cp -r src/tim/prune/lang compile/tim/prune/
+cp -r src/tim/prune/*.txt compile/tim/prune/
+cp -r src/tim/prune/gui/images compile/tim/prune/gui/
+cp src/tim/prune/function/srtm/srtmtiles.dat compile/tim/prune/function/srtm
+# make dist directory
+mkdir dist
+# build into jar file
+jar cfm dist/${PRUNENAME}.jar buildtools/MANIFEST.MF -C compile .
+# finished!
+echo "build complete"
+
diff --git a/buildtools/build.xml b/buildtools/build.xml
new file mode 100644 (file)
index 0000000..50dd138
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>\r
+\r
+<project name="GpsPrune" default="jar" basedir=".">\r
+       <!-- This file was supplied by Denny from the OpenSuse build service project -->\r
+\r
+       <property file="version.properties" />\r
+       <property name="src" value="src" />\r
+       <property name="build" value="build" />\r
+       <property name="dist" value="dist" />\r
+\r
+       <path id="j3dlibs">\r
+               <fileset dir="/usr/share/java/" includes="*.jar"/>\r
+       </path>\r
+\r
+       <!-- Init -->\r
+\r
+       <target name="init">\r
+               <mkdir dir="${build}" />\r
+               <mkdir dir="${dist}" />\r
+       </target>\r
+\r
+       <!-- Clean -->\r
+\r
+       <target name="clean" description="Clean build directory">\r
+\r
+               <delete dir="${build}" />\r
+               <delete dir="${dist}" />\r
+       </target>\r
+\r
+       <!-- Build -->\r
+\r
+       <target name="build" description="Build from source" depends="clean,init">\r
+               <javac srcdir="${src}" destdir="${build}">\r
+                       <classpath refid="j3dlibs" />\r
+               </javac>\r
+       </target>\r
+\r
+       <!-- Jar -->\r
+\r
+       <target name="jar" description="Create jar file" depends="build">\r
+               <copy todir="${build}/tim/prune/lang">\r
+                       <fileset dir="${src}/tim/prune/lang"/>\r
+               </copy>\r
+               <copy todir="${build}/tim/prune/gui/images">\r
+                       <fileset dir="${src}/tim/prune/gui/images"/>\r
+               </copy>\r
+               <copy todir="${build}/tim/prune/">\r
+                       <fileset dir="${src}/tim/prune">\r
+                               <include name="*.txt"/>\r
+                       </fileset>\r
+               </copy>\r
+               <copy file="${src}/tim/prune/function/srtm/srtmtiles.dat" todir="${build}/tim/prune/function/srtm"/>\r
+               <fileset dir="${build}" casesensitive="yes">\r
+                       <include name="build/*" />\r
+               </fileset>\r
+               <jar destfile="${dist}/${ant.project.name}-${version}.jar" basedir="${build}">\r
+                       <!-- define MANIFEST.MF -->\r
+                       <manifest>\r
+                               <!-- Who is building this jar? -->\r
+                               <attribute name="Built-By" value="${user.name}" />\r
+                               <!-- Information about the program itself -->\r
+                               <attribute name="Implementation-Vendor" value="ActivityWorkshop.net" />\r
+                               <attribute name="Implementation-Title" value="${ant.project.name}" />\r
+                               <attribute name="Implementation-Version" value="${version}" />\r
+                               <!-- details -->\r
+                               <attribute name="Main-Class" value="tim.prune.GpsPrune" />\r
+                               <attribute name="Class-Path" value="${ant.project.name}.jar" />\r
+                       </manifest>\r
+               </jar>\r
+       </target>\r
+</project>\r
diff --git a/buildtools/howtobuild.txt b/buildtools/howtobuild.txt
new file mode 100644 (file)
index 0000000..a8efe96
--- /dev/null
@@ -0,0 +1,85 @@
+How to build GpsPrune
+=====================
+
+As with any Java program, there are several different ways to build the GpsPrune application from source, and which method you choose depends a lot on what other Java technologies you're familiar with.
+
+The most popular methods used to build GpsPrune are probably:
+
+ 1.  Using any Java IDE, and linking the project to your installed Java3d jars
+ 2.  Using a build script
+ 2.  Using ant
+ 3.  Using maven
+ 4.  Using gradle
+
+Note: in order not to pollute the root directory with every configuration file for each and every possible build tool, they have all been collected into the separate "buildtools" subdirectory.  For some of these methods (such as ant and maven), the corresponding configuration files should first be selected and moved up to the parent directory before running the tool from there.
+
+
+1.  Using an IDE
+================
+
+There are many IDEs to choose from, including Eclipse, IntelliJ, Netbeans and many others.  A list can be found at https://en.wikipedia.org/wiki/Java_IDEs#Java
+
+Most of these will have the ability to automatically build, run and debug the GpsPrune application, providing that they are told where the Java3d libraries can be found.  This can be done by editing the project dependencies to additionally include the external jar files.  Where these jar files can be found will vary from system to system, but on most linux systems they are in /usr/share/java/.
+
+
+2.  Using a build script
+========================
+
+Requirements: some kind of linux, unix or osx system; build.sh modified to your own paths
+
+First it is necessary to manually edit the build.sh script to add the paths to where your java3d libraries are installed.  This tells the javac tool where to find them for compilation.  An example is shown in build.sh using the -cp parameter to javac with a colon-separated list of jar files.
+
+To compile the code and build a jar file, run:
+   sh buildtools/build.sh
+
+It should be easily possible to modify the script to run on Windows systems, and any contributions in this direction would be gratefully received.
+
+
+3.  Using ant
+=============
+
+Requirements: ant already installed (eg apt-get install ant); build.xml and version.properties
+Firstly, these two configuration files ("build.xml" and "version.properties") should be moved from the "buildtools" directory to the parent directory.
+Secondly, the paths to the java3d jars should be checked and if necessary corrected in the build.xml file.  This is shown in the section beginning with <path id="j3dlibs">.
+Thirdly, from this directory where the configuration files (and the src directory) are located, run the ant tool:
+    ant
+
+This will firstly compile the java files from "src" into class files under "compile", and then bundle these together (along with the required resources) into a jar file under "dist".
+
+
+4.  Using Maven
+===============
+
+Requirements: Maven already installed (eg apt-get install maven); pom.xml
+Also an internet connection is required whenever a target is run for the first time.
+Note that as well as downloading a variety of plugins, Maven will also download its own versions of the java3d dependencies and store them in its own "repository" to use for the building step.
+
+Before you can use Maven, you need to move the file "pom.xml" from the "buildtools" directory into the parent directory.
+
+Then, to build GpsPrune, execute from this directory:
+   mvn clean install
+
+This doesn't actually install anything, but compiles the code and produces a jar file.  The resulting jar will be placed in the target/ folder.
+
+To rebuild, package and run GpsPrune, execute:
+   mvn clean install exec:java
+
+The resources in pom.xml are changed (so they are not the maven common ones) because of the backward compatibility with the project.
+
+4.1.  Using Maven to setup Eclipse
+==================================
+
+Requirements: Eclipse already installed (eg apt-get install eclipse-jdt); Maven setup as above
+You can import the project in Eclipse either by calling:
+   mvn eclipse:eclipse
+
+and then File > Import > Existing Projects into Workspace or using File > Import > Existing Maven Projects.
+
+
+5.  Using Gradle
+================
+
+TODO
+Requirements: Gradle already installed (eg apt-get install gradle); build.gradle file
+Any contributions to provide a suitable gradle file would be gratefully received.
+
diff --git a/buildtools/pom.xml b/buildtools/pom.xml
new file mode 100644 (file)
index 0000000..82b29ac
--- /dev/null
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+
+       <groupId>tim.prune</groupId>
+       <artifactId>gpsprune</artifactId>
+       <version>19.2</version>
+       <packaging>jar</packaging>
+
+       <name>tim.prune.gpsprune</name>
+       <url>https://github.com/activityworkshop/GpsPrune</url>
+
+       <properties>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.compiler.source>1.8</maven.compiler.source>
+               <maven.compiler.target>1.8</maven.compiler.target>
+               <app.mainClass>tim.prune.GpsPrune</app.mainClass>
+               <java3d.version>1.3.1</java3d.version>
+               <j3dutils.version>1.5.2</j3dutils.version>
+       </properties>
+       <repositories>
+               <repository>
+                       <id>talanlabs-releases-repository</id>
+                       <url>http://nexus.talanlabs.com/content/repositories/releases/</url>
+               </repository>
+       </repositories>
+
+       <dependencies>
+               <dependency>
+                       <groupId>java3d</groupId>
+                       <artifactId>j3d-core</artifactId>
+                       <version>${java3d.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>java3d</groupId>
+                       <artifactId>vecmath</artifactId>
+                       <version>${java3d.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>java3d</groupId>
+                       <artifactId>j3dutils</artifactId>
+                       <version>${j3dutils.version}</version>
+               </dependency>
+       </dependencies>
+
+       <build>
+               <outputDirectory>${project.build.directory}/classes</outputDirectory>
+               <finalName>${project.artifactId}_${project.version}</finalName>
+               <sourceDirectory>${project.basedir}/</sourceDirectory>
+               <resources>
+                       <resource>
+                               <directory>${project.basedir}/src/</directory>
+                               <includes>
+                                       <include>tim/prune/gui/images/*</include>
+                                       <include>tim/prune/lang/*</include>
+                                       <include>tim/prune/function/srtm/srtmtiles.dat</include>
+                                       <include>tim/prune/*.txt</include>
+                               </includes>
+                       </resource>
+               </resources>
+
+               <pluginManagement>
+                       <!-- lock down plugins versions to avoid using Maven defaults -->
+                       <plugins>
+                               <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
+                               <plugin>
+                                       <artifactId>maven-clean-plugin</artifactId>
+                                       <version>3.1.0</version>
+                               </plugin>
+                               <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+                               <plugin>
+                                       <artifactId>maven-resources-plugin</artifactId>
+                                       <version>3.0.2</version>
+                               </plugin>
+                               <plugin>
+                                       <artifactId>maven-compiler-plugin</artifactId>
+                                       <version>3.8.0</version>
+                               </plugin>
+                               <plugin>
+                                       <artifactId>maven-jar-plugin</artifactId>
+                                       <version>3.0.2</version>
+                                       <configuration>
+                                               <archive>
+                                                       <manifest>
+                                                               <mainClass>${app.mainClass}</mainClass>
+                                                       </manifest>
+                                               </archive>
+                                       </configuration>
+
+                               </plugin>
+                               <plugin>
+                                       <artifactId>maven-install-plugin</artifactId>
+                                       <version>2.5.2</version>
+                               </plugin>
+                               <plugin>
+                                       <artifactId>maven-deploy-plugin</artifactId>
+                                       <version>2.8.2</version>
+                               </plugin>
+                               <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
+                               <plugin>
+                                       <artifactId>maven-site-plugin</artifactId>
+                                       <version>3.7.1</version>
+                               </plugin>
+                               <plugin>
+                                       <artifactId>maven-project-info-reports-plugin</artifactId>
+                                       <version>3.0.0</version>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-eclipse-plugin</artifactId>
+                                       <version>2.10</version>
+                                       <configuration>
+                                               <downloadSources>true</downloadSources>
+                                               <downloadJavadocs>true</downloadJavadocs>
+                                       </configuration>
+                               </plugin>
+
+                               <plugin>
+                                       <groupId>org.codehaus.mojo</groupId>
+                                       <artifactId>exec-maven-plugin</artifactId>
+                                       <version>1.6.0</version>
+                                       <configuration>
+                                               <mainClass>${app.mainClass}</mainClass>
+                                       </configuration>
+                               </plugin>
+
+                       </plugins>
+               </pluginManagement>
+       </build>
+
+</project>
diff --git a/buildtools/version.properties b/buildtools/version.properties
new file mode 100644 (file)
index 0000000..af25926
--- /dev/null
@@ -0,0 +1 @@
+version=19.2
similarity index 96%
rename from tim/prune/App.java
rename to src/tim/prune/App.java
index 3a778588ab815a7f30c4b396e4de9d2c266836da..317064d39984acb566cee90940236c52c32fd58f 100644 (file)
@@ -51,6 +51,7 @@ public class App
 {
        // Instance variables
        private JFrame _frame = null;
+       private String _titlePrefix = null;
        private Track _track = null;
        private TrackInfo _trackInfo = null;
        private int _lastSavePosition = 0;
@@ -79,6 +80,7 @@ public class App
        public App(JFrame inFrame)
        {
                _frame = inFrame;
+               _titlePrefix = _frame.getTitle();
                _undoStack = new UndoStack();
                _track = new Track();
                _trackInfo = new TrackInfo(_track);
@@ -454,6 +456,22 @@ public class App
        }
 
 
+       /**
+        * Remove altitudes from selected points
+        */
+       public void removeAltitudes(int selStart, int selEnd)
+       {
+               UndoRemoveAltitudes undo = new UndoRemoveAltitudes(_trackInfo, selStart, selEnd);
+               if (_trackInfo.getTrack().removeAltitudes(selStart, selEnd))
+               {
+                       _undoStack.add(undo);
+                       _trackInfo.getSelection().markInvalid();
+                       UpdateMessageBroker.informSubscribers(DataSubscriber.DATA_EDITED);
+                       UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.removealtitudes"));
+               }
+       }
+
+
        /**
         * Merge the track segments within the current selection
         */
@@ -759,6 +777,10 @@ public class App
                        + " '" + 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
@@ -1001,4 +1023,16 @@ public class App
        public void setCurrentMode(AppMode inMode) {
                _appMode = inMode;
        }
+
+       /** Update main window title **/
+       public void updateTitle() {
+               ArrayList<String> filenames = _trackInfo.getFileInfo().getFilenames();
+               if (filenames.size() > 0) {
+                       _frame.setTitle(_titlePrefix + ": " + String.join(", ", filenames));
+               }
+               else
+               {
+                       _frame.setTitle(_titlePrefix);
+               }
+       }
 }
similarity index 97%
rename from tim/prune/FunctionLibrary.java
rename to src/tim/prune/FunctionLibrary.java
index 0441826164d930de8b79acb7d45fd84a742d33ce..4be286e479d036a8b37cabe8223f495872a2f361 100644 (file)
@@ -28,6 +28,7 @@ import tim.prune.function.PhotoPopupFunction;
 import tim.prune.function.PlayAudioFunction;
 import tim.prune.function.RearrangePhotosFunction;
 import tim.prune.function.RearrangeWaypointsFunction;
+import tim.prune.function.RemoveAltitudes;
 import tim.prune.function.RemoveAudioFunction;
 import tim.prune.function.RemovePhotoFunction;
 import tim.prune.function.RotatePhoto;
@@ -56,12 +57,12 @@ import tim.prune.function.settings.SaveConfig;
 import tim.prune.function.settings.SetAltitudeTolerance;
 import tim.prune.function.settings.SetColours;
 import tim.prune.function.settings.SetDisplaySettings;
+import tim.prune.function.settings.SetEarthdataAuthentication;
 import tim.prune.function.settings.SetLanguage;
 import tim.prune.function.settings.SetMapBgFunction;
 import tim.prune.function.settings.SetPathsFunction;
 import tim.prune.function.sew.SewTrackSegmentsFunction;
 import tim.prune.function.sew.SplitSegmentsFunction;
-import tim.prune.function.srtm.DownloadSrtmFunction;
 import tim.prune.function.srtm.LookupSrtmFunction;
 import tim.prune.function.weather.GetWeatherForecastFunction;
 import tim.prune.load.AudioLoader;
@@ -103,13 +104,13 @@ public abstract class FunctionLibrary
        public static GenericFunction FUNCTION_DELETE_BY_DATE = null;
        public static SingleNumericParameterFunction FUNCTION_INTERPOLATE = null;
        public static GenericFunction FUNCTION_LOOKUP_SRTM = null;
-       public static GenericFunction FUNCTION_DOWNLOAD_SRTM = null;
        public static GenericFunction FUNCTION_NEARBY_WIKIPEDIA = null;
        public static GenericFunction FUNCTION_SEARCH_WIKIPEDIA = null;
        public static GenericFunction FUNCTION_SEARCH_OSMPOIS = null;
        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;
@@ -146,6 +147,7 @@ public abstract class FunctionLibrary
        public static GenericFunction FUNCTION_SET_COLOURS = null;
        public static GenericFunction FUNCTION_SET_LANGUAGE = null;
        public static SingleNumericParameterFunction FUNCTION_SET_ALTITUDE_TOLERANCE = null;
+       public static GenericFunction FUNCTION_SET_EARTHDATA_AUTH = null;
        public static GenericFunction FUNCTION_SET_TIMEZONE = null;
        public static GenericFunction FUNCTION_HELP   = null;
        public static GenericFunction FUNCTION_SHOW_KEYS = null;
@@ -183,13 +185,13 @@ public abstract class FunctionLibrary
                FUNCTION_DELETE_BY_DATE = new DeleteByDateFunction(inApp);
                FUNCTION_INTERPOLATE = new InterpolateFunction(inApp);
                FUNCTION_LOOKUP_SRTM = new LookupSrtmFunction(inApp);
-               FUNCTION_DOWNLOAD_SRTM = new DownloadSrtmFunction(inApp);
                FUNCTION_NEARBY_WIKIPEDIA = new GetWikipediaFunction(inApp);
                FUNCTION_SEARCH_WIKIPEDIA = new SearchWikipediaNames(inApp);
                FUNCTION_SEARCH_OSMPOIS = new SearchOsmPoisFunction(inApp);
                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);
@@ -227,6 +229,7 @@ public abstract class FunctionLibrary
                FUNCTION_SET_LANGUAGE = new SetLanguage(inApp);
                FUNCTION_SET_ALTITUDE_TOLERANCE = new SetAltitudeTolerance(inApp);
                FUNCTION_SET_TIMEZONE = new SelectTimezoneFunction(inApp);
+               FUNCTION_SET_EARTHDATA_AUTH = new SetEarthdataAuthentication(inApp);
                FUNCTION_HELP   = new HelpScreen(inApp);
                FUNCTION_SHOW_KEYS = new ShowKeysScreen(inApp);
                FUNCTION_ABOUT  = new AboutScreen(inApp);
similarity index 98%
rename from tim/prune/config/Config.java
rename to src/tim/prune/config/Config.java
index 84e5fd7dc6b4a248bb1d2bef51f18be225f90425..3939c004ae6a68d92f9f667bb0533b84abadf0c0 100644 (file)
@@ -105,6 +105,8 @@ public abstract class Config
        public static final String KEY_WAYPOINT_ICON_SIZE = "prune.waypointiconsize";
        /** Id of selected timezone */
        public static final String KEY_TIMEZONE_ID = "prune.timezoneid";
+       /** Username/password to the Earthdata server for SRTM 1-arcsecond tiles */
+       public static final String KEY_EARTHDATA_AUTH = "prune.earthdataauth";
 
 
        /** Initialise the default properties */
similarity index 98%
rename from tim/prune/data/DataPoint.java
rename to src/tim/prune/data/DataPoint.java
index 84f4800bcd2c0a0d546da8a83a87868810bf3a54..01e9975786139a1736653d68dd1fd747109b3788 100644 (file)
@@ -354,6 +354,16 @@ public class DataPoint
                }
        }
 
+       /**
+        * Remove altitude from point
+        */
+       public void removeAltitude()
+       {
+               _altitude = Altitude.NONE;
+               _fieldValues[_fieldList.getFieldIndex(Field.ALTITUDE)] = _altitude.getStringValue(null);
+               setModified(false);
+       }
+
        /**
         * Reset the altitude to the previous value (by an undo)
         * @param inClone altitude object cloned from earlier
similarity index 91%
rename from tim/prune/data/FileInfo.java
rename to src/tim/prune/data/FileInfo.java
index 41900cb8736df60d668238306079256bf2dca175..7eaac8f307d1bcde51f68a3bf662cd6879adeab2 100644 (file)
@@ -74,6 +74,19 @@ public class FileInfo
                return "";
        }
 
+       /**
+        * @return The source names
+        */
+       public ArrayList<String> getFilenames()
+       {
+               ArrayList<String> filenames = new ArrayList<String>();
+               for (SourceInfo source : _sources)
+               {
+                       filenames.add(source.getName());
+               }
+               return filenames;
+       }
+
        /**
         * @param inIndex index number, starting from zero
         * @return source info object
similarity index 98%
rename from tim/prune/data/Track.java
rename to src/tim/prune/data/Track.java
index f45854a0e3d47a1fd5fc0ee6924732b3294decc0..ef099d4c171d1651bfd627a3beb71bd271943a15 100644 (file)
@@ -377,6 +377,31 @@ public class Track
        }
 
 
+       /**
+        * Remove altitudes from the specified range
+        * @param inStart start of range
+        * @param inEnd end of range
+        */
+       public boolean removeAltitudes(int inStart, int inEnd)
+       {
+               // sanity check
+               if (inStart < 0 || inEnd < 0 || inStart >= inEnd || inEnd >= _numPoints) {
+                       return false;
+               }
+
+               boolean anyRemoved = false;
+               for (int i=inStart; i<=inEnd; i++)
+               {
+                       DataPoint p = _dataPoints[i];
+                       if (p != null && p.hasAltitude())
+                       {
+                               p.removeAltitude();
+                               anyRemoved = true;
+                       }
+               }
+               return anyRemoved;
+       }
+
        /**
         * Interleave all waypoints by each nearest track point
         * @return true if successful, false if no change
diff --git a/src/tim/prune/function/RemoveAltitudes.java b/src/tim/prune/function/RemoveAltitudes.java
new file mode 100644 (file)
index 0000000..1c8b05c
--- /dev/null
@@ -0,0 +1,60 @@
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.data.Field;
+import tim.prune.data.Unit;
+import tim.prune.data.UnitSetLibrary;
+
+/**
+ * Class to provide the function to add remove the altitude from points in a
+ * track range
+ */
+public class RemoveAltitudes extends GenericFunction
+{
+       /**
+        * Constructor
+        * @param inApp application object for callback
+        */
+       public RemoveAltitudes(App inApp)
+       {
+               super(inApp);
+       }
+
+       /** Get the name key */
+       public String getNameKey() {
+               return "function.removealtitudes";
+       }
+
+       /**
+        * Begin the function
+        */
+       public void begin()
+       {
+               int selStart = _app.getTrackInfo().getSelection().getStart();
+               int selEnd = _app.getTrackInfo().getSelection().getEnd();
+               if (!_app.getTrackInfo().getTrack().hasData(Field.ALTITUDE, selStart, selEnd))
+               {
+                       _app.showErrorMessage(getNameKey(), "dialog.addaltitude.noaltitudes");
+                       return;
+               }
+               _app.removeAltitudes(selStart, selEnd);
+       }
+}
similarity index 96%
rename from tim/prune/function/edit/PointEditor.java
rename to src/tim/prune/function/edit/PointEditor.java
index c66201b8d6f48ebcdf56105daa126077d0b85486..546a65e57e4cec6cf19be1ba0c477d598a7aeb4d 100644 (file)
@@ -307,10 +307,23 @@ public class PointEditor
                        if (_model.getChanged(i))
                        {
                                Field field = fieldList.getField(i);
+                               if (field == field.WAYPT_NAME) {
+                                       if (wasNameAdded(_model.getValue(i))) {
+                                               _app.createPoint(_point.clonePoint());
+                                       }
+                               }
                                editList.addEdit(new FieldEdit(field, _model.getValue(i)));
                                undoList.addEdit(new FieldEdit(field, _point.getFieldValue(field)));
                        }
                }
                _app.completePointEdit(editList, undoList);
        }
+
+       private boolean wasNameAdded(String newName)
+       {
+               String prevName = _point.getWaypointName();
+               boolean prevNull = (prevName == null || prevName.equals(""));
+               boolean newNull = (newName == null || newName.equals(""));
+               return (prevNull && !newNull);
+       }
 }
similarity index 92%
rename from tim/prune/function/edit/PointNameEditor.java
rename to src/tim/prune/function/edit/PointNameEditor.java
index 53e1f834b962fa8a098a9fc9345934dbdac3003f..9e6e343dc1357e3f0b9c753b4fd514cb21f20e1e 100644 (file)
@@ -206,7 +206,11 @@ public class PointNameEditor extends GenericFunction
                // Check whether name has really changed
                if (hasNameChanged())
                {
-                       // Make lists for edit and undo, and add the changed field
+                       // If a new name has been added, changing the point
+                       // from trackpoint to waypoint, duplicate it
+                       _app.createPoint(_point.clonePoint());
+                       
+                       // make lists for edit and undo, and add the changed field
                        FieldEditList editList = new FieldEditList();
                        FieldEditList undoList = new FieldEditList();
                        editList.addEdit(new FieldEdit(Field.WAYPT_NAME, _nameField.getText().trim()));
@@ -231,4 +235,17 @@ public class PointNameEditor extends GenericFunction
                        || (!prevNull && newNull)
                        || (!prevNull && !newNull && !prevName.equals(newName));
        }
+
+       /**
+        * Check whether a new name has been added
+        * @return true if it has indeed
+        */
+       private boolean wasNameAdded()
+       {
+               String prevName = _point.getWaypointName();
+               String newName = _nameField.getText().trim();
+               boolean prevNull = (prevName == null || prevName.equals(""));
+               boolean newNull = (newName == null || newName.equals(""));
+               return (prevNull && !newNull);
+       }
 }
diff --git a/src/tim/prune/function/settings/SetEarthdataAuthentication.java b/src/tim/prune/function/settings/SetEarthdataAuthentication.java
new file mode 100644 (file)
index 0000000..d4a166a
--- /dev/null
@@ -0,0 +1,183 @@
+package tim.prune.function.settings;
+
+import java.awt.Component;
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Base64;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.function.srtm.SrtmGl1Source;
+import tim.prune.function.srtm.SrtmSourceException;
+
+/**
+ * Set authentication data for the NASA Earthdata systems
+ */
+public class SetEarthdataAuthentication extends GenericFunction
+{
+       private JDialog _dialog = null;
+       private JTextField _usernameField = null;
+       private JPasswordField _passwordField = null;
+       private JLabel _authAccepted = null;
+
+       /**
+        * Constructor
+        * @param inApp App object
+        */
+       public SetEarthdataAuthentication(App inApp) {
+               super(inApp);
+       }
+
+       /** @return name key */
+       public String getNameKey() {
+               return "function.setearthdataauthentication";
+       }
+
+       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()
+       {
+               // Blurb to explain to the user
+               JPanel dialogPanel = new JPanel();
+               dialogPanel.setLayout(new BorderLayout());
+               dialogPanel.add(new JLabel("<html>"+I18nManager.getText("dialog.earthdataauth.intro")+"</html>"), BorderLayout.NORTH);
+
+               // username and password fields
+               JPanel mainPanel = new JPanel();
+               mainPanel.setLayout(new BorderLayout());
+               JPanel usernamePasswordPanel = new JPanel();
+               usernamePasswordPanel.setLayout(new GridLayout(2, 2));
+
+               JLabel usernameLabel = new JLabel(I18nManager.getText("dialog.earthdataauth.user"));
+               usernamePasswordPanel.add(usernameLabel);
+               _usernameField = new JTextField("");
+               usernamePasswordPanel.add(_usernameField);
+
+               JLabel passwordLabel = new JLabel(I18nManager.getText("dialog.earthdataauth.password"));
+               usernamePasswordPanel.add(passwordLabel);
+               _passwordField = new JPasswordField("");
+               usernamePasswordPanel.add(_passwordField);
+               mainPanel.add(usernamePasswordPanel, BorderLayout.CENTER);
+
+               JPanel authStatusPanel = new JPanel();
+               authStatusPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+               _authAccepted = new JLabel(" ");
+               authStatusPanel.add(_authAccepted);
+               mainPanel.add(authStatusPanel, BorderLayout.SOUTH);
+
+               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));
+               JButton checkButton = new JButton(I18nManager.getText("button.check"));
+               checkButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               testUsernameAndPassword();
+                       }
+               });
+               buttonPanel.add(checkButton);
+               JButton 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;
+       }
+
+       private String getNewAuthString()
+       {
+               String username = _usernameField.getText();
+               String password = _passwordField.getText();
+               return Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
+       }
+
+       private void finish()
+       {
+               Config.setConfigString(Config.KEY_EARTHDATA_AUTH, getNewAuthString());
+               _dialog.dispose();
+       }
+
+       private void prefillCurrentAuth()
+       {
+               String authString = Config.getConfigString(Config.KEY_EARTHDATA_AUTH);
+               if (authString == null)
+               {
+                       _usernameField.setText("");
+                       _passwordField.setText("");
+               }
+               String decoded = new String(Base64.getDecoder().decode(authString));
+               if (decoded.contains(":"))
+               {
+                       _usernameField.setText(decoded.split(":", 2)[0]);
+                       _passwordField.setText(decoded.split(":", 2)[1]);
+               }
+               else
+               {
+                       _usernameField.setText("");
+                       _passwordField.setText("");
+               }
+
+               _authAccepted.setText(" ");
+       }
+
+       private void testUsernameAndPassword()
+       {
+               String username = _usernameField.getText();
+               String password = _passwordField.getText();
+               SrtmGl1Source srtmGL1 = new SrtmGl1Source();
+               try
+               {
+                       _authAccepted.setText("...");
+                       srtmGL1.testAuth(getNewAuthString());
+                       _authAccepted.setText(I18nManager.getText("dialog.earthdataauth.authaccepted"));
+               }
+               catch (SrtmSourceException e)
+               {
+                       _authAccepted.setText(I18nManager.getText("dialog.earthdataauth.authrejected") + ": " + e.getMessage());
+               }
+       }
+}
similarity index 53%
rename from tim/prune/function/srtm/DownloadSrtmFunction.java
rename to src/tim/prune/function/srtm/DownloadSrtmFunction.java
index 0350ce38ddc7af88508523fa9b2f9f7ef14d41be..311ff9290408adebd9c65ab0c2fe027337114477 100644 (file)
@@ -1,11 +1,5 @@
 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;
@@ -14,7 +8,6 @@ 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;
 
@@ -28,19 +21,20 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
        private ProgressDialog _progress = null;
        /** Flag to check whether this function is currently running or not */
        private boolean _running = false;
-
+       private SrtmSource _srtmSource = null;
 
        /**
         * Constructor
         * @param inApp  App object
         */
-       public DownloadSrtmFunction(App inApp) {
+       public DownloadSrtmFunction(App inApp, SrtmSource inSrtmSource) {
                super(inApp);
+               _srtmSource = inSrtmSource;
        }
 
        /** @return name key */
        public String getNameKey() {
-               return "function.downloadsrtm";
+               return "function.downloadsrtm."+_srtmSource.getName();
        }
 
        /**
@@ -48,6 +42,17 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
         */
        public void begin()
        {
+               if (! SrtmDiskCache.ensureCacheIsUsable())
+               {
+                       _app.showErrorMessage(getNameKey(), "error.downloadsrtm.nocache");
+                       return;
+               }
+               if (! _srtmSource.isReadyToUse())
+               {
+                       _app.showErrorMessage(getNameKey(), getNameKey() + ".needsetup");
+                       return;
+               }
+
                _running = true;
                if (_progress == null) {
                        _progress = new ProgressDialog(_parentFrame, getNameKey());
@@ -61,6 +66,14 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
         * Run method using separate thread
         */
        public void run()
+       {
+               ArrayList<SrtmTile> tileList = buildCoveringTiles();
+               downloadTiles(tileList);
+               // Finished
+               _running = false;
+       }
+
+       private ArrayList<SrtmTile> buildCoveringTiles()
        {
                // Compile list of tiles to get
                ArrayList<SrtmTile> tileList = new ArrayList<SrtmTile>();
@@ -89,18 +102,16 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
                        }
                }
 
-               downloadTiles(tileList);
-               // Finished
-               _running = false;
+               return tileList;
        }
 
-
        /**
         * Download the tiles of SRTM data
         * @param inTileList list of tiles to get
         */
        private void downloadTiles(ArrayList<SrtmTile> inTileList)
        {
+               String errorMessage = "";
                // Update progress bar
                if (_progress != null)
                {
@@ -108,62 +119,29 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
                        _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)
+                       if (_srtmSource.isCached(inTileList.get(t)))
                        {
-                               // Define streams
-                               FileOutputStream outStream = null;
-                               InputStream inStream = null;
-                               try
+                               System.out.println(inTileList.get(t).getTileName()+" already in cache, nothing to do");
+                               continue;
+                       }
+
+                       boolean success;
+                       try
+                       {
+                               success = _srtmSource.downloadTile(inTileList.get(t));
+                               if (success)
                                {
-                                       // 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();
+                                       numDownloaded++;
                                }
-                               // Make sure streams are closed
-                               try {inStream.close();} catch (Exception e) {}
-                               try {outStream.close();} catch (Exception e) {}
+                               // Set progress
+                               _progress.setValue(t + 1);
+                       }
+                       catch (SrtmSourceException e)
+                       {
+                               errorMessage += e.getMessage();
                        }
                }
 
@@ -172,10 +150,11 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
                        return;
                }
 
-               if (errorMessage != null) {
+               if (! errorMessage.equals("")) {
                        _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
+                       return;
                }
-               else if (numDownloaded == 1)
+               if (numDownloaded == 1)
                {
                        JOptionPane.showMessageDialog(_parentFrame, I18nManager.getTextWithNumber("confirm.downloadsrtm.1", numDownloaded),
                                I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
@@ -186,37 +165,7 @@ public class DownloadSrtmFunction extends GenericFunction implements Runnable
                                I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
                }
                else if (inTileList.size() > 0) {
-                       _app.showErrorMessage(getNameKey(), "confirm.downloadsrtm.none");
+                       JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("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() <= 400) {
-                                       return srtmFile;
-                               }
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * @return true if a thread is currently running
-        */
-       public boolean isRunning()
-       {
-               return _running;
-       }
 }
similarity index 58%
rename from tim/prune/function/srtm/LookupSrtmFunction.java
rename to src/tim/prune/function/srtm/LookupSrtmFunction.java
index 15997448e038e6f4bb6e9f4b9437c99491b18a6e..927d2cd7bc013c4a9744e17fbb12797afdc73685 100644 (file)
@@ -1,12 +1,6 @@
 package tim.prune.function.srtm;
 
-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.JOptionPane;
 
@@ -15,14 +9,12 @@ 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;
 
 /**
@@ -38,13 +30,9 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
        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;
        /** Altitude below which is considered void */
        private static final int VOID_VAL = -32768;
 
@@ -84,7 +72,10 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
        private void begin(Track inTrack, boolean inNormalTrack)
        {
                _running = true;
-               _hadToDownload = false;
+               if (! SrtmDiskCache.ensureCacheIsUsable())
+               {
+                       _app.showErrorMessage(getNameKey(), "error.cache.notthere");
+               }
                if (_progress == null) {
                        _progress = new ProgressDialog(_parentFrame, getNameKey());
                }
@@ -131,8 +122,7 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                for (int i = 0; i < _track.getNumPoints(); i++)
                {
                        // Consider points which don't have altitudes or have zero values
-                       if (!_track.getPoint(i).hasAltitude()
-                               || (overwriteZeros && _track.getPoint(i).getAltitude().getValue() == 0))
+                       if (needsAltitude(_track.getPoint(i), overwriteZeros))
                        {
                                SrtmTile tile = new SrtmTile(_track.getPoint(i));
                                boolean alreadyGot = false;
@@ -148,12 +138,23 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                lookupValues(tileList, overwriteZeros);
                // Finished
                _running = false;
-               // Show tip if lots of online lookups were necessary
-               if (_hadToDownload) {
-                       _app.showTip(TipManager.Tip_DownloadSrtm);
-               }
        }
 
+       /**
+        * true if we need to set the altitude of this point
+        */
+       private boolean needsAltitude(DataPoint point, boolean overwriteZeros)
+       {
+               if (!point.hasAltitude())
+               {
+                       return true;
+               }
+               if (overwriteZeros && point.getAltitude().getValue() == 0)
+               {
+                       return true;
+               }
+               return false;
+       }
 
        /**
         * Lookup the values from SRTM data
@@ -170,94 +171,79 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                        _progress.setMaximum(inTileList.size());
                        _progress.setValue(0);
                }
-               String errorMessage = null;
-               // Get urls for each tile
-               URL[] urls = TileFinder.getUrls(inTileList);
+               String errorMessage = "";
                for (int t=0; t<inTileList.size() && !_progress.isCancelled(); t++)
                {
-                       if (urls[t] != null)
+                       SrtmTile tile = inTileList.get(t);
+                       SrtmSource srtmSource = tile.findBestCachedSource();
+
+                       if (srtmSource == null)
                        {
-                               SrtmTile tile = inTileList.get(t);
-                               try
+                               errorMessage += "Tile "+tile.getTileName()+" not in cache!\n";
+                               continue;
+                       }
+
+                       // Set progress
+                       _progress.setValue(t);
+
+                       int[] heights;
+                       try {
+                               heights = srtmSource.getTileHeights(tile);
+                       }
+                       catch (SrtmSourceException e)
+                       {
+                               errorMessage += e.getMessage();
+                               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))
                                {
-                                       // Set progress
-                                       _progress.setValue(t);
-                                       final int ARRLENGTH = 1201 * 1201;
-                                       int[] heights = new int[ARRLENGTH];
-                                       // Open zipinputstream on url and check size
-                                       ZipInputStream inStream = getStreamToHgtFile(urls[t]);
-                                       boolean entryOk = false;
-                                       if (inStream != null)
+                                       if (new SrtmTile(point).equals(tile))
                                        {
-                                               ZipEntry entry = inStream.getNextEntry();
-                                               entryOk = (entry != null && entry.getSize() == HGT_SIZE);
-                                               if (entryOk)
+                                               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
                                                {
-                                                       // Read entire file contents into one byte array
-                                                       for (int i = 0; i < ARRLENGTH; i++)
+                                                       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)
                                                        {
-                                                               heights[i] = inStream.read() * 256 + inStream.read();
-                                                               if (heights[i] >= 32768) {heights[i] -= 65536;}
+                                                       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;
                                                        }
-                                               }
-                                               // else {
-                                               //      System.out.println("length not ok: " + entry.getSize());
-                                               // }
-                                               // Close stream from url
-                                               inStream.close();
-                                       }
-
-                                       if (entryOk)
-                                       {
-                                               // 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))
+                                                       // Special case for terrain tracks, don't interpolate voids yet
+                                                       if (!_normalTrack && numVoids > 0) {
+                                                               altitude = VOID_VAL;
+                                                       }
+                                                       if (altitude != VOID_VAL)
                                                        {
-                                                               if (new SrtmTile(point).equals(tile))
-                                                               {
-                                                                       double x = (point.getLongitude().getDouble() - tile.getLongitude()) * 1200;
-                                                                       double y = 1201 - (point.getLatitude().getDouble() - tile.getLatitude()) * 1200;
-                                                                       int idx1 = ((int)y)*1201 + (int)x;
-                                                                       try
-                                                                       {
-                                                                               int[] fouralts = {heights[idx1], heights[idx1+1], heights[idx1-1201], heights[idx1-1200]};
-                                                                               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) {
-                                                                               // System.err.println("lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1);
-                                                                       }
-                                                               }
+                                                               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";
+                                               }
                                        }
                                }
-                               catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
-                               }
                        }
                }
 
@@ -266,6 +252,10 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                        return;
                }
 
+               if (! errorMessage.equals("")) {
+                       _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
+                       return;
+               }
                if (numAltitudesFound > 0)
                {
                        // Inform app including undo information
@@ -278,9 +268,6 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                                        I18nManager.getTextWithNumber("confirm.lookupsrtm", numAltitudesFound));
                        }
                }
-               else if (errorMessage != null) {
-                       _app.showErrorMessageNoLookup(getNameKey(), errorMessage);
-               }
                else if (inTileList.size() > 0) {
                        _app.showErrorMessage(getNameKey(), "error.lookupsrtm.nonefound");
                }
@@ -289,36 +276,6 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable
                }
        }
 
-       /**
-        * 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());
-       }
-
        /**
         * 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 --git a/src/tim/prune/function/srtm/Srtm3Source.java b/src/tim/prune/function/srtm/Srtm3Source.java
new file mode 100644 (file)
index 0000000..14fad59
--- /dev/null
@@ -0,0 +1,164 @@
+package tim.prune.function.srtm;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.HttpURLConnection;
+
+import tim.prune.GpsPrune;
+import tim.prune.I18nManager;
+
+public class Srtm3Source extends SrtmSource {
+       /** URL prefix for all tiles */
+       private static final String URL_PREFIX = "https://dds.cr.usgs.gov/srtm/version2_1/SRTM3/";
+       /** Directory names for each continent */
+       private static final String[] CONTINENTS = {"", "Eurasia", "North_America", "Australia",
+                                                   "Islands", "South_America", "Africa"};
+       private byte[] _continents_lookup;
+
+
+       public Srtm3Source()
+       {
+               _continents_lookup = populateContinents();
+       }
+
+       public String getNameKey()
+       {
+               return "function.downloadsrtm." + getName();
+       }
+
+       public String getName()
+       {
+               return "SRTM3_v21";
+       }
+
+       protected String getSourceExtension()
+       {
+               return ".hgt.zip";
+       }
+
+       /**
+        * Read the dat file and get the contents
+        * @return byte array containing file contents
+        */
+       private static byte[] populateContinents()
+       {
+               InputStream in = null;
+               try
+               {
+                       // Need absolute path to dat file
+                       in = Srtm3Source.class.getResourceAsStream("/tim/prune/function/srtm/srtmtiles.dat");
+                       if (in != null)
+                       {
+                               byte[] buffer = new byte[in.available()];
+                               in.read(buffer);
+                               in.close();
+                               return buffer;
+                       }
+               }
+               catch (java.io.IOException e) {
+                       System.err.println("Exception trying to read srtmtiles.dat : " + e.getMessage());
+               }
+               finally
+               {
+                       try {
+                               in.close();
+                       }
+                       catch (Exception e) {} // ignore
+               }
+               return null;
+       }
+
+       /**
+        * Get the Url for the given tile
+        * @param inTile Tile to get
+        * @return URL
+        */
+       private URL buildUrl(SrtmTile inTile)
+               throws SrtmSourceException
+       {
+               
+               // Get byte from lookup array
+               int idx = (inTile.getLatitude() + 59)*360 + (inTile.getLongitude() + 180);
+               int dir;
+               try
+               {
+                       dir = _continents_lookup[idx];
+               }
+               catch (ArrayIndexOutOfBoundsException e)
+               {
+                       throw new SrtmSourceException("Could not find continent for tile "+inTile.getTileName());
+               }
+               try
+               {
+                       return new URL(URL_PREFIX + CONTINENTS[dir] + "/" + inTile.getTileName() + getSourceExtension());
+               }
+               catch (MalformedURLException e)
+               {
+                       throw new SrtmSourceException("Could not build URL for tile "+inTile.getTileName());
+               }
+       }
+
+       public boolean isReadyToUse()
+       {
+               return true;
+       }
+
+       public boolean downloadTile(SrtmTile inTile)
+               throws SrtmSourceException
+       {
+               int redirects = 5;
+               URL tileUrl = buildUrl(inTile);
+               File outputFile = getCacheFileName(inTile);
+               System.out.println("Download: Need to download: " + tileUrl);
+
+               try
+               {
+                       HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection();
+
+                       // Define streams
+                       FileOutputStream outStream = null;
+                       InputStream inStream = null;
+
+                       conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
+
+                       int status = conn.getResponseCode();
+                       if (status == 200)
+                       {
+                               inStream = conn.getInputStream();
+                       }
+                       else if (status == 404)
+                       {
+                               throw new SrtmSourceException("Tile not found: "+conn.getURL());
+                       }
+                       else
+                       {
+                               throw new SrtmSourceException("Invalid response from server: " +status+conn.getContent());
+                       }
+
+                       outStream = new FileOutputStream(outputFile);
+
+                       int c;
+                       while ((c = inStream.read()) != -1)
+                       {
+                               outStream.write(c);
+                       }
+                       // Make sure streams are closed
+                       try {inStream.close();} catch (Exception e) {}
+                       try {outStream.close();} catch (Exception e) {}
+                       return true;
+               }
+               catch (IOException e)
+               {
+                       throw new SrtmSourceException("Error while downloading tile "+inTile.getTileName()+": "+e.getMessage());
+               }
+       }
+
+       public int getRowSize(SrtmTile inTile)
+       {
+               return 1201;
+       }
+}
diff --git a/src/tim/prune/function/srtm/SrtmDiskCache.java b/src/tim/prune/function/srtm/SrtmDiskCache.java
new file mode 100644 (file)
index 0000000..80159e0
--- /dev/null
@@ -0,0 +1,49 @@
+package tim.prune.function.srtm;
+
+import java.io.File;
+
+import tim.prune.config.Config;
+import tim.prune.I18nManager;
+
+public class SrtmDiskCache {
+
+       private static boolean _cacheIsUsable = false;
+       private static File _cacheDir = null;
+
+       public static boolean ensureCacheIsUsable()
+       {
+
+               if (_cacheIsUsable)
+               {
+                       return true;
+               }
+               // Check the cache is ok
+               String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
+               if (diskCachePath == null)
+               {
+                       return false;
+               }
+               File srtmDir = new File(diskCachePath, "srtm");
+               if (!srtmDir.exists() && !srtmDir.mkdir()) {
+                       // can't create the srtm directory
+                       return false;
+               }
+               _cacheIsUsable = true;
+               _cacheDir = srtmDir;
+               return true;
+       }
+
+       public static File getCacheDir(String inSourceName)
+       {
+               if (_cacheDir == null)
+               {
+                       ensureCacheIsUsable();
+               }
+               File cacheDir = new File(_cacheDir, inSourceName);
+               if (!cacheDir.exists() && !cacheDir.mkdir()) {
+                       // can't create the srtm directory
+                       return null;
+               }
+               return cacheDir;
+       }
+}
diff --git a/src/tim/prune/function/srtm/SrtmGl1Source.java b/src/tim/prune/function/srtm/SrtmGl1Source.java
new file mode 100644 (file)
index 0000000..51e6d77
--- /dev/null
@@ -0,0 +1,176 @@
+package tim.prune.function.srtm;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.HttpURLConnection;
+
+import tim.prune.App;
+import tim.prune.GpsPrune;
+import tim.prune.config.Config;
+
+/**
+ * Create an account at: https://urs.earthdata.nasa.gov/users/new
+ * Data policy: https://lpdaac.usgs.gov/data/data-citation-and-policies/
+ *
+ */
+
+public class SrtmGl1Source extends SrtmSource {
+       /** URL prefix for all tiles */
+       private static final String URL_PREFIX = "https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11/";
+       /** Auth URL */
+       private static final String AUTH_URL = "urs.earthdata.nasa.gov";
+
+
+       public SrtmGl1Source()
+       {
+               CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
+       }
+
+       public String getName()
+       {
+               return "SRTMGL1_v003";
+       }
+
+       protected String getSourceExtension()
+       {
+               return ".SRTMGL1.hgt.zip";
+       }
+
+       private URL buildUrl(SrtmTile inTile)
+               throws SrtmSourceException
+       {
+               try {
+                       return new URL(URL_PREFIX + inTile.getTileName() + getSourceExtension());
+               }
+               catch (MalformedURLException e)
+               {
+                       throw new SrtmSourceException(e.getMessage());
+               }
+       }
+
+       public boolean isReadyToUse()
+       {
+               return getAuth() != null;
+       }
+
+       private String getAuth()
+       {
+               String authString = Config.getConfigString(Config.KEY_EARTHDATA_AUTH);
+               if (authString != null)
+               {
+                       return "Basic " + authString; 
+               }
+               else
+               {
+                       return null;
+               }
+       }
+
+       public boolean downloadTile(SrtmTile inTile)
+               throws SrtmSourceException
+       {
+               return downloadTile(inTile, getAuth());
+       }
+
+       private boolean downloadTile(SrtmTile inTile, String auth)
+               throws SrtmSourceException
+       {
+               URL tileUrl = buildUrl(inTile);
+               File outputFile = getCacheFileName(inTile);
+               System.out.println("Download: Need to download: " + tileUrl);
+               try
+               {
+                       HttpURLConnection conn = (HttpURLConnection) tileUrl.openConnection();
+                       long fileLength = 0L;
+
+                       // Define streams
+                       FileOutputStream outStream = null;
+                       InputStream inStream = null;
+
+                       // Documentation about HTTP interface at:
+                       // https://wiki.earthdata.nasa.gov/display/EL/How+To+Access+Data+With+Java
+                       int redirects = 0;
+
+                       while (redirects < 10) {
+                               redirects++;
+
+                               conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
+                               conn.setInstanceFollowRedirects(false);
+                               conn.setUseCaches(false);
+                               if (conn.getURL().getHost().equals(AUTH_URL))
+                               {
+                                       conn.setRequestProperty("Authorization", auth);
+                               }
+
+                               int status = conn.getResponseCode();
+                               if (status == 200)
+                               {
+                                       // Found the tile, we're good
+                                       inStream = conn.getInputStream();
+                                       fileLength = conn.getContentLengthLong();
+                                       break;
+                               }
+                               else if (status == 302)
+                               {
+                                       // redirected to SSO server then back to original resource
+                                       String newUrl = conn.getHeaderField("Location");
+                                       conn = (HttpURLConnection) (new URL(newUrl)).openConnection();
+                               }
+                               else if (status == 404)
+                               {
+                                       throw new SrtmSourceException("Tile " + inTile.getTileName() + " not found at " + conn.getURL());
+                               }
+                               else
+                               {
+                                       throw new SrtmSourceException("Invalid response from server: " + status + conn.getResponseMessage());
+                               }
+                       }
+
+                       // _progress.setValue(t * 10 + 1);
+                       outStream = new FileOutputStream(outputFile);
+
+                       // Copy all the bytes to the file
+                       int c;
+                       long written = 0L;
+                       while ((c = inStream.read()) != -1)
+                       {
+                               outStream.write(c);
+                               written++;
+                               // _progress.setValue(t * 10 + 1 + (int) ((10 * written) / fileLength));
+                       }
+                       // Make sure streams are closed
+                       try {inStream.close();} catch (Exception e) {}
+                       try {outStream.close();} catch (Exception e) {}
+                       return true;
+               }
+               catch (IOException e)
+               {
+                       throw new SrtmSourceException("Error while downloading tile " + inTile.getTileName() + ": "+e.getMessage());
+               }
+       }
+
+       public boolean testAuth(String auth)
+               throws SrtmSourceException
+       {
+               // The only thing special about this tile is that it's the smallest tile
+               // It covers small islands in Malaysia
+               SrtmTile testTile = new SrtmTile(7, 117);
+               if (isCached(testTile))
+               {
+                       getCacheFileName(testTile).delete();
+               }
+               return downloadTile(testTile, auth);
+       }
+
+       public int getRowSize(SrtmTile inTile)
+       {
+               return 3601;
+       }
+}
diff --git a/src/tim/prune/function/srtm/SrtmSource.java b/src/tim/prune/function/srtm/SrtmSource.java
new file mode 100644 (file)
index 0000000..5651a3f
--- /dev/null
@@ -0,0 +1,69 @@
+package tim.prune.function.srtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public abstract class SrtmSource {
+       public abstract String getName();
+       public abstract boolean isReadyToUse();
+       public abstract boolean downloadTile(SrtmTile inTile)
+               throws SrtmSourceException;
+       public abstract int getRowSize(SrtmTile inTile);
+       protected abstract String getSourceExtension();
+
+       public int[] getTileHeights(SrtmTile inTile)
+               throws SrtmSourceException
+       {
+               File cacheFileName = getCacheFileName(inTile);
+               if (cacheFileName == null)
+               {
+                       throw new SrtmSourceException("Tile "+inTile.getTileName()+" not in cache");
+               }
+               try
+               {
+                       ZipInputStream inStream = new ZipInputStream(new FileInputStream(cacheFileName));
+                       ZipEntry entry = inStream.getNextEntry();
+                       int rowSize = getRowSize(inTile);
+                       int tileSize = rowSize * rowSize;
+                       if (entry.getSize() != 2 * tileSize)
+                       {
+                               throw new SrtmSourceException("Tile file "+cacheFileName+" does not have the expected size");
+                       }
+                       int[] heights = new int[tileSize];
+                       // Read entire file contents into one byte array
+                       for (int i = 0; i < heights.length; i++)
+                       {
+                               heights[i] = inStream.read() * 256 + inStream.read();
+                               if (heights[i] >= 32768) {heights[i] -= 65536;}
+                       }
+                       // Close stream
+                       inStream.close();
+                       return heights;
+               }
+               catch (IOException e)
+               {
+                       throw new SrtmSourceException("Failure opening "+cacheFileName+" for reading:"+e.getMessage());
+               }
+
+       }
+
+       protected File getCacheDir()
+       {
+               return SrtmDiskCache.getCacheDir(getName());
+       }
+
+       protected File getCacheFileName(SrtmTile inTile)
+       {
+               String fileName = inTile.getTileName() + getSourceExtension();
+               return new File(getCacheDir(), fileName);
+       }
+
+       public boolean isCached(SrtmTile inTile)
+       {
+               return getCacheFileName(inTile).exists();
+       }
+}
diff --git a/src/tim/prune/function/srtm/SrtmSourceException.java b/src/tim/prune/function/srtm/SrtmSourceException.java
new file mode 100644 (file)
index 0000000..37b2db5
--- /dev/null
@@ -0,0 +1,7 @@
+package tim.prune.function.srtm;
+
+public class SrtmSourceException extends Exception {
+       public SrtmSourceException(String message) {
+               super(message);
+       }
+}
similarity index 85%
rename from tim/prune/function/srtm/SrtmTile.java
rename to src/tim/prune/function/srtm/SrtmTile.java
index 301bbaf2ccb7849f1378a6f910999c188965a12a..7bc1d386419732c8d7ab9b048bcf06407d06a36b 100644 (file)
@@ -67,7 +67,20 @@ public class SrtmTile
                        + (_longitude >= 0?"E":"W")
                        + (Math.abs(_longitude) < 100?"0":"")
                        + (Math.abs(_longitude) < 10?"0":"")
-                       + Math.abs(_longitude)
-                       + ".hgt.zip";
+                       + Math.abs(_longitude);
+       }
+
+       public SrtmSource findBestCachedSource()
+       {
+               SrtmSource[] sources = {new SrtmGl1Source(),
+                                       new Srtm3Source() };
+               for (int i = 0; i < sources.length; i++)
+               {
+                       if (sources[i].isCached(this))
+                       {
+                               return sources[i];
+                       }
+               }
+               return null;
        }
 }
similarity index 96%
rename from tim/prune/gui/DisplayUtils.java
rename to src/tim/prune/gui/DisplayUtils.java
index 25640d8e5072bfc2e70acfc3e26c7de208a494e3..2300296760fa1febfeb8f2dc59d393ca35bb639a 100644 (file)
@@ -36,7 +36,8 @@ public abstract class DisplayUtils
                if (inNumSecs < 86400L) return "" + (inNumSecs / 60 / 60) + I18nManager.getText("display.range.time.hours")
                        + " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins");
                if (inNumSecs < 432000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days")
-                       + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours");
+                       + " " + (inNumSecs / 60 / 60) % 24 + I18nManager.getText("display.range.time.hours")
+                       + " " + ((inNumSecs / 60) % 60) + I18nManager.getText("display.range.time.mins");
                if (inNumSecs < 86400000L) return "" + (inNumSecs / 86400L) + I18nManager.getText("display.range.time.days");
                return "big";
        }
similarity index 97%
rename from tim/prune/gui/MenuManager.java
rename to src/tim/prune/gui/MenuManager.java
index bce3b4d67b0a6df980b66882f175245af1134155..bd0d37813d40c8d9259707999a7285bafddec348 100644 (file)
@@ -34,6 +34,9 @@ import tim.prune.function.SearchOpenCachingDeFunction;
 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;
 
 /**
  * Class to manage the menu bar and tool bar,
@@ -77,6 +80,7 @@ public class MenuManager implements DataSubscriber
        private JMenuItem _reverseItem = null;
        private JMenuItem _addTimeOffsetItem = null;
        private JMenuItem _addAltitudeOffsetItem = null;
+       private JMenuItem _removeAltitudesItem = null;
        private JMenuItem _mergeSegmentsItem = null;
        private JMenuItem _rearrangeWaypointsItem = null;
        private JMenuItem _splitSegmentsItem = null;
@@ -93,7 +97,7 @@ public class MenuManager implements DataSubscriber
        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;
@@ -257,8 +261,15 @@ public class MenuManager implements DataSubscriber
                // 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 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);
@@ -425,6 +436,8 @@ public class MenuManager implements DataSubscriber
                rangeMenu.add(_addTimeOffsetItem);
                _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET, false);
                rangeMenu.add(_addAltitudeOffsetItem);
+               _removeAltitudesItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_ALTITUDES, false);
+               rangeMenu.add(_removeAltitudesItem);
                _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.range.mergetracksegments"));
                _mergeSegmentsItem.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
@@ -651,6 +664,8 @@ public class MenuManager implements DataSubscriber
                settingsMenu.add(makeMenuItem(new ChooseSingleParameter(_app, FunctionLibrary.FUNCTION_SET_ALTITUDE_TOLERANCE)));
                // Set timezone
                settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_TIMEZONE));
+               // Set Earthdata authentication
+               settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_EARTHDATA_AUTH));
                settingsMenu.addSeparator();
                // Save configuration
                settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG));
@@ -889,7 +904,7 @@ public class MenuManager implements DataSubscriber
                _getWeatherItem.setEnabled(hasData);
                _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
                // have we got a cache?
-               _downloadSrtmItem.setEnabled(hasData && Config.getConfigString(Config.KEY_DISK_CACHE) != null);
+               _downloadSrtmMenu.setEnabled(hasData && Config.getConfigString(Config.KEY_DISK_CACHE) != null);
                // have we got any timestamps?
                _deleteByDateItem.setEnabled(hasData && _track.hasData(Field.TIMESTAMP));
 
@@ -956,6 +971,7 @@ public class MenuManager implements DataSubscriber
                _reverseItem.setEnabled(hasRange);
                _addTimeOffsetItem.setEnabled(hasRange);
                _addAltitudeOffsetItem.setEnabled(hasRange);
+               _removeAltitudesItem.setEnabled(hasRange);
                _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
                _deleteFieldValuesItem.setEnabled(hasRange);
                _fullRangeDetailsItem.setEnabled(hasRange);
similarity index 98%
rename from tim/prune/gui/SelectorDisplay.java
rename to src/tim/prune/gui/SelectorDisplay.java
index fa6630dc5b71400bd4f7202fb688f9a911cc3f6f..9dfc24f42394ad624d925589a2acd344411c12a0 100644 (file)
@@ -228,8 +228,9 @@ public class SelectorDisplay extends GenericDisplay
                        else if (numFiles > 1)
                        {
                                final String labelText = I18nManager.getText("details.track.numfiles") + ": " + numFiles;
+                               final String filenameString = String.join(", ", _trackInfo.getFileInfo().getFilenames());
                                _filenameLabel.setText(labelText);
-                               _filenameLabel.setToolTipText(labelText);
+                               _filenameLabel.setToolTipText(filenameString);
                        }
                        else
                        {
similarity index 92%
rename from tim/prune/gui/Viewport.java
rename to src/tim/prune/gui/Viewport.java
index 25eba2fb1847306d41aed63021c7cbe3e4ed2cf0..aec78a61f7703e3f3f97807c5347a04a91743708 100644 (file)
@@ -40,4 +40,12 @@ public class Viewport
                double maxLon = MapUtils.getLongitudeFromX(mapPosition.getXFromPixels(width, width));
                return new double[] {minLat, minLon, maxLat, maxLon};
        }
+
+       /**
+        * Recentre the viewport on the data
+        */
+       public void recentreViewport()
+       {
+               _mapCanvas.zoomToFit();
+       }
 }
similarity index 91%
rename from tim/prune/gui/map/MapCanvas.java
rename to src/tim/prune/gui/map/MapCanvas.java
index aa25dbcd939e39b96a6642f188b68665d4c74c4f..ad38d8182700cf49a1d5055f66bbb4ec8b56a20e 100644 (file)
@@ -92,7 +92,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
        WpIconDefinition _waypointIconDefinition = null;
 
        /** Constant for click sensitivity when selecting nearest point */
-       private static final int CLICK_SENSITIVITY = 10;
+       private static final int CLICK_SENSITIVITY = 30;
        /** Constant for pan distance from key presses */
        private static final int PAN_DISTANCE = 20;
        /** Constant for pan distance from autopan */
@@ -259,8 +259,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
 
                // add control panels to this one
                setLayout(new BorderLayout());
-               _topPanel.setVisible(false);
-               _sidePanel.setVisible(false);
+               _topPanel.setVisible(true);
+               _sidePanel.setVisible(true);
                add(_topPanel, BorderLayout.NORTH);
                add(_sidePanel, BorderLayout.WEST);
                add(_scaleBar, BorderLayout.SOUTH);
@@ -337,16 +337,19 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
        /**
         * Zoom to fit the current data area
         */
-       private void zoomToFit()
+       public void zoomToFit()
        {
+               int maxZoom = (_track.getNumPoints() == 0)?2:_tileManager.getMaxZoomLevel();
                _latRange = _track.getLatRange();
                _lonRange = _track.getLonRange();
                _xRange = new DoubleRange(MapUtils.getXFromLongitude(_lonRange.getMinimum()),
                        MapUtils.getXFromLongitude(_lonRange.getMaximum()));
                _yRange = new DoubleRange(MapUtils.getYFromLatitude(_latRange.getMinimum()),
                        MapUtils.getYFromLatitude(_latRange.getMaximum()));
-               _mapPosition.zoomToXY(_xRange.getMinimum(), _xRange.getMaximum(), _yRange.getMinimum(), _yRange.getMaximum(),
-                       getWidth(), getHeight());
+               _mapPosition.zoomToXY(
+                       _xRange.getMinimum(), _xRange.getMaximum(),
+                       _yRange.getMinimum(), _yRange.getMaximum(),
+                       getWidth(), getHeight(), maxZoom);
        }
 
 
@@ -360,70 +363,59 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
                if (_mapImage != null && (_mapImage.getWidth() != getWidth() || _mapImage.getHeight() != getHeight())) {
                        _mapImage = null;
                }
-               if (_track.getNumPoints() > 0)
+               // Check for autopan if enabled / necessary
+               if (_autopanCheckBox.isSelected())
                {
-                       // Check for autopan if enabled / necessary
-                       if (_autopanCheckBox.isSelected())
+                       int selectedPoint = _selection.getCurrentPointIndex();
+                       if (selectedPoint >= 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint)
                        {
-                               int selectedPoint = _selection.getCurrentPointIndex();
-                               if (selectedPoint >= 0 && _dragFromX == -1 && selectedPoint != _prevSelectedPoint)
-                               {
-                                       autopanToPoint(selectedPoint);
-                               }
-                               _prevSelectedPoint = selectedPoint;
+                               autopanToPoint(selectedPoint);
                        }
+                       _prevSelectedPoint = selectedPoint;
+               }
 
-                       // Draw the map contents if necessary
-                       if (_mapImage == null || _recalculate)
-                       {
-                               paintMapContents();
-                               _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getYFromPixels(0, 0));
-                       }
-                       // Draw the prepared image onto the panel
-                       if (_mapImage != null) {
-                               inG.drawImage(_mapImage, 0, 0, getWidth(), getHeight(), null);
-                       }
+               // Draw the map contents if necessary
+               if (_mapImage == null || _recalculate)
+               {
+                       paintMapContents();
+                       _scaleBar.updateScale(_mapPosition.getZoom(), _mapPosition.getYFromPixels(0, 0));
+               }
+               // Draw the prepared image onto the panel
+               if (_mapImage != null) {
+                       inG.drawImage(_mapImage, 0, 0, getWidth(), getHeight(), null);
+               }
 
-                       switch (_drawMode)
-                       {
-                               case MODE_DRAG_POINT:
-                                       drawDragLines(inG, _selection.getCurrentPointIndex()-1, _selection.getCurrentPointIndex()+1);
-                                       break;
+               switch (_drawMode)
+               {
+                       case MODE_DRAG_POINT:
+                               drawDragLines(inG, _selection.getCurrentPointIndex()-1, _selection.getCurrentPointIndex()+1);
+                               break;
 
-                               case MODE_CREATE_MIDPOINT:
-                                       drawDragLines(inG, _clickedPoint-1, _clickedPoint);
-                                       break;
+                       case MODE_CREATE_MIDPOINT:
+                               drawDragLines(inG, _clickedPoint-1, _clickedPoint);
+                               break;
 
-                               case MODE_ZOOM_RECT:
-                               case MODE_MARK_RECTANGLE:
-                                       if (_dragFromX != -1 && _dragFromY != -1)
-                                       {
-                                               // Draw the zoom rectangle if necessary
-                                               inG.setColor(Color.RED);
-                                               inG.drawLine(_dragFromX, _dragFromY, _dragFromX, _dragToY);
-                                               inG.drawLine(_dragFromX, _dragFromY, _dragToX, _dragFromY);
-                                               inG.drawLine(_dragToX, _dragFromY, _dragToX, _dragToY);
-                                               inG.drawLine(_dragFromX, _dragToY, _dragToX, _dragToY);
-                                       }
-                                       break;
-
-                               case MODE_DRAW_POINTS_CONT:
-                                       // draw line to mouse position to show drawing mode
-                                       inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_POINT));
-                                       int prevIndex = _track.getNumPoints()-1;
-                                       int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(prevIndex));
-                                       int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(prevIndex));
-                                       inG.drawLine(px, py, _dragToX, _dragToY);
-                                       break;
-                       }
-               }
-               else
-               {
-                       inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_BACKGROUND));
-                       inG.fillRect(0, 0, getWidth(), getHeight());
-                       inG.setColor(COLOR_MESSAGES);
-                       inG.drawString(I18nManager.getText("display.nodata"), 50, getHeight()/2);
-                       _scaleBar.updateScale(-1, 0);
+                       case MODE_ZOOM_RECT:
+                       case MODE_MARK_RECTANGLE:
+                               if (_dragFromX != -1 && _dragFromY != -1)
+                               {
+                                       // Draw the zoom rectangle if necessary
+                                       inG.setColor(Color.RED);
+                                       inG.drawLine(_dragFromX, _dragFromY, _dragFromX, _dragToY);
+                                       inG.drawLine(_dragFromX, _dragFromY, _dragToX, _dragFromY);
+                                       inG.drawLine(_dragToX, _dragFromY, _dragToX, _dragToY);
+                                       inG.drawLine(_dragFromX, _dragToY, _dragToX, _dragToY);
+                               }
+                               break;
+
+                       case MODE_DRAW_POINTS_CONT:
+                               // draw line to mouse position to show drawing mode
+                               inG.setColor(Config.getColourScheme().getColour(ColourScheme.IDX_POINT));
+                               int prevIndex = _track.getNumPoints()-1;
+                               int px = getWidth() / 2 + _mapPosition.getXFromCentre(_track.getX(prevIndex));
+                               int py = getHeight() / 2 + _mapPosition.getYFromCentre(_track.getY(prevIndex));
+                               inG.drawLine(px, py, _dragToX, _dragToY);
+                               break;
                }
                // Draw slider etc on top
                paintChildren(inG);
@@ -1074,66 +1066,63 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
         */
        public void mouseClicked(MouseEvent inE)
        {
-               if (_track != null && _track.getNumPoints() > 0)
+               // select point if it's a left-click
+               if (!inE.isMetaDown())
                {
-                       // select point if it's a left-click
-                       if (!inE.isMetaDown())
+                       if (inE.getClickCount() == 1)
                        {
-                               if (inE.getClickCount() == 1)
+                               // single click
+                               if (_drawMode == MODE_DEFAULT)
                                {
-                                       // single click
-                                       if (_drawMode == MODE_DEFAULT)
+                                       int pointIndex = _clickedPoint;
+                                       if (pointIndex == INDEX_UNKNOWN)
                                        {
-                                               int pointIndex = _clickedPoint;
-                                               if (pointIndex == INDEX_UNKNOWN)
-                                               {
-                                                       // index hasn't been calculated yet
-                                                       pointIndex = _track.getNearestPointIndex(
-                                                        _mapPosition.getXFromPixels(inE.getX(), getWidth()),
-                                                        _mapPosition.getYFromPixels(inE.getY(), getHeight()),
-                                                        _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
-                                               }
-                                               // Extend selection for shift-click
-                                               if (inE.isShiftDown()) {
-                                                       _trackInfo.extendSelection(pointIndex);
-                                               }
-                                               else {
-                                                       _trackInfo.selectPoint(pointIndex);
-                                               }
+                                               // index hasn't been calculated yet
+                                               pointIndex = _track.getNearestPointIndex(
+                                                       _mapPosition.getXFromPixels(inE.getX(), getWidth()),
+                                                       _mapPosition.getYFromPixels(inE.getY(), getHeight()),
+                                                       _mapPosition.getBoundsFromPixels(CLICK_SENSITIVITY), false);
                                        }
-                                       else if (_drawMode == MODE_DRAW_POINTS_START)
-                                       {
-                                               _app.createPoint(createPointFromClick(inE.getX(), inE.getY()));
-                                               _dragToX = inE.getX();
-                                               _dragToY = inE.getY();
-                                               _drawMode = MODE_DRAW_POINTS_CONT;
+                                       // Extend selection for shift-click
+                                       if (inE.isShiftDown()) {
+                                               _trackInfo.extendSelection(pointIndex);
                                        }
-                                       else if (_drawMode == MODE_DRAW_POINTS_CONT)
-                                       {
-                                               DataPoint point = createPointFromClick(inE.getX(), inE.getY());
-                                               _app.createPoint(point, false); // not a new segment
+                                       else {
+                                               _trackInfo.selectPoint(pointIndex);
                                        }
                                }
-                               else if (inE.getClickCount() == 2)
+                               else if (_drawMode == MODE_DRAW_POINTS_START)
                                {
-                                       // double click
-                                       if (_drawMode == MODE_DEFAULT) {
-                                               panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2);
-                                               zoomIn();
-                                       }
-                                       else if (_drawMode == MODE_DRAW_POINTS_START || _drawMode == MODE_DRAW_POINTS_CONT) {
-                                               _drawMode = MODE_DEFAULT;
-                                       }
+                                       _app.createPoint(createPointFromClick(inE.getX(), inE.getY()));
+                                       _dragToX = inE.getX();
+                                       _dragToY = inE.getY();
+                                       _drawMode = MODE_DRAW_POINTS_CONT;
+                               }
+                               else if (_drawMode == MODE_DRAW_POINTS_CONT)
+                               {
+                                       DataPoint point = createPointFromClick(inE.getX(), inE.getY());
+                                       _app.createPoint(point, false); // not a new segment
                                }
                        }
-                       else
+                       else if (inE.getClickCount() == 2)
                        {
-                               // show the popup menu for right-clicks
-                               _popupMenuX = inE.getX();
-                               _popupMenuY = inE.getY();
-                               _popup.show(this, _popupMenuX, _popupMenuY);
+                               // double click
+                               if (_drawMode == MODE_DEFAULT) {
+                                       panMap(inE.getX() - getWidth()/2, inE.getY() - getHeight()/2);
+                                       zoomIn();
+                               }
+                               else if (_drawMode == MODE_DRAW_POINTS_START || _drawMode == MODE_DRAW_POINTS_CONT) {
+                                       _drawMode = MODE_DEFAULT;
+                               }
                        }
                }
+               else
+               {
+                       // show the popup menu for right-clicks
+                       _popupMenuX = inE.getX();
+                       _popupMenuY = inE.getY();
+                       _popup.show(this, _popupMenuX, _popupMenuY);
+               }
                // Reset app mode
                _app.setCurrentMode(App.AppMode.NORMAL);
                if (_drawMode == MODE_MARK_RECTANGLE) _drawMode = MODE_DEFAULT;
@@ -1408,10 +1397,6 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
                        }
                }
                repaint();
-               // enable or disable components
-               boolean hasData = _track.getNumPoints() > 0;
-               _topPanel.setVisible(hasData);
-               _sidePanel.setVisible(hasData);
                // grab focus for the key presses
                this.requestFocus();
        }
similarity index 98%
rename from tim/prune/gui/map/MapPosition.java
rename to src/tim/prune/gui/map/MapPosition.java
index 25f05fc1a2a238370d8888ea4b807b7d3f5f8adb..71ab6cd4d88ed9eb9823db56ab19dc72d574db53 100644 (file)
@@ -30,14 +30,14 @@ public class MapPosition
         * @param inWidth width of display
         * @param inHeight height of display
         */
-       public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight)
+       public void zoomToXY(double inMinX, double inMaxX, double inMinY, double inMaxY, int inWidth, int inHeight, int maxZoom)
        {
                // System.out.println("Zooming to " + inMinX + ", " + inMaxX + ", " + inMinY + ", " + inMaxY + "; width=" + inWidth + ", height=" + inHeight);
                double diffX = Math.abs(inMaxX - inMinX);
                double diffY = Math.abs(inMaxY - inMinY);
                // Find out what zoom level to go to
                int requiredZoom = -1;
-               for (int currZoom = MAX_ZOOM; currZoom >= 2; currZoom--)
+               for (int currZoom = maxZoom; currZoom >= 2; currZoom--)
                {
                        if (transformToPixels(diffX, currZoom) < inWidth
                                && transformToPixels(diffY, currZoom) < inHeight)
similarity index 98%
rename from tim/prune/gui/map/MapSource.java
rename to src/tim/prune/gui/map/MapSource.java
index c4e294665e128def7d1fcbfb048cb516624d5d00..177ad670b14d89664f6129cf46d85038c3f8cd8e 100644 (file)
@@ -104,7 +104,7 @@ public abstract class MapSource
                        urlstr = "http://" + urlstr;
                }
                // check trailing /
-               if (!urlstr.endsWith("/")) {
+               if (!urlstr.endsWith("/") && !urlstr.contains("?")) {
                        urlstr = urlstr + "/";
                }
                // Validate current url, return null if not ok
similarity index 98%
rename from tim/prune/gui/map/MapTileManager.java
rename to src/tim/prune/gui/map/MapTileManager.java
index f7370c5c90c833e7f053fc786eafdae37ab7f843..d1e0047a2bc2624284308fad0f4ab1ea9df2dc09 100644 (file)
@@ -70,10 +70,19 @@ public class MapTileManager implements ImageObserver
         * @return true if zoom is too high for tiles
         */
        public boolean isOverzoomed()
+       {
+               return _zoom > getMaxZoomLevel();
+       }
+
+       /**
+        * @return the maximum useable zoom level for tiles
+        */
+       public int getMaxZoomLevel()
        {
                // Ask current map source what maximum zoom is
                int maxZoom = (_mapSource == null?0:_mapSource.getMaxZoomLevel());
-               return (_zoom > maxZoom);
+               return maxZoom;
+
        }
 
        /**
similarity index 81%
rename from tim/prune/gui/map/OsmMapSource.java
rename to src/tim/prune/gui/map/OsmMapSource.java
index 925fcf623ea456154c512c5e5e89454eb5b46bf8..e3fe58987b800f54cf10b1b8bd9ed8fe023c0897 100644 (file)
@@ -152,12 +152,31 @@ public class OsmMapSource extends MapSource
 
        /**
         * Make the URL to get the specified tile
+        * @param inLayerNum layer number
+        * @param inZoom zoom level
+        * @param inX x coordinate
+        * @param inY y coordinate
+        * @return relative file path as String
         */
        public String makeURL(int inLayerNum, int inZoom, int inX, int inY)
        {
                // Check if the base url has a [1234], if so replace at random
-               StringBuffer url = new StringBuffer();
-               url.append(pickServerUrl(_baseUrls[inLayerNum]));
+               String baseUrl = pickServerUrl(_baseUrls[inLayerNum]);
+               return makeUrl(baseUrl, inLayerNum, inZoom, inX, inY);
+       }
+
+       public String makeUrl(String baseUrl, int inLayerNum, int inZoom, int inX, int inY)
+       {
+               // If the base URL has {x}/{y} placeholders, use them
+               if (baseUrl.contains("{x}")) {
+                       baseUrl = baseUrl.replace("{z}", Integer.toString(inZoom))
+                               .replace("{x}", Integer.toString(inX))
+                               .replace("{y}", Integer.toString(inY));
+                       return baseUrl;
+               }
+
+               // Else simply append the tile indices and file extension
+               StringBuffer url = new StringBuffer(baseUrl);
                url.append(inZoom).append('/').append(inX).append('/').append(inY);
                url.append('.').append(getFileExtension(inLayerNum));
                if (_apiKey != null)
@@ -167,6 +186,26 @@ public class OsmMapSource extends MapSource
                return url.toString();
        }
 
+       /**
+        * Make a relative file path from the base directory including site name
+        * @param inLayerNum layer number
+        * @param inZoom zoom level
+        * @param inX x coordinate
+        * @param inY y coordinate
+        * @return relative file path as String
+        */
+       public String makeFilePath(int inLayerNum, int inZoom, int inX, int inY)
+       {
+               String siteName = getSiteName(inLayerNum);
+               String filePath = makeUrl(siteName, inLayerNum, inZoom, inX, inY);
+               int indexParam = filePath.indexOf("?");
+               if (indexParam > 0)
+               {
+                       filePath = filePath.substring(0, indexParam);
+               }
+               return filePath;
+       }
+
        /**
         * @return maximum zoom level
         */
similarity index 97%
rename from tim/prune/lang/prune-texts_en.properties
rename to src/tim/prune/lang/prune-texts_en.properties
index 76939263c9d8af07fa36db1f1686cf99550180dd..82219b22e3f7c71411c364f7f0d5d4cc5b4686d9 100644 (file)
@@ -94,6 +94,7 @@ function.interpolate=Interpolate points
 function.deletebydate=Delete points by date
 function.addtimeoffset=Add time offset
 function.addaltitudeoffset=Add altitude offset
+function.removealtitudes=Remove altitudes
 function.findwaypoint=Find waypoint
 function.rearrangewaypoints=Rearrange waypoints
 function.convertnamestotimes=Convert waypoint names to times
@@ -114,6 +115,9 @@ 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=Download 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=Download SRTM 3 arc-second tiles
 function.getwikipedia=Get nearby Wikipedia articles
 function.searchwikipedianames=Search Wikipedia by name
 function.searchosmpois=Get nearby OSM points
@@ -150,6 +154,7 @@ function.managetilecache=Manage tile cache
 function.getweatherforecast=Get weather forecast
 function.setaltitudetolerance=Set altitude tolerance
 function.selecttimezone=Set timezone
+function.setearthdataauthentication=Set Earthdata authentication
 
 # Dialogs
 dialog.exit.confirm.title=Exit GpsPrune
@@ -575,6 +580,11 @@ dialog.displaysettings.size.small=Small
 dialog.displaysettings.size.medium=Medium
 dialog.displaysettings.size.large=Large
 dialog.downloadosm.desc=Confirm to download the raw OSM data for the specified area:
+dialog.earthdataauth.intro=<p>Configure username and password to access your NASA Earthdata login account.</p><p> Create an account at <tt>https://urs.earthdata.nasa.gov/users/new</tt>.</p>
+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
@@ -632,6 +642,7 @@ confirm.mergetracksegments=Track segments merged
 confirm.reverserange=Range reversed
 confirm.addtimeoffset=Time offset added
 confirm.addaltitudeoffset=Altitude offset added
+confirm.removealtitudes=Altitudes removed
 confirm.rearrangewaypoints=Waypoints rearranged
 confirm.rearrangephotos=Photos rearranged
 confirm.splitsegments=%d segment splits were made
@@ -852,6 +863,7 @@ undo.splitsegments=split track segments
 undo.sewsegments=sew track segments
 undo.addtimeoffset=add time offset
 undo.addaltitudeoffset=add altitude offset
+undo.removealtitudes=remove altitudes
 undo.rearrangewaypoints=rearrange waypoints
 undo.cutandmove=move section
 undo.connect=connect
diff --git a/src/tim/prune/undo/UndoRemoveAltitudes.java b/src/tim/prune/undo/UndoRemoveAltitudes.java
new file mode 100644 (file)
index 0000000..becf2d7
--- /dev/null
@@ -0,0 +1,65 @@
+package tim.prune.undo;
+
+import tim.prune.I18nManager;
+import tim.prune.UpdateMessageBroker;
+import tim.prune.data.Altitude;
+import tim.prune.data.DataPoint;
+import tim.prune.data.TrackInfo;
+
+/**
+ * Undo removing (ie: restore the original) altitude from points
+ */
+public class UndoRemoveAltitudes implements UndoOperation
+{
+       /** Start index of section */
+       private int _startIndex;
+       /** altitude values before operation */
+       private Altitude[] _altitudes;
+
+
+       /**
+        * Constructor
+        * @param inTrackInfo track info object
+        */
+       public UndoRemoveAltitudes(TrackInfo inTrackInfo, int inStart, int inEnd)
+       {
+               _startIndex = inStart;
+               final int numPoints = inEnd - inStart + 1;
+               // Make array of cloned altitude objects
+               _altitudes = new Altitude[numPoints];
+               for (int i=0; i<numPoints; i++) {
+                       Altitude a = inTrackInfo.getTrack().getPoint(_startIndex+i).getAltitude();
+                       if (a != null && a.isValid()) {
+                               _altitudes[i] = a.clone();
+                       }
+               }
+       }
+
+
+       /**
+        * @return description of operation including number of points adjusted
+        */
+       public String getDescription()
+       {
+               return I18nManager.getText("undo.removealtitudes") + " (" + (_altitudes.length) + ")";
+       }
+
+
+       /**
+        * Perform the undo operation on the given Track
+        * @param inTrackInfo TrackInfo object on which to perform the operation
+        */
+       public void performUndo(TrackInfo inTrackInfo) throws UndoException
+       {
+               // Perform the inverse operation
+               final int numPoints = _altitudes.length;
+               for (int i=0; i<numPoints; i++)
+               {
+                       DataPoint point = inTrackInfo.getTrack().getPoint(i+_startIndex);
+                       point.resetAltitude(_altitudes[i]);
+               }
+               _altitudes = null;
+               inTrackInfo.getSelection().markInvalid();
+               UpdateMessageBroker.informSubscribers();
+       }
+}
diff --git a/tim/prune/function/srtm/TileFinder.java b/tim/prune/function/srtm/TileFinder.java
deleted file mode 100644 (file)
index 60a9479..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-package tim.prune.function.srtm;
-
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-
-
-/**
- * Class to get the URLs of the SRTM tiles
- * using the srtmtiles.dat file
- */
-public abstract class TileFinder
-{
-       /** URL prefix for all tiles */
-       private static final String URL_PREFIX = "https://dds.cr.usgs.gov/srtm/version2_1/SRTM3/";
-       /** Directory names for each continent */
-       private static final String[] CONTINENTS = {"", "Eurasia", "North_America", "Australia",
-               "Islands", "South_America", "Africa"};
-
-
-       /**
-        * Get the Urls for the given list of tiles
-        * @param inTiles list of Tiles to get
-        * @return array of URLs
-        */
-       public static URL[] getUrls(ArrayList<SrtmTile> inTiles)
-       {
-               if (inTiles == null || inTiles.size() < 1) {return null;}
-               URL[] urls = new URL[inTiles.size()];
-               // Read dat file into array
-               byte[] lookup = readDatFile();
-               for (int t=0; t<inTiles.size(); t++)
-               {
-                       SrtmTile tile = inTiles.get(t);
-                       // Get byte from lookup array
-                       int idx = (tile.getLatitude() + 59)*360 + (tile.getLongitude() + 180);
-                       try
-                       {
-                               int dir = lookup[idx];
-                               if (dir > 0) {
-                                       try {
-                                               urls[t] = new URL(URL_PREFIX + CONTINENTS[dir] + "/" + tile.getTileName());
-                                       } catch (MalformedURLException e) {} // ignore error, url stays null
-                               }
-                       } catch (ArrayIndexOutOfBoundsException e) {} // ignore error, url stays null
-               }
-               return urls;
-       }
-
-       /**
-        * Read the dat file and get the contents
-        * @return byte array containing file contents
-        */
-       private static byte[] readDatFile()
-       {
-               InputStream in = null;
-               try
-               {
-                       // Need absolute path to dat file
-                       in = TileFinder.class.getResourceAsStream("/tim/prune/function/srtm/srtmtiles.dat");
-                       if (in != null)
-                       {
-                               byte[] buffer = new byte[in.available()];
-                               in.read(buffer);
-                               in.close();
-                               return buffer;
-                       }
-               }
-               catch (java.io.IOException e) {
-                       System.err.println("Exception trying to read srtmtiles.dat : " + e.getMessage());
-               }
-               finally
-               {
-                       try {
-                               in.close();
-                       }
-                       catch (Exception e) {} // ignore
-               }
-               return null;
-       }
-}