[gpsprune] 01/04: Imported Upstream version 18.5
Bas Couwenberg
sebastic at debian.org
Tue Jul 26 11:15:19 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository gpsprune.
commit 7734d058cfb75afe8aad4d9c844143b6f5f78f9d
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Tue Jul 26 12:44:12 2016 +0200
Imported Upstream version 18.5
---
build.sh | 2 +-
tim/prune/GpsPrune.java | 4 +-
tim/prune/function/AboutScreen.java | 3 +-
.../function/gpsies/UploadGpsiesFunction.java | 5 +-
tim/prune/gui/map/DiskTileCacher.java | 35 +++----
tim/prune/gui/map/MapCanvas.java | 4 +-
tim/prune/gui/map/MapTile.java | 32 ++++++
tim/prune/gui/map/MapTileManager.java | 41 ++++----
tim/prune/gui/profile/ProfileChart.java | 5 +-
tim/prune/lang/prune-texts_cz.properties | 8 ++
tim/prune/lang/prune-texts_es.properties | 5 +
tim/prune/lang/prune-texts_ru.properties | 29 ++++--
tim/prune/lang/prune-texts_uk.properties | 10 ++
tim/prune/readme.txt | 15 ++-
tim/prune/save/GpsSaver.java | 5 +-
tim/prune/save/GpxExporter.java | 108 +++++++++++----------
tim/prune/save/SettingsForExport.java | 66 +++++++++++++
17 files changed, 263 insertions(+), 114 deletions(-)
diff --git a/build.sh b/build.sh
index e4f7081..3c157d7 100644
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
# Build script using external exif library
# Version number
-PRUNENAME=gpsprune_18.4
+PRUNENAME=gpsprune_18.5
# remove compile directory
rm -rf compile
# remove dist directory
diff --git a/tim/prune/GpsPrune.java b/tim/prune/GpsPrune.java
index 606e61c..ad71987 100644
--- a/tim/prune/GpsPrune.java
+++ b/tim/prune/GpsPrune.java
@@ -36,9 +36,9 @@ import tim.prune.gui.profile.ProfileChart;
public class GpsPrune
{
/** Version number of application, used in about screen and for version check */
- public static final String VERSION_NUMBER = "18.4";
+ public static final String VERSION_NUMBER = "18.5";
/** Build number, just used for about screen */
- public static final String BUILD_NUMBER = "340";
+ public static final String BUILD_NUMBER = "342";
/** Static reference to App object */
private static App APP = null;
diff --git a/tim/prune/function/AboutScreen.java b/tim/prune/function/AboutScreen.java
index c6bd759..d2f5712 100644
--- a/tim/prune/function/AboutScreen.java
+++ b/tim/prune/function/AboutScreen.java
@@ -168,6 +168,7 @@ public class AboutScreen extends GenericFunction
creditsPanel.setLayout(gridBag);
constraints = new GridBagConstraints();
constraints.weightx = 0.0; constraints.weighty = 0.0;
+ constraints.ipady = 3;
addToGridBagPanel(creditsPanel, gridBag, constraints,
new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
@@ -200,7 +201,7 @@ public class AboutScreen extends GenericFunction
new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d, Gy\u00F6rgy,"),
1, 5);
addToGridBagPanel(creditsPanel, gridBag, constraints,
- new JLabel(" HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian"),
+ new JLabel(" HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian, Roman"),
1, 6);
addToGridBagPanel(creditsPanel, gridBag, constraints,
new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
diff --git a/tim/prune/function/gpsies/UploadGpsiesFunction.java b/tim/prune/function/gpsies/UploadGpsiesFunction.java
index 9a4ae30..3cef9db 100644
--- a/tim/prune/function/gpsies/UploadGpsiesFunction.java
+++ b/tim/prune/function/gpsies/UploadGpsiesFunction.java
@@ -39,6 +39,7 @@ 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
@@ -279,9 +280,9 @@ public class UploadGpsiesFunction extends GenericFunction
_writer = new OutputStreamWriter(oStream);
new Thread(new Runnable() {
public void run() {
- boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
try {
- GpxExporter.exportData(_writer, _app.getTrackInfo(), _nameField.getText(), null, saveFlags, null);
+ GpxExporter.exportData(_writer, _app.getTrackInfo(), _nameField.getText(),
+ null, new SettingsForExport(), null);
} catch (IOException e) {}
finally {
try {_writer.close();} catch (IOException e) {}
diff --git a/tim/prune/gui/map/DiskTileCacher.java b/tim/prune/gui/map/DiskTileCacher.java
index 63dc684..fd2042a 100644
--- a/tim/prune/gui/map/DiskTileCacher.java
+++ b/tim/prune/gui/map/DiskTileCacher.java
@@ -46,10 +46,9 @@ public class DiskTileCacher implements Runnable
* Get the specified tile from the disk cache
* @param inBasePath base path to whole disk cache
* @param inTilePath relative path to requested tile
- * @param inCheckAge true to check age of file, false to ignore
* @return tile image if available, or null if not there
*/
- public static Image getTile(String inBasePath, String inTilePath, boolean inCheckAge)
+ public static MapTile getTile(String inBasePath, String inTilePath)
{
if (inBasePath == null) {return null;}
File tileFile = new File(inBasePath, inTilePath);
@@ -57,17 +56,17 @@ public class DiskTileCacher implements Runnable
if (tileFile.exists() && tileFile.canRead() && tileFile.length() > 0)
{
long fileStamp = tileFile.lastModified();
- if (!inCheckAge || ((System.currentTimeMillis()-fileStamp) < CACHE_TIME_LIMIT))
+ boolean isExpired = ((System.currentTimeMillis()-fileStamp) > CACHE_TIME_LIMIT);
+ try
{
- try {
- image = Toolkit.getDefaultToolkit().createImage(tileFile.getAbsolutePath());
- }
- catch (Exception e) {
- System.err.println("createImage: " + e.getClass().getName() + " _ " + e.getMessage());
- }
+ image = Toolkit.getDefaultToolkit().createImage(tileFile.getAbsolutePath());
+ return new MapTile(image, isExpired);
+ }
+ catch (Exception e) {
+ System.err.println("createImage: " + e.getClass().getName() + " _ " + e.getMessage());
}
}
- return image;
+ return null;
}
/**
@@ -76,31 +75,28 @@ public class DiskTileCacher implements Runnable
* @param inBasePath base path to disk cache
* @param inTilePath relative path to this tile
* @param inObserver observer to inform when load complete
- * @return true if successful, false for failure
*/
- public static boolean saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver)
+ public static void saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver)
{
- if (inBasePath == null || inTilePath == null) {return false;}
+ if (inBasePath == null || inTilePath == null) {return;}
// save file if possible
File basePath = new File(inBasePath);
if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) {
// Can't write to base path
- return false;
+ return;
}
File tileFile = new File(basePath, inTilePath);
// Check if this file is already being loaded
- if (isBeingLoaded(tileFile)) {return true;}
+ if (isBeingLoaded(tileFile)) {return;}
// Check if it has already failed
- if (BLOCKED_URLS.contains(inUrl.toString())) {return true;}
+ if (BLOCKED_URLS.contains(inUrl.toString())) {return;}
File dir = tileFile.getParentFile();
// Start a new thread to load the image if necessary
if ((dir.exists() || dir.mkdirs()) && dir.canWrite())
{
new Thread(new DiskTileCacher(inUrl, tileFile, inObserver)).start();
- return true;
}
- return false; // couldn't write the file
}
/**
@@ -141,6 +137,7 @@ public class DiskTileCacher implements Runnable
{
// Open streams from URL and to file
out = new FileOutputStream(tempFile);
+ //System.out.println("Opening URL: " + _url.toString());
// Set http user agent on connection
URLConnection conn = _url.openConnection();
conn.setRequestProperty("User-Agent", "GpsPrune v" + GpsPrune.VERSION_NUMBER);
@@ -165,7 +162,7 @@ public class DiskTileCacher implements Runnable
}
}
// Move temp file to desired file location
- if (!tempFile.renameTo(_file))
+ if (tempFile.exists() && !tempFile.renameTo(_file))
{
// File couldn't be moved - delete both to be sure
tempFile.delete();
diff --git a/tim/prune/gui/map/MapCanvas.java b/tim/prune/gui/map/MapCanvas.java
index 4221520..5711951 100644
--- a/tim/prune/gui/map/MapCanvas.java
+++ b/tim/prune/gui/map/MapCanvas.java
@@ -705,7 +705,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
anyWaypoints = anyWaypoints || isWaypoint;
if (!isWaypoint)
{
- if ((currPointVisible || prevPointVisible) && drawPoints)
+ if (currPointVisible || (drawLines && prevPointVisible))
{
// For track points, work out which colour to use
if (_track.getPoint(i).getDeleteFlag()) {
@@ -722,7 +722,7 @@ public class MapCanvas extends JPanel implements MouseListener, MouseMotionListe
}
// Draw rectangle for track point if it's visible
- if (currPointVisible)
+ if (currPointVisible && drawPoints)
{
inG.drawRect(px-2, py-2, 3, 3);
pointsPainted++;
diff --git a/tim/prune/gui/map/MapTile.java b/tim/prune/gui/map/MapTile.java
new file mode 100644
index 0000000..36a494d
--- /dev/null
+++ b/tim/prune/gui/map/MapTile.java
@@ -0,0 +1,32 @@
+package tim.prune.gui.map;
+
+import java.awt.Image;
+
+/**
+ * Simple wrapper to hold an image for a map tile
+ * and a boolean flag to show whether it's expired or not
+ */
+public class MapTile
+{
+ /** Image or null if no image available */
+ private Image _image = null;
+ /** True if image expired, false if still fresh */
+ private boolean _expired = false;
+
+ /** Constructor */
+ public MapTile(Image inImage, boolean inExpired)
+ {
+ _image = inImage;
+ _expired = inExpired;
+ }
+
+ /** Get the image */
+ public Image getImage() {
+ return _image;
+ }
+
+ /** Return true if image is too old */
+ public boolean isExpired() {
+ return _expired;
+ }
+}
diff --git a/tim/prune/gui/map/MapTileManager.java b/tim/prune/gui/map/MapTileManager.java
index ed8849b..f7370c5 100644
--- a/tim/prune/gui/map/MapTileManager.java
+++ b/tim/prune/gui/map/MapTileManager.java
@@ -155,14 +155,14 @@ public class MapTileManager implements ImageObserver
inX = ((inX % _numTileIndices) + _numTileIndices) % _numTileIndices;
// Check first in memory cache for tile
- Image tile = null;
+ Image tileImage = null;
MemTileCacher tempCache = null;
if (_tempCaches != null)
{
tempCache = _tempCaches[inLayer]; // Should probably guard array indexes here
- tile = tempCache.getTile(inX, inY);
- if (tile != null) {
- return tile;
+ tileImage = tempCache.getTile(inX, inY);
+ if (tileImage != null) {
+ return tileImage;
}
}
@@ -170,32 +170,37 @@ public class MapTileManager implements ImageObserver
String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
boolean useDisk = (diskCachePath != null);
boolean onlineMode = Config.getConfigBoolean(Config.KEY_ONLINE_MODE);
+ MapTile mapTile = null;
if (useDisk)
{
- tile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY), onlineMode);
- if (tile != null)
+ // Get the map tile from cache
+ mapTile = DiskTileCacher.getTile(diskCachePath, _mapSource.makeFilePath(inLayer, _zoom, inX, inY));
+ if (mapTile != null && mapTile.getImage() != null)
{
- if (_returnIncompleteImages) {return tile;}
+ tileImage = mapTile.getImage();
+ if (_returnIncompleteImages) {return tileImage;}
// Pass tile to memory cache
if (tempCache != null) {
- tempCache.setTile(tile, inX, inY, _zoom);
+ tempCache.setTile(tileImage, inX, inY, _zoom);
}
- if (tile.getWidth(this) > 0) {return tile;}
- return null;
+ tileImage.getWidth(this); // trigger the load from file
}
- // else System.out.println("DTC gave null tile for " + _zoom + ", " + inX + ", " + inY);
}
- // Tile wasn't in memory or on disk, so if online let's get it
- if (onlineMode && _downloadTiles && inDownloadIfNecessary)
+ // Maybe we've got an image now, maybe it's expired
+ final boolean shouldDownload = (tileImage == null || mapTile == null || mapTile.isExpired());
+
+ // If we're online then try to download the tile
+ if (onlineMode && _downloadTiles && inDownloadIfNecessary && shouldDownload)
{
try
{
URL tileUrl = new URL(_mapSource.makeURL(inLayer, _zoom, inX, inY));
- // System.out.println("Going to fetch: " + tileUrl);
- if (useDisk && DiskTileCacher.saveTile(tileUrl, diskCachePath,
- _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this))
+ //System.out.println("Trying to fetch: " + tileUrl);
+ if (useDisk)
{
- // Image now copied directly from URL stream to disk cache
+ DiskTileCacher.saveTile(tileUrl, diskCachePath,
+ _mapSource.makeFilePath(inLayer, _zoom, inX, inY), this);
+ // Image will now be copied directly from URL stream to disk cache
}
else
{
@@ -206,7 +211,7 @@ public class MapTileManager implements ImageObserver
}
catch (MalformedURLException urle) {} // ignore
}
- return null;
+ return tileImage;
}
/**
diff --git a/tim/prune/gui/profile/ProfileChart.java b/tim/prune/gui/profile/ProfileChart.java
index b2d0d0d..6e21996 100644
--- a/tim/prune/gui/profile/ProfileChart.java
+++ b/tim/prune/gui/profile/ProfileChart.java
@@ -136,8 +136,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener
// horizontal lines for scale - set to round numbers eg 500
int lineScale = getLineScale(minValue, maxValue);
- int scaleValue = (int) (minValue/lineScale + 1) * lineScale;
- if (minValue < 0.0) {scaleValue -= lineScale;}
+ double scaleValue = Math.ceil(minValue/lineScale) * lineScale;
int x = 0, y = 0;
final int zeroY = height - BORDER_WIDTH - (int) (yScaleFactor * (0.0 - minValue));
@@ -223,7 +222,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener
if (y < (BORDER_WIDTH + textHeight)) {
y = BORDER_WIDTH + textHeight;
}
- g.drawString(""+scaleValue, BORDER_WIDTH + 5, y);
+ g.drawString(""+(int)scaleValue, BORDER_WIDTH + 5, y);
scaleValue += lineScale;
}
}
diff --git a/tim/prune/lang/prune-texts_cz.properties b/tim/prune/lang/prune-texts_cz.properties
index 0d8c177..c060e88 100644
--- a/tim/prune/lang/prune-texts_cz.properties
+++ b/tim/prune/lang/prune-texts_cz.properties
@@ -39,6 +39,7 @@ menu.view.browser.yahoo=Mapy Yahoo
menu.view.browser.bing=Mapy Bing
menu.settings=Nastaven\u00ed
menu.settings.onlinemode=Na\u010d\u00edtat mapy z internetu
+menu.settings.antialias=Pou\u017e\u00edt antialiasing
menu.settings.autosave=P\u0159i ukon\u010den\u00ed automaticky ukl\u00e1dat
menu.help=Pomoc
# Popup menu for map
@@ -111,6 +112,8 @@ 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
function.searchwikipedianames=Hledat na Wikipedii podle jm\u00e9na
+function.searchopencachingde=Hledat na OpenCaching.de
+function.mapillary=Hledat fotografie v Mapillary
function.downloadosm=St\u00e1hnout data OSM pro oblast
function.duplicatepoint=Zdvojit bod
function.setcolours=Nastavit barvy
@@ -376,6 +379,7 @@ dialog.gpsies.activity.sailing=Lo\u010f
dialog.gpsies.activity.skating=Bruslen\u00ed
dialog.wikipedia.column.name=N\u00e1zev \u010dl\u00e1nku
dialog.wikipedia.column.distance=Vzd\u00e1lenost
+dialog.wikipedia.gallery=Galerie
dialog.correlate.notimestamps=U bod\u016f nejsou \u010dasov\u00e9 zna\u010dky, tak\u017ee nen\u00ed s \u010d\u00edm fotografie sladit.
dialog.correlate.nouncorrelatedphotos=V\u0161echny fotografie jsou slad\u011bn\u00e9.\nOpravdu chcete pokra\u010dovat?
dialog.correlate.nouncorrelatedaudios=V\u0161echny audionahr\u00e1vky jsou slad\u011bn\u00e9.\nOpravdu chcete pokra\u010dovat?
@@ -562,6 +566,7 @@ dialog.weather.day.sunday=Ned\u011ble
dialog.weather.temp=Teplota
dialog.weather.humidity=Vlhkost
dialog.weather.creditnotice=Data poskytuje slu\u017eba openweathermap.org, v\u00edce informac\u00ed na t\u00e9to adrese.
+dialog.deletebydate.column.delete=Smazat
# 3d window
dialog.3d.title=Trojrozm\u011brn\u00e9 zobrazen\u00ed GpsPrune
@@ -769,6 +774,9 @@ logic.or=nebo
url.googlemaps=maps.google.cz
wikipedia.lang=cs
openweathermap.lang=en
+webservice.peakfinder=Otev\u0159\u00edt Peakfinder.org
+webservice.geohack=Otev\u0159\u00edt Geohack
+webservice.panoramio=Otev\u0159\u00edt Panoramio
# Cardinals for 3d plots
cardinal.n=N
diff --git a/tim/prune/lang/prune-texts_es.properties b/tim/prune/lang/prune-texts_es.properties
index f5d6214..d8c19aa 100644
--- a/tim/prune/lang/prune-texts_es.properties
+++ b/tim/prune/lang/prune-texts_es.properties
@@ -591,6 +591,8 @@ dialog.weather.humidity=Humedad
dialog.deletebydate.nodate=Sin marcas de tiempo
dialog.deletebydate.column.keep=Mantener
dialog.deletebydate.column.delete=Eliminar
+dialog.setaltitudetolerance.text.metres=Limite (en metros) por debajo de cual pequeñas subidas o bajadas serán ignoradas
+dialog.setaltitudetolerance.text.feet=Limite (en pies) por debajo de cual pequeñas subidas o bajadas serán ignoradas
dialog.autoplay.duration=Duraci\u00f3n (seg)
dialog.autoplay.usetimestamps=Usar informaci\u00f3n de tiempo
dialog.autoplay.rewind=Rebobinar
@@ -641,6 +643,9 @@ confirm.correlateaudios.multi=Los audios fueron correlacionados
## Tips, shown just once when appropriate
tip.title=Sugerencia
+tip.useamapcache=By setting up a disk cache (Preferencias -> Guardar mapas en disco)\nyou can speed up the display and reduce network traffic.
+tip.learntimeparams=The results will be more accurate if you use\nTrack -> Apprender parametros por la estimaci\u00f3n del tiempo\non your recorded tracks.
+tip.downloadsrtm=You can speed this up by calling\nOnline -> Descargar datos de SRTM\nto save the data in your map cache.
tip.manuallycorrelateone=Correlacionando al menos una foto manualmente, el margen de tiempo se calcula autom\u00e1ticamente.
## Buttons
diff --git a/tim/prune/lang/prune-texts_ru.properties b/tim/prune/lang/prune-texts_ru.properties
index 87a20b1..6e6e8d7 100644
--- a/tim/prune/lang/prune-texts_ru.properties
+++ b/tim/prune/lang/prune-texts_ru.properties
@@ -1,5 +1,5 @@
# Text entries for the GpsPrune application
-# Russian entries thanks to Sergey
+# Russian entries thanks to Sergey, Roman
# Menu entries
menu.file=\u0424\u0430\u0439\u043b
@@ -13,7 +13,6 @@ 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 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\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
-function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b
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
@@ -38,19 +37,20 @@ menu.view.browser.mapquest=Mapquest
menu.view.browser.yahoo=Yahoo maps
menu.view.browser.bing=Bing maps
menu.settings=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-menu.settings.onlinemode=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442
+menu.settings.onlinemode=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430
+menu.settings.antialias=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435
menu.settings.autosave=\u0410\u0432\u0442\u043e\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435
menu.help=\u041f\u043e\u043c\u043e\u0449\u044c
# Popup menu for map
menu.map.zoomin=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c
menu.map.zoomout=\u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c
-menu.map.zoomfull=\u0423\u0432\u0435\u043b\u0447\u0438\u0442\u044c \u0434\u043e \u043f\u043e\u043b\u043d\u043e\u0439 \u0448\u043a\u0430\u043b\u044b
+menu.map.zoomfull=\u0423\u0432\u0435\u043b\u0447\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e
menu.map.newpoint=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0442\u043e\u0447\u043a\u0443
menu.map.drawpoints=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0447\u0435\u043a
menu.map.connect=\u0421\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u0442\u0440\u0435\u043a\u0430 \u0441 \u043b\u0438\u043d\u0438\u0435\u0439
menu.map.autopan=\u041e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435
menu.map.showmap=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u041e\u0421\u041c-\u043a\u0430\u0440\u0442\u0443
-menu.map.showscalebar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043b\u0438\u043d\u0435\u0439\u043a\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430
+menu.map.showscalebar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0448\u043a\u0430\u043b\u0443 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430
menu.map.editmode=\u0420\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
# Alt keys for menus
@@ -86,11 +86,14 @@ function.exportsvg=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 SVG
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.marklifts=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u043f\u043e\u0434\u044a\u0451\u043c\u0438\u043d\u0438\u043a \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.interpolate=\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f \u0442\u043e\u0447\u0435\u043a
+function.interpolate=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0447\u0435\u043a\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b
+function.deletebydate=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u043f\u043e \u0434\u0430\u0442\u0435
function.addtimeoffset=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
function.addaltitudeoffset=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u043a\u0443 \u0432\u044b\u0441\u043e\u0442\u044b
+function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b
function.convertnamestotimes=\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u0443\u0442\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f
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
@@ -104,6 +107,7 @@ function.learnestimationparams=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\
function.autoplay=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435
function.setmapbg=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0443-\u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0443
function.setpaths=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u0438 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c
+function.selectsegment=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442
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.getgpsies=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0438
@@ -112,6 +116,8 @@ function.lookupsrtm=\u0412\u044b\u0441\u043e\u0442\u044b \u0432 SRTM
function.downloadsrtm=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c STRM
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.searchwikipedianames=\u041f\u043e\u0438\u0441\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0432 \u0412\u0438\u043a\u0438 \u043f\u043e \u0438\u043c\u0435\u043d\u0438
+function.searchopencachingde=\u041f\u043e\u0438\u0441\u043a OpenCaching.de
+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 \u0442\u0435\u0440\u0440\u0438\u0442\u043e\u0440\u0438\u044e
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.setcolours=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430
@@ -139,6 +145,7 @@ function.saveconfig=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u044
function.diskcache=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u0434\u0438\u0441\u043a
function.managetilecache=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0435\u0448\u0435\u043c
function.getweatherforecast=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b
+function.setaltitudetolerance=\u0417\u0430\u0434\u0430\u0442\u044c \u043e\u0433\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u044b
# Dialogs
dialog.exit.confirm.title=\u0412\u044b\u0445\u043e\u0434
@@ -186,6 +193,7 @@ dialog.gpssend.sendtracks=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0442\u044
dialog.gpssend.trackname=\u0418\u043c\u044f \u0442\u0440\u0435\u043a\u0430
dialog.gpsbabel.filters=\u0424\u0438\u043b\u044c\u0442\u0440\u044b
dialog.addfilter.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
+dialog.gpsbabel.filter.simplify=\u0421\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c
dialog.gpsbabel.filter.distance=\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435
dialog.gpsbabel.filter.interpolate=\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f
dialog.gpsbabel.filter.discard.numsats=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u0443\u0442\u043d\u0438\u043a\u043e\u0432 <
@@ -388,6 +396,7 @@ dialog.rearrange.toend=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0
dialog.rearrange.tonearest=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439
dialog.rearrange.nosort=\u041d\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
dialog.rearrange.sortbyfilename=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430
+dialog.rearrange.sortbyname=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0438\u043c\u0435\u043d\u0438
dialog.rearrange.sortbytime=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438
dialog.compress.closepoints.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0431\u043b\u0438\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u0447\u0435\u043a
dialog.compress.closepoints.paramdesc=\u0420\u0430\u0437\u043c\u0430\u0445
@@ -534,7 +543,7 @@ dialog.weather.day.sunday=\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d
dialog.weather.wind=\u0412\u0435\u0442\u0435\u0440
dialog.weather.temp=\u0422\u00b0
dialog.weather.humidity=\u0412\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c
-dialog.weather.creditnotice=\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 openweathermap.org.
+dialog.weather.creditnotice=\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 openweathermap.org.
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
@@ -688,6 +697,7 @@ fieldname.longitude=\u0414\u043e\u043b\u0433\u043e\u0442\u0430
fieldname.altitude=\u0412\u044b\u0441\u043e\u0442\u0430
fieldname.timestamp=\u0412\u0440\u0435\u043c\u044f
fieldname.time=\u0412\u0440\u0435\u043c\u044f
+fieldname.date=\u0414\u0430\u0442\u0430
fieldname.waypointname=\u0418\u043c\u044f
fieldname.waypointtype=\u0422\u0438\u043f
fieldname.newsegment=\u0421\u0435\u0433\u043c\u0435\u043d\u0442
@@ -738,10 +748,13 @@ units.degreesfahrenheit.short=\u00b0F
logic.and=\u0438
logic.or=\u0438\u043b\u0438
-# External urls
+# External urls and services
url.googlemaps=maps.google.ru
wikipedia.lang=ru
openweathermap.lang=ru
+webservice.peakfinder=\u041e\u0442\u043a\u0440\u044b\u0442\u044c Peakfinder.org
+webservice.geohack=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 Geohack
+webservice.panoramio=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u0430\u0440\u0442\u0443 Panoramio
# Cardinals for 3d plots
cardinal.n=\u0421\u0435\u0432\u0435\u0440
diff --git a/tim/prune/lang/prune-texts_uk.properties b/tim/prune/lang/prune-texts_uk.properties
index 9624351..ddfb0ac 100644
--- a/tim/prune/lang/prune-texts_uk.properties
+++ b/tim/prune/lang/prune-texts_uk.properties
@@ -54,6 +54,7 @@ menu.map.editmode=\u0420\u0435\u0436\u0438\u043c \u0440\u0435\u0434\u0430\u0433\
# Alt keys for menus
altkey.menu.file=F
+altkey.menu.online=N
altkey.menu.track=T
altkey.menu.range=R
altkey.menu.point=P
@@ -87,6 +88,7 @@ function.compress=\u0421\u0442\u0438\u0441\u043d\u0443\u0442\u0438 \u0442\u0440\
function.deleterange=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b
function.croptrack=\u041e\u0431\u0440\u0456\u0437\u0430\u0442\u0438 \u0442\u0440\u0435\u043a
function.interpolate=\u0406\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0456\u044f \u0442\u043e\u0447\u043e\u043a
+function.deletebydate=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u0437\u0430 \u0434\u0430\u0442\u043e\u044e
function.addtimeoffset=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0447\u0430\u0441\u0443
function.addaltitudeoffset=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0432\u0438\u0441\u043e\u0442\u0438
function.rearrangewaypoints=\u041f\u0435\u0440\u0435\u0432\u0438\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0438
@@ -102,9 +104,13 @@ function.estimatetime=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u0438\u04
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.setpaths=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0448\u043b\u044f\u0445\u0438 \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c
+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.searchwikipedianames=\u041f\u043e\u0448\u0443\u043a \u0441\u0442\u0430\u0442\u0435\u0439 \u0437 \u0412\u0456\u043a\u0456\u043f\u0435\u0434\u0456\u0457 \u0437\u0430 \u043d\u0430\u0437\u0432\u043e\u044e
function.downloadosm=\u0417\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 OSM-\u0434\u0430\u043d\u0456 \u043d\u0430 \u0442\u0435\u0440\u0438\u0442\u043e\u0440\u0456\u044e
@@ -236,12 +242,16 @@ button.no=\u041d\u0456
# Display components
display.nodata=\u0416\u043e\u0434\u043d\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e
details.trackdetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0442\u0440\u0435\u043a\u0443
+details.notrack=\u0416\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0443 \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e
details.track.points=\u0422\u043e\u0447\u043a\u0438
details.track.file=\u0424\u0430\u0439\u043b
details.pointdetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0442\u043e\u0447\u043a\u0438
details.nopointselection=\u0422\u043e\u0447\u043a\u0443 \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
details.norangeselection=\u0414\u0456\u0430\u043f\u0430\u0437\u043e\u043d \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
details.rangedetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0443
+details.coordformat=\u0424\u043e\u0440\u043c\u0430\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442
+details.distanceunits=\u041e\u0434\u0438\u043d\u0438\u0446\u0456 \u0432\u0456\u0434\u0441\u0442\u0430\u043d\u0456
+details.lists.waypoints=\u0428\u043b\u044f\u0445\u043e\u0432\u0456 \u0442\u043e\u0447\u043a\u0438
details.lists.photos=\u0421\u0432\u0456\u0442\u043b\u0438\u043d\u0438
details.photodetails=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0441\u0432\u0456\u0442\u043b\u0438\u043d\u0438
details.nophoto=\u0421\u0432\u0456\u0442\u043b\u0438\u043d\u0443 \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u043e
diff --git a/tim/prune/readme.txt b/tim/prune/readme.txt
index d4996f7..afde04b 100644
--- a/tim/prune/readme.txt
+++ b/tim/prune/readme.txt
@@ -1,4 +1,4 @@
-GpsPrune version 18.4
+GpsPrune version 18.5
=====================
GpsPrune is an application for viewing, editing and managing coordinate data from GPS systems,
@@ -17,7 +17,7 @@ Running
=======
To run GpsPrune from the jar file, simply call it from a command prompt or shell:
- java -jar gpsprune_18.4.jar
+ java -jar gpsprune_18.5.jar
If the jar file is saved in a different directory, you will need to include the path.
Depending on your system settings, you may be able to click or double-click on the jar file
@@ -25,9 +25,18 @@ in a file manager window to execute it. A shortcut, menu item, alias, desktop i
or other link can of course be made should you wish.
To specify a language other than the default, use an additional parameter, eg:
- java -jar gpsprune_18.4.jar --lang=DE
+ java -jar gpsprune_18.5.jar --lang=DE
+New with version 18.5
+=====================
+The following fixes and additions were made since version 18.4:
+ - When points have no altitudes, send them to a GPS with altitude 0 (prevents weird values when reading back)
+ - When points are not displayed on map, still colour the lines according to the selected scheme
+ - When points all have crazy values, don't hang the profile chart
+ - When images can't be fetched from the internet, don't delete expired cache images
+ - Translation updates to es, uk, ru, cz
+
New with version 18.4
=====================
The following fixes and additions were made since version 18.3:
diff --git a/tim/prune/save/GpsSaver.java b/tim/prune/save/GpsSaver.java
index 3fa66c3..6179a5c 100644
--- a/tim/prune/save/GpsSaver.java
+++ b/tim/prune/save/GpsSaver.java
@@ -311,8 +311,9 @@ public class GpsSaver extends GenericFunction implements Runnable
if (trackName == null || trackName.equals("")) {trackName = "gpsprune";}
// Generate the GPX file and send to the GPS
OutputStreamWriter writer = new OutputStreamWriter(process.getOutputStream());
- boolean[] saveFlags = {true, true, true, true, false, true}; // export everything
- GpxExporter.exportData(writer, _app.getTrackInfo(), trackName, null, saveFlags, null);
+ SettingsForExport settings = new SettingsForExport();
+ settings.setExportMissingAltitudesAsZero(true);
+ GpxExporter.exportData(writer, _app.getTrackInfo(), trackName, null, settings, null);
writer.close();
// Read the error stream to see if there's a better error message there
diff --git a/tim/prune/save/GpxExporter.java b/tim/prune/save/GpxExporter.java
index 9363616..7cac01c 100644
--- a/tim/prune/save/GpxExporter.java
+++ b/tim/prune/save/GpxExporter.java
@@ -290,12 +290,17 @@ public class GpxExporter extends GenericFunction implements Runnable
writer = new OutputStreamWriter(new FileOutputStream(_exportFile), "UTF-8");
else
writer = new OutputStreamWriter(new FileOutputStream(_exportFile));
- final boolean[] saveFlags = {_pointTypeSelector.getTrackpointsSelected(), _pointTypeSelector.getWaypointsSelected(),
- _pointTypeSelector.getPhotopointsSelected(), _pointTypeSelector.getAudiopointsSelected(),
- _pointTypeSelector.getJustSelection(), _timestampsCheckbox.isSelected()};
+ // TODO: Move to new method
+ SettingsForExport settings = new SettingsForExport();
+ settings.setExportTrackPoints(_pointTypeSelector.getTrackpointsSelected());
+ settings.setExportWaypoints(_pointTypeSelector.getWaypointsSelected());
+ settings.setExportPhotoPoints(_pointTypeSelector.getPhotopointsSelected());
+ settings.setExportAudiopoints(_pointTypeSelector.getAudiopointsSelected());
+ settings.setExportJustSelection(_pointTypeSelector.getJustSelection());
+ settings.setExportTimestamps(_timestampsCheckbox.isSelected());
// write file
final int numPoints = exportData(writer, _trackInfo, _nameField.getText(),
- _descriptionField.getText(), saveFlags, gpxCachers);
+ _descriptionField.getText(), settings, gpxCachers);
// close file
writer.close();
@@ -334,13 +339,13 @@ public class GpxExporter extends GenericFunction implements Runnable
* @param inInfo track info object
* @param inName name of track (optional)
* @param inDesc description of track (optional)
- * @param inSaveFlags array of booleans to export tracks, waypoints, photos, audios, selection, timestamps
+ * @param inExportSettings flags for what to export and how
* @param inGpxCachers list of Gpx cachers containing input data
* @return number of points written
* @throws IOException if io errors occur on write
*/
public static int exportData(OutputStreamWriter inWriter, TrackInfo inInfo, String inName,
- String inDesc, boolean[] inSaveFlags, GpxCacherList inGpxCachers) throws IOException
+ String inDesc, SettingsForExport inSettings, GpxCacherList inGpxCachers) throws IOException
{
// Write or copy headers
inWriter.write(getXmlHeaderString(inWriter));
@@ -353,12 +358,9 @@ public class GpxExporter extends GenericFunction implements Runnable
writeNameAndDescription(inWriter, trackName, desc, isVersion1_1);
DataPoint point = null;
- final boolean exportTrackpoints = inSaveFlags[0];
- final boolean exportWaypoints = inSaveFlags[1];
- final boolean exportPhotos = inSaveFlags[2];
- final boolean exportAudios = inSaveFlags[3];
- final boolean exportSelection = inSaveFlags[4];
- final boolean exportTimestamps = inSaveFlags[5];
+ final boolean exportWaypoints = inSettings.getExportWaypoints();
+ final boolean exportSelection = inSettings.getExportJustSelection();
+ final boolean exportTimestamps = inSettings.getExportTimestamps();
// Examine selection
int selStart = -1, selEnd = -1;
if (exportSelection) {
@@ -388,23 +390,23 @@ public class GpxExporter extends GenericFunction implements Runnable
inWriter.write('\n');
}
else {
- exportWaypoint(point, inWriter, exportTimestamps, exportPhotos, exportAudios);
+ exportWaypoint(point, inWriter, inSettings);
}
numSaved++;
}
}
}
// Export both route points and then track points
- if (exportTrackpoints || exportPhotos || exportAudios)
+ if (inSettings.getExportTrackPoints() || inSettings.getExportPhotoPoints() || inSettings.getExportAudioPoints())
{
// Output all route points (if any)
- numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
- exportAudios, exportTimestamps, true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
+ numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+ true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
null, "\t</rte>\n");
// Output all track points, if any
String trackStart = "\t<trk>\n\t\t<name>" + trackName + "</name>\n\t\t<number>1</number>\n\t\t<trkseg>\n";
- numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
- exportAudios, exportTimestamps, false, inGpxCachers, "<trkpt", trackStart,
+ numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+ false, inGpxCachers, "<trkpt", trackStart,
"\t</trkseg>\n\t<trkseg>\n", "\t\t</trkseg>\n\t</trk>\n");
}
@@ -450,11 +452,7 @@ public class GpxExporter extends GenericFunction implements Runnable
* Loop through the track outputting the relevant track points
* @param inWriter writer object for output
* @param inInfo track info object containing track
- * @param inExportSelection true to just output current selection
- * @param inExportTrackpoints true to output track points
- * @param inExportPhotos true to output photo points
- * @param inExportAudios true to output audio points
- * @param inExportTimestamps true to include timestamps in export
+ * @param inSettings export settings defining what should be exported
* @param inOnlyCopies true to only export if source can be copied
* @param inCachers list of GpxCachers
* @param inPointTag tag to match for each point
@@ -463,26 +461,30 @@ public class GpxExporter extends GenericFunction implements Runnable
* @param inEndTag end tag to output
*/
private static int writeTrackPoints(OutputStreamWriter inWriter,
- TrackInfo inInfo, boolean inExportSelection, boolean inExportTrackpoints,
- boolean inExportPhotos, boolean inExportAudios, boolean exportTimestamps,
+ TrackInfo inInfo, SettingsForExport inSettings,
boolean inOnlyCopies, GpxCacherList inCachers, String inPointTag,
String inStartTag, String inSegmentTag, String inEndTag)
throws IOException
{
- // Note: far too many input parameters to this method but avoids duplication
+ // Note: Too many input parameters to this method but avoids duplication
// of output functionality for writing track points and route points
int numPoints = inInfo.getTrack().getNumPoints();
int selStart = inInfo.getSelection().getStart();
int selEnd = inInfo.getSelection().getEnd();
int numSaved = 0;
+ final boolean exportSelection = inSettings.getExportJustSelection();
+ final boolean exportTrackPoints = inSettings.getExportTrackPoints();
+ final boolean exportPhotos = inSettings.getExportPhotoPoints();
+ final boolean exportAudios = inSettings.getExportAudioPoints();
+ final boolean exportTimestamps = inSettings.getExportTimestamps();
// Loop over track points
for (int i=0; i<numPoints; i++)
{
DataPoint point = inInfo.getTrack().getPoint(i);
- if ((!inExportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
+ if ((!exportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
{
- if ((point.getPhoto()==null && inExportTrackpoints) || (point.getPhoto()!=null && inExportPhotos)
- || (point.getAudio()!=null && inExportAudios))
+ if ((point.getPhoto()==null && exportTrackPoints) || (point.getPhoto()!=null && exportPhotos)
+ || (point.getAudio()!=null && exportAudios))
{
// get the source from the point (if any)
String pointSource = getPointSource(inCachers, point);
@@ -506,15 +508,20 @@ public class GpxExporter extends GenericFunction implements Runnable
inWriter.write(pointSource);
inWriter.write('\n');
}
- else {
- if (!inOnlyCopies) {exportTrackpoint(point, inWriter, exportTimestamps, inExportPhotos, inExportAudios);}
+ else
+ {
+ if (!inOnlyCopies) {
+ exportTrackpoint(point, inWriter, inSettings);
+ }
}
numSaved++;
}
}
}
}
- if (numSaved > 0) {inWriter.write(inEndTag);}
+ if (numSaved > 0) {
+ inWriter.write(inEndTag);
+ }
return numSaved;
}
@@ -663,13 +670,11 @@ public class GpxExporter extends GenericFunction implements Runnable
* Export the specified waypoint into the file
* @param inPoint waypoint to export
* @param inWriter writer object
- * @param inTimestamps true to export timestamps too
- * @param inPhoto true to export link to photo
- * @param inAudio true to export link to audio
+ * @param inSettings export settings
* @throws IOException on write failure
*/
- private static void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
- boolean inPhoto, boolean inAudio)
+ private static void exportWaypoint(DataPoint inPoint, Writer inWriter,
+ SettingsForExport inSettings)
throws IOException
{
inWriter.write("\t<wpt lat=\"");
@@ -678,14 +683,14 @@ public class GpxExporter extends GenericFunction implements Runnable
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write("\">\n");
// altitude if available
- if (inPoint.hasAltitude())
+ if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
{
inWriter.write("\t\t<ele>");
- inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+ inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
inWriter.write("</ele>\n");
}
- // timestamp if available (point might have timestamp and then be turned into a waypoint)
- if (inPoint.hasTimestamp() && inTimestamps)
+ // timestamp if available (some waypoints have timestamps, some not)
+ if (inPoint.hasTimestamp() && inSettings.getExportTimestamps())
{
inWriter.write("\t\t<time>");
inWriter.write(inPoint.getTimestamp().getText(Timestamp.Format.ISO8601));
@@ -704,13 +709,13 @@ public class GpxExporter extends GenericFunction implements Runnable
inWriter.write("</desc>\n");
}
// Media links, if any
- if (inPhoto && inPoint.getPhoto() != null)
+ if (inSettings.getExportPhotoPoints() && inPoint.getPhoto() != null)
{
inWriter.write("\t\t");
inWriter.write(makeMediaLink(inPoint.getPhoto()));
inWriter.write('\n');
}
- if (inAudio && inPoint.getAudio() != null)
+ if (inSettings.getExportAudioPoints() && inPoint.getAudio() != null)
{
inWriter.write("\t\t");
inWriter.write(makeMediaLink(inPoint.getAudio()));
@@ -736,12 +741,9 @@ public class GpxExporter extends GenericFunction implements Runnable
* Export the specified trackpoint into the file
* @param inPoint trackpoint to export
* @param inWriter writer object
- * @param inTimestamps true to export timestamps too
- * @param inExportPhoto true to export photo link
- * @param inExportAudio true to export audio link
+ * @param inSettings export settings
*/
- private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
- boolean inExportPhoto, boolean inExportAudio)
+ private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, SettingsForExport inSettings)
throws IOException
{
inWriter.write("\t\t\t<trkpt lat=\"");
@@ -750,24 +752,24 @@ public class GpxExporter extends GenericFunction implements Runnable
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write("\">\n");
// altitude
- if (inPoint.hasAltitude())
+ if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
{
inWriter.write("\t\t\t\t<ele>");
- inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+ inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
inWriter.write("</ele>\n");
}
// timestamp if available (and selected)
- if (inPoint.hasTimestamp() && inTimestamps)
+ if (inPoint.hasTimestamp() && inSettings.getExportTimestamps())
{
inWriter.write("\t\t\t\t<time>");
inWriter.write(inPoint.getTimestamp().getText(Timestamp.Format.ISO8601));
inWriter.write("</time>\n");
}
// photo, audio
- if (inPoint.getPhoto() != null && inExportPhoto) {
+ if (inPoint.getPhoto() != null && inSettings.getExportPhotoPoints()) {
inWriter.write(makeMediaLink(inPoint.getPhoto()));
}
- if (inPoint.getAudio() != null && inExportAudio) {
+ if (inPoint.getAudio() != null && inSettings.getExportAudioPoints()) {
inWriter.write(makeMediaLink(inPoint.getAudio()));
}
inWriter.write("\t\t\t</trkpt>\n");
diff --git a/tim/prune/save/SettingsForExport.java b/tim/prune/save/SettingsForExport.java
new file mode 100644
index 0000000..b7e3c69
--- /dev/null
+++ b/tim/prune/save/SettingsForExport.java
@@ -0,0 +1,66 @@
+package tim.prune.save;
+
+/**
+ * Settings for controlling what gets exported,
+ * for example by the Gpx export functions
+ */
+public class SettingsForExport
+{
+ private boolean _exportTrackPoints = true;
+ private boolean _exportWaypoints = true;
+ private boolean _exportJustSelection = false;
+ private boolean _exportTimestamps = true;
+ private boolean _exportMissingAltitudes = false;
+ private boolean _exportPhotoPoints = true;
+ private boolean _exportAudioPoints = true;
+
+ /** Set to export track points or not */
+ public void setExportTrackPoints(boolean inExport) {
+ _exportTrackPoints = inExport;
+ }
+
+ /** Set to export waypoints or not */
+ public void setExportWaypoints(boolean inExport) {
+ _exportWaypoints = inExport;
+ }
+
+ /** Set to export just the selection or everything */
+ public void setExportJustSelection(boolean inExport) {
+ _exportJustSelection = inExport;
+ }
+
+ /** Set to export timestamps or not */
+ public void setExportTimestamps(boolean inExport) {
+ _exportTimestamps = inExport;
+ }
+
+ /** Set to export missing altitudes as zero or not */
+ public void setExportMissingAltitudesAsZero(boolean inExport) {
+ _exportMissingAltitudes = inExport;
+ }
+
+ /** Set to export photo points or not */
+ public void setExportPhotoPoints(boolean inExport) {
+ _exportPhotoPoints = inExport;
+ }
+
+ /** Set to export audio points or not */
+ public void setExportAudiopoints(boolean inExport) {
+ _exportAudioPoints = inExport;
+ }
+
+ /** @return true to export track points */
+ public boolean getExportTrackPoints() {return _exportTrackPoints;}
+ /** @return true to export waypoints */
+ public boolean getExportWaypoints() {return _exportWaypoints;}
+ /** @return true to export just the selection */
+ public boolean getExportJustSelection() {return _exportJustSelection;}
+ /** @return true to export timestamps */
+ public boolean getExportTimestamps() {return _exportTimestamps;}
+ /** @return true to export zeroes for missing altitudes */
+ public boolean getExportMissingAltitudesAsZero() {return _exportMissingAltitudes;}
+ /** @return true to export photo points */
+ public boolean getExportPhotoPoints() {return _exportPhotoPoints;}
+ /** @return true to export audio points */
+ public boolean getExportAudioPoints() {return _exportAudioPoints;}
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/gpsprune.git
More information about the Pkg-grass-devel
mailing list