--- /dev/null
+*.class
+*.jar
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.
# Build script
+set -e
# Version number
-PRUNENAME=gpsprune_19.2
+PRUNENAME=gpsprune_20
# remove compile directory
rm -rf compile
# remove dist directory
<groupId>tim.prune</groupId>
<artifactId>gpsprune</artifactId>
- <version>19.2</version>
+ <version>20</version>
<packaging>jar</packaging>
<name>tim.prune.gpsprune</name>
-version=19.2
+version=20
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}
/**
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;
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)
{
_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();
}
_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
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;
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;
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;
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;
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;
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);
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);
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);
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;
/**
* 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;
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);
}
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;
/**
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));
while (e.hasMoreElements())
{
String key = e.nextElement();
- LocalTexts.setProperty(key, inBundle.getString(key));
+ _localTexts.setProperty(key, inBundle.getString(key));
}
}
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) {}
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) {}
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 */
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 */
_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();
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
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
*/
public static void updatePointColourer(PointColourer inColourer)
{
_pointColourer = inColourer;
- setConfigString(KEY_POINT_COLOURER, ColourerFactory.PointColourerToString(_pointColourer));
+ setConfigString(KEY_POINT_COLOURER, ColourerFactory.pointColourerToString(_pointColourer));
}
/**
-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
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.
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;
+ }
+ }
}
*/
public void removeSource()
{
- _sources.remove(_sources.size()-1);
+ if (!_sources.isEmpty()) {
+ _sources.remove(_sources.size()-1);
+ }
}
/**
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() {
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;
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;
}
--- /dev/null
+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;
+ }
+}
{
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;
/**
*/
public void markInvalid()
{
- _valid = false;
+ _rangeStats = null;
}
*/
private void recalculate()
{
+ if (_rangeStats != null) {
+ return;
+ }
final int numPoints = _track.getNumPoints();
// Recheck if the number of points has changed
if (numPoints != _prevNumPoints)
}
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;
}
*/
public int getStart()
{
- if (!_valid) recalculate();
+ recalculate();
return _startIndex;
}
*/
public int getEnd()
{
- if (!_valid) recalculate();
+ recalculate();
return _endIndex;
}
*/
public AltitudeRange getAltitudeRange()
{
- if (!_valid) recalculate();
- return _altitudeRange;
+ recalculate();
+ return _rangeStats.getTotalAltitudeRange();
}
*/
public long getMovingSeconds()
{
- if (!_valid) recalculate();
- return _movingMilliseconds / 1000L;
+ recalculate();
+ return _rangeStats.getMovingDurationInSeconds();
}
/**
*/
public double getMovingDistance()
{
- return Distance.convertRadiansToDistance(_angMovingDistance);
+ return _rangeStats.getMovingDistance();
}
/**
selectRange(-1, -1);
_currentPhotoIndex = -1;
_currentAudioIndex = -1;
+ markInvalid();
check();
}
// Clear selected range
_startIndex = _endIndex = -1;
// Check for consistency and fire update
+ markInvalid();
check();
}
{
// track is empty, clear selections
_currentPoint = _startIndex = _endIndex = -1;
+ markInvalid();
}
UpdateMessageBroker.informSubscribers(DataSubscriber.SELECTION_CHANGED);
}
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 */
{
if (!isValid()) return "";
// Maybe we should add milliseconds to this format?
- if (hasMilliseconds() && !MillisAddedToTimeFormat)
+ if (hasMilliseconds() && !_millisAddedToTimeFormat)
{
try
{
if (pattern.indexOf("ss") > 0 && pattern.indexOf("SS") < 0)
{
sdf.applyPattern(pattern.replaceFirst("s+", "$0.SSS"));
- MillisAddedToTimeFormat = true;
+ _millisAddedToTimeFormat = true;
}
}
catch (ClassCastException cce) {}
descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ")
.append("afrikaans, \u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano,<br>" +
" magyar, nederlands, polski, portugu\u00EAs, rom\u00E2n\u0103, suomi, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian),<br>" +
- " \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, ukrainian</p>");
+ " \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch</p>");
descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>");
JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString());
descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
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);
MouseAdapter mouseListener = new MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent arg0) {
_okButton.setEnabled(getOffsetSecs() != 0L);
- };
+ }
};
_dayField.addKeyListener(keyListener);
_hourField.addKeyListener(keyListener);
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);
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
{
/** 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);
}
/**
*/
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<numPoints; i++)
+ if (createByTime || createByDistance) {
+ createWaypointsAtIntervals(timeLimitSeconds, distLimitKm);
+ }
+ else if (createHalves)
{
- currPoint = _app.getTrackInfo().getTrack().getPoint(i);
- if (!currPoint.isWaypoint())
- {
- if (!currPoint.getSegmentStart() && prevPoint != null)
- {
- // Calculate current value
- if (createByTime)
- {
- if (currPoint.hasTimestamp() && prevPoint.hasTimestamp())
- {
- currValue += (currPoint.getTimestamp().getMillisecondsSince(prevPoint.getTimestamp()) / 1000.0);
- processValue(prevPoint, prevValue, timeLimitSeconds, currPoint, currValue);
- }
- }
- else if (createByDistance)
- {
- currValue += DataPoint.calculateRadiansBetween(prevPoint, currPoint);
- processValue(prevPoint, prevValue, distLimitRadians, currPoint, currValue);
- }
- }
- prevPoint = currPoint;
- prevValue = currValue;
- }
+ createHalfwayWaypoints();
+ }
+ else
+ {
+ return;
}
- // System.out.println(_pointsToAdd.size() + " markers to add...");
if (!_pointsToAdd.isEmpty())
{
+ // Make undo object
+ final int numPoints = _app.getTrackInfo().getTrack().getNumPoints();
+ UndoAppendPoints undo = new UndoAppendPoints(numPoints);
+
// Append created points to Track
Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.ALTITUDE, Field.WAYPT_NAME};
final int numPointsToAdd = _pointsToAdd.size();
_app.getTrackInfo().getTrack().combine(wpTrack);
undo.setNumPointsAppended(numPointsToAdd);
- _app.completeFunction(undo, I18nManager.getText("confirm.interpolate"));
- // TODO: Maybe add new token including number of points added/created
+ final String confirmMessage = I18nManager.getTextWithNumber("confirm.pointsadded", _pointsToAdd.size());
+ _app.completeFunction(undo, confirmMessage);
UpdateMessageBroker.informSubscribers();
}
_dialog.dispose();
}
+ /**
+ * Create waypoints according to the given intervals
+ * @param inTimeLimitSeconds
+ * @param inDistLimitKm distance limit in kilometres
+ */
+ private void createWaypointsAtIntervals(int inTimeLimitSeconds, double inDistLimitKm)
+ {
+ final boolean createByTime = (inTimeLimitSeconds > 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<numPoints; i++)
+ {
+ currPoint = _app.getTrackInfo().getTrack().getPoint(i);
+ rangeStats.addPoint(currPoint);
+
+ if (!currPoint.isWaypoint())
+ {
+ // Calculate current value
+ if (createByTime)
+ {
+ currValue = rangeStats.getMovingDurationInSeconds();
+ processValue(prevPoint, prevValue, inTimeLimitSeconds, currPoint, currValue);
+ }
+ else if (createByDistance)
+ {
+ currValue = rangeStats.getMovingDistanceKilometres();
+ processValue(prevPoint, prevValue, inDistLimitKm, currPoint, currValue);
+ }
+
+ prevPoint = currPoint;
+ prevValue = currValue;
+ }
+ }
+ }
+
/**
* Consider a pair of points in the track to see if a new marker should be inserted between them
* @param inPrevPoint previous point
DataPoint marker = DataPoint.interpolate(inPrevPoint, inCurrPoint, fractionFromPrev);
marker.setFieldValue(Field.WAYPT_NAME, createLimitDescription(m), false);
_pointsToAdd.add(marker);
- // System.out.println("I would add a point here with values " + inPrevValue + " and " + inCurrValue);
}
_previousMultiple = currMultiple;
}
+
+ /**
+ * Create waypoints for the halfway markers
+ */
+ private void createHalfwayWaypoints()
+ {
+ // Calculate the details of the whole track so we can see what to halve
+ final int numPoints = _app.getTrackInfo().getTrack().getNumPoints();
+ RangeStats totalStats = new RangeStats();
+ DataPoint currPoint = null;
+ for (int i=0; i<numPoints; i++)
+ {
+ currPoint = _app.getTrackInfo().getTrack().getPoint(i);
+ totalStats.addPoint(currPoint);
+ }
+ // Calculate total moving distance of track
+ final double totalDist = totalStats.getMovingDistanceKilometres();
+ // If the track has altitudes, also calculate total climb and total descent
+ final double totalClimb = totalStats.getMovingAltitudeRange().getClimb(UnitSetLibrary.UNITS_METRES);
+ final double totalDescent = totalStats.getMovingAltitudeRange().getDescent(UnitSetLibrary.UNITS_METRES);
+
+ final double halfDistance = totalDist / 2.0;
+ final double halfClimb = totalClimb / 2.0;
+ final double halfDescent = totalDescent / 2.0;
+
+ // Now loop through points again, looking for the halfway points
+ RangeStats partialStats = new RangeStats();
+ DataPoint prevPoint = null;
+ boolean createdDistance = false, createdClimb = false, createdDescent = false;
+ double prevDistance = 0.0, prevClimb = 0.0, prevDescent = 0.0;
+ for (int i=0; i<numPoints; i++)
+ {
+ currPoint = _app.getTrackInfo().getTrack().getPoint(i);
+ partialStats.addPoint(currPoint);
+ if (!currPoint.isWaypoint())
+ {
+ // distance
+ if (!createdDistance && totalDist > 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";
+ }
}
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;
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;
/**
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<String> _distUnitsDropdown = null;
/** Text field for entering distance */
/**
- * 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;
}
/**
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);
_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);
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);
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
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
*/
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());
}
+++ /dev/null
-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("");
- }
- }
-}
// 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);
}
--- /dev/null
+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();
+ }
+}
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) {
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) {
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;
{
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;
}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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();
+ }
+}
// 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)
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
--- /dev/null
+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<heading.length(); i++)
+ {
+ inBuffer.append('=');
+ }
+ inBuffer.append('\n');
+ }
+}
public void actionPerformed(ActionEvent arg0)
{
preview();
- };
+ }
};
// construct track details to be used by all algorithms
TrackDetails details = new TrackDetails(_track);
_parameterField = new JTextField();
// Add listener to parameter field to re-run preview (and en/disable ok) when param changed
_parameterField.addKeyListener(new KeyListener() {
- public void keyTyped(java.awt.event.KeyEvent arg0) {};
- public void keyPressed(java.awt.event.KeyEvent arg0) {};
- public void keyReleased(java.awt.event.KeyEvent arg0) {if (isActivated()) _listener.actionPerformed(null);};
+ public void keyTyped(java.awt.event.KeyEvent arg0) {}
+ public void keyPressed(java.awt.event.KeyEvent arg0) {}
+ public void keyReleased(java.awt.event.KeyEvent arg0) {if (isActivated()) _listener.actionPerformed(null);}
});
}
// second table for distances
_distModel = new DistanceTableModel();
JTable distTable = new JTable(_distModel);
- // Use reflection to call distTable.setAutoCreateRowSorter(true) which is new with Java 1.6
- try {
- Class<?> 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);
{
if (inColumnIndex == 0) {return getPointName(inRowIndex);}
if (_distances == null) {return 0.0;}
- return new Double(_distances[inRowIndex]);
+ return Double.valueOf(_distances[inRowIndex]);
}
/**
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;
private JLabel _descentParamLabel = null;
private DecimalNumberField _gentleDescentField = null, _steepDescentField = null;
/** Range stats */
- private RangeStats _stats = null;
+ private RangeStatsWithGradients _stats = null;
/**
{
// 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)
{
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() + ": ");
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;
* @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
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;
{
_progress.setMaximum(100);
// Go through the track and collect the range stats for each sample
- ArrayList<RangeStats> statsList = new ArrayList<RangeStats>(20);
+ ArrayList<RangeStatsWithGradients> statsList = new ArrayList<RangeStatsWithGradients>(20);
Track track = _app.getTrackInfo().getTrack();
final int numPoints = track.getNumPoints();
final int sampleSize = numPoints / 30;
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);
}
* @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()) {
// Check moving distance
if (movingRads >= minimumRads) {
- return new RangeStats(inTrack, start, endIndex);
+ return new RangeStatsWithGradients(inTrack, start, endIndex);
}
return null;
}
* @param inStatsList list of (non-null) RangeStats objects
* @return A matrix with n rows and 5 columns
*/
- private static Matrix buildAMatrix(ArrayList<RangeStats> inStatsList)
+ private static Matrix buildAMatrix(ArrayList<RangeStatsWithGradients> 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));
* @param inStatsList list of (non-null) RangeStats objects
* @return B matrix with single column of n rows
*/
- private static Matrix buildBMatrix(ArrayList<RangeStats> inStatsList)
+ private static Matrix buildBMatrix(ArrayList<RangeStatsWithGradients> 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++;
* @param inRowToIgnore row index to ignore, or -1 to use them all
* @return true if the samples look ok
*/
- private static boolean isRangeSetSufficient(ArrayList<RangeStats> inRangeSet, int inRowToIgnore)
+ private static boolean isRangeSetSufficient(ArrayList<RangeStatsWithGradients> 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)
{
* @param inStatsList list of stats
* @return results in an object
*/
- private MatrixResults reduceSamples(ArrayList<RangeStats> inStatsList)
+ private MatrixResults reduceSamples(ArrayList<RangeStatsWithGradients> inStatsList)
{
int statsIndexToRemove = -1;
Matrix answer = null;
+++ /dev/null
-package tim.prune.function.gpsies;\r
-\r
-import java.net.HttpURLConnection;\r
-import java.net.URLConnection;\r
-import java.net.URL;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.Random;\r
-import java.io.OutputStream;\r
-\r
-/**\r
- * Taken from the Client HTTP Request class at com.myjavatools.web\r
- * and subsequently simplified and modified\r
- * @author Vlad Patryshev\r
- */\r
-public class FormPoster\r
-{\r
- private URLConnection _connection = null;\r
- private OutputStream _os = null;\r
- private static final Random RANDOM_GEN = new Random();\r
- private static final String BOUNDARY = "---------------------------"\r
- + randomString() + randomString() + randomString();\r
-\r
-\r
- /** Connect (if not already connected) */\r
- protected void connect() throws IOException {\r
- if (_os == null) _os = _connection.getOutputStream();\r
- }\r
-\r
- /** Write a single character */\r
- protected void write(char c) throws IOException {\r
- connect();\r
- _os.write(c);\r
- }\r
-\r
- /** Write a string */\r
- protected void write(String s) throws IOException {\r
- connect();\r
- _os.write(s.getBytes());\r
- }\r
-\r
- /** Write a -r-n newline sequence */\r
- protected void newline() throws IOException {\r
- write("\r\n");\r
- }\r
-\r
- /** Write a string followed by a newline */\r
- protected void writeln(String s) throws IOException {\r
- write(s);\r
- newline();\r
- }\r
-\r
- /** Generate a random alphanumeric string */\r
- private static String randomString() {\r
- return Long.toString(RANDOM_GEN.nextLong(), 36);\r
- }\r
-\r
- /** Write a boundary marker */\r
- private void boundary() throws IOException {\r
- write("--");\r
- write(BOUNDARY);\r
- }\r
-\r
-\r
- /**\r
- * Creates a new multipart POST HTTP request for a specified URL\r
- * @param url the URL to send request to\r
- * @throws IOException\r
- */\r
- public FormPoster(URL inUrl) throws IOException\r
- {\r
- _connection = inUrl.openConnection();\r
- _connection.setDoOutput(true);\r
- _connection.setRequestProperty("Content-Type",\r
- "multipart/form-data; boundary=" + BOUNDARY);\r
- }\r
-\r
- /** Write a header with the given name */\r
- private void writeName(String inName) throws IOException\r
- {\r
- newline();\r
- write("Content-Disposition: form-data; name=\"");\r
- write(inName);\r
- write('"');\r
- }\r
-\r
- /**\r
- * adds a string parameter to the request\r
- * @param name parameter name\r
- * @param value parameter value\r
- * @throws IOException\r
- */\r
- public void setParameter(String inName, String inValue) throws IOException\r
- {\r
- boundary();\r
- writeName(inName);\r
- newline(); newline();\r
- writeln(inValue);\r
- }\r
-\r
- /** Pipe the contents of the input stream to the output stream */\r
- private static void pipe(InputStream in, OutputStream out) throws IOException\r
- {\r
- byte[] buf = new byte[500000];\r
- int nread;\r
- synchronized (in) {\r
- while((nread = in.read(buf, 0, buf.length)) >= 0) {\r
- out.write(buf, 0, nread);\r
- }\r
- }\r
- out.flush();\r
- buf = null;\r
- }\r
-\r
- /**\r
- * adds a file parameter to the request\r
- * @param inName parameter name\r
- * @param inFilename the name of the file\r
- * @param inStream input stream to read the contents of the file from\r
- * @throws IOException\r
- */\r
- public void setParameter(String inName, String inFilename, InputStream inStream) throws IOException\r
- {\r
- boundary();\r
- writeName(inName);\r
- write("; filename=\"");\r
- write(inFilename);\r
- write('"');\r
- newline();\r
- write("Content-Type: ");\r
- String type = URLConnection.guessContentTypeFromName(inFilename);\r
- if (type == null) {type = "application/octet-stream";}\r
- writeln(type);\r
- newline();\r
- pipe(inStream, _os);\r
- newline();\r
- }\r
-\r
- /**\r
- * posts the requests to the server\r
- * @return input stream with the server response\r
- * @throws IOException\r
- */\r
- public InputStream post() throws IOException\r
- {\r
- boundary();\r
- writeln("--");\r
- _os.close();\r
- return _connection.getInputStream();\r
- }\r
-\r
- /**\r
- * @return the HTTP response code, 200 for success or -1 if not available\r
- */\r
- public int getResponseCode() throws IOException\r
- {\r
- if (_connection != null && _connection instanceof HttpURLConnection) {\r
- return ((HttpURLConnection) _connection).getResponseCode();\r
- }\r
- return -1;\r
- }\r
-}\r
+++ /dev/null
-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<SearchResult> 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<numSelected; i++)
- {
- int rowNum = rowNums[i];
- if (rowNum >= 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();
- }
-}
+++ /dev/null
-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<SearchResult> _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<SearchResult>();
- }
- 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<SearchResult> getTrackList()
- {
- return _trackList;
- }
-}
+++ /dev/null
-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<numActivities; i++)
- {
- _activityCheckboxes[i] = new JCheckBox(I18nManager.getText("dialog.gpsies.activity." + ACTIVITY_KEYS[i]));
- _activityCheckboxes[i].addChangeListener(checkListener);
- actGrid.add(_activityCheckboxes[i]);
- }
- grid.add(new JLabel(I18nManager.getText("dialog.gpsies.activities")));
- grid.add(activityPanel);
- JPanel midPanel = new JPanel();
- midPanel.setLayout(new BoxLayout(midPanel, BoxLayout.Y_AXIS));
- midPanel.add(gridPanel);
- dialogPanel.add(midPanel, BorderLayout.CENTER);
-
- // button panel at bottom
- JPanel buttonPanel = new JPanel();
- buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- _uploadButton = new JButton(I18nManager.getText("button.upload"));
- _uploadButton.setEnabled(false);
- _uploadButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- startUpload();
- }
- });
- buttonPanel.add(_uploadButton);
- 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;
- }
-
-
- /**
- * Check the inputs and enable or disable the upload button
- */
- private void enableOK()
- {
- // Check for lengths of input fields - only username, password and filename are required
- boolean ok = (_usernameField.getText().length() > 0 && _nameField.getText().length() > 0);
- if (ok) {
- // also check password field
- char[] pass = _passwordField.getPassword();
- ok = pass.length > 0;
- for (int i=0; i<pass.length; i++) {pass[i] = '0';} // recommended by javadoc
- if (ok) {
- ok = false;
- for (int i=0; i<_activityCheckboxes.length; i++) {
- ok = ok || _activityCheckboxes[i].isSelected();
- }
- }
- }
- _uploadButton.setEnabled(ok);
- }
-
-
- /**
- * Start the upload process (require separate thread?)
- */
- private void startUpload()
- {
- BufferedReader reader = null;
- try
- {
- FormPoster poster = new FormPoster(new URL(GPSIES_URL));
- poster.setParameter("device", "Prune");
- poster.setParameter("username", _usernameField.getText());
- poster.setParameter("password", new String(_passwordField.getPassword()));
- boolean hasActivity = false;
- for (int i=0; i<ACTIVITY_KEYS.length; i++)
- {
- if (_activityCheckboxes[i].isSelected()) {
- hasActivity = true;
- poster.setParameter("trackTypes", ACTIVITY_KEYS[i]);
- }
- }
- if (!hasActivity) {poster.setParameter("trackTypes", "walking");} // default if none given
- poster.setParameter("filename", _nameField.getText());
- poster.setParameter("fileDescription", _descField.getText());
- poster.setParameter("startpointCountry", "DE");
- poster.setParameter("endpointCountry", "DE"); // both those will be corrected by gpsies
- poster.setParameter("status", (_privateCheckbox.isSelected()?"3":"1"));
- poster.setParameter("submit", "speichern"); // required
- // Use Pipes to connect the GpxExporter's output with the FormPoster's input
- PipedInputStream iStream = new PipedInputStream();
- PipedOutputStream oStream = new PipedOutputStream(iStream);
- _writer = new OutputStreamWriter(oStream);
- new Thread(new Runnable() {
- public void run() {
- try {
- GpxExporter.exportData(_writer, _app.getTrackInfo(), _nameField.getText(),
- null, new SettingsForExport(), null);
- } catch (IOException e) {}
- finally {
- try {_writer.close();} catch (IOException e) {}
- }
- }
- }).start();
- poster.setParameter("formFile", "filename.gpx", iStream);
-
- BufferedInputStream answer = new BufferedInputStream(poster.post());
- int response = poster.getResponseCode();
- reader = new BufferedReader(new InputStreamReader(answer));
- String line = reader.readLine();
- // Try to extract gpsies page url from the returned message
- String pageUrl = null;
- if (response == 200 && line.substring(0, 2).toUpperCase().equals("OK"))
- {
- final int bracketPos = line.indexOf('[');
- if (bracketPos > 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();
- }
-}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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
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
{
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<SearchResult>
{
-package tim.prune.function.gpsies;
+package tim.prune.function.search;
import java.text.NumberFormat;
import java.util.ArrayList;
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
{
+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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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;
*/
public class SaveConfig extends GenericFunction
{
- private JDialog _dialog = null;
-
/**
* Constructor
* @param inApp application object for callback
* 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<Object> 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;}
File saveFile = chooser.getSelectedFile();
saveConfig(saveFile);
}
- _dialog.dispose();
- _dialog = null;
}
/**
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
+ 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
{
finally {
try {outStream.close();} catch (Exception e) {}
}
+ // Remember where it was saved to
+ Config.setConfigFile(inSaveFile);
}
}
private JCheckBox _antialiasCheckbox = null;
private JComboBox<Integer> _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
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
_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);
}
}
}
+ /**
+ * 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
*/
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();
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"
};
_installedLabels = new JLabel[NUM_KEYS];
for (int i=0; i<NUM_KEYS; i++)
{
- JLabel label = new JLabel(I18nManager.getText("dialog.saveconfig.prune." + LABEL_KEYS[i] + "path"));
+ JLabel label = new JLabel(I18nManager.getText("dialog.paths.prune." + LABEL_KEYS[i] + "path"));
label.setHorizontalAlignment(SwingConstants.RIGHT);
mainPanel.add(label);
String configVal = Config.getConfigString(CONFIG_KEYS[i]);
}
_dialog.dispose();
}
-}
\ No newline at end of file
+}
* Constructor
*/
public SplitSegmentsFunction(App inApp) {
- super(inApp);
+ super(inApp, false);
}
/**
String errorMessage = null;
// Get urls for each tile
URL[] urls = TileFinder.getUrls(inTileList);
- for (int t=0; t<inTileList.size() && !_progress.isCancelled(); t++)
+ for (int t=0; t<inTileList.size() && !_progress.isCancelled() && urls != null; t++)
{
if (urls[t] != null)
{
if (entryOk)
{
- // Loop over all points in track, try to apply altitude from array
- for (int p = 0; p < _track.getNumPoints(); p++)
- {
- DataPoint point = _track.getPoint(p);
- if (!point.hasAltitude()
- || (inOverwriteZeros && point.getAltitude().getValue() == 0))
- {
- if (new SrtmTile(point).equals(tile))
- {
- double x = (point.getLongitude().getDouble() - tile.getLongitude()) * 1200;
- double y = 1201 - (point.getLatitude().getDouble() - tile.getLatitude()) * 1200;
- int idx1 = ((int)y)*1201 + (int)x;
- try
- {
- int[] fouralts = {heights[idx1], heights[idx1+1], heights[idx1-1201], heights[idx1-1200]};
- int numVoids = (fouralts[0]==VOID_VAL?1:0) + (fouralts[1]==VOID_VAL?1:0)
- + (fouralts[2]==VOID_VAL?1:0) + (fouralts[3]==VOID_VAL?1:0);
- // if (numVoids > 0) System.out.println(numVoids + " voids found");
- double altitude = 0.0;
- switch (numVoids)
- {
- case 0: altitude = bilinearInterpolate(fouralts, x, y); break;
- case 1: altitude = bilinearInterpolate(fixVoid(fouralts), x, y); break;
- case 2:
- case 3: altitude = averageNonVoid(fouralts); break;
- default: altitude = VOID_VAL;
- }
- // Special case for terrain tracks, don't interpolate voids yet
- if (!_normalTrack && numVoids > 0) {
- altitude = VOID_VAL;
- }
- if (altitude != VOID_VAL)
- {
- point.setFieldValue(Field.ALTITUDE, ""+altitude, false);
- // depending on settings, this value may have been added as feet, we need to force metres
- point.getAltitude().reset(new Altitude((int)altitude, UnitSetLibrary.UNITS_METRES));
- numAltitudesFound++;
- }
- }
- catch (ArrayIndexOutOfBoundsException obe) {
- // System.err.println("lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1);
- }
- }
- }
- }
+ numAltitudesFound += applySrtmTileToWholeTrack(tile, heights, inOverwriteZeros);
}
}
- catch (IOException ioe) {errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
+ catch (IOException ioe) {
+ errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
}
}
}
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)
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<inTiles.size(); t++)
{
SrtmTile tile = inTiles.get(t);
--- /dev/null
+package tim.prune.gui;
+
+import tim.prune.data.Coordinate;
+
+/**
+ * Functions for display of coordinates in gui
+ */
+public abstract class CoordDisplay
+{
+
+ /**
+ * Construct an appropriate coordinate label using the selected format
+ * @param inCoordinate coordinate
+ * @param inFormat selected display format
+ * @return language-sensitive string
+ */
+ public static String makeCoordinateLabel(Coordinate inCoordinate, int inFormat)
+ {
+ String coord = inCoordinate.output(inFormat);
+ // 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 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;
+ }
+
+}
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)
{
_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) + " " +
}
// 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("");
}
filename = info.getName();
}
}
- if (filename != null) {
+ if (filename != null)
+ {
_filenameLabel.setText(LABEL_POINT_FILENAME + filename);
_filenameLabel.setToolTipText(filename);
}
- else {
+ else
+ {
_filenameLabel.setText("");
_filenameLabel.setToolTipText("");
}
_aveSpeedLabel.setText(I18nManager.getText("details.range.avespeed") + ": "
+ DisplayUtils.roundedNumber(selection.getMovingDistance()/numMovingSeconds*3600.0) + " " + speedUnitsStr);
}
- else {
+ else
+ {
_durationLabel.setText("");
_aveSpeedLabel.setText("");
}
_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();
}
- /**
- * 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
// 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;
+ }
+ }
}
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,
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;
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;
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;
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
// 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
_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);
_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);
_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);
_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);
_selectEndItem.setEnabled(hasPoint);
_selectEndButton.setEnabled(hasPoint);
_duplicatePointItem.setEnabled(hasPoint);
+ _projectPointItem.setEnabled(hasPoint);
_showPeakfinderItem.setEnabled(hasPoint);
_showGeohackItem.setEnabled(hasPoint);
_searchOpencachingDeItem.setEnabled(hasPoint);
_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());
_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();
}
/**
* 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.
* @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)
{
/**
* 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
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<String> BLOCKED_URLS = new HashSet<String>();
+ /**Hashset of files which are currently being processed */
+ private static final HashSet<String> DOWNLOADING_FILES = new HashSet<String>();
+ /** 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
_url = inUrl;
_file = inFile;
_observer = inObserver;
+ _active = registerCacher(inFile.getAbsolutePath());
}
/**
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);
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--;
+ }
}
}
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)
{
_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));
}
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;
}
}
try
{
URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY));
- //System.out.println("Trying to fetch: " + tileUrl);
if (useDisk)
{
DiskTileCacher.saveTile(tileUrl, diskCachePath,
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<String> BLOCKED_URLS = new HashSet<String>();
/** Hashset of all currently loading tiles to avoid requesting them again */
private static final HashSet<String> LOADING_URLS = new HashSet<String>();
+ /** Flag to maintain whether connection is active or not */
+ private static boolean CONNECTION_ACTIVE = true;
/**
LOADING_URLS.add(url);
new Thread(new TileDownloader(inManager, inUrl, inLayer, inX, inY, inZoom)).start();
}
+ else {
+ System.out.println("Already blocked: " + url);
+ }
}
}
// 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)
BLOCKED_URLS.add(_url.toString());
}
try {in.close();} catch (Exception e2) {}
+ CONNECTION_ACTIVE = false; // lost connection?
}
LOADING_URLS.remove(_url.toString());
}
if (!other.hasValue) {return;}
if (!hasValue) {
index = other.index;
- hasValue = other.hasValue;
+ hasValue = true;
}
else {
index = Math.min(index, other.index);
if (!other.hasValue) {return;}
if (!hasValue) {
index = other.index;
- hasValue = other.hasValue;
+ hasValue = true;
}
else {
index = Math.max(index, other.index);
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();
}
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);
}
}
}
- 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)
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);
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);
}
/**
}
}
}
- else {
+ else
+ {
// right clicks
_popup.show(this, e.getX(), e.getY());
}
_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);
}
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;
case TAG_THUMBNAIL_LENGTH:
_thumbnailLength = intVal;
break;
+ case TAG_GPS_BEARING:
+ _jpegData.setBearing(intVal);
+ break;
}
}
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
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
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
dialog.keys.keylist=<table><tr><td>Pylkie sleutels</td><td>Skuif kaart links regs, op, af</td></tr><tr><td>Ctrl + links, regs pylkie</td><td>Selekteer vorige of volgende punt</td></tr><tr><td>Ctrl + op, af pylkie</td><td>Vergroot in of uit</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Selekteer vorige, volgende segment</td></tr><tr><td>Ctrl + Home, Einde</td><td>Selekteer eerste, laaste punt</td></tr><tr><td>Del</td><td>Verwyder huidige punt</td></tr></table>
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
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
button.selectnone=Selekter geen
button.preview=Voorskou
button.load=Laai
-button.upload=Oplaai
button.guessfields=Raai velde
button.showwebpage=Wys webblad
button.check=Kontroleer
--- /dev/null
+# 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
+
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
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
dialog.keys.keylist=<table><tr><td>\u0160ipky</td><td>Posunout mapu vlevo, vpravo, nahoru, dol\u016f</td></tr><tr><td>Ctrl + \u0161ipka vlevo, vpravo</td><td>Vybrat p\u0159edchoz\u00ed nebo n\u00e1sleduj\u00edc\u00ed bod</td></tr><tr><td>Ctrl + \u0161ipka nahoru, dol\u016f</td><td>P\u0159ibl\u00ed\u017eit, odd\u00e1lit</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Vybrat p\u0159edchoz\u00ed, n\u00e1sleduj\u00edc\u00ed \u010d\u00e1st stopy</td></tr><tr><td>Ctrl + Home, End</td><td>Vybrat prvn\u00ed, posledn\u00ed bod</td></tr><tr><td>Del</td><td>Smazat aktu\u00e1ln\u00ed bod</td></tr></table>
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
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
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
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Pfeil Tasten</td><td>Karte verschieben</td></tr><tr><td>Strg + Links-, Rechts-Pfeil</td><td>Vorherigen oder n\u00e4chsten Punkt markieren</td></tr><tr><td>Strg + Auf-, Abw\u00e4rts-Pfeil</td><td>Ein- oder Auszoomen</td></tr><tr><td>Strg + Bild auf, ab</td><td>Zum vorherigen oder n\u00e4chsten Abschnitt</td></tr><tr><td>Strg + Pos1, Ende</td><td>Ersten oder letzten Punkt markieren</td></tr><tr><td>Entf</td><td>Aktuellen Punkt entfernen</td></tr></table>
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
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
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
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
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
# Field names
fieldname.latitude=Breitengrad
fieldname.longitude=L\u00e4ngengrad
+fieldname.coordinates=Koordinaten
fieldname.altitude=H\u00f6he
fieldname.timestamp=Zeitstempel
fieldname.time=Zeit
fieldname.speed=Geschwindigkeit
fieldname.verticalspeed=Vertikale Geschwindigkeit
fieldname.description=Beschreibung
+fieldname.comment=Anmerkung
fieldname.mediafilename=Foto- / Audioname
# Measurement units
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Pfiil Taste</td><td>Karte verschiebe</td></tr><tr><td>Strg + links, r\u00e4chts Pfiil</td><td>Vorherigi oder n\u00f6chsti Punkt markiere</td></tr><tr><td>Strg + uuf, aba Pfiil</td><td>Ii- oder Uusezoome</td></tr><tr><td>Strg + Bild uuf, ab</td><td>Vorherigi oder n\u00f6chsti Segm\u00e4nt markiere</td></tr><tr><td>Strg + Pos1, \u00c4nde</td><td>Erschti oder letschti Punkt markiere</td></tr><tr><td>Entf</td><td>Aktuelli Punkt l\u00f6sche</td></tr></table>
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
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
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
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.
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
# Field names
fieldname.latitude=Breitegrad
fieldname.longitude=L\u00e4ngegrad
+fieldname.coordinates=Koordinate
fieldname.altitude=H\u00f6chi
fieldname.timestamp=Ziitst\u00e4mpel
fieldname.time=Ziit
fieldname.speed=Gschwindikeit
fieldname.verticalspeed=Uf/Ab Gschwindikeit
fieldname.description=Bschriibig
+fieldname.comment=Aamerkig
fieldname.mediafilename=F\u00f6teli- / Audioname
# Measurement units
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Arrow keys</td><td>Pan map left right, up, down</td></tr><tr><td>Ctrl + left, right arrow</td><td>Select previous or next point</td></tr><tr><td>Ctrl + up, down arrow</td><td>Zoom in or out</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Select previous, next segment</td></tr><tr><td>Ctrl + Home, End</td><td>Select first, last point</td></tr><tr><td>Del</td><td>Delete current point</td></tr></table>
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
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
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
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
button.selectnone=Select none
button.preview=Preview
button.load=Load
-button.upload=Upload
button.guessfields=Guess fields
button.showwebpage=Show webpage
button.check=Check
# Field names
fieldname.latitude=Latitude
fieldname.longitude=Longitude
+fieldname.coordinates=Coordinates
fieldname.altitude=Altitude
fieldname.timestamp=Time
fieldname.time=Time
fieldname.speed=Speed
fieldname.verticalspeed=Vertical speed
fieldname.description=Description
+fieldname.comment=Comment
fieldname.mediafilename=Filename
# Measurement units
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
# 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
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
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
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
dialog.keys.keylist=<table><tr><td>Teclas de cursor</td><td>Desplazar a la izquierde, derecha, arriba, abajo</td></tr><tr><td>Ctrl + cursor izquierda, derecha</td><td>Seleccionar punto siguiente o anterior</td></tr><tr><td>Ctrl + cursor arriba, abajo</td><td>Ampliar o reducir zoom</td></tr><tr><td>Ctrl + Av Pag, Re Pag</td><td>Seleccionar segmento siguiente, anterior</td></tr><tr><td>Ctrl + Inicio, Fin</td><td>Seleccionar primer, \u00faltimo punto</td></tr><tr><td>Supr</td><td>Eliminar punto actual</td></tr></table>
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
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
## 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
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
## Field names
fieldname.latitude=Latitud
fieldname.longitude=Longitud
+fieldname.coordinates=Coordenadas
fieldname.altitude=Altitud
fieldname.timestamp=Informaci\u00f3n de tiempo
fieldname.time=Tiempo
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
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
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
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
dialog.keys.keylist=<table><tr><td>Nuolin\u00e4pp\u00e4imill\u00e4</td><td>voit siirt\u00e4\u00e4 kartaa vasemmalle, oikealle, yl\u00f6s ja alas</td></tr><tr><td>Ctrl + vasen/oikea nuoli\u00e4pp\u00e4in</td><td>Valitse edellinen/seuraava reittipiste</td></tr><tr><td>Ctrl + yl\u00f6s/alas nuolin\u00e4pp\u00e4in</td><td>L\u00e4henn\u00e4 tai loitonna</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Valitse edellinen/seuraava pistelohko</td></tr><tr><td>Ctrl + Home, End</td><td>Valitse ensimm\u00e4inen/viimeinen reittipiste</td></tr><tr><td>Del</td><td>Poista valittu reittipiste</td></tr></table>
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Touches-fl\u00e8ches</td><td>Faire d\u00e9filer la carte horizontalement et verticalement</td></tr><tr><td>Ctrl + gauche, Ctrl + droite</td><td>Choisir le point pr\u00e9c\u00e9dent ou suivant</td></tr><tr><td>Ctrl + haut, Ctrl + bas</td><td>Zoomer, s'\u00e9loigner</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Choisir le segment pr\u00e9c\u00e9dent ou suivant</td></tr><tr><td>Ctrl + Home, End</td><td>Choisir le point premier, dernier</td></tr><tr><td>Suppr</td><td>Effacer le point courant</td></tr></table>
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
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
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
# Field names
fieldname.latitude=Latitude
fieldname.longitude=Longitude
+fieldname.coordinates=Coordonn\u00e9es
fieldname.altitude=Altitude
fieldname.timestamp=Date et heure
fieldname.time=Temps
# 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
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
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
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
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
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
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
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
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?
dialog.keys.keylist=<table><tr><td>Ny\u00edlbillenty\u0171k</td><td>T\u00e9rk\u00e9p mozgat\u00e1sa balra, jobbra, fel, le</td></tr><tr><td>Ctrl + bal, jobb ny\u00edl</td><td>El\u0151z\u0151 vagy k\u00f6vetkez\u0151 pont kiv\u00e1laszt\u00e1sa</td></tr><tr><td>Ctrl + fel, le ny\u00edl</td><td>Nagy\u00edt\u00e1s vagy kicsiny\u00edt\u00e9s</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>El\u0151z\u0151, k\u00f6vetkez\u0151 szakasz kiv\u00e1laszt\u00e1sa</td></tr><tr><td>Ctrl + Home, End</td><td>Els\u0151, utols\u00f3 pont kiv\u00e1laszt\u00e1sa</td></tr><tr><td>Del</td><td>Jelenlegi pont t\u00f6rl\u00e9se</td></tr></table>
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
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
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
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
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
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Tasti freccia</td><td>Muovi mappa destra, sinistra, su, giu'</td></tr><tr><td>Ctrl + freccia destra, sinistra</td><td>Selezione punto successivo o precedente</td></tr><tr><td>Ctrl + freccia su, giu'</td><td>Zoom in o out</td></tr><tr><td>Ctrl + pagina su, giu'</td><td>Segmento successivo o precedente</tr><tr><td>Ctrl + Home, End</td><td>Punto primo o ultimo</td></tr><tr><td>Del</td><td>Cancella punto attuale</td></tr></table>
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
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
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
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
button.selectnone=Deseleziona tutto
button.preview=Anteprima
button.load=Carica
-button.upload=Caricato
button.guessfields=Campi soluzione
button.showwebpage=Mostra pagina
button.check=Controlla
# Field names
fieldname.latitude=Latitudine
fieldname.longitude=Longitudine
+fieldname.coordinates=Coordinate
fieldname.altitude=Altitudine
fieldname.timestamp=Dati temporali
fieldname.time=Tempo
fieldname.speed=Velocit\u00e0
fieldname.verticalspeed=Velocit\u00e0 verticale
fieldname.description=Descrizione
+fieldname.comment=Commento
fieldname.mediafilename=File
# Measurement units
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
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
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
dialog.keys.keylist=<table><tr><td>\u77e2\u5370\u30ad\u30fc</td><td>\u5730\u56f3\u3092\u4e0a\u4e0b\u5de6\u53f3\u306b\u79fb\u52d5</td></tr><tr><td>Ctrl + \u5de6\u30fb\u53f3\u77e2\u5370</td><td>\u524d\u30fb\u6b21\u306e\u70b9\u3092\u9078\u629e</td></tr><tr><td>Ctrl + \u4e0a\u30fb\u4e0b\u77e2\u5370</td><td>\u62e1\u5927\u30fb\u7e2e\u5c0f</td></tr><tr><td>Del</td><td>\u73fe\u5728\u306e\u70b9\u3092\u524a\u9664</td></tr></table>
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
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
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
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.
dialog.keys.keylist=<table><tr><td>\ud654\uc0b4\ud45c \ud0a4</td><td>\uc88c,\uc6b0,\uc544\ub798,\uc704\ub85c \uc9c0\ub3c4 \uc774\ub3d9</td></tr><tr><td>Ctrl + \uc67c\ucabd, \uc624\ub978\ucabd \ud654\uc0b4\ud45c</td><td>\uc9c0\uc810 \uc120\ud0dd \uc774\ub3d9</td></tr><tr><td>Ctrl + \uc704, \uc544\ub798 \ud654\uc0b4\ud45c</td><td>\uc9c0\ub3c4 \ud655\ub300 \ucd95\uc18c</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>\uc774\uc804 \uc774\ud6c4 \ubd80\ubd84 \uc120\ud0dd</td></tr><tr><td>Ctrl + Home, End</td><td>\ucc98\uc74c \uc9c0\uc810, \ub9c8\uc9c0\ub9c9 \uc9c0\uc810 \uc120\ud0dd</td></tr><tr><td>Del</td><td>\ud604\uc7ac \uc9c0\uc810 \uc0ad\uc81c</td></tr></table>
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.
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
# 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
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
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
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
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
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
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
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
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Pijltjestoetsen</td><td>verschuif de kaart links, rechts, omhoog, omlaag</td></tr><tr><td>Ctrl + pijltje naar links, rechts</td><td>Selecteer volgende, vorige punt</td></tr><tr><td>Ctrl + pijltje omhoog, omlaag</td><td>Zoom in of uit</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Selecteer vorig, volgend segment</td></tr><tr><td>Ctrl + Home, End</td><td>Select eerste, laatste punt</td></tr><tr><td>Del</td><td>Verwijder huidige punt</td></tr></table>
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
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
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
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
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.
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
button.selectnone=Selecteer niets
button.preview=Voorbeeld
button.load=Laden
-button.upload=Upload
button.guessfields=Raad velden
button.showwebpage=Toon webpagina
button.check=Controleren
button.manage=Beheer
button.combine=Samenvoegen
-# File types
+## File types
filetype.txt=TXT bestand
filetype.jpeg=JPG bestand
filetype.kmlkmz=KML, KMZ 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
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
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
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
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
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>klawisze strza\u0142ek</td><td>Przesuwa map\u0119 w lewo, w prawo, w g\u00f3r\u0119, w d\u00f3\u0142</td></tr><tr><td>Ctrl + lewa, prawa strza\u0142ka</td><td>Wybierz punkt poprzedni lub nast\u0119pny</td></tr><tr><td>Ctrl + strza\u0142ka w g\u00f3r\u0119, w d\u00f3\u0142</td><td>Powi\u0119ksz, pomniejsz</td></tr><tr><td>Del</td><td>Usun bie\u017c\u0105cy punkt</td></tr></table>
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Cursores</td><td>Move o mapa para esquerda, direita, acima e abaixo</td></tr><tr><td>Ctrl + cursores esquerdo e direito</td><td>Seleciona o pr\u00f3ximo ponto ou o anterior</td></tr><tr><td>Ctrl + cursores acima e abaixo</td><td>Amplia ou reduz</td></tr><tr><td>Del</td><td>Remove o ponto atual</td></tr></table>
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>Taste s\u0103ge\u021bi</td><td>Mut\u0103 harta st\u00e2nga, dreapta, sus, jos</td></tr><tr><td>Ctrl + s\u0103geat\u0103 st\u00e2nga, dreapta</td><td>Selecteaz\u0103 punctul anterior sau urm\u0103tor</td></tr><tr><td>Ctrl + s\u0103geat\u0103 sus, jos</td><td>Aproprie sau \u00eendep\u0103rteaz\u0103</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>Selecteaz\u0103 segmentul anterior sau urm\u0103tor</td></tr><tr><td>Ctrl + Home, End</td><td>Selecteaz\u0103 primul, ultimul punct</td></tr><tr><td>Del</td><td>\u0218terge punctul curent</td></tr></table>
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
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
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
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
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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td></td><td>\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</td><td><tr><td>Ctrl + \u043b\u0435\u0432\u0430\u044f, \u043f\u0440\u0430\u0432\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430</td><td>\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</td></tr><tr><td>Ctrl + \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u0432\u0432\u0435\u0440\u0445, \u0432\u043d\u0438\u0437 </td><td> \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</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>\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</td></tr><tr><td>Ctrl + Home, End</td><td>\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</td></tr><tr><td>Del</td><td>\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443</td></tr></table>
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
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
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
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
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
# 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
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
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
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
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
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
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
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,
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=<table><tr><td>Ok tu\u015flar\u0131</td><td>Haritay\u0131 sola/sa\u011fa/a\u015fa\u011f\u0131/yukar\u0131 kayd\u0131r</td></tr><tr><td>Ctrl + sol, sa\u011f</td><td>\u00d6nceki/sonraki noktay\u0131 se\u00e7</td></tr><tr><td>Ctrl + yukar/a\u015fa\u011f\u0131</td><td>Yak\u0131nla\u015ft\u0131r/Uzakla\u015ft\u0131r</td></tr><tr><td>Del</td><td>Se\u00e7ili noltay\u0131 sil</td></tr></table>
-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
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
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
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
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
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
dialog.keys.keylist=<table><tr><td>\u7bad\u5934</td><td>\u4e0a\u4e0b\u5de6\u53f3\u79fb\u52a8\u5730\u56fe</td></tr><tr><td>Ctrl + \u5de6\u53f3\u7bad\u5934</td><td>\u9009\u53d6\u524d\uff0c\u540e\u70b9</td></tr><tr><td>Ctrl + \u4e0a\u4e0b\u7bad\u5934</td><td>\u653e\u5927\u7f29\u5c0f</td></tr><tr><td>Ctrl + PgUp, PgDown</td><td>\u9009\u62e9\u524d\u540e\u6bb5</td></tr><tr><td>Ctrl + Home, End</td><td>\u9009\u62e9\u9996\u672b\u70b9</td></tr><tr><td>Del</td><td>\u5220\u9664\u5f53\u524d\u70b9</td></tr></table>
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
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
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
--- /dev/null
+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<size; i++)
+ {
+ if (result[i] == null)
+ result[i] = "";
+ else
+ {
+ if (result[i].length() > 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<String> inList)
+ {
+ // Convert into String array for keeps
+ int numLines = inList.size();
+ _contentArray = new String[numLines];
+ for (int i=0; i<numLines; i++)
+ {
+ _contentArray[i] = inList.get(i);
+ }
+ }
+}
* Class to load the contents of a file
* into an array for later retrieval
*/
-public class FileCacher
+public class FileCacher extends ContentCacher
{
- /** File to cache */
- private File _file = null;
- /** Array to hold lines of file */
- private String[] _contentArray = null;
-
-
/**
* Constructor
* @param inFile File object to cache
*/
public FileCacher(File inFile)
{
- _file = inFile;
- loadFile();
+ loadFile(inFile);
}
/**
* Load the specified file into memory
*/
- private void loadFile()
+ private void loadFile(File inFile)
{
ArrayList<String> contentList = new ArrayList<String>();
- 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("<?xml")) {
return; // it's an xml file, it shouldn't use this cacher
catch (Exception e) {}
}
}
- // Convert into String array for keeps
- int numLines = contentList.size();
- _contentArray = new String[numLines];
- for (int i=0; i<numLines; i++)
- _contentArray[i] = contentList.get(i);
- }
-
-
- /**
- * @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<size; i++)
- {
- if (result[i] == null)
- result[i] = "";
- else
- {
- if (result[i].length() > 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);
}
}
*/
public class FileSplitter
{
- private FileCacher _cacher = null;
+ private ContentCacher _cacher = null;
private int _numRows = 0;
private int _numColumns = 0;
private boolean[] _columnStates = null;
/**
* 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;
}
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;
}
--- /dev/null
+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<String> contentList = new ArrayList<String>();
+ if (inText != null)
+ {
+ for (String currLine : inText.split("\n"))
+ {
+ if (currLine != null)
+ {
+ currLine = currLine.trim();
+ if (currLine.length() > 0) {
+ contentList.add(currLine);
+ }
+ }
+ }
+ }
+ setContents(contentList);
+ }
+}
private JTextField _otherDelimiterText = null;
private JLabel _statusLabel = null;
private DelimiterInfo[] _delimiterInfos = null;
- private FileCacher _fileCacher = null;
+ private ContentCacher _contentCacher = null;
private JList<String> _snippetBox = null;
private FileExtractTableModel _fileExtractTableModel = null;
private JTable _fieldTable;
_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
{
/**
- * 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)
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;
String currLine = null;
String[] splitFields = null;
int commaFields = 0, semicolonFields = 0, tabFields = 0, spaceFields = 0;
- for (int lineNum=0; lineNum<fileContents.length && fileOK; lineNum++)
+ for (int lineNum=0; lineNum<contents.length && fileOK; lineNum++)
{
- currLine = fileContents[lineNum];
+ currLine = contents[lineNum];
// check for invalid characters
if (currLine.indexOf('\0') >= 0) {fileOK = false;}
// check for commas
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
delimsPanel.add(_statusLabel);
firstCard.add(delimsPanel, BorderLayout.SOUTH);
// load snippet to show first few lines
- _snippetBox = new JList<String>(_fileCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH));
+ _snippetBox = new JList<String>(_contentCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH));
_snippetBox.setEnabled(false);
firstCard.add(makeLabelledPanel("dialog.openoptions.filesnippet", _snippetBox), BorderLayout.CENTER);
*/
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];
}
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
_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()];
_app.informDataLoaded(_fieldTableModel.getFieldArray(),
_fileExtractTableModel.getData(), options, sourceInfo, null);
// clear up file cacher
- _fileCacher.clear();
+ _contentCacher.clear();
// dispose of dialog
_dialog.dispose();
}
-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.
=======
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
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
===================
===============================
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
{
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)
{
final Track track = _app.getTrackInfo().getTrack();
final int numPoints = track.getNumPoints();
int prevX = 0, prevY = 0;
+ boolean gotPreviousPoint = false;
for (int i=0; i<numPoints; i++)
{
DataPoint point = track.getPoint(i);
// use zoom level to calculate pixel coords on image
int px = (int) (x * zoomFactor * 256), py = (int) (y * zoomFactor * 256);
// System.out.println("Point: x=" + x + ", px=" + px + ", y=" + y + ", py=" + py);
- if (!point.getSegmentStart()) {
+ if (!point.getSegmentStart() && gotPreviousPoint) {
// draw from previous point to this one
g.drawLine(prevX, prevY, px, py);
}
}
// save coordinates
prevX = px; prevY = py;
+ gotPreviousPoint = true;
}
}
}
// Set text size according to input
int fontScalePercent = _textScaleField.getValue();
- if (fontScalePercent > 10 && fontScalePercent <= 999)
+ if (fontScalePercent > 0 && fontScalePercent <= 999)
{
Font gFont = g.getFont();
g.setFont(gFont.deriveFont((float) (gFont.getSize() * 0.01 * fontScalePercent)));
for (int i=0; i<numPoints; i++)
{
DataPoint point = track.getPoint(i);
- if (point.isWaypoint())
+ if (point.isWaypoint() && fontScalePercent > 0)
{
double x = track.getX(i) - xRange.getMinimum();
double y = track.getY(i) - yRange.getMinimum();