[Git][debian-gis-team/gpsprune][upstream] New upstream version 23.2
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Mon Oct 2 04:37:38 BST 2023
Bas Couwenberg pushed to branch upstream at Debian GIS Project / gpsprune
Commits:
91c24efc by Bas Couwenberg at 2023-10-02T05:32:32+02:00
New upstream version 23.2
- - - - -
15 changed files:
- build.sh
- tim/prune/GpsPrune.java
- tim/prune/data/Timestamp.java
- tim/prune/data/TimestampLocal.java
- tim/prune/data/TimestampUtc.java
- tim/prune/gui/map/MapSourceLibrary.java
- tim/prune/lang/prune-texts_en.properties
- tim/prune/lang/prune-texts_es.properties
- tim/prune/lang/prune-texts_pl.properties
- tim/prune/lang/prune-texts_pt.properties
- tim/prune/load/FileTypeLoader.java
- tim/prune/load/MediaHelper.java
- tim/prune/readme.txt
- tim/prune/save/GpxWriter.java
- tim/prune/save/KmlExporter.java
Changes:
=====================================
build.sh
=====================================
@@ -1,6 +1,6 @@
# Build script
# Version number
-PRUNENAME=gpsprune_23.1
+PRUNENAME=gpsprune_23.2
# remove compile directory
rm -rf compile
# remove dist directory
=====================================
tim/prune/GpsPrune.java
=====================================
@@ -37,9 +37,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 = "23.1";
+ public static final String VERSION_NUMBER = "23.2";
/** Build number, just used for about screen */
- public static final String BUILD_NUMBER = "406";
+ public static final String BUILD_NUMBER = "408";
/** Static reference to App object */
private static App APP = null;
=====================================
tim/prune/data/Timestamp.java
=====================================
@@ -66,32 +66,28 @@ public abstract class Timestamp
/**
* @return true if this timestamp is after the other one
*/
- public boolean isAfter(Timestamp inOther)
- {
- return getMillisecondsSince(inOther) > 0;
+ public boolean isAfter(Timestamp inOther) {
+ return getMillisecondsSince(inOther) > 0L;
}
/**
* @return true if this timestamp is before the other one
*/
- public boolean isBefore(Timestamp inOther)
- {
- return getMillisecondsSince(inOther) < 0;
+ public boolean isBefore(Timestamp inOther) {
+ return getMillisecondsSince(inOther) < 0L;
}
/**
* @return true if this timestamp is equal to the other one
*/
- public boolean isEqual(Timestamp inOther)
- {
- return getMillisecondsSince(inOther) == 0;
+ public boolean isEqual(Timestamp inOther) {
+ return getMillisecondsSince(inOther) == 0L;
}
/**
* @return the number of seconds since the other timestamp
*/
- public long getSecondsSince(Timestamp inOther)
- {
+ public long getSecondsSince(Timestamp inOther) {
return getMillisecondsSince(inOther) / 1000L;
}
@@ -100,16 +96,14 @@ public abstract class Timestamp
* @param inOther other, earlier Timestamp
* @return number of milliseconds since other timestamp
*/
- public long getMillisecondsSince(Timestamp inOther)
- {
+ public long getMillisecondsSince(Timestamp inOther) {
return getMilliseconds(null) - inOther.getMilliseconds(null);
}
/**
* @return the number of seconds since the other timestamp using the given timezone
*/
- public long getSecondsSince(Timestamp inOther, TimeZone inTimezone)
- {
+ public long getSecondsSince(Timestamp inOther, TimeZone inTimezone) {
return (getMilliseconds(inTimezone) - inOther.getMilliseconds(inTimezone)) / 1000L;
}
=====================================
tim/prune/data/TimestampLocal.java
=====================================
@@ -14,8 +14,8 @@ import java.util.TimeZone;
public class TimestampLocal extends Timestamp
{
private final boolean _valid;
- private int _year=0, _month=0, _day=0;
- private int _hour=0, _minute=0, _second=0;
+ private final int _year, _month, _day;
+ private final int _hour, _minute, _second;
/**
@@ -35,15 +35,12 @@ public class TimestampLocal extends Timestamp
&& inHour >= 0 && inHour < 24
&& inMinute >= 0 && inMinute < 60
&& inSecond >= 0 && inSecond < 60;
- if (_valid)
- {
- _year = inYear;
- _month = inMonth;
- _day = inDay;
- _hour = inHour;
- _minute = inMinute;
- _second = inSecond;
- }
+ _year = _valid ? inYear : 0;
+ _month = _valid ? inMonth : 0;
+ _day = _valid ? inDay : 0;
+ _hour = _valid ? inHour : 0;
+ _minute = _valid ? inMinute : 0;
+ _second = _valid ? inSecond : 0;
}
=====================================
tim/prune/data/TimestampUtc.java
=====================================
@@ -18,14 +18,14 @@ import java.util.regex.Pattern;
public class TimestampUtc extends Timestamp
{
private final boolean _valid;
- private long _milliseconds = 0L;
- private String _text = null;
+ private final long _milliseconds;
+ private final String _text;
private static final DateFormat ISO_8601_FORMAT_NOZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private static DateFormat[] ALL_DATE_FORMATS = null;
private static Calendar CALENDAR = null;
private static final Pattern ISO8601_FRACTIONAL_PATTERN
- = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:[\\.,](\\d{1,3}))?(Z|[\\+-]\\d{2}(?::?\\d{2})?)?");
+ = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:[.,](\\d{1,3}))?(Z|[+-]\\d{2}(?::?\\d{2})?)?");
// year month day T hour minute sec millisec Z or +/- hours : minutes
private static final Pattern GENERAL_TIMESTAMP_PATTERN
= Pattern.compile("(\\d{4})\\D(\\d{2})\\D(\\d{2})\\D(\\d{2})\\D(\\d{2})\\D(\\d{2})");
@@ -98,48 +98,51 @@ public class TimestampUtc extends Timestamp
*/
public TimestampUtc(String inString)
{
- _text = null;
+ String text = null;
+ long millis = 0L;
if (inString != null && !inString.equals(""))
{
// Try each of the parse types in turn
for (ParseType type : ALL_PARSE_TYPES)
{
- if (parseString(inString, type))
+ Long parsedMillis = parseString(inString, type);
+ if (parsedMillis != null)
{
ALL_PARSE_TYPES[0] = type;
- _valid = true;
- _text = inString;
- return;
+ text = inString;
+ millis = parsedMillis;
+ break;
}
}
}
- _valid = false;
+ _text = text;
+ _milliseconds = millis;
+ _valid = (_text != null);
}
/**
* Try to parse the given string in the specified way
* @param inString String to parse
* @param inType parse type to use
- * @return true if successful
+ * @return milliseconds if parse was successful, otherwise false
*/
- private boolean parseString(String inString, ParseType inType)
+ private static Long parseString(String inString, ParseType inType)
{
if (inString == null || inString.equals("")) {
- return false;
+ return null;
}
switch (inType)
{
- case NONE: return false;
+ case NONE:
+ return null;
case LONG:
// Try to parse into a long
try
{
long rawValue = Long.parseLong(inString.trim());
- _milliseconds = getMilliseconds(rawValue);
- return true;
+ return getMilliseconds(rawValue);
}
- catch (NumberFormatException nfe)
- {}
+ catch (NumberFormatException ignored) {}
break;
case ISO8601_FRACTIONAL:
@@ -147,7 +150,7 @@ public class TimestampUtc extends Timestamp
if (fmatcher.matches())
{
try {
- _milliseconds = getMilliseconds(Integer.parseInt(fmatcher.group(1)), // year
+ return getMilliseconds(Integer.parseInt(fmatcher.group(1)), // year
Integer.parseInt(fmatcher.group(2)), // month
Integer.parseInt(fmatcher.group(3)), // day
Integer.parseInt(fmatcher.group(4)), // hour
@@ -155,9 +158,8 @@ public class TimestampUtc extends Timestamp
Integer.parseInt(fmatcher.group(6)), // second
fmatcher.group(7), // fractional seconds
fmatcher.group(8)); // timezone, if any
- return true;
}
- catch (NumberFormatException nfe) {}
+ catch (NumberFormatException ignored) {}
}
break;
@@ -178,21 +180,20 @@ public class TimestampUtc extends Timestamp
if (matcher.matches())
{
try {
- _milliseconds = getMilliseconds(Integer.parseInt(matcher.group(1)),
+ return getMilliseconds(Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(2)),
Integer.parseInt(matcher.group(3)),
Integer.parseInt(matcher.group(4)),
Integer.parseInt(matcher.group(5)),
Integer.parseInt(matcher.group(6)),
null, null); // no fractions of a second and no timezone
- return true;
}
- catch (NumberFormatException nfe2) {} // parse shouldn't fail if matcher matched
+ catch (NumberFormatException ignored) {} // parse shouldn't fail if matcher matched
}
}
- return false;
+ break;
}
- return false;
+ return null;
}
@@ -200,20 +201,18 @@ public class TimestampUtc extends Timestamp
* Try to parse the given string with the given date format
* @param inString String to parse
* @param inDateFormat Date format to use
- * @return true if successful
+ * @return milliseconds if successful
*/
- private boolean parseString(String inString, DateFormat inDateFormat)
+ private static Long parseString(String inString, DateFormat inDateFormat)
{
ParsePosition pPos = new ParsePosition(0);
Date date = inDateFormat.parse(inString, pPos);
if (date != null && inString.length() == pPos.getIndex()) // require use of _all_ the string, not just the beginning
{
CALENDAR.setTime(date);
- _milliseconds = CALENDAR.getTimeInMillis();
- return true;
+ return CALENDAR.getTimeInMillis();
}
-
- return false;
+ return null;
}
@@ -224,6 +223,7 @@ public class TimestampUtc extends Timestamp
public TimestampUtc(long inMillis)
{
_milliseconds = inMillis;
+ _text = null;
_valid = true;
}
=====================================
tim/prune/gui/map/MapSourceLibrary.java
=====================================
@@ -38,8 +38,8 @@ public abstract class MapSourceLibrary
*/
private static void addFixedSources()
{
- _sourceList.add(new OsmMapSource("Mapnik", "https://[abc].tile.openstreetmap.org/"));
- _sourceList.add(new OsmMapSource("Cycling Trails", "https://[abc].tile.openstreetmap.org/", "png",
+ _sourceList.add(new OsmMapSource("Mapnik", "https://tile.openstreetmap.org/"));
+ _sourceList.add(new OsmMapSource("Cycling Trails", "https://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 OsmMapSource("Mapsforfree", "https://maps-for-free.com/layer/relief/z{z}/row{y}/{z}_{x}-{y}.jpg", "jpg",
=====================================
tim/prune/lang/prune-texts_en.properties
=====================================
@@ -676,7 +676,7 @@ confirm.audiosloaded.single=1 audio file added
confirm.audiosloaded=%d audio files added
confirm.correlateaudios.single=audio was correlated
confirm.correlateaudios.multi=%d audios were correlated
-confirm.applytimestamps=Timestamps applied to selection
+confirm.applytimestamps=Timestamps were applied to selection
# Tips, shown just once when appropriate
tip.title=Tip
=====================================
tim/prune/lang/prune-texts_es.properties
=====================================
@@ -310,7 +310,8 @@ dialog.pointnameedit.name=Nombre de waypoint
dialog.pointnameedit.uppercase=May\u00fasculas
dialog.pointnameedit.lowercase=min\u00fasculas
dialog.pointnameedit.titlecase=Mezcla
-dialog.truncatecoords.numdigits=N\u00famero de d\u00edgitos decimales
+dialog.truncatecoords.intro=Seleccione el formato de las coordenadas y el n\u00famero de cifras decimales
+dialog.truncatecoords.numdigits=N\u00famero de cifras decimales
dialog.truncatecoords.preview=Previsi\u00f3n
dialog.addtimeoffset.add=A\u00f1adir tiempo
dialog.addtimeoffset.subtract=Sustraer tiempo
@@ -615,6 +616,8 @@ dialog.projectpoint.bearing=Azimut (grados desde el Norte)
dialog.projectcircle.desc=Insertar el radio del c\u00edrculo
dialog.configuresrtm.threesecond=Datos de baja resoluci\u00f3n (3 segundos)
dialog.configuresrtm.onesecond=Datos de alta resoluci\u00f3n (1 segundo)
+dialog.configuresrtm.userid=Nombre de usuario para NASA Earthdata
+dialog.configuresrtm.password=Contrase\u00f1a para NASA Earthdata
# 3d window
dialog.3d.title=GpsPrune vista 3-D
@@ -661,6 +664,7 @@ confirm.audiosloaded.single=A\u00f1adido archivo de audio
confirm.audiosloaded=A\u00f1adidos %d archivos de audio
confirm.correlateaudios.single=El audio fue correlacionado
confirm.correlateaudios.multi=%d audios fueron correlacionados
+confirm.applytimestamps=Se han asignado marcas de tiempo a los puntos
# Tips, shown just once when appropriate
tip.title=Sugerencia
=====================================
tim/prune/lang/prune-texts_pl.properties
=====================================
@@ -25,6 +25,10 @@ menu.range.cutandmove=Wytnij i przesu\u0144 zaznaczenie
menu.point=Punkt
menu.point.editpoint=Edytuj punkt
menu.point.deletepoint=Usu\u0144 punkt
+menu.point.goto=I\u015B\u0107 do
+menu.point.goto.highest=Najwy\u017Cszego punktu
+menu.point.goto.lowest=Najni\u017Cszego point
+menu.point.goto.fastest=Najszybszego point
menu.photo=Zdj\u0119cie
menu.photo.saveexif=Zapisz Exif
menu.audio=Audio
@@ -530,6 +534,9 @@ dialog.displaysettings.wpicon.plectrum=Plektron
dialog.displaysettings.wpicon.ring=Pier\u015Bcie\u0144
dialog.displaysettings.linewidth=Wprowad\u017a grubo\u015b\u0107 linii do rysowania \u015bcie\u017cek
dialog.displaysettings.antialias=U\u017Cyj antyaliasingu
+dialog.displaysettings.wpicon.ring=Pier\u015Bcie\u0144
+dialog.displaysettings.wpicon.pin=Ko\u0142ek tablicy
+dialog.displaysettings.wpicon.flag=Flaga
dialog.displaysettings.size.small=Ma\u0142e
dialog.displaysettings.size.medium=\u015arednie
dialog.displaysettings.size.large=Du\u017ce
@@ -859,7 +866,6 @@ error.readme.notfound=Nie znaleziono pliku Readme
error.osmimage.dialogtitle=B\u0142\u0105d przy \u0142adowaniu obraz\u00f3w map
error.osmimage.failed=B\u0142\u0105d przy \u0142adowaniu obraz\u00f3w map. Sprawd\u017a po\u0142\u0105czenie z internetem.
error.language.wrongfile=Wybrany plik nie jest plikiem z t\u0142umaczeniem dla GpsPrune
-
error.lookupsrtm.nonefound=Nie znaleziono danych o wysoko\u015bci.
error.lookupsrtm.nonerequired=Wszystkie pola maj\u0105 informacj\u0119 o wysoko\u015bci, nie ma czego szuka\u0107
error.showphoto.failed=Nie powiod\u0142o si\u0119 za\u0142adowanie zdj\u0119cia
=====================================
tim/prune/lang/prune-texts_pt.properties
=====================================
@@ -800,9 +800,9 @@ cardinal.w=O
# Undo operations
undo.loadfile=Carregar dados %s
-undo.loadphoto=Carregar foto
+undo.loadphoto=Carregar foto %s
undo.loadphotos=Carregar %d fotos
-undo.loadaudio=Carregar arquivo de \u00e1udio
+undo.loadaudio=Carregar arquivo de \u00e1udio '%s'
undo.loadaudios=Carregar %d arquivos de \u00e1udio
undo.editpoint=Editar ponto
undo.editpoint.withname=Editar ponto '%s'
=====================================
tim/prune/load/FileTypeLoader.java
=====================================
@@ -151,7 +151,7 @@ public class FileTypeLoader
/**
* Load the data from the xml handler
- * @param inHandler xml handler which read the data from GPSBabel
+ * @param inHandler xml handler which read the data
* @param inSourceInfo info about file (or not)
* @param inAutoAppend true to auto-append
* @param inMediaLinks media links, if any
=====================================
tim/prune/load/MediaHelper.java
=====================================
@@ -51,8 +51,11 @@ public abstract class MediaHelper
{
if (inPath == null || inPath.length() < 5) return null;
byte[] data = null;
- // See if file is in the zip file
- if (inZipFile != null && inZipFile.exists() && inZipFile.canRead())
+ // See if file is inside a zip file
+ boolean isZip = inZipFile != null && inZipFile.exists() && inZipFile.canRead()
+ && !inZipFile.getName().toLowerCase().endsWith(".gpx")
+ && !inZipFile.getName().toLowerCase().endsWith(".kml");
+ if (isZip)
{
try (ZipFile zf = new ZipFile(inZipFile))
{
@@ -64,12 +67,12 @@ public abstract class MediaHelper
catch (IOException ioe) {
System.err.println("Got ioe from zip file: " + ioe.getMessage());
}
- }
- if (data != null)
- {
- final String filename = new File(inPath).getName();
- return createMediaObject(data, filename, null);
+ if (data != null)
+ {
+ final String filename = new File(inPath).getName();
+ return createMediaObject(data, filename, null);
+ }
}
// If we haven't got a result by now, try to load plain file
=====================================
tim/prune/readme.txt
=====================================
@@ -1,4 +1,4 @@
-GpsPrune version 23.1
+GpsPrune version 23.2
=====================
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_23.1.jar
+ java -jar gpsprune_23.2.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,15 @@ 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_23.1.jar --lang=DE
+ java -jar gpsprune_23.2.jar --lang=DE
+New with version 23.2
+=====================
+The following fixes were made since version 23.1:
+ - Bugfix for exporting timestamps of waypoints to gpx and kml/kmz
+ - Update to openstreetmap tile URLs (Issue #86)
+
New with version 23.1
=====================
The following fixes were made since version 23:
=====================================
tim/prune/save/GpxWriter.java
=====================================
@@ -253,11 +253,15 @@ public class GpxWriter
inWriter.write("</ele>\n");
}
// timestamp if available (some waypoints have timestamps, some not)
- if (inPoint.hasTimestamp() && _settings.getExportTimestamps())
+ if (_settings.getExportTimestamps())
{
- inWriter.write("\t\t<time>");
- inWriter.write(getPointTimestamp(inPoint).getText(Timestamp.Format.ISO8601, null));
- inWriter.write("</time>\n");
+ Timestamp waypointTimestamp = getPointTimestamp(inPoint);
+ if (waypointTimestamp != null && waypointTimestamp.isValid())
+ {
+ inWriter.write("\t\t<time>");
+ inWriter.write(getPointTimestamp(inPoint).getText(Timestamp.Format.ISO8601, null));
+ inWriter.write("</time>\n");
+ }
}
// write waypoint name after elevation and time
inWriter.write("\t\t<name>");
=====================================
tim/prune/save/KmlExporter.java
=====================================
@@ -455,7 +455,8 @@ public class KmlExporter extends GenericFunction implements Runnable
boolean writeAudios = _pointTypeSelector.getAudiopointsSelected();
boolean justSelection = _pointTypeSelector.getJustSelection();
// Define xml header (depending on whether extensions are used or not)
- if (useGxExtensions()) {
+ final boolean useGxExtensions = useGxExtensions();
+ if (useGxExtensions) {
inWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n");
}
else {
@@ -478,61 +479,62 @@ public class KmlExporter extends GenericFunction implements Runnable
selEnd = _trackInfo.getSelection().getEnd();
}
- boolean absoluteAltitudes = _altitudesCheckbox.isSelected();
- int i = 0;
- DataPoint point = null;
+ final boolean absoluteAltitudes = _altitudesCheckbox.isSelected();
+ final int numPoints = _track.getNumPoints();
boolean hasTrackpoints = false;
boolean writtenPhotoHeader = false, writtenAudioHeader = false;
- final int numPoints = _track.getNumPoints();
int numSaved = 0;
int photoNum = 0;
// Loop over waypoints
- for (i=0; i<numPoints; i++)
+ for (int i=0; i<numPoints; i++)
{
- point = _track.getPoint(i);
- boolean writeCurrentPoint = !justSelection || (i>=selStart && i<=selEnd);
- // Make a blob for each waypoint
- if (point.isWaypoint())
+ if (justSelection && (i < selStart || i > selEnd)) {
+ continue;
+ }
+ DataPoint point = _track.getPoint(i);
+ if (!point.hasMedia())
{
- if (writeWaypoints && writeCurrentPoint)
+ // Make a blob for each waypoint
+ if (point.isWaypoint())
{
- exportWaypoint(point, inWriter, absoluteAltitudes);
- numSaved++;
+ if (writeWaypoints)
+ {
+ exportWaypoint(point, inWriter, useGxExtensions, absoluteAltitudes);
+ numSaved++;
+ }
+ }
+ else {
+ hasTrackpoints = true;
}
- }
- else if (!point.hasMedia())
- {
- hasTrackpoints = true;
}
// Make a blob with description for each photo
// Photos have already been written so picture sizes already known
- if (point.getPhoto() != null && point.getPhoto().isValid() && writePhotos && writeCurrentPoint)
+ if (point.getPhoto() != null && point.getPhoto().isValid() && writePhotos)
{
if (!writtenPhotoHeader)
{
- inWriter.write("<Style id=\"camera_icon\"><IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/pal4/icon46.png</href></Icon></IconStyle></Style>");
+ inWriter.write("\t<Style id=\"camera_icon\"><IconStyle><Icon><href>https://maps.google.com/mapfiles/kml/pal4/icon46.png</href></Icon></IconStyle></Style>\n");
writtenPhotoHeader = true;
}
photoNum++;
- exportPhotoPoint(point, inWriter, inExportImages, i, photoNum, absoluteAltitudes);
+ exportPhotoPoint(point, inWriter, inExportImages, i, photoNum, useGxExtensions, absoluteAltitudes);
numSaved++;
}
// Make a blob with description for each audio clip
- if (point.getAudio() != null && writeAudios && writeCurrentPoint)
+ if (point.getAudio() != null && writeAudios)
{
if (!writtenAudioHeader)
{
- inWriter.write("<Style id=\"audio_icon\"><IconStyle><color>ff00ffff</color><Icon><href>http://maps.google.com/mapfiles/kml/shapes/star.png</href></Icon></IconStyle></Style>");
+ inWriter.write("\t<Style id=\"audio_icon\"><IconStyle><color>ff00ffff</color><Icon><href>https://maps.google.com/mapfiles/kml/shapes/star.png</href></Icon></IconStyle></Style>\n");
writtenAudioHeader = true;
}
- exportAudioPoint(point, inWriter, absoluteAltitudes);
+ exportAudioPoint(point, inWriter, useGxExtensions, absoluteAltitudes);
numSaved++;
}
}
// Make a line for the track, if there is one
if (hasTrackpoints && writeTrack)
{
- boolean useGxExtensions = _gxExtensionsRadio.isSelected();
if (useGxExtensions)
{
// Write track using the Google Extensions to KML including gx:Track
@@ -543,7 +545,7 @@ public class KmlExporter extends GenericFunction implements Runnable
numSaved += writeStandardTrack(inWriter, absoluteAltitudes, selStart, selEnd);
}
}
- inWriter.write("</Folder>\n</kml>\n");
+ inWriter.write("\n</Folder>\n</kml>\n");
return numSaved;
}
@@ -563,7 +565,7 @@ public class KmlExporter extends GenericFunction implements Runnable
int numSaved = 0;
// Set up strings for start and end of track segment
String trackStart = "\t<Placemark>\n\t\t<name>track</name>\n\t\t<Style>\n\t\t\t<LineStyle>\n"
- + "\t\t\t\t<color>cc" + reverse(ColourUtils.makeHexCode(_colourPatch.getBackground())) + "</color>\n"
+ + "\t\t\t\t<color>cc" + reverseRGB(ColourUtils.makeHexCode(_colourPatch.getBackground())) + "</color>\n"
+ "\t\t\t\t<width>4</width>\n\t\t\t</LineStyle>\n"
+ "\t\t</Style>\n\t\t<LineString>\n";
if (inAbsoluteAltitudes) {
@@ -623,7 +625,7 @@ public class KmlExporter extends GenericFunction implements Runnable
int numSaved = 0;
// Set up strings for start and end of track segment
String trackStart = "\t<Placemark>\n\t\t<name>track</name>\n\t\t<Style>\n\t\t\t<LineStyle>\n"
- + "\t\t\t\t<color>cc" + reverse(ColourUtils.makeHexCode(_colourPatch.getBackground())) + "</color>\n"
+ + "\t\t\t\t<color>cc" + reverseRGB(ColourUtils.makeHexCode(_colourPatch.getBackground())) + "</color>\n"
+ "\t\t\t\t<width>4</width>\n\t\t\t</LineStyle>\n"
+ "\t\t</Style>\n\t\t<gx:Track>\n";
if (inAbsoluteAltitudes) {
@@ -700,8 +702,11 @@ public class KmlExporter extends GenericFunction implements Runnable
* @param inCode colour code rrggbb
* @return kml code bbggrr
*/
- private static String reverse(String inCode)
+ private static String reverseRGB(String inCode)
{
+ if (inCode == null || inCode.length() != 6) {
+ return inCode;
+ }
return inCode.substring(4, 6) + inCode.substring(2, 4) + inCode.substring(0, 2);
}
@@ -709,13 +714,14 @@ public class KmlExporter extends GenericFunction implements Runnable
* Export the specified waypoint into the file
* @param inPoint waypoint to export
* @param inWriter writer object
+ * @param inWithTimestamp true to include timestamp of waypoint
* @param inAbsoluteAltitude true for absolute altitude
* @throws IOException on write failure
*/
- private void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inAbsoluteAltitude) throws IOException
+ private void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inWithTimestamp, boolean inAbsoluteAltitude) throws IOException
{
String name = inPoint.getWaypointName().trim();
- exportNamedPoint(inPoint, inWriter, name, inPoint.getFieldValue(Field.DESCRIPTION), null, inAbsoluteAltitude);
+ exportNamedPoint(inPoint, inWriter, name, inPoint.getFieldValue(Field.DESCRIPTION), null, inWithTimestamp, inAbsoluteAltitude);
}
@@ -723,17 +729,19 @@ public class KmlExporter extends GenericFunction implements Runnable
* Export the specified audio point into the file
* @param inPoint audio point to export
* @param inWriter writer object
+ * @param inWithTimestamp true to include point/audio timestamp
* @param inAbsoluteAltitude true for absolute altitude
* @throws IOException on write failure
*/
- private void exportAudioPoint(DataPoint inPoint, Writer inWriter, boolean inAbsoluteAltitude) throws IOException
+ private void exportAudioPoint(DataPoint inPoint, Writer inWriter, boolean inWithTimestamp, boolean inAbsoluteAltitude)
+ throws IOException
{
String name = inPoint.getAudio().getName();
String desc = null;
if (inPoint.getAudio().getFile() != null) {
desc = inPoint.getAudio().getFile().getAbsolutePath();
}
- exportNamedPoint(inPoint, inWriter, name, desc, "audio_icon", inAbsoluteAltitude);
+ exportNamedPoint(inPoint, inWriter, name, desc, "audio_icon", inWithTimestamp, inAbsoluteAltitude);
}
@@ -744,14 +752,18 @@ public class KmlExporter extends GenericFunction implements Runnable
* @param inImageLink flag to set whether to export image links or not
* @param inPointNumber number of point for accessing dimensions
* @param inImageNumber number of image for filename
+ * @param inWithTimestamp true to include point/photo timestamp
* @param inAbsoluteAltitude true for absolute altitudes
* @throws IOException on write failure
*/
private void exportPhotoPoint(DataPoint inPoint, Writer inWriter, boolean inImageLink,
- int inPointNumber, int inImageNumber, boolean inAbsoluteAltitude)
+ int inPointNumber, int inImageNumber, boolean inWithTimestamp, boolean inAbsoluteAltitude)
throws IOException
{
String name = inPoint.getPhoto().getName();
+ if (inPoint.isWaypoint()) {
+ name = inPoint.getWaypointName();
+ }
String desc = null;
if (inImageLink)
{
@@ -764,7 +776,7 @@ public class KmlExporter extends GenericFunction implements Runnable
+ wrapInTableRow(getPointCaption(inPoint)) + "</table>]]>";
}
// Export point
- exportNamedPoint(inPoint, inWriter, name, desc, "camera_icon", inAbsoluteAltitude);
+ exportNamedPoint(inPoint, inWriter, name, desc, "camera_icon", inWithTimestamp, inAbsoluteAltitude);
}
/**
@@ -774,11 +786,12 @@ public class KmlExporter extends GenericFunction implements Runnable
* @param inName name of point
* @param inDesc description of point, or null
* @param inStyle style of point, or null
+ * @param inWithTimestamp true to include timestamp
* @param inAbsoluteAltitude true for absolute altitudes
* @throws IOException on write failure
*/
private void exportNamedPoint(DataPoint inPoint, Writer inWriter, String inName,
- String inDesc, String inStyle, boolean inAbsoluteAltitude)
+ String inDesc, String inStyle, boolean inWithTimestamp, boolean inAbsoluteAltitude)
throws IOException
{
inWriter.write("\t<Placemark>\n\t\t<name>");
@@ -793,10 +806,20 @@ public class KmlExporter extends GenericFunction implements Runnable
}
if (inStyle != null)
{
- inWriter.write("<styleUrl>#");
+ inWriter.write("\t\t<styleUrl>#");
inWriter.write(inStyle);
inWriter.write("</styleUrl>\n");
}
+ if (inWithTimestamp)
+ {
+ Timestamp pointTimestamp = getPointTimestamp(inPoint);
+ if (pointTimestamp != null && pointTimestamp.isValid())
+ {
+ inWriter.write("\t\t<Timestamp>\n\t\t\t<when>");
+ inWriter.write(pointTimestamp.getText(Timestamp.Format.ISO8601, null));
+ inWriter.write("</when>\n\t\t</Timestamp>\n");
+ }
+ }
inWriter.write("\t\t<Point>\n");
if (inAbsoluteAltitude && inPoint.hasAltitude()) {
inWriter.write("\t\t\t<altitudeMode>absolute</altitudeMode>\n");
@@ -967,4 +990,29 @@ public class KmlExporter extends GenericFunction implements Runnable
}
return "<tr><td>" + fieldString + "</td></tr>";
}
+
+ /**
+ * Get the timestamp from the point or its media
+ * @param inPoint point object
+ * @return Timestamp object if available, or null
+ */
+ private static Timestamp getPointTimestamp(DataPoint inPoint)
+ {
+ if (inPoint.hasTimestamp()) {
+ return inPoint.getTimestamp();
+ }
+ if (inPoint.getPhoto() != null)
+ {
+ if (inPoint.getPhoto().hasTimestamp()) {
+ return inPoint.getPhoto().getTimestamp();
+ }
+ }
+ if (inPoint.getAudio() != null)
+ {
+ if (inPoint.getAudio().hasTimestamp()) {
+ return inPoint.getAudio().getTimestamp();
+ }
+ }
+ return null;
+ }
}
View it on GitLab: https://salsa.debian.org/debian-gis-team/gpsprune/-/commit/91c24efca178f9f3b9816dad2f9b67a107d7a68f
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/gpsprune/-/commit/91c24efca178f9f3b9816dad2f9b67a107d7a68f
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20231002/309db540/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list