From: activityworkshop Date: Mon, 6 Apr 2020 19:38:26 +0000 (+0200) Subject: Version 20, March 2020 X-Git-Tag: v20.0.fp1~1^2 X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=commitdiff_plain;h=8b20e3e027058cdf6ff52993ee5576193d08667a Version 20, March 2020 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8e9e794 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.class +*.jar diff --git a/README.md b/README.md index 9e9c08b..1a1aa06 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,5 @@ GpsPrune is a map-based application for viewing, editing and converting coordina It's a cross-platform java application, and its home page is at https://gpsprune.activityworkshop.net . -Here on github you'll find all the sources from version 1 to the current version 19.2, and in the wiki at https://github.com/activityworkshop/GpsPrune/wiki there's the beginning of a translation effort for anyone to contribute. -Currently just the Spanish translations are online, to see whether it's a workable idea or not. Please help with this if you can. +Here on github you'll find all the sources from version 1 to the current version 20, and in the wiki at https://github.com/activityworkshop/GpsPrune/wiki there's the beginning of a translation effort for anyone to contribute. +Currently just the Spanish translations and some missing French texts are online, to see whether it's a workable idea or not. Please help with these if you can. diff --git a/buildtools/build.sh b/buildtools/build.sh index b38e2ce..193244b 100644 --- a/buildtools/build.sh +++ b/buildtools/build.sh @@ -1,6 +1,7 @@ # Build script +set -e # Version number -PRUNENAME=gpsprune_19.2 +PRUNENAME=gpsprune_20 # remove compile directory rm -rf compile # remove dist directory diff --git a/buildtools/pom.xml b/buildtools/pom.xml index 82b29ac..15b6562 100644 --- a/buildtools/pom.xml +++ b/buildtools/pom.xml @@ -7,7 +7,7 @@ tim.prune gpsprune - 19.2 + 20 jar tim.prune.gpsprune diff --git a/buildtools/version.properties b/buildtools/version.properties index af25926..fe5699b 100644 --- a/buildtools/version.properties +++ b/buildtools/version.properties @@ -1 +1 @@ -version=19.2 +version=20 diff --git a/src/tim/prune/App.java b/src/tim/prune/App.java index 3a77858..94e10e0 100644 --- a/src/tim/prune/App.java +++ b/src/tim/prune/App.java @@ -69,7 +69,7 @@ public class App private AppMode _appMode = AppMode.NORMAL; /** Enum for the app mode - currently only two options but may expand later */ - public enum AppMode {NORMAL, DRAWRECT}; + public enum AppMode {NORMAL, DRAWRECT} /** @@ -649,7 +649,8 @@ public class App loadedTrack.load(inFieldArray, inDataArray, inOptions); if (loadedTrack.getNumPoints() <= 0) { - showErrorMessage("error.load.dialogtitle", "error.load.nopoints"); + String msgKey = (inSourceInfo == null ? "error.load.nopointsintext" : "error.load.nopoints"); + showErrorMessage("error.load.dialogtitle", msgKey); // load next file if there's a queue loadNextFile(); return; @@ -715,9 +716,12 @@ public class App undo.setNumPhotosAudios(_trackInfo.getPhotoList().getNumPhotos(), _trackInfo.getAudioList().getNumAudios()); _undoStack.add(undo); _track.combine(inLoadedTrack); - // set source information - inSourceInfo.populatePointObjects(_track, inLoadedTrack.getNumPoints()); - _trackInfo.getFileInfo().addSource(inSourceInfo); + if (inSourceInfo != null) + { + // set source information + inSourceInfo.populatePointObjects(_track, inLoadedTrack.getNumPoints()); + _trackInfo.getFileInfo().addSource(inSourceInfo); + } } else if (answer == JOptionPane.NO_OPTION) { @@ -732,8 +736,12 @@ public class App _lastSavePosition = _undoStack.size(); _trackInfo.getSelection().clearAll(); _track.load(inLoadedTrack); - inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); - _trackInfo.getFileInfo().replaceSource(inSourceInfo); + if (inSourceInfo != null) + { + // set source information + inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); + _trackInfo.getFileInfo().replaceSource(inSourceInfo); + } _trackInfo.getPhotoList().removeCorrelatedPhotos(); _trackInfo.getAudioList().removeCorrelatedAudios(); } @@ -747,16 +755,22 @@ public class App _lastSavePosition = _undoStack.size(); _trackInfo.getSelection().clearAll(); _track.load(inLoadedTrack); - inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); - _trackInfo.getFileInfo().addSource(inSourceInfo); + if (inSourceInfo != null) + { + inSourceInfo.populatePointObjects(_track, _track.getNumPoints()); + _trackInfo.getFileInfo().addSource(inSourceInfo); + } } // Update config before subscribers are told - boolean isRegularLoad = (inSourceInfo.getFileType() != FILE_TYPE.GPSBABEL); - Config.getRecentFileList().addFile(new RecentFile(inSourceInfo.getFile(), isRegularLoad)); + if (inSourceInfo != null) + { + boolean isRegularLoad = (inSourceInfo.getFileType() != FILE_TYPE.GPSBABEL); + Config.getRecentFileList().addFile(new RecentFile(inSourceInfo.getFile(), isRegularLoad)); + // Update status bar + UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") + + " '" + inSourceInfo.getName() + "'"); + } UpdateMessageBroker.informSubscribers(); - // Update status bar - UpdateMessageBroker.informSubscribers(I18nManager.getText("confirm.loadfile") - + " '" + inSourceInfo.getName() + "'"); // update menu _menuManager.informFileLoaded(); // Remove busy lock diff --git a/src/tim/prune/FunctionLibrary.java b/src/tim/prune/FunctionLibrary.java index 0441826..68303ed 100644 --- a/src/tim/prune/FunctionLibrary.java +++ b/src/tim/prune/FunctionLibrary.java @@ -18,12 +18,12 @@ import tim.prune.function.DiskCacheConfig; import tim.prune.function.DownloadOsmFunction; import tim.prune.function.DuplicatePoint; import tim.prune.function.FindWaypoint; -import tim.prune.function.FullRangeDetails; +import tim.prune.function.ProjectPoint; +import tim.prune.function.ShowFullDetails; import tim.prune.function.GetWikipediaFunction; import tim.prune.function.HelpScreen; import tim.prune.function.IgnoreExifThumb; import tim.prune.function.InterpolateFunction; -import tim.prune.function.PasteCoordinates; import tim.prune.function.PhotoPopupFunction; import tim.prune.function.PlayAudioFunction; import tim.prune.function.RearrangePhotosFunction; @@ -50,8 +50,6 @@ import tim.prune.function.distance.DistanceFunction; import tim.prune.function.edit.PointNameEditor; import tim.prune.function.estimate.EstimateTime; import tim.prune.function.estimate.LearnParameters; -import tim.prune.function.gpsies.GetGpsiesFunction; -import tim.prune.function.gpsies.UploadGpsiesFunction; import tim.prune.function.settings.SaveConfig; import tim.prune.function.settings.SetAltitudeTolerance; import tim.prune.function.settings.SetColours; @@ -88,6 +86,7 @@ public abstract class FunctionLibrary public static GenericFunction FUNCTION_IMPORTBABEL = null; public static GenericFunction FUNCTION_SAVECONFIG = null; public static GenericFunction FUNCTION_EDIT_WAYPOINT_NAME = null; + public static GenericFunction FUNCTION_PROJECT_POINT = null; public static GenericFunction FUNCTION_REARRANGE_WAYPOINTS = null; public static GenericFunction FUNCTION_SELECT_SEGMENT = null; public static GenericFunction FUNCTION_SPLIT_SEGMENTS = null; @@ -112,7 +111,6 @@ public abstract class FunctionLibrary public static GenericFunction FUNCTION_ADD_ALTITUDE_OFFSET = null; public static GenericFunction FUNCTION_CONVERT_NAMES_TO_TIMES = null; public static GenericFunction FUNCTION_DELETE_FIELD_VALUES = null; - public static GenericFunction FUNCTION_PASTE_COORDINATES = null; public static GenericFunction FUNCTION_FIND_WAYPOINT = null; public static GenericFunction FUNCTION_DUPLICATE_POINT = null; public static GenericFunction FUNCTION_CONNECT_TO_POINT = null; @@ -127,12 +125,10 @@ public abstract class FunctionLibrary public static GenericFunction FUNCTION_CHARTS = null; public static GenericFunction FUNCTION_3D = null; public static GenericFunction FUNCTION_DISTANCES = null; - public static GenericFunction FUNCTION_FULL_RANGE_DETAILS = null; + public static GenericFunction FUNCTION_FULL_DETAILS = null; public static GenericFunction FUNCTION_AUTOPLAY_TRACK = null; public static GenericFunction FUNCTION_ESTIMATE_TIME = null; public static GenericFunction FUNCTION_LEARN_ESTIMATION_PARAMS = null; - public static GenericFunction FUNCTION_GET_GPSIES = null; - public static GenericFunction FUNCTION_UPLOAD_GPSIES = null; public static GenericFunction FUNCTION_GET_WEATHER_FORECAST = null; public static GenericFunction FUNCTION_LOAD_AUDIO = null; public static GenericFunction FUNCTION_REMOVE_AUDIO = null; @@ -168,6 +164,7 @@ public abstract class FunctionLibrary FUNCTION_IMPORTBABEL = new BabelLoadFromFile(inApp); FUNCTION_SAVECONFIG = new SaveConfig(inApp); FUNCTION_EDIT_WAYPOINT_NAME = new PointNameEditor(inApp); + FUNCTION_PROJECT_POINT = new ProjectPoint(inApp); FUNCTION_REARRANGE_WAYPOINTS = new RearrangeWaypointsFunction(inApp); FUNCTION_SELECT_SEGMENT = new SelectSegmentFunction(inApp); FUNCTION_SPLIT_SEGMENTS = new SplitSegmentsFunction(inApp); @@ -192,7 +189,6 @@ public abstract class FunctionLibrary FUNCTION_ADD_ALTITUDE_OFFSET = new AddAltitudeOffset(inApp); FUNCTION_CONVERT_NAMES_TO_TIMES = new ConvertNamesToTimes(inApp); FUNCTION_DELETE_FIELD_VALUES = new DeleteFieldValues(inApp); - FUNCTION_PASTE_COORDINATES = new PasteCoordinates(inApp); FUNCTION_FIND_WAYPOINT = new FindWaypoint(inApp); FUNCTION_DUPLICATE_POINT = new DuplicatePoint(inApp); FUNCTION_CONNECT_TO_POINT = new ConnectToPointFunction(inApp); @@ -206,12 +202,10 @@ public abstract class FunctionLibrary FUNCTION_CHARTS = new Charter(inApp); FUNCTION_3D = new ShowThreeDFunction(inApp); FUNCTION_DISTANCES = new DistanceFunction(inApp); - FUNCTION_FULL_RANGE_DETAILS = new FullRangeDetails(inApp); + FUNCTION_FULL_DETAILS = new ShowFullDetails(inApp); FUNCTION_AUTOPLAY_TRACK = new AutoplayFunction(inApp); FUNCTION_ESTIMATE_TIME = new EstimateTime(inApp); FUNCTION_LEARN_ESTIMATION_PARAMS = new LearnParameters(inApp); - FUNCTION_GET_GPSIES = new GetGpsiesFunction(inApp); - FUNCTION_UPLOAD_GPSIES = new UploadGpsiesFunction(inApp); FUNCTION_GET_WEATHER_FORECAST = new GetWeatherForecastFunction(inApp); FUNCTION_LOAD_AUDIO = new AudioLoader(inApp); FUNCTION_REMOVE_AUDIO = new RemoveAudioFunction(inApp); diff --git a/src/tim/prune/GpsPrune.java b/src/tim/prune/GpsPrune.java index f396e9e..874ece5 100644 --- a/src/tim/prune/GpsPrune.java +++ b/src/tim/prune/GpsPrune.java @@ -9,9 +9,11 @@ import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Locale; + import javax.swing.JFrame; import javax.swing.JSplitPane; import javax.swing.JToolBar; +import javax.swing.UIManager; import javax.swing.WindowConstants; import tim.prune.config.Config; @@ -29,16 +31,16 @@ import tim.prune.gui.profile.ProfileChart; /** * GpsPrune is a tool to visualize, edit, convert and prune GPS data * Please see the included readme.txt or https://activityworkshop.net - * This software is copyright activityworkshop.net 2006-2018 and made available through the Gnu GPL version 2. + * This software is copyright activityworkshop.net 2006-2020 and made available through the Gnu GPL version 2. * For license details please see the included license.txt. * GpsPrune is the main entry point to the application, including initialisation and launch */ public class GpsPrune { /** Version number of application, used in about screen and for version check */ - public static final String VERSION_NUMBER = "19.2"; + public static final String VERSION_NUMBER = "20"; /** Build number, just used for about screen */ - public static final String BUILD_NUMBER = "363d"; + public static final String BUILD_NUMBER = "378"; /** Static reference to App object */ private static App APP = null; @@ -149,6 +151,14 @@ public class GpsPrune Config.setConfigString(Config.KEY_LANGUAGE_FILE, ""); } } + + // Set look-and-feel + try { + String windowStyle = Config.getConfigString(Config.KEY_WINDOW_STYLE); + UIManager.setLookAndFeel(windowStyle); + } + catch (Exception e) {} + // Set up the window and go launch(dataFiles); } diff --git a/src/tim/prune/I18nManager.java b/src/tim/prune/I18nManager.java index fbf781e..a271f81 100644 --- a/src/tim/prune/I18nManager.java +++ b/src/tim/prune/I18nManager.java @@ -18,10 +18,10 @@ import java.util.ResourceBundle; public abstract class I18nManager { /** Properties object into which all the texts are copied */ - private static Properties LocalTexts = null; + private static Properties _localTexts = null; /** External properties file for developer testing */ - private static Properties ExternalPropsFile = null; + private static Properties _externalPropsFile = null; /** @@ -33,7 +33,7 @@ public abstract class I18nManager final String BUNDLE_NAME = "tim.prune.lang.prune-texts"; final Locale BACKUP_LOCALE = new Locale("en", "GB"); - LocalTexts = new Properties(); + _localTexts = new Properties(); // Load English texts first to use as defaults loadFromBundle(ResourceBundle.getBundle(BUNDLE_NAME, BACKUP_LOCALE)); @@ -65,7 +65,7 @@ public abstract class I18nManager while (e.hasMoreElements()) { String key = e.nextElement(); - LocalTexts.setProperty(key, inBundle.getString(key)); + _localTexts.setProperty(key, inBundle.getString(key)); } } @@ -81,9 +81,9 @@ public abstract class I18nManager try { File file = new File(inFilename); - ExternalPropsFile = new Properties(); + _externalPropsFile = new Properties(); fis = new FileInputStream(file); - ExternalPropsFile.load(fis); + _externalPropsFile.load(fis); fileLoaded = true; // everything worked } catch (IOException ioe) {} @@ -103,17 +103,17 @@ public abstract class I18nManager public static String getText(String inKey) { // look in external props file if available - if (ExternalPropsFile != null) + if (_externalPropsFile != null) { - String extText = ExternalPropsFile.getProperty(inKey); + String extText = _externalPropsFile.getProperty(inKey); if (extText != null) return extText; } // look in texts if available - if (LocalTexts != null) + if (_localTexts != null) { try { - String localText = LocalTexts.getProperty(inKey); + String localText = _localTexts.getProperty(inKey); if (localText != null) return localText; } catch (MissingResourceException mre) {} diff --git a/src/tim/prune/config/Config.java b/src/tim/prune/config/Config.java index 84e5fd7..8c6eefe 100644 --- a/src/tim/prune/config/Config.java +++ b/src/tim/prune/config/Config.java @@ -55,6 +55,8 @@ public abstract class Config public static final String KEY_POVRAY_FONT = "prune.povrayfont"; /** Key for the selected unit set */ public static final String KEY_UNITSET_KEY = "prune.unitsetkey"; + /** Key for the selected coordinate display format */ + public static final String KEY_COORD_DISPLAY_FORMAT = "prune.coorddisplay"; /** Key for index of map source */ public static final String KEY_MAPSOURCE_INDEX = "prune.mapsource"; /** Key for number of fixed map sources */ @@ -87,6 +89,8 @@ public abstract class Config public static final String KEY_ANTIALIAS = "prune.antialias"; /** Key for kml track colour */ public static final String KEY_KML_TRACK_COLOUR = "prune.kmltrackcolour"; + /** Key for window style (name of look-and-feel) */ + public static final String KEY_WINDOW_STYLE = "prune.windowstyle"; /** Key for autosaving settings */ public static final String KEY_AUTOSAVE_SETTINGS = "prune.autosavesettings"; /** Key for recently used files */ @@ -170,6 +174,8 @@ public abstract class Config _unitSet = UnitSetLibrary.getUnitSet(_configValues.getProperty(KEY_UNITSET_KEY)); // Adjust map source index if necessary adjustSelectedMap(); + // Reset coord display format + setConfigInt(KEY_COORD_DISPLAY_FORMAT, 0); if (loadFailed) { throw new ConfigException(); @@ -197,6 +203,7 @@ public abstract class Config props.put(KEY_ANTIALIAS, "1"); // antialias on by default props.put(KEY_AUTOSAVE_SETTINGS, "0"); // autosave false by default props.put(KEY_UNITSET_KEY, "unitset.kilometres"); // metric by default + props.put(KEY_COORD_DISPLAY_FORMAT, "0"); // original props.put(KEY_HEIGHT_EXAGGERATION, "100"); // 100%, no exaggeration props.put(KEY_TERRAIN_GRID_SIZE, "50"); props.put(KEY_ALTITUDE_TOLERANCE, "0"); // 0, all exact as before @@ -246,6 +253,14 @@ public abstract class Config return _configFile; } + /** + * Set the file to which config was saved + */ + public static void setConfigFile(File inFile) + { + _configFile = inFile; + } + /** * @return config Properties object to allow all config values to be saved */ @@ -379,7 +394,7 @@ public abstract class Config public static void updatePointColourer(PointColourer inColourer) { _pointColourer = inColourer; - setConfigString(KEY_POINT_COLOURER, ColourerFactory.PointColourerToString(_pointColourer)); + setConfigString(KEY_POINT_COLOURER, ColourerFactory.pointColourerToString(_pointColourer)); } /** diff --git a/src/tim/prune/copyright.txt b/src/tim/prune/copyright.txt index 3022774..db7f2dd 100644 --- a/src/tim/prune/copyright.txt +++ b/src/tim/prune/copyright.txt @@ -1,4 +1,4 @@ -The source code of GpsPrune is copyright 2006-2018 activityworkshop.net +The source code of GpsPrune is copyright 2006-2020 activityworkshop.net and is distributed under the terms of the Gnu GPL version 2. Portions of the package jpeg.drew were taken @@ -6,4 +6,4 @@ from Drew Noakes' "Metadata extractor" v2.7.2 which is copyright Drew Noakes 2002-2015 and released under Apache 2.0. Translations are copyright various contributors, some of whom are named -in the source code and some preferred to remain anonymous. \ No newline at end of file +in the source code and some preferred to remain anonymous. diff --git a/src/tim/prune/data/Coordinate.java b/src/tim/prune/data/Coordinate.java index e30fa4a..b668660 100644 --- a/src/tim/prune/data/Coordinate.java +++ b/src/tim/prune/data/Coordinate.java @@ -475,4 +475,22 @@ public abstract class Coordinate return "Coord: " + _cardinal + " (" + _degrees + ") (" + _minutes + ") (" + _seconds + "." + formatFraction(_fracs, _fracDenom) + ") = " + _asDouble; } + + /** + * From a saved coordinate format display value, get the corresponding value to use + * @param inValue value from config + * @return coordinate format as int + */ + public static int getCoordinateFormatForDisplay(int inValue) + { + switch(inValue) + { + case FORMAT_DEG: + case FORMAT_DEG_MIN: + case FORMAT_DEG_MIN_SEC: + return inValue; + default: + return FORMAT_NONE; + } + } } diff --git a/src/tim/prune/data/FileInfo.java b/src/tim/prune/data/FileInfo.java index 41900cb..0c4ee5f 100644 --- a/src/tim/prune/data/FileInfo.java +++ b/src/tim/prune/data/FileInfo.java @@ -51,7 +51,9 @@ public class FileInfo */ public void removeSource() { - _sources.remove(_sources.size()-1); + if (!_sources.isEmpty()) { + _sources.remove(_sources.size()-1); + } } /** diff --git a/src/tim/prune/data/RangeStats.java b/src/tim/prune/data/RangeStats.java index 13ecaad..d8461c4 100644 --- a/src/tim/prune/data/RangeStats.java +++ b/src/tim/prune/data/RangeStats.java @@ -1,163 +1,133 @@ package tim.prune.data; -import tim.prune.config.Config; - /** - * Class to do calculations of range statistics such as distances, durations, - * speeds, gradients etc, and to hold the results of the calculations. - * Used by FullRangeDetails as well as the EstimateTime functions. + * Class to do basic calculations of range statistics such as distances, durations, + * and altitude ranges, and to hold the results of the calculations. */ public class RangeStats { - // MAYBE: Split into basic stats (quick to calculate, for detailsdisplay) and full stats (for other two) - private boolean _valid = false; - private int _numPoints = 0; - private int _startIndex = 0, _endIndex = 0; - private int _numSegments = 0; - private AltitudeRange _totalAltitudeRange = null, _movingAltitudeRange = null; - private AltitudeRange _gentleAltitudeRange = null, _steepAltitudeRange = null; + private int _numPoints = 0; + private int _numSegments = 0; + private boolean _foundTrackPoint = false; + protected AltitudeRange _totalAltitudeRange = new AltitudeRange(); + protected AltitudeRange _movingAltitudeRange = new AltitudeRange(); private Timestamp _earliestTimestamp = null, _latestTimestamp = null; private long _movingMilliseconds = 0L; private boolean _timesIncomplete = false; private boolean _timesOutOfSequence = false; - private double _totalDistanceRads = 0.0, _movingDistanceRads = 0.0; - // Note, maximum speed is not calculated here, use the SpeedData class instead + protected double _totalDistanceRads = 0.0, _movingDistanceRads = 0.0; + protected DataPoint _prevPoint = null; - private static final double STEEP_ANGLE = 0.15; // gradient steeper than 15% counts as steep + /** Constructor */ + public RangeStats() + {} /** - * Constructor - * @param inTrack track to compile data for - * @param inStartIndex start index of range to examine - * @param inEndIndex end index (inclusive) of range to examine + * Constructor giving Track + * @param inTrack track object to calculate with */ public RangeStats(Track inTrack, int inStartIndex, int inEndIndex) { - if (inTrack != null && inStartIndex >= 0 && inEndIndex > inStartIndex - && inEndIndex < inTrack.getNumPoints()) + populateFromTrack(inTrack, inStartIndex, inEndIndex); + } + + /** + * Add the specified points from the given track to the calculations + * @param inTrack track object + * @param inStartIndex start index (inclusive) + * @param inEndIndex end index (inclusive) + */ + protected void populateFromTrack(Track inTrack, int inStartIndex, int inEndIndex) + { + for (int i=inStartIndex; i<=inEndIndex; i++) { - _valid = calculateStats(inTrack, inStartIndex, inEndIndex); + addPoint(inTrack.getPoint(i)); } } /** - * Calculate the statistics and populate the member variables with the results - * @param inTrack track - * @param inStartIndex start index of range - * @param inEndIndex end index (inclusive) of range - * @return true on success + * @param inPoint point to add to the calculations */ - private boolean calculateStats(Track inTrack, int inStartIndex, int inEndIndex) + public void addPoint(DataPoint inPoint) { - _startIndex = inStartIndex; - _endIndex = inEndIndex; - _numPoints = inEndIndex - inStartIndex + 1; - _totalAltitudeRange = new AltitudeRange(); - _movingAltitudeRange = new AltitudeRange(); - _gentleAltitudeRange = new AltitudeRange(); - _steepAltitudeRange = new AltitudeRange(); - DataPoint prevPoint = null; - Altitude prevAltitude = null; - _totalDistanceRads = _movingDistanceRads = 0.0; - double radsSinceLastAltitude = 0.0; - _movingMilliseconds = 0L; - - // Loop over the points in the range - for (int i=inStartIndex; i<= inEndIndex; i++) + if (inPoint == null) + { + return; + } + _numPoints++; + // ignore all waypoints + if (inPoint.isWaypoint()) { + return; + } + if (inPoint.getSegmentStart() || !_foundTrackPoint) { + _numSegments++; + } + _foundTrackPoint = true; + // Get the distance to the previous track point + if (_prevPoint != null) { - DataPoint p = inTrack.getPoint(i); - if (p == null) return false; - // ignore all waypoints - if (p.isWaypoint()) continue; + double rads = DataPoint.calculateRadiansBetween(_prevPoint, inPoint); + _totalDistanceRads += rads; + if (!inPoint.getSegmentStart()) { + _movingDistanceRads += rads; + } + } - if (p.getSegmentStart()) { - _numSegments++; + // timestamps + if (inPoint.hasTimestamp()) + { + Timestamp currTstamp = inPoint.getTimestamp(); + if (_earliestTimestamp == null || currTstamp.isBefore(_earliestTimestamp)) { + _earliestTimestamp = currTstamp; } - // Get the distance to the previous track point - if (prevPoint != null) - { - double rads = DataPoint.calculateRadiansBetween(prevPoint, p); - _totalDistanceRads += rads; - if (!p.getSegmentStart()) { - _movingDistanceRads += rads; - } - // Keep track of rads since last point with an altitude - radsSinceLastAltitude += rads; + if (_latestTimestamp == null || currTstamp.isAfter(_latestTimestamp)) { + _latestTimestamp = currTstamp; } - // Get the altitude difference to the previous track point - if (p.hasAltitude()) + // Work out duration without segment gaps + if (!inPoint.getSegmentStart() && _prevPoint != null && _prevPoint.hasTimestamp()) { - Altitude altitude = p.getAltitude(); - _totalAltitudeRange.addValue(altitude); - if (p.getSegmentStart()) { - _movingAltitudeRange.ignoreValue(altitude); + long millisLater = currTstamp.getMillisecondsSince(_prevPoint.getTimestamp()); + if (millisLater < 0) { + _timesOutOfSequence = true; } - else - { - _movingAltitudeRange.addValue(altitude); - if (prevAltitude != null) - { - // Work out gradient, see whether to ignore/add to gentle or steep - double heightDiff = altitude.getMetricValue() - prevAltitude.getMetricValue(); - double metricDist = Distance.convertRadiansToDistance(radsSinceLastAltitude, UnitSetLibrary.UNITS_METRES); - final boolean isSteep = metricDist < 0.001 || (Math.abs(heightDiff / metricDist) > STEEP_ANGLE); - if (isSteep) { - _steepAltitudeRange.ignoreValue(prevAltitude); - _steepAltitudeRange.addValue(altitude); - } - else { - _gentleAltitudeRange.ignoreValue(prevAltitude); - _gentleAltitudeRange.addValue(altitude); - } - } + else { + _movingMilliseconds += millisLater; } - prevAltitude = altitude; - radsSinceLastAltitude = 0.0; } + } + else { + _timesIncomplete = true; + } - if (p.hasTimestamp()) - { - if (_earliestTimestamp == null || p.getTimestamp().isBefore(_earliestTimestamp)) { - _earliestTimestamp = p.getTimestamp(); - } - if (_latestTimestamp == null || p.getTimestamp().isAfter(_latestTimestamp)) { - _latestTimestamp = p.getTimestamp(); - } - // Work out duration without segment gaps - if (!p.getSegmentStart() && prevPoint != null && prevPoint.hasTimestamp()) - { - long millisLater = p.getTimestamp().getMillisecondsSince(prevPoint.getTimestamp()); - if (millisLater < 0) {_timesOutOfSequence = true;} - else { - _movingMilliseconds += millisLater; - } - } + // altitudes + if (inPoint.hasAltitude()) + { + Altitude altitude = inPoint.getAltitude(); + _totalAltitudeRange.addValue(altitude); + if (inPoint.getSegmentStart()) { + _movingAltitudeRange.ignoreValue(altitude); } - else { - _timesIncomplete = true; + else + { + _movingAltitudeRange.addValue(altitude); } - - prevPoint = p; } - return true; - } + // allow child classes to do additional calculations + doFurtherCalculations(inPoint); - /** @return true if results are valid */ - public boolean isValid() { - return _valid; + _prevPoint = inPoint; } - /** @return start index of range */ - public int getStartIndex() { - return _startIndex; + /** + * Hook for subclasses to do what they want in addition + * @param inPoint incoming point + */ + protected void doFurtherCalculations(DataPoint inPoint) + { } - /** @return end index of range */ - public int getEndIndex() { - return _endIndex; - } /** @return number of points in range */ public int getNumPoints() { @@ -179,16 +149,6 @@ public class RangeStats return _movingAltitudeRange; } - /** @return altitude range of range just considering low gradient bits */ - public AltitudeRange getGentleAltitudeRange() { - return _gentleAltitudeRange; - } - - /** @return altitude range of range just considering high gradient bits */ - public AltitudeRange getSteepAltitudeRange() { - return _steepAltitudeRange; - } - /** @return the earliest timestamp found */ public Timestamp getEarliestTimestamp() { return _earliestTimestamp; @@ -239,42 +199,26 @@ public class RangeStats return Distance.convertRadiansToDistance(_movingDistanceRads, UnitSetLibrary.UNITS_KILOMETRES); } - /** @return the total gradient in % (including segment gaps) */ - public double getTotalGradient() - { - double dist = Distance.convertRadiansToDistance(_totalDistanceRads, UnitSetLibrary.UNITS_METRES); - if (dist > 0.0 && _totalAltitudeRange.hasRange()) { - return _totalAltitudeRange.getMetricHeightDiff() / dist * 100.0; - } - return 0.0; - } - - /** @return the moving gradient in % (ignoring segment gaps) */ - public double getMovingGradient() - { - double dist = Distance.convertRadiansToDistance(_movingDistanceRads, UnitSetLibrary.UNITS_METRES); - if (dist > 0.0 && _movingAltitudeRange.hasRange()) { - return _movingAltitudeRange.getMetricHeightDiff() / dist * 100.0; - } - return 0.0; - } - - /** @return the total vertical speed (including segment gaps) in current vspeed units */ + /** + * @return the total vertical speed (including segment gaps) in metric units + */ public double getTotalVerticalSpeed() { long time = getTotalDurationInSeconds(); if (time > 0 && _totalAltitudeRange.hasRange()) { - return _totalAltitudeRange.getMetricHeightDiff() / time * Config.getUnitSet().getVerticalSpeedUnit().getMultFactorFromStd(); + return _totalAltitudeRange.getMetricHeightDiff() / time; } return 0.0; } - /** @return the moving vertical speed (ignoring segment gaps) in current vspeed units */ + /** + * @return the moving vertical speed (ignoring segment gaps) in metric units + */ public double getMovingVerticalSpeed() { long time = getMovingDurationInSeconds(); if (time > 0 && _movingAltitudeRange.hasRange()) { - return _movingAltitudeRange.getMetricHeightDiff() / time * Config.getUnitSet().getVerticalSpeedUnit().getMultFactorFromStd(); + return _movingAltitudeRange.getMetricHeightDiff() / time; } return 0.0; } diff --git a/src/tim/prune/data/RangeStatsWithGradients.java b/src/tim/prune/data/RangeStatsWithGradients.java new file mode 100644 index 0000000..c495c51 --- /dev/null +++ b/src/tim/prune/data/RangeStatsWithGradients.java @@ -0,0 +1,106 @@ +package tim.prune.data; + +/** + * Class to do additional range calculations including gradients + * Used by full details display as well as the EstimateTime functions. + */ +public class RangeStatsWithGradients extends RangeStats +{ + private AltitudeRange _gentleAltitudeRange = new AltitudeRange(); + private AltitudeRange _steepAltitudeRange = new AltitudeRange(); + private Altitude _prevAltitude = null; + private double _radsSinceLastAltitude = 0.0; + + private static final double STEEP_ANGLE = 0.15; // gradient steeper than 15% counts as steep + + + /** + * Default constructor + */ + public RangeStatsWithGradients() + { + super(); + } + + /** + * Constructor + * @param inTrack track object + * @param inStartIndex start index + * @param inEndIndex end index + */ + public RangeStatsWithGradients(Track inTrack, int inStartIndex, int inEndIndex) + { + super(); + populateFromTrack(inTrack, inStartIndex, inEndIndex); + } + + /** + * Add the given point to the calculations + * @param inPoint incoming point + */ + protected void doFurtherCalculations(DataPoint inPoint) + { + if (_prevPoint != null) + { + // Keep track of rads since last point with an altitude + double rads = DataPoint.calculateRadiansBetween(_prevPoint, inPoint); + _radsSinceLastAltitude += rads; + } + + if (inPoint.hasAltitude()) + { + Altitude altitude = inPoint.getAltitude(); + + if (!inPoint.getSegmentStart() && _prevAltitude != null) + { + // Work out gradient, see whether to ignore/add to gentle or steep + double heightDiff = altitude.getMetricValue() - _prevAltitude.getMetricValue(); + double metricDist = Distance.convertRadiansToDistance(_radsSinceLastAltitude, UnitSetLibrary.UNITS_METRES); + final boolean isSteep = metricDist < 0.001 || (Math.abs(heightDiff / metricDist) > STEEP_ANGLE); + if (isSteep) + { + _steepAltitudeRange.ignoreValue(_prevAltitude); + _steepAltitudeRange.addValue(altitude); + } + else + { + _gentleAltitudeRange.ignoreValue(_prevAltitude); + _gentleAltitudeRange.addValue(altitude); + } + } + _prevAltitude = altitude; + _radsSinceLastAltitude = 0.0; + } + + } + + /** @return altitude range of range just considering low gradient bits */ + public AltitudeRange getGentleAltitudeRange() { + return _gentleAltitudeRange; + } + + /** @return altitude range of range just considering high gradient bits */ + public AltitudeRange getSteepAltitudeRange() { + return _steepAltitudeRange; + } + + /** @return the total gradient in % (including segment gaps) */ + public double getTotalGradient() + { + double dist = Distance.convertRadiansToDistance(_totalDistanceRads, UnitSetLibrary.UNITS_METRES); + if (dist > 0.0 && _totalAltitudeRange.hasRange()) { + return _totalAltitudeRange.getMetricHeightDiff() / dist * 100.0; + } + return 0.0; + } + + /** @return the moving gradient in % (ignoring segment gaps) */ + public double getMovingGradient() + { + double dist = Distance.convertRadiansToDistance(_movingDistanceRads, UnitSetLibrary.UNITS_METRES); + if (dist > 0.0 && _movingAltitudeRange.hasRange()) { + return _movingAltitudeRange.getMetricHeightDiff() / dist * 100.0; + } + return 0.0; + } +} diff --git a/src/tim/prune/data/Selection.java b/src/tim/prune/data/Selection.java index 7b63d70..24fda5d 100644 --- a/src/tim/prune/data/Selection.java +++ b/src/tim/prune/data/Selection.java @@ -11,14 +11,11 @@ public class Selection { private Track _track = null; private int _currentPoint = -1; - private boolean _valid = false; private int _prevNumPoints = 0; private int _startIndex = -1, _endIndex = -1; private int _currentPhotoIndex = -1; private int _currentAudioIndex = -1; - private AltitudeRange _altitudeRange = null; - private long _movingMilliseconds = 0L; - private double _angMovingDistance = -1.0; + private RangeStats _rangeStats = null; /** @@ -36,7 +33,7 @@ public class Selection */ public void markInvalid() { - _valid = false; + _rangeStats = null; } @@ -63,6 +60,9 @@ public class Selection */ private void recalculate() { + if (_rangeStats != null) { + return; + } final int numPoints = _track.getNumPoints(); // Recheck if the number of points has changed if (numPoints != _prevNumPoints) @@ -72,52 +72,12 @@ public class Selection } if (numPoints > 0 && hasRangeSelected()) { - _altitudeRange = new AltitudeRange(); - Altitude altitude = null; - Timestamp time = null, previousTime = null; - DataPoint lastPoint = null, currPoint = null; - _angMovingDistance = 0.0; - _movingMilliseconds = 0L; - // Loop over points in selection - for (int i=_startIndex; i<=_endIndex; i++) - { - currPoint = _track.getPoint(i); - altitude = currPoint.getAltitude(); - // Ignore waypoints in altitude calculations - if (!currPoint.isWaypoint() && altitude.isValid()) - { - if (currPoint.getSegmentStart()) { - _altitudeRange.ignoreValue(altitude); - } - else { - _altitudeRange.addValue(altitude); - } - } - // Compare timestamps within the segments - time = currPoint.getTimestamp(); - if (time.isValid()) - { - // add moving time - if (!currPoint.getSegmentStart() && previousTime != null && time.isAfter(previousTime)) { - _movingMilliseconds += time.getMillisecondsSince(previousTime); - } - previousTime = time; - } - // Calculate distances, again ignoring waypoints - if (!currPoint.isWaypoint()) - { - if (lastPoint != null) - { - double radians = DataPoint.calculateRadiansBetween(lastPoint, currPoint); - if (!currPoint.getSegmentStart()) { - _angMovingDistance += radians; - } - } - lastPoint = currPoint; - } - } + _rangeStats = new RangeStats(_track, _startIndex, _endIndex); + } + else + { + _rangeStats = new RangeStats(); } - _valid = true; } @@ -126,7 +86,7 @@ public class Selection */ public int getStart() { - if (!_valid) recalculate(); + recalculate(); return _startIndex; } @@ -136,7 +96,7 @@ public class Selection */ public int getEnd() { - if (!_valid) recalculate(); + recalculate(); return _endIndex; } @@ -145,8 +105,8 @@ public class Selection */ public AltitudeRange getAltitudeRange() { - if (!_valid) recalculate(); - return _altitudeRange; + recalculate(); + return _rangeStats.getTotalAltitudeRange(); } @@ -155,8 +115,8 @@ public class Selection */ public long getMovingSeconds() { - if (!_valid) recalculate(); - return _movingMilliseconds / 1000L; + recalculate(); + return _rangeStats.getMovingDurationInSeconds(); } /** @@ -164,7 +124,7 @@ public class Selection */ public double getMovingDistance() { - return Distance.convertRadiansToDistance(_angMovingDistance); + return _rangeStats.getMovingDistance(); } /** @@ -176,6 +136,7 @@ public class Selection selectRange(-1, -1); _currentPhotoIndex = -1; _currentAudioIndex = -1; + markInvalid(); check(); } @@ -276,6 +237,7 @@ public class Selection // Clear selected range _startIndex = _endIndex = -1; // Check for consistency and fire update + markInvalid(); check(); } @@ -355,6 +317,7 @@ public class Selection { // track is empty, clear selections _currentPoint = _startIndex = _endIndex = -1; + markInvalid(); } UpdateMessageBroker.informSubscribers(DataSubscriber.SELECTION_CHANGED); } diff --git a/src/tim/prune/data/Timestamp.java b/src/tim/prune/data/Timestamp.java index ac144bb..6083cf6 100644 --- a/src/tim/prune/data/Timestamp.java +++ b/src/tim/prune/data/Timestamp.java @@ -22,7 +22,7 @@ public abstract class Timestamp protected static final DateFormat ISO_8601_FORMAT_WITH_MILLIS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - private static boolean MillisAddedToTimeFormat = false; + private static boolean _millisAddedToTimeFormat = false; /** Possible formats for parsing and displaying timestamps */ @@ -138,7 +138,7 @@ public abstract class Timestamp { if (!isValid()) return ""; // Maybe we should add milliseconds to this format? - if (hasMilliseconds() && !MillisAddedToTimeFormat) + if (hasMilliseconds() && !_millisAddedToTimeFormat) { try { @@ -147,7 +147,7 @@ public abstract class Timestamp if (pattern.indexOf("ss") > 0 && pattern.indexOf("SS") < 0) { sdf.applyPattern(pattern.replaceFirst("s+", "$0.SSS")); - MillisAddedToTimeFormat = true; + _millisAddedToTimeFormat = true; } } catch (ClassCastException cce) {} diff --git a/src/tim/prune/function/AboutScreen.java b/src/tim/prune/function/AboutScreen.java index 80a7983..518b10e 100644 --- a/src/tim/prune/function/AboutScreen.java +++ b/src/tim/prune/function/AboutScreen.java @@ -98,7 +98,7 @@ public class AboutScreen extends GenericFunction descBuffer.append("

").append(I18nManager.getText("dialog.about.languages")).append(" : ") .append("afrikaans, \u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano,
" + " magyar, nederlands, polski, portugu\u00EAs, rom\u00E2n\u0103, suomi, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian),
" + - " \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, ukrainian

"); + " \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch

"); descBuffer.append("

").append(I18nManager.getText("dialog.about.translatedby")).append("

"); JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString()); descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); diff --git a/src/tim/prune/function/AddAltitudeOffset.java b/src/tim/prune/function/AddAltitudeOffset.java index c98ab3e..26849de 100644 --- a/src/tim/prune/function/AddAltitudeOffset.java +++ b/src/tim/prune/function/AddAltitudeOffset.java @@ -101,7 +101,7 @@ public class AddAltitudeOffset extends GenericFunction MouseAdapter mouseListener = new MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent arg0) { _okButton.setEnabled(Math.abs(getOffset()) > 0.001); - }; + } }; _editField.addKeyListener(keyListener); _editField.addMouseListener(mouseListener); diff --git a/src/tim/prune/function/AddTimeOffset.java b/src/tim/prune/function/AddTimeOffset.java index 2e259bb..115bfa5 100644 --- a/src/tim/prune/function/AddTimeOffset.java +++ b/src/tim/prune/function/AddTimeOffset.java @@ -126,7 +126,7 @@ public class AddTimeOffset extends GenericFunction MouseAdapter mouseListener = new MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent arg0) { _okButton.setEnabled(getOffsetSecs() != 0L); - }; + } }; _dayField.addKeyListener(keyListener); _hourField.addKeyListener(keyListener); diff --git a/src/tim/prune/function/ConnectToPointFunction.java b/src/tim/prune/function/ConnectToPointFunction.java index 0998020..9921dc5 100644 --- a/src/tim/prune/function/ConnectToPointFunction.java +++ b/src/tim/prune/function/ConnectToPointFunction.java @@ -42,9 +42,9 @@ public class ConnectToPointFunction extends GenericFunction boolean connectPhoto = (point != null && photo != null && point.getPhoto() == null); boolean connectAudio = (point != null && audio != null && point.getAudio() == null); - if (connectPhoto && connectAudio) { + // if (connectPhoto && connectAudio) { // TODO: Let user choose whether to connect photo/audio or both - } + // } // Make undo object UndoOperation undo = new UndoConnectMedia(point, connectPhoto?photo.getName():null, connectAudio?audio.getName():null); diff --git a/src/tim/prune/function/CreateMarkerWaypointsFunction.java b/src/tim/prune/function/CreateMarkerWaypointsFunction.java index f3dd1f1..92b4ce5 100644 --- a/src/tim/prune/function/CreateMarkerWaypointsFunction.java +++ b/src/tim/prune/function/CreateMarkerWaypointsFunction.java @@ -8,12 +8,14 @@ import tim.prune.UpdateMessageBroker; import tim.prune.data.DataPoint; import tim.prune.data.Field; import tim.prune.data.FieldList; +import tim.prune.data.RangeStats; import tim.prune.data.Track; +import tim.prune.data.UnitSetLibrary; import tim.prune.undo.UndoAppendPoints; /** - * Function to create waypoints marking either - * at regular distance intervals or time intervals + * Function to create waypoints marking regular distance intervals, + * regular time intervals, or halfway points */ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction { @@ -22,12 +24,21 @@ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction /** Counter of previously used multiple */ private int _previousMultiple = 0; + /* + * Type of halfway point + */ + private enum HalfwayType + { + HALF_DISTANCE, + HALF_CLIMB, + HALF_DESCENT + } /** * Constructor */ public CreateMarkerWaypointsFunction(App inApp) { - super(inApp); + super(inApp, true); } /** @@ -51,55 +62,34 @@ public class CreateMarkerWaypointsFunction extends DistanceTimeLimitFunction */ protected void performFunction() { - // Distribute either by distance or time + // Determine which kind of markers to create final int timeLimitSeconds = getTimeLimitInSeconds(); final boolean createByTime = (timeLimitSeconds > 0); - final double distLimitRadians = getDistanceLimitRadians(); - final boolean createByDistance = (distLimitRadians > 0.0); - if (!createByTime && !createByDistance) { - return; // neither option selected - } - - // Make undo object - final int numPoints = _app.getTrackInfo().getTrack().getNumPoints(); - UndoAppendPoints undo = new UndoAppendPoints(numPoints); + final double distLimitKm = getDistanceLimitKilometres(); + final boolean createByDistance = (distLimitKm > 0.0); + final boolean createHalves = isHalvesSelected(); // set up the memory from scratch to collect the created points initMemory(); - // Make new waypoints, looping through the points in the track - DataPoint currPoint = null, prevPoint = null; - double currValue = 0.0, prevValue = 0.0; - for (int i=0; i 0); + final boolean createByDistance = (inDistLimitKm > 0.0); + + // Make new waypoints, looping through the points in the track + DataPoint currPoint = null, prevPoint = null; + double currValue = 0.0, prevValue = 0.0; + RangeStats rangeStats = new RangeStats(); + final int numPoints = _app.getTrackInfo().getTrack().getNumPoints(); + for (int i=0; i 0.0) + { + final double currDist = partialStats.getMovingDistanceKilometres(); + createdDistance = processHalfValue(prevPoint, prevDistance, halfDistance, + currPoint, currDist, HalfwayType.HALF_DISTANCE); + prevDistance = currDist; + } + // climb + if (!createdClimb && totalClimb > 0.0) + { + final double currClimb = partialStats.getMovingAltitudeRange().getClimb(UnitSetLibrary.UNITS_METRES); + createdClimb = processHalfValue(prevPoint, prevClimb, halfClimb, + currPoint, currClimb, HalfwayType.HALF_CLIMB); + prevClimb = currClimb; + } + // descent + if (!createdDescent && totalDescent > 0.0) + { + final double currDescent = partialStats.getMovingAltitudeRange().getDescent(UnitSetLibrary.UNITS_METRES); + createdDescent = processHalfValue(prevPoint, prevDescent, halfDescent, + currPoint, currDescent, HalfwayType.HALF_DESCENT); + prevDescent = currDescent; + } + + prevPoint = currPoint; + } + } + } + + /** + * Consider a pair of points in the track to see if a new halfway marker should be inserted between them + * @param inPrevPoint previous point + * @param inPrevValue value of function at this previous point + * @param inTargetValue target halfway value + * @param inCurrPoint current point + * @param inCurrValue value of function at this current point + * @param inType type of halfway point + */ + private boolean processHalfValue(DataPoint inPrevPoint, double inPrevValue, double inTargetValue, + DataPoint inCurrPoint, double inCurrValue, HalfwayType inType) + { + if (inPrevValue <= inTargetValue && inCurrValue >= inTargetValue) + { + // Calculate position of limit between the two points + final double valueBeforeBreak = inTargetValue - inPrevValue; + final double valueAfterBreak = inCurrValue - inTargetValue; + final double fractionFromPrev = valueBeforeBreak / (valueBeforeBreak + valueAfterBreak); + DataPoint marker = DataPoint.interpolate(inPrevPoint, inCurrPoint, fractionFromPrev); + marker.setFieldValue(Field.WAYPT_NAME, createHalfwayName(inType), false); + _pointsToAdd.add(marker); + return true; + } + return false; + } + + /** + * Create the name of the halfway point according to type + * @param inType type of point + */ + private String createHalfwayName(HalfwayType inType) + { + String typeString = null; + switch (inType) + { + case HALF_DISTANCE: + typeString = "distance"; + break; + case HALF_CLIMB: + typeString = "climb"; + break; + case HALF_DESCENT: + typeString = "descent"; + break; + } + if (typeString != null) + { + return I18nManager.getText("dialog.markers.half." + typeString); + } + return "half"; + } } diff --git a/src/tim/prune/function/DistanceTimeLimitFunction.java b/src/tim/prune/function/DistanceTimeLimitFunction.java index eaa7b7d..48075e7 100644 --- a/src/tim/prune/function/DistanceTimeLimitFunction.java +++ b/src/tim/prune/function/DistanceTimeLimitFunction.java @@ -10,8 +10,7 @@ import java.awt.event.ItemListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import javax.swing.Box; -import javax.swing.BoxLayout; +import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JComboBox; @@ -28,6 +27,7 @@ import tim.prune.data.Field; import tim.prune.data.TimeDifference; import tim.prune.data.Unit; import tim.prune.data.UnitSetLibrary; +import tim.prune.gui.GuiGridLayout; import tim.prune.gui.WholeNumberField; /** @@ -40,6 +40,10 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction protected JDialog _dialog = null; /** Radio buttons for splitting by distance and time */ private JRadioButton _distLimitRadio = null, _timeLimitRadio = null; + /** Radio button for splitting by fraction (such as half-distance) */ + private JRadioButton _halvesRadio = null; + /** Flag for whether to offer halves or not */ + private boolean _showHalves = false; /** Dropdown for selecting distance units */ private JComboBox _distUnitsDropdown = null; /** Text field for entering distance */ @@ -52,29 +56,28 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction /** - * React to item changes and key presses + * React to item changes and key presses by enabling / disabling ok button */ - private abstract class ChangeListener extends KeyAdapter implements ItemListener + private class ChangeListener extends KeyAdapter implements ItemListener { - /** Method to be implemented */ - public abstract void optionsChanged(); - /** Item changed in ItemListener */ public void itemStateChanged(ItemEvent arg0) { - optionsChanged(); + enableOkButton(); } /** Key released in KeyListener */ public void keyReleased(KeyEvent arg0) { - optionsChanged(); + enableOkButton(); } } /** * Constructor */ - public DistanceTimeLimitFunction(App inApp) { + public DistanceTimeLimitFunction(App inApp, boolean inShowHalves) + { super(inApp); + _showHalves = inShowHalves; } /** @@ -112,28 +115,31 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction JPanel dialogPanel = new JPanel(); dialogPanel.setLayout(new BorderLayout(5, 5)); - // Make radio buttons for three different options + // Make radio buttons for the options _distLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.distancelimit") + ": "); _timeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.timelimit") + ": "); + if (_showHalves) { + _halvesRadio = new JRadioButton(I18nManager.getText("dialog.markers.halves")); + } ButtonGroup radioGroup = new ButtonGroup(); radioGroup.add(_distLimitRadio); radioGroup.add(_timeLimitRadio); + if (_showHalves) { + radioGroup.add(_halvesRadio); + } // central panel for limits JPanel limitsPanel = new JPanel(); - limitsPanel.setLayout(new BoxLayout(limitsPanel, BoxLayout.Y_AXIS)); - limitsPanel.add(Box.createVerticalStrut(8)); - ChangeListener optionsChangedListener = new ChangeListener() { - public void optionsChanged() { - enableOkButton(); - } - }; + limitsPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); + GuiGridLayout grid = new GuiGridLayout(limitsPanel, new double[] {0.5, 1.0}, + new boolean[] {false, false}); + ChangeListener optionsChangedListener = new ChangeListener(); // distance limits - JPanel distLimitPanel = new JPanel(); - distLimitPanel.setLayout(new FlowLayout()); + grid.add(_distLimitRadio); _distLimitRadio.setSelected(true); _distLimitRadio.addItemListener(optionsChangedListener); - distLimitPanel.add(_distLimitRadio); + JPanel distLimitPanel = new JPanel(); + distLimitPanel.setLayout(new FlowLayout()); _distanceField = new WholeNumberField(3); _distanceField.addKeyListener(optionsChangedListener); distLimitPanel.add(_distanceField); @@ -143,13 +149,13 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction _distUnitsDropdown.addItemListener(optionsChangedListener); distLimitPanel.add(_distUnitsDropdown); distLimitPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - limitsPanel.add(distLimitPanel); + grid.add(distLimitPanel); // time limit panel + grid.add(_timeLimitRadio); + _timeLimitRadio.addItemListener(optionsChangedListener); JPanel timeLimitPanel = new JPanel(); timeLimitPanel.setLayout(new FlowLayout()); - _timeLimitRadio.addItemListener(optionsChangedListener); - timeLimitPanel.add(_timeLimitRadio); _limitHourField = new WholeNumberField(2); _limitHourField.addKeyListener(optionsChangedListener); timeLimitPanel.add(_limitHourField); @@ -159,7 +165,14 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction timeLimitPanel.add(_limitMinField); timeLimitPanel.add(new JLabel(I18nManager.getText("units.minutes"))); timeLimitPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - limitsPanel.add(timeLimitPanel); + grid.add(timeLimitPanel); + + // halves + if (_showHalves) + { + grid.add(_halvesRadio); + _halvesRadio.addItemListener(optionsChangedListener); + } dialogPanel.add(limitsPanel, BorderLayout.NORTH); @@ -203,6 +216,9 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction else if (_timeLimitRadio.isSelected()) { enabled = _limitHourField.getValue() > 0 || _limitMinField.getValue() > 0; } + else if (_halvesRadio != null && _halvesRadio.isSelected()) { + enabled = true; + } _okButton.setEnabled(enabled); // Also enable/disable the other fields @@ -245,6 +261,21 @@ public abstract class DistanceTimeLimitFunction extends GenericFunction return 0.0; } + /** + * @return selected distance limit in km, or 0.0 + */ + protected double getDistanceLimitKilometres() + { + return Distance.convertRadiansToDistance(getDistanceLimitRadians(), UnitSetLibrary.UNITS_KILOMETRES); + } + + /** + * @return true if "halves" option was selected + */ + protected boolean isHalvesSelected() { + return _halvesRadio != null && _halvesRadio.isSelected(); + } + /** * The dialog has been completed and OK pressed, so do the corresponding function */ diff --git a/src/tim/prune/function/DuplicatePoint.java b/src/tim/prune/function/DuplicatePoint.java index 341066a..7739092 100644 --- a/src/tim/prune/function/DuplicatePoint.java +++ b/src/tim/prune/function/DuplicatePoint.java @@ -30,7 +30,8 @@ public class DuplicatePoint extends GenericFunction public void begin() { DataPoint point = _app.getTrackInfo().getCurrentPoint(); - if (point != null) { + if (point != null) + { // Pass information back to App to complete function _app.createPoint(point.clonePoint()); } diff --git a/src/tim/prune/function/FullRangeDetails.java b/src/tim/prune/function/FullRangeDetails.java deleted file mode 100644 index 07ef39e..0000000 --- a/src/tim/prune/function/FullRangeDetails.java +++ /dev/null @@ -1,367 +0,0 @@ -package tim.prune.function; - -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; - -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import tim.prune.App; -import tim.prune.GenericFunction; -import tim.prune.I18nManager; -import tim.prune.config.Config; -import tim.prune.data.RangeStats; -import tim.prune.data.Selection; -import tim.prune.data.Unit; -import tim.prune.gui.DisplayUtils; -import tim.prune.gui.profile.SpeedData; - -/** - * Class to show the full range details in a separate popup - */ -public class FullRangeDetails extends GenericFunction -{ - /** Dialog */ - private JDialog _dialog = null; - /** Label for number of points */ - private JLabel _numPointsLabel = null; - /** Label for number of segments */ - private JLabel _numSegsLabel = null; - /** Label for the maximum speed */ - private JLabel _maxSpeedLabel = null; - - /** Label for heading of "total" column */ - private JLabel _colTotalLabel = null; - /** Label for heading of "segments" column */ - private JLabel _colSegmentsLabel = null; - /** Labels for distances */ - private JLabel _totalDistanceLabel = null, _movingDistanceLabel = null; - /** Labels for durations */ - private JLabel _totalDurationLabel = null, _movingDurationLabel = null; - /** Labels for climbs */ - private JLabel _totalClimbLabel = null, _movingClimbLabel = null; - /** Labels for descents */ - private JLabel _totalDescentLabel = null, _movingDescentLabel = null; - /** Labels for pace */ - private JLabel _totalPaceLabel = null, _movingPaceLabel = null; - /** Labels for gradient */ - private JLabel _totalGradientLabel = null, _movingGradientLabel = null; - /** Labels for speed */ - private JLabel _totalSpeedLabel, _movingSpeedLabel = null; - /** Labels for vertical speed */ - private JLabel _totalVertSpeedLabel, _movingVertSpeedLabel = null; - - - /** - * Constructor - * @param inApp App object - */ - public FullRangeDetails(App inApp) - { - super(inApp); - } - - /** Get the name key */ - public String getNameKey() { - return "function.fullrangedetails"; - } - - /** - * Begin the function - */ - public void begin() - { - if (_dialog == null) - { - _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - _dialog.getContentPane().add(makeDialogComponents()); - _dialog.pack(); - } - updateDetails(); - _dialog.setVisible(true); - } - - /** - * Create dialog components - * @return Panel containing all gui elements in dialog - */ - private Component makeDialogComponents() - { - JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BorderLayout(5, 5)); - // Label at top - JLabel topLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.intro") + ":"); - topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - dialogPanel.add(topLabel, BorderLayout.NORTH); - - // Details panel in middle - JPanel midPanel = new JPanel(); - midPanel.setLayout(new GridLayout(0, 3, 6, 2)); - midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); - // Number of points - JLabel pointsLabel = new JLabel(I18nManager.getText("details.track.points") + ": "); - pointsLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(pointsLabel); - _numPointsLabel = new JLabel("100"); - midPanel.add(_numPointsLabel); - midPanel.add(new JLabel(" ")); - // Number of segments - JLabel segLabel = new JLabel(I18nManager.getText("details.range.numsegments") + ": "); - segLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(segLabel); - _numSegsLabel = new JLabel("100"); - midPanel.add(_numSegsLabel); - midPanel.add(new JLabel(" ")); - // Maximum speed - JLabel maxSpeedLabel = new JLabel(I18nManager.getText("details.range.maxspeed") + ": "); - maxSpeedLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(maxSpeedLabel); - _maxSpeedLabel = new JLabel("10 km/h"); - midPanel.add(_maxSpeedLabel); - midPanel.add(new JLabel(" ")); - - // blank row - for (int i=0; i<3; i++) midPanel.add(new JLabel(" ")); - - // Row for column headings - midPanel.add(new JLabel(" ")); - _colTotalLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.coltotal")); - midPanel.add(_colTotalLabel); - _colSegmentsLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.colsegments")); - midPanel.add(_colSegmentsLabel); - - // Distance - JLabel distLabel = new JLabel(I18nManager.getText("fieldname.distance") + ": "); - distLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(distLabel); - _totalDistanceLabel = new JLabel("5 km"); - midPanel.add(_totalDistanceLabel); - _movingDistanceLabel = new JLabel("5 km"); - midPanel.add(_movingDistanceLabel); - - // Duration - JLabel durationLabel = new JLabel(I18nManager.getText("fieldname.duration") + ": "); - durationLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(durationLabel); - _totalDurationLabel = new JLabel("15 min"); - midPanel.add(_totalDurationLabel); - _movingDurationLabel = new JLabel("15 min"); - midPanel.add(_movingDurationLabel); - - // Speed - JLabel speedLabel = new JLabel(I18nManager.getText("details.range.avespeed") + ": "); - speedLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(speedLabel); - _totalSpeedLabel = new JLabel("5.5 km/h"); - midPanel.add(_totalSpeedLabel); - _movingSpeedLabel = new JLabel("5.5 km/h"); - midPanel.add(_movingSpeedLabel); - - // Pace - JLabel paceLabel = new JLabel(I18nManager.getText("details.range.pace") + ": "); - paceLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(paceLabel); - _totalPaceLabel = new JLabel("8 min/km"); - midPanel.add(_totalPaceLabel); - _movingPaceLabel = new JLabel("8 min/km"); - midPanel.add(_movingPaceLabel); - - // Climb - JLabel climbLabel = new JLabel(I18nManager.getText("details.range.climb") + ": "); - climbLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(climbLabel); - _totalClimbLabel = new JLabel("1000 m"); - midPanel.add(_totalClimbLabel); - _movingClimbLabel = new JLabel("1000 m"); - midPanel.add(_movingClimbLabel); - // Descent - JLabel descentLabel = new JLabel(I18nManager.getText("details.range.descent") + ": "); - descentLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(descentLabel); - _totalDescentLabel = new JLabel("1000 m"); - midPanel.add(_totalDescentLabel); - _movingDescentLabel = new JLabel("1000 m"); - midPanel.add(_movingDescentLabel); - - // Gradient - JLabel gradientLabel = new JLabel(I18nManager.getText("details.range.gradient") + ": "); - gradientLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(gradientLabel); - _totalGradientLabel = new JLabel("10 %"); - midPanel.add(_totalGradientLabel); - _movingGradientLabel = new JLabel("10 %"); - midPanel.add(_movingGradientLabel); - - // Vertical speed - JLabel vSpeedLabel = new JLabel(I18nManager.getText("fieldname.verticalspeed") + ": "); - vSpeedLabel.setHorizontalAlignment(JLabel.RIGHT); - midPanel.add(vSpeedLabel); - _totalVertSpeedLabel = new JLabel("1 m/s"); - midPanel.add(_totalVertSpeedLabel); - _movingVertSpeedLabel = new JLabel("1 m/s"); - midPanel.add(_movingVertSpeedLabel); - - dialogPanel.add(midPanel, BorderLayout.CENTER); - // button panel at bottom - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - JButton closeButton = new JButton(I18nManager.getText("button.close")); - closeButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) - { - _dialog.dispose(); - } - }); - closeButton.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent inE) { - if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();} - super.keyPressed(inE); - } - }); - buttonPanel.add(closeButton); - dialogPanel.add(buttonPanel, BorderLayout.SOUTH); - return dialogPanel; - } - - - /** - * Update the labels with the current details - */ - private void updateDetails() - { - Selection selection = _app.getTrackInfo().getSelection(); - // Do the calculations with a separate class - RangeStats stats = new RangeStats(_app.getTrackInfo().getTrack(), selection.getStart(), selection.getEnd()); - - // Number of points - _numPointsLabel.setText("" + stats.getNumPoints()); - // Number of segments - _numSegsLabel.setText("" + stats.getNumSegments()); - final boolean isMultiSegments = (stats.getNumSegments() > 1); - // Set visibility of third column accordingly - _movingDistanceLabel.setVisible(isMultiSegments); - _movingDurationLabel.setVisible(isMultiSegments || stats.getTimestampsOutOfSequence()); - // FIXME: What to show if timestamps are out of sequence? Warning message? - _movingClimbLabel.setVisible(isMultiSegments); - _movingDescentLabel.setVisible(isMultiSegments); - _movingSpeedLabel.setVisible(isMultiSegments); - _movingPaceLabel.setVisible(isMultiSegments); - _movingGradientLabel.setVisible(isMultiSegments); - _movingVertSpeedLabel.setVisible(isMultiSegments); - - // Total and moving distance in current units - final Unit distUnit = Config.getUnitSet().getDistanceUnit(); - final String distUnitsStr = I18nManager.getText(distUnit.getShortnameKey()); - _totalDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getTotalDistance()) + " " + distUnitsStr); - _movingDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getMovingDistance()) + " " + distUnitsStr); - - // Duration - _totalDurationLabel.setText(DisplayUtils.buildDurationString(stats.getTotalDurationInSeconds())); - _movingDurationLabel.setText(DisplayUtils.buildDurationString(stats.getMovingDurationInSeconds())); - - // Climb and descent - final Unit altUnit = Config.getUnitSet().getAltitudeUnit(); - final String altUnitsStr = " " + I18nManager.getText(altUnit.getShortnameKey()); - if (stats.getTotalAltitudeRange().hasRange()) { - _totalClimbLabel.setText(stats.getTotalAltitudeRange().getClimb(altUnit) + altUnitsStr); - _totalDescentLabel.setText(stats.getTotalAltitudeRange().getDescent(altUnit) + altUnitsStr); - } - else { - _totalClimbLabel.setText(""); - _totalDescentLabel.setText(""); - } - if (stats.getMovingAltitudeRange().hasRange()) { - _movingClimbLabel.setText(stats.getMovingAltitudeRange().getClimb(altUnit) + altUnitsStr); - _movingDescentLabel.setText(stats.getMovingAltitudeRange().getDescent(altUnit) + altUnitsStr); - } - else { - _movingClimbLabel.setText(""); - _movingDescentLabel.setText(""); - } - - // Overall pace and speed - final String speedUnitsStr = I18nManager.getText(Config.getUnitSet().getSpeedUnit().getShortnameKey()); - long numSecs = stats.getTotalDurationInSeconds(); - double dist = stats.getTotalDistance(); - if (numSecs > 0 && dist > 0) - { - _totalSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr); - _totalPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist)) - + " / " + distUnitsStr); - } - else { - _totalSpeedLabel.setText(""); - _totalPaceLabel.setText(""); - } - // and same for within the segments - numSecs = stats.getMovingDurationInSeconds(); - dist = stats.getMovingDistance(); - if (numSecs > 0 && dist > 0) - { - _movingSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr); - _movingPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist)) - + " / " + distUnitsStr); - } - else { - _movingSpeedLabel.setText(""); - _movingPaceLabel.setText(""); - } - - // Gradient - if (stats.getTotalAltitudeRange().hasRange()) { - _totalGradientLabel.setText(DisplayUtils.formatOneDp(stats.getTotalGradient()) + " %"); - } - else { - _totalGradientLabel.setText(""); - } - if (stats.getMovingAltitudeRange().hasRange()) { - _movingGradientLabel.setText(DisplayUtils.formatOneDp(stats.getMovingGradient()) + " %"); - } - else { - _movingGradientLabel.setText(""); - } - - // Maximum speed - SpeedData speeds = new SpeedData(_app.getTrackInfo().getTrack()); - speeds.init(Config.getUnitSet()); - double maxSpeed = 0.0; - for (int i=selection.getStart(); i<=selection.getEnd(); i++) - { - if (speeds.hasData(i) && (speeds.getData(i) > maxSpeed)) { - maxSpeed = speeds.getData(i); - } - } - if (maxSpeed > 0.0) { - _maxSpeedLabel.setText(DisplayUtils.roundedNumber(maxSpeed) + " " + speedUnitsStr); - } - else { - _maxSpeedLabel.setText(""); - } - - // vertical speed - final String vertSpeedUnitsStr = I18nManager.getText(Config.getUnitSet().getVerticalSpeedUnit().getShortnameKey()); - if (stats.getMovingAltitudeRange().hasRange() && stats.getTotalDurationInSeconds() > 0) - { - // got an altitude and time - do totals - _totalVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getTotalVerticalSpeed()) + " " + vertSpeedUnitsStr); - _movingVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getMovingVerticalSpeed()) + " " + vertSpeedUnitsStr); - } - else - { - // no vertical speed available - _totalVertSpeedLabel.setText(""); - _movingVertSpeedLabel.setText(""); - } - } -} diff --git a/src/tim/prune/function/InterpolateFunction.java b/src/tim/prune/function/InterpolateFunction.java index 221fdaf..ce0dad5 100644 --- a/src/tim/prune/function/InterpolateFunction.java +++ b/src/tim/prune/function/InterpolateFunction.java @@ -122,7 +122,8 @@ public class InterpolateFunction extends SingleNumericParameterFunction // Replace track with new points array if (track.replaceContents(newPoints)) { - _app.completeFunction(undo, I18nManager.getText("confirm.interpolate")); + final String confirmMessage = I18nManager.getTextWithNumber("confirm.pointsadded", totalInserted); + _app.completeFunction(undo, confirmMessage); // Alter selection _app.getTrackInfo().getSelection().selectRange(startIndex, endIndex + totalInserted); } diff --git a/src/tim/prune/function/PasteCoordinateList.java b/src/tim/prune/function/PasteCoordinateList.java new file mode 100644 index 0000000..9fc259e --- /dev/null +++ b/src/tim/prune/function/PasteCoordinateList.java @@ -0,0 +1,147 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +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 java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.load.TextFileLoader; + +/** + * Class to provide the function to paste a list of coordinates + * and create points for them as if they were loaded from a text file + */ +public class PasteCoordinateList extends GenericFunction +{ + private JDialog _dialog = null; + private JTextArea _coordArea = null; + private JButton _okButton = null; + + + /** + * Constructor + * @param inApp application object for callback + */ + public PasteCoordinateList(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.pastecoordinatelist"; + } + + /** + * Begin the function + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // MAYBE: Paste clipboard into the edit area + _coordArea.setText(""); + enableOK(); + _dialog.setVisible(true); + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(0, 10)); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.pastecoordinatelist.desc")), BorderLayout.NORTH); + _coordArea = new JTextArea(8, 35); + _coordArea.setLineWrap(true); + _coordArea.setWrapStyleWord(true); + JScrollPane coordsPane = new JScrollPane(_coordArea); + // Listeners to enable/disable ok button + KeyAdapter keyListener = new KeyAdapter() { + /** Key released */ + public void keyReleased(KeyEvent inE) { + enableOK(); + if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + MouseAdapter mouseListener = new MouseAdapter() { + public void mouseReleased(MouseEvent inE) { + enableOK(); + } + }; + _coordArea.addKeyListener(keyListener); + _coordArea.addMouseListener(mouseListener); + dialogPanel.add(coordsPane, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + if (_okButton.isEnabled()) {finish();} + } + }; + _okButton.addActionListener(okListener); + _okButton.setEnabled(false); + 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; + } + + /** + * Enable or disable the OK button based on the contents of the text field + */ + private void enableOK() + { + String text = _coordArea.getText(); + _okButton.setEnabled(text != null && text.length() > 6 + && (text.indexOf(' ') >= 0 || text.indexOf(',') >= 0)); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + new TextFileLoader(_app, _parentFrame).loadText(_coordArea.getText()); + _dialog.dispose(); + } +} diff --git a/src/tim/prune/function/PasteCoordinates.java b/src/tim/prune/function/PasteCoordinates.java index c9b2ad1..c60bb85 100644 --- a/src/tim/prune/function/PasteCoordinates.java +++ b/src/tim/prune/function/PasteCoordinates.java @@ -183,7 +183,8 @@ public class PasteCoordinates extends GenericFunction else if (items.length == 3) { point = parseValues(items[0].trim(), items[1].trim(), items[2].trim()); } - else { + else + { // Splitting with commas didn't work, so try spaces items = _coordField.getText().split(" "); if (items.length == 2) { @@ -211,7 +212,8 @@ public class PasteCoordinates extends GenericFunction I18nManager.getText("dialog.pastecoordinates.nothingfound"), I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); } - else { + else + { // See if name was entered String name = _nameField.getText(); if (name != null && name.length() > 0) { diff --git a/src/tim/prune/function/PlayAudioFunction.java b/src/tim/prune/function/PlayAudioFunction.java index 2ac71e9..44b77d9 100644 --- a/src/tim/prune/function/PlayAudioFunction.java +++ b/src/tim/prune/function/PlayAudioFunction.java @@ -1,11 +1,11 @@ package tim.prune.function; +import java.awt.Desktop; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; @@ -146,17 +146,10 @@ public class PlayAudioFunction extends GenericFunction implements Runnable { try { - Class d = Class.forName("java.awt.Desktop"); - d.getDeclaredMethod("open", new Class[] {File.class}).invoke( - d.getDeclaredMethod("getDesktop").invoke(null), new Object[] {inFile}); - //above code mimics: Desktop.getDesktop().open(audioFile); + Desktop.getDesktop().open(inFile); played = true; } - catch (InvocationTargetException e) { - System.err.println("ITE: " + e.getCause().getClass().getName() + " - " + e.getCause().getMessage()); - played = false; - } - catch (Exception ignore) { + catch (IOException ignore) { System.err.println(ignore.getClass().getName() + " - " + ignore.getMessage()); played = false; } diff --git a/src/tim/prune/function/PlusCodeFunction.java b/src/tim/prune/function/PlusCodeFunction.java new file mode 100644 index 0000000..b208b7f --- /dev/null +++ b/src/tim/prune/function/PlusCodeFunction.java @@ -0,0 +1,209 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +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 java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.data.Field; +import tim.prune.function.olc.OlcArea; +import tim.prune.function.olc.OlcDecoder; +import tim.prune.gui.GuiGridLayout; + +/** + * Class to provide the function to parse + * OpenLocationCodes, or PlusCodes + */ +public class PlusCodeFunction extends GenericFunction +{ + private JDialog _dialog = null; + private JTextField _codeField = null; + private JButton _okButton = null; + + + /** + * Constructor + * @param inApp application object for callback + */ + public PlusCodeFunction(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.enterpluscode"; + } + + /** + * Begin the function + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + // MAYBE: Paste clipboard into the edit field + _codeField.setText(""); + enableOK(); + _dialog.setVisible(true); + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(0, 10)); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.pluscode.desc")), BorderLayout.NORTH); + JPanel mainPanel = new JPanel(); + GuiGridLayout grid = new GuiGridLayout(mainPanel); + _codeField = new JTextField("", 12); + // Listeners to enable/disable ok button + KeyAdapter keyListener = new KeyAdapter() { + /** Key released */ + public void keyReleased(KeyEvent inE) { + enableOK(); + if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + MouseAdapter mouseListener = new MouseAdapter() { + public void mouseReleased(MouseEvent inE) { + enableOK(); + } + }; + _codeField.addKeyListener(keyListener); + _codeField.addMouseListener(mouseListener); + JLabel codeLabel = new JLabel(I18nManager.getText("dialog.pluscode.code")); + codeLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(codeLabel); + grid.add(_codeField); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + if (_okButton.isEnabled()) {finish();} + } + }; + _okButton.addActionListener(okListener); + _okButton.setEnabled(false); + _codeField.addActionListener(okListener); + 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; + } + + /** + * Enable or disable the OK button based on the contents of the text field + */ + private void enableOK() + { + String text = _codeField.getText(); + _okButton.setEnabled(text != null && text.length() > 7 + && text.indexOf(' ') < 0 && text.indexOf(',') < 0); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + OlcArea area = OlcDecoder.decode(_codeField.getText()); + + if (area == null) + { + JOptionPane.showMessageDialog(_parentFrame, + I18nManager.getText("dialog.pluscode.nothingfound"), + I18nManager.getText(getNameKey()), JOptionPane.ERROR_MESSAGE); + } + else if (loadTrack(area)) + { + _dialog.dispose(); + } + } + + /** + * Load the generated points from the given area + * @param inArea rectangular area + * @return true on success + */ + private boolean loadTrack(OlcArea inArea) + { + if (inArea == null) + { + return false; + } + + final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.WAYPT_NAME}; + _app.autoAppendNextFile(); + + if (inArea.minLat == inArea.maxLat && inArea.minLon == inArea.maxLon) + { + String[][] pointData = new String[1][]; + pointData[0] = new String[3]; // lat, long, name + pointData[0][0] = "" + inArea.minLat; + pointData[0][1] = "" + inArea.minLon; + pointData[0][2] = _codeField.getText(); + _app.informDataLoaded(fields, pointData, null, null); + } + else + { + String[][] pointData = new String[6][]; + for (int i=0; i<5; i++) + { + pointData[i] = new String[3]; // lat, long, name + pointData[i][0] = "" + ((i%4==0 || i==3) ? inArea.minLat : inArea.maxLat); + pointData[i][1] = "" + ((i%4==0 || i==1) ? inArea.minLon : inArea.maxLon); + pointData[i][2] = null; + } + // Middle point with name + pointData[5] = new String[3]; // lat, long, name + pointData[5][0] = "" + ((inArea.minLat + inArea.maxLat) / 2.0); + pointData[5][1] = "" + ((inArea.minLon + inArea.maxLon) / 2.0); + pointData[5][2] = _codeField.getText(); + _app.informDataLoaded(fields, pointData, null, null); + } + return true; + } +} diff --git a/src/tim/prune/function/ProjectPoint.java b/src/tim/prune/function/ProjectPoint.java new file mode 100644 index 0000000..10c0675 --- /dev/null +++ b/src/tim/prune/function/ProjectPoint.java @@ -0,0 +1,225 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +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 java.awt.event.MouseEvent; + +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 javax.swing.SwingConstants; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.data.Coordinate; +import tim.prune.data.DataPoint; +import tim.prune.data.Distance; +import tim.prune.data.Field; +import tim.prune.data.Latitude; +import tim.prune.data.Longitude; +import tim.prune.data.Unit; +import tim.prune.data.UnitSetLibrary; +import tim.prune.gui.DecimalNumberField; +import tim.prune.gui.GuiGridLayout; +import tim.prune.gui.WholeNumberField; + + +/** + * Class to provide the function to project the current point + * with a given bearing and distance + */ +public class ProjectPoint extends GenericFunction +{ + private JDialog _dialog = null; + private WholeNumberField _bearingField = null; + private JLabel _distanceDescLabel = null; + private DecimalNumberField _distanceField = null; + private boolean _distanceIsMetric = true; + private JTextField _nameField = null; + private JButton _okButton = null; + + + /** + * Constructor + * @param inApp application object for callback + */ + public ProjectPoint(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.projectpoint"; + } + + /** + * Begin the function + */ + public void begin() + { + // Make dialog window + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + + // Clear fields + _bearingField.setText(""); + _distanceField.setText(""); + _nameField.setText(""); + // Set the units of the distance label + setLabelText(); + enableOK(); + _dialog.setVisible(true); + } + + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel dialogPanel = new JPanel(); + dialogPanel.setLayout(new BorderLayout(0, 10)); + dialogPanel.add(new JLabel(I18nManager.getText("dialog.projectpoint.desc")), BorderLayout.NORTH); + JPanel mainPanel = new JPanel(); + GuiGridLayout grid = new GuiGridLayout(mainPanel); + _bearingField = new WholeNumberField(3); + _distanceField = new DecimalNumberField(false); + // Listeners to enable/disable ok button + KeyAdapter keyListener = new KeyAdapter() { + /** Key released */ + public void keyReleased(KeyEvent inE) { + enableOK(); + if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) { + _dialog.dispose(); + } + } + }; + MouseAdapter mouseListener = new MouseAdapter() { + public void mouseReleased(MouseEvent inE) { + enableOK(); + } + }; + _bearingField.addKeyListener(keyListener); + _bearingField.addMouseListener(mouseListener); + _distanceField.addKeyListener(keyListener); + _distanceField.addMouseListener(mouseListener); + + JLabel bearingLabel = new JLabel(I18nManager.getText("dialog.projectpoint.bearing")); + bearingLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(bearingLabel); + grid.add(_bearingField); + + // Distance including units + _distanceDescLabel = new JLabel(I18nManager.getText("fieldname.distance") + " (ft)"); + // Note, this label will be reset at each run + _distanceDescLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(_distanceDescLabel); + grid.add(_distanceField); + + // Waypoint name + JLabel nameLabel = new JLabel(I18nManager.getText("dialog.pointnameedit.name")); + nameLabel.setHorizontalAlignment(SwingConstants.RIGHT); + grid.add(nameLabel); + _nameField = new JTextField("", 12); + grid.add(_nameField); + dialogPanel.add(mainPanel, BorderLayout.CENTER); + // button panel at bottom + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + _okButton = new JButton(I18nManager.getText("button.ok")); + ActionListener okListener = new ActionListener() { + public void actionPerformed(ActionEvent e) + { + if (_okButton.isEnabled()) {finish();} + } + }; + _okButton.addActionListener(okListener); + _okButton.setEnabled(false); + + 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; + } + + /** + * Set the label text according to the current units + */ + private void setLabelText() + { + Unit distUnit = Config.getUnitSet().getDistanceUnit(); + _distanceIsMetric = (distUnit == UnitSetLibrary.UNITS_METRES || distUnit == UnitSetLibrary.UNITS_KILOMETRES); + distUnit = _distanceIsMetric ? UnitSetLibrary.UNITS_METRES : UnitSetLibrary.UNITS_FEET; + final String unitKey = distUnit.getShortnameKey(); + _distanceDescLabel.setText(I18nManager.getText("fieldname.distance") + " (" + I18nManager.getText(unitKey) + ")"); + } + + /** + * Enable or disable the OK button based on the contents of the input fields + */ + private void enableOK() + { + final boolean bearingOk = !_bearingField.getText().isEmpty() + && _bearingField.getValue() < 360; + final boolean distanceOk = _distanceField.getValue() > 0.0; + _okButton.setEnabled(bearingOk && distanceOk); + } + + /** + * Finish the dialog when OK pressed + */ + private void finish() + { + DataPoint currPoint = _app.getTrackInfo().getCurrentPoint(); + Unit distUnit = _distanceIsMetric ? UnitSetLibrary.UNITS_METRES : UnitSetLibrary.UNITS_FEET; + final double projectRads = Distance.convertDistanceToRadians(_distanceField.getValue(), distUnit); + final double origLatRads = Math.toRadians(currPoint.getLatitude().getDouble()); + final double origLonRads = Math.toRadians(currPoint.getLongitude().getDouble()); + System.out.println("Project from: " + origLatRads + ", " + origLonRads); + final double bearingRads = Math.toRadians(_bearingField.getValue()); + + double lat2 = Math.asin(Math.sin(origLatRads) * Math.cos(projectRads) + + Math.cos(origLatRads) * Math.sin(projectRads) * Math.cos(bearingRads)); + double lon2 = origLonRads + Math.atan2(Math.sin(bearingRads) * Math.sin(projectRads) * Math.cos(origLatRads), + Math.cos(projectRads) - Math.sin(origLatRads) * Math.sin(lat2)); + + double finalLatDeg = Math.toDegrees(lat2); + double finalLonDeg = Math.toDegrees(lon2); + System.out.println("Result is: lat=" + finalLatDeg + ", lon=" + finalLonDeg); + + // Create point and append to track + DataPoint point = new DataPoint(new Latitude(finalLatDeg, Coordinate.FORMAT_DEG), + new Longitude(finalLonDeg, Coordinate.FORMAT_DEG), null); + point.setFieldValue(Field.WAYPT_NAME, _nameField.getText(), false); + _app.createPoint(point); + + _dialog.dispose(); + } +} diff --git a/src/tim/prune/function/RearrangeWaypointsFunction.java b/src/tim/prune/function/RearrangeWaypointsFunction.java index 17e9370..c62b130 100644 --- a/src/tim/prune/function/RearrangeWaypointsFunction.java +++ b/src/tim/prune/function/RearrangeWaypointsFunction.java @@ -119,7 +119,7 @@ public class RearrangeWaypointsFunction extends RearrangeFunction // Exit if the data is already in the specified order final boolean wpsToStart = (inRearrangeOption == Rearrange.TO_START); final boolean doSort = (inSortOption != SortMode.DONT_SORT); - if (numWaypoints == 0 || numNonWaypoints == 0 + if (numWaypoints == 0 || (wpsToStart && !wayAfterNon && nonAfterWay && !doSort) || (!wpsToStart && wayAfterNon && !nonAfterWay && !doSort) || inRearrangeOption == Rearrange.TO_NEAREST) diff --git a/src/tim/prune/function/SearchOpenCachingDeFunction.java b/src/tim/prune/function/SearchOpenCachingDeFunction.java index 20e2fc8..39df30a 100644 --- a/src/tim/prune/function/SearchOpenCachingDeFunction.java +++ b/src/tim/prune/function/SearchOpenCachingDeFunction.java @@ -84,7 +84,7 @@ public class SearchOpenCachingDeFunction extends GenericDownloaderFunction private void submitSearch(double inLat, double inLon) { // The only parameters are lat and long from the current point - String urlString = "http://opencaching.de/search.php?searchto=searchbydistance&showresult=1" + String urlString = "https://opencaching.de/search.php?searchto=searchbydistance&showresult=1" + "&output=XML&sort=bydistance&lat=" + inLat + "&lon=" + inLon + "&distance=" + MAX_DISTANCE + "&unit=km"; // Parse the returned XML with a special handler diff --git a/src/tim/prune/function/ShowFullDetails.java b/src/tim/prune/function/ShowFullDetails.java new file mode 100644 index 0000000..8f8289e --- /dev/null +++ b/src/tim/prune/function/ShowFullDetails.java @@ -0,0 +1,417 @@ +package tim.prune.function; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.TimeZone; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTextArea; + +import tim.prune.App; +import tim.prune.GenericFunction; +import tim.prune.I18nManager; +import tim.prune.config.Config; +import tim.prune.config.TimezoneHelper; +import tim.prune.data.AltitudeRange; +import tim.prune.data.AudioClip; +import tim.prune.data.Coordinate; +import tim.prune.data.DataPoint; +import tim.prune.data.Field; +import tim.prune.data.Photo; +import tim.prune.data.RangeStatsWithGradients; +import tim.prune.data.Selection; +import tim.prune.data.SpeedCalculator; +import tim.prune.data.SpeedValue; +import tim.prune.data.Track; +import tim.prune.data.Unit; +import tim.prune.data.UnitSet; +import tim.prune.gui.CoordDisplay; +import tim.prune.gui.DisplayUtils; + + +/** + * Class to show the full point/range details in a separate popup + */ +public class ShowFullDetails extends GenericFunction +{ + private JDialog _dialog = null; + private JTabbedPane _tabs = null; + private JButton _okButton = null; + + private JTextArea _pointTextArea = null; + private JTextArea _rangeTextArea = null; + + + /** + * Constructor + * @param inApp App object + */ + public ShowFullDetails(App inApp) + { + super(inApp); + } + + /** Get the name key */ + public String getNameKey() { + return "function.viewfulldetails"; + } + + /** + * Begin the function + */ + public void begin() + { + if (_dialog == null) + { + _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + _dialog.getContentPane().add(makeDialogComponents()); + _dialog.pack(); + } + updateDetails(); + _dialog.setVisible(true); + _okButton.requestFocus(); + } + + /** + * Create dialog components + * @return Panel containing all gui elements in dialog + */ + private Component makeDialogComponents() + { + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + + _tabs = new JTabbedPane(); + mainPanel.add(_tabs, BorderLayout.CENTER); + + JPanel pointPanel = new JPanel(); + pointPanel.setLayout(new BorderLayout()); + _pointTextArea = new JTextArea(I18nManager.getText("details.nopointselection")); + _pointTextArea.setEditable(false); + _pointTextArea.setLineWrap(true); + JScrollPane scrollPane = new JScrollPane(_pointTextArea); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setPreferredSize(new Dimension(500, 230)); + pointPanel.add(scrollPane, BorderLayout.CENTER); + _tabs.add(I18nManager.getText("details.pointdetails"), pointPanel); + + JPanel rangePanel = new JPanel(); + rangePanel.setLayout(new BorderLayout()); + _rangeTextArea = new JTextArea(I18nManager.getText("details.norangeselection")); + _rangeTextArea.setEditable(false); + _rangeTextArea.setLineWrap(true); + JScrollPane scrollPane2 = new JScrollPane(_rangeTextArea); + scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane2.setPreferredSize(new Dimension(500, 230)); + rangePanel.add(scrollPane2, BorderLayout.CENTER); + _tabs.add(I18nManager.getText("details.rangedetails"), rangePanel); + + // OK button at the bottom + JPanel okPanel = new JPanel(); + okPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + _okButton = new JButton(I18nManager.getText("button.ok")); + _okButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + _dialog.dispose(); + } + }); + _okButton.addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();} + } + public void keyTyped(KeyEvent e) {} + public void keyReleased(KeyEvent e) {} + }); + okPanel.add(_okButton); + mainPanel.add(okPanel, BorderLayout.SOUTH); + return mainPanel; + } + + + /** + * Update the labels with the current details + */ + private void updateDetails() + { + if (_app.getTrackInfo().getCurrentPoint() != null) + { + final String pointString = makePointDescription(_app.getTrackInfo().getTrack(), + _app.getTrackInfo().getSelection().getCurrentPointIndex()); + _pointTextArea.setText(pointString); + // Select point tab + _tabs.setSelectedIndex(0); + } + else + { + _pointTextArea.setText(I18nManager.getText("details.nopointselection")); + // Select range tab + _tabs.setSelectedIndex(1); + } + + Selection selection = _app.getTrackInfo().getSelection(); + if (selection.hasRangeSelected()) + { + RangeStatsWithGradients stats = new RangeStatsWithGradients(_app.getTrackInfo().getTrack(), + selection.getStart(), selection.getEnd()); + SpeedValue maxSpeed = calculateMaxSpeed(_app.getTrackInfo().getTrack(), + selection.getStart(), selection.getEnd()); + _rangeTextArea.setText(makeRangeDescription(stats, maxSpeed)); + } + else + { + _rangeTextArea.setText(I18nManager.getText("details.norangeselection")); + } + } + + /** + * Calculate the maximum horizontal speed value in the given selection + * @param inTrack track object + * @param inStartIndex start of selection + * @param inEndIndex end of selection + * @return max speed, if any + */ + private static SpeedValue calculateMaxSpeed(Track inTrack, int inStartIndex, int inEndIndex) + { + SpeedValue maxSpeed = new SpeedValue(); + SpeedValue currSpeed = new SpeedValue(); + for (int i=inStartIndex; i<=inEndIndex; i++) + { + SpeedCalculator.calculateSpeed(inTrack, i, currSpeed); + if (currSpeed.isValid() && (!maxSpeed.isValid() || currSpeed.getValue() > maxSpeed.getValue())) + { + maxSpeed.setValue(currSpeed.getValue()); + } + } + return maxSpeed; + } + + /** + * @param inTrack current track + * @param inPointIndex current point index + * @return string describing point details + */ + private static String makePointDescription(Track inTrack, int inPointIndex) + { + DataPoint point = inTrack.getPoint(inPointIndex); + if (point == null) + { + return ""; + } + + final int coordDisplayFormat = Coordinate.getCoordinateFormatForDisplay( + Config.getConfigInt(Config.KEY_COORD_DISPLAY_FORMAT)); + StringBuffer result = new StringBuffer(); + final String latStr = CoordDisplay.makeCoordinateLabel(point.getLatitude(), coordDisplayFormat); + final String lonStr = CoordDisplay.makeCoordinateLabel(point.getLongitude(), coordDisplayFormat); + addTextPair(result, "fieldname.latitude", latStr); + addTextPair(result, "fieldname.longitude", lonStr); + addTextPair(result, "fieldname.coordinates", latStr + ", " + lonStr); + + if (point.hasAltitude()) + { + final Unit altUnit = Config.getUnitSet().getAltitudeUnit(); + addTextPair(result, "fieldname.altitude", "" + point.getAltitude().getValue(altUnit), + I18nManager.getText(altUnit.getShortnameKey())); + } + if (point.hasTimestamp()) + { + TimeZone timezone = TimezoneHelper.getSelectedTimezone(); + addTextPair(result, "fieldname.date", point.getTimestamp().getDateText(timezone)); + addTextPair(result, "fieldname.timestamp", point.getTimestamp().getTimeText(timezone)); + } + + addTextPair(result, "fieldname.waypointname", point.getWaypointName()); + + addTextPair(result, "fieldname.description", point.getFieldValue(Field.DESCRIPTION)); + + addTextPair(result, "fieldname.waypointtype", point.getFieldValue(Field.WAYPT_TYPE)); + + // Speed can come from either timestamps and distances, or speed values in data + SpeedValue speedValue = new SpeedValue(); + SpeedCalculator.calculateSpeed(inTrack, inPointIndex, speedValue); + UnitSet unitSet = Config.getUnitSet(); + if (speedValue.isValid()) + { + final String speedUnitsStr = I18nManager.getText(unitSet.getSpeedUnit().getShortnameKey()); + String speed = DisplayUtils.roundedNumber(speedValue.getValue()); + addTextPair(result, "fieldname.speed", speed, speedUnitsStr); + } + + // Now do the vertical speed in the same way + SpeedCalculator.calculateVerticalSpeed(inTrack, inPointIndex, speedValue); + if (speedValue.isValid()) + { + final String vSpeedUnitsStr = I18nManager.getText(unitSet.getVerticalSpeedUnit().getShortnameKey()); + String speed = DisplayUtils.roundedNumber(speedValue.getValue()); + addTextPair(result, "fieldname.verticalspeed", speed, vSpeedUnitsStr); + } + + Photo currentPhoto = point.getPhoto(); + if (currentPhoto != null) + { + addTextPair(result, "details.photofile", currentPhoto.getName()); + addTextPair(result, "details.media.fullpath", currentPhoto.getFullPath()); + } + + AudioClip currentAudio = point.getAudio(); + if (currentAudio != null) + { + addTextPair(result, "details.audio.file", currentAudio.getName()); + addTextPair(result, "details.media.fullpath", currentAudio.getFullPath()); + } + + return result.toString(); + } + + /** + * Make the range description text + * @param inStats stats object + * @param inMaxSpeed maximum speed info + * @return string describing range + */ + private static String makeRangeDescription(RangeStatsWithGradients inStats, SpeedValue inMaxSpeed) + { + StringBuffer result = new StringBuffer(); + addTextPair(result, "details.track.points", "" + inStats.getNumPoints()); + addTextPair(result, "details.range.numsegments", "" + inStats.getNumSegments()); + final boolean hasMultipleSegments = (inStats.getNumSegments() > 1); + + UnitSet unitSet = Config.getUnitSet(); + final String speedUnitsStr = I18nManager.getText(unitSet.getSpeedUnit().getShortnameKey()); + if (inMaxSpeed.isValid()) + { + final String maxSpeedStr = DisplayUtils.roundedNumber(inMaxSpeed.getValue()) + " " + speedUnitsStr; + addTextPair(result, "details.range.maxspeed", maxSpeedStr); + } + + addHeading(result, "dialog.fullrangedetails.colsegments"); + final Unit distUnit = Config.getUnitSet().getDistanceUnit(); + final String distUnitsStr = I18nManager.getText(distUnit.getShortnameKey()); + final double movingDist = inStats.getMovingDistance(); + addTextPair(result, "fieldname.distance", DisplayUtils.roundedNumber(movingDist), + distUnitsStr); + long numSecs = inStats.getMovingDurationInSeconds(); + addTextPair(result, "fieldname.duration", DisplayUtils.buildDurationString(numSecs)); + + if (numSecs > 0 && movingDist > 0.0) + { + addTextPair(result, "details.range.avespeed", DisplayUtils.roundedNumber(movingDist/numSecs*3600.0), + speedUnitsStr); + addTextPair(result, "details.range.pace", DisplayUtils.buildDurationString((long) (numSecs/movingDist)), + "/ " + distUnitsStr); + } + final Unit altUnit = unitSet.getAltitudeUnit(); + final String altUnitsStr = I18nManager.getText(altUnit.getShortnameKey()); + if (inStats.getMovingAltitudeRange().hasRange()) + { + AltitudeRange altRange = inStats.getMovingAltitudeRange(); + addTextPair(result, "fieldname.altitude", "" + altRange.getMinimum(altUnit) + altUnitsStr + " " + + I18nManager.getText("details.altitude.to") + " " + + altRange.getMaximum(altUnit) + altUnitsStr); + addTextPair(result, "details.range.climb", "" + altRange.getClimb(altUnit), altUnitsStr); + addTextPair(result, "details.range.descent", "" + altRange.getDescent(altUnit), altUnitsStr); + addTextPair(result, "details.range.gradient", DisplayUtils.formatOneDp(inStats.getMovingGradient()), "%"); + if (numSecs > 0) + { + final String vertSpeedUnitsStr = I18nManager.getText(unitSet.getVerticalSpeedUnit().getShortnameKey()); + final String vertSpeedStr = DisplayUtils.roundedNumber(inStats.getMovingVerticalSpeed()); + addTextPair(result, "fieldname.verticalspeed", vertSpeedStr, vertSpeedUnitsStr); + } + } + + if (hasMultipleSegments) + { + addHeading(result, "dialog.fullrangedetails.coltotal"); + final double totalDist = inStats.getTotalDistance(); + addTextPair(result, "fieldname.distance", DisplayUtils.roundedNumber(totalDist), distUnitsStr); + long totalSecs = inStats.getTotalDurationInSeconds(); + addTextPair(result, "fieldname.duration", DisplayUtils.buildDurationString(totalSecs)); + if (totalSecs > 0 && totalDist > 0.0) + { + addTextPair(result, "details.range.avespeed", DisplayUtils.roundedNumber(totalDist/totalSecs*3600.0), + speedUnitsStr); + addTextPair(result, "details.range.pace", DisplayUtils.buildDurationString((long) (totalSecs/totalDist)), + "/ " + distUnitsStr); + } + if (inStats.getTotalAltitudeRange().hasRange()) + { + AltitudeRange altRange = inStats.getTotalAltitudeRange(); + addTextPair(result, "details.range.climb", "" + altRange.getClimb(altUnit), altUnitsStr); + addTextPair(result, "details.range.descent", "" + altRange.getDescent(altUnit), altUnitsStr); + addTextPair(result, "details.range.gradient", DisplayUtils.formatOneDp(inStats.getTotalGradient()), "%"); + if (totalSecs > 0) + { + final String vertSpeedUnitsStr = I18nManager.getText(unitSet.getVerticalSpeedUnit().getShortnameKey()); + final String vertSpeedStr = DisplayUtils.roundedNumber(inStats.getTotalVerticalSpeed()); + addTextPair(result, "fieldname.verticalspeed", vertSpeedStr, vertSpeedUnitsStr); + } + } + } + return result.toString(); + } + + /** + * Add the label and value to the buffer + * @param inBuffer buffer to append to + * @param inLabelKey label key + * @param inValue value text + */ + private static void addTextPair(StringBuffer inBuffer, String inLabelKey, String inValue) + { + addTextPair(inBuffer, inLabelKey, inValue, null); + } + + /** + * Add the label and value to the buffer + * @param inBuffer buffer to append to + * @param inLabelKey label key + * @param inValue value text + * @param inUnits optional units string + */ + private static void addTextPair(StringBuffer inBuffer, String inLabelKey, String inValue, String inUnits) + { + if (inValue != null && !inValue.equals("")) + { + inBuffer.append(I18nManager.getText(inLabelKey)); + inBuffer.append(": "); + inBuffer.append(inValue); + if (inUnits != null && !inUnits.equals("")) + { + inBuffer.append(' '); + inBuffer.append(inUnits); + } + inBuffer.append("\n"); + } + } + + /** + * Add a heading to the buffer + * @param inBuffer buffer to append to + * @param inLabelKey key for heading + */ + private static void addHeading(StringBuffer inBuffer, String inLabelKey) + { + final String heading = I18nManager.getText(inLabelKey); + inBuffer.append('\n').append(heading).append('\n'); + for (int i=0; i d = Class.forName("javax.swing.JTable"); - d.getDeclaredMethod("setAutoCreateRowSorter", new Class[]{Boolean.TYPE}).invoke(distTable, Boolean.TRUE); - } - catch (Exception e) {} + distTable.setAutoCreateRowSorter(true); scrollPane = new JScrollPane(distTable); scrollPane.setPreferredSize(new Dimension(200, 250)); mainPanel.add(scrollPane); diff --git a/src/tim/prune/function/distance/DistanceTableModel.java b/src/tim/prune/function/distance/DistanceTableModel.java index 2c1d83d..b0340b9 100644 --- a/src/tim/prune/function/distance/DistanceTableModel.java +++ b/src/tim/prune/function/distance/DistanceTableModel.java @@ -37,7 +37,7 @@ public class DistanceTableModel extends GenericTableModel { if (inColumnIndex == 0) {return getPointName(inRowIndex);} if (_distances == null) {return 0.0;} - return new Double(_distances[inRowIndex]); + return Double.valueOf(_distances[inRowIndex]); } /** diff --git a/src/tim/prune/function/estimate/EstimateTime.java b/src/tim/prune/function/estimate/EstimateTime.java index ef69793..8caad11 100644 --- a/src/tim/prune/function/estimate/EstimateTime.java +++ b/src/tim/prune/function/estimate/EstimateTime.java @@ -23,7 +23,7 @@ import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.config.Config; -import tim.prune.data.RangeStats; +import tim.prune.data.RangeStatsWithGradients; import tim.prune.data.Selection; import tim.prune.data.Unit; import tim.prune.gui.DecimalNumberField; @@ -54,7 +54,7 @@ public class EstimateTime extends GenericFunction private JLabel _descentParamLabel = null; private DecimalNumberField _gentleDescentField = null, _steepDescentField = null; /** Range stats */ - private RangeStats _stats = null; + private RangeStatsWithGradients _stats = null; /** @@ -78,7 +78,8 @@ public class EstimateTime extends GenericFunction { // Get the stats on the selection before launching the dialog Selection selection = _app.getTrackInfo().getSelection(); - _stats = new RangeStats(_app.getTrackInfo().getTrack(), selection.getStart(), selection.getEnd()); + _stats = new RangeStatsWithGradients(_app.getTrackInfo().getTrack(), + selection.getStart(), selection.getEnd()); if (_stats.getMovingDistance() < 0.01) { @@ -297,7 +298,11 @@ public class EstimateTime extends GenericFunction EstimationParameters estParams = new EstimationParameters(Config.getConfigString(Config.KEY_ESTIMATION_PARAMS)); String[] paramValues = estParams.getStrings(); - if (paramValues == null || paramValues.length != 5) {return;} // TODO: What to do in case of error? + if (paramValues == null || paramValues.length != 5) + { + // TODO: What to do in case of error? + return; + } // Flat time is either for 5 km, 3 miles or 3 nm _flatSpeedLabel.setText(I18nManager.getText("dialog.estimatetime.parameters.timefor") + " " + EstimationParameters.getStandardDistance() + ": "); diff --git a/src/tim/prune/function/estimate/EstimationParameters.java b/src/tim/prune/function/estimate/EstimationParameters.java index 1b80467..afe5938 100644 --- a/src/tim/prune/function/estimate/EstimationParameters.java +++ b/src/tim/prune/function/estimate/EstimationParameters.java @@ -6,7 +6,7 @@ import java.util.Locale; import tim.prune.I18nManager; import tim.prune.config.Config; -import tim.prune.data.RangeStats; +import tim.prune.data.RangeStatsWithGradients; import tim.prune.data.Unit; import tim.prune.data.UnitSetLibrary; @@ -254,9 +254,11 @@ public class EstimationParameters * @param inStats stats of current range * @return estimated number of minutes required */ - public double applyToStats(RangeStats inStats) + public double applyToStats(RangeStatsWithGradients inStats) { - if (inStats == null || !inStats.isValid()) return 0.0; + if (inStats == null) { + return 0.0; + } final Unit METRES = UnitSetLibrary.UNITS_METRES; final double STANDARD_CLIMB = 100.0; // metres final double STANDARD_DISTANCE = 5.0; // kilometres diff --git a/src/tim/prune/function/estimate/LearnParameters.java b/src/tim/prune/function/estimate/LearnParameters.java index 74021dd..3efaa2f 100644 --- a/src/tim/prune/function/estimate/LearnParameters.java +++ b/src/tim/prune/function/estimate/LearnParameters.java @@ -26,7 +26,7 @@ import tim.prune.I18nManager; import tim.prune.config.Config; import tim.prune.data.DataPoint; import tim.prune.data.Distance; -import tim.prune.data.RangeStats; +import tim.prune.data.RangeStatsWithGradients; import tim.prune.data.Track; import tim.prune.data.Unit; import tim.prune.data.UnitSetLibrary; @@ -100,7 +100,7 @@ public class LearnParameters extends GenericFunction implements Runnable { _progress.setMaximum(100); // Go through the track and collect the range stats for each sample - ArrayList statsList = new ArrayList(20); + ArrayList statsList = new ArrayList(20); Track track = _app.getTrackInfo().getTrack(); final int numPoints = track.getNumPoints(); final int sampleSize = numPoints / 30; @@ -108,15 +108,15 @@ public class LearnParameters extends GenericFunction implements Runnable for (int i=0; i<30; i++) { int startIndex = i * sampleSize; - RangeStats stats = getRangeStats(track, startIndex, startIndex + sampleSize, prevStartIndex); + RangeStatsWithGradients stats = getRangeStats(track, startIndex, startIndex + sampleSize, prevStartIndex); if (stats != null && stats.getMovingDistanceKilometres() > 1.0 && !stats.getTimestampsIncomplete() && !stats.getTimestampsOutOfSequence() && stats.getTotalDurationInSeconds() > 100 - && stats.getStartIndex() > prevStartIndex) + && startIndex > prevStartIndex) { // System.out.println("Got stats for " + stats.getStartIndex() + " to " + stats.getEndIndex()); statsList.add(stats); - prevStartIndex = stats.getStartIndex(); + prevStartIndex = startIndex; } _progress.setValue(i); } @@ -246,7 +246,8 @@ public class LearnParameters extends GenericFunction implements Runnable * @param inPreviousStartIndex the previously used start index, or -1 * @return range stats object or null if required information missing from this bit of the track */ - private RangeStats getRangeStats(Track inTrack, int inStartIndex, int inEndIndex, int inPreviousStartIndex) + private RangeStatsWithGradients getRangeStats(Track inTrack, int inStartIndex, + int inEndIndex, int inPreviousStartIndex) { // Check parameters if (inTrack == null || inStartIndex < 0 || inEndIndex <= inStartIndex || inStartIndex > inTrack.getNumPoints()) { @@ -297,7 +298,7 @@ public class LearnParameters extends GenericFunction implements Runnable // Check moving distance if (movingRads >= minimumRads) { - return new RangeStats(inTrack, start, endIndex); + return new RangeStatsWithGradients(inTrack, start, endIndex); } return null; } @@ -307,12 +308,12 @@ public class LearnParameters extends GenericFunction implements Runnable * @param inStatsList list of (non-null) RangeStats objects * @return A matrix with n rows and 5 columns */ - private static Matrix buildAMatrix(ArrayList inStatsList) + private static Matrix buildAMatrix(ArrayList inStatsList) { final Unit METRES = UnitSetLibrary.UNITS_METRES; Matrix result = new Matrix(inStatsList.size(), 5); int row = 0; - for (RangeStats stats : inStatsList) + for (RangeStatsWithGradients stats : inStatsList) { result.setValue(row, 0, stats.getMovingDistanceKilometres()); result.setValue(row, 1, stats.getGentleAltitudeRange().getClimb(METRES)); @@ -329,11 +330,11 @@ public class LearnParameters extends GenericFunction implements Runnable * @param inStatsList list of (non-null) RangeStats objects * @return B matrix with single column of n rows */ - private static Matrix buildBMatrix(ArrayList inStatsList) + private static Matrix buildBMatrix(ArrayList inStatsList) { Matrix result = new Matrix(inStatsList.size(), 1); int row = 0; - for (RangeStats stats : inStatsList) + for (RangeStatsWithGradients stats : inStatsList) { result.setValue(row, 0, stats.getMovingDurationInSeconds() / 60.0); // convert seconds to minutes row++; @@ -372,12 +373,13 @@ public class LearnParameters extends GenericFunction implements Runnable * @param inRowToIgnore row index to ignore, or -1 to use them all * @return true if the samples look ok */ - private static boolean isRangeSetSufficient(ArrayList inRangeSet, int inRowToIgnore) + private static boolean isRangeSetSufficient(ArrayList inRangeSet, int inRowToIgnore) { - int numGC = 0, numSC = 0, numGD = 0, numSD = 0; // number of samples with gentle/steep climb/descent values > 0 + // number of samples with gentle/steep climb/descent values > 0 + int numGC = 0, numSC = 0, numGD = 0, numSD = 0; final Unit METRES = UnitSetLibrary.UNITS_METRES; int i = 0; - for (RangeStats stats : inRangeSet) + for (RangeStatsWithGradients stats : inRangeSet) { if (i != inRowToIgnore) { @@ -396,7 +398,7 @@ public class LearnParameters extends GenericFunction implements Runnable * @param inStatsList list of stats * @return results in an object */ - private MatrixResults reduceSamples(ArrayList inStatsList) + private MatrixResults reduceSamples(ArrayList inStatsList) { int statsIndexToRemove = -1; Matrix answer = null; diff --git a/src/tim/prune/function/gpsies/FormPoster.java b/src/tim/prune/function/gpsies/FormPoster.java deleted file mode 100644 index 5939e63..0000000 --- a/src/tim/prune/function/gpsies/FormPoster.java +++ /dev/null @@ -1,162 +0,0 @@ -package tim.prune.function.gpsies; - -import java.net.HttpURLConnection; -import java.net.URLConnection; -import java.net.URL; -import java.io.IOException; -import java.io.InputStream; -import java.util.Random; -import java.io.OutputStream; - -/** - * Taken from the Client HTTP Request class at com.myjavatools.web - * and subsequently simplified and modified - * @author Vlad Patryshev - */ -public class FormPoster -{ - private URLConnection _connection = null; - private OutputStream _os = null; - private static final Random RANDOM_GEN = new Random(); - private static final String BOUNDARY = "---------------------------" - + randomString() + randomString() + randomString(); - - - /** Connect (if not already connected) */ - protected void connect() throws IOException { - if (_os == null) _os = _connection.getOutputStream(); - } - - /** Write a single character */ - protected void write(char c) throws IOException { - connect(); - _os.write(c); - } - - /** Write a string */ - protected void write(String s) throws IOException { - connect(); - _os.write(s.getBytes()); - } - - /** Write a -r-n newline sequence */ - protected void newline() throws IOException { - write("\r\n"); - } - - /** Write a string followed by a newline */ - protected void writeln(String s) throws IOException { - write(s); - newline(); - } - - /** Generate a random alphanumeric string */ - private static String randomString() { - return Long.toString(RANDOM_GEN.nextLong(), 36); - } - - /** Write a boundary marker */ - private void boundary() throws IOException { - write("--"); - write(BOUNDARY); - } - - - /** - * Creates a new multipart POST HTTP request for a specified URL - * @param url the URL to send request to - * @throws IOException - */ - public FormPoster(URL inUrl) throws IOException - { - _connection = inUrl.openConnection(); - _connection.setDoOutput(true); - _connection.setRequestProperty("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY); - } - - /** Write a header with the given name */ - private void writeName(String inName) throws IOException - { - newline(); - write("Content-Disposition: form-data; name=\""); - write(inName); - write('"'); - } - - /** - * adds a string parameter to the request - * @param name parameter name - * @param value parameter value - * @throws IOException - */ - public void setParameter(String inName, String inValue) throws IOException - { - boundary(); - writeName(inName); - newline(); newline(); - writeln(inValue); - } - - /** Pipe the contents of the input stream to the output stream */ - private static void pipe(InputStream in, OutputStream out) throws IOException - { - byte[] buf = new byte[500000]; - int nread; - synchronized (in) { - while((nread = in.read(buf, 0, buf.length)) >= 0) { - out.write(buf, 0, nread); - } - } - out.flush(); - buf = null; - } - - /** - * adds a file parameter to the request - * @param inName parameter name - * @param inFilename the name of the file - * @param inStream input stream to read the contents of the file from - * @throws IOException - */ - public void setParameter(String inName, String inFilename, InputStream inStream) throws IOException - { - boundary(); - writeName(inName); - write("; filename=\""); - write(inFilename); - write('"'); - newline(); - write("Content-Type: "); - String type = URLConnection.guessContentTypeFromName(inFilename); - if (type == null) {type = "application/octet-stream";} - writeln(type); - newline(); - pipe(inStream, _os); - newline(); - } - - /** - * posts the requests to the server - * @return input stream with the server response - * @throws IOException - */ - public InputStream post() throws IOException - { - boundary(); - writeln("--"); - _os.close(); - return _connection.getInputStream(); - } - - /** - * @return the HTTP response code, 200 for success or -1 if not available - */ - public int getResponseCode() throws IOException - { - if (_connection != null && _connection instanceof HttpURLConnection) { - return ((HttpURLConnection) _connection).getResponseCode(); - } - return -1; - } -} diff --git a/src/tim/prune/function/gpsies/GetGpsiesFunction.java b/src/tim/prune/function/gpsies/GetGpsiesFunction.java deleted file mode 100644 index cdcc9a9..0000000 --- a/src/tim/prune/function/gpsies/GetGpsiesFunction.java +++ /dev/null @@ -1,147 +0,0 @@ -package tim.prune.function.gpsies; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import tim.prune.App; -import tim.prune.GpsPrune; -import tim.prune.I18nManager; -import tim.prune.function.search.GenericDownloaderFunction; -import tim.prune.function.search.SearchResult; -import tim.prune.load.xml.XmlFileLoader; -import tim.prune.load.xml.ZipFileLoader; - -/** - * Function to load track information from Gpsies.com - * according to the currently viewed area - */ -public class GetGpsiesFunction extends GenericDownloaderFunction -{ - /** Number of results per page */ - private static final int RESULTS_PER_PAGE = 20; - /** Maximum number of results to get */ - private static final int MAX_RESULTS = 60; - /** New API key (specific to this program) */ - private static final String GPSIES_API_KEY = "oumgvvbckiwpvsnb"; - - - /** - * Constructor - * @param inApp App object - */ - public GetGpsiesFunction(App inApp) { - super(inApp); - } - - /** - * @return name key - */ - public String getNameKey() { - return "function.getgpsies"; - } - - /** - * @param inColNum index of column, 0 or 1 - * @return key for this column - */ - protected String getColumnKey(int inColNum) - { - if (inColNum == 0) return "dialog.gpsies.column.name"; - return "dialog.gpsies.column.length"; - } - - - /** - * Run method to call gpsies.com in separate thread - */ - public void run() - { - _statusLabel.setText(I18nManager.getText("confirm.running")); - // Act on callback to update list and send another request if necessary - double[] coords = _app.getViewport().getBounds(); - int currPage = 1; - - ArrayList trackList = null; - URL url = null; - String descMessage = ""; - InputStream inStream = null; - // Loop for each page of the results - do - { - // Example http://ws.gpsies.com/api.do?BBOX=10,51,12,53&limit=20&resultPage=1&key=oumgvvbckiwpvsnb - String urlString = "http://ws.gpsies.com/api.do?BBOX=" + - coords[1] + "," + coords[0] + "," + coords[3] + "," + coords[2] + - "&limit=" + RESULTS_PER_PAGE + "&resultPage=" + currPage + - "&key=" + GPSIES_API_KEY; - // Parse the returned XML with a special handler - GpsiesXmlHandler xmlHandler = new GpsiesXmlHandler(); - try - { - url = new URL(urlString); - SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - URLConnection conn = url.openConnection(); - conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER); - inStream = conn.getInputStream(); - saxParser.parse(inStream, xmlHandler); - } - catch (Exception e) { - descMessage = e.getClass().getName() + " - " + e.getMessage(); - } - // Close stream and ignore errors - try { - inStream.close(); - } catch (Exception e) {} - // Add track list to model - trackList = xmlHandler.getTrackList(); - _trackListModel.addTracks(trackList); - - // Compare number of results with results per page and call again if necessary - currPage++; - } - while (trackList != null && trackList.size() == RESULTS_PER_PAGE - && _trackListModel.getRowCount() < MAX_RESULTS && !_cancelled); - // Set status label according to error or "none found", leave blank if ok - if (descMessage.equals("") && (trackList == null || trackList.size() == 0)) { - descMessage = I18nManager.getText("dialog.gpsies.nonefound"); - } - _statusLabel.setText(descMessage); - } - - /** - * Load the selected track(s) - */ - protected void loadSelected() - { - // Find the row(s) selected in the table and get the corresponding track - int numSelected = _trackTable.getSelectedRowCount(); - if (numSelected < 1) return; - int[] rowNums = _trackTable.getSelectedRows(); - for (int i=0; i= 0 && rowNum < _trackListModel.getRowCount()) - { - String url = _trackListModel.getTrack(rowNum).getDownloadLink(); - XmlFileLoader xmlLoader = new XmlFileLoader(_app); - ZipFileLoader loader = new ZipFileLoader(_app, xmlLoader); - if (i>0) _app.autoAppendNextFile(); - try - { - loader.openStream(new URL(url).openStream()); - } - catch (IOException ioe) { - System.err.println("IO Exception : " + ioe.getMessage()); - } - } - } - // Close the dialog - _cancelled = true; - _dialog.dispose(); - } -} diff --git a/src/tim/prune/function/gpsies/GpsiesXmlHandler.java b/src/tim/prune/function/gpsies/GpsiesXmlHandler.java deleted file mode 100644 index c549c59..0000000 --- a/src/tim/prune/function/gpsies/GpsiesXmlHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -package tim.prune.function.gpsies; - -import java.util.ArrayList; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import tim.prune.function.search.SearchResult; - -/** - * XML handler for dealing with XML returned from gpsies.com - */ -public class GpsiesXmlHandler extends DefaultHandler -{ - private String _value = null; - private ArrayList _trackList = null; - private SearchResult _track = null; - - - /** - * React to the start of an XML tag - */ - public void startElement(String inUri, String inLocalName, String inTagName, - Attributes inAttributes) throws SAXException - { - if (inTagName.equals("tracks")) { - _trackList = new ArrayList(); - } - else if (inTagName.equals("track")) { - _track = new SearchResult(); - } - _value = null; - super.startElement(inUri, inLocalName, inTagName, inAttributes); - } - - /** - * React to the end of an XML tag - */ - public void endElement(String inUri, String inLocalName, String inTagName) - throws SAXException - { - if (inTagName.equals("track")) { - _trackList.add(_track); - } - else if (inTagName.equals("title")) { - _track.setTrackName(_value); - } - else if (inTagName.equals("description")) { - _track.setDescription(_value); - } - else if (inTagName.equals("fileId")) { - _track.setWebUrl("https://gpsies.com/map.do?fileId=" + _value); - } - else if (inTagName.equals("trackLengthM")) { - try { - _track.setLength(Double.parseDouble(_value)); - } - catch (NumberFormatException nfe) {} - } - else if (inTagName.equals("downloadLink")) { - _track.setDownloadLink(_value); - } - super.endElement(inUri, inLocalName, inTagName); - } - - /** - * React to characters received inside tags - */ - public void characters(char[] inCh, int inStart, int inLength) - throws SAXException - { - String value = new String(inCh, inStart, inLength); - _value = (_value==null?value:_value+value); - super.characters(inCh, inStart, inLength); - } - - /** - * @return the list of tracks - */ - public ArrayList getTrackList() - { - return _trackList; - } -} diff --git a/src/tim/prune/function/gpsies/UploadGpsiesFunction.java b/src/tim/prune/function/gpsies/UploadGpsiesFunction.java deleted file mode 100644 index 3cef9db..0000000 --- a/src/tim/prune/function/gpsies/UploadGpsiesFunction.java +++ /dev/null @@ -1,332 +0,0 @@ -package tim.prune.function.gpsies; - -import java.awt.BorderLayout; -import java.awt.Component; -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.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.net.MalformedURLException; -import java.net.URL; - -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.border.EtchedBorder; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import tim.prune.App; -import tim.prune.GenericFunction; -import tim.prune.I18nManager; -import tim.prune.function.browser.BrowserLauncher; -import tim.prune.gui.GuiGridLayout; -import tim.prune.save.GpxExporter; -import tim.prune.save.SettingsForExport; - -/** - * Function to upload track information up to Gpsies.com - */ -public class UploadGpsiesFunction extends GenericFunction -{ - /** Dialog object */ - private JDialog _dialog = null; - /** Edit box for user name */ - private JTextField _usernameField = null; - /** Edit box for password */ - private JPasswordField _passwordField = null; - /** Name of track */ - private JTextField _nameField = null; - /** Description */ - private JTextArea _descField = null; - /** Private checkbox */ - private JCheckBox _privateCheckbox = null; - /** Activity checkboxes */ - private JCheckBox[] _activityCheckboxes = null; - /** Writer object for GPX export */ - private OutputStreamWriter _writer = null; - /** upload button */ - private JButton _uploadButton = null; - - /** URL to post form to */ - private static final String GPSIES_URL = "http://www.gpsies.com/upload.do"; - /** Keys for describing activities */ - private static final String[] ACTIVITY_KEYS = {"trekking", "walking", "jogging", - "biking", "motorbiking", "snowshoe", "sailing", "skating"}; - - /** - * Constructor - * @param inApp App object - */ - public UploadGpsiesFunction(App inApp) { - super(inApp); - } - - /** - * @return name key - */ - public String getNameKey() { - return "function.uploadgpsies"; - } - - /** - * Begin the function - */ - public void begin() - { - // Initialise dialog, show empty list - if (_dialog == null) - { - _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - _dialog.getContentPane().add(makeDialogComponents()); - _dialog.pack(); - } - // Show dialog - _dialog.setVisible(true); - } - - - /** - * Create dialog components - * @return Panel containing all gui elements in dialog - */ - private Component makeDialogComponents() - { - JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BorderLayout()); - - JPanel gridPanel = new JPanel(); - GuiGridLayout grid = new GuiGridLayout(gridPanel); - grid.add(new JLabel(I18nManager.getText("dialog.gpsies.username"))); - _usernameField = new JTextField(15); - grid.add(_usernameField); - grid.add(new JLabel(I18nManager.getText("dialog.gpsies.password"))); - _passwordField = new JPasswordField(15); - grid.add(_passwordField); - // Track name and description - grid.add(new JLabel(I18nManager.getText("dialog.gpsies.column.name"))); - _nameField = new JTextField(15); - grid.add(_nameField); - grid.add(new JLabel(I18nManager.getText("dialog.gpsies.description"))); - _descField = new JTextArea(5, 15); - _descField.setLineWrap(true); - _descField.setWrapStyleWord(true); - grid.add(new JScrollPane(_descField)); - // Listener on all these text fields to enable/disable the ok button - KeyAdapter keyListener = new KeyAdapter() { - /** Key released */ - public void keyReleased(KeyEvent inE) { - enableOK(); - if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) { - _dialog.dispose(); - } - } - }; - _usernameField.addKeyListener(keyListener); - _passwordField.addKeyListener(keyListener); - _nameField.addKeyListener(keyListener); - // Listen for tabs on description field, to change focus not enter tabs - _descField.addKeyListener(new KeyAdapter() { - /** Key pressed */ - public void keyPressed(KeyEvent inE) { - if (inE.getKeyCode() == KeyEvent.VK_TAB) { - inE.consume(); - if (inE.isShiftDown()) { - _nameField.requestFocusInWindow(); - } - else { - _privateCheckbox.requestFocusInWindow(); - } - } - } - }); - // Listen for Ctrl-backspace on password field (delete contents) - _passwordField.addKeyListener(new KeyAdapter() { - /** Key released */ - public void keyReleased(KeyEvent inE) { - if (inE.isControlDown() && (inE.getKeyCode() == KeyEvent.VK_BACK_SPACE - || inE.getKeyCode() == KeyEvent.VK_DELETE)) { - _passwordField.setText(""); - } - } - }); - // Checkbox for private / public - grid.add(new JLabel(I18nManager.getText("dialog.gpsies.keepprivate"))); - _privateCheckbox = new JCheckBox(); - _privateCheckbox.setSelected(true); - grid.add(_privateCheckbox); - - // panel for activity type checkboxes - JPanel activityPanel = new JPanel(); - activityPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); - ChangeListener checkListener = new ChangeListener() { - public void stateChanged(ChangeEvent arg0) { - enableOK(); - } - }; - // Why not a simple grid layout here? - GuiGridLayout actGrid = new GuiGridLayout(activityPanel, new double[] {1.0, 1.0}, new boolean[] {false, false}); - final int numActivities = ACTIVITY_KEYS.length; - _activityCheckboxes = new JCheckBox[numActivities]; - for (int i=0; i 0 && _nameField.getText().length() > 0); - if (ok) { - // also check password field - char[] pass = _passwordField.getPassword(); - ok = pass.length > 0; - for (int i=0; i 0 && line.endsWith("]")) { - pageUrl = line.substring(bracketPos + 1, line.length()-1); - } - } - if (pageUrl != null) - { - // OK received and managed to extract a Url from the return message. - int userChoice = JOptionPane.showConfirmDialog(_app.getFrame(), - I18nManager.getText("dialog.gpsies.confirmopenpage"), - I18nManager.getText(getNameKey()), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (userChoice == JOptionPane.OK_OPTION) { - BrowserLauncher.launchBrowser(pageUrl); - } - } - else { - _app.showErrorMessageNoLookup(getNameKey(), I18nManager.getText("error.gpsies.uploadnotok") - + ": " + line); - } - } - catch (MalformedURLException e) {} - catch (IOException ioe) { - _app.showErrorMessageNoLookup(getNameKey(), I18nManager.getText("error.gpsies.uploadfailed") + ": " - + ioe.getClass().getName() + " : " + ioe.getMessage()); - } - finally { - try {if (reader != null) reader.close();} catch (IOException e) {} - } - _dialog.dispose(); - } -} diff --git a/src/tim/prune/function/olc/CoordPair.java b/src/tim/prune/function/olc/CoordPair.java new file mode 100644 index 0000000..778b46d --- /dev/null +++ b/src/tim/prune/function/olc/CoordPair.java @@ -0,0 +1,75 @@ +package tim.prune.function.olc; + +class ParseException extends Exception {} + +/** + * Pair of coordinates + */ +class CoordPair +{ + /** Alphabet of allowed characters */ + private static final String ALPHABET = "23456789CFGHJMPQRVWX"; + + public double lat = 0.0; + public double lon = 0.0; + + /** Constructor */ + public CoordPair(double inLat, double inLon) + { + lat = inLat; + lon = inLon; + } + + /** Constant pair to represent padding */ + public static CoordPair PADDING = new CoordPair(-1.0, -1.0); + + /** + * Try to parse the given pair of characters into a CoordPair + * @param inFirst first character of pair + * @param inSecond second character of pair + * @return CoordPair from (0, 0) to (19/20, 19/20) + * @throws ParseException + */ + public static CoordPair decode(char inFirst, char inSecond) throws ParseException + { + final boolean isFirstPadding = (inFirst == '0'); + final boolean isSecondPadding = (inSecond == '0'); + if (isFirstPadding && isSecondPadding) {return CoordPair.PADDING;} + if (isFirstPadding || isSecondPadding) {throw new ParseException();} + // Try to turn these characters into numbers + final double lat = decodeChar(inFirst); + final double lon = decodeChar(inSecond); + return new CoordPair(lat / 20.0, lon / 20.0); + } + + /** + * Try to parse the given single character into a CoordPair + * @param inChar single character from level 11 + * @return CoordPair from (0, 0) to (19/20, 19/20) + * @throws ParseException + */ + public static CoordPair decode(char inChar) throws ParseException + { + // Try to turn this character into a number + final int charIndex = decodeChar(inChar); + final int lat = charIndex / 4; + final int lon = charIndex % 4; + return new CoordPair(lat / 5.0, lon / 4.0); + } + + /** + * Get the index from the given character + * @param inChar character from OLC + * @return index from 0 to 19 + * @throws ParseException if character not found + */ + private static int decodeChar(char inChar) throws ParseException + { + final int index = ALPHABET.indexOf(inChar); + if (index < 0) + { + throw new ParseException(); + } + return index; + } +} diff --git a/src/tim/prune/function/olc/OlcArea.java b/src/tim/prune/function/olc/OlcArea.java new file mode 100644 index 0000000..bc7a3e8 --- /dev/null +++ b/src/tim/prune/function/olc/OlcArea.java @@ -0,0 +1,21 @@ +package tim.prune.function.olc; + +/** + * Class to represent the result of an OLC decoding + */ +public class OlcArea +{ + public double minLat = 0.0; + public double maxLat = 0.0; + public double minLon = 0.0; + public double maxLon = 0.0; + + /** Constructor */ + public OlcArea(double inMinLat, double inMinLon, double inMaxLat, double inMaxLon) + { + minLat = inMinLat; + minLon = inMinLon; + maxLat = inMaxLat; + maxLon = inMaxLon; + } +} diff --git a/src/tim/prune/function/olc/OlcDecoder.java b/src/tim/prune/function/olc/OlcDecoder.java new file mode 100644 index 0000000..122f6fe --- /dev/null +++ b/src/tim/prune/function/olc/OlcDecoder.java @@ -0,0 +1,101 @@ +package tim.prune.function.olc; + + +/** + * Decoder of OLC (Open Location Code) strings + */ +public class OlcDecoder +{ + /** + * Decode the given String into an OlcArea object + * @param inCode code representing an OLC + * @return an OlcArea object, or null if parsing failed + */ + public static OlcArea decode(String inCode) + { + if (inCode == null || inCode.length() < 8) { + return null; + } + String code = inCode.trim().toUpperCase(); + if (code.length() < 8 || code.length() > 12) { + return null; + } + double lat = 0.0, lon = 0.0; + double resolution = 400.0; + int charPos = 0; + int numSteps = 0; + boolean amPadding = false; + try + { + while (charPos < inCode.length()) + { + if (charPos == 0 || charPos == 2 || charPos == 4 || charPos == 6 || charPos == 9) + { + // take next two characters, make pair, position += 2 + CoordPair pair = CoordPair.decode(code.charAt(charPos), code.charAt(charPos+1)); + if (pair == CoordPair.PADDING) { + amPadding = true; + } + else if (amPadding) + { + return null; + } + else + { + // Add to current lat, lon + lat += (pair.lat * resolution); + lon += (pair.lon * resolution); + numSteps++; + resolution /= 20.0; + } + charPos += 2; + } + else if (charPos == 8) + { + if (code.charAt(charPos) != '+') + { + return null; + } + charPos += 1; + } + else if (charPos == 11) + { + // take next character, make pair + CoordPair pair = CoordPair.decode(code.charAt(charPos)); + // Add to current lat, lon + lat += (pair.lat * resolution); + lon += (pair.lon * resolution); + charPos += 1; + numSteps++; + resolution /= 20.0; + } + else + { + return null; + } + } + + // Make OlcArea object and return it + if (numSteps < 1) + { + return null; + } + else if (numSteps < 6) + { + // make four points + lat -= 90.0; + lon -= 180.0; + return new OlcArea(lat, lon, lat+resolution, lon+resolution); + } + else + { + // make single point: + lat -= 90.0; + lon -= 180.0; + return new OlcArea(lat, lon, lat+resolution*2.5, lon+resolution*2.0); + } + } + catch (ParseException e) {} + return null; + } +} \ No newline at end of file diff --git a/src/tim/prune/function/search/GenericDownloaderFunction.java b/src/tim/prune/function/search/GenericDownloaderFunction.java index fa8d4c3..079bf9d 100644 --- a/src/tim/prune/function/search/GenericDownloaderFunction.java +++ b/src/tim/prune/function/search/GenericDownloaderFunction.java @@ -25,11 +25,10 @@ import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.function.browser.BrowserLauncher; -import tim.prune.function.gpsies.TrackListModel; /** * Function to load track information from any source, - * subclassed for special cases like gpsies, wikipedia or OSM + * subclassed for special cases like wikipedia or OSM */ public abstract class GenericDownloaderFunction extends GenericFunction implements Runnable { diff --git a/src/tim/prune/function/search/SearchResult.java b/src/tim/prune/function/search/SearchResult.java index d757b01..52b902f 100644 --- a/src/tim/prune/function/search/SearchResult.java +++ b/src/tim/prune/function/search/SearchResult.java @@ -1,7 +1,7 @@ package tim.prune.function.search; /** - * Class to hold a search result from wikipedia / gpsies etc + * Class to hold a search result from wikipedia or other online service */ public class SearchResult implements Comparable { diff --git a/src/tim/prune/function/gpsies/TrackListModel.java b/src/tim/prune/function/search/TrackListModel.java similarity index 95% rename from src/tim/prune/function/gpsies/TrackListModel.java rename to src/tim/prune/function/search/TrackListModel.java index 8509213..d9163be 100644 --- a/src/tim/prune/function/gpsies/TrackListModel.java +++ b/src/tim/prune/function/search/TrackListModel.java @@ -1,4 +1,4 @@ -package tim.prune.function.gpsies; +package tim.prune.function.search; import java.text.NumberFormat; import java.util.ArrayList; @@ -9,10 +9,9 @@ import javax.swing.table.AbstractTableModel; import tim.prune.I18nManager; import tim.prune.config.Config; import tim.prune.data.Unit; -import tim.prune.function.search.SearchResult; /** - * Model for list of tracks from a search result (eg gpsies.com, geonames, overpass) + * Model for list of tracks from a search result (eg geonames, overpass) */ public class TrackListModel extends AbstractTableModel { diff --git a/src/tim/prune/function/search/wikimedia_galleries.txt b/src/tim/prune/function/search/wikimedia_galleries.txt index 3647237..6b1ba55 100644 --- a/src/tim/prune/function/search/wikimedia_galleries.txt +++ b/src/tim/prune/function/search/wikimedia_galleries.txt @@ -1,113 +1,116 @@ +116/122/A-180 Z light pillbox 49 57 30.7 N 14 05 23.85 E +A-4/51/A-200 Y light pillbox Back to 1938 state restored Pillbox Type 37 built in a unique modification into road embankment between Dolní Bezděkov and Bratronice, Kladno District, Czech Republic. 50 04 47.94 N 14 02 01.85 E A Arnoia 42 14 54.95 N 8 08 04.88 W A Barciela, Oroso 42 57 57.49 N 8 26 31.07 W -A Cañiza A Cañiza is a municipality in Galicia, in the province of Pontevedra. 42 12 45.46 N 8 16 29.77 W -A Coruña A Coruña is a Galician city, in north-western Spain. 43 21 58.95 N 8 24 28.71 W -A Estrada 41 32 35.1 N 2 12 59.63 E -A Guarda 41 54 09.12 N 8 52 27.15 W -A Gudiña A Gudiña is a municipality in Galicia, in the province of Ourense. 42 03 40.13 N 7 08 34.19 W -A Illa de Arousa A Illa de Arousa is a municipality in Galicia, in the province of Pontevedra. 42 33 08.36 N 8 52 06.13 W -A Merca A Merca is a municipality in Galicia, in the province of Ourense. 42 13 22.53 N 7 54 15.55 W -A Mezquita 42 00 42.5 N 7 02 43.17 W -A Pobra de Trives 42 20 19.96 N 7 15 15.88 W -A Pobra do Brollón 42 33 29.3 N 7 23 40.15 W -A Pobra do Caramiñal A Pobra do Caramiñal is a municipality in the province of A Coruña, Galicia, Spain. 42 36 12.2 N 8 56 14.25 W -A Rúa A Rúa is a municipality in Galicia, in the province of Ourense. 42 23 34.93 N 7 06 59.02 W -A Veiga A Veiga is a municipality in Galicia, in the province of Ourense. 42 15 01.36 N 7 01 30.25 W -A Walk on Main Street, Ferndale, California Ferndale is a small town in Humboldt County, California. Its Main Street is listed by the National Register of Historic Places as a historic district. 40 34 32.16 N 124 15 54 W -A Walk up Main Street, Adamstown, Pennsylvania Adamstown is a small, historic town in Lancaster County, Pennsylvania. 40 14 36.96 N 76 03 16.2 W Abbaye d'Acey 47 15 42 N 5 39 25 E Abbaye de Bourgueil 47 16 46.2 N 0 10 18.12 E Abbaye de Cluny The Abbey of Cluny (or Cluni, or Clugny) was founded on 2 September 909 and is located in the modern-day department of Saône-et-Loire in the region of Bourgogne, in east-central France, near Mâcon. 46 26 03 N 4 39 33 E -Abbaye de Fontenay 47 38 27 N 4 23 23 E Abbaye de Fontevraud Fontevraud Abbey is located near Saumur in Anjou, France 47 10 53 N 0 03 06 E Abbaye de La Sauve-Majeure 44 46 07.24 N 0 18 42.41 W -Abbaye de Montmajour 43 42 20 N 4 39 50 E +Abbaye de Montmajour 43 42 20.16 N 4 39 50.04 E Abbaye de Saint-Germain-des-Prés 48 51 14 N 2 20 04 E Abbaye de Saint-Savin-sur-Gartempe 46 33 51 N 0 51 58 E Abbaye de Sénanque 43 55 42 N 5 11 13 E Abbaye de Valmagne 43 29 12.97 N 3 33 44.19 E Abbaye du Relec 48 26 56 N 3 43 00 W -Abbaye Saint Wandrille Monastery Saint Wandrille in France 49 31 46.42 N 0 45 59.58 E Abbaye Saint-Corneille 49 25 02.6 N 2 49 28.57 E -Abbaye Saint-Florentin, Bonneval 48 10 40.41 N 1 23 04.87 E -Abeilhan 43 27 02 N 3 17 43 E +Abbaye Saint Wandrille Monastery Saint Wandrille in France 49 31 46.42 N 0 45 59.58 E +Abeilhan Abeilhan is a commune of the Hérault département in the Region of Occitanie - France. 43 27 02 N 3 17 43 E Abri-caverne de l'ouvrage du Haut-Bois 47 35 24.07 N 6 48 34.23 E Abtei Saint-André (Lavaudieu) 45 15 49 N 3 27 17 E +A Cañiza A Cañiza is a municipality in Galicia, in the province of Pontevedra. 42 12 45.46 N 8 16 29.77 W Aceldama Aceldama or Akeldama is the Aramaic name for a place in Jerusalem associated with Judas Iscariot, one of the followers of Jesus. 31 46 05.1 N 35 13 59.51 E -Adissan 43 32 09.96 N 3 25 45.12 E -Agadir 30 25 00 N 9 35 00 W -Agel 43 20 18.96 N 2 51 13.68 E +Adissan Adissan is a commune of the Hérault département in the Region of Occitanie - France. 43 32 09.96 N 3 25 45.12 E +Aérodrome de Besançon-Thise 47 16 25.68 N 6 04 59.09 E +A Estrada A Estrada is a municipality in Galicia, Spain in the province of Pontevedra. 41 32 35.1 N 2 12 59.63 E +Agel Agel is a commune of the Hérault département - France. 43 20 18.96 N 2 51 13.68 E Agrón, Ames 42 54 20.32 N 8 41 43.21 W +A Guarda A Guarda is a municipality in Galicia, in the province of Pontevedra. 41 54 09.12 N 8 52 27.15 W +A Gudiña A Gudiña is a municipality in Galicia, in the province of Ourense. 42 03 40.13 N 7 08 34.19 W Aguiño, Ribeira 42 31 24.99 N 9 00 57.6 W -Aichi prefecture 35 04 59 N 136 58 59 E Aiguafreda Montseny 41 46 05.2 N 2 15 05.39 E +A Illa de Arousa A Illa de Arousa is a municipality in Galicia, in the province of Pontevedra. 42 33 08.36 N 8 52 06.13 W Alagna Valsesia Alagna Valsesia is a village in Piemonte in Italy. 45 51 05.16 N 7 56 16.98 E Albrechtsburg The Albrechtsburg is the castle that dominates the city centre of Meißen, Germany. 51 09 59.65 N 13 28 17.83 E Aletsch Aletsch region, UNESCO World Heritage Site since 2001, in Bernese Alps, Switzerland 46 27 50.9 N 8 04 20.89 E Allariz Allariz is a municipality in Galicia, in the province of Ourense. 42 11 20.76 N 7 48 09.71 W +Alte Kanzlei, Stuttgart 48 46 39.1 N 9 10 42.97 E Alt Katholische Christuskirche Offenbach 50 06 01.91 N 8 45 52.28 E +A Merca A Merca is a municipality in Galicia, in the province of Ourense. 42 13 22.53 N 7 54 15.55 W Ames 42 51 35.95 N 8 38 58.21 W +A Mezquita 42 00 42.5 N 7 02 43.17 W Amoeiro 42 24 37.45 N 7 57 15.38 W Ansemil, Silleda 42 44 21.56 N 8 16 12.47 W Anta de Casaínhos 38 52 50.16 N 9 10 09.91 W Antwerp Central Station 51 13 02 N 4 25 15.6 E -Aquis Querquennis Aquis Querquennis was a Roman castra at Os Baños, Bande (Ourense, Galiza). 41 58 27.2 N 7 58 52.1 W +A Pobra de Trives 42 20 19.96 N 7 15 15.88 W +A Pobra do Brollón 42 33 29.3 N 7 23 40.15 W +A Pobra do Caramiñal A Pobra do Caramiñal is a municipality in the province of A Coruña, Galicia, Spain. 42 36 12.2 N 8 56 14.25 W +Aquis Querquennis 41 58 12 N 7 58 48 W Arbo 42 06 39.45 N 8 18 57.47 W -Arc de Triomf de Barcelona The Arc de Triomf (Triumphal Arch) is an archway structure in Barcelona, Spain. 41 23 27 N 2 10 50 E +Arc de Triomf de Barcelona 41 23 28 N 2 10 50.02 E Arc de Triomphe du Carrousel The Arc de Triomphe du Carrousel is a triumphal arch in Paris, located in the Place du Carrousel on the site of the former Tuileries Palace. 48 51 43 N 2 19 58 E -Arch of Constantine 41 53 23 N 12 29 27 E +Arch of Constantine 41 53 22.92 N 12 29 26.88 E Arch of Septimius Severus (Rome) The Arch of Septimius Severus is situated in the Forum Romanum in Rome. 41 53 34 N 12 29 05 E Arch of Titus The Arch of Titus is a triumphal arch with a single arched opening, located on the Summa Sacra Via to the west of the Roman Forum in Rome. 41 53 26 N 12 29 19 E -Arnhem 51 59 00 N 5 55 00 E -Arenys de Munt Arenys de Munt is a village in the comarca of Maresme, Catalonia. 41 36 46 N 2 32 25 E +A Rúa A Rúa is a municipality in Galicia, in the province of Ourense. 42 23 34.93 N 7 06 59.02 W +Askersund Askersund is a town in Sweden. 58 53 00 N 14 54 00 E As Neves As Neves is a municipality in Galicia, in the province of Pontevedra. 42 05 10.49 N 8 24 53.43 W As Pontes de García Rodríguez 43 26 47.63 N 7 51 09.54 W -Askersund 58 53 00 N 14 54 00 E Assumption Cathedral in Odessa Assumption Cathedral in Odessa, Ukraine 46 28 49.43 N 30 44 21.24 E +Äußerer Plauenscher Friedhof Cemetery „Äußerer Plauenscher Friedhof“ in Dresden-Plauen 51 01 11.89 N 13 42 26.03 E Australian Synchrotron The Australian Synchrotron, a synchrotron facility in the suburb of Clayton, in Melbourne, Victoria, Australia. 37 54 51 S 145 08 33 E +A Veiga A Veiga is a municipality in Galicia, in the province of Ourense. 42 15 01.36 N 7 01 30.25 W Avión Avión is a municipality in Galicia, in the province of Ourense. 42 22 23.73 N 8 15 02.64 W +A Walk on Main Street, Ferndale, California Ferndale is a small town in Humboldt County, California. 40 34 32.16 N 124 15 54 W +A Walk up Main Street, Adamstown, Pennsylvania Adamstown is a small, historic town in Lancaster County, Pennsylvania. 40 14 36.96 N 76 03 16.2 W Ayasofya The Church of the Holy Wisdom, commonly known as Hagia Sophia in English, is the former Greek Orthodox patriarchal cathedral, converted in 1453 to a mosque, now a museum, in Istanbul. 41 00 30.5 N 28 58 47.7 E -Aérodrome de Besançon-Thise 47 16 25.68 N 6 04 59.09 E -Aşgabat 37 57 00 N 58 23 00 E +B-6/61/A-220 Z light pillbox B-6/61/A-220Z light pillbox, Beroun 49 57 25.96 N 14 05 35.6 E +B-7/5/A-200 Z light pillbox 49 56 28.3 N 14 07 53.68 E +B-7/6/A-200 Z light pillbox 49 56 19.34 N 14 07 56.34 E Bahnhof Dresden-Neustadt Dresden-Neustadt railway station and the four inner city bridges 51 03 56 N 13 44 27 E Baiona Baiona is a municipality in Galicia, Spain in the province of Pontevedra. 42 07 03.29 N 8 51 01.86 W +Baker Glacier Chugach National Forest, Alaska 61 04 53 N 148 21 52 W Baltar Baltar is a municipality in Galicia, in the province of Ourense. 41 57 04.75 N 7 42 56.7 W Barbadás 42 17 56.03 N 7 53 13.14 W -Basilique Notre-Dame de la Daurade 43 36 03 N 1 26 23 E +Basilique Notre-Dame de la Daurade 36 02.88 N 1 26 22.92 E Basilique Notre-Dame de Thierenbach 47 52 54.12 N 7 11 21.16 E -Basilique Saint-Sauveur de Rennes 48 06 42 N 1 40 55 W +Basilique Saint-Sauveur de Rennes 48 06 42 N 1 40 54 W Beade Beade is a municipality in Galicia, in the province of Ourense. 42 20 06.72 N 8 08 45.05 W +Bear Lake (Alaska) Kenai Peninsula, Alaska 60 12 03 N 149 21 11 W Bergfriedhof (Stuttgart) The Bergfriedhof is a cemetery in the Stadtbezirk Stuttgart-Ost in Stuttgart. 48 47 19.16 N 9 12 23.35 E Bergondo 43 19 15.36 N 8 13 54.04 W Berlin Anhalter Bahnhof The Anhalter Bahnhof was a large main-line railway station in Berlin. Today it is just a stop on the Berlin S-Bahn. 52 30 11 N 13 22 55 E Betanzos 43 16 44.24 N 8 12 55.95 W Bibliothèque Sainte-Geneviève 48 50 49.5 N 2 20 45 E -Bibracte 46 55 23 N 4 02 15 E +Bibracte Bibracte est le nom de la cité gauloise, capitale des Eduens, qui était située au sommet du mont Beuvray (France) 46 55 23 N 4 02 15 E Biella 45 34 05.07 N 8 03 02.61 E Bienertparks in Dresden Als Bienertpark werden verschiedene Parkanlagen in Dresden bezeichnet, deren Entstehung auf die Familie Gottlieb Traugott Bienert zurückgeht. 51 01 48.29 N 13 42 54.9 E -Bishkek 42 52 00 N 74 34 00 E +Billings Glacier Chugach National Forest, Alaska 60 52 55 N 148 34 28 W +Bishkek 42 52 00.12 N 74 34 00.12 E Boccadasse Boccadasse è un antico borgo marinaro situato nel levante di Genova. 44 23 23.85 N 8 58 22.71 E Boettcherstrasse 53 04 30 N 8 48 21 E Boiro 42 38 13.16 N 8 52 12.31 W Boke Boke is a small village in the German district Paderborn; it belongs to the city of Delbrück. 51 43 48 N 8 33 43.56 E Bolongaropalast The Bolongaro Palace is a baroque building in Frankfurt-Höchst. 50 06 04 N 8 33 08 E Borne des Trois Puissances Dreiländerstein 47 30 10.58 N 7 07 48.76 E -Borovsk Эта страница на русском: Боровск 55 12 27.19 N 36 29 05.05 E +Borovsk Borovsk, a town established in 1358, stands between Moscow and Kaluga. 55 12 27.19 N 36 29 05.05 E Bosco delle Querce The Regional Natural Park Bosco delle Querce (Oaks' Wood), built after the Seveso Disaster on the "A" zone. 45 38 55 N 9 09 10 E Botanischer Garten Heidelberg 49 25 00 N 8 40 10 E -Brancion 46 32 51 N 4 47 48.12 E -Brudermühlbrücke The Brudermühlbrücke is a bridge in Munich across the Isar. 48 06 45.3 N 11 33 36.07 E -Brudermühlstraße The Brudermühlstraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 06 44.2 N 11 33 01.37 E +Brancion Brancion is a small fortified medieval city in Burgundy, Central France. 46 32 51 N 4 47 48.12 E +Broad Pass George Parks Highway, Alaska 63 19 22 N 149 10 10 W +Brudermühlbrücke The Brudermühlbrücke is a bridge in Munich across the Isar. 48 06 45.36 N 11 33 36 E +Brudermühlstraße The Brudermühlstraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 06 43.92 N 11 32 58.56 E Buenos Aires 34 36 13 S 58 22 54 W Bueu Bueu is a municipality in Galicia, Spain in the province of Pontevedra. 42 19 24.69 N 8 47 23.1 W -Buffalo Central Terminal The New York Central Terminal in Buffalo, USA, was a key railroad station from 1929 to 1979. 42 53 22.44 N 78 49 51.08 W +Bürgerhospital (Stuttgart) 48 47 34.6 N 9 10 45.95 E Burg Stahleck Stahleck Castle in Bacharach is a 12th century castle occupying a commanding view of the Rhine in the Loreley valley. Nowadays it's a youth hostel. 50 03 29.49 N 7 45 56.46 E Burj Khalifa The Burj Khalifa ("Khalifa Tower") is a skyscraper in Dubai, United Arab Emirates. 25 11 49.7 N 55 16 26.8 E -Bürgerhospital (Stuttgart) 48 47 34.6 N 9 10 45.95 E Cabanas 43 24 50.49 N 8 10 04.15 W -Cabo Fisterra Cape Finisterre is a rock-bound peninsula on the west coast of Galicia, in Fisterra (Spain). 42 52 50.96 N 9 16 18.27 W +Cabo Fisterra 42 52 57 N 9 16 19.92 W Cabrils 41 31 42 N 2 22 09 E -Cadaqués Cadaqués is a touristic village in Costa Brava, Alt Empordà, Catalonia, Spain. 42 17 19.46 N 3 16 40.96 E +Cáceres Cáceres is the capital of Cáceres Province, in Extremadura, Spain. 39 28 23 N 6 22 16 W +Cadaqués 42 17 18.96 N 3 16 40.08 E Calgary 51 02 42 N 114 03 26 W Cambados 42 30 52.2 N 8 48 24.89 W Cambre Cambre is a municipality in the province A Coruña, Galicia, Spain. 43 17 37.32 N 8 20 34.49 W @@ -117,7 +120,8 @@ Candelabro de Paracas The Paracas Candelabra is a well-known prehistoric geoglyp Cangas 42 15 47.1 N 8 47 09.5 W Cape Arkona There are two bunkers at Cape Arkona. 54 40 47 N 13 25 57 E Cape Horn Cape Horn is often said to be the southernmost point of South America. 55 58 47 S 67 16 18 W -Capela de São Nicolau Capela de São Nicolau ou Passos da Via Sacra. Em Portugal, Porto. 41 08 27.14 N 8 36 55.49 W +Capela de São Nicolau 32 41 08 27.15 N 8 36 55.57 W +Cap Glacier Chugach National Forest, Alaska 60 56 57 N 147 54 57 W Capriata d'Orba Capriata d'Orba è un comune in provincia di Alessandria, Piemonte, Italia. 44 43 43.93 N 8 41 25.29 E Carballeda de Avia Carballeda de Avia is a municipality in Galicia, in the province of Ourense. 42 19 12.81 N 8 09 53.03 W Cariño Cariño is a municipality in the province A Coruña, Galicia, Spain. 43 43 58 N 7 52 39.76 W @@ -126,8 +130,7 @@ Cartelle Cartelle is a municipality in Galicia, in the province of Ourense. 42 1 Casa Buonarroti (Florence) Casa Buonarroti è un museo di Firenze 43 46 11.64 N 11 15 49 E Casa de las Carnicerías, León The Casa de las Carnicerías (butcher's shops), a monument declared as a Bien de Interés Cultural in 1992, is located at San Martín square, León (Spain). 42 35 48.84 N 5 34 04.4 W Casa del esquileo, Cabanillas del Monte The casa del esquileo (shearing shed) is a monument placed at Cabanillas del Monte, Torrecaballeros, Segovia (Spain). 40 58 36 N 4 01 54 W -Casa Milà Casa Milà, also known as La Pedrera (the open quarry), is a modernist building in Barcelona, Catalonia, Spain 41 23 42.66 N 2 09 42.37 E -Cassine 44 45 03 N 8 31 44 E +Casa Milà 41 23 43.08 N 2 09 42.12 E Castel del Monte Castel del Monte is a castle in Apulia, in Italy. 41 05 05.28 N 16 16 15.57 E Castellazzo Bormida Castellazzo Bormida is a comune (municipality) in the Province of Alessandria in the Italian region Piedmont 44 50 46 N 8 34 42 E Castello di Duino Il castello di Duino è un castello situato nel comune di Duino-Aurisina, in provincia di Trieste, Italia. 45 46 18.39 N 13 36 14.3 E @@ -138,7 +141,7 @@ Castelo da Rocha Forte 42 51 42.29 N 8 34 29.38 W Castelo de Castro Marim 37 13 07.43 N 7 26 29.69 W Castelo de Maceda 42 16 13.92 N 7 39 32.36 W Castelo de Monforte de Lemos 42 31 26.71 N 7 30 38.86 W -Castelo de Monterreal 42 07 29.82 N 8 50 59.18 W +Castelo de Monterreal 42 07 32.16 N 8 51 00 W Castelo de Pambre 42 51 34.87 N 7 56 53.7 W Castelo de Ribadavia 42 17 12.3 N 8 08 37.49 W Castelo de San Felipe Castillo de San Felipe is a castle in the county of Ferrol, Galicia 43 27 53 N 8 16 54 W @@ -146,27 +149,28 @@ Castelo de Santa Cruz 43 20 54.08 N 8 21 00.64 W Castelo de Santo Antón 43 21 56.6 N 8 23 16.12 W Castelo de Sobroso The Sobroso Castle is a castle located in Vilasobroso- Mondariz, Provincia of Pontevedra, Galicia (Spain). 42 12 17.31 N 8 27 20.51 W Castelo de Soutomaior 42 19 46.77 N 8 34 05.54 W -Castelo de Vilalba 43 17 52.79 N 7 40 56.44 W +Castelo de Vilalba 43 17 52.8 N 7 40 56.42 W Castelo de Vilamarín 42 27 02.87 N 7 54 02.26 W Castiñeiras, Ribeira 42 31 57.33 N 8 59 44.67 W Castrelo de Miño Castrelo de Miño is a municipality in Galicia, in the province of Ourense. 42 17 49.63 N 8 04 02.63 W Castrelo do Val Castrelo do Val is a municipality in Galicia, in the province of Ourense. 41 59 26.73 N 7 25 25.2 W Castro Caldelas Castro Caldelas is a municipality in Galicia, in the province of Ourense. 42 22 32.62 N 7 24 54 W -Castro de Baroña O Castro de Baroña está situado na parroquia de Baroña no concello de Porto do Son. 42 41 40.91 N 9 01 54.91 W +Castro de Baroña 42 41 41.8 N 9 01 55.99 W Castro de Rei 43 12 32.14 N 7 23 58.38 W Catacaos 5 16 00 S 80 41 00 W +Cataract Glacier Chugach National Forest, Alaska 61 01 39 N 148 25 23 W Catedral de Santiago de Compostela 42 52 51.27 N 8 32 42.17 W -Cathedral of Justo The Cathedral of Justo is being built by Justo Gallego in Mejorada del Campo (Community of Madrid, Spain). 40 23 38.88 N 3 29 17.99 W Cathédrale Notre-Dame d'Amiens The cathedral of Our Lady of Amiens (fr: Cathédrale Notre-Dame d'Amiens), or just Amiens Cathedral, is the tallest complete cathedral in France. 49 53 42 N 2 18 08 E -Cathédrale Notre-Dame de Chartres 48 26 50 N 1 29 16 E +Cathédrale Notre-Dame de Chartres 48 26 52 N 1 29 16 E Cathédrale Notre-Dame de Paris 48 51 10.8 N 2 20 59.28 E Cathédrale Notre-Dame de Reims Cathedral "Notre-Dame de Reims", located in Reims, France 49 15 13.9 N 4 02 02.5 E Cathédrale Notre-Dame de Strasbourg 48 34 55 N 7 45 03 E Cathédrale Notre-Dame du Havre 49 29 13 N 0 06 30 E Cathédrale Saint-André de Bordeaux 44 50 16 N 0 34 39 W Cathédrale Saint-Bénigne de Dijon 47 19 17 N 5 02 04 E -Cathédrale Saint-Julien du Mans Interior 48 00 33 N 0 11 56 E Cathédrale Sainte-Cécile d'Albi 43 55 42.57 N 2 08 34.6 E +Cathédrale Saint-Julien du Mans Interior 48 00 33 N 0 11 56 E +Cathedral of Justo The Cathedral of Justo is being built by Justo Gallego in Mejorada del Campo (Community of Madrid, Spain). 40 23 38.88 N 3 29 17.99 W Catoira Catoira is a municipality in Galicia, Spain in the province of Pontevedra. 42 39 54.98 N 8 43 57.93 W Cedeira Cedeira is a municipality in the province A Coruña, Galicia, Spain. 43 39 39.53 N 8 03 10.41 W Celanova Celanova is a municipality in Galicia, in the province of Ourense. 42 09 07.02 N 7 57 24.65 W @@ -176,56 +180,45 @@ Cesantes, Redondela 42 18 33.05 N 8 36 44.72 W Champ-de-Mars (Paris) 48 51 22 N 2 17 54 E Chantada 42 36 27.15 N 7 46 09.2 W Chapela, Redondela 42 15 53.95 N 8 40 22.71 W -Chapelle de Languidou Chapel in Plovan / Bretagne 47 54 49.13 N 4 21 09.72 W +Chapelle de Languidou 47 54 49.13 N 4 21 09.72 W Chapelle Notre-Dame de Molsheim 48 32 26.16 N 7 29 40.13 E -Chapelle Notre-Dame du Schaefertal (Soultzmatt) 47 57 06.84 N 7 12 59.4 E -Chapelle Notre-Dame du Verger Chapelle Notre-Dame du Verger dans l'anse du Verger à Cancale (Ille-et-Vilaine) 48 41 37 N 1 52 51 W Chapelle Notre-Dame-du-Chêne de Plobsheim 48 27 35.28 N 7 42 49.32 E Chapelle Notre-Dame-du-Grasweg de Huttenheim 48 21 31.32 N 7 34 33.85 E +Chapelle Notre-Dame du Schaefertal (Soultzmatt) 47 57 06.84 N 7 12 59.4 E +Chapelle Notre-Dame du Verger Chapelle Notre-Dame du Verger dans l'anse du Verger à Cancale (Ille-et-Vilaine) 48 41 37 N 1 52 51 W Chapelle royale Saint-Louis, Dreux 48 44 18 N 1 21 48 E +Chapelle Sainte-Marguerite d'Epfig 48 21 15.84 N 7 28 40.12 E +Chapelle Sainte-Marie de l'Assomption d'Obersteigen 48 38 32.28 N 7 18 22.32 E Chapelle Saint-Gonéry 48 50 29.4 N 3 13 42.38 W Chapelle Saint-Sébastien de Dambach-la-Ville 48 19 37.56 N 7 25 11.75 E Chapelle Saint-Théodore de Vienne 45 31 28.56 N 4 52 24.13 E Chapelle Saint-Ulrich d'Avolsheim 48 33 43.56 N 7 30 01.51 E -Chapelle Sainte-Marguerite d'Epfig 48 21 15.84 N 7 28 40.12 E -Chapelle Sainte-Marie de l'Assomption d'Obersteigen 48 38 32.28 N 7 18 22.32 E Chapelles du Kochersberg 48 38 42 N 7 31 14.88 E -Château d'Angers 47 28 11.67 N 0 33 33.61 W -Château de Bugarach 42 52 36.16 N 2 21 05.15 E -Château de Couiza 42 56 42.68 N 2 15 14.11 E -Château de Condé 49 00 20 N 3 33 34 E -Chiesa di Sant'Antonio in Caggiano Church of Saint Anthony in Caggiano. 40 34 04.13 N 15 29 39.47 E -Chioggia Chioggia is a town in Veneto in Italy. 45 13 04.23 N 12 16 36.76 E -Chroniques de Jérusalem Jerusalem Mount of Olives Santa Marta Passionists church. 31 46 15.83 N 35 15 08.48 E -Church of Adelboden The gothic village church of Adelboden was built in the 15th century 46 29 34.1 N 7 33 32.4 E -Church of Saints Apostles Peter and Paul in Vilnius 54 41 38.82 N 25 18 22.69 E -Church of St. Johns in Vilnius Organ 54 40 57.5 N 25 17 19.22 E -Church of São Vítor (Braga) Igreja de São Victor em Braga 41 33 09.95 N 8 24 47.49 W Château d'Anet 48 51 29 N 1 26 19 E +Château d'Angers 47 28 11.67 N 0 33 33.61 W Château d'Arlay 46 45 32.4 N 5 32 16.44 E -Château d'Azay-le-Rideau The Château de Azay-le-Rideau is one of the most famous castles in t -he French Loire Valley. 47 15 33 N 0 27 58 E -Château d'Effiat The château d'Effiat in Puy de Dôme, Auvergne, France. 46 02 37 N 3 15 06 E -Château d'If 43 16 47.5 N 5 19 30.5 E -Château d'Ussé The Château d'Ussé is a château of the Loire Valley in Rigny-Ussé. 47 14 59 N 0 17 28 E +Château d'Azay-le-Rideau The Château de Azay-le-Rideau is one of the most famous castles in the French Loire Valley. 47 15 33 N 0 27 58 E Château de Blois The Château de Blois is one of the most renowned châteaux of the Loire Valley. 47 35 07.8 N 1 19 51.42 E Château de Bressieux 45 19 21 N 5 16 45.01 E Château de Brest 48 22 52.52 N 4 29 40.95 W Château de Chambord 47 36 58.22 N 1 31 03.25 E Château de Chamerolles 48 03 37.08 N 2 09 51.01 E Château de Chantilly 49 11 38 N 2 29 09 E +Château de Châteaudun 48 04 14 N 1 19 25 E Château de Chenonceau 47 19 30 N 1 04 14.16 E Château de Cheverny 47 30 01 N 1 27 29 E Château de Chinon 47 10 05 N 0 14 10 E -Château de Châteaudun 48 04 14 N 1 19 25 E Château de Cléron 47 05 16 N 6 03 27 E +Château de Condé 49 00 20 N 3 33 34 E +Château de Crussol The Château de Crussol is a castle in the Ardèche départment of France. 44 56 18 N 4 51 09 E Château de Domfront 48 35 39 N 0 39 09 W +Château d'Effiat The château d'Effiat in Puy de Dôme, Auvergne, France. 46 02 37 N 3 15 06 E Château de Fontainebleau The Château of Fontainebleau is the largest of the French royal châteaux. 48 24 08 N 2 42 02 E Château de Frontenay 46 47 08.88 N 5 37 05.88 E Château de Gevrey-Chambertin 47 13 46 N 4 57 56 E -Château de l'Arthaudière The Château de l'Arthaudière is a castle in the Isère départment of the Rhône-Alpes région of France. 45 07 09 N 5 13 59 E Château de Lagarde 43 03 02 N 1 56 08.5 E Château de Langeais The Château de Langeais in the Loire Valley 47 19 29.28 N 0 24 21.96 E +Château de l'Arthaudière The Château de l'Arthaudière is a castle in the Isère départment of the Rhône-Alpes région of France. 45 07 09 N 5 13 59 E Château de Loches The Château de Loches in Loches is a château of the Loire Valley. The castle area, consisting of three buildings, among them one the oldest keeps in France, is one of the best preserved European architecture ensembles of the Middle Ages. 47 07 37 N 0 59 54 E Château de Maintenon 48 35 08 N 1 34 41 E Château de Malmaison Château de Malmaison was the place of residence of Joséphine de Beauharnais and Napoleon Bonaparte 48 52 15 N 2 10 01 E @@ -233,34 +226,49 @@ Château de Montfaucon 47 14 46.32 N 6 04 42.24 E Château de Murol 45 34 42 N 2 56 43 E Château de Pagax 44 36 29.88 N 2 15 06.98 E Château de Puivert 42 55 16.21 N 2 03 17.82 E +Château des Adhémar 44 33 33.02 N 4 45 15.35 E Château de Saint-Germain-en-Laye The Château de Saint-Germain-en-Laye is a former royal residence in Saint-Germain-en-Laye, located ca. 19 km to the west of Paris. Nowadays it serves as Musée des Antiquités Nationales. 48 53 53 N 2 05 47 E Château de Saint-Izaire The Château de Saint-Izaire is a castle in the Saint-Izaire commune of the Aveyron département of France 43 58 31 N 2 43 10 E +Château de Saissac The Château de Saissac is a Cathar castle in the Saissac commune, Aude département of France. 43 21 25 N 2 10 04.7 E Château de Suscinio 47 30 46 N 2 43 46 W Château de Suze-la-Rousse 44 17 14.64 N 4 50 11.62 E Château de Thorens The Château de Thorens is a castle in the commune of Thorens-Glières in the Haute-Savoie département of France. 45 59 37 N 6 15 20 E Château de Valençay The Château de Valençay is one of the châteaux of the Loire Valley in the french region Centre. 47 09 27 N 1 33 48 E +Château de Varillettes The Château de Varillettes is a château in the Cantal. 45 01 26.76 N 3 08 53.16 E Château de Vaux-le-Vicomte 48 33 53.46 N 2 42 50.4 E Château de Wangenbourg The castle of Wangenbourg is a mediaeval castle in Wangenbourg-Engental, Bas-Rhin, France. 48 37 15 N 7 18 51 E -Château des Adhémar 44 33 33.02 N 4 45 15.35 E +Château d'Harcourt The Château d'Harcourt is a castle located in the commune of Harcourt in the Eure département of France 49 10 26 N 0 47 11 E +Château d'If 43 16 47.5 N 5 19 30.5 E Château du Haut-Kœnigsbourg The castle of Haut-Kœnigsbourg is a mediaeval castle located in Orschwiller, France. 48 14 58 N 7 20 39 E -Château-Gaillard 49 14 17.26 N 1 24 09.91 E +Château d'Ussé The Château d'Ussé is a château of the Loire Valley in Rigny-Ussé. 47 14 59 N 0 17 28 E +Château-Gaillard Château-Gaillard is a castle in Les Andelys (Normandie, France). 49 14 17.26 N 1 24 09.91 E +Chena Hot Springs, Alaska 65 03 10 N 146 03 19 W +Chiesa di Sant'Antonio in Caggiano Church of Saint Anthony in Caggiano. 40 34 04.13 N 15 29 39.47 E +Chioggia Chioggia is a town in Veneto in Italy. 45 13 04.23 N 12 16 36.76 E +Chroniques de Jérusalem Jerusalem Mount of Olives Santa Marta Passionists church. 31 46 15.83 N 35 15 08.48 E +Church of Adelboden The gothic village church of Adelboden was built in the 15th century 46 29 34.1 N 7 33 32.4 E +Church of Saints Apostles Peter and Paul in Vilnius 54 41 38.82 N 25 18 22.69 E +Church of São Vítor (Braga) Igreja de São Victor em Braga 41 33 09.95 N 8 24 47.49 W +Church of St. Johns in Vilnius 54 40 57.5 N 25 17 19.22 E Cimetière du Montparnasse The Montparnasse cemetery (Fr: Cimetière du Montparnasse) is a famous cemetery in the Montparnasse quarter of Paris, France. 48 50 17 N 2 19 37 E -Cimetière du Père-Lachaise Père Lachaise Cemetery (French: Cimetière du Père-Lachaise) (officially, cimetière de l'Est “eastern cemetery”) is the largest cemetery in the city of Paris at 118 acres (48 ha), though there are larger cemeteries in Paris suburbs. 48 51 43 N 2 23 39 E +Cimetière du Père-Lachaise Père Lachaise Cemetery (French: Cimetière du Père-Lachaise) (officially, cimetière de l'Est “eastern cemetery”) is the largest cemetery in the city of Paris at 118 acres (48 ha), though there are larger cemeteries in Paris suburbs. 48 51 42.84 N 2 23 39.12 E Cinque Terre The Cinque Terre are five coastal villages in the province of La Spezia, Italy. 44 06 37.74 N 9 44 31.35 E -Ciudad Real 38 59 00 N 3 55 00 W -Clermont-Ferrand 45 46 47 N 3 05 13 E -Clos Vougeot 47 10 29.72 N 4 57 19.74 E -Collingwood Monument A monument to Admiral Collingwood (1748-1810) was erected in Tynemouth, North East England, in 1845. 55 00 52.96 N 1 25 12.14 W +City Palace (Udaipur) The City Palace in Udaipur was the royal palace of the Maharana of Mewar. The palace is located on the east bank of Lake Pichola in Udaipur, Rajasthan, India. 24 34 37.2 N 73 41 00.96 E +Ciudad Real 38 58 59.88 N 3 55 00.12 W +Clos Vougeot Clos Vougeot is a famous vineyard in Burgundy, France. 47 10 29.72 N 4 57 19.74 E +Cochrane Bay Chugach National Forest, Alaska 60 44 18 N 148 20 06 W Collégiale Notre-Dame de Melun 48 32 08 N 2 39 37 E Collégiale Saint-Florent de Niederhaslach 48 32 35 N 7 20 29 E Collégiale Saint-Martin de Colmar 48 04 38.5 N 7 21 29 E -Collégiale Saint-Thiébaut de Thann 47 48 40 N 7 06 06 E Collégiale Saints-Michel-et-Gangolphe de Lautenbach 47 56 27.96 N 7 09 32.94 E +Collégiale Saint-Thiébaut de Thann 47 48 40 N 7 06 06 E +Collingwood Monument A monument to Admiral Collingwood (1748-1810) was erected in Tynemouth, North East England, in 1845. 55 00 52.96 N 1 25 12.14 W Colonia-Haus The Colonia-Haus is a 45-storey, 147 m skyscraper completed in 1973 in the Riehl district of Cologne, Germany. 50 57 38 N 6 58 55 E Colonne Vendôme 48 52 02.89 N 2 19 45.89 E Comacchio Comacchio is a town in Emilia Romagna in Italy. 44 41 31.74 N 12 10 55.95 E Concatedral de Santa María de Guadalajara 40 38 04.72 N 3 09 45.15 W Conciergerie The Conciergerie in the Palais de Justice, Paris, France 48 51 23 N 2 20 44 E +Córdoba (Argentina) Intendancy square 31 24 00 S 64 11 00 W Corrubedo, Ribeira 42 34 21.64 N 9 04 22.76 W Cortegada Cortegada is a municipality in Galicia, in the province of Ourense. 42 12 24.86 N 8 10 01.06 W Coulée verte René-Dumont The Promenade plantée is an elevated park in the 12th arrondissement of Paris, France. 48 50 32 N 2 23 15 E @@ -269,41 +277,165 @@ Couvent de la Divine Providence de Saint-Jean-de-Bassel 48 48 12.12 N 6 59 32.0 Couvent de Reinacker 48 40 51.96 N 7 24 27.5 E Crecente Crecente is a municipality in Galicia, in the province of Pontevedra. 42 09 07.02 N 8 13 22.52 W Credit Lyonnais Head Office 48 52 14.95 N 2 20 11.45 E -Château de Crussol The Château de Crussol is a castle in the Ardèche départment of France. 44 56 18 N 4 51 09 E Cualedro 41 59 18.46 N 7 35 40.71 W Culleredo Culleredo is a municipality in the province A Coruña, Galicia, Spain. 43 17 31.02 N 8 23 08.99 W Curtis Hall Arboretum 40 04 42 N 75 07 44 W -Cáceres Cáceres is the capital of Cáceres Province, in Extremadura, Spain. 39 28 23 N 6 22 16 W -Córdoba (Argentina) Intendancy square 31 24 00 S 64 11 00 W +Cygnus olor from Carolasee The swans and pond are there since 1882. 51 01 59.16 N 13 45 52.69 E Dakar 14 43 55 N 17 27 26 W Dalhems kyrka Die Kirche von Dalhem zählt zu den berühmtesten auf Gotland. Ihr Turm, der im 14. Jahrhundert angefügt wurde, gehört zu den höchsten der Landkirchen Gotlands. 57 33 08.7 N 18 32 03.2 E Dazaifu Tenman-gū 33 31 17.49 N 130 32 05.45 E +Delaney Park, Anchorage, Alaska 61 12 47 N 149 54 04 W Dent du Géant 45 51 43 N 6 57 06 E Detroit Institute of Arts The Detroit Institute of Arts is a large art museum in Detroit, Michigan in the United States. 42 21 33.5 N 83 03 53.3 W -Deutsches Museum Verkehrszentrum München 48 07 57.85 N 11 32 40.69 E +Deutsches Museum Verkehrszentrum Ganghoferstraße 29, 80339 München 48 07 57.85 N 11 32 40.69 E Deyrulzaferan 37 17 57.6 N 40 47 33.9 E +Đình Bảng Bảng Communal House (Đình Bảng in Vietnamese) is one of largest and finest village communal houses in Việt Nam. 21 06 29.99 N 105 57 06.31 E +Doran Strait Chugach National Forest, Alaska 61 04 34 N 148 11 20 W +Dorfkirche Dabergotz 52 54 10.44 N 12 43 30.42 E +Dorfkirche Golzow (Barnim) 52 54 41.37 N 13 48 32.69 E +Dorfkirche Hohenfinow 52 48 38.1 N 13 55 29.08 E +Dorfkirche Kirchlotheim 51 10 07.83 N 8 53 46.05 E Dorfkirche Klein Haßlow Church in Klein Haßlow, Wittstock municipality, Ostprignitz-Ruppin district, Brandenburg state, Germany 53 10 29.84 N 12 31 28.6 E Dorfkirche Priort Church in Priort, Wustermark municipality, Havelland district, Brandenburg state, Germany. 52 30 44.61 N 12 57 49.36 E +Dorfkirche Zechow 53 03 18.01 N 12 54 44.88 E Dozón 42 34 09.35 N 8 03 08.25 W Drexel University 39 57 14.68 N 75 11 12.76 W Duchesse Anne (voilier) 51 02 15.37 N 2 22 20.21 E Duino-Aurisina 45 45 02.29 N 13 40 29.6 E Durban 29 53 00 S 31 03 00 E Dürrenstein (Südtirol) The Dürrenstein is a mountain in the Dolomites in South Tyrol. 46 40 24 N 12 11 04 E -Effnerplatz The Effnerplatz is a square in the north of Munich, in the Borough Bogenhausen. 48 09 11.79 N 11 36 54.73 E -Église Saint-Jean-Baptiste de Laure-Minervois 43 16 20.78 N 2 31 12.11 E -Église Saint-Louis-en-l'Île The Saint-Louis-en-l'Île Church (lit. "St. Louis on the Island"), is a Catholic church located on Île Saint-Louis in the IVe arrondissement of Paris 48 51 4.38 N 2 21 27.47 E +École centrale de Lille École Centrale de Lille is a graduate engineering school located in campus Lille I within Université Lille Nord de France. 50 36 21.62 N 3 08 13.63 E +École Jules Ferry de Royan 45 37 38.16 N 1 01 33.66 W +Effnerplatz The Effnerplatz is a square in the north of Munich in the Borough Bogenhausen. 48 09 09 N 11 36 51.12 E +Église de la Sainte-Trinité (Lauterbourg) 48 58 30.1 N 8 10 40.77 E +Église de l'Assomption simultanée (La Petite-Pierre) 48 51 25.2 N 7 18 55.84 E +Église de Saint-Lothain 46 49 27.84 N 5 38 30.12 E +Église de Saint-Paul de Frontignan L'Église de Saint-Paul de Frontignan est une église catholique de l'ancien diocèse de Maguelone en Languedoc, France. 43 26 50.47 N 3 45 18.66 E +Église des Augustins (Ribeauvillé) 48 11 43.44 N 7 19 08.87 E +Église des Jésuites (Molsheim) 48 32 25.3 N 7 29 45 E +Église des Saints-Innocents (Blienschwiller) 48 20 25.8 N 7 25 06.17 E +Église Notre-Dame de la Dalbade 43 35 51.36 N 1 26 32.89 E +Église Notre-Dame-de-la-Nativité (Saverne) 48 44 28.32 N 7 21 50.36 E +Église Notre-Dame-de-l'Assomption (Bergheim) 48 12 18 N 7 21 53.28 E +Église Notre-Dame-de-l'Assomption (Bernardswiller) 48 27 10.08 N 7 27 49.57 E +Église Notre-Dame-de-l'Assomption (Monswiller) 48 45 17.61 N 7 22 39.66 E +Église Notre-Dame-de-l'Assomption (Rosenwiller) 48 30 21.96 N 7 26 25.48 E +Église Notre-Dame-de-l'Assomption (Rouffach) 47 57 24 N 7 18 02 E +Église Notre-Dame (Guebwiller) 47 54 20.75 N 7 12 52.56 E +Église protestante (Balbronn) 48 35 05.28 N 7 26 15.97 E +Église protestante (Baldenheim) 48 14 15 N 7 32 14.35 E +Église protestante (Berg) 48 53 52.08 N 7 09 24.01 E +Église protestante (Bischheim) 48 36 55.08 N 7 45 21.89 E +Église protestante du Temple Neuf (Strasbourg) 48 35 00 N 7 44 54 E +Église protestante (Fouday) 48 25 17.76 N 7 11 12.95 E +Église protestante (Harskirchen) 48 56 02.04 N 7 02 20.15 E +Église protestante (Scharrachbergheim) 48 35 35.52 N 7 29 55.9 E +Église protestante (Schiltigheim) 48 36 21.96 N 7 45 05.04 E +Église protestante (Sélestat) 48 15 36.36 N 7 27 11.56 E +Église protestante (Weiterswiller) 48 51 10.44 N 7 24 50.9 E +Église Sainte-Marie-Madeleine de Rennes-le-Château 42 55 41.05 N 2 15 45.69 E +Église Saint-Eustache de Paris 48 51 48 N 2 20 42 E +Église Saint-Gervais-Saint-Protais 48 51 19.8 N 2 21 16.6 E +Église Saint-Laurent (Paris) 48 52 29.45 N 2 21 29.92 E +Église Saint-Louis-en-l'Île The Saint-Louis-en-l'Île Church (lit. "St. Louis on the Island"), is a Catholic church located on Île Saint-Louis in the IVe arrondissement of Paris 48 51 4.38 N 2 21 27.47 E Église Saint-Martin de Chambonas 44 25 02.45 N 4 07 43.97 E -Eglise Saint-Pierre des Cuisines 43 36 15.49 N 1 26 08.26 E +Église Saint-Michel d'Ernolsheim-lès-Saverne Bells 48 47 27.85 N 7 22 47.57 E +Église Saint-Nicolas-du-Chardonnet St. Nicolas du Chardonnet is a church in the centre of Paris, France located in the 5th arrondissement. 48 50 57 N 2 21 01 E +Église Saint-Pierre de Montmartre Saint-Pierre de Montmartre is a church in Paris 48 53 12 N 2 20 31 E +Église Saint-Pierre-de-Rhèdes 43 35 16.22 N 3 04 43.64 E +Eglise Saint-Pierre des Cuisines L'Église Saint-Pierre des Cuisines, située rue de la Boule, à côté de la place Saint-Pierre à Toulouse, est la plus vieille église du sud-ouest de la France. Elle est construite sur une ancienne nécropole gallo-romaine du IVe siècle. 43 36 15.49 N 1 26 08.26 E +Église Saint-Pierre-Saint-Paul de Rueil-Malmaison 48 52 35.4 N 2 10 53.15 E +Église Saints-Pierre-et-Paul (Andlau) 48 23 16.3 N 7 24 54.3 E +Église Saints-Pierre-et-Paul (Eguisheim) 48 02 32.28 N 7 18 21.2 E +Église Saints-Pierre-et-Paul (Hohatzenheim) 48 42 44.64 N 7 36 59.11 E +Église Saints-Pierre-et-Paul (Neuwiller-lès-Saverne) 48 49 25 N 7 24 20 E +Église Saints-Pierre-et-Paul (Obernai) 48 27 47.88 N 7 28 54.48 E +Église Saints-Pierre-et-Paul (Ottmarsheim) 47 47 13.2 N 7 30 25.2 E +Église Saints-Pierre-et-Paul (Rosheim) 48 29 48 N 7 28 14 E +Église Saints-Pierre-et-Paul (Sigolsheim) 48 08 04.2 N 7 18 03.1 E +Église Saints-Pierre-et-Paul (Wissembourg) 49 02 14 N 7 56 30 E +Église Saint-Sulpice 48 51 04 N 2 20 05 E Église Saint-Vincent-de-Paul (Paris) Saint-Vincent-de-Paul is a church in Paris near the Gare du Nord 48 52 43.7 N 2 21 06.6 E -El Padul 37 01 27 N 3 37 36 W +Églises St Pierre le Vieux (Strasbourg) protestant church 48 34 58 N 7 44 24 E +Église St Antoine de Padoue (Saverne) 48 44 29.4 N 7 21 40.82 E +Église St Arbogast (Offenheim) 48 37 53.76 N 7 36 59.54 E +Église St Barthélemy (Sarrewerden) 48 55 22.8 N 7 04 56.93 E +Église St Benoît (Bergholtzzell) 47 55 51.34 N 7 13 54.48 E +Église St Blaise (Valff) 48 25 12.36 N 7 31 06.96 E +Église St Cyriaque (Altorf) 48 31 22.7 N 7 31 50 E +Église Ste Anne (Turckheim) 48 05 15.72 N 7 16 41.12 E +Église Ste Aurélie protestante (Strasbourg) 48 34 53 N 7 44 00 E +Église Ste Colombe (Hattstatt) 48 00 44.28 N 7 18 06.01 E +Église Ste Croix (Kaysersberg) Lamentation of Christ 48 08 20.04 N 7 15 48.56 E +Église Ste Croix (Rountzenheim) 48 49 08.76 N 8 00 26.39 E +Église Ste Foy (Sélestat) 48 15 33.67 N 7 27 21.81 E +Église Ste Lucie (Niederhergheim) 47 59 10.32 N 7 23 48.41 E +Église Ste Madeleine (Strasbourg) 48 34 48 N 7 45 17 E +Église Ste Marguerite (Geispolsheim) 48 30 50.4 N 7 38 36.06 E +Église Ste Odile (Lapoutroie) 48 09 08.64 N 7 10 03.97 E +Église Ste Odile (Wintzfelden) 47 58 32.88 N 7 11 49.92 E +Église St Étienne (Rosheim) 48 29 43.8 N 7 27 59.72 E +Église St Étienne (Seltz) 48 53 37.32 N 8 06 28.44 E +Église St Étienne simultanée (Wangen) 48 37 01.56 N 7 27 53.68 E +Église Ste Walburge (Walbourg) 48 53 05.51 N 7 47 21.97 E +Église St Gall (Niedermorschwihr) 48 05 57.84 N 7 16 26.47 E +Église St Gall protestante (Domfessel) 48 57 06.48 N 7 09 07.56 E +Église St Georges (Châtenois) 48 16 09.12 N 7 23 51 E +Église St Georges (Sélestat) 48 15 36 N 7 27 24.12 E +Église St Grégoire (Ribeauvillé) 48 11 49.2 N 7 19 00.41 E +Église St Guillaume protestante (Strasbourg) 48 34 55.5 N 7 45 28 E +Église St Hippolyte (Saint-Hippolyte) 48 14 01.68 N 7 22 04.01 E +Église St Jacques-le-Majeur (Kuttolsheim) 48 38 37.32 N 7 31 41.34 E +Église St Jacques-le-Majeur simultanée (Dettwiller) 48 45 12.6 N 7 27 56.77 E +Église St Jacques-le-Majeur simultanée (Hunawihr) 48 10 42.24 N 7 18 38.02 E +Église St Jean-Baptiste (Saint-Jean-Saverne) 48 46 18.7 N 7 21 48.5 E +Église St Jean-Baptiste simultanée (Hohwiller) 48 45 12.78 N 7 27 56.77 E +Église St Jean-Baptiste (Surbourg) 48 54 34.2 N 7 50 50.28 E +Église St Jean-Baptiste (Wattwiller) 47 50 07.72 N 7 10 37.27 E +Église St Jean protestante (Wissembourg) 49 02 18.96 N 7 56 33.36 E +Église St Jean (Strasbourg) 48 35 04 N 7 44 25 E +Église St Laurent (Dieffenbach-au-Val) 48 18 44.64 N 7 19 41.34 E +Église St Laurent protestante (Dorlisheim) 48 31 30 N 7 29 13.99 E +Église St Léger (Guebwiller) 47 54 42.1 N 7 12 33.75 E +Église St Léger (Murbach) 47 55 24 N 7 09 29 E +Église St Martin (Ammerschwihr) 48 07 37.92 N 7 16 54.01 E +Église St Martin (Ebersheim) 48 18 14.04 N 7 30 14.08 E +Église St Martin (Pfaffenheim) 47 59 05.28 N 7 17 08.59 E +Église St Martin protestante (Barr) 48 24 33.84 N 7 26 51.47 E +Église St Martin protestante (Westhoffen) 48 36 01.8 N 7 26 30.3 E +Église St Maurice (Ebersmunster) 48 18 39.5 N 7 31 37 E +Église St Maurice (Fegersheim) 48 29 23.64 N 7 40 50.27 E +Église St Maurice (Orschwiller) 48 14 27.24 N 7 22 44.62 E +Église St Maurice (Soultz-Haut-Rhin) 47 53 13.2 N 7 13 48.29 E +Église St Maurice (Soultz-les-Bains) 48 34 17.4 N 7 29 09.35 E +Église St Maurice (Willgottheim) 48 40 14.52 N 7 30 33.23 E +Église St Médard (Bœrsch) 48 28 40.44 N 7 26 24.4 E +Église St Michel (Reichshoffen) 48 55 54.84 N 7 39 52.02 E +Église St Michel (Weyersheim) 48 43 06.24 N 7 48 07.96 E +Église St Nicolas (Haguenau) 48 49 13 N 7 47 32 E +Église St Nicolas (Neuve-Église) 48 19 50.88 N 7 18 48.24 E +Église St Nicolas (Wingersheim) 48 43 18.84 N 7 38 08.02 E +Église St Pantaléon (Gueberschwihr) 48 00 16.92 N 7 16 29.78 E +Église St Paul protestante (Strasbourg) 48 35 11 N 7 45 35 E +Église St Pierre "Dompeter" (Molsheim, Avolsheim) 48 33 24.12 N 7 30 19.59 E +Église St Pierre le Jeune catholique (Strasbourg) 48 35 18.35 N 7 44 55.75 E +Église St Pierre le Jeune protestante (Strasbourg) 48 35 08 N 7 44 47 E +Église St Rémi (Itterswiller) 48 21 51.48 N 7 25 37.42 E +Église St Sébastien (Soultzmatt) 47 57 37.08 N 7 14 15.36 E +Église St Thomas protestante (Strasbourg) 48 34 47 N 7 44 44 E +Église St Trophime (Eschau) 48 29 25.08 N 7 42 57.96 E +Église St Ulrich (Altenstadt) 49 01 49.8 N 7 58 05.88 E +Église St Ulrich (Wittersheim) 48 46 53.04 N 7 39 27.47 E +Eklutna Village Cemetery Anchorage, Alaska 61 27 38 N 149 21 42 W El Vendrell 41 13 11.72 N 1 32 04.08 E Empúries Empúries is a town on the Mediterranean coast of the Catalan comarca of Alt Empordà in Catalonia, Spain. 42 08 20.29 N 3 07 11.19 E Enclos paroissial de Saint-Thégonnec 48 31 13.4 N 3 56 47.44 W -Erica, Victoria 37 59 00 S 146 22 00 E +Erica, Victoria 37 59 00 S 146 22 00 E Erlöserkirche (Bad Homburg) The Church of the Redeemer is a protestant church in Bad Homburg, Germany. 50 13 35.5 N 8 36 42 E Esgos 42 19 29.71 N 7 41 45.94 W +Esther Passage Chugach National Forest, Alaska 60 53 20 N 147 56 27 W European Parliament The European Parliament is the parliament of the European Union. 48 35 51.82 N 7 46 09.82 E +Explorer Glacier Chugach National Forest, Alaska 60 46 34 N 148 55 03 W Familistère 49 54 15 N 3 37 31 E Fangelsbachfriedhof The Fangelsbachfriedhof is one of the most important historical cemeteries in Stuttgart. 48 45 56 N 9 10 28 E Feldkommandostelle Hegewald (East Prussia) 54 08 05.54 N 21 58 36.02 E @@ -312,115 +444,129 @@ Ferrol 43 29 21.47 N 8 13 29.94 W Ferrytoll Park & Ride Ferrytoll Park & Ride is a bus/car interchange in Fife, Scotland, at the northern end of the Forth road crossing. 56 01 21.47 N 3 24 22.97 W Fieschergletscher 46 30 07.88 N 8 08 30.59 E Fiesole (area archeologica) 43 48 29.04 N 11 17 39.19 E +Filialkirche hl. Gotthart in Lansach, Weißenstein 46 41 12.84 N 13 42 16.56 E Fish Creek, Victoria 38 41 00 S 146 05 00 E Flaucher Flaucher is an area in the south of Munich on the left and right hand side of the Isar (district: Sendling and Thalkirchen). 48 06 27 N 11 33 27 E Fontaine des Neuf-Canons 43 31 36.12 N 5 26 55.25 E Fontaine du Palmier 48 51 26.99 N 2 20 50.17 E +Forêt domaniale de Sète The National Forest of Sète in the commune of Sète, Hérault, France. 43 24 18.74 N 3 40 13.74 E +Forge d'Étueffont 47 43 20.9 N 6 55 15.19 E +Fortaleza da Nogueirosa 43 23 29.12 N 8 08 09.12 W +Fortaleza de San Paio de Narla 43 00 25.83 N 7 49 14 W Fort Boyard Fort Boyard is a fort located between the île d'Aix and the île d'Oléron in the Pertuis d'Antioche straits, on the west coast of France. 45 59 58.71 N 1 12 50.16 W Fort de Bessoncourt 47 38 58.41 N 6 55 37.74 E Fort de la Miotte 47 38 53.29 N 6 52 30.33 E -Fort de Vézelois 47 36 01.67 N 6 54 29.41 E Fort des Basses Perches 47 37 34.05 N 6 52 06.81 E +Fort de Vézelois 47 36 01.67 N 6 54 29.41 E Fort du Bois d'Oye 47 34 27.7 N 6 50 36.55 E -Fort Ross Fort Ross, a former Russian fur trade outpost, located on the coast of Northern California (United States). 38 30 51.35 N 123 14 36.88 W -Fortaleza da Nogueirosa 43 23 29.12 N 8 08 09.12 W -Fortaleza de San Paio de Narla 43 00 25.83 N 7 49 14 W Forte di Gavi Il Forte di Gavi è una fortezza storica costruita su un preesistente castello di origine medioevale. 44 41 27.95 N 8 48 15.55 E Fortezza del Priamar La fortezza del Priamar è un antico insediamento storico presente nella città ligure di Savona, Italia. 44 18 16.29 N 8 29 03.44 E -Forêt domaniale de Sète The National Forest of Sète in the commune of Sète, Hérault, France. 43 24 18.74 N 3 40 13.74 E +Fort Ross Fort Ross, a former Russian fur trade outpost, located on the coast of Northern California. 38 30 51.35 N 123 14 36.88 W Fosse De Sessevalle 50 22 11.03 N 3 15 41.09 E Four solaire d'Odeillo The "Centre du Four Solaire Félix Trombe" is located in Odeillo, France. 42 29 37 N 2 01 45 E +Fox Island (Alaska) Kenai Peninsula, Alaska 59 54 46 N 149 20 52 W Francelos, Ribadavia 42 16 35.51 N 8 09 34.88 W Franciscan Monastery in Katowice Panewniki Neo-Romanesque monastery of the Franciscans in Katowice Panewniki in Poland from the early XX century. 50 13 37 N 18 57 45 E -Pfarrkirche St. Bartholomäus in Friesach 46 57 04.28 N 14 24 18.19 E Fubine Fubine è un comune in provincia di Alessandria, Piemonte, Italia. 44 57 55.35 N 8 25 32.75 E Funkturm Leipzig 51 18 49.02 N 12 23 34.93 E -Fuzhou Fuzhou, also known as Foochow, is a city in China. 26 04 16 N 119 18 13 E +Fuzhou 26 04 16 N 119 18 13 E +Galata Bridge Galata Bridge crosses the Golden Horn in Istanbul, Turkey 41 01 13.1 N 28 58 24.4 E Gandino 45 48 42 N 9 54 11 E -Gardens of Nymphenburg Palace Der Nymphenburger Schlosspark ist eines der größten und bedeutendsten Gartenkunstwerke Deutschlands. 48 09 29 N 11 30 13 E +Gardens of Nymphenburg Palace Der Nymphenburger Schlosspark ist eines der größten und bedeutendsten Gartenkunstwerke Deutschlands. 48 09 28 N 11 29 34 E Gare de Metz-Ville 49 06 35.28 N 6 10 39 E -Gare de Paris-Est Literally East Station, Paris, but usually called Gare de l'Est in Paris, France. 48 52 37 N 2 21 33 E -Gare de Paris-Nord Literally North Station, Paris, but usually called Gare du Nord in Paris, France. 48 52 58 N 2 21 24 E +Gare de Paris-Est 48 52 36.84 N 2 21 33.12 E +Gare de Paris-Nord 48 52 58 N 2 21 24 E Gare de Paris-Saint-Lazare Gare Paris Saint-Lazare is one of the six large terminus railway stations of Paris. 48 52 37 N 2 19 28 E -Garmischer Straße The Garmischer Straße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 07 28.03 N 11 31 14.51 E +Garmischer Straße The Garmischer Straße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 07 28.2 N 11 31 14.52 E Garten des Himmlischen Friedens The Garten des Himmlischen Friedens (lit. Garden of Heavenly Peace) is a small walled Chinese garden in the Bethmannpark in Frankfurt-Nordend 50 07 07.57 N 8 41 26.52 E Gavi Gavi is a town in Piemonte in Italy. 44 41 19.35 N 8 48 10.64 E Gedankengang Offenbach This is part of a series of tunnels in Offenbach that have been redesigned. 50 05 58.64 N 8 45 49.92 E -Georg-Brauchle-Ring The Georg-Brauchle-Ring is a street in Munich. 48 10 34.46 N 11 32 35.48 E Gernikako Arbola The Gernika oak where the lords of Biscay (including several kings of Castile and Spain) came to take the oath of respect to the basques Fueros (Rules and Rights). 43 18 53.43 N 2 40 47.92 W Giardino dei Semplici di Firenze The Orto Botanico di Firenze (2.3 hectares), also known as the Giardino dei Semplici, is a botanical garden maintained by the University of Florence. 43 46 45 N 11 15 39 E Giurtelecu Șimleului Giurtelecu Șimleului is a settlement in Romania. 47 18 N 22 48 E Glanum 43 46 26 N 4 49 57 E +Godwin Glacier Chugach National Forest, Alaska 60 07 45 N 149 12 52 W Goethedenkmal (Wien) The Goethe monument at the Opernring in Vienna by Edmund Hellmer 48 12 12.07 N 16 21 57.73 E Gogar Tram Depot 55 56 22.27 N 3 19 36.44 W +Göltzschtalbrücke 50 37 21.29 N 12 14 37.46 E +Goose Lake Park, Anchorage, Alaska 61 11 49 N 149 49 13 W Gorle 45 42 14 N 9 43 08 E +Görzig (Rietz-Neuendorf) Train station 52 14 20.25 N 14 11 48.91 E Government House, Jersey 49 11 41.44 N 2 05 39.78 W Gradara Gradara is a town in Marche, Italy. 43 56 15.75 N 12 45 59.25 E +Gråmanstorps kyrka 56 08 59.33 N 13 06 00.4 E Grand Hôtel de Cabourg 49 17 37.32 N 0 06 59.08 W Grand Palais The Grand Palais in Paris, France 48 51 58 N 2 18 45 E -Granollers Granollers is a city near Barcelona, in Catalonia, Spain. 41 32 35.1 N 2 12 59.63 E -Gromo Gromo is a town in Lombardia in Italy. 45 58 09.91 N 9 55 25.72 E -Gråmanstorps kyrka 56 08 59.33 N 13 06 00.4 E +Gromo Gromo is a town in Lombardia in Italy. 45 57 51.84 N 9 55 39 E +Grouse Lake Kenai Peninsula, Alaska 60 12 05 N 149 22 29 W +Gulkana Glacier Eastern Alaska Range, Alaska 63 14 26 N 145 28 03 W Gut Böckel Böckel Castle in Rödinghausen, District of Herford, North Rhine-Westphalia, Germany. 52 13 29.1 N 8 31 02.98 E Gymnasium Koblenzer Straße The Gymnasium Koblenzer Straße, also known as Kobi, is a German grammar school in Urdenbach, an urban borough of Düsseldorf. 51 08 58.67 N 6 53 08.95 E -Göltzschtalbrücke 50 37 21.29 N 12 14 37.46 E -Hamburg Hamburg is a City-State in the North of Germany and one of the biggest seaports in Europe. 53 34 07 N 10 02 19 E +Haage Train station 52 40 37.61 N 12 35 48.46 E Hamburger Rathaus 53 33 01 N 9 59 32 E +Hamburg Hamburg is a City-State in the North of Germany and one of the biggest seaports in Europe. 53 34 07 N 10 02 19 E +Hamburg-Moorburg Sprengung Kraftwerk Bursting of the 256 meters high chimney of the deactivated HEW power plant in Hamburg-Moorburg, Germany. The chimney was Hamburg's highest massiv building. The HEW power plant Hamburg-Moorburg was in operation from 1974 untill 2001. It was one of the biggest conventional power plant in Germany and was fired on both with natural gas and fuel oil. 53 29 24 N 9 57 06 E Hameau de la Reine 48 49 07 N 2 06 46 E -Hampigny 48 27 21 N 4 35 24 E -Hansestaden Visby The Hanseatic town Visby was founded in the 10th century, on the then independent Baltic Sea island of Gotland. 57 38 20 N 18 17 40 E -Château d'Harcourt The Château d'Harcourt is a castle located in the commune of Harcourt in the Eure département of France 49 10 26 N 0 47 11 E +Hammer (Liebenwalde) Former town hall 52 52 54.39 N 13 26 32.69 E +Hansestaden Visby The Hanseatic town Visby is the description of Visby, Sweden, from the UNESCO World Heritage Committee. 57 38 20 N 18 17 40 E +Hans Paasche Hans Paasche (3 April 1881 – 21 May 1920) was a German politician and pacifist. 52 59 48.32 N 15 58 47.1 E +Harriman Fjord Chugach National Forest, Alaska 61 02 20 N 148 19 17 W Haus Werburg Haus Werburg is a small water castle in Spenge, Kreis Herford. 52 08 30.78 N 8 28 33.66 E Hazmburk Hazmburk is a hill with castle in České středohoří in Czech Republic. 50 26 03 N 14 00 52 E -Heckenstallerstraße The Heckenstallerstraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 06 35.77 N 11 31 42 E +Heckenstallerstraße The Heckenstallerstraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 06 35.64 N 11 31 41.88 E Hellig Kors Kirke Hellig Kors Kirke is a church on Nørrebro in Copenhagen, Denmark. 55 41 15.72 N 12 33 05.04 E Henninger-Turm The 120-m-high Henninger Turm is located in Frankfurt-Sachsenhausen in Germany. 50 05 50.16 N 8 41 36.77 E Herford Herford is a city in North Rhine-Westphalia, Germany. 52 06 57.81 N 8 40 12.11 E HMS Otus The HMS Otus is a british Oberon class submarine. It serves today as a museum Sassnitz harbour. 54 30 43.13 N 13 38 29.79 E -Holy Trinity Cathedral in Odessa 46 28 34.36 N 30 44 18.43 E +Holgate Arm Kenai Fjords National Park, Alaska 59 49 56 N 149 47 56 W +Holy Trinity Cathedral in Odessa Holy Trinity Cathedral in Odessa 46 28 33.96 N 30 44 17.16 E +Hope Highway, Alaska Kenai Peninsula, Alaska 60 46 50 N 149 25 50 W Hoppenlaufriedhof The Hoppenlaufriedhof is a cemetery in Stuttgart. 48 46 54 N 9 10 05 E Horyuji Hōryū-ji (法隆寺, "Temple of the Flourishing Law") is a Buddhist temple in Ikaruga, Nara Prefecture, Japan. 34 36 53.06 N 135 44 03.02 E Hospitalkirche (Stuttgart) 48 46 40 N 9 10 22 E -Humprecht Humprecht is a castle on top of a hill near Sobotka in the Hradec Králové region in the Czech Republic. 50 28 13 N 15 10 11 E Hôtel Biron 48 51 19 N 2 18 57 E -Hôtel d'Ulmo 43 35 51 N 1 26 59.28 E Hôtel de Bourgtheroulde 49 26 31.2 N 1 05 17.77 E Hôtel de Sens 48 51 12 N 2 21 33 E Hôtel de Soubise 48 51 38 N 2 21 30 E +Hôtel d'Ulmo 43 35 51 N 1 26 59.28 E Hôtel Lutetia 48 51 04 N 2 19 39 E Hôtel Négresco 43 41 40 N 7 15 27 E -Igreja de São Martinho de Aldoar 41 10 14.58 N 8 40 13.83 W +Hübners Mühle in Werder (Havel) The fire ruin of the windmill of miller and baker named Hübner in Werder (Havel) 52 22 28.38 N 12 55 15.28 E +Humprecht Humprecht is a castle on top of a hill near Sobotka in the Hradec Králové region in the Czech Republic. 50 28 13.08 N 15 10 10.92 E +Igreja de São Martinho de Aldoar 41 10 14.59 N 8 40 13.84 W Igrexa de San Pedro de Vilanova de Dozón The romanic parochial Church of San Pedro of Dozón 42 35 06.77 N 8 01 27.02 W -Igrexa de Santa María de Cambre 43 17 32.03 N 8 20 34.4 W +Igrexa de Santa María de Cambre 43 17 31.92 N 8 20 34.08 W Igrexa de Santo Antolín de Toques 42 58 41.36 N 7 58 59.23 W Illa de Cortegada 42 37 05.87 N 8 47 02.7 W Iloilo City The City of Iloilo is the capital city of the Provinces of the Philippines of Iloilo. 10 41 24 N 122 33 00 E Innerer Plauenscher Friedhof Cemetery „Innerer Plauenscher Friedhof“ near church „Auferstehungskirche“ in Dresden-Plauen 51 01 42.38 N 13 42 15.91 E Institut de théologie orthodoxe Saint-Serge 48 52 59.98 N 2 23 01.23 E -Isarring The Isarring is a street in Munich, part of the Mittlerer Ring around the city centre. 48 09 36.65 N 11 36 03.89 E -Isfahan اصفهان 32 39 05 N 51 40 45 E +Isabel Pass Richardson Highway, Alaska 63 11 15 N 145 33 28 W +Isarring The Isarring is a street in Munich, part of the Mittlerer Ring around the city centre. 48 09 36.72 N 11 36 03.96 E Isla San Carlos Isla San Carlos or peninsula of San Carlos, is part of Venezuela and is located north of the island of Toas. 10 59 42.73 N 71 36 43.16 W Ivrea Ivrea is a town in Piemonte in Italy. 45 27 50.4 N 7 52 42.96 E Jagdschloss Wermsdorf 51 16 59.52 N 12 56 21.85 E Jardin de l'État The Jardin de l'État is a botanical garden on Réunion island. 20 53 12 S 55 27 04 E Jardin des Tuileries 48 51 50 N 2 19 34 E -Jaroměř Pond 50 21 22.45 N 15 55 17.21 E +Jaroměř Pond 50 21 21.6 N 15 55 15.6 E Jesuitenkirche (Wien) The Jesuitenkirche (Jesuit church) is a prominent church in Vienna, Austria. 48 12 32.95 N 16 22 39.48 E Jin Mao Tower Jin Mao Building 31 14 14 N 121 30 05 E Johannesburg Johannesburg is the largest city in South Africa. 26 12 16 S 28 02 44 E +José María Acuña López José María Acuña López, born in Pontevedra (Spain) on April 4, 1903 and died on 4 June 1991 in Vigo (Spain), was a spanish sculptor. 42 19 46.38 N 8 34 04.43 W Jubiläumssäule 48 46 42.85 N 9 10 47.53 E -Jumkils kyrka Jumkils kyrka tillhör Bälingebygdens församling, Upplands västra kontrakt, Uppsala stift / Diocese of Uppsala. 59 56 33.2 N 17 25 23.7 E Jüdischer Friedhof Haunetal 50 45 12.6 N 9 41 00.6 E +Jumkils kyrka Jumkils kyrka tillhör Bälingebygdens församling, Upplands västra kontrakt, Uppsala stift / Diocese of Uppsala. 59 56 33.2 N 17 25 23.7 E Kaaba 21 25 21.11 N 39 49 34.41 E Kagawa prefecture Kagawa Prefecture (香川県, Kagawa-ken?) is a prefecture of Japan located on Shikoku island. The capital is Takamatsu. 34 20 24.4 N 134 02 35.8 E -Kansai International Airport Kansai International Airport, is an international airport located on an artificial island in the middle of Osaka Bay, off the shore of Sennan district of Osaka, Japan. 34 26 03 N 135 13 58 E +Kansai International Airport Kansai International Airport is an international airport located on an artificial island in the middle of Osaka Bay, off the shore of Sennan district of Osaka, Japan. 34 26 03 N 135 13 58 E Karlsfried Karlsfried Castle is situated nearby the town of Zittau in Sachsen, Germany. 50 50 05.05 N 14 47 32.29 E Katharinenhospital Stuttgart 48 48 01.87 N 9 12 21.6 E -Kathmandu 27 43 00 N 85 22 00 E +Kathmandu 27 43 12 N 85 22 12 E Kiel Kiel is the capital city and most populous city of the northern German state Schleswig-Holstein. 54 19 31 N 10 08 26 E Kleinmarkthalle Frankfurt Vegetable stall 50 06 45 N 8 41 01 E Klimkówka - stary dwór 49 35 18.78 N 21 49 50.14 E Kloster Ettal The monastery of Ettal is a Benedictine monastery in Bavaria/Germany near Oberammergau. 47 34 09.33 N 11 05 40.42 E +Korsberga kyrka, Småland 57 18 25.2 N 15 07 25.6 E Kotohira Gu Kotohira Gu in Kotohira, Kagawa prefecture, Japan. 34 11 02.2 N 133 48 34 E Kreis Herford 52 06 57.54 N 8 39 40.42 E Kreis Minden-Lübbecke Der Kreis Minden-Lübbecke ist ein Landkreis im Osten des Landes Nordrhein-Westfalen mit Sitz in Minden. 52 16 53.48 N 8 54 41.71 E @@ -429,32 +575,31 @@ Kriegerdenkmal in Arnsdorf (Ruhland) 51 25 48.02 N 13 51 05.5 E Kronprinzenpalais (Stuttgart) 48 46 41.56 N 9 10 39.88 E Krumbach (Schwaben) Krumbach (Schwaben) ist eine Stadt im Landkreis Günzburg, Regierungsbezirk Schwaben, Bayern. 48 14 35 N 10 21 48 E Krummesse Krummesse is a village in Schleswig-Holstein, Germany, which partly belongs to Kreis Herzogtum Lauenburg and partly to Lübeck. 53 46 45 N 10 38 30 E -Kuala Lumpur 3 09 35 N 101 42 00 E +Kuala Lumpur 3 08 52.08 N 101 41 43.08 E Kunsthalle Bremen 53 04 22 N 8 48 49 E Kuressaare 58 09 00 N 22 16 48 E Kusterdingen 48 31 20.28 N 9 07 15.24 E Lac Blanc (Orbey) Dans le massif des Vosges, près d'Orbey. 48 07 31.32 N 7 05 34.95 E -Lac Chambon 45 34 13 N 2 55 18 E Lac de Serre-Ponçon Le Lac de Serre-Ponçon, vallé de l'Ubaye, Hautes-Alpes, France 44 30 33.26 N 6 22 10.8 E -Lac des Dix 46 03 25.74 N 7 23 51.17 E +Lake Louise, Alaska Borough di Matanuska-Susitna, Alaska 62 19 26 N 146 32 56 W Lalín Lalín is a municipality in Galicia, Spain in the province of Pontevedra. 42 39 36.8 N 8 06 43.31 W Langes Tannen 53 41 32.67 N 9 40 28.6 E -Large Hadron Collider CERN collider near Geneva, Switzerland 46 16 17 N 6 03 48.5 E +Large Hadron Collider 46 16 17 N 6 03 48.5 E Larouco Larouco is a municipality in Galicia, in the province of Ourense. 42 20 48.74 N 7 09 37.22 W Lavoir de Gex 46 20 02.04 N 6 03 30.02 E Laza Laza is a municipality in Galicia, in the province of Ourense. 42 03 36.68 N 7 27 37.14 W +Learnard Glacier Chugach National Forest, Alaska 60 48 44 N 148 42 55 W +Leiro Leiro is a municipality in Galicia, in the province of Ourense. 42 22 11.51 N 8 07 27.42 W Le Louxor 48 52 00 N 2 20 59 E Le Sauze-du-Lac Le Sauze-du-Lac est un petit village de les Hautes-Alpes, prés du lac de Serre-Ponçon. 44 28 42.94 N 6 18 52.35 E -Le Train Bleu 48 50 42 N 2 22 24 E -Legnano Legnano is a town in the north-west of Lombardy, situated on the flat lands of the Po Valley between Milan and Lake Maggiore. 45 35 48.84 N 8 54 32 E -Leiro Leiro is a municipality in Galicia, in the province of Ourense. 42 22 11.51 N 8 07 27.42 W Les Invalides 48 51 18 N 2 18 45 E +Le Train Bleu 48 50 42 N 2 22 24 E Levanto Levanto is a village in Liguria in Italy. 44 10 15.82 N 9 36 41.68 E Lighthouses at Cape Arkona There are two lighthouses and one bearing tower at Cape Arkona. 54 40 47 N 13 25 57 E -Ligne Aubagne - Fuveau 43 23 41.38 N 5 33 59.44 E -Lima 12 05 36 S 77 02 48 W -Loro Parque Puerto de la Cruz, Tenerife, Canarias, España 28 24 30.18 N 16 33 51.25 W -Loschwitzer Friedhof Cemetery "Loschwitzer Friedhof" in Dresden-Loschwitz 51 02 46 N 13 49 18.98 E +Lima Lima 12 03 00 S 77 02 00 W +Loro Parque 28 24 29.88 N 16 33 52.74 W +Loschwitzer Friedhof Cemetery „Loschwitzer Friedhof“ in Dresden-Loschwitz 51 02 46 N 13 49 18.98 E +Lowell Point, Alaska Kenai Peninsula, Alaska 60 04 18 N 149 26 37 W Luise-Kiesselbach-Platz The Luise-Kiesselbach-Platz is a square in the southwest of Munich. 48 06 44.17 N 11 31 03.27 E Lunds domkyrka Lunds domkyrka or Lund Cathedral is the cathedral of Lund in Skåne in southern Sweden. 55 42 14.59 N 13 11 36.91 E LWL-Freilichtmuseum Detmold The LWL-Freilichtmuseum Detmold (earlier name: Westfälisches Freilichtmuseum Detmold) is a museum for folklife studies in the town of Detmold, Germany. 51 55 25 N 8 52 12 E @@ -468,7 +613,10 @@ Maisons de la rue Jeanne-Mance 45 30 31.9 N 73 34 11.02 W Manneken Pis van Brussel Manneken Pis in Brussels 50 50 42 N 4 21 00 E Manufacture nationale de Sèvres 48 49 43 N 2 13 21 E Manzaneda Manzaneda is a municipality in Galicia, in the province of Ourense. 42 18 35.33 N 7 13 58.01 W +Margaret Eagan Sullivan Park, Anchorage, Alaska 61 12 31 N 149 55 16 W +Marienkirche Witzwort 54 23 58.86 N 8 59 06.17 E Marín 42 23 31.28 N 8 42 16.58 W +Mary's Tomb 31 46 48.5 N 35 14 21.41 E Maside Maside is a municipality in Galicia, in the province of Ourense. 42 24 44.75 N 8 01 31.85 W Matitone (Genova) Il Matitone è un grattacielo di Genova dalla struttura a forma di lapis. È situato nella zona portuale di San Benigno, a breve distanza dalla torre della Lanterna. 44 24 40.59 N 8 54 25.07 E Matteus kyrka, Stockholm 59 20 43.08 N 18 02 32.94 E @@ -476,110 +624,112 @@ Maximiliansbrücke in München 48 08 12.42 N 11 35 31.45 E Meaño Meaño is a municipality in Galicia, Spain in the province of Pontevedra. 42 26 31.95 N 8 46 46.02 W Meis Meis is a municipality in Galicia, Spain in the province of Pontevedra. 42 30 49.01 N 8 41 27.14 W Melón Melón is a municipality in Galicia, in the province of Ourense. 42 15 26.97 N 8 13 01.51 W +Mérida (Spain) 38 54 56.88 N 6 19 59.88 W Mii-dera Mii-dera 三井寺, formally Onjōji 園城寺, is a Tendai Buddhist temple in the city of Otsu, Shiga Prefecture, Japan. 35 00 48.09 N 135 51 10.26 E Millennium Town Park The Millennium Town Park is a public park in Saint Helier, Jersey. 49 11 15.01 N 2 06 06.95 W -Minden Minden is a German city in North Rhine-Westphalia. 52 17 20.18 N 8 55 04.19 E Mindener Dom Cathedral in Minden, District of Minden-Lübbecke, North Rhine-Westphalia, Germany. 52 17 19.85 N 8 55 09.94 E Mindener Kreisbahnen Kreisbahnen Minden, ein Unternehmen aus dem 19. Jahrhundert, das in Abwandlungen noch heute besteht. 52 18 01.14 N 8 54 50.98 E +Minden Minden is a German city in North Rhine-Westphalia. 52 17 20.18 N 8 55 04.19 E Mittagskogel Mittagskogel is a peak in the Karawanken mountain chain in Carinthia / Austria / EU. 46 30 26.54 N 13 57 08.1 E Moaña Moaña is a municipality in Galicia, Spain in the province of Pontevedra. 42 17 05.52 N 8 44 57.56 W Moe, Victoria 38 10 20 S 146 16 04 E +Möja kyrka 59 24 18.8 N 18 52 53 E Molino Stucky Il Molino Stucky è uno storico edificio di Venezia. È un esempio di architettura industriale neogotica. 45 25 41.55 N 12 19 11.95 E Monastery of San Paio de Diomondi 42 36 13.6 N 7 42 34.1 W Monforte de Lemos 42 31 19.98 N 7 30 46.56 W -Monte Amiata Il Monte Amiata è un monte situato nella Toscana. 42 54 00 N 11 38 00 E -Monte Musinè el Monte Musinè es una cima de los Alpes Grayos, en Italia. 45 06 50 N 7 27 16 E +Mońki Railway station 53 24 00 N 22 47 00 E +Monte Amiata Il Monte Amiata è un monte situato nella Toscana. 42 53 15.9 N 11 37 27.73 E Monterrei Monterrei is a municipality in Galicia, in the province of Ourense. 41 56 51.19 N 7 26 58.52 W -Montevideo 34 52 01 S 56 10 00 W -Montmartre Cemetery Montmartre Cemetery (Fr: Cimetière de Montmartre) is a famous cemetery located at 37 Avenue Samson, in the 18th arrondissement of Paris, France. 48 53 16 N 2 19 49 E +Montevideo Montevideo is the capital and largest city of Uruguay. 34 52 01 S 56 10 00 W +Montmartre Cemetery Montmartre Cemetery (Fr: Cimetière de Montmartre) is a famous cemetery located at 37 Avenue Samson, in the 18th arrondissement of Paris, France. 48 53 16.08 N 2 19 49.08 E Monument de Joseph Sec Monument Joseph Sec, 8 avenue Pasteur, Aix-en-Provence, France. 43 31 59.44 N 5 26 46.71 E Monument international de la Réformation 46 12 00.78 N 6 08 45.19 E Mos Mos is a municipality in Galicia, Spain in the province of Pontevedra. 42 11 39.08 N 8 39 11.19 W +Mössingen 48 24 23 N 9 03 27 E Mosteiro de San Clodio de Leiro 42 22 02.61 N 8 06 54.12 W Mosteiro de San Salvador de Celanova 42 09 06.55 N 7 57 24.85 W Mosteiro de Santa María de Aciveiro 42 37 03 N 8 18 06 W -Mońki Railway station 53 24 00 N 22 47 00 E +Mount Muir, Alaska Chugach Mountains, Alaska 61 06 29 N 148 22 42 W Mugardos Mugardos is a municipality in the province A Coruña, Galicia, Spain. 43 27 43.7 N 8 15 12.52 W -Muntic Muntic is a village in Istria, Croatia. 44 55 00 N 13 56 00 E -Murol 45 34 23 N 2 56 35 E +Mühlen am Löbauer Wasser 51 12 02.21 N 14 39 21.09 E Muros 42 46 28.69 N 9 03 23.75 W Murray House 22 13 05.15 N 114 12 34.96 E Murviel-lès-Béziers 43 26 29 N 3 08 42 E +Museo Archeologico Regionale Paolo Orsi Archaeological Museum Paolo Orsi in Syracuse 37 04 34.36 N 15 17 10.89 E Museo Civico d'Arte Antica di Torino Il Museo Civico d'Arte Antica è un polo museale situato a Torino presso Palazzo Madama. 45 04 15.95 N 7 41 07.72 E Museo della Storia del Genoa 44 24 37.8 N 8 56 11.39 E Museo Regionale della Fauna Alpina - Alpenfaunamuseum "Beck-Peccoz" Un museo sulla fauna alpina situato a Gressoney-Saint-Jean, in Valle d'Aosta, Italia. 45 46 35.57 N 7 49 36.84 E Museum für Moderne Kunst The Museum für Moderne Kunst (MMK) is an art museum in Frankfurt am Main. 50 06 42.56 N 8 41 03.86 E -Mérida (Spain) 38 54 57 N 6 20 00 W -Möja kyrka 59 24 18.8 N 18 52 53 E -Mössingen 48 24 23 N 9 03 27 E -Mühlen am Löbauer Wasser 51 12 02.21 N 14 39 21.09 E Narón Narón is a municipality in the province A Coruña, Galicia, Spain. 43 32 14.91 N 8 10 53.28 W +Naturschutzgebiet „Königsbrücker Heide“ 51 20 07.58 N 13 52 06.67 E Necrópole Megalítica da Lameira de Cima Necrópole Megalítica da Lameira de Cima, freguesia de Antas, Penedono, Portugal. 40 56 09.92 N 7 20 57.52 W Neda Neda is a municipality in the province A Coruña, Galicia, Spain. 43 29 58.68 N 8 09 21.51 W -Nedroma 35 00 47.01 N 1 44 51.12 W Neues Rathaus München 48 08 16.07 N 11 34 33.35 E Neues Schloss, Stuttgart 48 46 41 N 9 10 55 E New Mosque in Istanbul New Mosque (Yeni Cami) in Istanbul 41 01 01.05 N 28 58 19.2 E Niujie Mosque The Niujie Mosque (Chinese: 牛街清真寺; pinyin: niújiē qīngzhēnsì) is the oldest mosque in Beijing, China. It was built in 996 and completely rebuilt under the Kangxi Emperor (1622-1722). 39 53 04 N 116 21 29 E Nizza-Ufer The Nizza bank is a park with mild microclimate at the Main river bank in Frankfurt am Main. The Park was constructed in 1860. 50 06 15.68 N 8 40 14.37 E Noorderplantsoen The Noorderplantsoen is a park in the Dutch city of Groningen. 53 13 25 N 6 33 20 E +Nordwestbahnhof, Vienna Emergency quarters from Northwest Railway Wagon 13 46.81 N 16 22 58.91 E +Nulbay Park, Anchorage, Alaska 61 12 57 N 149 54 36 W Nullamunjie Olive Grove, Victoria Nullamunjie olive groves are situated in the mountains of eastern Victoria, Australia on the slopes of Mount Stawell and near the banks of the Tambo River. 37 11 05 S 147 43 58 E O Barco de Valdeorras 42 24 38.82 N 6 58 33.51 W -O Bolo O Bolo is a municipality in Galicia, in the province of Ourense. 42 18 27.11 N 7 05 52.28 W -O Carballiño 42 25 53.18 N 8 04 38.47 W -O Grove 42 29 34.29 N 8 52 04.9 W -O Pereiro de Aguiar O Pereiro de Aguiar is a municipality in Galicia, in the province of Ourense. 42 20 47.83 N 7 48 06.62 W -O Porriño O Porriño is a municipality in Galicia, Spain in the province of Pontevedra. 42 09 41.84 N 8 37 15 W -O Rosal O Rosal is a municipality in Galicia, Spain in the province of Pontevedra. 41 56 07.3 N 8 50 05.63 W -O Ézaro, Dumbría 42 54 38.2 N 9 07 54.12 W Obermillstatt 46 48 36.91 N 13 35 29.41 E Obervellach 46 55 55.76 N 13 12 06.68 E +O Bolo O Bolo is a municipality in Galicia, in the province of Ourense. 42 18 27.11 N 7 05 52.28 W +O Carballiño 42 25 53.18 N 8 04 38.47 W Ocean Park, Hong Kong 22 14 45.1 N 114 10 33.3 E +O Ézaro, Dumbría 42 54 38.2 N 9 07 54.12 W +O Grove 42 29 34.29 N 8 52 04.9 W Ohr Somayach Synagogue Ohr Somayach Synagogue, the main synagogue in Odessa, Ukraine 46 28 40.55 N 30 44 22.13 E Oia Oia is a municipality in Galicia, Spain in the province of Pontevedra. 42 00 06.45 N 8 52 30.54 W +Oímbra 41 53 07.94 N 7 28 19.78 W Oleiros Oleiros is a municipality in the province A Coruña, Galicia, Spain. 43 19 57.16 N 8 18 54.38 W Oleiros, Ribeira 42 36 11.29 N 9 00 20.52 W Olgastraße (Stuttgart) 48 46 04.17 N 9 10 44.23 E +O Pereiro de Aguiar O Pereiro de Aguiar is a municipality in Galicia, in the province of Ourense. 42 20 47.83 N 7 48 06.62 W +O Porriño O Porriño is a municipality in Galicia, Spain in the province of Pontevedra. 42 09 41.84 N 8 37 15 W Oradour-sur-Glane Oradour-sur-Glane was a village in the Limousin region of Vichy France that came under direct German control in 1942. 45 55 55 N 1 01 54 E -Oran 35 41 49 N 0 37 59 W Orangerie (Neustrelitz) Die Orangerie in Neustrelitz wurde bereits 1755 erbaut und erfuhr 1840 bis 1842 einen grundlegenden Umbau durch Friedrich Wilhelm Buttel. 53 21 40 N 13 03 27 E Organización Médica Colegial de España Spanish Medical Colleges Organization 40 24 57.24 N 3 41 49.49 W +O Rosal O Rosal is a municipality in Galicia, Spain in the province of Pontevedra. 41 56 07.3 N 8 50 05.63 W Ortigueira Ortigueira is a municipality in the province A Coruña, Galicia, Spain. 43 41 12.94 N 7 51 10.47 W Os Blancos Os Blancos is a municipality in Galicia, in the province of Ourense. 41 59 50.61 N 7 45 12.34 W Ouaisné 49 10 45.75 N 2 11 10.77 W Oza-Cesuras Oza-Cesuras, municipality in the province of A Coruña, in Galicia (Spain). 43 16 44.24 N 8 12 55.95 W Ozurgeti Ozurgeti is a town and the regional administrative centre of Western Georgian province of Guria, former Macharadze or Makharadze. 41 55 26.26 N 42 00 33.84 E -Oímbra 41 53 07.94 N 7 28 19.78 W Palace and park of Versailles 48 48 15.85 N 2 07 23.38 E +Palácio de Estói 37 05 47.79 N 7 53 44.05 W +Palácio Nacional da Pena 38 47 15.24 N 9 23 25.75 W +Palácio Nacional de Mafra O Palácio Nacional de Mafra é um palácio e mosteiro monumental de estilo neoclássico localizado em Mafra (Portugal) a poucos mais de 50 quilómetros de Lisboa. 38 56 12 N 9 19 35 W Palais Brongniart The Palais Brongniart was the site of the Paris Stock Exchange until 1987. 48 52 09.01 N 2 20 26.98 E Palais de justice de Paris Palais de Justice is a building complex on the Île-de-la-Cité in Paris. It was built on the site of the Palais de la Cité, the residence of the Kings of France until the 14th century. 48 51 20.6 N 2 20 42.18 E Palais de l'Élysée 48 52 13 N 2 18 59 E -Palais des Papes The Palais des Papes in Avignon, France was the residency of popes during the 14th and 15th century. 43 57 02 N 4 48 25 E 43.95068 N 4.80704 E 43.95068 4.80704 +Palais des Papes The Palais des Papes in Avignon, France was the residency of popes during the 14th and 15th century. 43 57 02 N 4 48 25 E +Palais ducal de Nevers The Palais Ducal in Nevers, France 46 59 18 N 3 09 30 E Palais du parlement de Bretagne 48 06 46.08 N 1 40 40.01 W Palais du parlement du Dauphiné 45 11 35.97 N 5 43 42.86 E Palais du Tau 49 15 11 N 4 02 04 E -Palais ducal de Nevers The Palais Ducal in Nevers, France 46 59 18 N 3 09 30 E Palais Garnier The Palais Garnier, also known as Opéra Garnier or Opéra national de Paris is an opera house situated at the northern end of the avenue de l'Opera, in Paris. 48 52 19 N 2 19 54 E -Palais Granvelle (Besançon) 47 14 08.52 N 6 01 35.76 E Palais Idéal 45 15 22.85 N 5 01 42.74 E Palais Longchamp 43 18 15.48 N 5 23 40.2 E Palais Royal 48 51 52.5 N 2 20 15.1 E Palmenhaus, Vienna Vienna's Palmenhaus ('palm house', a Jugendstil greenhouse built in 1901) is a building in Vienna's 1st district, beneath 'Burggarten' and Hofburg. 48 12 18 N 16 22 01 E -Palácio de Estói 37 05 47.79 N 7 53 44.05 W -Palácio Nacional da Pena 38 47 15.24 N 9 23 25.75 W -Palácio Nacional de Mafra O Palácio Nacional de Mafra é um palácio e mosteiro monumental de estilo neoclássico localizado em Mafra (Portugal) a poucos mais de 50 quilómetros de Lisboa. 38 56 12 N 9 19 35 W Pamukkale Pamukkale is a natural site and attraction and a UNESCO World Heritage Site in south-western Turkey. 37 55 25 N 29 07 24 E Panthéon de Paris 48 50 46 N 2 20 45 E -Parc Astérix 48 27 21 N 4 35 24 E +Parc Astérix 49 08 07.08 N 2 34 18.12 E Parc du Thabor 48 06 51 N 1 40 12 W -Parc Monceau 48 52 45.84 N 2 18 33.23 E +Parc Monceau Parc Monceau is a public park situated in the 8th and 17th Arrondissements of Paris at the junction of Boulevard de Courcelles, Rue de Prony and Rue Georges Berger. 48 52 45.84 N 2 18 33.23 E Parc Natural del Delta de l'Ebre Village 40 42 09 N 0 48 32 E Paris-Gare de Lyon 48 50 41 N 2 22 25 E -Emin Pasha Emin Pasha (born Eduard Schnitzer, 1840-1892) was a German explorer of Central Africa. 42 12 40.68 N 20 44 28.26 E +Passage Canal, Alaska Chugach National Forest, Alaska 60 48 53 N 148 31 28 W +Penniman Glaciers Chugach National Forest, Alaska 61 05 42 N 148 20 24 W Petit Palais The Petit Palais is a palace in Paris, France built for the Universal Exhibition in 1900. It now houses the Musée des Beaux-Arts de la Ville de Paris (Paris Museum of Fine Arts). 48 51 57.72 N 2 18 52.39 E Petuelpark 48 10 39.64 N 11 34 45.32 E Petuelring The Petuelring is a street in Munich, part of the Mittlerer Ring around the city centre. 48 10 40.25 N 11 34 19 E Petueltunnel The Petueltunnel is a tunnel that runs beneath the Petuelring between the Boroughs Milbertshofen-Am Hart and Schwabing-West in Munich. 48 10 39.9 N 11 34 37.48 E +Pfaffendorf (Rietz-Neuendorf) 52 15 57.79 N 14 09 46.25 E +Pfarrkirche St. Bartholomäus in Friesach 46 57 04.28 N 14 24 18.19 E Phare de Chassiron 46 02 48.12 N 1 24 37.01 W Philadelphia City Hall Philadelphia City Hall is the seat of government for the city of Philadelphia, Pennsylvania. 39 57 08.28 N 75 09 48.96 W Piazza Corvetto (Genova) Piazza Corvetto è una delle principali piazze di Genova 44 24 36.1 N 8 56 18.2 E @@ -588,158 +738,182 @@ Piazza delle Erbe (Verona) 45 26 36.74 N 10 59 48.53 E Piazza Navona Piazza Navona is a square in Parione, the VI. Rione (district) from Rome, Italy. 41 53 56.21 N 12 28 23.15 E Piazza Venezia Piazza Venezia is Located in Rome. 41 53 47 N 12 28 57 E Pieve di San Giorgio di Valpolicella The Pieve di San Giorgio di Valpolicella is a particularly large and elaborate Pieve (ancient church) of the city of Sant'Ambrogio di Valpolicella, Italy. 45 32 07 N 10 51 00 E -Piode Piode è un comune della Valsesia, in provincia di Vercelli, Piemonte, Italia. 45 46 09.98 N 8 02 57.28 E +Pigot Glacier Chugach National Forest, Alaska 60 54 12 N 148 28 44 W Piñor Piñor is a municipality in Galicia, in the province of Ourense. 42 29 50.69 N 8 00 21.39 W -Place de la Concorde The Place de la Concorde is one of the major public squares in Paris, France. 48 51 56 N 2 19 16 E +Piode Piode è un comune della Valsesia, in provincia di Vercelli, Piemonte, Italia. 45 46 09.98 N 8 02 57.28 E +Plaça Catalunya Plaça Catalunya (or Plaza de Cataluña in spanish) is a large square in central Barcelona. 41 23 13.21 N 2 10 12.09 E +Place de la Concorde The Place de la Concorde is one of the major public squares in Paris, France. 48 51 56.16 N 2 19 15.96 E Place des Vosges Place des Vosges in Paris, France 48 51 20 N 2 21 56 E +Placer River Valley Kenai Peninsula, Alaska 60 49 25 N 148 59 47 W Plaridel Airport 14 53 27.91 N 120 51 09.9 E -Plaça Catalunya Plaça Catalunya (or Plaza de Cataluña in spanish) is a large square in central Barcelona. 41 23 13.21 N 2 10 12.09 E Pont Ambroix The Pont Ambroix was a Roman bridge across the Vidourle in Gallargues-le-Montueux, Gard department, and Villetelle, Hérault department, both Languedoc-Roussillon, France. 43 43 02 N 4 09 07 E Pont Camille-de-Hogues 46 48 49.12 N 0 32 15.32 E Pont de la Concorde 48 51 47.99 N 2 19 09.98 E Pont du Gard The Pont du Gard is a Roman aqueduct bridge near Nîmes, France. 43 56 50.28 N 4 32 07.8 E -Pont Flavien The Pont Flavien is a Roman bridge in Saint-Chamas, Bouches-du-Rhône department, Provence-Alpes-Côte d'Azur, France. 43 32 29 N 5 02 35 E -Pont Julien The Pont Julien is a Roman bridge near Bonnieux, Vaucluse department, Provence-Alpes-Côte d’Azur, France. 43 51 45 N 5 18 28 E -Pont Neuf 48 51 26.81 N 2 20 29.82 E -Pont sur la Laye Roadway 43 55 48 N 5 45 23 E Ponte de Rande The Rande Bridge is a cable-stayed bridge near Vigo, Galicia, Spain. 42 17 18.66 N 8 39 37.45 W -Ponte Sant'Angelo (Rome) The Ponte Sant'Angelo is a Roman bridge across the Tiber in Rome, Italy. 41 54 06.46 N 12 27 59.24 E Pontedeume 43 24 13.68 N 8 09 46.85 W +Ponte Sant'Angelo (Rome) The Ponte Sant'Angelo is a Roman bridge across the Tiber in Rome, Italy. 41 54 06.46 N 12 27 59.24 E Pontevedra 42 25 50.84 N 8 38 56.27 W +Pont Flavien The Pont Flavien is a Roman bridge in Saint-Chamas, Bouches-du-Rhône department, Provence-Alpes-Côte d'Azur, France. 43 32 29 N 5 02 35 E +Pont Julien The Pont Julien is a Roman bridge near Bonnieux, Vaucluse department, Provence-Alpes-Côte d’Azur, France. 43 51 45 N 5 18 28 E +Pont Neuf 48 51 26.81 N 2 20 29.82 E +Pont sur la Laye The Pont sur la Laye is an old bridge across the Laye near Mane, Alpes-de-Haute-Provence department, Provence, France. 43 55 48 N 5 45 23.04 E Pordoi Pass The Pordoi Pass is an Alpine pass in the Dolomites. 46 29 19.33 N 11 48 52.54 E -Port of Kobe Port of Kobe in Kobe, Hyōgo Prefecture, Japan 34 40 39.17 N 135 13 36.97 E Porta Pia 41 54 33 N 12 30 04 E Porta san Sebastiano 41 52 25 N 12 30 07 E Porta Soprana (Genova) Porta Soprana a Genova. 44 24 19.76 N 8 56 05.6 E Porta Westfalica 52 14 22.66 N 8 55 14.31 E Porto antico di Genova 44 24 34.22 N 8 55 04.26 E Porto Azzurro 42 46 05.02 N 10 23 48.33 E +Port of Kobe Port of Kobe in Kobe, Hyōgo Prefecture, Japan 34 40 39.17 N 135 13 36.97 E Portor, Negreira 42 54 45.44 N 8 41 52.17 W Potemkin Stairs 46 29 18.75 N 30 44 31.18 E +Potter Marsh Anchorage 61 04 39 N 149 49 37 W Praia de Cabanas 43 24 55.21 N 8 10 23.62 W Prinzenbau Stuttgart 48 46 38.55 N 9 10 40.96 E Promenade du Peyrou 43 36 40 N 3 52 15 E Prytanée national militaire 47 42 10.09 N 0 04 35.77 W -Puerto de Navacerrada 40 47 19.04 N 4 00 13.23 W +Puerto de Navacerrada El puerto de Navacerrada es un puerto de montaña a 1858 msnm de altitud, que alberga una estación de esquí y que está situado en la sierra de Guadarrama (Sistema Central). 40 47 19.04 N 4 00 13.23 W Puits Arthur-de-Buyer 47 40 37.23 N 6 36 51.29 E Punta Manara Manara Bivouac 44 15 19.08 N 9 24 20.88 E Punxín Punxín is a municipality in Galicia, in the province of Ourense. 42 22 06.15 N 8 00 03.16 W Quartier de Beaugrenelle 48 51 03.87 N 2 17 07.61 E +Radweg Arnsdorf-Guteborn 51 25 49.66 N 13 53 18.08 E +Rainy Glacier Chugach National Forest, Alaska 60 38 39 N 148 32 37 W Rairiz de Veiga 42 04 57.65 N 7 49 56.92 W Ravensberger Bahn Die Ravensberger Bahn ist eine Eisenbahnstrecke von Bielefeld nach Rahden. 52 13 36.48 N 8 31 20.75 E Regattastrecke Oberschleißheim Die Regattastrecke Oberschleißheim ist ein künstlicher, rechteckiger Grundwassersee im Norden von München, angelegt für die Olympischen Sommerspiele 1972. 48 14 33.67 N 11 30 54.38 E Reggia di Caserta La Reggia di Caserta, Palazzo Reale, è stata la dimora della dinastia dei Borboni, sovrani del Regno delle due Sicilie. È situata a Caserta, in Campania (Italia). 41 04 26.27 N 14 19 36.92 E Reservoir in Stara Morawa Reservoir in Stara Morawa near Stronie Śląskie (Lower Silesian Voivodeship, Poland) 50 16 31.15 N 16 52 47.84 E +Resurrection Peninsula Kenai Peninsula, Alaska 59 56 53 N 149 16 41 W Rianxo Rianxo is a port town in Galicia, Spain, in the province of A Coruña. 42 38 38.62 N 8 48 44.67 W Ribadavia 42 17 13.06 N 8 08 34.54 W Ribadumia Ribadumia is a municipality in Galicia, Spain in the province of Pontevedra. 42 30 50.38 N 8 45 25.68 W -Ribeira Ribeira is a municipality in the province A Coruña, Galicia, Spain. 42 32 38.31 N 9 00 06.92 W Ribeira, Ribeira 42 33 16.32 N 8 59 27.37 W +Ribeira Ribeira is a municipality in the province A Coruña, Galicia, Spain. 42 32 38.31 N 9 00 06.92 W Ricetto di Candelo 45 32 46.68 N 8 06 48.96 E Rio Marina Rio Marina is a village in Isola d'Elba Toscana in Italy 42 48 44.2 N 10 25 39.87 E -Risiera di San Sabba La Risiera di San Sabba è stato un campo di concentramento nazista, attivo negli ultimi anni della seconda guerra mondiale a Trieste, Italia. 45 37 26.09 N 13 47 22.1 E Riós Riós is a municipality in Galicia, in the province of Ourense. 41 58 29.53 N 7 16 55.68 W +Río Tambre 42 54 20.32 N 8 41 43.21 W +Risiera di San Sabba La Risiera di San Sabba è stato un campo di concentramento nazista, attivo negli ultimi anni della seconda guerra mondiale a Trieste, Italia. 45 37 26.09 N 13 47 22.1 E Robben Island Robben Island, Cape Town, South Africa 33 48 24.24 S 18 21 58.4 E Rocca Grimalda Rocca Grimalda è un comune dell'Alto Monferrato, in provincia di Alessandria, Piemonte, Italia. 44 40 17.48 N 8 38 55.11 E Rodeiro Rodeiro is a municipality in Galicia, Spain in the province of Pontevedra. 42 39 00.44 N 7 56 59.94 W Roman Bridge (Saint-Thibéry) Old mill nearby 43 23 34.39 N 3 25 58.21 E Roman Bridge (Vaison-la-Romaine) The Roman Bridge at Vaison-la-Romaine is a bridge across the Ouvèze in the Vaucluse department, Provence, France. 44 14 20.3 N 5 04 28.7 E Roman Theatre of Catania 37 30 10.4 N 15 05 00.9 E -Roujan 43 30 32.5 N 3 17 15.15 E -Río Tambre 42 54 20.32 N 8 41 43.21 W +Roujan Roujan is a commune of the Hérault département in the Region of Languedoc-Roussillon - France. 43 30 32.5 N 3 17 15.15 E +Rudyerd Bay Borough di Ketchikan Gateway, Alaska 55 35 23 N 130 44 45 W +Ruhlsdorf (Teltow) Former town hall 52 22 28.71 N 13 16 04.56 E +Russian Jack Springs Park, Anchorage, Alaska 61 12 21 N 149 47 18 W Sacrario Militare di Redipuglia 45 51 05.58 N 13 29 22.49 E Sada Sada is a municipality in the province A Coruña, Galicia, Spain. 43 21 01.43 N 8 15 16.23 W -Safranbolu Safranbolu is a city and World Heritage site of Karabük Province, Turkey. 41 14 41 N 32 41 37 E -Sagrada Família 41 24 12.82 N 2 10 27.64 E -Église Saint-Gervais-Saint-Protais 48 51 19.8 N 2 21 16.6 E -Saint-Michel de Nahuze Prieuré du XIe siècle, situé sur la commune de Lagrasse (département de l'Aude), dont les ruines ont été inscrites comme monument historique 43 07 56.82 N 2 37 06.38 E -Saint-Nazaire-de-Ladarez 43 30 37 N 3 04 36 E +Safranbolu Safranbolu is a city and district of Karabük Province, Turkey. 41 14 41 N 32 41 37 E +Sagrada Família 41 24 13 N 2 10 27.05 E Sainte-Chapelle 48 51 20 N 2 20 41 E -Château de Saissac The Château de Saissac is a Cathar castle in the Saissac commune, Aude département of France. 43 21 25 N 2 10 04.7 E -Salt Lake Temple The Salt Lake Temple, the sixth temple built by the church overall, and the fourth operating temple, is the largest and best-known temple of The Church of Jesus Christ of Latter-day Saints. 40 46 14.45 N 111 53 31.18 W +Saint-Michel de Nahuze Prieuré du XIe siècle, situé sur la commune de Lagrasse (département de l'Aude), dont les ruines ont été inscrites comme monument historique 43 07 56.82 N 2 37 06.38 E +Saint-Nazaire-de-Ladarez Saint-Nazaire-de-Ladarez is a commune of the Hérault département, France. 43 30 37 N 3 04 36 E +Salt Lake Temple The Salt Lake Temple, the sixth temple built by the church overall, and the fourth operating temple, is the largest and best-known temple of The Church of Jesus Christ of Latter-day Saints. 40 46 13.69 N 111 53 31.06 W San Amaro San Amaro is a municipality in Galicia, in the province of Ourense. 42 22 20.07 N 8 04 23.65 W San Clodio, Leiro 42 22 02.61 N 8 06 54.12 W San Cristovo de Cea San Cristovo de Cea is a municipality in Galicia, in the province of Ourense. 42 28 33.22 N 7 59 07.24 W +Sandiás Sandiás is a municipality in Galicia, in the province of Ourense. 42 06 38.53 N 7 45 28.41 W San Giorgio in Lemine San Giorgio in Lemine is a church in the comune of Almenno San Salvatore, Bergamo, Lombardy, Italy 45 44 46 N 9 35 50 E +Sankt Martini 53 04 30 N 8 48 15 E San Marco (Milan) 45 28 23.77 N 9 11 20 E San Sadurniño San Sadurniño is a municipality of Spain in the province of A Coruña, in the autonomous community of Galicia. 43 33 44.93 N 8 03 17.21 W -Sandiás Sandiás is a municipality in Galicia, in the province of Ourense. 42 06 38.53 N 7 45 28.41 W -Sankt Martini 53 04 30 N 8 48 15 E -Sant'Anastasia Sant'Anastasia è una chiesa di Roma. 41 53 17.6 N 12 29 03 E Santa Maria degli Scalzi (Venice) 45 26 29.4 N 12 19 19.56 E Santa Maria dei Servi (Padua) 45 24 16.56 N 11 52 32.63 E +Sant'Anastasia Sant'Anastasia è una chiesa di Roma. 41 53 17.6 N 12 29 03 E Santiago de Chile Santiago is the capital of Chile, it is also the country's industrial and commercial center. 33 27 00 S 70 40 00 W Sanxenxo 42 24 19.2 N 8 48 23.66 W Sarreaus 42 05 13.93 N 7 36 10.99 W Sarria 42 46 38.13 N 7 24 54.31 W Schallenberg 46 49 34 N 7 47 50 E Schenkendorfstraße The Schenkendorfstraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 10 34.21 N 11 35 29.04 E +Schenkenhorst (Stahnsdorf) Former town hall 52 20 28.05 N 13 11 46.85 E Schloss Eutin The Castle of Eutin is located in Eutin in Schleswig-Holstein. 54 08 15.75 N 10 37 13.22 E Schloss Hüffe Schloss Hüffe ist ein Ende des 13. Jahrhunderts errichtetes Wasserschloss in der Ortschaft Lashorst der Stadt Preußisch Oldendorf im Kreis Minden-Lübbecke. 52 20 05.99 N 8 30 55.72 E Schloss Kalkum Schloss Kalkum is a water castle in Kalkum in the north of Düsseldorf, about two kilometers northeast of Kaiserwerth. 51 18 14.9 N 6 45 26.7 E +Schlosskirche (Neustrelitz) Die Neustrelitzer Schlosskirche wurde durch Friedrich Wilhelm Buttel erbaut und ist dessen Hauptwerk in der Stadt. 53 21 35 N 13 03 32 E Schloss Nymphenburg Nymphenburg Palace is a château in Munich. 48 09 29 N 11 30 13 E Schloss Petershagen Das Schloss Petershagen in Petershagen ist ein Wasserschloss im Stil der Weserrenaissance. 52 22 46.16 N 8 58 18.62 E -Schloss Rosenstein 48 48 15 N 9 11 30 E -Schlosskirche (Neustrelitz) Die Neustrelitzer Schlosskirche wurde durch Friedrich Wilhelm Buttel erbaut und ist dessen Hauptwerk in der Stadt. 53 21 35 N 13 03 32 E Schlossplatz Stuttgart 48 46 42.81 N 9 10 47.45 E -Serres d'Auteuil The Jardin des serres d'Auteuil is a botanical garden in the Bois de Boulogne, Paris 16th, located at 3 avenue de la Porte d'Auteuil and 1 avenue Gordon-Bennett. 48 50 49 N 2 15 8 E +Schloss Rosenstein 48 48 26 N 9 11 22 E +Schönfließ (Mühlenbecker Land) 52 39 23.04 N 13 20 21.84 E +Serpentine Glacier Chugach National Forest, Alaska 61 07 41 N 148 16 02 W +Serres d'Auteuil The Jardin des serres d'Auteuil is a botanical garden in the Bois de Boulogne, Paris 16th, located at 3 avenue de la Porte d'Auteuil and 1 avenue Gordon-Bennett. 48 50 49 N 2 15 8 E Sestri Levante Sestri Levante is a town in Liguria in Italy. 44 16 17.76 N 9 23 33 E Shokeda Shokeda is a religious settlement in Israel, in north-west part of Negev, south to Sderot and east to the Gaza Strip. 31 25 19.56 N 34 31 28.2 E -Sidi Okba 34 45 00 N 5 54 00 E Sigüeiro, A Barciela, Oroso 42 58 06.42 N 8 26 33.39 W Silleda 42 41 49.46 N 8 14 50.28 W Singapore Singapore is a city state at the southern tip of peninsular Malaysia. It is an island approximately 40 by 20 km in size inhabited by more than five million people. 1 18 00 N 103 48 00 E -Singapore Zoo 1 24 15.9 N 103 47 28.1 E +Singapore Zoo Singapore Zoo / Mandai Zoo 1 24 15.9 N 103 47 28.1 E Sistiana Sistiana is a town near Trieste. 45 46 09.98 N 13 38 01.98 E Sistine Chapel The Sistine Chapel is located in the Vatican and is decorated with frescoes by Michelangelo. 41 54 11 N 12 27 16 E +Site des missiles Plutons Bourogne-Meroux 47 34 54.94 N 6 54 17.69 E +Sixmile Creek (Alaska) Kenai Peninsula, Alaska 60 54 18 N 149 25 36 W Sohland am Rotstein Sohland am Rotstein is a municipality in Saxony, Germany. 51 07 00 N 14 47 00 E Sopron Sopron (pronounced "shop-ron"; German: Ödenburg) is a city in Hungary near the Austrian border. 47 41 12 N 16 34 49 E Spenge Spenge is a northrhine-westphalian town in the administrative district Kreis Herford. 52 08 33.29 N 8 28 59.9 E Spišský hrad The ruins of Spiš Castle are situated above the town of Spišské Podhradie and the village of Žehra in the Spiš region in eastern Slovakia. 48 59 58.5 N 20 46 03.3 E -St. Jürgenskirche (Lilienthal) The church of St. Jürgen is in the same named district of Lilienthal in the county of Osterholz in Lower Saxony, Germany. 53 10 36 N 8 48 29 E -St. Maria in der Kupfergasse St. Maria in der Kupfergasse is a baroque church in Cologne. 50 56 23.2 N 6 57 01.04 E +Spreenhagen Village Pub 52 20 28.62 N 13 52 50.12 E +Sputendorf Former town hall 52 20 20.99 N 13 13 11.05 E +Stadium of Epidaurus 37 35 51.77 N 23 04 27.8 E +Städtisches Lapidarium Stuttgart 48 46 03.36 N 9 10 04.58 E Stadtplatz (Steyr) 48 02 20.42 N 14 25 08.89 E -Stalis 35 17 47.4 N 25 25 25.9 E +Staffelde 52 43 47.5 N 12 59 23.57 E +Stalis Stalis is a small resort village on the island of Crete thirty kilometers from the capital Heraklion, located on the north side of the island. 35 17 47.4 N 25 25 25.9 E +State Bank of Indiana, Terre Haute branch 39 27 55 N 87 24 52.5 W Stefanskyrkan, Stockholm 59 20 51.38 N 18 03 16.7 E Steigfriedhof The Steigfriedhof is a cemetery in the Stadtbezirk Bad Cannstatt in Stuttgart. 48 48 41.9 N 9 12 28.95 E Stift Göttweig Göttweig Abbey is a Benedictine monastery in Lower Austria. 48 22 00.2 N 15 36 45.5 E +St. Jürgenskirche (Lilienthal) The church of St. Jürgen is in the same named district of Lilienthal in the county of Osterholz in Lower Saxony, Germany. 53 10 36 N 8 48 29 E +St. Maria in der Kupfergasse St. Maria in der Kupfergasse is a baroque church in Cologne. 50 56 23.2 N 6 57 01.04 E Stockholms stadshus 59 19 38.57 N 18 03 15.67 E Stockholms universitet Stockholm University, founded 1878, with about 37,000 students. 59 21 46.68 N 18 03 31.4 E -Städtisches Lapidarium Stuttgart 48 46 03.36 N 9 10 04.58 E -Sultanahmet Camii The Sultan Ahmed Mosque (in Turkish Sultanahmet Camii, in English commonly called the Blue Mosque) is a mosque in Istanbul. 41 00 19.3 N 28 58 36.6 E -Synchrotron Soleil 48 42 33 N 2 08 41 E +St. Peter und Paul (Grettstadt) 49 59 06.21 N 10 18 44.87 E Süleymaniye camii The Mosque of Suleiman I in Istanbul. 41 00 58.3 N 28 57 50 E +Sultanahmet Camii The Sultan Ahmed Mosque (in Turkish Sultanahmet Camii, in English commonly called the Blue Mosque) is a mosque in Istanbul. 41 00 19.39 N 28 58 36.57 E +Synchrotron Soleil 48 42 33 N 2 08 41 E Tarancón Tarancón village and municipality in the province of Cuenca, part of the autonomous community of Castile-La Mancha, Spain. 40 00 45.89 N 3 00 14.85 W Teixido, Cedeira 43 42 36.72 N 7 59 00.44 W -Villa romana de Tejada The ancient roman villa of La Tejada is an archaeological site from II to V centuries in Quintanilla de la Cueza, Cervatos de la Cueza (Palencia, Spain). 40 58 36 N 4 48 25 W Templer Cemetery, Jerusalem Jerusalem, German Colony, Emek Refaim street 39 31 45 47.46 N 35 13 08.68 E Texas State Capitol The Texas State Capitol, located in Downtown Austin, Texas, is the fourth building to serve as the seat of Texas government. 30 16 29 N 97 44 26 W -The Dormition Cathedral in Odessa 46 28 31.07 N 30 43 55.42 E -The Spice Bazaar, Istanbul 41 01 00.7 N 28 58 15.13 E Théâtre municipal de Besançon 47 14 03.84 N 6 01 33.89 E +The Dormition Cathedral in Odessa 46 28 30.98 N 30 43 54.89 E +The Spice Bazaar, Istanbul 41 01 00.7 N 28 58 15.13 E +Thunderbird Falls Chugach Mountains, Alaska 61 26 31 N 149 21 28 W Tiberias 32 47 20.04 N 35 31 20.28 E Toblinger Knoten The Toblinger Knoten is a mountain in the Sexten Dolomites in South Tyrol. 46 38 31 N 12 18 29 E Tomiño Tomiño is a municipality in Galicia, Spain in the province of Pontevedra. 41 59 31.78 N 8 44 32.54 W Toosa Toosa is a village in Punjab. 30 44 45.31 N 75 41 14.53 E Topkapı Sarayı İznik tiles: camp of the Mount Arafat 41 00 45.7 N 28 59 03.25 E -Torre de San Sadurniño 42 30 25 N 8 49 16 W +Torre de San Sadurniño 42 30 36 N 8 49 12 W Torre de Vilanova dos Infantes 42 09 58.36 N 7 57 16.62 W +Torreón dos Andrade 43 24 27.5 N 8 10 19.25 W Torres de Altamira 42 52 39.02 N 8 41 15.17 W Torres de Oeste 42 40 35.81 N 8 43 32.46 W -Torreón dos Andrade 43 24 27.98 N 8 10 17.88 W -Toshkent 41 18 00 N 69 16 00 E +Tour de la Chaîne The tour de la Chaîne (XIVth century) is, with the tour Saint-Nicolas and the tour de la Lanterne, one of the three towers located on the seafront of La Rochelle, and one of the two towers that is representative of the city old harbour. 46 09 21.24 N 1 09 15.52 W +Tour de la Lanterne The tour de la Lanterne (XVth century) is, with the tour Saint-Nicolas and the tour de la Chaîne, one of the three towers located on the seafront of La Rochelle. It was added to the historical monument list of France in 1879. 46 09 20.88 N 1 09 25.42 W Tour Eiffel 48 51 30 N 2 17 39 E Tour Goguin 46 59 03.84 N 3 09 19.91 E +Tour Saint-Jacques Saint-Jacques Tower is located in the IVe arrondissement of Paris. This gothic tower is all that remains of the former church of Saint-Jacques-de-la-Boucherie. 48 51 27.95 N 2 20 55.6 E +Tour Saint-Nicolas 46 09 20.88 N 1 09 11.99 W +Trail Glacier, Alaska Kenai Peninsula, Alaska 60 33 14 N 148 54 32 W Transfiguration Cathedral in Odessa Odessa Cathedral of God's Transfiguration 46 28 59.44 N 30 43 51.75 E -Trappentreustraße The Trappentreustraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 08 12.34 N 11 32 03.84 E -Trappentreutunnel The Trappentreutunnel is a tunnel that runs beneath the Trappentreustraße in the Borough Schwanthalerhöhe in Munich. 48 08 08.78 N 11 32 03.17 E +Trappentreustraße The Trappentreustraße is a street in Munich, part of the Mittlerer Ring around the city centre. 48 08 12.48 N 11 32 03.84 E +Trappentreutunnel The Trappentreutunnel is a tunnel that runs beneath the Trappentreustraße in the Borough Schwanthalerhöhe in Munich. 48 08 08.88 N 11 32 03.12 E Trastevere Restaurant in Via della Lungaretta 41 53 22.54 N 12 28 12.76 E Travemünde Travemünde is a part of Lübeck in Germany at the Baltic Sea. 53 58 00 N 10 52 00 E +Třebechovice pod Orebem Třebechovice pod Orebem is a town in Czech Republic in Hradec Králové Region 50 12 07 N 15 59 38 E +Treskow-Platane The Treskow-Platane is a old hybrid plane and natural monument in Berlin-Friedrichsfelde, so called in memorial of Johann Carl Sigismund von Treskow. 52 30 23.69 N 13 31 17.47 E +Treuners Altstadtmodell The Treuner brothers' Altstadtmodell is a scale model which shows the oldtown of Frankfurt am Main prior to the air-raid damages in 1943 and 1944. The ruin model shows the destroyed old town of Frankfurt in spring 1945. 50 06 35 N 8 40 57 E Trinitatisfriedhof, Dresden Cemetery „Trinitatisfriedhof“ in Dresden-Johannstadt 51 03 15.08 N 13 46 20.93 E Twierdza Osowiec Dry moat around the fort No 3 53 27 44 N 22 37 38 E -Třebechovice pod Orebem Třebechovice pod Orebem is a town in Czech Republic in Hradec Králové Region 50 12 07 N 15 59 38 E Uetersen 53 41 14 N 9 40 09 E Université Lille Nord de France 50 36 33.38 N 3 08 29.72 E +University of Alaska Museum of the North Fairbanks, Alaska 64 51 30 N 147 50 32 W Upper Darby, Pennsylvania 39 57 40.2 N 75 15 32.06 W Urgnano 45 35 50 N 9 41 42 E Valdoviño Valdoviño is a municipality in the province A Coruña, Galicia, Spain. 43 36 32.23 N 8 08 30.84 W @@ -750,9 +924,9 @@ Varigotti Varigotti è una frazione del comune di Finale Ligure, in provincia di Verducido, Pontevedra 42 28 35.96 N 8 37 06.66 W Verín Verín is a municipality in Galicia, in the province of Ourense. 41 56 22.47 N 7 26 19.59 W Via dell'Amore (Cinque Terre) The Via dell'Amore (=way of love) is a hiking path above the sea linking the villages of Riomaggiore and Manarola in the Cinque Terre (Liguria, Italia). 44 06 06.07 N 9 44 00.37 E +Via Dolorosa signs third fall of Jesus (not in the Gospels). 31 46 46.48 N 35 13 56.63 E Viana do Bolo 42 10 46.42 N 7 06 44.81 W Vieilles prisons d'Annecy Ancient Jails or the Palais de l'Île of Annecy. 45 53 54.89 N 6 07 36.59 E -Vigo Vigo is a Spanish municipality and the largest city in Galicia. 42 14 00.05 N 8 42 37.59 W Vilagarcía de Arousa 42 35 33.08 N 8 46 36.13 W Vilamarín Vilamarín is a municipality in Galicia, in the province of Ourense. 42 27 51.29 N 7 53 23.64 W Vilanova de Arousa Vilanova de Arousa is a municipality in Galicia, Spain in the province of Pontevedra. 42 33 48.42 N 8 49 26.69 W @@ -764,203 +938,81 @@ Vilassar de Mar Vilassar de Mar is a village in the county of the Maresme, Catal Villa Berg 48 47 31.34 N 9 12 27.17 E Villa d'Este (Tivoli) The Villa d'Este in Tivoli is a masterpiece of Italian architecture and garden design. 41 57 45 N 12 47 46 E Villa Ephrussi de Rothschild 43 41 48 N 7 19 42.5 E -Villa Les Glycines 48 40 46 N 6 10 56 E -Villa Majorelle 48 41 8 N 6 9 50 E -Villa Schneider Villa Schneider è un palazzo storico di Biella (Piemonte, Italia), servito come quartier generale delle SS durante la seconda guerra mondiale. 45 33 49.52 N 8 03 04.87 E Village Vanguard The Village Vanguard is a jazzclub in Greenwich Village (New York City). 40 44 09.64 N 74 00 05.81 W +Villa Les Glycines Villa Les Glycines (1902-1904) 48 40 46 N 6 10 56 E +Villa Majorelle 48 41 8 N 6 9 50 E +Villa romana de Tejada The ancient roman villa of La Tejada is an archaeological site from II to V centuries in Quintanilla de la Cueza, Cervatos de la Cueza (Palencia, Spain). 40 58 36 N 4 48 25 W +Villa Schneider Villa Schneider è un palazzo storico di Biella (Piemonte, Italia), servito come quartier generale delle SS durante la seconda guerra mondiale. 45 33 49.52 N 8 03 04.87 E Villeneuve-d'Ascq Villeneuve-d'Ascq is a commune within Lille Metropolis, in northern France 50 37 24 N 3 08 42 E Walhalla, Victoria 37 56 37.43 S 146 27 02.75 E Walt Disney Concert Hall 34 03 19.36 N 118 14 59.61 W Wayside Cross Villenstraße, Bonn-Dottendorf 50 42 15.73 N 7 06 43.18 E Weckschnapp 50 56 57.48 N 6 57 55.5 E +Westchester Lagoon, Anchorage, Alaska 61 12 16 N 149 54 58 W West Lake 30 15 00 N 120 09 00 E Whitemarsh Hall 40 04 42 N 75 07 44 W Wilhelmsstift Tübingen 48 31 16.19 N 9 03 18.53 E Woodlawn Cemetery (Bronx) Gate on Jerome Avenue 40 53 30 N 73 52 12 W -Xinzo de Limia Xinzo de Limia is a municipality in Galicia, in the province of Ourense. 42 03 36 N 7 43 19.87 W Xàbia Xàbia is a village in the province of Alicante. 38 47 21 N 0 09 47 E +Xinzo de Limia Xinzo de Limia is a municipality in Galicia, in the province of Ourense. 42 03 36 N 7 43 19.87 W Yad Vashem 31 46 23.55 N 35 10 29.2 E -Yao Yao (八尾市, Yao-shi) is a city in Osaka, Japan. 34 37 36.9 N 135 36 03 E +Yao Yao (八尾市, Yao-shi) is a city in Osaka, Japan. 34 37 36.9 N 135 36 03 E Zwehrenturm The Zwehrenturm from 1330 is a remain of Kassel's medieval defensive wall. 51 18 49 N 9 29 54 E -Äußerer Plauenscher Friedhof Cemetery „Äußerer Plauenscher Friedhof“ in Dresden-Plauen 51 01 11.89 N 13 42 26.03 E -École centrale de Lille École Centrale de Lille is a graduate engineering school located in campus Lille I within Université Lille Nord de France. 50 36 21.62 N 3 08 13.63 E -Église de l'Assomption simultanée (La Petite-Pierre) 48 51 25.2 N 7 18 55.84 E -Église de la Sainte-Trinité (Lauterbourg) 48 58 30.1 N 8 10 40.77 E -Église de Saint-Lothain 46 49 27.84 N 5 38 30.12 E -Église de Saint-Paul de Frontignan 43 26 50.47 N 3 45 18.66 E -Église des Augustins (Ribeauvillé) 48 11 43.44 N 7 19 08.87 E -Église des Jésuites (Molsheim) 48 32 25.3 N 7 29 45 E -Église des Saints-Innocents (Blienschwiller) 48 20 25.8 N 7 25 06.17 E -Église Notre-Dame (Guebwiller) 47 54 20.75 N 7 12 52.56 E -Église Notre-Dame de la Dalbade 43 35 51.36 N 1 26 32.89 E -Église Notre-Dame-de-l'Assomption (Bergheim) 48 12 18 N 7 21 53.28 E -Église Notre-Dame-de-l'Assomption (Bernardswiller) 48 27 10.08 N 7 27 49.57 E -Église Notre-Dame-de-l'Assomption (Monswiller) 48 45 17.61 N 7 22 39.66 E -Église Notre-Dame-de-l'Assomption (Rosenwiller) 48 30 21.96 N 7 26 25.48 E -Église Notre-Dame-de-l'Assomption (Rouffach) 47 57 24 N 7 18 02 E -Église Notre-Dame-de-la-Nativité (Saverne) 48 44 28.32 N 7 21 50.36 E -Église protestante (Balbronn) 48 35 05.28 N 7 26 15.97 E -Église protestante (Baldenheim) 48 14 15 N 7 32 14.35 E -Église protestante (Berg) 48 53 52.08 N 7 09 24.01 E -Église protestante (Bischheim) 48 36 55.08 N 7 45 21.89 E -Église protestante (Fouday) 48 25 17.76 N 7 11 12.95 E -Église protestante (Harskirchen) 48 56 02.04 N 7 02 20.15 E -Église protestante (Scharrachbergheim) 48 35 35.52 N 7 29 55.9 E -Église protestante (Schiltigheim) 48 36 21.96 N 7 45 05.04 E -Église protestante (Weiterswiller) 48 51 10.44 N 7 24 50.9 E -Église protestante du Temple Neuf (Strasbourg) 48 35 00 N 7 44 54 E -Église Saint-Eustache de Paris 48 51 48 N 2 20 42 E -Église Saint-Laurent (Paris) 48 52 29.45 N 2 21 29.92 E -Église Saint-Michel d'Ernolsheim-lès-Saverne Bells 48 47 27.85 N 7 22 47.57 E -Église Saint-Nicolas-du-Chardonnet St. Nicolas du Chardonnet is a church in the centre of Paris, France located in the 5th arrondissement. 48 50 57 N 2 21 01 E -Église Saint-Pierre de Montmartre Saint-Pierre de Montmartre is a church in Paris 48 53 12 N 2 20 31 E -Église Saint-Pierre-de-Rhèdes 43 35 16.22 N 3 04 43.64 E -Église Saint-Pierre-Saint-Paul de Rueil-Malmaison 48 52 35.4 N 2 10 53.15 E -Église Saint-Sulpice 48 51 04 N 2 20 05 E -Église Saint-Étienne-du-Mont Saint-Étienne-du-Mont church is located in Paris, nearby Panthéon. 48 50 47 N 2 20 52 E -Église Sainte-Marie-Madeleine de Rennes-le-Château 42 55 41.05 N 2 15 45.69 E -Église Saints-Pierre-et-Paul (Andlau) 48 23 16.3 N 7 24 54.3 E -Église Saints-Pierre-et-Paul (Eguisheim) 48 02 32.28 N 7 18 21.2 E -Église Saints-Pierre-et-Paul (Hohatzenheim) 48 42 44.64 N 7 36 59.11 E -Église Saints-Pierre-et-Paul (Neuwiller-lès-Saverne) 48 49 25 N 7 24 20 E -Église Saints-Pierre-et-Paul (Obernai) 48 27 47.88 N 7 28 54.48 E -Église Saints-Pierre-et-Paul (Ottmarsheim) 47 47 13.2 N 7 30 25.2 E -Église Saints-Pierre-et-Paul (Rosheim) 48 29 48 N 7 28 14 E -Église Saints-Pierre-et-Paul (Sigolsheim) 48 08 04.2 N 7 18 03.1 E -Église Saints-Pierre-et-Paul (Wissembourg) 49 02 14 N 7 56 30 E -Église St Antoine de Padoue (Saverne) The cloister 48 44 29.4 N 7 21 40.82 E -Église St Arbogast (Offenheim) 48 37 53.76 N 7 36 59.54 E -Église St Barthélemy (Sarrewerden) 48 55 22.8 N 7 04 56.93 E -Église St Benoît (Bergholtzzell) 47 55 51.34 N 7 13 54.48 E -Église St Blaise (Valff) 48 25 12.36 N 7 31 06.96 E -Église St Cyriaque (Altorf) 48 31 22.7 N 7 31 50 E -Église St Gall (Niedermorschwihr) 48 05 57.84 N 7 16 26.47 E -Église St Gall protestante (Domfessel) 48 57 06.48 N 7 09 07.56 E -Église St Georges (Châtenois) 48 16 09.12 N 7 23 51 E -Église St Georges (Sélestat) 48 15 36 N 7 27 24.12 E -Église St Grégoire (Ribeauvillé) 48 11 49.2 N 7 19 00.41 E -Église St Guillaume protestante (Strasbourg) 48 34 55.5 N 7 45 28 E -Église St Hippolyte (Saint-Hippolyte) 48 14 01.68 N 7 22 04.01 E -Église St Jacques-le-Majeur (Kuttolsheim) 48 38 37.32 N 7 31 41.34 E -Église St Jacques-le-Majeur simultanée (Dettwiller) 48 45 12.6 N 7 27 56.77 E -Église St Jacques-le-Majeur simultanée (Hunawihr) 48 10 42.24 N 7 18 38.02 E -Église St Jean (Strasbourg) 48 35 04 N 7 44 25 E -Église St Jean protestante (Wissembourg) 49 02 18.96 N 7 56 33.36 E -Église St Jean-Baptiste (Saint-Jean-Saverne) 48 46 18.7 N 7 21 48.5 E -Église St Jean-Baptiste (Surbourg) 48 54 34.2 N 7 50 50.28 E -Église St Jean-Baptiste (Wattwiller) 47 50 07.72 N 7 10 37.27 E -Église St Jean-Baptiste simultanée (Hohwiller) 48 45 12.78 N 7 27 56.77 E -Église St Laurent (Dieffenbach-au-Val) 48 18 44.64 N 7 19 41.34 E -Église St Laurent protestante (Dorlisheim) 48 31 30 N 7 29 13.99 E -Église St Léger (Guebwiller) 47 54 42.1 N 7 12 33.75 E -Église St Léger (Murbach) 47 55 24 N 7 09 29 E -Église St Martin (Ammerschwihr) 48 07 37.92 N 7 16 54.01 E -Église St Martin (Ebersheim) 48 18 14.04 N 7 30 14.08 E -Église St Martin (Pfaffenheim) 47 59 05.28 N 7 17 08.59 E -Église St Martin protestante (Barr) 48 24 33.84 N 7 26 51.47 E -Église St Martin protestante (Westhoffen) 48 36 01.8 N 7 26 30.3 E -Église St Maurice (Ebersmunster) 48 18 39.5 N 7 31 37 E -Église St Maurice (Fegersheim) 48 29 23.64 N 7 40 50.27 E -Église St Maurice (Orschwiller) 48 14 27.24 N 7 22 44.62 E -Église St Maurice (Soultz-Haut-Rhin) 47 53 13.2 N 7 13 48.29 E -Église St Maurice (Soultz-les-Bains) 48 34 17.4 N 7 29 09.35 E -Église St Maurice (Willgottheim) 48 40 14.52 N 7 30 33.23 E -Église St Michel (Reichshoffen) 48 55 54.84 N 7 39 52.02 E -Église St Michel (Weyersheim) 48 43 06.24 N 7 48 07.96 E -Église St Médard (Bœrsch) 48 28 40.44 N 7 26 24.4 E -Église St Nicolas (Haguenau) 48 49 13 N 7 47 32 E -Église St Nicolas (Neuve-Église) 48 19 50.88 N 7 18 48.24 E -Église St Nicolas (Wingersheim) 48 43 18.84 N 7 38 08.02 E -Église St Pantaléon (Gueberschwihr) 48 00 16.92 N 7 16 29.78 E -Église St Paul protestante (Strasbourg) 48 35 11 N 7 45 35 E -Église St Pierre "Dompeter" (Molsheim, Avolsheim) 48 33 24.12 N 7 30 19.59 E -Église St Pierre le Jeune catholique (Strasbourg) 48 35 18.35 N 7 44 55.75 E -Église St Pierre le Jeune protestante (Strasbourg) 48 35 08 N 7 44 47 E -Église St Rémi (Itterswiller) 48 21 51.48 N 7 25 37.42 E -Église St Sébastien (Soultzmatt) 47 57 37.08 N 7 14 15.36 E -Église St Thomas protestante (Strasbourg) 48 34 47 N 7 44 44 E -Église St Trophime (Eschau) 48 29 25.08 N 7 42 57.96 E -Église St Ulrich (Altenstadt) 49 01 49.8 N 7 58 05.88 E -Église St Ulrich (Wittersheim) 48 46 53.04 N 7 39 27.47 E -Église St Étienne (Rosheim) 48 29 43.8 N 7 27 59.72 E -Église St Étienne (Seltz) 48 53 37.32 N 8 06 28.44 E -Église St Étienne simultanée (Wangen) 48 37 01.56 N 7 27 53.68 E -Église Ste Anne (Turckheim) 48 05 15.72 N 7 16 41.12 E -Église Ste Aurélie protestante (Strasbourg) 48 34 53 N 7 44 00 E -Église Ste Colombe (Hattstatt) 48 00 44.28 N 7 18 06.01 E -Église Ste Croix (Kaysersberg) Lamentation of Christ 48 08 20.04 N 7 15 48.56 E -Église Ste Croix (Rountzenheim) 48 49 08.76 N 8 00 26.39 E -Église Ste Foy (Sélestat) 48 15 33.67 N 7 27 21.81 E -Église Ste Lucie (Niederhergheim) 47 59 10.32 N 7 23 48.41 E -Église Ste Madeleine (Strasbourg) 48 34 48 N 7 45 17 E -Église Ste Marguerite (Geispolsheim) 48 30 50.4 N 7 38 36.06 E -Église Ste Odile (Lapoutroie) 48 09 08.64 N 7 10 03.97 E -Église Ste Odile (Wintzfelden) 47 58 32.88 N 7 11 49.92 E -Église Ste Walburge (Walbourg) 48 53 05.51 N 7 47 21.97 E -Églises St Pierre le Vieux (Strasbourg) 48 34 58 N 7 44 24 E -Đình Bảng Bảng Communal House (Đình Bảng in Vietnamese) is one of largest and finest village communal houses in Việt Nam. It is located in Đình Bảng commune, Từ Sơn district, Bắc Ninh province. 21 06 29.99 N 105 57 06.31 E -Архангельск 64 33 00 N 40 32 00 E -Астана 51 11 00 N 71 24 00 E -Астрахань 46 20 00 N 48 01 00 E -Барнаул 53 21 24 N 83 47 14 E -Боровск Borovsk 55 12 27.19 N 36 29 05.05 E -Душанбе 38 34 23 N 68 47 11 E -Екатеринбург 59 57 00 N 30 19 00 E -Москва 55 45 21 N 37 37 04 E -Нижний Новгород 56 19 37 N 44 00 27 E -Санкт-Петербург 59 57 00 N 30 19 00 E -Северодвинск 64 34 00 N 39 51 00 E -กรุงเทพมหานคร Bangkok 13 45 00 N 100 31 00 E +Архангельск 3 64 33 00 N 40 31 48 E +Астана 1 51 07 48 N 71 25 48 E +Астрахань 46 19 59.88 N 48 01 00.12 E +Боровск 55 12 27.19 N 36 29 05.05 E +Душанбе Dushanbe is the capital city of Tajikistan. 38 34 23.16 N 68 47 11.04 E +Екатеринбург 56 49 59.88 N 60 34 59.88 E +Москва 55 45 20.88 N 37 37 04.08 E +Нижний Новгород 56 19 36.84 N 44 00 27 E +Санкт-Петербург 59 57 00 N 30 19 12 E სვეტიცხოველი 41 50 31 N 44 43 16 E ჯვარი 41 30 06.84 N 44 26 24.72 E -鹿児島市 Kagoshima(鹿児島市; -shi) is a city in Japan and the capital city of Kagoshima Prefecture. 31 35 48.5 N 130 33 25.7 E -薩摩川内市 Satsumasendai is a city in Kagoshima prefecture, Japan. 31 48 48.5 N 130 18 14.3 E -上海 Shanghai is the largest city in China and is divided into 18 districts and one county (the island in the Yangtze River). It is located on the coast of eastern China at the mouth of the Chang Jiang (Yangtze River), and borders the provinces of Jiangsu and Zhejiang. 31 10 00 N 121 28 00 E -东平 Daqing River 35 54 30 N 116 18 00 E +চট্টগ্রাম 22 19 12 N 91 49 12 E +上海 1 31 10 12 N 121 28 12 E 中南海 Zhongnanhai (Chinese: 中南海; pinyin: Zhōngnánhăi) is a complex of buildings in Beijing, China which serves as the central headquarters for the Communist Party of China and the government of the People's Republic of China. 39 54 41 N 116 22 50 E 九寨沟 Jiuzhaigou Valley (Chinese: 九寨沟; pinyin: Jiǔzhàigōu; lit. "Nine Stockades Gully") is a nature reserve in Aba(阿坝) Tibetan and Qiang Autonomous District, northern Sichuan province, China. 33 09 34 N 103 52 40 E 云南 Yunnan(云南) is a Chinese southwest border province, with the most varied nationalities in China. There are 52 nationalities of people living in Yunnan, out of 56 total throughout China. 25 03 00 N 101 52 00 E -京都市 Kyoto is a city in Japan. It was the capital of Japan from 794 to 1869. 35 00 42 N 135 46 05 E +京都市 Kyoto is a city in Japan. It was the capital of Japan from 794 to 1869. 35 00 42.12 N 135 46 05.16 E 兵馬俑 Terracotta Army 34 23 05.7 N 109 16 23.1 E 別府市 Beppu is a famous onsen city in Oita Prefecture on the island of Kyushu in Japan. 33 17 04.6 N 131 29 28.6 E 北九州市 Kitakyūshū is a city in Fukuoka Prefecture on the island of Kyushu, Japan. 33 53 00.3 N 130 52 30.7 E 北京动物园 beijing zoo lies west of Xizhimen and is the western part of the Beijing, China. It is one of the largest zoos in mainland china. 39 56 19 N 116 20 00 E 北海公园 中文: 北海公园位于中国北京市城区的中偏北部,故宫和景山的西北侧,始建于辽代,是世界上现存建园时间最早的皇家宫苑。 39 55 28 N 116 22 59 E -南京 Nanjing (南京) is the capital of Jiangsu Province of China. It was the Chinese capital from 1927-1949. 32 03 00 N 118 46 00 E +南京 Nanjing (南京) is the capital of Jiangsu Province of China. It was the Chinese capital from 1927-1949. 32 03 00 N 118 46 00.12 E 南法華寺 Minamihokke-ji is the Buddhist temple in Takatori, Nara prefecture, Japan. 34 25 35.1 N 135 48 35.5 E -台南市 22 59 00 N 120 11 00 E -名古屋市 35 07 00 N 136 56 00 E -和歌山市 Wakayama (和歌山市, Wakayama-shi) is the capital city of Wakayama Prefecture in the Kansai region of Japan. 34 13 49.3 N 135 10 14.7 E +台南市 22 58 59.88 N 120 10 59.88 E +和歌山市 Wakayama (和歌山市, Wakayama-shi) is the capital city of Wakayama Prefecture in the Kansai region of Japan. 34 13 49.3 N 135 10 14.7 E 哈尔滨 Harbin is a sub-provincial city in north-east China and the capital of the Heilongjiang Province. 45 48 05 N 126 31 45 E -四川 Nature reserve in Aba(阿坝) Tibetan and Qiang Autonomous District, northern Sichuan province, China. It is known for its many multi-level waterfalls and colorful lakes, and was declared a UNESCO World Heritage Site in 1992. 30 08 00 N 102 56 00 E +四川 Nature reserve in Aba(阿坝) Tibetan and Qiang Autonomous District, northern Sichuan province, China. 30 08 00 N 102 56 00 E 圆明园 Yuanmingyuan (pinyin: Yuanmingyuan, 圆明园), or the old Summer Palace in Peking. 40 00 26 N 116 17 33 E 大津市 Ōtsu is a city in Japan. It was the capital of Japan from 667 to 672. 35 01 04.1 N 135 51 17 E -大阪市 Osaka 34 41 37.5 N 135 30 07.6 E +大阪市 34 41 37.5 N 135 30 07.6 E 天坛 Temple of Heaven in Beijing. 39 52 56.1 N 116 24 23.7 E 天安門 Tiananmen (Gate of Heavenly Peace) in Beijing was the southern gate of the Imperial City in Beijing. 39 54 26.4 N 116 23 27.9 E 天安门广场 Mausoleum of Mao Zedong 39 54 12 N 116 23 30 E 宇治市 Uji is a city in Kyoto prefecture. The Byodoin (an ancient Buddhist temple) and the Ujigami Shrine are famous landmarks in Uji. 34 53 03.7 N 135 47 59.3 E -小田原市 Odawara, Kanagawa 35 15 52.6 N 139 09 08 E 屋久島 Yakushima island 30 20 00 N 130 30 00 E 广东 Guangdong (广东) is a coastal province in southern China adjacent to Hongkong and Macao. 23 24 00 N 113 30 00 E -广州 Guangzhou is the capital of Guangdong Province in southern China. The city was formerly known internationally as Canton City or simply Canton. 23 07 43.66 N 113 15 32.31 E -広島市 Hiroshima is one of largest cities in Japan and the capital of Hiroshima prefecture. 34 23 06.9 N 132 27 19.1 E +广州 23 07 43.66 N 113 15 32.31 E +広島市 Hiroshima is one of largest cities in Japan and the capital of Hiroshima prefecture. During World War II, it was the first city in the world to have an atomic bomb dropped on it. 34 23 06.9 N 132 27 19.1 E 徳島市 Tokushima is the capital city of Tokushima prefecture on the island of Kyushu in Japan. 34 04 13 N 134 33 17.8 E -成都 Chengdu is the capital city and prefecture-level division of Sichuan Province, in southwestern China. 30 39 49 N 104 04 00 E +成都 Chengdu is the capital city and prefecture-level division of Sichuan Province, in southwestern China. 30 39 48.96 N 104 04 00.12 E 景山公园 Jingshan Park, Dongcheng District, Beijing. 39 55 24.5 N 116 23 26.2 E -杭州 Hangzhou (杭州) is a picturesque city in south China. It is the capital of Zhejiang Province and was visited by Marco Polo. 30 15 00 N 120 10 00 E -武汉 Wuhan is the capital of the Chinese province of Hubei 30 34 21 N 114 16 45 E -深圳 Shenzhen is a major city in Guangdong Province, China. 22 32 06 N 114 03 14.4 E -滕王阁 The Pavilion of Prince Teng or Tengwang Pavilion is a building in the north west of the city of Nanchang, in Jiangxi province, China. 28 41 02.76 N 115 52 32.88 E +杭州 30 15 00 N 120 10 03 E +武汉 Wuhan is the capital of the Chinese province of Hubei 30 35 13.92 N 114 17 17.16 E +滕王阁 28 41 02.76 N 115 52 32.88 E 相模原市 Sagamihara, Kanagawa 35 34 17.1 N 139 22 23.3 E 祇園 Gion (祇園) is a district of Kyoto, Japan, originally developed in the middle ages. 35 00 13 N 135 46 30 E 福岡市 Fukuoka, Fukuoka 33 35 24.5 N 130 24 06.2 E +福建 Lu You Statue in Ningde中文(简体)‎: 宁德的陆游雕像 25 54 00 N 118 18 00 E 紫禁城 The Forbidden City (紫禁城), located at the centre of Beijing, China, was the imperial palace of the last two imperial dynasties of China (from 1420 to 1924). 39 54 50.1 N 116 23 27.6 E -西安 Xi'an is an ancient city located in north central China. It was the capital of various dynasties from 1046 B.C. to 907 A.D, and it has been known under a number of different names including most notably Chang'an during the Tang dynasty. 34 16 00 N 108 57 00 E +薩摩川内市 Satsumasendai is a city in Kagoshima prefecture, Japan. 31 48 48.5 N 130 18 14.3 E +西安 Xi'an is an ancient city located in north central China. It was the capital of various dynasties from 1046 B.C. to 907 A.D, and it has been known under a number of different names including most notably Chang'an during the Tang dynasty. Today it is the capital of Shaanxi province. 34 16 00.12 N 108 54 00 E 逗子市 Zushi (逗子市 Zushi-shi) is a city located in Kanagawa, Japan. 35 17 44.2 N 139 34 49.2 E -重庆 Chongqing is located in the southwest of China, is China's largest and most populous municipality. 29 33 00 N 106 33 00 E -鎌倉 Zeniarai Benten shrine 35 19 09.3 N 139 32 48.1 E +重庆 Chongqing is located in the southwest of China, is China's largest and most populous municipality. 29 33 00 N 106 30 24.84 E 颐和园 The Summer Palace is a former imperial palace in northwest of Beijing, China. It has been transformed in a public garden. 39 59 51 N 116 16 08.04 E -香港 22 16 01 N 114 11 17 E -高雄市 Kaohsiung is a city in Taiwan. 22 38 00 N 120 16 00 E -서울특별시 Seoul is the capital of South Korea. 37 35 00 N 127 00 00 E +香港 22 16 48 N 114 09 36 E +高雄市 Kaohsiung is a city in Taiwan. 22 37 00.01 N 120 18 00 E +鹿児島市 Kagoshima(鹿児島市; -shi) is a city in Japan and the capital city of Kagoshima Prefecture. 31 35 48.12 N 130 33 25.92 E diff --git a/src/tim/prune/function/settings/SaveConfig.java b/src/tim/prune/function/settings/SaveConfig.java index d449051..b737bd2 100644 --- a/src/tim/prune/function/settings/SaveConfig.java +++ b/src/tim/prune/function/settings/SaveConfig.java @@ -1,24 +1,11 @@ package tim.prune.function.settings; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.GridLayout; import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.Enumeration; -import java.util.Properties; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JDialog; import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JPanel; import tim.prune.App; import tim.prune.GenericFunction; @@ -30,8 +17,6 @@ import tim.prune.config.Config; */ public class SaveConfig extends GenericFunction { - private JDialog _dialog = null; - /** * Constructor * @param inApp application object for callback @@ -50,86 +35,6 @@ public class SaveConfig extends GenericFunction * Begin the function */ public void begin() - { - // Make new dialog window (don't reuse it) - _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - _dialog.getContentPane().add(makeDialogComponents()); - _dialog.pack(); - _dialog.setVisible(true); - } - - - /** - * Create dialog components - * @return Panel containing all gui elements in dialog - */ - private Component makeDialogComponents() - { - JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BorderLayout()); - dialogPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); - JLabel descLabel = new JLabel(I18nManager.getText("dialog.saveconfig.desc")); - dialogPanel.add(descLabel, BorderLayout.NORTH); - - // Grid panel in centre - JPanel mainPanel = new JPanel(); - mainPanel.setLayout(new GridLayout(0, 2, 15, 2)); - mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15)); - Properties conf = Config.getAllConfig(); - Enumeration keys = conf.keys(); - while (keys.hasMoreElements()) - { - String key = keys.nextElement().toString(); - String keyLabel = I18nManager.getText("dialog.saveconfig." + key); - if (!keyLabel.equals("dialog.saveconfig." + key)) - { - mainPanel.add(new JLabel(keyLabel)); - String val = conf.getProperty(key); - String tipText = val; - if (Config.isKeyBoolean(key)) { - val = Config.getConfigBoolean(key)?I18nManager.getText("dialog.about.yes"):I18nManager.getText("dialog.about.no"); - } - else if (val != null && val.length() > 30) { - val = val.substring(0, 30) + " ..."; - } - JLabel label = new JLabel(val); - label.setToolTipText(tipText); - mainPanel.add(label); - } - } - dialogPanel.add(mainPanel, BorderLayout.CENTER); - - // button panel at bottom - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - 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(); - _dialog = null; - } - }); - buttonPanel.add(cancelButton); - dialogPanel.add(buttonPanel, BorderLayout.SOUTH); - return dialogPanel; - } - - - /** - * Finish the dialog when OK pressed - */ - private void finish() { File configFile = Config.getConfigFile(); if (configFile == null) {configFile = Config.HOME_CONFIG_FILE;} @@ -141,8 +46,6 @@ public class SaveConfig extends GenericFunction File saveFile = chooser.getSelectedFile(); saveConfig(saveFile); } - _dialog.dispose(); - _dialog = null; } /** @@ -153,6 +56,24 @@ public class SaveConfig extends GenericFunction saveConfig(Config.getConfigFile()); } + /** + * Autosave has been turned on or off, so maybe need to save + * @param inSaveOn true if autosave was switched on + */ + public void autosaveSwitched(boolean inSaveOn) + { + File configFile = Config.getConfigFile(); + if (inSaveOn && configFile == null) + { + begin(); + } + else if (!inSaveOn && configFile != null) + { + // TODO: Ask whether to save or not? + silentSave(); + } + } + /** * Actually save the config file * @param inSaveFile file to save to @@ -165,7 +86,6 @@ public class SaveConfig extends GenericFunction + currBounds.width + "x" + currBounds.height; Config.setConfigString(Config.KEY_WINDOW_BOUNDS, windowBounds); - // TODO: Check for null inSaveFile, then just call finish() ? FileOutputStream outStream = null; try { @@ -180,5 +100,7 @@ public class SaveConfig extends GenericFunction finally { try {outStream.close();} catch (Exception e) {} } + // Remember where it was saved to + Config.setConfigFile(inSaveFile); } } diff --git a/src/tim/prune/function/settings/SetDisplaySettings.java b/src/tim/prune/function/settings/SetDisplaySettings.java index 63286c5..fd15a50 100644 --- a/src/tim/prune/function/settings/SetDisplaySettings.java +++ b/src/tim/prune/function/settings/SetDisplaySettings.java @@ -93,8 +93,11 @@ public class SetDisplaySettings extends GenericFunction private JCheckBox _antialiasCheckbox = null; private JComboBox _wpIconCombobox = null; private JRadioButton[] _sizeRadioButtons = null; + private JRadioButton[] _windowStyleRadios = null; private JButton _okButton = null; + private static final String STYLEKEY_NIMBUS = "javax.swing.plaf.nimbus.NimbusLookAndFeel"; + /** * Constructor @@ -176,6 +179,25 @@ public class SetDisplaySettings extends GenericFunction waypointsPanel.setAlignmentX(Component.CENTER_ALIGNMENT); midPanel.add(waypointsPanel); + // Panel for window style + JPanel windowStylePanel = new JPanel(); + windowStylePanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3)) + ); + windowStylePanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + windowStylePanel.add(new JLabel(I18nManager.getText("dialog.displaysettings.windowstyle"))); + windowStylePanel.add(Box.createHorizontalStrut(10)); + ButtonGroup styleGroup = new ButtonGroup(); + final String[] styleKeys = {"default", "nimbus"}; + _windowStyleRadios = new JRadioButton[2]; + for (int i=0; i<2; i++) + { + _windowStyleRadios[i] = new JRadioButton( + I18nManager.getText("dialog.displaysettings.windowstyle." + styleKeys[i])); + styleGroup.add(_windowStyleRadios[i]); + windowStylePanel.add(_windowStyleRadios[i]); + } + midPanel.add(windowStylePanel); mainPanel.add(midPanel, BorderLayout.CENTER); // button panel at bottom @@ -221,6 +243,7 @@ public class SetDisplaySettings extends GenericFunction _antialiasCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_ANTIALIAS)); _wpIconCombobox.setSelectedIndex(Config.getConfigInt(Config.KEY_WAYPOINT_ICONS)); selectIconSizeRadio(Config.getConfigInt(Config.KEY_WAYPOINT_ICON_SIZE)); + selectWindowStyleRadio(Config.getConfigString(Config.KEY_WINDOW_STYLE)); _dialog.setVisible(true); } @@ -240,6 +263,20 @@ public class SetDisplaySettings extends GenericFunction } } + /** + * Select the corresponding radio button according to the selected style + * @param inValue style string saved in Config + */ + private void selectWindowStyleRadio(String inValue) + { + int selectedRadio = 0; + if (inValue != null && inValue.equals(STYLEKEY_NIMBUS)) + { + selectedRadio = 1; + } + _windowStyleRadios[selectedRadio].setSelected(true); + } + /** * @return numeric value of selected icon size according to radio buttons */ @@ -267,6 +304,8 @@ public class SetDisplaySettings extends GenericFunction Config.setConfigBoolean(Config.KEY_ANTIALIAS, _antialiasCheckbox.isSelected()); Config.setConfigInt(Config.KEY_WAYPOINT_ICONS, _wpIconCombobox.getSelectedIndex()); Config.setConfigInt(Config.KEY_WAYPOINT_ICON_SIZE, getSelectedIconSize()); + final String styleString = (_windowStyleRadios[1].isSelected() ? STYLEKEY_NIMBUS : null); + Config.setConfigString(Config.KEY_WINDOW_STYLE, styleString); // refresh display UpdateMessageBroker.informSubscribers(DataSubscriber.MAPSERVER_CHANGED); _dialog.dispose(); diff --git a/src/tim/prune/function/settings/SetLanguage.java b/src/tim/prune/function/settings/SetLanguage.java index 642e715..d6edd8b 100644 --- a/src/tim/prune/function/settings/SetLanguage.java +++ b/src/tim/prune/function/settings/SetLanguage.java @@ -44,12 +44,11 @@ public class SetLanguage extends GenericFunction private static final String[] LANGUAGE_NAMES = {"afrikaans", "\u010de\u0161tina", "deutsch", "english", "american english", "espa\u00F1ol", "fran\u00E7ais", "italiano", "magyar", "nederlands", "polski", "portugu\u00EAs", "rom\u00E2n\u0103", "suomi", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian)", "\u4e2d\u6587 (chinese)", - "\u65E5\u672C\u8A9E (japanese)", "\uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean)", "schwiizerd\u00FC\u00FCtsch", - "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430 \u043c\u043e\u0432\u0430 (ukrainian)" + "\u65E5\u672C\u8A9E (japanese)", "\uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean)", "schwiizerd\u00FC\u00FCtsch" }; /** Associated language codes (must be in same order as names!) */ private static final String[] LANGUAGE_CODES = {"af", "cz", "de", "en", "en_us", "es", "fr", "it", "hu", - "nl", "pl", "pt", "ro", "fi", "ru", "zh", "ja", "ko", "de_ch", "uk" + "nl", "pl", "pt", "ro", "fi", "ru", "zh", "ja", "ko", "de_ch" }; diff --git a/src/tim/prune/function/settings/SetPathsFunction.java b/src/tim/prune/function/settings/SetPathsFunction.java index a5d0871..e8faeb1 100644 --- a/src/tim/prune/function/settings/SetPathsFunction.java +++ b/src/tim/prune/function/settings/SetPathsFunction.java @@ -95,7 +95,7 @@ public class SetPathsFunction extends GenericFunction _installedLabels = new JLabel[NUM_KEYS]; for (int i=0; i 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); - } - } - } - } + numAltitudesFound += applySrtmTileToWholeTrack(tile, heights, inOverwriteZeros); } } - catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage(); + catch (IOException ioe) { + errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage(); } } } @@ -319,6 +276,65 @@ public class LookupSrtmFunction extends GenericFunction implements Runnable return new ZipInputStream(inUrl.openStream()); } + /** + * Given the height data read in from file, apply the given tile to all points + * in the track with missing altitude + * @param inTile tile being applied + * @param inHeights height data read in from file + * @param inOverwriteZeros true to overwrite zero altitude values + * @return number of altitudes found + */ + private int applySrtmTileToWholeTrack(SrtmTile inTile, int[] inHeights, boolean inOverwriteZeros) + { + int numAltitudesFound = 0; + // Loop over all points in track, try to apply altitude from array + for (int p = 0; p < _track.getNumPoints(); p++) + { + DataPoint point = _track.getPoint(p); + if (!point.hasAltitude() + || (inOverwriteZeros && point.getAltitude().getValue() == 0)) + { + if (new SrtmTile(point).equals(inTile)) + { + double x = (point.getLongitude().getDouble() - inTile.getLongitude()) * 1200; + double y = 1201 - (point.getLatitude().getDouble() - inTile.getLatitude()) * 1200; + int idx1 = ((int)y)*1201 + (int)x; + try + { + int[] fouralts = {inHeights[idx1], inHeights[idx1+1], inHeights[idx1-1201], inHeights[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); + } + } + } + } + return numAltitudesFound; + } + /** * Perform a bilinear interpolation on the given altitude array * @param inAltitudes array of four altitude values on corners of square (bl, br, tl, tr) diff --git a/src/tim/prune/function/srtm/TileFinder.java b/src/tim/prune/function/srtm/TileFinder.java index 60a9479..5ada68c 100644 --- a/src/tim/prune/function/srtm/TileFinder.java +++ b/src/tim/prune/function/srtm/TileFinder.java @@ -30,6 +30,11 @@ public abstract class TileFinder URL[] urls = new URL[inTiles.size()]; // Read dat file into array byte[] lookup = readDatFile(); + if (lookup == null) + { + System.err.println("Build error: resource srtmtiles.dat missing!"); + return null; + } for (int t=0; t= 0) + { + coord = coord.replaceAll(String.valueOf(brokenDeg), "\u00B0"); + } + return restrictDP(coord); + } + + + /** + * Restrict the given coordinate to a limited number of decimal places for display + * @param inCoord coordinate string + * @return chopped string + */ + private static String restrictDP(String inCoord) + { + final int DECIMAL_PLACES = 7; + if (inCoord == null) return ""; + String result = inCoord; + final int dotPos = Math.max(inCoord.lastIndexOf('.'), inCoord.lastIndexOf(',')); + if (dotPos >= 0) + { + final int chopPos = dotPos + DECIMAL_PLACES; + if (chopPos < (inCoord.length()-1)) + { + result = inCoord.substring(0, chopPos); + // Maybe there's an exponential in there too which needs to be appended + int expPos = inCoord.toUpperCase().indexOf("E", chopPos); + if (expPos > 0 && expPos < (inCoord.length()-1)) + { + result += inCoord.substring(expPos); + } + } + } + return result; + } + +} diff --git a/src/tim/prune/gui/DetailsDisplay.java b/src/tim/prune/gui/DetailsDisplay.java index 2fa98dc..1b8148d 100644 --- a/src/tim/prune/gui/DetailsDisplay.java +++ b/src/tim/prune/gui/DetailsDisplay.java @@ -306,6 +306,9 @@ public class DetailsDisplay extends GenericDisplay if (_timezone == null || (inUpdateType | UNITS_CHANGED) > 0) { _timezone = TimezoneHelper.getSelectedTimezone(); } + if ((inUpdateType | UNITS_CHANGED) > 0) { + Config.setConfigString(Config.KEY_COORD_DISPLAY_FORMAT, "" + getSelectedCoordFormat()); + } if (_track == null || currentPoint == null) { @@ -327,8 +330,10 @@ public class DetailsDisplay extends GenericDisplay _indexLabel.setText(LABEL_POINT_SELECTED + (currentPointIndex+1) + " " + I18nManager.getText("details.index.of") + " " + _track.getNumPoints()); - _latLabel.setText(makeCoordinateLabel(LABEL_POINT_LATITUDE, currentPoint.getLatitude(), _coordFormatDropdown.getSelectedIndex())); - _longLabel.setText(makeCoordinateLabel(LABEL_POINT_LONGITUDE, currentPoint.getLongitude(), _coordFormatDropdown.getSelectedIndex())); + _latLabel.setText(LABEL_POINT_LATITUDE + + CoordDisplay.makeCoordinateLabel(currentPoint.getLatitude(), getSelectedCoordFormat())); + _longLabel.setText(LABEL_POINT_LONGITUDE + + CoordDisplay.makeCoordinateLabel(currentPoint.getLongitude(), getSelectedCoordFormat())); Unit altUnit = Config.getUnitSet().getAltitudeUnit(); _altLabel.setText(currentPoint.hasAltitude()? (LABEL_POINT_ALTITUDE + currentPoint.getAltitude().getValue(altUnit) + " " + @@ -346,7 +351,8 @@ public class DetailsDisplay extends GenericDisplay } // Maybe the point has a description? String pointDesc = currentPoint.getFieldValue(Field.DESCRIPTION); - if (pointDesc == null || pointDesc.equals("") || currentPoint.hasMedia()) { + if (pointDesc == null || pointDesc.equals("") || currentPoint.hasMedia()) + { _descLabel.setText(""); _descLabel.setToolTipText(""); } @@ -409,11 +415,13 @@ public class DetailsDisplay extends GenericDisplay filename = info.getName(); } } - if (filename != null) { + if (filename != null) + { _filenameLabel.setText(LABEL_POINT_FILENAME + filename); _filenameLabel.setToolTipText(filename); } - else { + else + { _filenameLabel.setText(""); _filenameLabel.setToolTipText(""); } @@ -442,7 +450,8 @@ public class DetailsDisplay extends GenericDisplay _aveSpeedLabel.setText(I18nManager.getText("details.range.avespeed") + ": " + DisplayUtils.roundedNumber(selection.getMovingDistance()/numMovingSeconds*3600.0) + " " + speedUnitsStr); } - else { + else + { _durationLabel.setText(""); _aveSpeedLabel.setText(""); } @@ -502,7 +511,9 @@ public class DetailsDisplay extends GenericDisplay _photoThumbnail.setVisible(true); _photoThumbnail.setPhoto(currentPhoto); _rotationButtons.setVisible(true); - if ((inUpdateType & DataSubscriber.PHOTOS_MODIFIED) > 0) {_photoThumbnail.refresh();} + if ((inUpdateType & DataSubscriber.PHOTOS_MODIFIED) > 0) { + _photoThumbnail.refresh(); + } } _photoThumbnail.repaint(); @@ -538,63 +549,6 @@ public class DetailsDisplay extends GenericDisplay } - /** - * Construct an appropriate coordinate label using the selected format - * @param inPrefix prefix of label - * @param inCoordinate coordinate - * @param inFormat index of format selection dropdown - * @return language-sensitive string - */ - private static String makeCoordinateLabel(String inPrefix, Coordinate inCoordinate, int inFormat) - { - String coord = null; - switch (inFormat) { - case 1: // degminsec - coord = inCoordinate.output(Coordinate.FORMAT_DEG_MIN_SEC); break; - case 2: // degmin - coord = inCoordinate.output(Coordinate.FORMAT_DEG_MIN); break; - case 3: // degrees - coord = inCoordinate.output(Coordinate.FORMAT_DEG); break; - default: // just as it was - coord = inCoordinate.output(Coordinate.FORMAT_NONE); - } - // Fix broken degree signs (due to unicode mangling) - final char brokenDeg = 65533; - if (coord.indexOf(brokenDeg) >= 0) { - coord = coord.replaceAll(String.valueOf(brokenDeg), "\u00B0"); - } - return inPrefix + restrictDP(coord); - } - - - /** - * Restrict the given coordinate to a limited number of decimal places for display - * @param inCoord coordinate string - * @return chopped string - */ - private static String restrictDP(String inCoord) - { - final int DECIMAL_PLACES = 7; - if (inCoord == null) return ""; - String result = inCoord; - final int dotPos = Math.max(inCoord.lastIndexOf('.'), inCoord.lastIndexOf(',')); - if (dotPos >= 0) - { - final int chopPos = dotPos + DECIMAL_PLACES; - if (chopPos < (inCoord.length()-1)) - { - result = inCoord.substring(0, chopPos); - // Maybe there's an exponential in there too which needs to be appended - int expPos = inCoord.toUpperCase().indexOf("E", chopPos); - if (expPos > 0 && expPos < (inCoord.length()-1)) - { - result += inCoord.substring(expPos); - } - } - } - return result; - } - /** * Make a details subpanel * @param inNameKey key to use for top label @@ -657,4 +611,22 @@ public class DetailsDisplay extends GenericDisplay // string is too long return inString.substring(0, 20) + "..."; } + + /** + * @return the currently selected coordinate display format + */ + private int getSelectedCoordFormat() + { + switch (_coordFormatDropdown.getSelectedIndex()) + { + case 1: // degminsec + return Coordinate.FORMAT_DEG_MIN_SEC; + case 2: // degmin + return Coordinate.FORMAT_DEG_MIN; + case 3: // degrees + return Coordinate.FORMAT_DEG; + default: // just as it was + return Coordinate.FORMAT_NONE; + } + } } diff --git a/src/tim/prune/gui/MenuManager.java b/src/tim/prune/gui/MenuManager.java index bce3b4d..d289b78 100644 --- a/src/tim/prune/gui/MenuManager.java +++ b/src/tim/prune/gui/MenuManager.java @@ -30,10 +30,14 @@ import tim.prune.data.Selection; import tim.prune.data.Track; import tim.prune.data.TrackInfo; import tim.prune.function.ChooseSingleParameter; +import tim.prune.function.PasteCoordinateList; +import tim.prune.function.PasteCoordinates; +import tim.prune.function.PlusCodeFunction; 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.settings.SaveConfig; /** * Class to manage the menu bar and tool bar, @@ -74,6 +78,7 @@ public class MenuManager implements DataSubscriber private JMenuItem _selectEndItem = null; private JMenuItem _findWaypointItem = null; private JMenuItem _duplicatePointItem = null; + private JMenuItem _projectPointItem = null; private JMenuItem _reverseItem = null; private JMenuItem _addTimeOffsetItem = null; private JMenuItem _addAltitudeOffsetItem = null; @@ -90,8 +95,6 @@ public class MenuManager implements DataSubscriber private JMenu _browserMapMenu = null; private JMenuItem _routingGraphHopperItem = null; private JMenuItem _chartItem = null; - private JMenuItem _getGpsiesItem = null; - private JMenuItem _uploadGpsiesItem = null; private JMenuItem _lookupSrtmItem = null; private JMenuItem _downloadSrtmItem = null; private JMenuItem _nearbyWikipediaItem = null; @@ -103,7 +106,7 @@ public class MenuManager implements DataSubscriber private JMenuItem _downloadOsmItem = null; private JMenuItem _getWeatherItem = null; private JMenuItem _distanceItem = null; - private JMenuItem _fullRangeDetailsItem = null; + private JMenuItem _viewFullDetailsItem = null; private JMenuItem _estimateTimeItem = null; private JMenuItem _learnEstimationParams = null; private JMenuItem _autoplayTrack = null; @@ -259,12 +262,6 @@ public class MenuManager implements DataSubscriber onlineMenu.add(_lookupSrtmItem); _downloadSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_DOWNLOAD_SRTM, false); onlineMenu.add(_downloadSrtmItem); - // Get gpsies tracks - _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES, false); - onlineMenu.add(_getGpsiesItem); - // Upload to gpsies - _uploadGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_UPLOAD_GPSIES, false); - onlineMenu.add(_uploadGpsiesItem); onlineMenu.addSeparator(); // browser submenu @@ -491,9 +488,17 @@ public class MenuManager implements DataSubscriber // duplicate current point _duplicatePointItem = makeMenuItem(FunctionLibrary.FUNCTION_DUPLICATE_POINT, false); pointMenu.add(_duplicatePointItem); + // project current point + _projectPointItem = makeMenuItem(FunctionLibrary.FUNCTION_PROJECT_POINT, false); + pointMenu.add(_projectPointItem); // paste coordinates function - JMenuItem pasteCoordsItem = makeMenuItem(FunctionLibrary.FUNCTION_PASTE_COORDINATES); + JMenuItem pasteCoordsItem = makeMenuItem(new PasteCoordinates(_app)); pointMenu.add(pasteCoordsItem); + JMenuItem pasteCoordsListItem = makeMenuItem(new PasteCoordinateList(_app)); + pointMenu.add(pasteCoordsListItem); + // pluscodes function + JMenuItem plusCodeItem = makeMenuItem(new PlusCodeFunction(_app)); + pointMenu.add(plusCodeItem); menubar.add(pointMenu); // Add view menu @@ -530,8 +535,8 @@ public class MenuManager implements DataSubscriber _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES, false); viewMenu.add(_distanceItem); // full range details - _fullRangeDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_RANGE_DETAILS, false); - viewMenu.add(_fullRangeDetailsItem); + _viewFullDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_DETAILS, false); + viewMenu.add(_viewFullDetailsItem); // estimate time _estimateTimeItem = makeMenuItem(FunctionLibrary.FUNCTION_ESTIMATE_TIME, false); viewMenu.add(_estimateTimeItem); @@ -659,7 +664,10 @@ public class MenuManager implements DataSubscriber _autosaveSettingsCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS)); _autosaveSettingsCheckbox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Config.setConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS, _autosaveSettingsCheckbox.isSelected()); + final boolean autosaveOn = _autosaveSettingsCheckbox.isSelected(); + Config.setConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS, autosaveOn); + // Maybe want to save config? + new SaveConfig(_app).autosaveSwitched(autosaveOn); } }); settingsMenu.add(_autosaveSettingsCheckbox); @@ -868,7 +876,7 @@ public class MenuManager implements DataSubscriber _markRectangleItem.setEnabled(hasData); _markUphillLiftsItem.setEnabled(hasData && _track.hasAltitudeData()); _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints()); - _rearrangeWaypointsItem.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints()); + _rearrangeWaypointsItem.setEnabled(hasData && _track.hasWaypoints() && _track.getNumPoints() > 1); final boolean hasSeveralTrackPoints = hasData && _track.hasTrackPoints() && _track.getNumPoints() > 3; _splitSegmentsItem.setEnabled(hasSeveralTrackPoints); _sewSegmentsItem.setEnabled(hasSeveralTrackPoints); @@ -880,8 +888,6 @@ public class MenuManager implements DataSubscriber _browserMapMenu.setEnabled(hasData); _distanceItem.setEnabled(hasData); _autoplayTrack.setEnabled(hasData && _track.getNumPoints() > 3); - _getGpsiesItem.setEnabled(hasData); - _uploadGpsiesItem.setEnabled(hasData && _track.hasTrackPoints()); _lookupSrtmItem.setEnabled(hasData); _nearbyWikipediaItem.setEnabled(hasData); _nearbyOsmPoiItem.setEnabled(hasData); @@ -911,6 +917,7 @@ public class MenuManager implements DataSubscriber _selectEndItem.setEnabled(hasPoint); _selectEndButton.setEnabled(hasPoint); _duplicatePointItem.setEnabled(hasPoint); + _projectPointItem.setEnabled(hasPoint); _showPeakfinderItem.setEnabled(hasPoint); _showGeohackItem.setEnabled(hasPoint); _searchOpencachingDeItem.setEnabled(hasPoint); @@ -958,7 +965,7 @@ public class MenuManager implements DataSubscriber _addAltitudeOffsetItem.setEnabled(hasRange); _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints()); _deleteFieldValuesItem.setEnabled(hasRange); - _fullRangeDetailsItem.setEnabled(hasRange); + _viewFullDetailsItem.setEnabled(hasRange || hasPoint); _estimateTimeItem.setEnabled(hasRange); _learnEstimationParams.setEnabled(hasData && _track.hasTrackPoints() && _track.hasData(Field.TIMESTAMP) && _track.hasAltitudeData()); diff --git a/src/tim/prune/gui/StatusBar.java b/src/tim/prune/gui/StatusBar.java index a5462ed..1839d87 100644 --- a/src/tim/prune/gui/StatusBar.java +++ b/src/tim/prune/gui/StatusBar.java @@ -59,7 +59,8 @@ public class StatusBar extends JPanel implements Runnable, DataSubscriber _label.setText(" " + inMessage); _timer = System.currentTimeMillis() + DEFAULT_CLEAR_INTERVAL; // If necessary, start a new checker thread - if (_thread == null || !_thread.isAlive()) { + if (_thread == null || !_thread.isAlive()) + { _thread = new Thread(this); _thread.start(); } diff --git a/src/tim/prune/gui/Viewport.java b/src/tim/prune/gui/Viewport.java index 25eba2f..38620e4 100644 --- a/src/tim/prune/gui/Viewport.java +++ b/src/tim/prune/gui/Viewport.java @@ -7,7 +7,7 @@ import tim.prune.gui.map.MapUtils; /** * Class to provide access to current viewport * The point of this class is to decouple the view from the MapCanvas object - * so that when the GetGpsies function needs to know the area currently viewed, it doesn't + * so that when a search function needs to know the area currently viewed, it doesn't * need to have a direct connection to the MapCanvas. Instead it asks the App for the viewport, * which is then able to get the map position from the MapCanvas. * I'm still not sure whether this is ugly or not, but it's more efficient than constantly listening. diff --git a/src/tim/prune/gui/colour/ColourerFactory.java b/src/tim/prune/gui/colour/ColourerFactory.java index 767456e..8c8829f 100644 --- a/src/tim/prune/gui/colour/ColourerFactory.java +++ b/src/tim/prune/gui/colour/ColourerFactory.java @@ -130,7 +130,7 @@ public abstract class ColourerFactory * @param inColourer PointColourer object * @return string describing object (for later re-creation) or null */ - public static String PointColourerToString(PointColourer inColourer) + public static String pointColourerToString(PointColourer inColourer) { if (inColourer != null) { diff --git a/src/tim/prune/gui/colour/FileColourer.java b/src/tim/prune/gui/colour/FileColourer.java index 2a0e8cb..4f08918 100644 --- a/src/tim/prune/gui/colour/FileColourer.java +++ b/src/tim/prune/gui/colour/FileColourer.java @@ -26,13 +26,13 @@ public class FileColourer extends DiscretePointColourer /** * Calculate the colours for each of the points in the given track - * @param inTrack track object + * @param inTrackInfo track info object */ @Override public void calculateColours(TrackInfo inTrackInfo) { // initialise the array to the right size - final int numPoints = inTrackInfo == null ? 0 : inTrackInfo.getTrack().getNumPoints(); + final int numPoints = inTrackInfo.getTrack().getNumPoints(); init(numPoints); // loop over track points diff --git a/src/tim/prune/gui/map/DiskTileCacher.java b/src/tim/prune/gui/map/DiskTileCacher.java index fd2042a..875fcc3 100644 --- a/src/tim/prune/gui/map/DiskTileCacher.java +++ b/src/tim/prune/gui/map/DiskTileCacher.java @@ -25,10 +25,20 @@ public class DiskTileCacher implements Runnable private File _file = null; /** Observer to be notified */ private ImageObserver _observer = null; + /** True if cacher is active, false if blocked */ + private boolean _active = false; + /** Time limit to cache images for */ private static final long CACHE_TIME_LIMIT = 20 * 24 * 60 * 60 * 1000; // 20 days in ms /** Hashset of all blocked / 404 tiles to avoid requesting them again */ private static final HashSet BLOCKED_URLS = new HashSet(); + /**Hashset of files which are currently being processed */ + private static final HashSet DOWNLOADING_FILES = new HashSet(); + /** Number of currently active threads */ + private static int NUMBER_ACTIVE_THREADS = 0; + /** Flag to remember whether any server connection is possible */ + private static boolean CONNECTION_ACTIVE = true; + /** * Private constructor @@ -40,6 +50,7 @@ public class DiskTileCacher implements Runnable _url = inUrl; _file = inFile; _observer = inObserver; + _active = registerCacher(inFile.getAbsolutePath()); } /** @@ -81,63 +92,97 @@ public class DiskTileCacher implements Runnable if (inBasePath == null || inTilePath == null) {return;} // save file if possible File basePath = new File(inBasePath); - if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) { + if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) + { // Can't write to base path return; } File tileFile = new File(basePath, inTilePath); - // Check if this file is already being loaded - if (isBeingLoaded(tileFile)) {return;} + // Check if it has already failed - if (BLOCKED_URLS.contains(inUrl.toString())) {return;} + if (BLOCKED_URLS.contains(inUrl.toString())) { + return; + } File dir = tileFile.getParentFile(); - // Start a new thread to load the image if necessary + // Construct a cacher to load the image if necessary if ((dir.exists() || dir.mkdirs()) && dir.canWrite()) { - new Thread(new DiskTileCacher(inUrl, tileFile, inObserver)).start(); + DiskTileCacher cacher = new DiskTileCacher(inUrl, tileFile, inObserver); + cacher.startDownloading(); } } /** - * Check whether the given tile is already being loaded - * @param inFile desired file - * @return true if temporary file with this name exists + * Start downloading the configured tile */ - private static boolean isBeingLoaded(File inFile) + private void startDownloading() { - File tempFile = new File(inFile.getAbsolutePath() + ".temp"); - if (!tempFile.exists()) { - return false; + if (_active) + { + new Thread(this).start(); } - // File exists, so check if it was created recently - final long fileAge = System.currentTimeMillis() - tempFile.lastModified(); - return fileAge < 1000000L; // overwrite if the temp file is still there after 1000s } /** * Run method for loading URL asynchronously and saving to file */ public void run() + { + waitUntilAllowedToRun(); + if (doDownload()) + { + if (!CONNECTION_ACTIVE) + { + // wasn't active before but this download worked - we've come back online + BLOCKED_URLS.clear(); + CONNECTION_ACTIVE = true; + } + } + // Release file and thread + unregisterCacher(_file.getAbsolutePath()); + threadFinished(); + } + + /** + * Blocks (in separate thread) until allowed by concurrent thread limit + */ + private void waitUntilAllowedToRun() + { + while (!canStartNewThread()) + { + try { + Thread.sleep(400); + } + catch (InterruptedException e) {} + } + } + + /** + * @return true if download was successful + */ + private boolean doDownload() { boolean finished = false; InputStream in = null; FileOutputStream out = null; File tempFile = new File(_file.getAbsolutePath() + ".temp"); - // Use a synchronized block across all threads to make sure this url is only fetched once - synchronized (DiskTileCacher.class) + + if (tempFile.exists()) { - if (tempFile.exists()) {tempFile.delete();} - try { - if (!tempFile.createNewFile()) {return;} - } - catch (Exception e) {return;} + tempFile.delete(); } + try + { + if (!tempFile.createNewFile()) {return false;} + } + catch (Exception e) {return false;} + try { // Open streams from URL and to file out = new FileOutputStream(tempFile); - //System.out.println("Opening URL: " + _url.toString()); + //System.out.println("DiskTileCacher opening URL: " + _url.toString()); // Set http user agent on connection URLConnection conn = _url.openConnection(); conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER); @@ -148,27 +193,97 @@ public class DiskTileCacher implements Runnable out.write(d); } finished = true; - } catch (IOException e) { + } + catch (IOException e) + { System.err.println("ioe: " + e.getClass().getName() + " - " + e.getMessage()); BLOCKED_URLS.add(_url.toString()); + CONNECTION_ACTIVE = false; } finally { // clean up files try {in.close();} catch (Exception e) {} // ignore try {out.close();} catch (Exception e) {} // ignore - if (!finished) { + if (!finished) + { tempFile.delete(); } } + boolean success = false; // Move temp file to desired file location - if (tempFile.exists() && !tempFile.renameTo(_file)) + if (tempFile.exists() && tempFile.length() > 0L) { - // File couldn't be moved - delete both to be sure - tempFile.delete(); - _file.delete(); + if (tempFile.renameTo(_file)) + { + success = true; + } + else + { + // File couldn't be moved - delete both to be sure + System.out.println("Failed to rename temp file: " + tempFile.getAbsolutePath()); + tempFile.delete(); + _file.delete(); + } } + // Tell parent that load is finished (parameters ignored) _observer.imageUpdate(null, ImageObserver.ALLBITS, 0, 0, 0, 0); + return success; + } + + // Blocking of cachers working on same file + + /** + * Register a cacher writing to the specified file path + * @param inFilePath destination path to tile file + * @return true if nobody else has claimed this file yet + */ + private synchronized static boolean registerCacher(String inFilePath) + { + if (DOWNLOADING_FILES.contains(inFilePath)) + { + return false; + } + // Nobody has claimed this file yet + DOWNLOADING_FILES.add(inFilePath); + return true; + } + + /** + * Cacher has finished dealing with the specified file + * @param inFilePath destination path to tile file + */ + private synchronized static void unregisterCacher(String inFilePath) + { + DOWNLOADING_FILES.remove(inFilePath); + } + + // Limiting of active threads + + /** + * @return true if another thread is allowed to become active + */ + private synchronized static boolean canStartNewThread() + { + final int MAXIMUM_NUM_THREADS = 8; + if (NUMBER_ACTIVE_THREADS < MAXIMUM_NUM_THREADS) + { + NUMBER_ACTIVE_THREADS++; + return true; + } + // Already too many threads active + return false; + } + + /** + * Inform that one of the previously active threads has now completed + */ + private synchronized static void threadFinished() + { + if (NUMBER_ACTIVE_THREADS > 0) + { + NUMBER_ACTIVE_THREADS--; + } } } diff --git a/src/tim/prune/gui/map/MapCanvas.java b/src/tim/prune/gui/map/MapCanvas.java index aa25dbc..d305d1c 100644 --- a/src/tim/prune/gui/map/MapCanvas.java +++ b/src/tim/prune/gui/map/MapCanvas.java @@ -720,8 +720,8 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe final double pointSeparationSqd = (prevX-px) * (prevX-px) + (prevY-py) * (prevY-py); if (pointSeparationSqd > pointSeparationForArrowsSqd) { - final double midX = (prevX + px) / 2; - final double midY = (prevY + py) / 2; + final double midX = (prevX + px) / 2.0; + final double midY = (prevY + py) / 2.0; final boolean midPointVisible = midX >= 0 && midX < winWidth && midY >= 0 && midY < winHeight; if (midPointVisible) { diff --git a/src/tim/prune/gui/map/MapSourceLibrary.java b/src/tim/prune/gui/map/MapSourceLibrary.java index 331d8fe..08ab4bc 100644 --- a/src/tim/prune/gui/map/MapSourceLibrary.java +++ b/src/tim/prune/gui/map/MapSourceLibrary.java @@ -42,10 +42,10 @@ public abstract class MapSourceLibrary _sourceList.add(new OsmMapSource("Cycling Trails", "https://[abc].tile.openstreetmap.org/", "png", "https://tile.waymarkedtrails.org/cycling/", "png", 18)); _sourceList.add(new OsmMapSource("Reitkarte", "http://topo[234].wanderreitkarte.de/topo/")); - _sourceList.add(new MffMapSource("Mapsforfree", "http://maps-for-free.com/layer/relief/", "jpg", - "http://maps-for-free.com/layer/water/", "gif", 11)); - _sourceList.add(new OsmMapSource("Hikebikemap", "http://[abc].tiles.wmflabs.org/hikebike/", - "http://[abc].tiles.wmflabs.org/hillshading/", 18)); + _sourceList.add(new MffMapSource("Mapsforfree", "https://maps-for-free.com/layer/relief/", "jpg", + "https://maps-for-free.com/layer/water/", "gif", 11)); + _sourceList.add(new OsmMapSource("Hikebikemap", "https://tiles.wmflabs.org/hikebike/", + "https://tiles.wmflabs.org/hillshading/", 18)); _sourceList.add(new OsmMapSource("OpenSeaMap", "http://tile.openstreetmap.org/", "http://tiles.openseamap.org/seamark/", 18)); } diff --git a/src/tim/prune/gui/map/MapTileManager.java b/src/tim/prune/gui/map/MapTileManager.java index f7370c5..8c2c6ee 100644 --- a/src/tim/prune/gui/map/MapTileManager.java +++ b/src/tim/prune/gui/map/MapTileManager.java @@ -162,6 +162,7 @@ public class MapTileManager implements ImageObserver tempCache = _tempCaches[inLayer]; // Should probably guard array indexes here tileImage = tempCache.getTile(inX, inY); if (tileImage != null) { + //System.out.println("Got tile from memory: " + inX + ", " + inY); return tileImage; } } @@ -195,7 +196,6 @@ public class MapTileManager implements ImageObserver try { URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY)); - //System.out.println("Trying to fetch: " + tileUrl); if (useDisk) { DiskTileCacher.saveTile(tileUrl, diskCachePath, diff --git a/src/tim/prune/gui/map/TileDownloader.java b/src/tim/prune/gui/map/TileDownloader.java index 7c75400..7ec6d91 100644 --- a/src/tim/prune/gui/map/TileDownloader.java +++ b/src/tim/prune/gui/map/TileDownloader.java @@ -21,10 +21,13 @@ public class TileDownloader implements Runnable private int _layer = 0; private int _x = 0, _y = 0; private int _zoom = 0; + /** Hashset of all blocked / 404 tiles to avoid requesting them again */ private static final HashSet BLOCKED_URLS = new HashSet(); /** Hashset of all currently loading tiles to avoid requesting them again */ private static final HashSet LOADING_URLS = new HashSet(); + /** Flag to maintain whether connection is active or not */ + private static boolean CONNECTION_ACTIVE = true; /** @@ -67,6 +70,9 @@ public class TileDownloader implements Runnable LOADING_URLS.add(url); new Thread(new TileDownloader(inManager, inUrl, inLayer, inX, inY, inZoom)).start(); } + else { + System.out.println("Already blocked: " + url); + } } } @@ -98,6 +104,17 @@ public class TileDownloader implements Runnable // Pass back to manager so it can be stored in its memory cache _manager.notifyImageLoaded(tile, _layer, _x, _y, _zoom); + + if (!CONNECTION_ACTIVE) + { + // We've just come back online, so forget which tiles gave 404 before + System.out.println("Deleting blocked urls, currently holds " + BLOCKED_URLS.size()); + synchronized(this.getClass()) + { + BLOCKED_URLS.clear(); + } + CONNECTION_ACTIVE = true; + } } } catch (IOException e) @@ -108,6 +125,7 @@ public class TileDownloader implements Runnable BLOCKED_URLS.add(_url.toString()); } try {in.close();} catch (Exception e2) {} + CONNECTION_ACTIVE = false; // lost connection? } LOADING_URLS.remove(_url.toString()); } diff --git a/src/tim/prune/gui/profile/ProfileChart.java b/src/tim/prune/gui/profile/ProfileChart.java index 466fda2..5d18e1e 100644 --- a/src/tim/prune/gui/profile/ProfileChart.java +++ b/src/tim/prune/gui/profile/ProfileChart.java @@ -61,7 +61,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener if (!other.hasValue) {return;} if (!hasValue) { index = other.index; - hasValue = other.hasValue; + hasValue = true; } else { index = Math.min(index, other.index); @@ -73,7 +73,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener if (!other.hasValue) {return;} if (!hasValue) { index = other.index; - hasValue = other.hasValue; + hasValue = true; } else { index = Math.max(index, other.index); @@ -239,7 +239,8 @@ public class ProfileChart extends GenericDisplay implements MouseListener int selectedPoint = _trackInfo.getSelection().getCurrentPointIndex(); // selection start, end int selectionStart = -1, selectionEnd = -1; - if (_trackInfo.getSelection().hasRangeSelected()) { + if (_trackInfo.getSelection().hasRangeSelected()) + { selectionStart = _trackInfo.getSelection().getStart(); selectionEnd = _trackInfo.getSelection().getEnd(); } @@ -289,12 +290,14 @@ public class ProfileChart extends GenericDisplay implements MouseListener y = (int) (yScaleFactor * (value - minValue)); g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); } - else if (value >= 0.0) { + else if (value >= 0.0) + { // Bar upwards from the zero line y = height-BORDER_WIDTH - (int) (yScaleFactor * (value - minValue)); g.fillRect(BORDER_WIDTH+x, y, barWidth, zeroY - y); } - else { + else + { // Bar downwards from the zero line int barHeight = (int) (yScaleFactor * value); g.fillRect(BORDER_WIDTH+x, zeroY, barWidth, -barHeight); @@ -317,7 +320,8 @@ public class ProfileChart extends GenericDisplay implements MouseListener } } } - catch (NullPointerException npe) { // ignore, probably due to data being changed + catch (NullPointerException npe) + { // ignore, probably due to data being changed } // Draw numbers on top of the graph to mark scale if (lineScale >= 1) @@ -458,29 +462,32 @@ public class ProfileChart extends GenericDisplay implements MouseListener if ((inUpdateType & DATA_ADDED_OR_REMOVED) > 0) { makePopup(); } - if (inUpdateType == SELECTION_CHANGED) { - triggerPartialRepaint(); + + ChartParameters currentParameters = new ChartParameters(); + currentParameters.selectedPoint.set(_trackInfo.getSelection().getCurrentPointIndex()); + if (_trackInfo.getSelection().hasRangeSelected()) + { + currentParameters.rangeStart.set(_trackInfo.getSelection().getStart()); + currentParameters.rangeEnd.set(_trackInfo.getSelection().getEnd()); + } + if (inUpdateType == SELECTION_CHANGED) + { + triggerPartialRepaint(currentParameters); } else { repaint(); } + _previousParameters = currentParameters; } /** * For performance reasons, only repaint the part of the graphics affected by * the change in selection + * @param currentParameters - contains the current selected point, range */ - private void triggerPartialRepaint() + private void triggerPartialRepaint(ChartParameters currentParameters) { - ChartParameters currentParameters = new ChartParameters(); - currentParameters.selectedPoint.set(_trackInfo.getSelection().getCurrentPointIndex()); - if (_trackInfo.getSelection().hasRangeSelected()) - { - currentParameters.rangeStart.set(_trackInfo.getSelection().getStart()); - currentParameters.rangeEnd.set(_trackInfo.getSelection().getEnd()); - } - int minPointIndex = currentParameters.getMinChangedIndex(_previousParameters); minPointIndex = Math.max(minPointIndex, 0); int maxPointIndex = currentParameters.getMaxChangedIndex(_previousParameters); @@ -488,10 +495,10 @@ public class ProfileChart extends GenericDisplay implements MouseListener maxPointIndex = _trackInfo.getTrack().getNumPoints() - 1; } // System.out.println("Redraw from index: " + minPointIndex + " to " + maxPointIndex); - _previousParameters = currentParameters; - final int region_x = (int) (_xScaleFactor * minPointIndex) + BORDER_WIDTH; - final int region_width = (int) (_xScaleFactor * (maxPointIndex-minPointIndex+2)) + 2; + final int region_x = (int) (_xScaleFactor * minPointIndex) + BORDER_WIDTH - 2; + final int region_width = (int) (_xScaleFactor * (maxPointIndex-minPointIndex+2)) + 6; repaint(region_x, 0, region_width, getHeight()); + // System.out.println("Partial repaint, x=" + region_x + ", region_width=" + region_width); } /** @@ -520,7 +527,8 @@ public class ProfileChart extends GenericDisplay implements MouseListener } } } - else { + else + { // right clicks _popup.show(this, e.getX(), e.getY()); } @@ -538,12 +546,14 @@ public class ProfileChart extends GenericDisplay implements MouseListener _data = new AltitudeData(_track); } } - else if (inField == Field.SPEED) { + else if (inField == Field.SPEED) + { if (!(_data instanceof SpeedData)) { _data = new SpeedData(_track); } } - else if (inField == Field.VERTICAL_SPEED) { + else if (inField == Field.VERTICAL_SPEED) + { if (!(_data instanceof VerticalSpeedData)) { _data = new VerticalSpeedData(_track); } diff --git a/src/tim/prune/jpeg/drew/ExifTiffHandler.java b/src/tim/prune/jpeg/drew/ExifTiffHandler.java index a98e720..130a78a 100644 --- a/src/tim/prune/jpeg/drew/ExifTiffHandler.java +++ b/src/tim/prune/jpeg/drew/ExifTiffHandler.java @@ -21,9 +21,9 @@ public class ExifTiffHandler private long _thumbnailOffset = -1L, _thumbnailLength = -1L; /** This tag is a pointer to the Exif SubIFD. */ - final int DIR_EXIF_SUB_IFD_OFFSET = 0x8769; + private static final int DIR_EXIF_SUB_IFD_OFFSET = 0x8769; /** This tag is a pointer to the Exif GPS IFD. */ - final int DIR_GPS_INFO_OFFSET = 0x8825; + private static final int DIR_GPS_INFO_OFFSET = 0x8825; private static final int TAG_GPS_LATITUDE_REF = 0x0001; private static final int TAG_GPS_LATITUDE = 0x0002; @@ -142,6 +142,9 @@ public class ExifTiffHandler case TAG_THUMBNAIL_LENGTH: _thumbnailLength = intVal; break; + case TAG_GPS_BEARING: + _jpegData.setBearing(intVal); + break; } } diff --git a/src/tim/prune/lang/prune-texts_af.properties b/src/tim/prune/lang/prune-texts_af.properties index 54c713a..e12df2c 100644 --- a/src/tim/prune/lang/prune-texts_af.properties +++ b/src/tim/prune/lang/prune-texts_af.properties @@ -100,7 +100,7 @@ function.pastecoordinates=Verskaf nuwe koordinate function.charts=Grafieke function.show3d=Vertoon 3D function.distances=Afstande -function.fullrangedetails=Vol reeks besonderhede +function.viewfulldetails=Vol besonderhede function.estimatetime=Skat tyd function.learnestimationparams=Leer tyd skatings paramters function.setmapbg=Stel kaart agtergrond @@ -108,8 +108,6 @@ function.setpaths=Stel program paaie function.selectsegment=Selekteer huidige segment function.splitsegments=Verdeel baan in segmente function.sewsegments=Naai baan segmente aanmekaar -function.getgpsies=Kry Spsies spore -function.uploadgpsies=Laai baan op na Gpsies function.lookupsrtm=Kry hoogtes vanaf SRTM function.downloadsrtm=Laai SRTM te\u00ebls af function.getwikipedia=Kry nabye Wikipedia artikels @@ -360,18 +358,6 @@ dialog.gpsies.column.length=Lengte dialog.gpsies.description=Beskrywing dialog.gpsies.nodescription=Geen beskrywing dialog.gpsies.nonefound=Geen bane gevind -dialog.gpsies.username=Gpsies gebruikersnaam -dialog.gpsies.password=Spsies wagwoord -dialog.gpsies.keepprivate=Hou baan privaat -dialog.gpsies.confirmopenpage=Maak web blad oop vir opgelaaide baan -dialog.gpsies.activities=Aktiwiteits tipes -dialog.gpsies.activity.trekking=Stap -dialog.gpsies.activity.walking=Loop -dialog.gpsies.activity.jogging=Hardloop -dialog.gpsies.activity.biking=Fietsry -dialog.gpsies.activity.motorbiking=Moterfietsry -dialog.gpsies.activity.sailing=Seiljagwedvaart -dialog.gpsies.activity.skating=Skaats dialog.wikipedia.column.name=Artikel naam dialog.wikipedia.column.distance=Afstand dialog.wikipedia.nonefound=Geen wikipedia insetsels gevind @@ -472,25 +458,9 @@ dialog.keys.intro=Jy kan die volgende kortpadsleutels gebruik in plaas van om di dialog.keys.keylist=
Pylkie sleutelsSkuif kaart links regs, op, af
Ctrl + links, regs pylkieSelekteer vorige of volgende punt
Ctrl + op, af pylkieVergroot in of uit
Ctrl + PgUp, PgDownSelekteer vorige, volgende segment
Ctrl + Home, EindeSelekteer eerste, laaste punt
DelVerwyder huidige punt
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=Die volgende stelligns kan gestoor word na 'n konfigurasie le\u00ear -dialog.saveconfig.prune.trackdirectory=Baan gids -dialog.saveconfig.prune.photodirectory=foto gids -dialog.saveconfig.prune.languagecode=Taal kode (AF) -dialog.saveconfig.prune.languagefile=Taal le\u00ear -dialog.saveconfig.prune.gpsdevice=GPS apparaat -dialog.saveconfig.prune.gpsformat=GPS formaat -dialog.saveconfig.prune.povrayfont=Pocray font -dialog.saveconfig.prune.gnuplotpath=Pad na gnuplot -dialog.saveconfig.prune.gpsbabelpath=Pad na gpsbabel -dialog.saveconfig.prune.exiftoolpath=Pad na exitool -dialog.saveconfig.prune.mapsource=Geselekteerde kaart bron -dialog.saveconfig.prune.mapsourcelist=Kaarte bronne -dialog.saveconfig.prune.diskcache=Kaart stoorarea -dialog.saveconfig.prune.kmzimagewidth=KMZ beeld groote -dialog.saveconfig.prune.colourscheme=Kleur skema -dialog.saveconfig.prune.linewidth=Lyn dikte -dialog.saveconfig.prune.kmltrackcolour=KML baan kleur -dialog.saveconfig.prune.autosavesettings=Autostoor stellings +dialog.paths.prune.gnuplotpath=Pad na gnuplot +dialog.paths.prune.gpsbabelpath=Pad na gpsbabel +dialog.paths.prune.exiftoolpath=Pad na exitool dialog.setpaths.intro=As jy wil, kan jy die paie kies na die eksterne programme: dialog.setpaths.found=Pad gefind? dialog.addaltitude.noaltitudes=Die geselekteerde reeks bevat nie hoogtes nie @@ -593,7 +563,7 @@ confirm.rearrangephotos=Fotos ge-herrangskik confirm.splitsegments=%d segment verdelings is gemaak confirm.sewsegments=%d segment las is gemaak confirm.cutandmove=Seleksie geskuif -confirm.interpolate=Punte bygevoeg +confirm.pointsadded=%d punte bygevoeg confirm.convertnamestotimes=Baken name aangepas confirm.saveexif.ok=%d fotos gestoor confirm.undo.single=operasie ongedaan @@ -645,7 +615,6 @@ button.selectall=Selekteer almal button.selectnone=Selekter geen button.preview=Voorskou button.load=Laai -button.upload=Oplaai button.guessfields=Raai velde button.showwebpage=Wys webblad button.check=Kontroleer diff --git a/src/tim/prune/lang/prune-texts_cy.properties b/src/tim/prune/lang/prune-texts_cy.properties new file mode 100644 index 0000000..1c2d752 --- /dev/null +++ b/src/tim/prune/lang/prune-texts_cy.properties @@ -0,0 +1,96 @@ +# Text entries for the GpsPrune application +# Welsh entries + +# Menu entries +menu.file=Ffeil +menu.file.exit=Gadael +menu.online=Rhyngrwyd +menu.track=Wysg +menu.track.undo=Dadwneud +menu.point=Pwynt +menu.photo=Llun +menu.photo.saveexif=Cadw Exif +menu.audio=Awdio +menu.view=Golygu +menu.settings=Dewisiadau +menu.help=Cymorth + +# Alt keys for menus +altkey.menu.file=F +altkey.menu.online=R +altkey.menu.range=N +altkey.menu.track=T +altkey.menu.point=P +altkey.menu.view=G +altkey.menu.photo=L +altkey.menu.audio=A +altkey.menu.settings=D +altkey.menu.help=C + +# Functions +function.open=Agor ffeil +function.exportkml=Cadw KML +function.exportgpx=Cadw GPX +function.exportpov=Cadw POV +function.exportimage=Cadw llun +function.charts=Siartiau +function.distances=Pellterau +function.help=Cymorth +function.about=Ynghylych GpsPrune + +# Dialogs +dialog.exit.confirm.title=Gadael GpsPrune +dialog.delimiter.comma=Coma , +dialog.delimiter.semicolon=Hannercolon ; +dialog.gpsload.format=Fformat +dialog.gpsload.save=Cadw ffeil +dialog.save.table.save=Cadw +dialog.exportgpx.name=Enw +dialog.exportgpx.encoding.system=System +dialog.exportgpx.encoding.utf8=UTF-8 +dialog.exportpov.camerax=Camera X +dialog.exportpov.cameray=Camera Y +dialog.exportpov.cameraz=Camera Z +dialog.saveexif.title=Cadw Exif +dialog.saveexif.table.save=Cadw +dialog.estimatetime.results=Canlyniadau +dialog.wikipedia.column.distance=Pellter +dialog.osmpois.column.name=Enw +dialog.about.version=Fersiwn +dialog.about.translatedby=Testunau yn Cymraeg ... +dialog.about.credits.thanks=Diolch a +dialog.setcolours.text=Testun +dialog.colourchooser.red=Coch +dialog.colourchooser.green=Gwyrdd +dialog.colourchooser.blue=Glas +dialog.colourer.type.none=Dim +dialog.setlanguage.language=Iaith +dialog.diskcache.table.megabytes=Megabeitiau +dialog.displaysettings.size.small=Bach +dialog.displaysettings.size.large=Mawr +dialog.weather.day.today=Heddiw +dialog.weather.day.tomorrow=Yfory + +# Buttons +button.ok=Iawn +button.cancel=Diddymu +button.exit=Gadael +button.yes=Ie +button.no=Na + +# Display components +details.track.file=Ffeil +details.lists.audio=Awdio + +# Field names +fieldname.waypointname=Enw + +# How to combine conditions, such as filters +logic.and=a +logic.or=neu + +# External urls +url.googlemaps=maps.google.co.uk +wikipedia.lang=cy +openweathermap.lang=en + diff --git a/src/tim/prune/lang/prune-texts_cz.properties b/src/tim/prune/lang/prune-texts_cz.properties index 6957b1d..4d4b5c0 100644 --- a/src/tim/prune/lang/prune-texts_cz.properties +++ b/src/tim/prune/lang/prune-texts_cz.properties @@ -99,15 +99,12 @@ function.pastecoordinates=Zadat sou\u0159adnice function.charts=Grafy function.show3d=Trojrozm\u011brn\u011b function.distances=Vzd\u00e1lenosti -function.fullrangedetails=Detaily rozmez\u00ed function.estimatetime=Odhad \u010dasu function.learnestimationparams=Anal\u00fdza stopy pro odhad \u010dasu function.setmapbg=Nastavit pozad\u00ed function.setpaths=Nastavit cestu k program\u016fm function.splitsegments=Rozd\u011blit stopu na \u010d\u00e1sti function.sewsegments=Spojit \u010d\u00e1sti stopy -function.getgpsies=St\u00e1hnout stopy z Gpsies -function.uploadgpsies=Nahr\u00e1t stopu na Gpsies function.lookupsrtm=Na\u010d\u00edst nadm. v\u00fd\u0161ku ze SRTM function.downloadsrtm=St\u00e1hnout dla\u017edice ze SRTM function.getwikipedia=Hledat na Wikipedii podle vzd\u00e1lenosti @@ -359,19 +356,6 @@ dialog.gpsies.column.length=D\u00e9lka dialog.gpsies.description=Popis dialog.gpsies.nodescription=Bez popisu dialog.gpsies.nonefound=Nenalezeny \u017e\u00e1dn\u00e9 stopy -dialog.gpsies.username=U\u017eiv. jm\u00e9no k gpsies -dialog.gpsies.password=Heslo k gpsies -dialog.gpsies.keepprivate=Stopu nezve\u0159ej\u0148ovat -dialog.gpsies.confirmopenpage=Otev\u0159\u00edt nahranou stopu v internetov\u00e9m prohl\u00ed\u017ee\u010di? -dialog.gpsies.activities=Aktivita -dialog.gpsies.activity.trekking=Turistika -dialog.gpsies.activity.walking=Ch\u016fze -dialog.gpsies.activity.jogging=B\u011bh -dialog.gpsies.activity.biking=Kolo -dialog.gpsies.activity.motorbiking=Motorka -dialog.gpsies.activity.snowshoe=Sn\u011b\u017enice -dialog.gpsies.activity.sailing=Lo\u010f -dialog.gpsies.activity.skating=Bruslen\u00ed dialog.mapillary.nonefound=Nenalezeny \u017e\u00e1dn\u00e9 fotografie dialog.wikipedia.column.name=N\u00e1zev \u010dl\u00e1nku dialog.wikipedia.column.distance=Vzd\u00e1lenost @@ -476,25 +460,9 @@ dialog.keys.intro=M\u00edsto my\u0161i m\u016f\u017eete pou\u017e\u00edvat n\u00 dialog.keys.keylist=
\u0160ipkyPosunout mapu vlevo, vpravo, nahoru, dol\u016f
Ctrl + \u0161ipka vlevo, vpravoVybrat p\u0159edchoz\u00ed nebo n\u00e1sleduj\u00edc\u00ed bod
Ctrl + \u0161ipka nahoru, dol\u016fP\u0159ibl\u00ed\u017eit, odd\u00e1lit
Ctrl + PgUp, PgDownVybrat p\u0159edchoz\u00ed, n\u00e1sleduj\u00edc\u00ed \u010d\u00e1st stopy
Ctrl + Home, EndVybrat prvn\u00ed, posledn\u00ed bod
DelSmazat aktu\u00e1ln\u00ed bod
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=N\u00e1sleduj\u00edc\u00ed volby mohou b\u00fdt ulo\u017eeny do konfigura\u010dn\u00edho souboru : -dialog.saveconfig.prune.trackdirectory=Adres\u00e1\u0159 s stopami -dialog.saveconfig.prune.photodirectory=Ad\u0159es\u00e1\u0159 s fotografiemi -dialog.saveconfig.prune.languagecode=K\u00f3d jazyka -dialog.saveconfig.prune.languagefile=Soubor jazyka -dialog.saveconfig.prune.gpsdevice=Za\u0159\u00edzen\u00ed GPS -dialog.saveconfig.prune.gpsformat=Form\u00e1t GPS -dialog.saveconfig.prune.povrayfont=Font Povray -dialog.saveconfig.prune.gnuplotpath=Cesta k gnuplot -dialog.saveconfig.prune.gpsbabelpath=Cesta k gpsbabel -dialog.saveconfig.prune.exiftoolpath=Cesta k exiftool -dialog.saveconfig.prune.mapsource=Vybran\u00fd zdroj map -dialog.saveconfig.prune.mapsourcelist=Zdroje map -dialog.saveconfig.prune.diskcache=Cache s mapami -dialog.saveconfig.prune.kmzimagewidth=\u0160\u00ed\u0159ka bitmapy KMZ -dialog.saveconfig.prune.colourscheme=Barevn\u00e9 sch\u00e9ma -dialog.saveconfig.prune.linewidth=Tlou\u0161\u0165ka \u010d\u00e1ry -dialog.saveconfig.prune.kmltrackcolour=Barva stopy v KML -dialog.saveconfig.prune.autosavesettings=Mo\u017enosti ukl\u00e1d\u00e1n\u00ed +dialog.paths.prune.gnuplotpath=Cesta k gnuplot +dialog.paths.prune.gpsbabelpath=Cesta k gpsbabel +dialog.paths.prune.exiftoolpath=Cesta k exiftool dialog.setpaths.intro=Je-li to t\u0159eba, m\u016f\u017eete nastavit cesty k extern\u00edm aplikac\u00edm: dialog.setpaths.found=Cesta nalezena? dialog.addaltitude.noaltitudes=Vybran\u00e9 rozmez\u00ed neobsahuje nadmo\u0159skou v\u00fd\u0161ku @@ -585,7 +553,7 @@ confirm.rearrangephotos=Fotografie p\u0159euspo\u0159\u00e1d\u00e1ny confirm.splitsegments=\u00dasp\u011b\u0161n\u011b rozd\u011bleno v %d bodech confirm.sewsegments=\u00dasp\u011b\u0161n\u011b spojeno v %d bodech confirm.cutandmove=V\u00fdb\u011br p\u0159esunut -confirm.interpolate=Body p\u0159id\u00e1ny +confirm.pointsadded=%d body p\u0159id\u00e1ny confirm.convertnamestotimes=N\u00e1zvy bod\u016f p\u0159evedeny confirm.saveexif.ok=Ulo\u017eeno %d fotografi\u00ed confirm.undo.single=operace vr\u00e1cena @@ -641,7 +609,6 @@ button.selectall=Vybrat v\u0161e button.selectnone=Zru\u0161it v\u00fdb\u011br button.preview=N\u00e1hled button.load=Na\u010d\u00edst -button.upload=Upload button.guessfields=Odhadnout pole button.showwebpage=Zobrazit str\u00e1nku button.check=Zkontrolovat diff --git a/src/tim/prune/lang/prune-texts_da.properties b/src/tim/prune/lang/prune-texts_da.properties index e975e29..2b8e26c 100644 --- a/src/tim/prune/lang/prune-texts_da.properties +++ b/src/tim/prune/lang/prune-texts_da.properties @@ -77,7 +77,6 @@ function.pastecoordinates=Indf\u00f8j nye koordinater function.charts=Kort function.show3d=3-D view function.distances=Afstande -function.fullrangedetails=Vis alle detaljer +function.viewfulldetails=Vis alle detaljer function.setmapbg=V\u00e6lg kort som baggrund function.setpaths=V\u00e6lg sti til programmer -function.getgpsies=Se liste af GPS-spor diff --git a/src/tim/prune/lang/prune-texts_de.properties b/src/tim/prune/lang/prune-texts_de.properties index 1c35d25..d1f6976 100644 --- a/src/tim/prune/lang/prune-texts_de.properties +++ b/src/tim/prune/lang/prune-texts_de.properties @@ -96,11 +96,13 @@ function.addaltitudeoffset=H\u00f6henverschiebung aufrechnen function.convertnamestotimes=Namen der Wegpunkte in Zeitstempel umwandeln function.deletefieldvalues=Werte eines Feldes l\u00f6schen function.findwaypoint=Wegpunkt finden -function.pastecoordinates=Neuen Wegpunkt anlegen +function.pastecoordinates=Koordinaten eingeben +function.pastecoordinatelist=Koordinatenliste eingeben +function.enterpluscode=Pluscode eingeben function.charts=Diagramme function.show3d=3D Ansicht function.distances=Entfernungen -function.fullrangedetails=Zus\u00e4tzliche Bereichdetails +function.viewfulldetails=Zus\u00e4tzliche Details function.estimatetime=Zeit absch\u00e4tzen function.learnestimationparams=Zeitparameter erlernen function.autoplay=Track abspielen @@ -110,8 +112,6 @@ function.selectsegment=Aktuellen Abschnitt markieren function.splitsegments=In Trackabschnitte schneiden function.sewsegments=Trackabschnitte zusammenf\u00fcgen function.createmarkerwaypoints=Wegpunkte im bestimmten Abstand kreieren -function.getgpsies=Tracks bei GPSies.com herunterladen -function.uploadgpsies=Track zu GPSies.com hochladen function.lookupsrtm=H\u00f6hendaten von SRTM nachschlagen function.downloadsrtm=SRTM Dateien herunterladen function.getwikipedia=Wikipediaartikel in der N\u00e4he nachschlagen @@ -121,6 +121,7 @@ function.searchopencachingde=OpenCaching.de durchsuchen function.mapillary=Mapillary nach Fotos durchsuchen function.downloadosm=OSM-Daten f\u00fcr dieses Gebiet herunterladen function.duplicatepoint=Punkt verdoppeln +function.projectpoint=Punkt projizieren function.setcolours=Farben einstellen function.setdisplaysettings=Darstellungsoptionen function.setlanguage=Sprache einstellen @@ -367,19 +368,6 @@ dialog.gpsies.column.length=L\u00e4nge dialog.gpsies.description=Beschreibung dialog.gpsies.nodescription=Keine Beschreibung dialog.gpsies.nonefound=Keine Tracks gefunden -dialog.gpsies.username=Username bei GPSies.com -dialog.gpsies.password=Passwort bei GPSies.com -dialog.gpsies.keepprivate=Track privat halten -dialog.gpsies.confirmopenpage=Webseite f\u00fcr den hochgeladenen Track \u00f6ffnen? -dialog.gpsies.activities=Aktivit\u00e4ten -dialog.gpsies.activity.trekking=Wandern -dialog.gpsies.activity.walking=Walking -dialog.gpsies.activity.jogging=Laufen -dialog.gpsies.activity.biking=Fahrradfahren -dialog.gpsies.activity.motorbiking=Motorradfahren -dialog.gpsies.activity.snowshoe=Schneeschuhwandern -dialog.gpsies.activity.sailing=Segeln -dialog.gpsies.activity.skating=Inline-Skating dialog.mapillary.nonefound=Keine Fotos gefunden dialog.wikipedia.column.name=Artikelname dialog.wikipedia.column.distance=Entfernung @@ -447,6 +435,10 @@ dialog.deletemarked.nonefound=Es konnten keine Punkte entfernt werden dialog.pastecoordinates.desc=Koordinaten eingeben oder einf\u00fcgen dialog.pastecoordinates.coords=Koordinaten dialog.pastecoordinates.nothingfound=Bitte pr\u00fcfen Sie die Koordinaten und versuchen Sie es nochmals +dialog.pastecoordinatelist.desc=Liste von Koordinaten eingeben mit einem Punkt pro Zeile +dialog.pluscode.desc=Pluscode hier eingeben +dialog.pluscode.code=Pluscode +dialog.pluscode.nothingfound=Bitte pr\u00fcfen Sie den Code und versuchen Sie es nochmals dialog.help.help=Weitere Informationen und Benutzeranleitungen finden Sie unter\n https://gpsprune.activityworkshop.net/ dialog.about.version=Version dialog.about.build=Build @@ -486,25 +478,9 @@ dialog.keys.intro=Anstelle der Maus k\u00f6nnen Sie folgende Tastenkombinationen dialog.keys.keylist=
Pfeil TastenKarte verschieben
Strg + Links-, Rechts-PfeilVorherigen oder n\u00e4chsten Punkt markieren
Strg + Auf-, Abw\u00e4rts-PfeilEin- oder Auszoomen
Strg + Bild auf, abZum vorherigen oder n\u00e4chsten Abschnitt
Strg + Pos1, EndeErsten oder letzten Punkt markieren
EntfAktuellen Punkt entfernen
dialog.keys.normalmodifier=Strg dialog.keys.macmodifier=Kommando -dialog.saveconfig.desc=Die folgende Einstellungen k\u00f6nnen gespeichert werden: -dialog.saveconfig.prune.trackdirectory=Datenverzeichnis -dialog.saveconfig.prune.photodirectory=Fotoverzeichnis -dialog.saveconfig.prune.languagecode=Sprachcode (DE) -dialog.saveconfig.prune.languagefile=Sprachdatei -dialog.saveconfig.prune.gpsdevice=GPS-Ger\u00e4tename -dialog.saveconfig.prune.gpsformat=GPS-Format -dialog.saveconfig.prune.povrayfont=Povray-Font -dialog.saveconfig.prune.gnuplotpath=Gnuplot-Pfad -dialog.saveconfig.prune.gpsbabelpath=GPSBabel-Pfad -dialog.saveconfig.prune.exiftoolpath=ExifTool-Pfad -dialog.saveconfig.prune.mapsource=Kartenserver-Index -dialog.saveconfig.prune.mapsourcelist=Kartenserver -dialog.saveconfig.prune.diskcache=Kartenordner -dialog.saveconfig.prune.kmzimagewidth=Bildgr\u00f6\u00dfe in KMZ -dialog.saveconfig.prune.colourscheme=Farbschema -dialog.saveconfig.prune.linewidth=Liniedicke -dialog.saveconfig.prune.kmltrackcolour=KML-Trackfarbe -dialog.saveconfig.prune.autosavesettings=Einstellungen speichern +dialog.paths.prune.gnuplotpath=Gnuplot-Pfad +dialog.paths.prune.gpsbabelpath=GPSBabel-Pfad +dialog.paths.prune.exiftoolpath=ExifTool-Pfad dialog.setpaths.intro=Sie k\u00f6nnen hier die Pfade f\u00fcr externe Programme setzen: dialog.setpaths.found=Pfad gefunden? dialog.addaltitude.noaltitudes=Der markierte Bereich enth\u00e4lt keine H\u00f6henangaben @@ -571,6 +547,9 @@ dialog.displaysettings.wpicon.pin=Sto\u00dfnadel dialog.displaysettings.size.small=Klein dialog.displaysettings.size.medium=Mittel dialog.displaysettings.size.large=Gro\u00df +dialog.displaysettings.windowstyle=Fensterstil (Neustart n\u00f6tig) +dialog.displaysettings.windowstyle.default=Standart +dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Die OpenStreetMap-Daten f\u00fcr das folgende Gebiet werden heruntergeladen (.osm-Datei): dialog.searchwikipedianames.search=Suche nach: dialog.weather.location=Ort @@ -613,6 +592,12 @@ dialog.autoplay.usetimestamps=Zeitstempeln verwenden dialog.autoplay.rewind=Zum Anfang dialog.autoplay.pause=Pause dialog.autoplay.play=Abspielen +dialog.markers.halves=Punkte auf halben Weg +dialog.markers.half.distance=Halbe Distanz +dialog.markers.half.climb=Halber Aufstieg +dialog.markers.half.descent=Halber Abstieg +dialog.projectpoint.desc=Geben Sie die Azimut und Distanz f\u00fcr die Projizierung +dialog.projectpoint.bearing=Azimut (Grad von N) # 3d window dialog.3d.title=GpsPrune-3D-Ansicht @@ -634,7 +619,7 @@ confirm.rearrangephotos=Fotos neu angeordnet confirm.splitsegments=Es wurden %d Schnitte gemacht confirm.sewsegments=Es wurden %d Verbindungen gemacht confirm.cutandmove=Bereich verschoben -confirm.interpolate=Punkte eingef\u00fcgt +confirm.pointsadded=%d Punkte eingef\u00fcgt confirm.convertnamestotimes=Wegpunktnamen umgewandelt confirm.saveexif.ok=Es wurden %d Fotodateien geschrieben confirm.undo.single=Operation r\u00fcckg\u00e4ngig gemacht @@ -690,7 +675,6 @@ button.selectall=Alle ausw\u00e4hlen button.selectnone=Nichts ausw\u00e4hlen button.preview=Vorschau button.load=Laden -button.upload=Hochladen button.guessfields=Felder erraten button.showwebpage=Webseite anzeigen button.check=Pr\u00fcfen @@ -764,6 +748,7 @@ map.overzoom=Keine Karten f\u00fcr diesen Zoomfaktor verf\u00fcgbar # Field names fieldname.latitude=Breitengrad fieldname.longitude=L\u00e4ngengrad +fieldname.coordinates=Koordinaten fieldname.altitude=H\u00f6he fieldname.timestamp=Zeitstempel fieldname.time=Zeit @@ -778,6 +763,7 @@ fieldname.duration=Zeitdauer fieldname.speed=Geschwindigkeit fieldname.verticalspeed=Vertikale Geschwindigkeit fieldname.description=Beschreibung +fieldname.comment=Anmerkung fieldname.mediafilename=Foto- / Audioname # Measurement units @@ -871,6 +857,7 @@ error.load.nopoints=Keine g\u00fcltigen Daten in Datei gefunden error.load.unknownxml=Unbekanntes XML-Format: error.load.noxmlinzip=Keine XML-Datei in Zip-Datei gefunden error.load.othererror=Fehler beim Lesen der Datei: +error.load.nopointsintext=Keine g\u00fcltigen Daten gefunden error.jpegload.dialogtitle=Fehler beim Laden von Fotos error.jpegload.nofilesfound=Keine Dateien gefunden error.jpegload.nojpegsfound=Keine JPG-Dateien gefunden diff --git a/src/tim/prune/lang/prune-texts_de_CH.properties b/src/tim/prune/lang/prune-texts_de_CH.properties index acd393a..e2172ee 100644 --- a/src/tim/prune/lang/prune-texts_de_CH.properties +++ b/src/tim/prune/lang/prune-texts_de_CH.properties @@ -95,11 +95,13 @@ function.addaltitudeoffset=H\u00f6chiverschiebig zutue function.findwaypoint=Waypoint suech\u00e4 function.convertnamestotimes=Waypointname ins Ziitst\u00e4mple verwondle function.deletefieldvalues=Werte von nem F\u00e4ld l\u00f6sche -function.pastecoordinates=Noii Koordinaten iigebe +function.pastecoordinates=Noii Koordinate iigeh +function.pastecoordinatelist=Liste vo Koordinatene iigeh +function.enterpluscode=Pluscode iigeh function.charts=Diagramme function.show3d=Dr\u00fc\u00fc-D Aasicht function.distances=Entf\u00e4rnige -function.fullrangedetails=Zues\u00e4tzlichi Beriichinfos +function.viewfulldetails=No meh Infos function.estimatetime=Ziit absch\u00e4tze function.learnestimationparams=Ziitparameter erlerne function.autoplay=Track abschpiel\u00e4 @@ -108,8 +110,6 @@ function.selectsegment=Aktuelli Segm\u00e4nt selektiere function.splitsegments=In Tracksegm\u00e4nte schniide function.sewsegments=Tracksegm\u00e4nte z\u00e4mef\u00fcge function.createmarkerwaypoints=Waypoints inem bestimmten Abstand kreiere -function.getgpsies=Gpsies Tracks hol\u00e4 -function.uploadgpsies=Date zum Gpsies uufalad\u00e4 function.lookupsrtm=H\u00f6hendate vonem SRTM hole function.downloadsrtm=SRTM Files abalade function.getwikipedia=Im Wikipedia in dr N\u00f6chi naaluege @@ -119,6 +119,7 @@ function.searchopencachingde=OpenCaching.de durasueche function.mapillary=Mapillary na F\u00f6telis durasueche function.downloadosm=OSM-Date f\u00fcr dere Gebiet abalad\u00e4 function.duplicatepoint=Punkt verdoppl\u00e4 +function.projectpoint=Punkt projizier\u00e4 function.correlatephotos=F\u00f6telis korrelier\u00e4 function.rearrangephotos=F\u00f6telis reorganisier\u00e4 function.rotatephotoleft=F\u00f6teli nach Links dr\u00e4y\u00e4 @@ -363,19 +364,6 @@ dialog.gpsies.column.length=L\u00e4nge dialog.gpsies.description=Beschriebig dialog.gpsies.nodescription=Kei Beschriebig dialog.gpsies.nonefound=Kei Tracks gfunde -dialog.gpsies.username=Gpsies Username -dialog.gpsies.password=Gpsies Passwort -dialog.gpsies.keepprivate=Track privat halte -dialog.gpsies.confirmopenpage=Websiite f\u00fcrn uufagladenen Track \u00f6ffne? -dialog.gpsies.activities=Aktivit\u00e4ten -dialog.gpsies.activity.trekking=Wandere -dialog.gpsies.activity.walking=Z'Fuess gah -dialog.gpsies.activity.jogging=Seggle -dialog.gpsies.activity.biking=Velotour -dialog.gpsies.activity.motorbiking=Motorrad -dialog.gpsies.activity.snowshoe=Schneeschuh -dialog.gpsies.activity.sailing=Segle -dialog.gpsies.activity.skating=Inline-Skate dialog.mapillary.nonefound=Kei F\u00f6telis gfunde dialog.wikipedia.column.name=Artikelname dialog.wikipedia.column.distance=Entf\u00e4rnig @@ -443,6 +431,10 @@ dialog.deletemarked.nonefound=Kei P\u00fcnkte h\u00e4tte gel\u00f6scht werde k\u dialog.pastecoordinates.desc=G\u00e4bet Sie hier die Koordinaten inn\u00e4 dialog.pastecoordinates.coords=Koordinate dialog.pastecoordinates.nothingfound=Pr\u00fcefet Sie die Koordinate und versuechet nomal +dialog.pastecoordinatelist.desc=G\u00e4bet Sie hier die Koordinaten inn\u00e4, j\u00e4de Ziile git n Punkt +dialog.pluscode.desc=G\u00e4bet Sie hier den Code ii +dialog.pluscode.code=Pluscode +dialog.pluscode.nothingfound=Tut mer leid, n\u00fc\u00fct gfunde dialog.help.help=Lueget Sie na\n https://gpsprune.activityworkshop.net/\nf\u00fcr wiitere Information und Benutzeraaleitige. dialog.about.version=Version dialog.about.build=Build @@ -482,25 +474,9 @@ dialog.keys.intro=Aastatt d'Muus k\u00f6nnet Sie diese Tastekombinationen nutze dialog.keys.keylist=
Pfiil TasteKarte verschiebe
Strg + links, r\u00e4chts PfiilVorherigi oder n\u00f6chsti Punkt markiere
Strg + uuf, aba PfiilIi- oder Uusezoome
Strg + Bild uuf, abVorherigi oder n\u00f6chsti Segm\u00e4nt markiere
Strg + Pos1, \u00c4ndeErschti oder letschti Punkt markiere
EntfAktuelli Punkt l\u00f6sche
dialog.keys.normalmodifier=Strg dialog.keys.macmodifier=Kommando -dialog.saveconfig.desc=Die folgendi Iistellige k\u00f6nne gspeicheret werde : -dialog.saveconfig.prune.trackdirectory=Trackverzeichnis -dialog.saveconfig.prune.photodirectory=F\u00f6teliverzeichnis -dialog.saveconfig.prune.languagecode=Sprochecode (DE_ch) -dialog.saveconfig.prune.languagefile=Sprochedatei -dialog.saveconfig.prune.gpsdevice=GPS Ger\u00e4tename -dialog.saveconfig.prune.gpsformat=GPS Format -dialog.saveconfig.prune.povrayfont=Povray Font -dialog.saveconfig.prune.gnuplotpath=Gnuplot Pfad -dialog.saveconfig.prune.gpsbabelpath=Gpsbabel Pfad -dialog.saveconfig.prune.exiftoolpath=Exiftool Pfad -dialog.saveconfig.prune.mapsource=Kartenserver Index -dialog.saveconfig.prune.mapsourcelist=Kartenservers -dialog.saveconfig.prune.diskcache=Kartenordner -dialog.saveconfig.prune.kmzimagewidth=Bildr\u00f6sse im KMZ -dialog.saveconfig.prune.colourscheme=Farbeschema -dialog.saveconfig.prune.linewidth=Liniedicke -dialog.saveconfig.prune.kmltrackcolour=KML Trackfarb -dialog.saveconfig.prune.autosavesettings=Iistellige speichere +dialog.paths.prune.gnuplotpath=Gnuplot Pfad +dialog.paths.prune.gpsbabelpath=Gpsbabel Pfad +dialog.paths.prune.exiftoolpath=Exiftool Pfad dialog.setpaths.intro=Sie k\u00f6nnet dann die Pfade f\u00fcr dia Applikatione setz\u00e4: dialog.setpaths.found=Pfad gfunde? dialog.addaltitude.noaltitudes=Dr sel\u00e4ktierte Beriich h\u00e4t keini H\u00f6chiinformation @@ -566,6 +542,9 @@ dialog.displaysettings.wpicon.pin=Stossnadeli dialog.displaysettings.size.small=Chli dialog.displaysettings.size.medium=Mittel dialog.displaysettings.size.large=Gross +dialog.displaysettings.windowstyle=F\u00e4nsterstil (Neustart n\u00f6tig) +dialog.displaysettings.windowstyle.default=Standart +dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Best\u00e4tige um rohi OSM Date f\u00fcrn Gebiet aba zlade: dialog.searchwikipedianames.search=Sueche na: dialog.weather.location=Ort @@ -608,6 +587,12 @@ dialog.autoplay.usetimestamps=Ziitst\u00e4mple verw\u00e4nde dialog.autoplay.rewind=Zum Aafang dialog.autoplay.pause=Pause dialog.autoplay.play=Abschpiele +dialog.markers.halves=P\u00fcnkt ufem halben Weg +dialog.markers.half.distance=Halbe Distanz +dialog.markers.half.climb=Halber Uufstieg +dialog.markers.half.descent=Halber Abstieg +dialog.projectpoint.desc=Richtig und Distanz iigeh, mit dene s zu projizieren isch +dialog.projectpoint.bearing=Azimut (Grad vo N) # 3d window dialog.3d.title=GpsPrune Dr\u00fc\u00fc-d Aasicht @@ -629,7 +614,7 @@ confirm.rearrangephotos=Fotos umorganisiert confirm.splitsegments=Es sin %d Schnitte gmacht worde confirm.sewsegments=Es sin %d Verbindige gemacht worde confirm.cutandmove=Beriich gmoved -confirm.interpolate=P\u00fcnkte iigf\u00fcgt worde +confirm.pointsadded=%d P\u00fcnkte iigf\u00fcgt worde confirm.convertnamestotimes=Waypointname verwondlet confirm.saveexif.ok=Es sin %d F\u00f6telis gschriebe worde confirm.undo.single=Operation r\u00fcckg\u00e4ngig gmacht worde. @@ -686,7 +671,6 @@ button.selectall=Alli uusw\u00e4hle button.selectnone=N\u00fc\u00fct uusw\u00e4hle button.preview=Vorschau\u00e4 button.load=Lad\u00e4 -button.upload=Uufalad\u00e4 button.guessfields=F\u00e4lde errat\u00e4 button.showwebpage=Websiite aazeig\u00e4 button.check=Pr\u00fcefa @@ -759,6 +743,7 @@ map.overzoom=Kei Karte mit diesem Zoom # Field names fieldname.latitude=Breitegrad fieldname.longitude=L\u00e4ngegrad +fieldname.coordinates=Koordinate fieldname.altitude=H\u00f6chi fieldname.timestamp=Ziitst\u00e4mpel fieldname.time=Ziit @@ -773,6 +758,7 @@ fieldname.duration=Ziitl\u00e4ngi fieldname.speed=Gschwindikeit fieldname.verticalspeed=Uf/Ab Gschwindikeit fieldname.description=Bschriibig +fieldname.comment=Aamerkig fieldname.mediafilename=F\u00f6teli- / Audioname # Measurement units @@ -866,6 +852,7 @@ error.load.nopoints=Kei g\u00fcltigi Information inem File gfunde error.load.unknownxml=Unbekanntes xml Format: error.load.noxmlinzip=Kei xml im Zip File gfunde error.load.othererror=F\u00e4hle bim L\u00e4se: +error.load.nopointsintext=Kei g\u00fcltigi Koordinate gfunde error.jpegload.dialogtitle=F\u00e4hle bim Lade von F\u00f6telis error.jpegload.nofilesfound=Kei Files gfunde error.jpegload.nojpegsfound=Kei Jpegs gfunde diff --git a/src/tim/prune/lang/prune-texts_en.properties b/src/tim/prune/lang/prune-texts_en.properties index 7693926..dbc4be4 100644 --- a/src/tim/prune/lang/prune-texts_en.properties +++ b/src/tim/prune/lang/prune-texts_en.properties @@ -98,11 +98,13 @@ function.findwaypoint=Find waypoint function.rearrangewaypoints=Rearrange waypoints function.convertnamestotimes=Convert waypoint names to times function.deletefieldvalues=Delete field values -function.pastecoordinates=Enter new coordinates +function.pastecoordinates=Enter point coordinates +function.pastecoordinatelist=Enter list of coordinates +function.enterpluscode=Enter pluscode function.charts=Charts function.show3d=Three-D view function.distances=Distances -function.fullrangedetails=Full range details +function.viewfulldetails=Full details function.estimatetime=Estimate time function.learnestimationparams=Learn time estimation parameters function.autoplay=Autoplay track @@ -110,8 +112,6 @@ function.selectsegment=Select current segment function.splitsegments=Split track into segments function.sewsegments=Sew track segments together function.createmarkerwaypoints=Create marker waypoints -function.getgpsies=Get Gpsies tracks -function.uploadgpsies=Upload track to Gpsies function.lookupsrtm=Get altitudes from SRTM function.downloadsrtm=Download SRTM tiles function.getwikipedia=Get nearby Wikipedia articles @@ -121,6 +121,7 @@ function.searchopencachingde=Search OpenCaching.de function.mapillary=Search for photos in Mapillary function.downloadosm=Download OSM data for area function.duplicatepoint=Duplicate point +function.projectpoint=Project point function.connecttopoint=Connect to point function.disconnectfrompoint=Disconnect from point function.removephoto=Remove photo @@ -370,19 +371,6 @@ dialog.gpsies.column.length=Length dialog.gpsies.description=Description dialog.gpsies.nodescription=No description dialog.gpsies.nonefound=No tracks found -dialog.gpsies.username=Gpsies username -dialog.gpsies.password=Gpsies password -dialog.gpsies.keepprivate=Keep track private -dialog.gpsies.confirmopenpage=Open the web page for the uploaded track? -dialog.gpsies.activities=Activity types -dialog.gpsies.activity.trekking=Hiking -dialog.gpsies.activity.walking=Walking -dialog.gpsies.activity.jogging=Running -dialog.gpsies.activity.biking=Cycling -dialog.gpsies.activity.motorbiking=Motorbiking -dialog.gpsies.activity.snowshoe=Snowshoeing -dialog.gpsies.activity.sailing=Sailing -dialog.gpsies.activity.skating=Skating dialog.mapillary.nonefound=No photos found dialog.wikipedia.column.name=Article name dialog.wikipedia.column.distance=Distance @@ -450,6 +438,10 @@ dialog.deletemarked.nonefound=No data points could be removed dialog.pastecoordinates.desc=Enter or paste the coordinates here dialog.pastecoordinates.coords=Coordinates dialog.pastecoordinates.nothingfound=Please check the coordinates and try again +dialog.pastecoordinatelist.desc=Enter the coordinates for the new points with one point per line +dialog.pluscode.desc=Enter or paste the pluscode here +dialog.pluscode.code=Pluscode +dialog.pluscode.nothingfound=Please check the code and try again dialog.help.help=Please see\n https://gpsprune.activityworkshop.net/\nfor more information and tips,\nincluding a PDF user guide you can buy. dialog.about.version=Version dialog.about.build=Build @@ -489,25 +481,9 @@ dialog.keys.intro=You can use the following shortcut keys instead of using the m dialog.keys.keylist=
Arrow keysPan map left right, up, down
Ctrl + left, right arrowSelect previous or next point
Ctrl + up, down arrowZoom in or out
Ctrl + PgUp, PgDownSelect previous, next segment
Ctrl + Home, EndSelect first, last point
DelDelete current point
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=The following settings can be saved to a configuration file : -dialog.saveconfig.prune.trackdirectory=Track directory -dialog.saveconfig.prune.photodirectory=Photo directory -dialog.saveconfig.prune.languagecode=Language code (EN) -dialog.saveconfig.prune.languagefile=Language file -dialog.saveconfig.prune.gpsdevice=GPS device -dialog.saveconfig.prune.gpsformat=GPS format -dialog.saveconfig.prune.povrayfont=Povray font -dialog.saveconfig.prune.gnuplotpath=Path to gnuplot -dialog.saveconfig.prune.gpsbabelpath=Path to gpsbabel -dialog.saveconfig.prune.exiftoolpath=Path to exiftool -dialog.saveconfig.prune.mapsource=Selected map source -dialog.saveconfig.prune.mapsourcelist=Map sources -dialog.saveconfig.prune.diskcache=Map cache -dialog.saveconfig.prune.kmzimagewidth=KMZ image size -dialog.saveconfig.prune.colourscheme=Colour scheme -dialog.saveconfig.prune.linewidth=Line width -dialog.saveconfig.prune.kmltrackcolour=KML track colour -dialog.saveconfig.prune.autosavesettings=Autosave settings +dialog.paths.prune.gnuplotpath=Path to gnuplot +dialog.paths.prune.gpsbabelpath=Path to gpsbabel +dialog.paths.prune.exiftoolpath=Path to exiftool dialog.setpaths.intro=If you need to, you can choose the paths to the external applications: dialog.setpaths.found=Path found? dialog.addaltitude.noaltitudes=The selected range does not contain altitudes @@ -574,6 +550,9 @@ dialog.displaysettings.wpicon.pin=Board pin dialog.displaysettings.size.small=Small dialog.displaysettings.size.medium=Medium dialog.displaysettings.size.large=Large +dialog.displaysettings.windowstyle=Window style (requires restart) +dialog.displaysettings.windowstyle.default=Default +dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Confirm to download the raw OSM data for the specified area: dialog.searchwikipedianames.search=Search for: dialog.weather.location=Location @@ -616,6 +595,12 @@ dialog.autoplay.usetimestamps=Use point timestamps dialog.autoplay.rewind=Back to beginning dialog.autoplay.pause=Pause dialog.autoplay.play=Play +dialog.markers.halves=Halfway points +dialog.markers.half.distance=Half distance +dialog.markers.half.climb=Half climb +dialog.markers.half.descent=Half descent +dialog.projectpoint.desc=Enter the direction and distance to project this point +dialog.projectpoint.bearing=Bearing (degrees from N) # 3d window dialog.3d.title=GpsPrune Three-d view @@ -637,7 +622,7 @@ confirm.rearrangephotos=Photos rearranged confirm.splitsegments=%d segment splits were made confirm.sewsegments=%d segment joins were made confirm.cutandmove=Selection moved -confirm.interpolate=Points added +confirm.pointsadded=%d points added confirm.convertnamestotimes=Waypoint names converted confirm.saveexif.ok=Saved %d photo files confirm.undo.single=operation undone @@ -693,7 +678,6 @@ button.selectall=Select all button.selectnone=Select none button.preview=Preview button.load=Load -button.upload=Upload button.guessfields=Guess fields button.showwebpage=Show webpage button.check=Check @@ -767,6 +751,7 @@ map.overzoom=No maps available at this zoom level # Field names fieldname.latitude=Latitude fieldname.longitude=Longitude +fieldname.coordinates=Coordinates fieldname.altitude=Altitude fieldname.timestamp=Time fieldname.time=Time @@ -781,6 +766,7 @@ fieldname.duration=Duration fieldname.speed=Speed fieldname.verticalspeed=Vertical speed fieldname.description=Description +fieldname.comment=Comment fieldname.mediafilename=Filename # Measurement units @@ -880,6 +866,7 @@ error.load.nopoints=No coordinate information found in the file error.load.unknownxml=Unrecognised xml format: error.load.noxmlinzip=No xml file found inside zip file error.load.othererror=Error reading file: +error.load.nopointsintext=No coordinate information found error.jpegload.dialogtitle=Error loading photos error.jpegload.nofilesfound=No files found error.jpegload.nojpegsfound=No jpeg files found diff --git a/src/tim/prune/lang/prune-texts_en_US.properties b/src/tim/prune/lang/prune-texts_en_US.properties index d6724ab..e70c8d3 100644 --- a/src/tim/prune/lang/prune-texts_en_US.properties +++ b/src/tim/prune/lang/prune-texts_en_US.properties @@ -6,9 +6,6 @@ function.setcolours=Set colors # Dialogs dialog.exportkml.trackcolour=Track color -dialog.saveconfig.prune.languagecode=Language code (EN_US) -dialog.saveconfig.prune.colourscheme=Color scheme -dialog.saveconfig.prune.kmltrackcolour=KML track color dialog.setcolours.intro=Click on a color patch to change the color dialog.colourchooser.title=Choose color dialog.colourer.intro=A point colorer can give track points different colors diff --git a/src/tim/prune/lang/prune-texts_es.properties b/src/tim/prune/lang/prune-texts_es.properties index 07cfeca..e4676f6 100644 --- a/src/tim/prune/lang/prune-texts_es.properties +++ b/src/tim/prune/lang/prune-texts_es.properties @@ -102,7 +102,7 @@ function.pastecoordinates=Insertar nuevas coordenadas function.charts=Diagramas function.show3d=Mostrar en 3-D function.distances=Distancias -function.fullrangedetails=Detalles adicionales de rango +function.viewfulldetails=Detalles adicionales function.estimatetime=Estimar duraci\u00f3n function.learnestimationparams=Apprender parametros por la estimaci\u00f3n del tiempo function.autoplay=Jugar track @@ -111,8 +111,6 @@ function.setpaths=Configurar rutas del programas function.selectsegment=Seleccionar segmento actual function.splitsegments=Segmentar el track function.sewsegments=Ensamblar los segmentos -function.getgpsies=Bajar ruta de Gpsies -function.uploadgpsies=Subir recorrido a Gpsies function.lookupsrtm=Obtener altitudes de SRTM function.downloadsrtm=Descargar datos de SRTM function.getwikipedia=Obtener art\u00edculos de Wikipedia cercanos @@ -367,19 +365,6 @@ dialog.gpsies.column.length=Distancia dialog.gpsies.description=Descripci\u00f3n dialog.gpsies.nodescription=Sin descripci\u00f3n dialog.gpsies.nonefound=No se encontraron pistas -dialog.gpsies.username=Nombre de usuario en Gpsies -dialog.gpsies.password=Contrase\u00f1a de Gpsies -dialog.gpsies.keepprivate=Mantener el recorrido como privado -dialog.gpsies.confirmopenpage=Abrir la p\u00e1gina web del recorrido subido -dialog.gpsies.activities=Apto para -dialog.gpsies.activity.trekking=Excursi\u00f3n -dialog.gpsies.activity.walking=Caminar -dialog.gpsies.activity.jogging=Correr -dialog.gpsies.activity.biking=En bicicleta -dialog.gpsies.activity.motorbiking=En moto -dialog.gpsies.activity.snowshoe=Raquetas de nieve -dialog.gpsies.activity.sailing=Vela -dialog.gpsies.activity.skating=Patinaje dialog.mapillary.nonefound=No se encontraron fotos dialog.wikipedia.column.name=Nombre del art\u00edculo dialog.wikipedia.column.distance=Distancia @@ -486,25 +471,9 @@ dialog.keys.intro=Usted puede usar el siguiente atajo en lugar de usar el rat\u0 dialog.keys.keylist=
Teclas de cursorDesplazar a la izquierde, derecha, arriba, abajo
Ctrl + cursor izquierda, derechaSeleccionar punto siguiente o anterior
Ctrl + cursor arriba, abajoAmpliar o reducir zoom
Ctrl + Av Pag, Re PagSeleccionar segmento siguiente, anterior
Ctrl + Inicio, FinSeleccionar primer, \u00faltimo punto
SuprEliminar punto actual
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=La siguiente configuraci\u00f3n puede ser salvada en un archivo de configuraci\u00f3n -dialog.saveconfig.prune.trackdirectory=Directorio de pista -dialog.saveconfig.prune.photodirectory=Directorio de foto -dialog.saveconfig.prune.languagecode=C\u00f3digo de lenguaje (ES) -dialog.saveconfig.prune.languagefile=Archivo de lenguaje -dialog.saveconfig.prune.gpsdevice=Dispositivo GPS -dialog.saveconfig.prune.gpsformat=Formato GPS -dialog.saveconfig.prune.povrayfont=Fuente povray -dialog.saveconfig.prune.gnuplotpath=Ruta a gnuplot -dialog.saveconfig.prune.gpsbabelpath=Ruta a gpsbabel -dialog.saveconfig.prune.exiftoolpath=Ruta a exiftool -dialog.saveconfig.prune.mapsource=Proveedor de mapas seleccionado -dialog.saveconfig.prune.mapsourcelist=Proveedor de mapas -dialog.saveconfig.prune.diskcache=Memoria intermedia de mapas -dialog.saveconfig.prune.kmzimagewidth=Ancho de im\u00e1genes en KMZ -dialog.saveconfig.prune.colourscheme=Color de esquema -dialog.saveconfig.prune.linewidth=Ancho de l\u00ednea -dialog.saveconfig.prune.kmltrackcolour=Color de pista de KML -dialog.saveconfig.prune.autosavesettings=Guardar preferencias al salir +dialog.paths.prune.gnuplotpath=Ruta a gnuplot +dialog.paths.prune.gpsbabelpath=Ruta a gpsbabel +dialog.paths.prune.exiftoolpath=Ruta a exiftool dialog.setpaths.intro=Si usted necesita, puede escoger las rutas a aplicaciones externas dialog.setpaths.found=\u00bfRuta encontrada? dialog.addaltitude.noaltitudes=Los rangos seleccionados no contienen altitudes @@ -619,10 +588,10 @@ confirm.addtimeoffset=A\u00f1adido margen de tiempo confirm.addaltitudeoffset=A\u00f1adido margen de altitud confirm.rearrangewaypoints=Waypoints reorganizados confirm.rearrangephotos=Fotos reacomodadas -confirm.splitsegments=%d escisiones fueron hechas -confirm.sewsegments=%d conexiones fueron hechas +confirm.splitsegments=Se han hecho %d divisiones +confirm.sewsegments=Se han hecho %d uniones confirm.cutandmove=Mover selecci\u00f3n -confirm.interpolate=Puntos insertados +confirm.pointsadded=%d puntos insertados confirm.convertnamestotimes=Nombres de "waypoint" convertidos confirm.saveexif.ok=Guardado %d fotos confirm.undo.single=operaci\u00f3n deshecha @@ -648,9 +617,6 @@ confirm.correlateaudios.multi=Los audios fueron correlacionados ## Tips, shown just once when appropriate tip.title=Sugerencia -tip.useamapcache=By setting up a disk cache (Preferencias -> Guardar mapas en disco)\nyou can speed up the display and reduce network traffic. -tip.learntimeparams=The results will be more accurate if you use\nTrack -> Apprender parametros por la estimaci\u00f3n del tiempo\non your recorded tracks. -tip.downloadsrtm=You can speed this up by calling\nOnline -> Descargar datos de SRTM\nto save the data in your map cache. tip.manuallycorrelateone=Correlacionando al menos una foto manualmente, el margen de tiempo se calcula autom\u00e1ticamente. ## Buttons @@ -676,7 +642,6 @@ button.selectall=Seleccionar todo button.selectnone=Seleccionar nada button.preview=Previsualizaci\u00f3n button.load=Cargar -button.upload=Subir button.guessfields=Adivinar campos button.showwebpage=Mostrar p\u00e1gina web button.check=Verificar @@ -750,6 +715,7 @@ map.overzoom=No existen mapas disponibles con este nivel de enfoque ## Field names fieldname.latitude=Latitud fieldname.longitude=Longitud +fieldname.coordinates=Coordenadas fieldname.altitude=Altitud fieldname.timestamp=Informaci\u00f3n de tiempo fieldname.time=Tiempo @@ -893,3 +859,29 @@ error.cache.cannotdelete=No se pudieron borrar recuadros error.tracksplit.nosplit=Imposible segmentar el track error.downloadsrtm.nocache=Imposible guardar los archivos.\nPor favor, compruebe el cache. error.sewsegments.nothingdone=Imposible ensamblar los segmentos.\nEl track tiene ahora %d segmentos. + +dialog.exportimage.noimagepossible=Las im\u00e1genes de mapas deben ser guardadas para poder usarlas para una exportaci\u00f3n. +dialog.estimatetime.error.nodistance=Las estimaciones de tiempo necesitan puntos de v\u00eda conectados, para dar una distancia +dialog.learnestimationparams.intro=Estos son los par\u00e1metros calculados a partir del track +dialog.learnestimationparams.combine=Estos par\u00e1metros se pueden combinar con los valores actuales +dialog.weather.creditnotice=Estos datos est\u00e1n disponibles en openweathermap.org. Su sitio web tiene m\u00e1s detalles. +dialog.deletebydate.onlyonedate=Todos los puntos se registraron en la misma fecha. +dialog.deletebydate.intro=Para cada fecha del track, puede elegir entre borrar o mantener los puntos +confirm.downloadsrtm.none=No se descargaron archivos, ya estaban en la cache +tip.useamapcache=Configurando una cach\u00e9 de disco (Preferencias -> Guardar mapas en disco)\npuede acelerar la visualizaci\u00f3n y reducir el tr\u00e1fico de la red. +tip.learntimeparams=Los resultados ser\u00e1n m\u00e1s precisos si utiliza\nTrack -> Aprender par\u00e1metros de estimaci\u00f3n de tiempo\nen sus pistas grabadas. +tip.downloadsrtm=Puede acelerar esto si llama a\nOnline -> Descargar datos de SRTM\npara guardar los datos en su cach\u00e9 de mapas. +tip.usesrtmfor3d=Esta pista no tiene altitudes.\nPuede utilizar las funciones del SRTM\npara obtener altitudes aproximadas para la vista 3d. +error.learnestimationparams.failed=No puede aprender los par\u00e1metros de esta pista.\nIntente cargar m\u00e1s pistas. +function.enterpluscode=Insertar c\u00f3digo plus +function.projectpoint=Proyectar punto +dialog.pastecoordinatelist.desc=Introducir las coordenadas de los nuevos puntos con un punto por l\u00ednea +dialog.pluscode.desc=Introduzca o pegue el c\u00f3digo plus aqu\u00ed +dialog.pluscode.code=C\u00f3digo plus +dialog.pluscode.nothingfound=Por favor, compruebe el c\u00f3digo e int\u00e9ntelo de nuevo +dialog.displaysettings.windowstyle=Estilo de la ventana +dialog.projectpoint.desc=Introduzca la direcci\u00f3n y la distancia para proyectar este punto +dialog.projectpoint.bearing=Azimut (grados desde el Norte) +fieldname.comment=Comentario +dialog.settimezone.selectedzone=Zona horaria seleccionada +function.selecttimezone=Seleccionar la zona horaria diff --git a/src/tim/prune/lang/prune-texts_fi.properties b/src/tim/prune/lang/prune-texts_fi.properties index e6d6860..8b54aa6 100644 --- a/src/tim/prune/lang/prune-texts_fi.properties +++ b/src/tim/prune/lang/prune-texts_fi.properties @@ -100,7 +100,6 @@ function.pastecoordinates=Anna uudet koordinaatit... function.charts=Kaaviot function.show3d=3D-n\u00e4kym\u00e4 function.distances=V\u00e4limatkat -function.fullrangedetails=Koko pistealueen tiedot function.estimatetime=Arvioi aika function.learnestimationparams=Opi aika-arvion parametrit function.autoplay=Animoi reitti @@ -108,8 +107,6 @@ function.selectsegment=Valitse nykyinen lohko function.splitsegments=Pilko reitti lohkoihin function.sewsegments=Yhdist\u00e4 reittilohkot function.createmarkerwaypoints=Luo merkityt kohdepisteet -function.getgpsies=Lataa reitit Gpsies.com:sta -function.uploadgpsies=Vie reitti Gpsies.com:iin... function.lookupsrtm=Lue korkeysk\u00e4yr\u00e4t SRTM:st\u00e4 function.downloadsrtm=Lataa SRTM-palat function.getwikipedia=Hae likeiset Wikipedia-artikkelit @@ -362,18 +359,6 @@ dialog.gpsies.column.length=Pituus dialog.gpsies.description=Kuvaus dialog.gpsies.nodescription=Ei kuvausta dialog.gpsies.nonefound=Reittej\u00e4 ei l\u00f6ytynyt -dialog.gpsies.username=Gpsies.com:n k\u00e4ytt\u00e4j\u00e4nimi -dialog.gpsies.password=Gpsies.com:n salasana -dialog.gpsies.keepprivate=Pid\u00e4 reitti yksityisen\u00e4 -dialog.gpsies.activities=Aktiviteettityypit -dialog.gpsies.activity.trekking=Patikointi -dialog.gpsies.activity.walking=K\u00e4vely -dialog.gpsies.activity.jogging=Juoksu -dialog.gpsies.activity.biking=Polkupy\u00f6r\u00e4ily -dialog.gpsies.activity.motorbiking=Moottoripy\u00f6r\u00e4ily -dialog.gpsies.activity.snowshoe=Lumikenk\u00e4ily -dialog.gpsies.activity.sailing=Purjehdus -dialog.gpsies.activity.skating=Luistelu dialog.mapillary.nonefound=Kuvia ei l\u00f6ytynyt dialog.wikipedia.column.name=Artikkelin nimi dialog.wikipedia.column.distance=V\u00e4limatka @@ -480,25 +465,9 @@ dialog.keys.intro=Voit hiiren asemesta k\u00e4ytt\u00e4\u00e4 seuraavia n\u00e4p dialog.keys.keylist=
Nuolin\u00e4pp\u00e4imill\u00e4voit siirt\u00e4\u00e4 kartaa vasemmalle, oikealle, yl\u00f6s ja alas
Ctrl + vasen/oikea nuoli\u00e4pp\u00e4inValitse edellinen/seuraava reittipiste
Ctrl + yl\u00f6s/alas nuolin\u00e4pp\u00e4inL\u00e4henn\u00e4 tai loitonna
Ctrl + PgUp, PgDownValitse edellinen/seuraava pistelohko
Ctrl + Home, EndValitse ensimm\u00e4inen/viimeinen reittipiste
DelPoista valittu reittipiste
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=Seuraava asetukset voidaan tallentaa asetustiedostoon: -dialog.saveconfig.prune.trackdirectory=Reittihakemisto -dialog.saveconfig.prune.photodirectory=Kuvahakemisto -dialog.saveconfig.prune.languagecode=Kielitunnus (FI) -dialog.saveconfig.prune.languagefile=Kielitiedosto -dialog.saveconfig.prune.gpsdevice=GPS-laite -dialog.saveconfig.prune.gpsformat=GPS-formaatti -dialog.saveconfig.prune.povrayfont=Povray fontti -dialog.saveconfig.prune.gnuplotpath=Polku ohjelmaan gnuplot -dialog.saveconfig.prune.gpsbabelpath=Polku ohjelmaan gpsbabel -dialog.saveconfig.prune.exiftoolpath=Polku ohjelmaan exiftool -dialog.saveconfig.prune.mapsource=Valittu karttal\u00e4hde -dialog.saveconfig.prune.mapsourcelist=Karttal\u00e4hteet -dialog.saveconfig.prune.diskcache=Karttojen v\u00e4limuisti -dialog.saveconfig.prune.kmzimagewidth=KMZ:in kuvan leveys -dialog.saveconfig.prune.colourscheme=V\u00e4rij\u00e4rjestelm\u00e4 -dialog.saveconfig.prune.linewidth=Viivan leveys -dialog.saveconfig.prune.kmltrackcolour=KML:n reitin v\u00e4ri -dialog.saveconfig.prune.autosavesettings=Tallenna asetukset automaattisesti +dialog.paths.prune.gnuplotpath=Polku ohjelmaan gnuplot +dialog.paths.prune.gpsbabelpath=Polku ohjelmaan gpsbabel +dialog.paths.prune.exiftoolpath=Polku ohjelmaan exiftool dialog.setpaths.intro=Halutessasi voit valita hakemistopolut ulkoisiin sovelluksiin: dialog.setpaths.found=Polku l\u00f6ydetty? dialog.addaltitude.noaltitudes=Valittu alue ei sis\u00e4ll\u00e4 korkeustietoja @@ -664,7 +633,6 @@ button.selectall=Valitse kaikki button.selectnone=Valitse 'ei mit\u00e4\u00e4n' button.preview=Esikatselu button.load=Lataa -button.upload=Uppaa button.guessfields=Arvaa kent\u00e4t button.showwebpage=N\u00e4yt\u00e4 webbisivu button.check=Tarkista diff --git a/src/tim/prune/lang/prune-texts_fr.properties b/src/tim/prune/lang/prune-texts_fr.properties index f884c02..9c0f85a 100644 --- a/src/tim/prune/lang/prune-texts_fr.properties +++ b/src/tim/prune/lang/prune-texts_fr.properties @@ -100,7 +100,7 @@ function.pastecoordinates=Coller les coordonn\u00e9es function.charts=Graphiques function.show3d=Montrer en 3D function.distances=Distances -function.fullrangedetails=Montrer tous les d\u00e9tails +function.viewfulldetails=Montrer tous les d\u00e9tails function.estimatetime=Temps estim\u00e9 function.learnestimationparams=Apprentissage de l'estimation function.setmapbg=D\u00e9finir le fond de carte @@ -109,8 +109,6 @@ function.autoplay=Jouer la trace function.selectsegment=S\u00e9lectionner le segment courant function.splitsegments=S\u00e9pare les segments function.sewsegments=R\u00e9unis les segments -function.getgpsies=R\u00e9cup\u00e9rer les traces Gpsies -function.uploadgpsies=T\u00e9l\u00e9charger la trace sur Gpsies function.lookupsrtm=R\u00e9cup\u00e9rer les altitudes depuis SRTM function.downloadsrtm=T\u00e9l\u00e9charger les donn\u00e9es SRTM function.getwikipedia=Obtenir les articles de Wikip\u00e9dia \u00e0 proximit\u00e9 @@ -359,19 +357,6 @@ dialog.gpsies.column.length=Distance dialog.gpsies.description=Description dialog.gpsies.nodescription=Aucune description dialog.gpsies.nonefound=Aucune trace trouv\u00e9e -dialog.gpsies.username=Nom d'utilisateur Gpsies -dialog.gpsies.password=Mot de passe Gpsies -dialog.gpsies.keepprivate=Trace priv\u00e9e -dialog.gpsies.confirmopenpage=Ouvrir la page web de la trace t\u00e9l\u00e9charg\u00e9e ? -dialog.gpsies.activities=Activit\u00e9 -dialog.gpsies.activity.trekking=Trekking -dialog.gpsies.activity.walking=Randonn\u00e9e -dialog.gpsies.activity.jogging=Jogging -dialog.gpsies.activity.biking=V\u00e9lo -dialog.gpsies.activity.motorbiking=Moto -dialog.gpsies.activity.snowshoe=Raquette -dialog.gpsies.activity.sailing=Volle -dialog.gpsies.activity.skating=Skating dialog.mapillary.nonefound=Aucun foto trouv\u00e9 dialog.wikipedia.column.name=Nom de l'article dialog.wikipedia.column.distance=Distance @@ -478,25 +463,9 @@ dialog.keys.intro=Vous pouvez utiliser ces raccourcis clavier \u00e0 la place de dialog.keys.keylist=
Touches-fl\u00e8chesFaire d\u00e9filer la carte horizontalement et verticalement
Ctrl + gauche, Ctrl + droiteChoisir le point pr\u00e9c\u00e9dent ou suivant
Ctrl + haut, Ctrl + basZoomer, s'\u00e9loigner
Ctrl + PgUp, PgDownChoisir le segment pr\u00e9c\u00e9dent ou suivant
Ctrl + Home, EndChoisir le point premier, dernier
SupprEffacer le point courant
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=Les param\u00e8tres suivants peuvent \u00eatre sauvegard\u00e9s dans un fichier de configuration: -dialog.saveconfig.prune.trackdirectory=Dossier des traces -dialog.saveconfig.prune.photodirectory=Dossier des Photos -dialog.saveconfig.prune.languagecode=Code langue (FR) -dialog.saveconfig.prune.languagefile=Fichier de langue -dialog.saveconfig.prune.gpsdevice=Chemin du p\u00e9riph\u00e9rique GPS -dialog.saveconfig.prune.gpsformat=Format GPS -dialog.saveconfig.prune.povrayfont=Police povray -dialog.saveconfig.prune.gnuplotpath=Chemin gnuplot -dialog.saveconfig.prune.gpsbabelpath=Chemin gpsbabel -dialog.saveconfig.prune.exiftoolpath=Chemin exiftool -dialog.saveconfig.prune.mapsource=Carte source s\u00e9lectionn\u00e9e -dialog.saveconfig.prune.mapsourcelist=Sources de cartes -dialog.saveconfig.prune.diskcache=Cache de carte -dialog.saveconfig.prune.kmzimagewidth=Largeur de l'image KMZ -dialog.saveconfig.prune.colourscheme=Mod\u00e8le de couleurs -dialog.saveconfig.prune.linewidth=Largeur de ligne -dialog.saveconfig.prune.kmltrackcolour=Couleur de la trace KML -dialog.saveconfig.prune.autosavesettings=R\u00e9glages de sauvegarde automatique +dialog.paths.prune.gnuplotpath=Chemin gnuplot +dialog.paths.prune.gpsbabelpath=Chemin gpsbabel +dialog.paths.prune.exiftoolpath=Chemin exiftool dialog.setpaths.intro=Si vous le souhaitez, vous pouvez d\u00e9finir les chemins des applications externes: dialog.setpaths.found=Chemin trouv\u00e9 ? dialog.addaltitude.noaltitudes=L'\u00e9tendue s\u00e9lectionn\u00e9e de contient pas d'altitudes @@ -610,7 +579,7 @@ confirm.addaltitudeoffset=D\u00e9calage d'altitude ajout\u00e9 confirm.rearrangewaypoints=Waypoints r\u00e9arrang\u00e9s confirm.rearrangephotos=Photos r\u00e9arrang\u00e9es confirm.cutandmove=S\u00e9lection d\u00e9plac\u00e9e -confirm.interpolate=Points ajout\u00e9s +confirm.pointsadded=%d points ajout\u00e9s confirm.convertnamestotimes=Noms de waypoints convertis confirm.saveexif.ok=Enregistr\u00e9 %d fichiers photo confirm.undo.single=op\u00e9ration annul\u00e9e @@ -665,7 +634,6 @@ button.selectall=Tout s\u00e9lectionner button.selectnone=Ne rien s\u00e9lectionner button.preview=Aper\u00e7u button.load=T\u00e9l\u00e9charger -button.upload=Envoyer button.guessfields=Deviner les champs button.showwebpage=Montrer page web button.check=V\u00e9rifier @@ -739,6 +707,7 @@ map.overzoom=Aucune carte disponible \u00e0 ce niveau de zoom # Field names fieldname.latitude=Latitude fieldname.longitude=Longitude +fieldname.coordinates=Coordonn\u00e9es fieldname.altitude=Altitude fieldname.timestamp=Date et heure fieldname.time=Temps diff --git a/src/tim/prune/lang/prune-texts_hu.properties b/src/tim/prune/lang/prune-texts_hu.properties index 359ad21..021db53 100644 --- a/src/tim/prune/lang/prune-texts_hu.properties +++ b/src/tim/prune/lang/prune-texts_hu.properties @@ -1,5 +1,5 @@ # Text entries for the GpsPrune application -# Hungarian entries thanks to Gy\u00f6rgy Ball\u00f3, Peter Bathory and Peter Gervai +# Hungarian entries thanks to Gy\u00f6rgy Ball\u00f3, P\u00e9ter B\u00e1thory and Peter Gervai # Menu entries menu.file=F\u00e1jl @@ -12,7 +12,6 @@ menu.track=Nyomvonal menu.track.undo=Visszavon\u00e1s menu.track.clearundo=Visszavon\u00e1si lista t\u00f6rl\u00e9se menu.track.markrectangle=N\u00e9gyzeten bel\u00fcli pontok megjel\u00f6l\u00e9se -function.deletemarked=Jel\u00f6lt pontok t\u00f6rl\u00e9se menu.range=Tartom\u00e1ny menu.range.all=Mindet kijel\u00f6l menu.range.none=Kijel\u00f6l\u00e9s megsz\u00fcntet\u00e9se @@ -38,7 +37,6 @@ menu.view.browser.yahoo=Yahoo! Maps menu.view.browser.bing=Bing Maps menu.settings=Be\u00e1ll\u00edt\u00e1sok menu.settings.onlinemode=T\u00e9rk\u00e9pek bet\u00f6lt\u00e9se internetr\u0151l -dialog.displaysettings.antialias=\u00c9lsim\u00edt\u00e1s haszn\u00e1lata menu.settings.autosave=Be\u00e1ll\u00edt\u00e1sok automatikus ment\u00e9se kil\u00e9p\u00e9skor menu.help=S\u00fag\u00f3 @@ -86,6 +84,7 @@ function.exportpov=Export\u00e1l\u00e1s POV-ba function.exportimage=Export\u00e1l\u00e1s k\u00e9pbe function.editwaypointname=\u00datpont nev\u00e9nek szerkeszt\u00e9se function.compress=Nyomvonal t\u00f6m\u00f6r\u00edt\u00e9se +function.deletemarked=Jel\u00f6lt pontok t\u00f6rl\u00e9se function.marklifts=S\u00edliftek megjel\u00f6l\u00e9se function.deleterange=Tartom\u00e1ny t\u00f6rl\u00e9se function.croptrack=Nyomvonal k\u00f6rbev\u00e1g\u00e1sa @@ -101,7 +100,6 @@ function.pastecoordinates=\u00daj koordin\u00e1t\u00e1k megad\u00e1sa function.charts=Diagramok function.show3d=3D n\u00e9zet function.distances=T\u00e1vols\u00e1gok -function.fullrangedetails=Teljes tartom\u00e1ny r\u00e9szletei function.estimatetime=Becs\u00fclt id\u0151 function.learnestimationparams=Id\u0151becsl\u00e9s tanul\u00e1s\u00e1nak param\u00e9terei function.autoplay=Nyomvonal lej\u00e1tsz\u00e1sa @@ -110,17 +108,18 @@ function.setpaths=Program\u00fatvonalak be\u00e1ll\u00edt\u00e1sa function.selectsegment=Aktu\u00e1lis szakasz kiv\u00e1laszt\u00e1sa function.splitsegments=Nyomvonal kett\u00e9v\u00e1g\u00e1sa szakaszokk\u00e1 function.sewsegments=Nyomvonalszakaszok \u00f6sszevon\u00e1sa -function.getgpsies=Gpsies nyomvonalak let\u00f6lt\u00e9se -function.uploadgpsies=Nyomvonal felt\u00f6lt\u00e9se Gpsiesra +function.createmarkerwaypoints=\u00datpont jel\u00f6l\u0151k k\u00e9sz\u00edt\u00e9se function.lookupsrtm=Magass\u00e1gok let\u00f6lt\u00e9se SRTM-r\u0151l function.downloadsrtm=SRTM csemp\u00e9k let\u00f6lt\u00e9se function.getwikipedia=K\u00f6zeli Wikip\u00e9dia sz\u00f3cikkek let\u00f6lt\u00e9se function.searchwikipedianames=Keres\u00e9s a Wikip\u00e9di\u00e1ban n\u00e9v szerint +function.searchosmpois=K\u00f6zeli OSM pontok function.searchopencachingde=Keres\u00e9s az OpenCaching.de-n function.mapillary=F\u00e9nyk\u00e9pek keres\u00e9se Mapillary-n function.downloadosm=OSM adatok let\u00f6lt\u00e9se a ter\u00fcletr\u0151l function.duplicatepoint=Pont kett\u0151z\u00e9se function.setcolours=Sz\u00ednek be\u00e1ll\u00edt\u00e1sa +function.setdisplaysettings=Megjelen\u00edt\u00e9s be\u00e1ll\u00edt\u00e1sa function.setlanguage=Nyelv be\u00e1ll\u00edt\u00e1sa function.connecttopoint=Kapcsol\u00e1s ponthoz function.disconnectfrompoint=Lev\u00e1laszt\u00e1s pontr\u00f3l @@ -145,6 +144,7 @@ function.diskcache=T\u00e9rk\u00e9pek ment\u00e9se lemezre function.managetilecache=Csempegyors\u00edt\u00f3t\u00e1r kezel\u00e9se function.getweatherforecast=Id\u0151j\u00e1r\u00e1s el\u0151rejelz\u00e9s function.setaltitudetolerance=Magass\u00e1gi t\u0171r\u00e9s be\u00e1ll\u00edt\u00e1sa +function.selecttimezone=Id\u0151z\u00f3na be\u00e1ll\u00edt\u00e1sa # Dialogs dialog.exit.confirm.title=Kil\u00e9p\u00e9s a GpsPrune-b\u00f3l @@ -173,7 +173,7 @@ dialog.openoptions.deliminfo.norecords=Nincsenek rekordok dialog.openoptions.altitudeunits=Magass\u00e1g m\u00e9rt\u00e9kegys\u00e9ge dialog.openoptions.speedunits=Sebess\u00e9g m\u00e9rt\u00e9kegys\u00e9ge dialog.openoptions.vertspeedunits=F\u00fcgg\u0151leges sebess\u00e9g m\u00e9rt\u00e9kegys\u00e9ge -dialog.openoptions.vspeed.positiveup=Pozit\u00edv sebess\u00e9g m\u00e9rt\u00e9kegys\u00e9ge +dialog.openoptions.vspeed.positiveup=Pozit\u00edv sebess\u00e9g felfel\u00e9 dialog.openoptions.vspeed.positivedown=Pozit\u00edv sebess\u00e9g lefel\u00e9 dialog.open.contentsdoubled=Ez a f\u00e1jl minden egyes pont k\u00e9t p\u00e9ld\u00e1ny\u00e1t tartalmazza,\negyszer mint \u00fatpont, m\u00e1sodszor mint nyompont. dialog.selecttracks.intro=Nyomvonal vagy nyomvonalak kiv\u00e1laszt\u00e1sa bet\u00f6lt\u00e9shez @@ -364,24 +364,14 @@ dialog.gpsies.column.length=Hossz dialog.gpsies.description=Le\u00edr\u00e1s dialog.gpsies.nodescription=Nincs le\u00edr\u00e1s dialog.gpsies.nonefound=Nem tal\u00e1lhat\u00f3 nyomvonal -dialog.gpsies.username=Gpsies felhaszn\u00e1l\u00f3n\u00e9v -dialog.gpsies.password=Gpsies jelsz\u00f3 -dialog.gpsies.keepprivate=A nyomvonal maradjon priv\u00e1t -dialog.gpsies.confirmopenpage=Megnyitja a weboldalt a felt\u00f6lt\u00f6tt nyomvonal sz\u00e1m\u00e1ra? -dialog.gpsies.activities=Tev\u00e9kenys\u00e9gt\u00edpusok -dialog.gpsies.activity.trekking=T\u00far\u00e1z\u00e1s -dialog.gpsies.activity.walking=S\u00e9ta -dialog.gpsies.activity.jogging=Fut\u00e1s -dialog.gpsies.activity.biking=Ker\u00e9kp\u00e1roz\u00e1s -dialog.gpsies.activity.motorbiking=Motorker\u00e9kp\u00e1roz\u00e1s -dialog.gpsies.activity.snowshoe=H\u00f3talpas s\u00e9ta -dialog.gpsies.activity.sailing=Vitorl\u00e1z\u00e1s -dialog.gpsies.activity.skating=Korcsoly\u00e1z\u00e1s dialog.mapillary.nonefound=Nem tal\u00e1lhat\u00f3k f\u00e9nyk\u00e9pek dialog.wikipedia.column.name=Sz\u00f3cikk neve dialog.wikipedia.column.distance=T\u00e1vols\u00e1g dialog.wikipedia.nonefound=Nem tal\u00e1lhat\u00f3 Wikip\u00e9dia sz\u00f3cikk dialog.wikipedia.gallery=Gal\u00e9ria +dialog.osmpois.column.name=N\u00e9v +dialog.osmpois.column.type=T\u00edpus +dialog.osmpois.nonefound=Nem tal\u00e1lhat\u00f3k pontok dialog.geocaching.nonefound=Nem tal\u00e1lhat\u00f3 geol\u00e1da dialog.correlate.notimestamps=Nincsenek id\u0151b\u00e9lyegek az adatpontokon, \u00edgy nem feleltethet\u0151 meg semmi a f\u00e9nyk\u00e9pekkel. dialog.correlate.nouncorrelatedphotos=Nincsenek megfeleltetlen f\u00e9nyk\u00e9pek.\nBiztos benne, hogy folytatja? @@ -480,25 +470,9 @@ dialog.keys.intro=A k\u00f6vetkez\u0151 gyorsbillenty\u0171k haszn\u00e1lhat\u00 dialog.keys.keylist=
Ny\u00edlbillenty\u0171kT\u00e9rk\u00e9p mozgat\u00e1sa balra, jobbra, fel, le
Ctrl + bal, jobb ny\u00edlEl\u0151z\u0151 vagy k\u00f6vetkez\u0151 pont kiv\u00e1laszt\u00e1sa
Ctrl + fel, le ny\u00edlNagy\u00edt\u00e1s vagy kicsiny\u00edt\u00e9s
Ctrl + PgUp, PgDownEl\u0151z\u0151, k\u00f6vetkez\u0151 szakasz kiv\u00e1laszt\u00e1sa
Ctrl + Home, EndEls\u0151, utols\u00f3 pont kiv\u00e1laszt\u00e1sa
DelJelenlegi pont t\u00f6rl\u00e9se
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=A k\u00f6vetkez\u0151 be\u00e1ll\u00edt\u00e1sok menthet\u0151k egy konfigur\u00e1ci\u00f3s f\u00e1jlba -dialog.saveconfig.prune.trackdirectory=Nyomvonalak k\u00f6nyvt\u00e1ra -dialog.saveconfig.prune.photodirectory=F\u00e9nyk\u00e9pek k\u00f6nyvt\u00e1ra -dialog.saveconfig.prune.languagecode=Nyelv k\u00f3dja (HU) -dialog.saveconfig.prune.languagefile=Nyelvi f\u00e1jl -dialog.saveconfig.prune.gpsdevice=GPS eszk\u00f6z -dialog.saveconfig.prune.gpsformat=GPS form\u00e1tum -dialog.saveconfig.prune.povrayfont=Povray bet\u0171t\u00edpus -dialog.saveconfig.prune.gnuplotpath=\u00datvonal a gnuplothoz -dialog.saveconfig.prune.gpsbabelpath=\u00datvonal a gpsbabelhez -dialog.saveconfig.prune.exiftoolpath=\u00datvonal az exiftoolhoz -dialog.saveconfig.prune.mapsource=Kiv\u00e1lasztott t\u00e9rk\u00e9pforr\u00e1s -dialog.saveconfig.prune.mapsourcelist=T\u00e9rk\u00e9pforr\u00e1sok -dialog.saveconfig.prune.diskcache=T\u00e9rk\u00e9p-gyors\u00edt\u00f3t\u00e1r -dialog.saveconfig.prune.kmzimagewidth=KMZ k\u00e9psz\u00e9less\u00e9g -dialog.saveconfig.prune.colourscheme=Sz\u00edns\u00e9ma -dialog.saveconfig.prune.linewidth=Vonalsz\u00e9less\u00e9g -dialog.saveconfig.prune.kmltrackcolour=KML nyomvonal sz\u00edne -dialog.saveconfig.prune.autosavesettings=Automatikus ment\u00e9s be\u00e1ll\u00edt\u00e1sai +dialog.paths.prune.gnuplotpath=\u00datvonal a gnuplothoz +dialog.paths.prune.gpsbabelpath=\u00datvonal a gpsbabelhez +dialog.paths.prune.exiftoolpath=\u00datvonal az exiftoolhoz dialog.setpaths.intro=Ha sz\u00fcks\u00e9ges, kiv\u00e1laszthatja a k\u00fcls\u0151 alkalmaz\u00e1sok \u00fatvonalait: dialog.setpaths.found=\u00datvonal megtal\u00e1lhat\u00f3? dialog.addaltitude.noaltitudes=A kiv\u00e1lasztott tartom\u00e1ny nem tartalmaz magass\u00e1gi \u00e9rt\u00e9keket @@ -555,6 +529,16 @@ dialog.diskcache.deleted=%d f\u00e1jl t\u00f6r\u00f6lve a gyors\u00edt\u00f3t\u0 dialog.deletefieldvalues.intro=V\u00e1lassza ki a t\u00f6rlend\u0151 mez\u0151t a jelenlegi tartom\u00e1nyban dialog.deletefieldvalues.nofields=Nincs t\u00f6r\u00f6lhet\u0151 mez\u0151 a tartom\u00e1nyban dialog.displaysettings.linewidth=Adja meg a rajzoland\u00f3 vonalak vastags\u00e1g\u00e1t a nyomvonalak sz\u00e1m\u00e1ra (1-4) +dialog.displaysettings.antialias=\u00c9lsim\u00edt\u00e1s haszn\u00e1lata +dialog.displaysettings.waypointicons=\u00datpont ikon +dialog.displaysettings.wpicon.default=Alap\u00e9rtelmezett +dialog.displaysettings.wpicon.ringpt=Kerek +dialog.displaysettings.wpicon.plectrum=Penget\u0151 +dialog.displaysettings.wpicon.ring=Gy\u0171r\u0171 +dialog.displaysettings.wpicon.pin=Gombost\u0171 +dialog.displaysettings.size.small=Kicsi +dialog.displaysettings.size.medium=K\u00f6zepes +dialog.displaysettings.size.large=Nagy dialog.downloadosm.desc=Nyers OSM adatok let\u00f6lt\u00e9s\u00e9nek meger\u0151s\u00edt\u00e9se a megadott ter\u00fcletre: dialog.searchwikipedianames.search=Keres\u00e9s erre: dialog.weather.location=Helysz\u00edn @@ -586,6 +570,10 @@ dialog.deletebydate.column.keep=Megtart dialog.deletebydate.column.delete=T\u00f6r\u00f6l dialog.setaltitudetolerance.text.metres=Az a hat\u00e1r (m\u00e9terben) ami alatt a kis s\u00fcllyed\u00e9seket \u00e9s emelked\u00e9seket figyelmen k\u00edv\u00fcl hagyjuk dialog.setaltitudetolerance.text.feet=Az a hat\u00e1r (l\u00e1bban) ami alatt a kis s\u00fcllyed\u00e9seket \u00e9s emelked\u00e9seket figyelmen k\u00edv\u00fcl hagyjuk +dialog.settimezone.intro=Kiv\u00e1laszthatja, hogy az \u00fatvonalpontok id\u0151b\u00e9lyegz\u0151i milyen id\u0151z\u00f3na szerint jelenjenek meg +dialog.settimezone.system=Rendszer id\u0151z\u00f3na haszn\u00e1lata +dialog.settimezone.custom=Az al\u00e1bbi id\u0151z\u00f3na haszn\u00e1lata +dialog.settimezone.list.toomany=T\u00fal sok lehet\u0151s\u00e9g dialog.autoplay.duration=Id\u0151tartam (mp) dialog.autoplay.usetimestamps=Nyompontok id\u0151b\u00e9lyege alapj\u00e1n dialog.autoplay.rewind=Vissza az elej\u00e9re @@ -612,7 +600,7 @@ confirm.rearrangephotos=F\u00e9nyk\u00e9pek \u00fajrarendezve confirm.splitsegments=%d szakasz v\u00e1g\u00e1s elv\u00e9gezve confirm.sewsegments=%d szakasz egyes\u00edt\u00e9se elv\u00e9gezve confirm.cutandmove=Kijel\u00f6l\u00e9s \u00e1thelyezve -confirm.interpolate=Pontok hozz\u00e1adva +confirm.pointsadded=%d pontok hozz\u00e1adva confirm.convertnamestotimes=\u00datpont nevei konvert\u00e1lva confirm.saveexif.ok=Mentve %d k\u00e9pf\u00e1jl confirm.undo.single=m\u0171velet visszavonva @@ -668,7 +656,6 @@ button.selectall=Mindent kijel\u00f6l button.selectnone=Kijel\u00f6l\u00e9s megsz\u00fcntet\u00e9se button.preview=El\u0151n\u00e9zet button.load=Bet\u00f6lt\u00e9s -button.upload=Felt\u00f6lt\u00e9s button.guessfields=Mez\u0151k kital\u00e1l\u00e1sa button.showwebpage=Weboldal megjelen\u00edt\u00e9se button.check=Ellen\u0151rz\u00e9s @@ -783,9 +770,9 @@ units.feetpersec.short=ft/s units.hours=\u00f3ra units.minutes=perc units.seconds=m\u00e1sodperc -units.degminsec=Sz\u00f6g-sz\u00f6gperc-sz\u00f6gm\u00e1sodperc -units.degmin=Sz\u00f6g-sz\u00f6gperc -units.deg=Sz\u00f6g +units.degminsec=Fok-perc-m\u00e1sodperc +units.degmin=Fok-perc +units.deg=Fok units.iso8601=ISO 8601 units.degreescelsius=Celsius units.degreescelsius.short=\u00b0C diff --git a/src/tim/prune/lang/prune-texts_it.properties b/src/tim/prune/lang/prune-texts_it.properties index 6648b0e..bc5a7b3 100644 --- a/src/tim/prune/lang/prune-texts_it.properties +++ b/src/tim/prune/lang/prune-texts_it.properties @@ -97,10 +97,12 @@ function.convertnamestotimes=Converti nomi dei waypoint in orari function.deletefieldvalues=Cancella i valori del campo function.findwaypoint=Trova waypoint function.pastecoordinates=Aggiungi coordinate +function.pastecoordinatelist=Inserisci lista di coordinate +function.enterpluscode=Inserisci pluscode function.charts=Diagrammi function.show3d=Mostra in 3D function.distances=Mostra distanze -function.fullrangedetails=Mostra dettagli +function.viewfulldetails=Mostra dettagli function.estimatetime=Stima durata function.learnestimationparams=Apprendi parametri di stima function.autoplay=Riproduci traccia @@ -110,8 +112,6 @@ function.selectsegment=Seleziona segmento corrente function.splitsegments=Dividi traccia in segmenti function.sewsegments=Riorganizza segmenti insieme function.createmarkerwaypoints=Crea marcatori -function.getgpsies=Ottieni tracce da Gpsies -function.uploadgpsies=Carica traccia su Gpsies function.lookupsrtm=Ottieni quote da SRTM function.downloadsrtm=Scarica file da SRTM function.getwikipedia=Ottieni i punti Wikipedia nelle vicinanze @@ -148,6 +148,7 @@ function.managetilecache=Gestione del cache di tasselli function.getweatherforecast=Ottieni previsioni del tempo function.setaltitudetolerance=Configura tolleranza di altitudini function.selecttimezone=Seleziona fuso orario +function.projectpoint=Proiettare il punto # Dialogs dialog.exit.confirm.title=Esci da GpsPrune @@ -367,19 +368,6 @@ dialog.gpsies.column.length=Lunghezza dialog.gpsies.description=Descrizione dialog.gpsies.nodescription=Senza descrizione dialog.gpsies.nonefound=Nessuna traccia trovata -dialog.gpsies.username=Gpsies username -dialog.gpsies.password=Gpsies password -dialog.gpsies.keepprivate=Rendi la traccia privata -dialog.gpsies.confirmopenpage=Apri la pagina web per caricare la traccia? -dialog.gpsies.activities=Attivit\u00e0 -dialog.gpsies.activity.trekking=Trekking -dialog.gpsies.activity.walking=Camminare -dialog.gpsies.activity.jogging=Jogging -dialog.gpsies.activity.biking=Ciclismo -dialog.gpsies.activity.motorbiking=Motocicletta -dialog.gpsies.activity.snowshoe=Trekking sulla neve -dialog.gpsies.activity.sailing=Navigazione -dialog.gpsies.activity.skating=Pattinaggio dialog.mapillary.nonefound=Nessuna foto trovata dialog.wikipedia.column.name=Titolo articolo dialog.wikipedia.column.distance=Distanza @@ -447,6 +435,10 @@ dialog.deletemarked.nonefound=Nessun punto rimosso dialog.pastecoordinates.desc=Inserisci o incolla qui le coordinate dialog.pastecoordinates.coords=Coordinate dialog.pastecoordinates.nothingfound=Per favore, controlla le coordinate e riprova +dialog.pastecoordinatelist.desc=Inserisci le coordinate per i nuovi punti, utilizzando un linea per punto +dialog.pluscode.desc=Inserisci o incolla qui il pluscode +dialog.pluscode.code=Pluscode +dialog.pluscode.nothingfound=Per favore, controlla il codice e riprova dialog.help.help=Per favore vedi\n https://gpsprune.activityworkshop.net/\nper maggiori informazioni e per la guida utente. dialog.about.version=Versione dialog.about.build=Build @@ -486,25 +478,9 @@ dialog.keys.intro=Puoi utilizzare i seguenti tast di scelta rapida al posto del dialog.keys.keylist=
Tasti frecciaMuovi mappa destra, sinistra, su, giu'
Ctrl + freccia destra, sinistraSelezione punto successivo o precedente
Ctrl + freccia su, giu'Zoom in o out
Ctrl + pagina su, giu'Segmento successivo o precedente
Ctrl + Home, EndPunto primo o ultimo
DelCancella punto attuale
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Comando -dialog.saveconfig.desc=Le configurazioni seguenti possono essere salvati in un file di configurazione: -dialog.saveconfig.prune.trackdirectory=Cartella tracce -dialog.saveconfig.prune.photodirectory=Cartella foto -dialog.saveconfig.prune.languagecode=Codice lingua (IT) -dialog.saveconfig.prune.languagefile=File lingua -dialog.saveconfig.prune.gpsdevice=Nome del Dispositivo GPS -dialog.saveconfig.prune.gpsformat=Formato GPS -dialog.saveconfig.prune.povrayfont=Font povray -dialog.saveconfig.prune.gnuplotpath=Path gnuplot -dialog.saveconfig.prune.gpsbabelpath=Path gpsbabel -dialog.saveconfig.prune.exiftoolpath=Path exiftool -dialog.saveconfig.prune.mapsource=Selezionale la fonte delle mappe -dialog.saveconfig.prune.mapsourcelist=Fonte delle mappe -dialog.saveconfig.prune.diskcache=Cache delle mappe -dialog.saveconfig.prune.kmzimagewidth=larghezza immagine KMZ -dialog.saveconfig.prune.colourscheme=Schema colori -dialog.saveconfig.prune.linewidth=Spessore linea -dialog.saveconfig.prune.kmltrackcolour=Colore della traccia KML -dialog.saveconfig.prune.autosavesettings=Salvare settaggi automaticamente +dialog.paths.prune.gnuplotpath=Path gnuplot +dialog.paths.prune.gpsbabelpath=Path gpsbabel +dialog.paths.prune.exiftoolpath=Path exiftool dialog.setpaths.intro=Se necessario, puoi indicare il percorso delle applicazioni esterne: dialog.setpaths.found=trovato? dialog.addaltitude.noaltitudes=L'intervallo selezionato non contiene altitudini @@ -571,6 +547,9 @@ dialog.displaysettings.wpicon.pin=Spillo da lavagna dialog.displaysettings.size.small=Piccole dialog.displaysettings.size.medium=Medie dialog.displaysettings.size.large=Grandi +dialog.displaysettings.windowstyle=Stile della finestra (è necessario il riavvio) +dialog.displaysettings.windowstyle.default=Normale +dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Conferma lo scarico dei dati raw OSM per l'area specificata: dialog.searchwikipedianames.search=Cerca per: dialog.weather.location=Localit\u00e0 @@ -613,6 +592,12 @@ dialog.autoplay.usetimestamps=Usa dati temporali dialog.autoplay.rewind=Riavvolga dialog.autoplay.pause=Pausa dialog.autoplay.play=Riproduci +dialog.markers.halves=Punti a metà strada +dialog.markers.half.distance=Metà della distanza +dialog.markers.half.climb=Metà della salita +dialog.markers.half.descent=Metà della discesa +dialog.projectpoint.bearing=Azimut (gradi da nord) +dialog.projectpoint.desc=Inserire l'azimut e la distanza per la proiezione # 3d window dialog.3d.title=Visione GpsPrune in 3D @@ -634,7 +619,7 @@ confirm.rearrangephotos=Foto riorganizzate confirm.splitsegments=%d segmenti sono stati suddivisi confirm.sewsegments=%d segmenti sono stati raggruppati confirm.cutandmove=Selezione spostata -confirm.interpolate=Aggiungi punto +confirm.pointsadded=Aggiungi %d punto confirm.convertnamestotimes=Nome del waypoint convertito confirm.saveexif.ok=Salvato %d foto confirm.undo.single=operazione annullate @@ -690,7 +675,6 @@ button.selectall=Seleziona tutto button.selectnone=Deseleziona tutto button.preview=Anteprima button.load=Carica -button.upload=Caricato button.guessfields=Campi soluzione button.showwebpage=Mostra pagina button.check=Controlla @@ -764,6 +748,7 @@ map.overzoom=Mappa non disponibile a questo livello di zoom # Field names fieldname.latitude=Latitudine fieldname.longitude=Longitudine +fieldname.coordinates=Coordinate fieldname.altitude=Altitudine fieldname.timestamp=Dati temporali fieldname.time=Tempo @@ -778,6 +763,7 @@ fieldname.duration=Durata fieldname.speed=Velocit\u00e0 fieldname.verticalspeed=Velocit\u00e0 verticale fieldname.description=Descrizione +fieldname.comment=Commento fieldname.mediafilename=File # Measurement units @@ -877,6 +863,7 @@ error.load.nopoints=Non ci sono coordinate nel file error.load.unknownxml=Formato xml non riconosciuto: error.load.noxmlinzip=File xml non trovato all'interno del zip file error.load.othererror=Errore nella lettura del file: +error.load.nopointsintext=Non ci sono coordinate error.jpegload.dialogtitle=Errore nel caricamento delle foto error.jpegload.nofilesfound=File non trovato error.jpegload.nojpegsfound=File jpeg non trovato diff --git a/src/tim/prune/lang/prune-texts_ja.properties b/src/tim/prune/lang/prune-texts_ja.properties index 738a101..f698aba 100644 --- a/src/tim/prune/lang/prune-texts_ja.properties +++ b/src/tim/prune/lang/prune-texts_ja.properties @@ -93,11 +93,8 @@ function.pastecoordinates=\u65b0\u3057\u3044\u5ea7\u6a19\u3092\u5165\u529b function.charts=\u9ad8\u5ea6\u901f\u5ea6\u30c1\u30e3\u30fc\u30c8 function.show3d=3-D\u30d3\u30e5\u30fc function.distances=\u8ddd\u96e2 -function.fullrangedetails=\u5168\u7bc4\u56f2\u8a73\u7d30 function.setmapbg=\u80cc\u666f\u5730\u56f3 function.setpaths=\u5916\u90e8\u30d7\u30ed\u30b0\u30e9\u30e0\u30d1\u30b9\u3092\u8a2d\u5b9a -function.getgpsies=Gpsies\u30c8\u30e9\u30c3\u30af\u3092\u5f97\u308b -function.uploadgpsies=Gpsies\u306b\u30c8\u30e9\u30c3\u30af\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 function.lookupsrtm=SRTM\u304b\u3089\u6a19\u9ad8\u3092\u53d6\u5f97\u3059\u308b function.getwikipedia=Wikipedia\u304b\u3089\u5468\u56f2\u306e\u8a18\u4e8b\u3092\u53d6\u5f97\u3059\u308b function.searchwikipedianames=\u540d\u524d\u3067Wikipedia\u3092\u691c\u7d22 @@ -270,17 +267,6 @@ dialog.gpsies.column.length=\u9577\u3055 dialog.gpsies.description=\u8a18\u8ff0 dialog.gpsies.nodescription=\u8a18\u8ff0\u304c\u3042\u308a\u307e\u305b\u3093 dialog.gpsies.nonefound=\u30c8\u30e9\u30c3\u30af\u304c\u3042\u308a\u307e\u305b\u3093 -dialog.gpsies.username=Gpsies\u306e\u30e6\u30fc\u30b6\u30fc\u540d -dialog.gpsies.password=Gpsies\u306e\u30d1\u30b9\u30ef\u30fc\u30c9 -dialog.gpsies.activities=\u6d3b\u52d5\u306b\u9069\u3057\u3066 -dialog.gpsies.activity.trekking=\u30cf\u30a4\u30ad\u30f3\u30b0 -dialog.gpsies.activity.walking=\u30a6\u30a9\u30fc\u30ad\u30f3\u30b0 -dialog.gpsies.activity.jogging=\u5b9f\u884c\u4e2d -dialog.gpsies.activity.biking=\u30b5\u30a4\u30af\u30ea\u30f3\u30b0 -dialog.gpsies.activity.motorbiking=\u30e2\u30fc\u30bf\u30fc\u30d0\u30a4\u30af -dialog.gpsies.activity.snowshoe=\u30b9\u30ce\u30fc\u30b7\u30e5\u30fc\u30a4\u30f3\u30b0 -dialog.gpsies.activity.sailing=\u30bb\u30fc\u30ea\u30f3\u30b0 -dialog.gpsies.activity.skating=\u30d5\u30a3\u30ae\u30e5\u30a2\u30b9\u30b1\u30fc\u30c8 dialog.wikipedia.column.name=Wikipedia\u8a18\u4e8b\u540d dialog.wikipedia.column.distance=\u8ddd\u96e2 dialog.correlate.notimestamps=\u30c7\u30fc\u30bf\u30dd\u30a4\u30f3\u30c8\u306b\u306f\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u304c\u306a\u3044\u306e\u3067\u3001\u5199\u771f\u3092\u95a2\u9023\u4ed8\u3051\u3089\u308c\u308b\u7269\u304c\u3042\u308a\u307e\u305b\u3093\u3002 @@ -369,24 +355,9 @@ dialog.keys.intro=\u30de\u30a6\u30b9\u306e\u4ee3\u308f\u308a\u306b\u6b21\u306e\u dialog.keys.keylist=
\u77e2\u5370\u30ad\u30fc\u5730\u56f3\u3092\u4e0a\u4e0b\u5de6\u53f3\u306b\u79fb\u52d5
Ctrl + \u5de6\u30fb\u53f3\u77e2\u5370\u524d\u30fb\u6b21\u306e\u70b9\u3092\u9078\u629e
Ctrl + \u4e0a\u30fb\u4e0b\u77e2\u5370\u62e1\u5927\u30fb\u7e2e\u5c0f
Del\u73fe\u5728\u306e\u70b9\u3092\u524a\u9664
dialog.keys.normalmodifier=Ctrl\u30ad\u30fc dialog.keys.macmodifier=Command\u30ad\u30fc -dialog.saveconfig.desc=\u4e0b\u8a18\u306e\u8a2d\u5b9a\u304c\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059 -dialog.saveconfig.prune.trackdirectory=\u30c8\u30e9\u30c3\u30af\u30c7\u30a3\u30ec\u30af\u30c8\u30ea -dialog.saveconfig.prune.photodirectory=\u5199\u771f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea -dialog.saveconfig.prune.languagecode=\u8a00\u8a9e\u30b3\u30fc\u30c9(JA) -dialog.saveconfig.prune.languagefile=\u8a00\u8a9e\u30d5\u30a1\u30a4\u30eb -dialog.saveconfig.prune.gpsdevice=GPS\u30c7\u30d0\u30a4\u30b9 -dialog.saveconfig.prune.gpsformat=GPS\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 -dialog.saveconfig.prune.povrayfont=Povray \u30d5\u30a9\u30f3\u30c8 -dialog.saveconfig.prune.gnuplotpath=gnuplot\u3078\u306e\u30d1\u30b9 -dialog.saveconfig.prune.gpsbabelpath=gpsbabel\u3078\u306e\u30d1\u30b9 -dialog.saveconfig.prune.exiftoolpath=exiftool\u3078\u306e\u30d1\u30b9 -dialog.saveconfig.prune.mapsource=\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9\u3092\u9078\u629e -dialog.saveconfig.prune.mapsourcelist=\u30de\u30c3\u30d7\u30fb\u30bd\u30fc\u30b9 -dialog.saveconfig.prune.diskcache=\u30de\u30c3\u30d7\u306e\u30ad\u30e3\u30c3\u30b7\u30e5 -dialog.saveconfig.prune.kmzimagewidth=KML \u753b\u50cf\u5e45 -dialog.saveconfig.prune.colourscheme=\u8272\u306e\u30b9\u30ad\u30fc\u30e0 -dialog.saveconfig.prune.linewidth=\u7dda\u306e\u5e45 -dialog.saveconfig.prune.kmltrackcolour=KML \u30c8\u30e9\u30c3\u30af\u306e\u8272 +dialog.paths.prune.gnuplotpath=gnuplot\u3078\u306e\u30d1\u30b9 +dialog.paths.prune.gpsbabelpath=gpsbabel\u3078\u306e\u30d1\u30b9 +dialog.paths.prune.exiftoolpath=exiftool\u3078\u306e\u30d1\u30b9 dialog.setpaths.intro=\u5fc5\u8981\u306a\u3089\u3001\u5916\u90e8\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30d1\u30b9\u3092\u9078\u3076\u4e8b\u304c\u3067\u304d\u307e\u3059 dialog.addaltitude.noaltitudes=\u9078\u629e\u7bc4\u56f2\u306f\u3001\u9ad8\u5ea6\u3092\u542b\u3093\u3067\u307e\u305b\u3093\u3002 dialog.addaltitude.desc=\u52a0\u3048\u305f\u9ad8\u5ea6\u504f\u4f4d @@ -475,7 +446,6 @@ button.selectall=\u5168\u9078\u629e button.selectnone=\u9078\u629e\u89e3\u9664 button.preview=\u30d7\u30ec\u30d3\u30e5\u30fc button.load=\u8aad\u307f\u8fbc\u307f -button.upload=\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 button.guessfields=\u30d5\u30a3\u30fc\u30eb\u30c9\u4e88\u6e2c button.showwebpage=\u30a6\u30a7\u30d6\u30da\u30fc\u30b8\u3092\u8868\u793a button.check=\u691c\u67fb diff --git a/src/tim/prune/lang/prune-texts_ko.properties b/src/tim/prune/lang/prune-texts_ko.properties index b748f07..75332e4 100644 --- a/src/tim/prune/lang/prune-texts_ko.properties +++ b/src/tim/prune/lang/prune-texts_ko.properties @@ -88,11 +88,8 @@ function.pastecoordinates=\uc0c8 \uc88c\ud45c \ub123\uae30 function.charts=\ucc28\ud2b8 function.show3d=3\ucc28\uc6d0 \ubcf4\uae30 function.distances=\uac70\ub9ac -function.fullrangedetails=\uc5f0\uacb0\uc120 \uc0c1\uc138 \uc815\ubcf4 \ubcf4\uae30 function.setmapbg=\ubc30\uacbd \uc9c0\ub3c4 \uc9c0\uc815 function.setpaths=\uc678\ubd80\ud504\ub85c\uadf8\ub7a8 \uc9c0\uc815 -function.getgpsies=gpsies\uc5d0\uc11c \ud2b8\ub799\ubaa9\ub85d \uc5bb\uae30 -function.uploadgpsies=gpsies\ub85c \ud2b8\ub799 \uc62c\ub9ac\uae30 function.lookupsrtm=SRTM\uc5d0\uc11c \uace0\ub3c4 \ucc3e\uae30 function.getwikipedia=\uc704\ud0a4\ud53c\ub514\uc544\uc5d0\uc11c \uadfc\ucc98 \uc815\ubcf4 \ucc3e\uae30 function.searchwikipedianames=\uc774\ub984\uc73c\ub85c \uc704\ud0a4\ud53c\ub514\uc544 \uac80\uc0c9 @@ -263,19 +260,6 @@ dialog.gpsies.column.length=\uae38\uc774 dialog.gpsies.description=\uc124\uba85 dialog.gpsies.nodescription=\uc124\uba85 \uc5c6\uc74c dialog.gpsies.nonefound=\ud2b8\ub799\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc74c -dialog.gpsies.username=Gpsies username -dialog.gpsies.password=Gpsies \ube44\ubc00\ubc88\ud638 -dialog.gpsies.keepprivate=\ud2b8\ub799 \uac1c\uc778\uc815\ubcf4\ubcf4\ud638 -dialog.gpsies.confirmopenpage=\uc5c5\ub85c\ub4dc\ud55c \ud2b8\ub799\uc744 \uc6f9\ud398\uc774\uc9c0\uc5d0\uc11c \ubcf4\uc2dc\uaca0\uc5b4\uc694? -dialog.gpsies.activities=\ud65c\ub3d9 \ud615\ud0dc -dialog.gpsies.activity.trekking=\ub3c4\ubcf4\uc5ec\ud589 -dialog.gpsies.activity.walking=\uac77\uae30 -dialog.gpsies.activity.jogging=\ub2ec\ub9ac\uae30 -dialog.gpsies.activity.biking=\uc790\uc804\uac70\ud0c0\uae30 -dialog.gpsies.activity.motorbiking=\uc624\ud1a0\ubc14\uc774\ud0c0\uae30 -dialog.gpsies.activity.snowshoe=\ub208\uae38\uac77\uae30 -dialog.gpsies.activity.sailing=\ubc30\ud0c0\uae30 -dialog.gpsies.activity.skating=\uc2a4\ucf00\uc774\ud2b8\ud0c0\uae30 dialog.wikipedia.column.name=\uac8c\uc2dc\ubb3c \uc774\ub984 dialog.wikipedia.column.distance=\uac70\ub9ac dialog.correlate.notimestamps=\uc9c0\uc810 \ub370\uc774\ud130\uc5d0 \uc2dc\uac04\uc815\ubcf4\uac00 \uc5c6\uc5b4\uc11c \uc0ac\uc9c4\uc744 \uc5f0\uacb0 \ud560 \uc218 \uc5c6\uc5b4\uc694. @@ -368,24 +352,9 @@ dialog.keys.intro=\ub9c8\uc6b0\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \ub9c8\uc2dc dialog.keys.keylist=
\ud654\uc0b4\ud45c \ud0a4\uc88c,\uc6b0,\uc544\ub798,\uc704\ub85c \uc9c0\ub3c4 \uc774\ub3d9
Ctrl + \uc67c\ucabd, \uc624\ub978\ucabd \ud654\uc0b4\ud45c\uc9c0\uc810 \uc120\ud0dd \uc774\ub3d9
Ctrl + \uc704, \uc544\ub798 \ud654\uc0b4\ud45c\uc9c0\ub3c4 \ud655\ub300 \ucd95\uc18c
Ctrl + PgUp, PgDown\uc774\uc804 \uc774\ud6c4 \ubd80\ubd84 \uc120\ud0dd
Ctrl + Home, End\ucc98\uc74c \uc9c0\uc810, \ub9c8\uc9c0\ub9c9 \uc9c0\uc810 \uc120\ud0dd
Del\ud604\uc7ac \uc9c0\uc810 \uc0ad\uc81c
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=\uc544\ub798 \uc124\uc815\ub4e4\uc740 \uc124\uc815\ud30c\uc77c\uc5d0 \uc800\uc7a5\ud560 \uc218 \uc788\uc5b4\uc694: -dialog.saveconfig.prune.trackdirectory=\ud2b8\ub809 \ud3f4\ub354 -dialog.saveconfig.prune.photodirectory=\uc0ac\uc9c4 \ud3f4\ub354 -dialog.saveconfig.prune.languagecode=\uc5b8\uc5b4\ucf54\ub4dc (KO) -dialog.saveconfig.prune.languagefile=\uc5b8\uc5b4\ud30c\uc77c -dialog.saveconfig.prune.gpsdevice=GPS\uc7a5\uce58 -dialog.saveconfig.prune.gpsformat=GPS \ud615\uc2dd -dialog.saveconfig.prune.povrayfont=Povray \uae00\uaf34 -dialog.saveconfig.prune.gnuplotpath=gnjuplot \uacbd\ub85c -dialog.saveconfig.prune.gpsbabelpath=gpsbabel \uacbd\ub85c -dialog.saveconfig.prune.exiftoolpath=exiftool \uacbd\ub85c -dialog.saveconfig.prune.mapsource=\uc120\ud0dd\ub41c \uc9c0\ub3c4 \uc704\uce58 -dialog.saveconfig.prune.mapsourcelist=\uc9c0\ub3c4 \uc18c\uc2a4 -dialog.saveconfig.prune.diskcache=\uc9c0\ub3c4 \uce90\uc2dc -dialog.saveconfig.prune.kmzimagewidth=KMZ \uc774\ubbf8\uc9c0 \ub113\uc774 -dialog.saveconfig.prune.colourscheme=\uc0c9 \uad6c\uc131 -dialog.saveconfig.prune.linewidth=\ud2b8\ub799\uc120 \ub450\uaed8 -dialog.saveconfig.prune.kmltrackcolour=KML \ud2b8\ub799 \uc0c9 +dialog.paths.prune.gnuplotpath=gnjuplot \uacbd\ub85c +dialog.paths.prune.gpsbabelpath=gpsbabel \uacbd\ub85c +dialog.paths.prune.exiftoolpath=exiftool \uacbd\ub85c dialog.setpaths.intro=\uc678\ubd80 \ud504\ub85c\uadf8\ub7a8\uc758 \uacbd\ub85c\ub97c \uc120\ud0dd\ud560 \uc218 \uc788\uc5b4\uc694. dialog.setpaths.found=\uacbd\ub85c\ub97c \ucc3e\uc73c\uc168\ub098\uc694? dialog.addaltitude.noaltitudes=\uc120\ud0dd\ub41c \ubc94\uc704\uc5d0 \uace0\ub3c4\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\uc9c0 \uc54a\ub124\uc694. @@ -483,7 +452,6 @@ button.selectall=\uc804\ubd80\uc120\ud0dd button.selectnone=\uc544\ubb34\uac83\ub3c4 \uc120\ud0dd\ud558\uc9c0\uc54a\uae30 button.preview=\ubbf8\ub9ac\ubcf4\uae30 button.load=\ubd88\ub7ec\uc624\uae30 -button.upload=\uc62c\ub9ac\uae30 button.guessfields=\ucd94\uce21 \ud544\ub4dc button.showwebpage=\uc6f9\ud398\uc774\uc9c0 \ubcf4\uae30 button.check=\uccb4\ud06c diff --git a/src/tim/prune/lang/prune-texts_nl.properties b/src/tim/prune/lang/prune-texts_nl.properties index 2e0f727..cde8d6e 100644 --- a/src/tim/prune/lang/prune-texts_nl.properties +++ b/src/tim/prune/lang/prune-texts_nl.properties @@ -1,7 +1,7 @@ # Text entries for the GpsPrune application # Dutch entries thanks to Jeroen -# Menu entries +## Menu entries menu.file=Bestand menu.file.addphotos=Foto's toevoegen menu.file.recentfiles=Onlangs geopend @@ -12,7 +12,6 @@ menu.track=Route menu.track.undo=Ongedaan maken menu.track.clearundo=Ongedaan-maken lijst wissen menu.track.markrectangle=Makeer alle punten in een vierkant -function.deletemarked=Verwijderen gemarkeerde punten menu.range=Reeks menu.range.all=Selecteer alles menu.range.none=Selecteer geen @@ -36,12 +35,14 @@ menu.view.browser.openstreetmap=Openstreetmap menu.view.browser.mapquest=Mapquest menu.view.browser.yahoo=Yahoo maps menu.view.browser.bing=Bing maps +menu.view.browser.inlinemap=Inline kaart +menu.view.browser.graphhopper=GraphHopper menu.settings=Instellingen menu.settings.onlinemode=Kaarten van internet ophalen menu.settings.autosave=Automatisch opslaan bij afsluiten menu.help=Help -# Popup menu for map +## Popup menu for map menu.map.zoomin=Zoom + menu.map.zoomout=Zoom - menu.map.zoomfull=Zoom alles @@ -53,7 +54,7 @@ menu.map.showmap=Toon kaart menu.map.showscalebar=Toon schaal menu.map.editmode=Wijzigen -# Alt keys for menus +## Alt keys for menus altkey.menu.file=F altkey.menu.online=O altkey.menu.track=R @@ -65,7 +66,7 @@ altkey.menu.audio=A altkey.menu.settings=I altkey.menu.help=H -# Ctrl shortcuts for menu items +## Ctrl shortcuts for menu items shortcut.menu.file.open=O shortcut.menu.file.load=L shortcut.menu.file.save=S @@ -75,7 +76,7 @@ shortcut.menu.range.all=A shortcut.menu.point.edit=W shortcut.menu.help.help=H -# Functions +## Functions function.open=Open bestand function.importwithgpsbabel=Bestand importeren met GPSBabel function.loadfromgps=Gegevens lezen van GPS @@ -86,6 +87,7 @@ function.exportpov=Export POV function.exportimage=Bestand exporteren function.editwaypointname=Hernoem waypoint function.compress=Route comprimeren +function.deletemarked=Verwijderen gemarkeerde punten function.marklifts=Markeer opgaande liften function.deleterange=Verwijder reeks function.croptrack=Route bijknippen @@ -98,10 +100,12 @@ function.convertnamestotimes=Converteer waypointnamen naar tijden function.deletefieldvalues=Verwijder veldwaarden function.findwaypoint=Zoek waypoint function.pastecoordinates=Nieuwe co\u00f6rdinaten ingeven +function.pastecoordinatelist=Lijst met co\u00f6rdinaten invoeren +function.enterpluscode=Pluscode invoeren function.charts=Diagram function.show3d=3D beeld function.distances=Afstanden -function.fullrangedetails=Reeks details +function.viewfulldetails=Alle details function.estimatetime=Geschatte tijd function.learnestimationparams=Parameters voor geschatte tijd function.autoplay=Route automatisch afspelen @@ -111,8 +115,6 @@ function.selectsegment=Selecteer huidige segment function.splitsegments=Splits route in segmenten function.sewsegments=Voeg segmenten samen function.createmarkerwaypoints=aak waypoints voor markering -function.getgpsies=Routes van Gpsies ophalen -function.uploadgpsies=Upload routes naar Gpsies function.lookupsrtm=Hoogtes van SRTM ophalen function.downloadsrtm=Downloaden SRTM tegels function.getwikipedia=Wikipedia artikelen uit de buurt ophalen @@ -122,6 +124,7 @@ function.searchopencachingde=Doorzoek OpenCaching.de function.mapillary=Zoek naar foto's op Mapillary function.downloadosm=Downloaden OSM data voor gebied function.duplicatepoint=Dupliceer punt +function.projectpoint=Bereken punt function.setcolours=Instellen kleuren function.setdisplaysettings=Instellen afbeeldingopties function.setlanguage=Instellen taal @@ -150,7 +153,7 @@ function.getweatherforecast=Ophalen weersvoorspelling function.setaltitudetolerance=Instellen hoogtetolerantie function.selecttimezone=Instellen tijdzone -# Dialogs +## Dialogs dialog.exit.confirm.title=GpsPrune afsluiten dialog.exit.confirm.text=Uw data is niet opgeslagen. Weet u zeker dat u wilt afsluiten? dialog.openappend.title=Toevoegen aan bestaande data @@ -368,19 +371,6 @@ dialog.gpsies.column.length=Lengte dialog.gpsies.description=Omschrijving dialog.gpsies.nodescription=Geen omschrivjing dialog.gpsies.nonefound=Geen routes gevonden -dialog.gpsies.username=Gpsies gebruikersnaam -dialog.gpsies.password=Gpsies wachtwoord -dialog.gpsies.keepprivate=Houd route priv\u00e9 -dialog.gpsies.confirmopenpage=Webpagina van de ge\u00fcploade route openen? -dialog.gpsies.activities=Aktiviteit -dialog.gpsies.activity.trekking=Trekking -dialog.gpsies.activity.walking=Lopen -dialog.gpsies.activity.jogging=Hardlopen -dialog.gpsies.activity.biking=Fietsen -dialog.gpsies.activity.motorbiking=Motorrijden -dialog.gpsies.activity.snowshoe=Sneeuwschoen-lopen -dialog.gpsies.activity.sailing=Zeilen -dialog.gpsies.activity.skating=Skating dialog.mapillary.nonefound=Geen foto's gevonden dialog.wikipedia.column.name=Artikelnaam dialog.wikipedia.column.distance=Afstand @@ -448,6 +438,10 @@ dialog.deletemarked.nonefound=Er konden geen punten verwijderd worden dialog.pastecoordinates.desc=Geef co\u00f6rdinaten in dialog.pastecoordinates.coords=Co\u00f6rdinaten dialog.pastecoordinates.nothingfound=Controleer de co\u00f6rdinaten en probeer het nogmaals +dialog.pastecoordinatelist.desc=Geef de co\u00f6rdinaten voor nieuwe punten met \u00e9\u00e9n punt per regel +dialog.pluscode.desc=Type of plak hier de pluscode +dialog.pluscode.code=Pluscode +dialog.pluscode.nothingfound=Controleer de code en probeer het nogmaals dialog.help.help=Ga naar\n https://gpsprune.activityworkshop.net/\nvoor meer informatie en handleidingen. dialog.about.version=Versie dialog.about.build=Build @@ -461,9 +455,9 @@ dialog.about.systeminfo.os=Besturingssysteem dialog.about.systeminfo.java=Java Runtime dialog.about.systeminfo.java3d=Java3d ge\u00efnstalleerd dialog.about.systeminfo.povray=Povray ge\u00efnstalleerd -dialog.about.systeminfo.exiftool=Exiftool ge\u00efnstalleer -dialog.about.systeminfo.gpsbabel=Gpsbabel ge\u00efnstalleer -dialog.about.systeminfo.gnuplot=Gnuplot ge\u00efnstalleer +dialog.about.systeminfo.exiftool=Exiftool ge\u00efnstalleerd +dialog.about.systeminfo.gpsbabel=Gpsbabel ge\u00efnstalleerd +dialog.about.systeminfo.gnuplot=Gnuplot ge\u00efnstalleerd dialog.about.yes=Ja dialog.about.no=Nee dialog.about.credits=Credits @@ -487,25 +481,9 @@ dialog.keys.intro=De volgende sneltoetsen vervangen muisacties dialog.keys.keylist=
Pijltjestoetsenverschuif de kaart links, rechts, omhoog, omlaag
Ctrl + pijltje naar links, rechtsSelecteer volgende, vorige punt
Ctrl + pijltje omhoog, omlaagZoom in of uit
Ctrl + PgUp, PgDownSelecteer vorig, volgend segment
Ctrl + Home, EndSelect eerste, laatste punt
DelVerwijder huidige punt
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=De volgende instellingen kunnen worden opgeslagen in een configuratiebestand: -dialog.saveconfig.prune.trackdirectory=Route map -dialog.saveconfig.prune.photodirectory=Foto map -dialog.saveconfig.prune.languagecode=Taalcode (NL) -dialog.saveconfig.prune.languagefile=Taal bestand -dialog.saveconfig.prune.gpsdevice=GPS apparaat -dialog.saveconfig.prune.gpsformat=GPS formaat -dialog.saveconfig.prune.povrayfont=Povray lettertype -dialog.saveconfig.prune.gnuplotpath=Pad naar gnuplot -dialog.saveconfig.prune.gpsbabelpath=Pad naar gpsbabel -dialog.saveconfig.prune.exiftoolpath=Pad naar exiftool -dialog.saveconfig.prune.mapsource=Geselecteerde kaartbron -dialog.saveconfig.prune.mapsourcelist=Kaartbronnen -dialog.saveconfig.prune.diskcache=Kaartcache -dialog.saveconfig.prune.kmzimagewidth=KMZ afbeelding breedte -dialog.saveconfig.prune.colourscheme=Kleurenschema -dialog.saveconfig.prune.linewidth=Lijndikte -dialog.saveconfig.prune.kmltrackcolour=KML routekleur -dialog.saveconfig.prune.autosavesettings=Instellingen automatisch opslaan +dialog.paths.prune.gnuplotpath=Pad naar gnuplot +dialog.paths.prune.gpsbabelpath=Pad naar gpsbabel +dialog.paths.prune.exiftoolpath=Pad naar exiftool dialog.setpaths.intro=Indien nodig kan je de paden naar externe applicaties kiezen: dialog.setpaths.found=Pad gevonden? dialog.addaltitude.noaltitudes=De geselecteerde reeks bevat geen hoogtes @@ -572,6 +550,9 @@ dialog.displaysettings.wpicon.pin=Punaise dialog.displaysettings.size.small=Klein dialog.displaysettings.size.medium=Middel dialog.displaysettings.size.large=Groot +dialog.displaysettings.windowstyle=Windows stijl (herstart nodig) +dialog.displaysettings.windowstyle.default=Standaard +dialog.displaysettings.windowstyle.nimbus=Nimbus dialog.downloadosm.desc=Bevestig het downloaden van ruwe OSM data voor dit gebied: dialog.searchwikipedianames.search=Zoeken naar: dialog.weather.location=Locatie @@ -614,12 +595,18 @@ dialog.autoplay.usetimestamps=Gebruik tijdinfo van punt dialog.autoplay.rewind=Terug naar begin dialog.autoplay.pause=Pauze dialog.autoplay.play=Afspelen +dialog.markers.halves=Punt op halve afstand +dialog.markers.half.distance=Halve afstand +dialog.markers.half.climb=Halve klim +dialog.markers.half.descent=Halve afdaling +dialog.projectpoint.desc=Geef de richting en afstand om dit punt te berekenen +dialog.projectpoint.bearing=Richting (graden Noord) -# 3d window +## 3d window dialog.3d.title=GpsPrune in 3D dialog.3d.altitudefactor=Hoogte overdrijvingsfactor -# Confirm messages +## Confirm messages confirm.loadfile=Data van schijf geladen confirm.save.ok1=Succesvol opgeslagen confirm.save.ok2=Punten naar bestand @@ -635,7 +622,7 @@ confirm.rearrangephotos=Foto herschikt confirm.splitsegments=Er zijn %d opdelingen gemaakt confirm.sewsegments=Er zijn %d samenvoegingen gemaakt confirm.cutandmove=Selectie verplaatst -confirm.interpolate=Punten toegevoegd +confirm.pointsadded=%d punten toegevoegd confirm.convertnamestotimes=Namen waypoint geconverteerd confirm.saveexif.ok=Opgeslagen %d foto bestanden confirm.undo.single=Actie geannuleerd @@ -660,7 +647,7 @@ confirm.audioload=Audiobestanden toegevoegd confirm.correlateaudios.single=audiobestand gecorreleerd confirm.correlateaudios.multi=audiobestanden gecorreleerd -# Tips, shown just once when appropriate +## Tips, shown just once when appropriate tip.title=Tip tip.useamapcache=Door het instellen van een schijfcache (Instellingen -> Kaart opslaan op schijf)\nkan je de afbeeldsnelheid verbeteren en het netwerkverkeer verminderen. tip.learntimeparams=De resultaten zullen nauwkeuriger zijn als je \nRoute -> Parameters voor geschatte tijd\ngebruikt op je opgenomen routes. @@ -668,7 +655,7 @@ tip.downloadsrtm=Je kan dit versnellen door hier\nOnline -> Download SRTM tegels tip.usesrtmfor3d=Deze route heeft geen hoogten.\nJe kan de SRTM functies gebruiken om een geschatte hoogte\nop te halen voor het 3d beeld. tip.manuallycorrelateone=Door handmatig een foto te koppelen kan het tijdsverschil voor u berekend worden. -# Buttons +## Buttons button.ok=OK button.back=Terug button.next=Volgende @@ -691,7 +678,6 @@ button.selectall=Selecteer alles button.selectnone=Selecteer niets button.preview=Voorbeeld button.load=Laden -button.upload=Upload button.guessfields=Raad velden button.showwebpage=Toon webpagina button.check=Controleren @@ -702,7 +688,7 @@ button.delete=Verwijderen button.manage=Beheer button.combine=Samenvoegen -# File types +## File types filetype.txt=TXT bestand filetype.jpeg=JPG bestand filetype.kmlkmz=KML, KMZ bestand @@ -714,7 +700,7 @@ filetype.svg=SVG bestand filetype.png=PNG bestand filetype.audio=MP3, OGG, WAV bestanden -# Display components +## Display components display.nodata=Geen gegevens geladen display.noaltitudes=Route gegevens bevatten geen hoogte display.notimestamps=Route gegevens bevatten geen tijdinformatie @@ -762,9 +748,10 @@ details.audio.file=Audiobestand details.audio.playing=Afspelen... map.overzoom=Geen kaarten beschikbaar op dit zoom-niveau -# Field names +## Field names fieldname.latitude=Breedtegraad fieldname.longitude=Lengtegraad +fieldname.coordinates=Co\u00f6rdinaten fieldname.altitude=Hoogte fieldname.timestamp=Tijd fieldname.time=Tijd @@ -779,9 +766,10 @@ fieldname.duration=Duur fieldname.speed=Snelheid fieldname.verticalspeed=Verticale snelheid fieldname.description=Omschrijving +fieldname.comment=Commentaar fieldname.mediafilename=Bestandsnaam -# Measurement units +## Measurement units units.original=Oorspronkelijke units.default=Default units.metres=Meters @@ -815,24 +803,24 @@ units.degreescelsius.short=\u00baC units.degreesfahrenheit=Fahrenheit units.degreesfahrenheit.short=\u00baF -# How to combine conditions, such as filters +## How to combine conditions, such as filters logic.and=en logic.or=of -# External urls and services +## External urls and services url.googlemaps=maps.google.nl wikipedia.lang=nl openweathermap.lang=nl webservice.peakfinder=Open Peakfinder.org webservice.geohack=Open Geohack pagina -# Cardinals for 3d plots +## Cardinals for 3d plots cardinal.n=N cardinal.s=Z cardinal.e=O cardinal.w=W -# Undo operations +## Undo operations undo.load=gegevens laden undo.loadphotos=foto's laden undo.loadaudios=audiobestanden laden @@ -863,7 +851,7 @@ undo.lookupsrtm=opzoeken hoogtes in SRTM undo.deletefieldvalues=verwijder veldwaarden undo.correlateaudios=correleer audiobestanden -# Error messages +## Error messages error.save.dialogtitle=Fout bij opslaan gegevens error.save.nodata=Geen gegevens om op te slaan error.save.failed=Kon de gegevens niet naar bestand wegschrijven @@ -878,6 +866,7 @@ error.load.nopoints=Geen co\u00f6rdinaat informatie gevonden in bestand error.load.unknownxml=Onbekend xml-formaat: error.load.noxmlinzip=Geen xml-bestand gevonden in zipbestand error.load.othererror=Fout bij lezen bestand: +error.load.nopointsintext=Geen co\u00f6rdinaten informatie gevonden error.jpegload.dialogtitle=Fout bij inlezen foto's error.jpegload.nofilesfound=Bestanden niet gevonden error.jpegload.nojpegsfound=Geen jpeg-bestanden gevonden diff --git a/src/tim/prune/lang/prune-texts_no.properties b/src/tim/prune/lang/prune-texts_no.properties index c90acb7..86aac6f 100644 --- a/src/tim/prune/lang/prune-texts_no.properties +++ b/src/tim/prune/lang/prune-texts_no.properties @@ -99,7 +99,7 @@ function.pastecoordinates=Legg til nye koordinater function.charts=Grafer function.show3d=3-D visning function.distances=Avstander -function.fullrangedetails=Vis alle detaljer +function.viewfulldetails=Vis alle detaljer function.estimatetime= function.learnestimationparams= function.setmapbg=Velg grunnlagskart @@ -107,8 +107,6 @@ function.setpaths=Angi plassering av programmer function.selectsegment= function.splitsegments= function.sewsegments= -function.getgpsies=Vis spor fra gpsies.com -function.uploadgpsies=Last opp spor til gpsies.com function.lookupsrtm=Hent h\u00f8yde fra SRTM function.downloadsrtm= function.getwikipedia=Vis Wikipedia info for omegn diff --git a/src/tim/prune/lang/prune-texts_pl.properties b/src/tim/prune/lang/prune-texts_pl.properties index eb0a727..d3b72e7 100644 --- a/src/tim/prune/lang/prune-texts_pl.properties +++ b/src/tim/prune/lang/prune-texts_pl.properties @@ -100,7 +100,7 @@ function.pastecoordinates=Wprowad\u017a nowe wsp\u00f3\u0142rz\u0119dne function.charts=Wykres function.show3d=Poka\u017c model 3D function.distances=Odleg\u0142o\u015bci -function.fullrangedetails=Wszystkie detale +function.viewfulldetails=Wszystkie detale function.estimatetime=Przewidywany czas function.learnestimationparams=Skoryguj wsp\u00f3\u0142czynniki szacowania czasu function.autoplay=Gra\u0107 \u015bcie\u017ck\u0119 @@ -110,8 +110,6 @@ function.selectsegment=Wybierz bie\u017c\u0105cy fragment function.splitsegments=Podziel \u015bcie\u017ck\u0119 na fragmenty function.sewsegments=Po\u0142\u0105cz fragmenty function.createmarkerwaypoints=Stw\u00f3rz markery podzia\u0142u -function.getgpsies=Pobierz \u015bcie\u017cki z Gpsies -function.uploadgpsies=Wy\u015blij \u015bcie\u017cki do Gpsies function.lookupsrtm=Pobierz wysoko\u015bci z SRTM function.downloadsrtm=Zapisz dane z SRTM function.getwikipedia=Szukaj w Wikipedii o okolicy @@ -366,19 +364,6 @@ dialog.gpsies.column.length=D\u0142ugo\u015b\u0107 dialog.gpsies.description=Opis dialog.gpsies.nodescription=Brak opisu dialog.gpsies.nonefound=Nie znalaz\u0142em \u015bcie\u017cek -dialog.gpsies.username=nazwa u\u017cytkownika w Gpsies -dialog.gpsies.password=has\u0142o u\u017cytkownika w Gpsies -dialog.gpsies.keepprivate=Zaznacz \u015bcie\u017cki jako prywatne -dialog.gpsies.confirmopenpage=Otw\u00f3rz stron\u0119 z za\u0142adowan\u0105 \u015bcie\u017ck\u0105 -dialog.gpsies.activities=Aktywno\u015b\u0107 -dialog.gpsies.activity.trekking=W\u0119drowa\u0107 -dialog.gpsies.activity.walking=Spacer -dialog.gpsies.activity.jogging=Bieganie -dialog.gpsies.activity.biking=Wycieczka rowerowa -dialog.gpsies.activity.motorbiking=Wycieczka motocyklowa -dialog.gpsies.activity.snowshoe=Snowshoeing -dialog.gpsies.activity.sailing=\u017beglarstwo -dialog.gpsies.activity.skating=Wrotki/rolki dialog.mapillary.nonefound=Nic nie zosta\u0142o znalezione dialog.wikipedia.column.name=Tytu\u0142 artyku\u0142u dialog.wikipedia.column.distance=Odleg\u0142o\u015b\u0107 @@ -483,25 +468,9 @@ dialog.keys.intro=U\u017cuwaj nast\u0119puj\u0105cych klawiszy skr\u00f3t\u00f3w dialog.keys.keylist=
klawisze strza\u0142ekPrzesuwa map\u0119 w lewo, w prawo, w g\u00f3r\u0119, w d\u00f3\u0142
Ctrl + lewa, prawa strza\u0142kaWybierz punkt poprzedni lub nast\u0119pny
Ctrl + strza\u0142ka w g\u00f3r\u0119, w d\u00f3\u0142Powi\u0119ksz, pomniejsz
DelUsun bie\u017c\u0105cy punkt
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=Nast\u0119puj\u0105ce ustawienia mog\u0105 zosta\u0107 zapisane w pliku konfiguracyjnym: -dialog.saveconfig.prune.trackdirectory=Katalog ze \u015bcie\u017ckami -dialog.saveconfig.prune.photodirectory=Katalog ze zdj\u0119ciami -dialog.saveconfig.prune.languagecode=Kod j\u0119zyka (PL) -dialog.saveconfig.prune.languagefile=Plik t\u0142umaczenia -dialog.saveconfig.prune.gpsdevice=Urz\u0105dzenie GPS -dialog.saveconfig.prune.gpsformat=Format pliku GPS -dialog.saveconfig.prune.povrayfont=czcionka dla Povray-a -dialog.saveconfig.prune.gnuplotpath=\u015bcie\u017cka do gnuplot -dialog.saveconfig.prune.gpsbabelpath=\u015bcie\u017cka do gpsbabel -dialog.saveconfig.prune.exiftoolpath=\u015bcie\u017cka do exiftool -dialog.saveconfig.prune.mapsource=Wybrany dostawca map -dialog.saveconfig.prune.mapsourcelist=Dostawcy map -dialog.saveconfig.prune.diskcache=Pami\u0119\u0107 podr\u0119czna map -dialog.saveconfig.prune.kmzimagewidth=szeroko\u015b\u0107 obrazka w KMZ -dialog.saveconfig.prune.colourscheme=Schemat kolor\u00f3w -dialog.saveconfig.prune.linewidth=Szeroko\u015b\u0107 linii -dialog.saveconfig.prune.kmltrackcolour=Kolor \u015bcie\u017cki w pliku KML -dialog.saveconfig.prune.autosavesettings=ustawienia autozapisu +dialog.paths.prune.gnuplotpath=\u015bcie\u017cka do gnuplot +dialog.paths.prune.gpsbabelpath=\u015bcie\u017cka do gpsbabel +dialog.paths.prune.exiftoolpath=\u015bcie\u017cka do exiftool dialog.setpaths.intro=Je\u015bli zachodzi tak potrzeba, mo\u017cesz wybra\u0107 \u015bcie\u017cki do aplikacji zewn\u0119trznych dialog.setpaths.found=Znalezione \u015bcie\u017cki? dialog.addaltitude.noaltitudes=Wybrany zakres nie zawiera danych o wysoko\u015bciach @@ -620,7 +589,7 @@ confirm.rearrangephotos=Zmieniono kolejno\u015b\u0107 zdj\u0119\u0107 confirm.splitsegments=Podzielono na %d fragmenty/\u00f3w confirm.sewsegments=Po\u0142\u0105czono %d fragmenty/\u00f3w confirm.cutandmove=Przesuni\u0119to zaznaczenie -confirm.interpolate=Dodano punkty +confirm.pointsadded=Dodano %d punkty confirm.convertnamestotimes=Zmieniono nazwy punkt\u00f3w po\u015brednich confirm.saveexif.ok=Zapisano %d plik(\u00f3w) zdj\u0119\u0107 confirm.undo.single=cofni\u0119to operacj\u0119 @@ -676,7 +645,6 @@ button.selectall=Zaznacz wszystko button.selectnone=Odznacz button.preview=Podgl\u0105d button.load=\u0141aduj -button.upload=Wy\u015blij button.guessfields=Zgadnij pola button.showwebpage=Poka\u017c stron\u0119 web button.check=Sprawd\u017a diff --git a/src/tim/prune/lang/prune-texts_pt.properties b/src/tim/prune/lang/prune-texts_pt.properties index bab5623..fd785bf 100644 --- a/src/tim/prune/lang/prune-texts_pt.properties +++ b/src/tim/prune/lang/prune-texts_pt.properties @@ -99,7 +99,7 @@ function.pastecoordinates=Inserir novas coordenadas function.charts=Gr\u00e1ficos function.show3d=Visualizar 3D function.distances=Dist\u00e2ncias -function.fullrangedetails=Todos os detalhes +function.viewfulldetails=Todos os detalhes function.estimatetime=Tempo estimado function.learnestimationparams=Aprender os par\u00e2metros para estimativa de tempo function.setmapbg=Definir como fundo do mapa @@ -107,8 +107,6 @@ function.setpaths=Definir caminhos do programa function.selectsegment=Selecionar segmento atual function.splitsegments=Dividir rota em segmentos function.sewsegments=Reunir segmentos em rota -function.getgpsies=Obter rotas Gpsies -function.uploadgpsies=Enviar rotas para o Gpsies function.lookupsrtm=Obter altitudes a partir do SRTM function.downloadsrtm=Baixar arquivos SRTM function.getwikipedia=Obter artigos da Wikip\u00e9dia das redondezas @@ -360,19 +358,6 @@ dialog.gpsies.column.length=Extens\u00e3o dialog.gpsies.description=Descri\u00e7\u00e3o dialog.gpsies.nodescription=Sem descri\u00e7\u00e3o dialog.gpsies.nonefound=Nenhuma rota encontrada -dialog.gpsies.username=Nome do usu\u00e1rio Gpsies -dialog.gpsies.password=Senha do Gpsies -dialog.gpsies.keepprivate=Manter rota privada -dialog.gpsies.confirmopenpage=Abrir a p\u00e1gina para rotas enviadas? -dialog.gpsies.activities=Tipos de atividade -dialog.gpsies.activity.trekking=Trilha -dialog.gpsies.activity.walking=Caminhada -dialog.gpsies.activity.jogging=Corrida -dialog.gpsies.activity.biking=Ciclismo -dialog.gpsies.activity.motorbiking=Motocross -dialog.gpsies.activity.snowshoe=Snowshoeing -dialog.gpsies.activity.sailing=Sailing -dialog.gpsies.activity.skating=Patina\u00e7\u00e3o dialog.mapillary.nonefound=Nenhuma foto encontrada dialog.wikipedia.column.name=Nome do artigo dialog.wikipedia.column.distance=Dist\u00e2ncia @@ -473,25 +458,9 @@ dialog.keys.intro=Voc\u00ea pode usar os seguintes atalhos de teclado ao inv\u00 dialog.keys.keylist=
CursoresMove o mapa para esquerda, direita, acima e abaixo
Ctrl + cursores esquerdo e direitoSeleciona o pr\u00f3ximo ponto ou o anterior
Ctrl + cursores acima e abaixoAmplia ou reduz
DelRemove o ponto atual
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=As seguintes configura\u00e7\u00f5es podem ser salvas para um arquivo de configura\u00e7\u00e3o. -dialog.saveconfig.prune.trackdirectory=Pasta de rotas -dialog.saveconfig.prune.photodirectory=Pasta de fotos -dialog.saveconfig.prune.languagecode=C\u00f3digo do idioma (PT_BR) -dialog.saveconfig.prune.languagefile=Arquivo de idioma -dialog.saveconfig.prune.gpsdevice=Dispositivo de GPS -dialog.saveconfig.prune.gpsformat=Formato do GPS -dialog.saveconfig.prune.povrayfont=Fonte Povray -dialog.saveconfig.prune.gnuplotpath=Caminho para o gnuplot -dialog.saveconfig.prune.gpsbabelpath=Caminho para o gpsbabel -dialog.saveconfig.prune.exiftoolpath=Caminho para o exiftool -dialog.saveconfig.prune.mapsource=Selecionar fonte de mapas -dialog.saveconfig.prune.mapsourcelist=Fontes de mapas -dialog.saveconfig.prune.diskcache=Cache de mapas -dialog.saveconfig.prune.kmzimagewidth=Largura da imagem KMZ -dialog.saveconfig.prune.colourscheme=Esquema de cores -dialog.saveconfig.prune.linewidth=Espessura da linha -dialog.saveconfig.prune.kmltrackcolour=Cor da rota KML -dialog.saveconfig.prune.autosavesettings=Configura\u00e7\u00f5es para salvamento autom\u00e1tico +dialog.paths.prune.gnuplotpath=Caminho para o gnuplot +dialog.paths.prune.gpsbabelpath=Caminho para o gpsbabel +dialog.paths.prune.exiftoolpath=Caminho para o exiftool dialog.setpaths.intro=Se voc\u00ea precisar, voc\u00ea pode escolher os caminhos para as aplica\u00e7\u00f5es externas: dialog.setpaths.found=Caminho encontrado? dialog.addaltitude.noaltitudes=O intervalo selecionado n\u00e3o cont\u00e9m altitudes @@ -587,7 +556,7 @@ confirm.rearrangephotos=Fotos rearrumadas confirm.splitsegments=%d divis\u00f5es de segmentos feitas confirm.sewsegments=%d reuni\u00f5es de segmentos feitas confirm.cutandmove=Sele\u00e7\u00e3o movida -confirm.interpolate=Pontos adicionados +confirm.pointsadded=%d pontos adicionados confirm.convertnamestotimes=Nomes dos pontos convertidos confirm.saveexif.ok=Salvo %d arquivos de foto confirm.undo.single=opera\u00e7\u00e3o desfeita @@ -643,7 +612,6 @@ button.selectall=Selecionar todos button.selectnone=Selecionar nenhum button.preview=Previs\u00e3o button.load=Carregar -button.upload=Enviar button.guessfields=Campos adivinhados button.showwebpage=Mostrar p\u00e1gina Web button.check=Verificar diff --git a/src/tim/prune/lang/prune-texts_ro.properties b/src/tim/prune/lang/prune-texts_ro.properties index 9c62dbe..70ceab6 100644 --- a/src/tim/prune/lang/prune-texts_ro.properties +++ b/src/tim/prune/lang/prune-texts_ro.properties @@ -102,7 +102,7 @@ function.pastecoordinates=Introdu coordonate noi function.charts=Grafice function.show3d=Vizualizare 3D function.distances=Distan\u0163e -function.fullrangedetails=Informa\u0163ie complet\u0103 +function.viewfulldetails=Informa\u0163ie complet\u0103 function.estimatetime=Estimare durat\u0103 function.learnestimationparams=\u00cenva\u021b\u0103 parametri de estimare timpi function.autoplay=Parcurge traseu @@ -111,8 +111,6 @@ function.setpaths=Seteaz\u0103 calea c\u0103tre aplica\u021bii function.selectsegment=Selecteaz\u0103 segment curent function.splitsegments=Divizeaz\u0103 traseul \u00een segmente function.sewsegments=Combin\u0103 segmentele traseului -function.getgpsies=\u00cencarc\u0103 trasee Gpsies -function.uploadgpsies=Trimite date spre Gpsies function.lookupsrtm=Descarc\u0103 date SRTM \u00een cache function.downloadsrtm=Descarc\u0103 date SRTM function.getwikipedia=Caut\u0103 articole Wikipedia din proximitate @@ -365,19 +363,6 @@ dialog.gpsies.column.length=Lungime dialog.gpsies.description=Descriere dialog.gpsies.nodescription=F\u0103r\u0103 descriere dialog.gpsies.nonefound=Nu a fost g\u0103sit niciun traseu -dialog.gpsies.username=Gpsies username -dialog.gpsies.password=Gpsies parol\u0103 -dialog.gpsies.keepprivate=Traseu privat -dialog.gpsies.confirmopenpage=Deschid pagin\u0103 web pentru traseul \u00eenc\u0103rcat? -dialog.gpsies.activities=Activit\u0103\u0163i -dialog.gpsies.activity.trekking=Mers pe munte -dialog.gpsies.activity.walking=Mers pe jos -dialog.gpsies.activity.jogging=Alergare -dialog.gpsies.activity.biking=Biciclet\u0103 -dialog.gpsies.activity.motorbiking=Motociclet\u0103 -dialog.gpsies.activity.snowshoe=Mers cu rachete de z\u0103pad\u0103 -dialog.gpsies.activity.sailing=Navigare -dialog.gpsies.activity.skating=Role dialog.mapillary.nonefound=Nicio fotografie nu a fost g\u0103sit\u0103 dialog.wikipedia.column.name=Nume dialog.wikipedia.column.distance=Distan\u0163\u0103 @@ -481,25 +466,9 @@ dialog.keys.intro=Pute\u021bi folosi urm\u0103toarele scurt\u0103turi \u00een lo dialog.keys.keylist=
Taste s\u0103ge\u021biMut\u0103 harta st\u00e2nga, dreapta, sus, jos
Ctrl + s\u0103geat\u0103 st\u00e2nga, dreaptaSelecteaz\u0103 punctul anterior sau urm\u0103tor
Ctrl + s\u0103geat\u0103 sus, josAproprie sau \u00eendep\u0103rteaz\u0103
Ctrl + PgUp, PgDownSelecteaz\u0103 segmentul anterior sau urm\u0103tor
Ctrl + Home, EndSelecteaz\u0103 primul, ultimul punct
Del\u0218terge punctul curent
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=Urm\u0103toarele set\u0103ri pot fi salvate \u00eentr-un fi\u0219ier de configur\u0103ri : -dialog.saveconfig.prune.trackdirectory=Director trasee -dialog.saveconfig.prune.photodirectory=Director foto -dialog.saveconfig.prune.languagecode=Limb\u0103 (RO) -dialog.saveconfig.prune.languagefile=Fi\u015fier de limba -dialog.saveconfig.prune.gpsdevice=Dispozitiv GPS -dialog.saveconfig.prune.gpsformat=Format GPS -dialog.saveconfig.prune.povrayfont=Font Povray -dialog.saveconfig.prune.gnuplotpath=Calea c\u0103tre gnuplot -dialog.saveconfig.prune.gpsbabelpath=Calea c\u0103tre gpsbabel -dialog.saveconfig.prune.exiftoolpath=Calea c\u0103tre exiftool -dialog.saveconfig.prune.mapsource=Surs\u0103 hart\u0103 selectat\u0103 -dialog.saveconfig.prune.mapsourcelist=Surse hart\u0103 -dialog.saveconfig.prune.diskcache=Cache hart\u0103 -dialog.saveconfig.prune.kmzimagewidth=Dimensiuni imagini \u00een KMZ -dialog.saveconfig.prune.colourscheme=Schem\u0103 de culoare -dialog.saveconfig.prune.linewidth=Grosime linie -dialog.saveconfig.prune.kmltrackcolour=Culoar track KML -dialog.saveconfig.prune.autosavesettings=Set\u0103ri salv\u0103ri automate +dialog.paths.prune.gnuplotpath=Calea c\u0103tre gnuplot +dialog.paths.prune.gpsbabelpath=Calea c\u0103tre gpsbabel +dialog.paths.prune.exiftoolpath=Calea c\u0103tre exiftool dialog.setpaths.intro=Dac\u0103 dori\u021bi pute\u021bi alege calea c\u0103tre aplica\u021bii externe dialog.setpaths.found=Cale g\u0103sit\u0103? dialog.addaltitude.noaltitudes=Intervalul nu con\u021bine altitudini @@ -613,7 +582,7 @@ confirm.rearrangephotos=Fotografiile au fost rearanjate confirm.splitsegments=Au fost f\u0103cute %d diviz\u0103ri de segmente confirm.sewsegments=Au fost combinate %d segmente confirm.cutandmove=Selec\u021bia a fost mutat\u0103 -confirm.interpolate=Punctele au fost ad\u0103ugate +confirm.pointsadded=%d punctele au fost ad\u0103ugate confirm.convertnamestotimes=Numele waypoint-urile au fost convertite confirm.saveexif.ok=Au fost salvate %d fi\u0219iere foto confirm.undo.single=opera\u021bia a fost anulat\u0103 @@ -669,7 +638,6 @@ button.selectall=Selecteaz\u0103 tot button.selectnone=Deselecteaz\u0103 tot button.preview=Previzualizare button.load=Descarc\u0103 -button.upload=Trimite button.guessfields=Ghice\u0219te c\u00e2mpuri button.showwebpage=Deschide pagina web button.check=Verific\u0103 diff --git a/src/tim/prune/lang/prune-texts_ru.properties b/src/tim/prune/lang/prune-texts_ru.properties index ea4286b..6f99f0f 100644 --- a/src/tim/prune/lang/prune-texts_ru.properties +++ b/src/tim/prune/lang/prune-texts_ru.properties @@ -12,7 +12,6 @@ menu.track=\u0422\u0440\u0435\u043a menu.track.undo=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c menu.track.clearundo=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 menu.track.markrectangle=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0432 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435 -function.deletemarked=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 menu.range=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b menu.range.all=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 menu.range.none=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443 @@ -86,6 +85,7 @@ function.exportpov=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 POV function.exportimage=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u0301\u043d\u0438\u0435 function.editwaypointname=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 function.compress=\u0421\u0436\u0430\u0442\u044c \u0442\u0440\u0435\u043a +function.deletemarked=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 function.marklifts=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u044a\u0451\u043c\u043d\u0438\u043a\u0438 \u0432 \u0433\u043e\u0440\u0443 function.deleterange=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b function.croptrack=\u041e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0442\u0440\u0435\u043a @@ -98,10 +98,12 @@ function.convertnamestotimes=\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0 function.deletefieldvalues=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f function.findwaypoint=\u041d\u0430\u0439\u0442\u0438 \u043f\u0443\u0442\u0435\u0432\u0443\u044e \u0442\u043e\u0447\u043a\u0443 function.pastecoordinates=\u0412\u0432\u043e\u0434 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 +function.pastecoordinatelist=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 +function.enterpluscode=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 pluscode function.charts=\u0413\u0440\u0430\u0444\u0438\u043a\u0438 function.show3d=3D-\u0432\u0438\u0434 function.distances=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f -function.fullrangedetails=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0443 +function.viewfulldetails=\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f function.estimatetime=\u0421\u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0435\u043c\u044f function.learnestimationparams=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 function.autoplay=\u0410\u0432\u0442\u043e\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0430 @@ -111,8 +113,6 @@ function.selectsegment=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u function.splitsegments=\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b function.sewsegments=\u0421\u043a\u043b\u0435\u0438\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u043a\u0430 \u0432\u043e\u0435\u0434\u0438\u043d\u043e function.createmarkerwaypoints=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0430\u0440\u043a\u0435\u0440\u044b \u043f\u0443\u0442\u0435\u0432\u044b\u0445 \u0442\u043e\u0447\u0435\u043a -function.getgpsies=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0438 -function.uploadgpsies=\u0412\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u043d\u0430 gpsies.com function.lookupsrtm=\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0441\u043e\u0442\u0443 \u0438\u0437 SRTM function.downloadsrtm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c SRTM-\u0442\u0430\u0439\u043b\u044b function.getwikipedia=\u0421\u0442\u0430\u0442\u044c\u044f \u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u0412\u0438\u043a\u0438 @@ -122,6 +122,7 @@ function.searchopencachingde=\u041f\u043e\u0438\u0441\u043a \u0442\u0430\u0439\u function.mapillary=\u041f\u043e\u0438\u0441\u043a \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u0444\u043e\u0442\u043e function.downloadosm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c OSM \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\u044c function.duplicatepoint=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0442\u0440\u0435\u043a\u0430 +function.projectpoint=\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 function.setcolours=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430 function.setdisplaysettings=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f function.setlanguage=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u044f\u0437\u044b\u043a @@ -369,19 +370,6 @@ dialog.gpsies.column.length=\u0414\u043b\u0438\u043d\u0430 dialog.gpsies.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 dialog.gpsies.nodescription=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e dialog.gpsies.nonefound=\u0422\u0440\u0435\u043a\u043e\u0432 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e -dialog.gpsies.username=\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 Gpsies -dialog.gpsies.password=\u043f\u0430\u0440\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Gpsies -dialog.gpsies.keepprivate=\u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0442\u0440\u0435\u043a -dialog.gpsies.confirmopenpage=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0440\u0435\u043a\u0430 \u043d\u0430 \u0441\u0430\u0439\u0442 gpsies.com? -dialog.gpsies.activities=\u0422\u0438\u043f\u044b \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 -dialog.gpsies.activity.trekking=\u041f\u0435\u0448\u0438\u0439 \u0442\u0443\u0440\u0438\u0437\u043c -dialog.gpsies.activity.walking=\u0425\u043e\u0434\u044c\u0431\u0430 -dialog.gpsies.activity.jogging=\u0411\u0435\u0433 -dialog.gpsies.activity.biking=\u041d\u0430 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0435 -dialog.gpsies.activity.motorbiking=\u041d\u0430 \u043c\u043e\u0442\u043e\u0446\u0438\u043a\u043b\u0435 -dialog.gpsies.activity.snowshoe=\u041d\u0430 \u0441\u043d\u0435\u0433\u043e\u0441\u0442\u0443\u043f\u0430\u0445 -dialog.gpsies.activity.sailing=\u041f\u0430\u0440\u0443\u0441\u043d\u044b\u0439 \u0441\u043f\u043e\u0440\u0442 -dialog.gpsies.activity.skating=\u041d\u0430 \u043a\u043e\u043d\u044c\u043a\u0430\u0445 dialog.mapillary.nonefound=\u0424\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b dialog.wikipedia.column.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 dialog.wikipedia.column.distance=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 @@ -449,6 +437,9 @@ dialog.deletemarked.nonefound=\u041d\u0435\u0442 \u043f\u043e\u043c\u0435\u0447\ dialog.pastecoordinates.desc=\u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0437\u0434\u0435\u0441\u044c dialog.pastecoordinates.coords=\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b dialog.pastecoordinates.nothingfound=\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437 +dialog.pastecoordinatelist.desc=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0442\u043e\u0447\u0435\u043a \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043d\u0430 \u043f\u0440\u044f\u043c\u043e\u0439 +dialog.pluscode.desc=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043b\u0438 \u0432\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043b\u044e\u0441-\u043a\u043e\u0434 \u0437\u0434\u0435\u0441\u044c +dialog.pluscode.nothingfound=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043a\u043e\u0434 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437 dialog.help.help=\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443\nhttps://gpsprune.activityworkshop.net/ dialog.about.version=\u0412\u0435\u0440\u0441\u0438\u044f dialog.about.build=\u0420\u0435\u0432\u0438\u0437\u0438\u044f @@ -488,25 +479,9 @@ dialog.keys.intro=\u0412\u043c\u0435\u0441\u0442\u043e \u043c\u044b\u0448\u0438 dialog.keys.keylist=
\u0421\u0434\u0432\u0438\u0433 \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0435\u0432\u043e, \u0432\u043f\u0440\u0430\u0432\u043e, \u0432\u0432\u0435\u0440\u0445, \u0432\u043d\u0438\u0437
Ctrl + \u043b\u0435\u0432\u0430\u044f, \u043f\u0440\u0430\u0432\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443
Ctrl + \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u0432\u0435\u0440\u0445, \u0432\u043d\u0438\u0437 \u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430
Ctrl + PgUp, PgDown\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442
Ctrl + Home, End\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0435\u0440\u0432\u0443\u044e, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0442\u043e\u0447\u043a\u0443
Del\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0444\u0430\u0439\u043b: -dialog.saveconfig.prune.trackdirectory=\u041f\u0430\u043f\u043a\u0430 \u0441 \u0442\u0440\u0435\u043a\u0430\u043c\u0438 -dialog.saveconfig.prune.photodirectory=\u041f\u0430\u043f\u043a\u0430 \u0441 \u0444\u043e\u0442\u043e -dialog.saveconfig.prune.languagecode=\u041a\u043e\u0434 \u044f\u0437\u044b\u043a\u0430 (RU) -dialog.saveconfig.prune.languagefile=\u042f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u0444\u0430\u0439\u043b -dialog.saveconfig.prune.gpsdevice=GPS \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e -dialog.saveconfig.prune.gpsformat=GPS \u0444\u043e\u0440\u043c\u0430\u0442 -dialog.saveconfig.prune.povrayfont=Povray \u0448\u0440\u0438\u0444\u0442 -dialog.saveconfig.prune.gnuplotpath=\u041f\u0443\u0442\u044c \u043a GNUPLOT -dialog.saveconfig.prune.gpsbabelpath=\u041f\u0443\u0442\u044c \u043a GPSBabel -dialog.saveconfig.prune.exiftoolpath=\u041f\u0443\u0442\u044c \u043a ExifTool -dialog.saveconfig.prune.mapsource=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043a\u0430\u0440\u0442\u044b -dialog.saveconfig.prune.mapsourcelist=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043a\u0430\u0440\u0442 -dialog.saveconfig.prune.diskcache=\u041a\u0435\u0448 \u043a\u0430\u0440\u0442\u044b -dialog.saveconfig.prune.kmzimagewidth=\u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f KMZ -dialog.saveconfig.prune.colourscheme=\u0426\u0432\u0435\u0442\u043e\u0432\u0430\u044f \u0441\u0445\u0435\u043c\u0430 -dialog.saveconfig.prune.linewidth=\u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0438 -dialog.saveconfig.prune.kmltrackcolour=\u0446\u0432\u0435\u0442 \u0442\u0440\u0435\u043a\u0430 KML -dialog.saveconfig.prune.autosavesettings=\u0410\u0432\u0442\u043e\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043e\u043a +dialog.paths.prune.gnuplotpath=\u041f\u0443\u0442\u044c \u043a GNUPLOT +dialog.paths.prune.gpsbabelpath=\u041f\u0443\u0442\u044c \u043a GPSBabel +dialog.paths.prune.exiftoolpath=\u041f\u0443\u0442\u044c \u043a ExifTool dialog.setpaths.intro=\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c: dialog.setpaths.found=\u041f\u0443\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d? dialog.addaltitude.noaltitudes=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u044b\u0441\u043e\u0442 @@ -573,6 +548,8 @@ dialog.displaysettings.wpicon.pin=\u0417\u0430\u043a\u043e\u043b\u043a\u0430 dialog.displaysettings.size.small=\u041c\u0430\u043b\u044b\u0439 dialog.displaysettings.size.medium=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 dialog.displaysettings.size.large=\u0411\u043e\u043b\u044c\u0448\u043e\u0439 +dialog.displaysettings.windowstyle=\u0441\u0442\u0438\u043b\u044c \u043e\u043a\u043d\u0430 +dialog.displaysettings.windowstyle.default=\u0441\u0442\u0438\u043b\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e dialog.downloadosm.desc=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 OSM \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438: dialog.searchwikipedianames.search=\u041f\u043e\u0438\u0441\u043a \u0434\u043b\u044f: dialog.weather.location=\u041c\u0435\u0441\u0442\u043e @@ -615,6 +592,12 @@ dialog.autoplay.usetimestamps=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u dialog.autoplay.rewind=\u041d\u0430\u0437\u0430\u0434 dialog.autoplay.pause=\u0414\u0435\u0301\u043b\u0430\u0442\u044c \u043f\u0430\u0301\u0443\u0437\u0443 dialog.autoplay.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 +dialog.markers.halves=\u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 +dialog.markers.half.distance=\u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f +dialog.markers.half.climb=\u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u043f\u043e\u0434\u044a\u0451\u043c\u0430 +dialog.markers.half.descent=\u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0441\u043f\u0443\u0441\u043a\u0430 +dialog.projectpoint.desc=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u044d\u0442\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 +dialog.projectpoint.bearing=\u0430\u0437\u0438\u043c\u0443\u0442 (\u0433\u0440\u0430\u0434\u0443\u0441\u044b \u0441 \u0441\u0435\u0432\u0435\u0440\u0430) # 3d window dialog.3d.title=GpsPrune 3D-\u0432\u0438\u0434 @@ -636,7 +619,7 @@ confirm.rearrangephotos=\u0424\u043e\u0442\u043e \u043f\u0435\u0440\u0435\u0434\ confirm.splitsegments=\u0421\u0434\u0435\u043b\u0430\u043d\u043e %d \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b confirm.sewsegments=\u0421\u0434\u0435\u043b\u0430\u043d\u043e %d \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 confirm.cutandmove=\u041e\u0442\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u043e -confirm.interpolate=\u0422\u043e\u0447\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b +confirm.pointsadded=%d \u0422\u043e\u0447\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b confirm.convertnamestotimes=\u0418\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u043e confirm.saveexif.ok=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e %d \u0444\u0430\u0439\u043b\u044b \u0441 \u0444\u043e\u0442\u043e confirm.undo.single=\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u043c\u0435\u043d\u044b @@ -692,7 +675,6 @@ button.selectall=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 button.selectnone=\u041e\u0442\u043c\u0435\u043d\u0442\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443 button.preview=\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 button.load=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c -button.upload=\u0412\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c button.guessfields=\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u0435 \u043f\u043e\u043b\u044f button.showwebpage=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 button.check=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 @@ -766,6 +748,7 @@ map.overzoom=\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b # Field names fieldname.latitude=\u0428\u0438\u0440\u043e\u0442\u0430 fieldname.longitude=\u0414\u043e\u043b\u0433\u043e\u0442\u0430 +fieldname.coordinates=\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0301\u0442\u044b fieldname.altitude=\u0412\u044b\u0441\u043e\u0442\u0430 fieldname.timestamp=\u0412\u0440\u0435\u043c\u044f fieldname.time=\u0412\u0440\u0435\u043c\u044f @@ -780,6 +763,7 @@ fieldname.duration=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\ fieldname.speed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c fieldname.verticalspeed=\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c fieldname.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +fieldname.comment=\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0301\u0440\u0438\u0439 fieldname.mediafilename=\u0424\u0430\u0439\u043b # Measurement units @@ -879,6 +863,7 @@ error.load.nopoints=\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u04 error.load.unknownxml=\u041d\u0435\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 XML- \u0444\u043e\u0440\u043c\u0430\u0442: error.load.noxmlinzip=\u0412 zip-\u0430\u0440\u0445\u0438\u0432\u0435 \u043d\u0435\u0442 XML-\u0444\u0430\u0439\u043b\u0430 error.load.othererror=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u0430: +error.load.nopointsintext=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 error.jpegload.dialogtitle=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u043e\u0442\u043e error.jpegload.nofilesfound=\u0424\u0430\u0439\u043b\u044b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b error.jpegload.nojpegsfound=JPEG-\u0444\u0430\u0439\u043b\u044b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b diff --git a/src/tim/prune/lang/prune-texts_sv.properties b/src/tim/prune/lang/prune-texts_sv.properties index d149f98..e2115aa 100644 --- a/src/tim/prune/lang/prune-texts_sv.properties +++ b/src/tim/prune/lang/prune-texts_sv.properties @@ -100,7 +100,7 @@ function.pastecoordinates=Infoga koordinater function.charts=Diagram function.show3d=3D-vy function.distances=Avst\u00e5nd -function.fullrangedetails=Alla intevall-detaljer +function.viewfulldetails=Alla detaljer function.estimatetime=Uppskatta tid function.learnestimationparams=L\u00e4r upp tidsuppskattningsparametrar function.setmapbg=V\u00e4lj bakgrundskarta @@ -109,8 +109,6 @@ function.selectsegment=Markera aktuellt segment function.splitsegments=Dela upp sp\u00e5ret i segment function.sewsegments=Sy ihop sp\u00e5r-segment function.createmarkerwaypoints=Skapa markerings-waypoints -function.getgpsies=H\u00e4mta Gpsies-sp\u00e5r -function.uploadgpsies=Ladda upp sp\u00e5r till Gpsies function.lookupsrtm=H\u00e4mta h\u00f6jddata fr\u00e5n SRTM function.downloadsrtm=Ladda ner SRTM-h\u00f6jddata function.getwikipedia=H\u00e4mta n\u00e4rliggande Wikipedia-artiklar @@ -356,7 +354,6 @@ button.selectall=Markera alla button.selectnone=Markera inget button.preview=F\u00f6rhandsvisa button.load=Ladda in -button.upload=Ladda upp button.guessfields=Gissa f\u00e4lt button.showwebpage=Visa hemsida button.resettodefaults=\u00c5terst\u00e4ll till default diff --git a/src/tim/prune/lang/prune-texts_tr.properties b/src/tim/prune/lang/prune-texts_tr.properties index 998c112..72a718f 100644 --- a/src/tim/prune/lang/prune-texts_tr.properties +++ b/src/tim/prune/lang/prune-texts_tr.properties @@ -85,10 +85,8 @@ function.pastecoordinates=Yeni korrdinatlar gir function.charts=Krokiler function.show3d=3B g\u00fcr\u00fcnt\u00fcs\u00fc function.distances=Uzakl\u0131klar -function.fullrangedetails=S\u0131ran\u0131n b\u00fct\u00fcn ayr\u0131nt\u0131lar function.setmapbg=Arkafonun haritas\u0131 se\u00e7 function.setpaths=Uygulamalar\u0131n yollar\u0131 ayarla -function.getgpsies=Gpsies.com'dan yolu al function.duplicatepoint=Noktay\u0131 kopyala function.setcolours=Renkleri ayarla function.setlanguage=Dil se\u00e7 @@ -213,13 +211,6 @@ dialog.gpsies.column.length=Uzunlu\u011fu dialog.gpsies.description=A\u00e7\u0131klama dialog.gpsies.nodescription=A\u00e7\u0131klama yok dialog.gpsies.nonefound=Herhangi bir yol bulunmad\u0131 -dialog.gpsies.activities=Etkinlik -dialog.gpsies.activity.trekking=Y\u00fcr\u00fcy\u00fc\u015f -dialog.gpsies.activity.walking=Y\u00fcr\u00fcme -dialog.gpsies.activity.jogging=Ko\u015fma -dialog.gpsies.activity.biking=Bisiklet -dialog.gpsies.activity.sailing=Yelken -dialog.gpsies.activity.skating=Paten dialog.correlate.select.photoname=Foto ad\u0131 dialog.correlate.select.photolater=Foto sonra dialog.correlate.options.offset.hours=saat, @@ -256,19 +247,9 @@ dialog.checkversion.releasedate2=. dialog.checkversion.download=Yeni s\u00fcr\u00fcm indirmek i\u00e7in https://gpsprune.activityworkshop.net/download.html adresine git. dialog.keys.intro=Fare yerinde a\u015fa\u011f\u0131daki k\u0131sayol tu\u015flar\u0131 kullanabilirsin: dialog.keys.keylist=
Ok tu\u015flar\u0131Haritay\u0131 sola/sa\u011fa/a\u015fa\u011f\u0131/yukar\u0131 kayd\u0131r
Ctrl + sol, sa\u011f\u00d6nceki/sonraki noktay\u0131 se\u00e7
Ctrl + yukar/a\u015fa\u011f\u0131Yak\u0131nla\u015ft\u0131r/Uzakla\u015ft\u0131r
DelSe\u00e7ili noltay\u0131 sil
-dialog.saveconfig.desc=A\u011fa\u015f\u0131daki ayarlar\u0131 bir dasyada kaydedilir: -dialog.saveconfig.prune.trackdirectory=\u0130z klas\u00f6r\u00fc -dialog.saveconfig.prune.photodirectory=Foto klas\u00f6r\u00fc -dialog.saveconfig.prune.languagecode=Dil kodu (TR) -dialog.saveconfig.prune.gpsdevice=GPS ayg\u0131t -dialog.saveconfig.prune.gpsformat=GPS bi\u00e7imi -dialog.saveconfig.prune.povrayfont=Povray yaz\u0131tipi -dialog.saveconfig.prune.gnuplotpath=gnuplot'un yeriyolu -dialog.saveconfig.prune.gpsbabelpath=gpsbabel'in yeriyolu -dialog.saveconfig.prune.exiftoolpath=exiftool'un yeriyolu -dialog.saveconfig.prune.mapserverindex=Harita sunucunun index -dialog.saveconfig.prune.mapserverurl=Harita sunucunun adresi -dialog.saveconfig.prune.kmzimagewidth=KMZ resim geni\u015fli\u011fi +dialog.paths.prune.gnuplotpath=gnuplot'un yeriyolu +dialog.paths.prune.gpsbabelpath=gpsbabel'in yeriyolu +dialog.paths.prune.exiftoolpath=exiftool'un yeriyolu dialog.setpaths.intro=\u0130ste\u011fe ba\u011fl\u0131 a\u015fa\u011f\u0131daki uygulamalar\u0131n veriyolu kaydedebilirsin: dialog.addaltitude.noaltitudes=Se\u00e7ili s\u0131rada y\u00fckseklik bilgisi bulunmad\u0131 dialog.addaltitude.desc=Eklenecek y\u00fckseklik ofseti diff --git a/src/tim/prune/lang/prune-texts_uk.properties b/src/tim/prune/lang/prune-texts_uk.properties index 15b6b53..43ef43d 100644 --- a/src/tim/prune/lang/prune-texts_uk.properties +++ b/src/tim/prune/lang/prune-texts_uk.properties @@ -98,7 +98,6 @@ function.pastecoordinates=\u0412\u0432\u0435\u0434\u0435\u043d\u043d\u044f \u043 function.charts=\u0413\u0440\u0430\u0444\u0456\u043a\u0438 function.show3d=3D-\u0432\u0438\u0433\u043b\u044f\u0434 function.distances=\u0412\u0456\u0434\u0441\u0442\u0430\u043d\u0456 -function.fullrangedetails=\u0414\u0435\u0442\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u043f\u043e \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0443 function.estimatetime=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u0438\u0439 \u0447\u0430\u0441 function.learnestimationparams=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0432\u0433\u0430\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u043e\u0433\u043e \u0447\u0430\u0441\u0443 function.setmapbg=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043c\u0430\u043f\u0443-\u043f\u0456\u0434\u043a\u043b\u0430\u0434\u043a\u0443 @@ -106,8 +105,6 @@ function.setpaths=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \ function.selectsegment=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 function.splitsegments=\u0420\u043e\u0437\u0431\u0438\u0442\u0438 \u0442\u0440\u0435\u043a \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0438 function.sewsegments=\u0417\u0448\u0438\u0442\u0438 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0438 \u0442\u0440\u0435\u043a\u0456\u0432 \u0440\u0430\u0437\u043e\u043c -function.getgpsies=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0438 \u0437 Gpsies -function.uploadgpsies=\u0412\u0438\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0438 \u043d\u0430 Gpsies function.lookupsrtm=\u041e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0432\u0438\u0441\u043e\u0442\u0438 \u0437 SRTM function.downloadsrtm=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 SRTM-\u0442\u0430\u0439\u043b\u0438 function.getwikipedia=\u041e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u043d\u0430\u0439\u0431\u043b\u0438\u0436\u0447\u0443 \u0441\u0442\u0430\u0442\u0442\u044e \u0437 \u0412\u0456\u043a\u0456\u043f\u0435\u0434\u0456\u0457 diff --git a/src/tim/prune/lang/prune-texts_zh.properties b/src/tim/prune/lang/prune-texts_zh.properties index c42fe08..eba2b71 100644 --- a/src/tim/prune/lang/prune-texts_zh.properties +++ b/src/tim/prune/lang/prune-texts_zh.properties @@ -98,7 +98,6 @@ function.pastecoordinates=\u8f93\u5165\u65b0\u5750\u6807 function.charts=\u56fe\u8868 function.show3d=3D\u89c6\u56fe function.distances=\u8ddd\u79bb -function.fullrangedetails=\u5168\u822a\u6bb5\u8be6\u7ec6\u4fe1\u606f function.estimatetime=\u4f30\u8ba1\u65f6\u95f4 function.learnestimationparams=\u4f7f\u7528\u5f53\u524d\u8f68\u8ff9\u53c2\u6570\u4f30\u8ba1\u65f6\u95f4 function.setmapbg=\u80cc\u666f\u5730\u56fe @@ -106,8 +105,6 @@ function.setpaths=\u8bbe\u7f6e\u7a0b\u5e8f\u8def\u5f84 function.selectsegment=\u9009\u4e2d\u5f53\u524d\u8f68\u8ff9\u6bb5 function.splitsegments=\u5206\u5272\u8f68\u8ff9 function.sewsegments=\u63a5\u5408\u8f68\u8ff9\u7247\u6bb5 -function.getgpsies=\u83b7\u53d6Gpsies\u8f68\u8ff9 -function.uploadgpsies=\u4e0a\u4f20\u8f68\u8ff9\u5230Gpsies function.lookupsrtm=\u4eceSRTM\u83b7\u5f97\u9ad8\u5ea6\u4fe1\u606f function.downloadsrtm=\u4e0b\u8f7dSRTM\u6570\u636e function.getwikipedia=\u7ef4\u57fa\u767e\u79d1\u6709\u5173\u672c\u5730\u6587\u7ae0 @@ -358,19 +355,6 @@ dialog.gpsies.column.length=\u957f\u5ea6 dialog.gpsies.description=\u63cf\u8ff0 dialog.gpsies.nodescription=\u65e0\u63cf\u8ff0 dialog.gpsies.nonefound=\u672a\u627e\u5230\u8f68\u8ff9 -dialog.gpsies.username=Gpsies\u7f51\u7ad9\u7528\u6237\u540d -dialog.gpsies.password=Gpsies\u7f51\u7ad9\u5bc6\u7801 -dialog.gpsies.keepprivate=\u4e0d\u516c\u5f00\u8f68\u8ff9 -dialog.gpsies.confirmopenpage=\u6253\u5f00\u4e0a\u4f20\u8f68\u8ff9\u7684\u7f51\u7ad9\uff1f -dialog.gpsies.activities=\u6d3b\u52a8\u7c7b\u578b -dialog.gpsies.activity.trekking=\u5f92\u6b65 -dialog.gpsies.activity.walking=\u6b65\u884c -dialog.gpsies.activity.jogging=\u8dd1\u6b65 -dialog.gpsies.activity.biking=\u81ea\u884c\u8f66 -dialog.gpsies.activity.motorbiking=\u7535\u52a8\u81ea\u884c\u8f66 -dialog.gpsies.activity.snowshoe=\u96ea\u978b\u5065\u884c -dialog.gpsies.activity.sailing=\u5e06\u8239 -dialog.gpsies.activity.skating=\u6ed1\u51b0 dialog.wikipedia.column.name=\u6587\u7ae0\u9898\u76ee dialog.wikipedia.column.distance=\u8ddd\u79bb dialog.wikipedia.nonefound=\u672a\u627e\u5230\u7ef4\u57fa\u767e\u79d1\u6761\u76ee @@ -471,25 +455,9 @@ dialog.keys.intro=\u53ef\u7528\u4e0b\u5217\u5feb\u6377\u952e\u66ff\u4ee3\u9f20\u dialog.keys.keylist=
\u7bad\u5934\u4e0a\u4e0b\u5de6\u53f3\u79fb\u52a8\u5730\u56fe
Ctrl + \u5de6\u53f3\u7bad\u5934\u9009\u53d6\u524d\uff0c\u540e\u70b9
Ctrl + \u4e0a\u4e0b\u7bad\u5934\u653e\u5927\u7f29\u5c0f
Ctrl + PgUp, PgDown\u9009\u62e9\u524d\u540e\u6bb5
Ctrl + Home, End\u9009\u62e9\u9996\u672b\u70b9
Del\u5220\u9664\u5f53\u524d\u70b9
dialog.keys.normalmodifier=Ctrl dialog.keys.macmodifier=Command -dialog.saveconfig.desc=\u4e0b\u5217\u8bbe\u7f6e\u5c06\u4fdd\u5b58\u5230\u8bbe\u7f6e\u6587\u4ef6 -dialog.saveconfig.prune.trackdirectory=\u8f68\u8ff9\u6587\u4ef6\u5939 -dialog.saveconfig.prune.photodirectory=\u7167\u7247\u6587\u4ef6\u5939 -dialog.saveconfig.prune.languagecode=\u8bed\u8a00\u9009\u62e9(ZH) -dialog.saveconfig.prune.languagefile=\u8bed\u8a00\u6587\u4ef6\u5305 -dialog.saveconfig.prune.gpsdevice=GPS\u7aef\u53e3\u540d\u79f0 -dialog.saveconfig.prune.gpsformat=GPS\u6587\u4ef6\u683c\u5f0f -dialog.saveconfig.prune.povrayfont=Povray \u5b57\u4f53 -dialog.saveconfig.prune.gnuplotpath=gnuplot\u8def\u5f84 -dialog.saveconfig.prune.gpsbabelpath=gpsbabel\u8def\u5f84 -dialog.saveconfig.prune.exiftoolpath=exiftool\u8def\u5f84 -dialog.saveconfig.prune.mapsource=\u5df2\u9009\u62e9\u7684\u5730\u56fe\u6570\u636e\u6e90 -dialog.saveconfig.prune.mapsourcelist=\u5730\u56fe\u6570\u636e\u6e90 -dialog.saveconfig.prune.diskcache=\u5b58\u50a8\u8def\u5f84 -dialog.saveconfig.prune.kmzimagewidth=KMZ\u56fe\u50cf\u5bbd\u5ea6 -dialog.saveconfig.prune.colourscheme=\u989c\u8272 -dialog.saveconfig.prune.linewidth=\u7ebf\u4f53\u5bbd\u5ea6 -dialog.saveconfig.prune.kmltrackcolour=KML\u8f68\u8ff9\u989c\u8272 -dialog.saveconfig.prune.autosavesettings=\u81ea\u52a8\u4fdd\u5b58\u8bbe\u7f6e +dialog.paths.prune.gnuplotpath=gnuplot\u8def\u5f84 +dialog.paths.prune.gpsbabelpath=gpsbabel\u8def\u5f84 +dialog.paths.prune.exiftoolpath=exiftool\u8def\u5f84 dialog.setpaths.intro=\u5982\u679c\u9700\u8981\uff0c\u53ef\u8bbe\u5b9a\u5916\u6302\u7a0b\u5e8f\u8def\u5f84 dialog.setpaths.found=\u627e\u5230\u8def\u5f84\uff1f dialog.addaltitude.noaltitudes=\u8f68\u8ff9\u4e0d\u542b\u9ad8\u5ea6\u4fe1\u606f @@ -598,7 +566,6 @@ confirm.rearrangephotos=\u7167\u7247\u5df2\u91cd\u6392 confirm.splitsegments=\u8f68\u8ff9\u5df2\u5206\u5272\u4e3a %d \u6bb5 confirm.sewsegments=%d \u8f68\u8ff9\u6bb5\u5df2\u5408\u5e76 confirm.cutandmove=\u5df2\u79fb\u52a8\u7684\u8f68\u8ff9\u6bb5 -confirm.interpolate=\u8f68\u8ff9\u70b9\u5df2\u6dfb\u52a0 confirm.convertnamestotimes=\u822a\u70b9\u540d\u79f0\u5df2\u8f6c\u6362 confirm.saveexif.ok=\u5df2\u4fdd\u5b58 %d \u7167\u7247\u6587\u4ef6 confirm.undo.single=\u5df2\u64a4\u9500\u7684\u64cd\u4f5c @@ -654,7 +621,6 @@ button.selectall=\u5168\u9009 button.selectnone=\u5168\u4e0d\u9009 button.preview=\u9884\u89c8 button.load=\u5bfc\u5165 -button.upload=\u4e0a\u8f7d button.guessfields=\u4f30\u6d4b\u6570\u636e\u6bb5 button.showwebpage=\u663e\u793a\u7f51\u9875 button.check=\u68c0\u67e5 diff --git a/src/tim/prune/load/ContentCacher.java b/src/tim/prune/load/ContentCacher.java new file mode 100644 index 0000000..623abda --- /dev/null +++ b/src/tim/prune/load/ContentCacher.java @@ -0,0 +1,90 @@ +package tim.prune.load; + +import java.util.ArrayList; + +/** + * General point data cacher + */ +public abstract class ContentCacher +{ + /** Array to hold lines of file */ + private String[] _contentArray = null; + + + /** + * @return Contents of the file as array of non-blank Strings + */ + public String[] getContents() + { + return _contentArray; + } + + + /** + * Get the top section of the file for preview + * @param inNumRows number of lines to extract + * @param inMaxWidth max length of Strings (longer ones will be chopped) + * @return String array containing non-blank lines from the file + */ + public String[] getSnippet(int inNumRows, int inMaxWidth) + { + final int MIN_SNIPPET_SIZE = 3; + // Check size is within sensible limits + int numToCopy = inNumRows; + if (numToCopy > getNumLines()) numToCopy = getNumLines(); + int size = numToCopy; + if (size < MIN_SNIPPET_SIZE) size = MIN_SNIPPET_SIZE; + String[] result = new String[size]; + // Copy Strings across + System.arraycopy(_contentArray, 0, result, 0, numToCopy); + // Chop Strings to max width if necessary + if (inMaxWidth > 10) + { + for (int i=0; i inMaxWidth) + result[i] = result[i].trim(); + if (result[i].length() > inMaxWidth) + result[i] = result[i].substring(0, inMaxWidth); + } + } + } + return result; + } + + /** + * @return the number of non-blank lines in the file + */ + public int getNumLines() + { + return _contentArray.length; + } + + + /** + * Clear the memory + */ + public void clear() + { + _contentArray = null; + } + + /** + * Populate the string array + * @param inList list of lines + */ + protected void setContents(ArrayList inList) + { + // Convert into String array for keeps + int numLines = inList.size(); + _contentArray = new String[numLines]; + for (int i=0; i contentList = new ArrayList(); - if (_file != null && _file.exists() && _file.canRead()) + if (inFile != null && inFile.exists() && inFile.canRead()) { BufferedReader reader = null; try { - reader = new BufferedReader(new FileReader(_file)); + reader = new BufferedReader(new FileReader(inFile)); String currLine = reader.readLine(); if (currLine != null && currLine.startsWith(" getNumLines()) numToCopy = getNumLines(); - int size = numToCopy; - if (size < MIN_SNIPPET_SIZE) size = MIN_SNIPPET_SIZE; - String[] result = new String[size]; - // Copy Strings across - System.arraycopy(_contentArray, 0, result, 0, numToCopy); - // Chop Strings to max width if necessary - if (inMaxWidth > 10) - { - for (int i=0; i inMaxWidth) - result[i] = result[i].trim(); - if (result[i].length() > inMaxWidth) - result[i] = result[i].substring(0, inMaxWidth); - } - } - } - return result; - } - - /** - * @return the number of non-blank lines in the file - */ - public int getNumLines() - { - return _contentArray.length; - } - - - /** - * Clear the memory - */ - public void clear() - { - _file = null; - _contentArray = null; + setContents(contentList); } } diff --git a/src/tim/prune/load/FileSplitter.java b/src/tim/prune/load/FileSplitter.java index 60c2c5d..9902792 100644 --- a/src/tim/prune/load/FileSplitter.java +++ b/src/tim/prune/load/FileSplitter.java @@ -6,7 +6,7 @@ package tim.prune.load; */ public class FileSplitter { - private FileCacher _cacher = null; + private ContentCacher _cacher = null; private int _numRows = 0; private int _numColumns = 0; private boolean[] _columnStates = null; @@ -15,9 +15,9 @@ public class FileSplitter /** * Constructor - * @param inCacher FileCacher object holding file contents + * @param inCacher cacher object holding file contents */ - public FileSplitter(FileCacher inCacher) + public FileSplitter(ContentCacher inCacher) { _cacher = inCacher; } diff --git a/src/tim/prune/load/JpegLoader.java b/src/tim/prune/load/JpegLoader.java index 3e22eba..471226f 100644 --- a/src/tim/prune/load/JpegLoader.java +++ b/src/tim/prune/load/JpegLoader.java @@ -256,11 +256,9 @@ public class JpegLoader implements Runnable, Cancellable if (timestamp == null) { timestamp = new TimestampUtc(inFile.lastModified()); } - // Apply timestamp to photo and its point (if any) + // Apply timestamp to photo (but not its point) photo.setTimestamp(timestamp); - if (photo.getDataPoint() != null) { - // photo.getDataPoint().setFieldValue(Field.TIMESTAMP, timestamp.getText(Timestamp.Format.ISO8601), false); - } + return photo; } diff --git a/src/tim/prune/load/TextCacher.java b/src/tim/prune/load/TextCacher.java new file mode 100644 index 0000000..0945bfe --- /dev/null +++ b/src/tim/prune/load/TextCacher.java @@ -0,0 +1,42 @@ +package tim.prune.load; + +import java.util.ArrayList; + +/** + * Class to split a pasted text + * into an array for later retrieval + */ +public class TextCacher extends ContentCacher +{ + /** + * Constructor + * @param inText text to cache + */ + public TextCacher(String inText) + { + splitText(inText); + } + + + /** + * Load and split the specified text + */ + private void splitText(String inText) + { + ArrayList contentList = new ArrayList(); + if (inText != null) + { + for (String currLine : inText.split("\n")) + { + if (currLine != null) + { + currLine = currLine.trim(); + if (currLine.length() > 0) { + contentList.add(currLine); + } + } + } + } + setContents(contentList); + } +} diff --git a/src/tim/prune/load/TextFileLoader.java b/src/tim/prune/load/TextFileLoader.java index b4a0ca8..f61af39 100644 --- a/src/tim/prune/load/TextFileLoader.java +++ b/src/tim/prune/load/TextFileLoader.java @@ -48,7 +48,7 @@ public class TextFileLoader private JTextField _otherDelimiterText = null; private JLabel _statusLabel = null; private DelimiterInfo[] _delimiterInfos = null; - private FileCacher _fileCacher = null; + private ContentCacher _contentCacher = null; private JList _snippetBox = null; private FileExtractTableModel _fileExtractTableModel = null; private JTable _fieldTable; @@ -117,29 +117,7 @@ public class TextFileLoader _file = inFile; if (preCheckFile(_file)) { - _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.openoptions.title"), true); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); - // add closing listener - _dialog.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - _dialog.dispose(); - _app.informNoDataLoaded(); - } - }); - _dialog.getContentPane().add(makeDialogComponents()); - - // select best separator according to row counts (more is better) - int bestDelim = getBestOption(_delimiterInfos[0].getNumWinningRecords(), - _delimiterInfos[1].getNumWinningRecords(), _delimiterInfos[2].getNumWinningRecords(), - _delimiterInfos[3].getNumWinningRecords()); - if (bestDelim >= 0) - _delimiterRadios[bestDelim].setSelected(true); - else - _delimiterRadios[_delimiterRadios.length-1].setSelected(true); - informDelimiterSelected(); - _dialog.pack(); - _dialog.setVisible(true); + showDialog(); } else { @@ -152,8 +130,38 @@ public class TextFileLoader /** - * Check the given file for readability and funny characters, - * and count the fields for the various separators + * Checks passed, so now build and show the dialog + */ + private void showDialog() + { + _dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.openoptions.title"), true); + _dialog.setLocationRelativeTo(_parentFrame); + _dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + // add closing listener + _dialog.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + _dialog.dispose(); + _app.informNoDataLoaded(); + } + }); + _dialog.getContentPane().add(makeDialogComponents()); + + // select best separator according to row counts (more is better) + int bestDelim = getBestOption(_delimiterInfos[0].getNumWinningRecords(), + _delimiterInfos[1].getNumWinningRecords(), _delimiterInfos[2].getNumWinningRecords(), + _delimiterInfos[3].getNumWinningRecords()); + if (bestDelim >= 0) + _delimiterRadios[bestDelim].setSelected(true); + else + _delimiterRadios[_delimiterRadios.length-1].setSelected(true); + informDelimiterSelected(); + _dialog.pack(); + _dialog.setVisible(true); + } + + + /** + * Check the given file for validity * @param inFile file to check */ private boolean preCheckFile(File inFile) @@ -164,11 +172,20 @@ public class TextFileLoader return false; } // Use a FileCacher to read the file into an array - _fileCacher = new FileCacher(inFile); + _contentCacher = new FileCacher(inFile); + + return preCheckContents(); + } + /** + * Check the contents for readability and funny characters, + * and count the fields for the various separators + */ + private boolean preCheckContents() + { // Check each line of the file - String[] fileContents = _fileCacher.getContents(); - if (fileContents == null) { + String[] contents = _contentCacher.getContents(); + if (contents == null) { return false; // nothing cached, might be binary } boolean fileOK = true; @@ -178,9 +195,9 @@ public class TextFileLoader String currLine = null; String[] splitFields = null; int commaFields = 0, semicolonFields = 0, tabFields = 0, spaceFields = 0; - for (int lineNum=0; lineNum= 0) {fileOK = false;} // check for commas @@ -211,6 +228,39 @@ public class TextFileLoader return fileOK; } + /** + * @param inText text to load (as if it came from a file) + */ + public void loadText(String inText) + { + _file = null; + if (preCheckText(inText)) + { + showDialog(); + } + else + { + // Didn't pass pre-check + _app.showErrorMessage("error.load.dialogtitle", "error.load.nopointsintext"); + } + } + + /** + * Check the given text for validity + * @param inText (pasted) text to check + */ + private boolean preCheckText(String inText) + { + if (inText == null || inText.length() < 6) + { + return false; + } + // Use a cacher to split the text into an array + _contentCacher = new TextCacher(inText); + + return preCheckContents(); + } + /** * Get the index of the best one in the list @@ -326,7 +376,7 @@ public class TextFileLoader delimsPanel.add(_statusLabel); firstCard.add(delimsPanel, BorderLayout.SOUTH); // load snippet to show first few lines - _snippetBox = new JList(_fileCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH)); + _snippetBox = new JList(_contentCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH)); _snippetBox.setEnabled(false); firstCard.add(makeLabelledPanel("dialog.openoptions.filesnippet", _snippetBox), BorderLayout.CENTER); @@ -531,11 +581,13 @@ public class TextFileLoader */ public DelimiterInfo getSelectedDelimiterInfo() { - for (int i=0; i<4; i++) + for (int i=0; i<4; i++) { if (_delimiterRadios[i].isSelected()) return _delimiterInfos[i]; + } // must be "other" - build info if necessary - if (_delimiterInfos[4] == null) + if (_delimiterInfos[4] == null) { _delimiterInfos[4] = new DelimiterInfo(_otherDelimiterText.getText().charAt(0)); + } return _delimiterInfos[4]; } @@ -567,7 +619,7 @@ public class TextFileLoader private void prepareSecondPanel() { DelimiterInfo info = getSelectedDelimiterInfo(); - FileSplitter splitter = new FileSplitter(_fileCacher); + FileSplitter splitter = new FileSplitter(_contentCacher); // Check info makes sense - num fields > 0, num records > 0 // set "Finished" button to disabled if not ok // Add data to GUI elements @@ -637,7 +689,7 @@ public class TextFileLoader _lastSelectedFields = _fieldTableModel.getFieldArray(); // TODO: Remember all the units selections for next load? // Get the selected units for altitudes and speeds - SourceInfo sourceInfo = new SourceInfo(_file, SourceInfo.FILE_TYPE.TEXT); + SourceInfo sourceInfo = (_file == null ? null : new SourceInfo(_file, SourceInfo.FILE_TYPE.TEXT)); PointCreateOptions options = new PointCreateOptions(); options.setAltitudeUnits(_altitudeUnitsDropdown.getSelectedIndex() == 0 ? UnitSetLibrary.UNITS_METRES : UnitSetLibrary.UNITS_FEET); Unit hSpeedUnit = UnitSetLibrary.ALL_SPEED_UNITS[_hSpeedUnitsDropdown.getSelectedIndex()]; @@ -649,7 +701,7 @@ public class TextFileLoader _app.informDataLoaded(_fieldTableModel.getFieldArray(), _fileExtractTableModel.getData(), options, sourceInfo, null); // clear up file cacher - _fileCacher.clear(); + _contentCacher.clear(); // dispose of dialog _dialog.dispose(); } diff --git a/src/tim/prune/readme.txt b/src/tim/prune/readme.txt index 0c5bf5c..0023c74 100644 --- a/src/tim/prune/readme.txt +++ b/src/tim/prune/readme.txt @@ -1,11 +1,11 @@ -GpsPrune version 19.2 -===================== +GpsPrune version 20 +=================== GpsPrune is an application for viewing, editing and managing coordinate data from GPS systems, including format conversion, charting, 3d visualisation, audio and photo correlation, and online resource lookup. Full details can be found at https://gpsprune.activityworkshop.net/ -GpsPrune is copyright 2006-2018 activityworkshop.net and distributed under the terms of the Gnu GPL version 2. +GpsPrune is copyright 2006-2020 activityworkshop.net and distributed under the terms of the Gnu GPL version 2. You may freely use the software, and may help others to freely use it too. For further information on your rights and how they are protected, see the included license.txt file. @@ -17,7 +17,7 @@ Running ======= To run GpsPrune from the jar file, simply call it from a command prompt or shell: - java -jar gpsprune_19.2.jar + java -jar gpsprune_20.jar If the jar file is saved in a different directory, you will need to include the path. Depending on your system settings, you may be able to click or double-click on the jar file @@ -25,46 +25,37 @@ in a file manager window to execute it. A shortcut, menu item, alias, desktop i or other link can of course be made should you wish. To specify a language other than the default, use an additional parameter, eg: - java -jar gpsprune_19.2.jar --lang=DE + java -jar gpsprune_20.jar --lang=DE -New with version 19.2 -===================== -The following fixes and additions were made since version 19.1: - - Fix right-click-and-drag bug for zooming with Java 9 and Java 10 - - Fix export of timestamps when photo points don't have timestamps - - Lighting of 3d views from the northwest (thanks, PeHar) - - Remember the name tag from a loaded gpx file, suggest it again for gpx export - - Removal of the Thunderforest tile sources (OpenCycleMap, Outdoors) - -New with version 19.1 +New with version 20 ===================== The following fixes and additions were made since version 19: - - Performance improvements regarding scrolling through points - - Keyboard shortcut to access point edit dialog (part of Github issue #10) - - Online services Inlinemap.net and Graphhopper.com (routing) - - Cardinals in java3d view get billboard behaviour to always face camera (thanks, PeHar) - - Fix for PeakFinder urls + - Add option to use Nimbus look-and-feel (wishlist 77) + - Extend the marker waypoints function to include half the distance, half the climb and half the descent + - Remove Ukrainian language + - Add support for entering Pluscodes + - Add way to copy point details or range details to clipboard (wishlist 76) + - Project point using bearing and distance (wishlist 35) + - Possibility to paste a list of coordinates instead of just one + - Removal of Gpsies functions (both download and upload) New with version 19 =================== The following fixes and additions were made since version 18: - - Fix for duration rounding bug affecting sub-second timestamps - Wikipedia search now also includes galleries from wikimedia - Photo popup window now gets updated when the track selection changes - - Remove export to SVG function as it has fallen behind the java3d and pov options - - Remove Turkish language because there haven't been any translators since early 2010 - Function to add waypoints along the track at intervals of distance or time (eg every 5 km) - Optionally draw arrows on the track lines to show direction of travel - Waypoint rendering using icons (wishlist 71) - Allow user to select timezone in which timestamps are displayed (wishlist 61) - Provide call to geonames.org's OSM node search function, to find amenities (like bus stops) close to the current point - - Fix OSM download function using overpass API - - Fix opencyclemap URLs - - Fix reading of Exif data for some unusual cases (from Adobe Lightroom?) - - Remove Panoramio - - Update wikimedia catalogue - Debian and Ubuntu packages no longer rely on external libmetadata jar + - Keyboard shortcut to access point edit dialog (part of Github issue #10) + - Online services Inlinemap.net and Graphhopper.com (routing) + - Cardinals in java3d view get billboard behaviour to always face camera (thanks, PeHar) + - Lighting of 3d views from the northwest (thanks, PeHar) + - Remember the name tag from a loaded gpx file, suggest it again for gpx export New with version 18 =================== @@ -279,7 +270,7 @@ Further information and updates =============================== To obtain the source code (if it wasn't included in your jar file), or for further information, -please visit the website: http://gpsprune.activityworkshop.net/ +please visit the website: https://gpsprune.activityworkshop.net/ You will find there user guides, screenshots and demo videos illustrating the major features. As GpsPrune is further developed, subsequent versions of the program will also be made freely diff --git a/src/tim/prune/save/BaseImageConfigDialog.java b/src/tim/prune/save/BaseImageConfigDialog.java index 8e7e9ae..0623b1f 100644 --- a/src/tim/prune/save/BaseImageConfigDialog.java +++ b/src/tim/prune/save/BaseImageConfigDialog.java @@ -142,7 +142,7 @@ public class BaseImageConfigDialog implements Runnable { for (int i=0; i<_zoomDropdown.getItemCount(); i++) { - String item = _zoomDropdown.getItemAt(i).toString(); + String item = _zoomDropdown.getItemAt(i); try { if (Integer.parseInt(item) == zoomLevel) { diff --git a/src/tim/prune/save/ImageExporter.java b/src/tim/prune/save/ImageExporter.java index ea18892..eb5e6ef 100644 --- a/src/tim/prune/save/ImageExporter.java +++ b/src/tim/prune/save/ImageExporter.java @@ -300,6 +300,7 @@ public class ImageExporter extends GenericFunction implements BaseImageConsumer final Track track = _app.getTrackInfo().getTrack(); final int numPoints = track.getNumPoints(); int prevX = 0, prevY = 0; + boolean gotPreviousPoint = false; for (int i=0; i