forked from upstream-mirrors/OpenTracks
ActivityType non-localized: import and export for GPX, KML, and KMZ.
Fixes #1608.
This commit is contained in:
@@ -51,4 +51,13 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="typeTranslated"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation xml:lang="en">
|
||||
User-defined translation of GPX's <![CDATA[<type>]]>.
|
||||
Only used in GPX.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
+2
-4
@@ -309,10 +309,10 @@ public class ExportImportTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(track.getActivityType(), importedTrack.getActivityType());
|
||||
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
|
||||
assertEquals(track.getDescription(), importedTrack.getDescription());
|
||||
assertEquals(track.getName(), importedTrack.getName());
|
||||
assertEquals(track.getActivityType(), importedTrack.getActivityType());
|
||||
|
||||
// 2. trackpoints
|
||||
TrackPointAssert a = new TrackPointAssert();
|
||||
@@ -380,13 +380,11 @@ public class ExportImportTest {
|
||||
// 1. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(track.getActivityType(), importedTrack.getActivityType());
|
||||
assertEquals(track.getActivityTypeLocalized(), importedTrack.getActivityTypeLocalized());
|
||||
assertEquals(track.getDescription(), importedTrack.getDescription());
|
||||
assertEquals(track.getName(), importedTrack.getName());
|
||||
|
||||
//TODO exporting and importing a track icon is not yet supported by GpxTrackWriter.
|
||||
//assertEquals(track.getIcon(), importedTrack.getIcon());
|
||||
|
||||
// 2. trackpoints
|
||||
// The GPX exporter does not support exporting TrackPoints without lat/lng.
|
||||
// Therefore, the track segmentation is changes.
|
||||
|
||||
+1
@@ -80,6 +80,7 @@ public class GPXTrackImporterTest {
|
||||
// 2. track
|
||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||
assertNotNull(importedTrack);
|
||||
assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType());
|
||||
assertEquals("the category", importedTrack.getActivityTypeLocalized());
|
||||
assertEquals("the description", importedTrack.getDescription());
|
||||
assertEquals("2021-01-07 22:51", importedTrack.getName());
|
||||
|
||||
@@ -21,10 +21,11 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/
|
||||
<trk>
|
||||
<name><![CDATA[2021-01-07 22:51]]></name>
|
||||
<desc><![CDATA[the description]]></desc>
|
||||
<type><![CDATA[the category]]></type>
|
||||
<type><![CDATA[unknown]]></type>
|
||||
<extensions>
|
||||
<topografix:color>c0c0c0</topografix:color>
|
||||
<opentracks:trackid>7002101e-4198-4613-8c24-544e01ca3981</opentracks:trackid>
|
||||
<opentracks:typeTranslated><![CDATA[unknown]]></opentracks:typeTranslated>
|
||||
<gpxtrkx:TrackStatsExtension>
|
||||
<gpxtrkx:Distance>0.0</gpxtrkx:Distance>
|
||||
<gpxtrkx:TimerTime>0</gpxtrkx:TimerTime>
|
||||
|
||||
@@ -261,7 +261,7 @@ public class GPXTrackExporter implements TrackExporter {
|
||||
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(marker.getTime(), zoneOffset) + "</time>");
|
||||
printWriter.println("<name>" + StringUtils.formatCData(marker.getName()) + "</name>");
|
||||
printWriter.println("<desc>" + StringUtils.formatCData(marker.getDescription()) + "</desc>");
|
||||
printWriter.println("<type>" + StringUtils.formatCData(marker.getCategory()) + "</type>");
|
||||
printWriter.println("<type>" + StringUtils.formatCData(marker.getCategory()) + "</type>"); //TODO This is localized; may be better to export in English only. See #1608
|
||||
printWriter.println("</wpt>");
|
||||
}
|
||||
|
||||
@@ -269,12 +269,16 @@ public class GPXTrackExporter implements TrackExporter {
|
||||
printWriter.println("<trk>");
|
||||
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
||||
printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>");
|
||||
printWriter.println("<type>" + StringUtils.formatCData(track.getActivityTypeLocalized()) + "</type>");
|
||||
printWriter.println("<type>" + StringUtils.formatCData(track.getActivityType().getId()) + "</type>");
|
||||
|
||||
printWriter.println("<extensions>");
|
||||
printWriter.println("<topografix:color>c0c0c0</topografix:color>");
|
||||
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
||||
|
||||
if (track.getActivityTypeLocalized() != null || !track.getActivityTypeLocalized().isBlank()) {
|
||||
printWriter.println("<opentracks:typeTranslated>" + StringUtils.formatCData(track.getActivityTypeLocalized()) + "</opentracks:typeTranslated>");
|
||||
}
|
||||
|
||||
TrackStatistics trackStatistics = track.getTrackStatistics();
|
||||
printWriter.println("<gpxtrkx:TrackStatsExtension>");
|
||||
printWriter.println("<gpxtrkx:Distance>" + trackStatistics.getTotalDistance().toM() + "</gpxtrkx:Distance>");
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.util.Objects;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
@@ -59,7 +60,8 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
private static final String TRACK_STYLE = "track";
|
||||
private static final String SCHEMA_ID = "schema";
|
||||
|
||||
public static final String EXTENDED_DATA_TYPE_ACTIVITYTYPE = "type";
|
||||
public static final String EXTENDED_DATA_TYPE_LOCALIZED = "type";
|
||||
public static final String EXTENDED_DATA_ACTIVITY_TYPE = "activityType";
|
||||
|
||||
public static final String EXTENDED_DATA_TYPE_TRACKPOINT = "trackpoint_type";
|
||||
public static final String EXTENDED_DATA_TYPE_SPEED = "speed";
|
||||
@@ -298,13 +300,13 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
||||
|
||||
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
|
||||
writeActivityType(track.getActivityTypeLocalized());
|
||||
writeActivityType(track.getActivityType());
|
||||
writeTypeLocalized(track.getActivityTypeLocalized());
|
||||
printWriter.println("<MultiTrack>");
|
||||
printWriter.println("<altitudeMode>absolute</altitudeMode>");
|
||||
printWriter.println("<interpolate>1</interpolate>");
|
||||
}
|
||||
|
||||
|
||||
private void writeEndTrack() {
|
||||
printWriter.println("</MultiTrack>");
|
||||
printWriter.println("</Placemark>");
|
||||
@@ -416,7 +418,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
printWriter.println("<description>" + StringUtils.formatCData(description) + "</description>");
|
||||
printWriter.println("<TimeStamp><when>" + getTime(zoneOffset, location) + "</when></TimeStamp>");
|
||||
printWriter.println("<styleUrl>#" + KMLTrackExporter.MARKER_STYLE + "</styleUrl>");
|
||||
writeActivityType(activityType);
|
||||
writeTypeLocalized(activityType);
|
||||
printWriter.println("<Point>");
|
||||
printWriter.println("<coordinates>" + getCoordinates(location, ",") + "</coordinates>");
|
||||
printWriter.println("</Point>");
|
||||
@@ -437,7 +439,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
printWriter.println("</Camera>");
|
||||
printWriter.println("<TimeStamp><when>" + getTime(zoneOffset, marker.getLocation()) + "</when></TimeStamp>");
|
||||
printWriter.println("<styleUrl>#" + MARKER_STYLE + "</styleUrl>");
|
||||
writeActivityType(marker.getCategory());
|
||||
writeTypeLocalized(marker.getCategory());
|
||||
|
||||
if (exportPhotos) {
|
||||
printWriter.println("<Icon><href>" + KmzTrackExporter.buildKmzImageFilePath(marker) + "</href></Icon>");
|
||||
@@ -492,12 +494,21 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeActivityType(String activityTypeLocalized) {
|
||||
if (activityTypeLocalized == null || "".equals(activityTypeLocalized)) {
|
||||
private void writeTypeLocalized(String localizedValue) {
|
||||
if (localizedValue == null || localizedValue.equals("")) {
|
||||
return;
|
||||
}
|
||||
printWriter.println("<ExtendedData>");
|
||||
printWriter.println("<Data name=\"" + EXTENDED_DATA_TYPE_ACTIVITYTYPE + "\"><value>" + StringUtils.formatCData(activityTypeLocalized) + "</value></Data>");
|
||||
printWriter.println("<Data name=\"" + EXTENDED_DATA_TYPE_LOCALIZED + "\"><value>" + StringUtils.formatCData(localizedValue) + "</value></Data>");
|
||||
printWriter.println("</ExtendedData>");
|
||||
}
|
||||
|
||||
private void writeActivityType(ActivityType value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
printWriter.println("<ExtendedData>");
|
||||
printWriter.println("<Data name=\"" + EXTENDED_DATA_ACTIVITY_TYPE + "\"><value>" + StringUtils.formatCData(value.getId()) + "</value></Data>");
|
||||
printWriter.println("</ExtendedData>");
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private static final String TAG = GpxTrackImporter.class.getSimpleName();
|
||||
|
||||
private static final String TAG_DESCRIPTION = "desc";
|
||||
private static final String TAG_COMMENT = "cmt";
|
||||
private static final String TAG_ALTITUDE = "ele";
|
||||
private static final String TAG_GPX = "gpx";
|
||||
private static final String TAG_NAME = "name";
|
||||
@@ -64,6 +63,7 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private static final String TAG_TRACK_POINT = "trkpt";
|
||||
private static final String TAG_TRACK_SEGMENT = "trkseg";
|
||||
private static final String TAG_TYPE = "type";
|
||||
private static final String TAG_TYPE_LOCALIZED = "opentracks:typeTranslated";
|
||||
private static final String TAG_MARKER = "wpt";
|
||||
private static final String TAG_ID = "opentracks:trackid";
|
||||
|
||||
@@ -99,6 +99,7 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private String name;
|
||||
private String description;
|
||||
private String activityType;
|
||||
private String activityTypeLocalized;
|
||||
private String latitude;
|
||||
private String longitude;
|
||||
private String altitude;
|
||||
@@ -159,7 +160,11 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
case TAG_GPX -> onFileEnd();
|
||||
case TAG_MARKER -> onMarkerEnd();
|
||||
case TAG_TRACK -> {
|
||||
trackImporter.setTrack(context, name, uuid, description, activityType, null, zoneOffset);
|
||||
if (activityTypeLocalized == null ) {
|
||||
// Backward compatibility: up v4.9.1 as <type> contained localized content.
|
||||
activityTypeLocalized = activityType;
|
||||
}
|
||||
trackImporter.setTrack(context, name, uuid, description, activityTypeLocalized, activityType, zoneOffset);
|
||||
zoneOffset = null;
|
||||
}
|
||||
case TAG_TRACK_SEGMENT -> onTrackSegmentEnd();
|
||||
@@ -174,9 +179,16 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
description = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_TYPE -> {
|
||||
case TAG_TYPE -> { //Track or Marker/WPT
|
||||
if (content != null) {
|
||||
// In older version this might be localized content.
|
||||
activityType = content.trim();
|
||||
markerType = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_TYPE_LOCALIZED -> {
|
||||
if (content != null) {
|
||||
activityTypeLocalized = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_TIME -> {
|
||||
@@ -189,11 +201,6 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
altitude = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_COMMENT -> {
|
||||
if (content != null) {
|
||||
markerType = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_EXTENSION_SPEED, TAG_EXTENSION_SPEED_COMPAT -> {
|
||||
if (content != null) {
|
||||
speed = content.trim();
|
||||
@@ -385,7 +392,6 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private void onMarkerStart(Attributes attributes) {
|
||||
name = null;
|
||||
description = null;
|
||||
activityType = null;
|
||||
photoUrl = null;
|
||||
latitude = attributes.getValue(ATTRIBUTE_LAT);
|
||||
longitude = attributes.getValue(ATTRIBUTE_LON);
|
||||
@@ -415,8 +421,8 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
if (description != null) {
|
||||
marker.setDescription(description);
|
||||
}
|
||||
if (activityType != null) {
|
||||
marker.setCategory(activityType);
|
||||
if (markerType != null) {
|
||||
marker.setCategory(markerType);
|
||||
}
|
||||
|
||||
if (photoUrl != null) {
|
||||
|
||||
@@ -53,7 +53,6 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
|
||||
private static final String TAG_COORDINATES = "coordinates";
|
||||
private static final String TAG_DESCRIPTION = "description";
|
||||
private static final String TAG_ICON = "icon";
|
||||
|
||||
private static final String TAG_COORD = "coord";
|
||||
private static final String TAG_KML22_COORD = "gx:coord";
|
||||
@@ -61,7 +60,7 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private static final String TAG_MULTI_TRACK = "MultiTrack";
|
||||
private static final String TAG_KML22_MULTI_TRACK = "gx:MultiTrack";
|
||||
|
||||
private static final String TAG_DATA_ACTIVITYTYPE = "Data";
|
||||
private static final String TAG_EXTENDED_DATA = "Data";
|
||||
|
||||
private static final String TAG_SIMPLE_ARRAY_DATA = "SimpleArrayData";
|
||||
private static final String TAG_KML22_SIMPLE_ARRAY_DATA = "gx:SimpleArrayData";
|
||||
@@ -94,7 +93,7 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private final ArrayList<Instant> whenList = new ArrayList<>();
|
||||
private final ArrayList<Location> locationList = new ArrayList<>();
|
||||
|
||||
private String dataType; //Could be converted to an ENUM
|
||||
private String dataType;
|
||||
|
||||
private final ArrayList<String> trackpointTypeList = new ArrayList<>();
|
||||
private final ArrayList<Float> sensorSpeedList = new ArrayList<>();
|
||||
@@ -112,10 +111,10 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
// The current element content
|
||||
private String content = "";
|
||||
|
||||
private String icon;
|
||||
private String name;
|
||||
private String description;
|
||||
private String activityType;
|
||||
private String activityTypeLocalized;
|
||||
private String latitude;
|
||||
private String longitude;
|
||||
private String altitude;
|
||||
@@ -148,7 +147,7 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
}
|
||||
onTrackSegmentStart();
|
||||
}
|
||||
case TAG_DATA_ACTIVITYTYPE, TAG_SIMPLE_ARRAY_DATA, TAG_KML22_SIMPLE_ARRAY_DATA ->
|
||||
case TAG_EXTENDED_DATA, TAG_SIMPLE_ARRAY_DATA, TAG_KML22_SIMPLE_ARRAY_DATA ->
|
||||
dataType = attributes.getValue(ATTRIBUTE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -167,18 +166,24 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
onMarkerEnd();
|
||||
case TAG_COORDINATES -> onMarkerLocationEnd();
|
||||
case TAG_MULTI_TRACK, TAG_KML22_MULTI_TRACK -> {
|
||||
trackImporter.setTrack(context, name, uuid, description, activityType, icon, zoneOffset);
|
||||
trackImporter.setTrack(context, name, uuid, description, activityTypeLocalized, activityType, zoneOffset);
|
||||
zoneOffset = null;
|
||||
}
|
||||
case TAG_TRACK, TAG_KML22_TRACK -> onTrackSegmentEnd();
|
||||
case TAG_COORD, TAG_KML22_COORD -> onCoordEnded();
|
||||
case TAG_VALUE, TAG_KML22_VALUE -> {
|
||||
if (KMLTrackExporter.EXTENDED_DATA_TYPE_ACTIVITYTYPE.equals(dataType)) {
|
||||
if (content != null) {
|
||||
activityType = content.trim();
|
||||
switch (dataType) {
|
||||
case KMLTrackExporter.EXTENDED_DATA_ACTIVITY_TYPE -> {
|
||||
if (content != null) {
|
||||
activityType = content.trim();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onExtendedDataValueEnd();
|
||||
case KMLTrackExporter.EXTENDED_DATA_TYPE_LOCALIZED -> {
|
||||
if (content != null) {
|
||||
activityTypeLocalized = content.trim();
|
||||
}
|
||||
}
|
||||
default -> onExtendedDataValueEnd();
|
||||
}
|
||||
}
|
||||
case TAG_NAME -> {
|
||||
@@ -196,11 +201,6 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
description = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_ICON -> {
|
||||
if (content != null) {
|
||||
icon = content.trim();
|
||||
}
|
||||
}
|
||||
case TAG_WHEN -> {
|
||||
if (content != null) {
|
||||
try {
|
||||
@@ -233,9 +233,8 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private void onMarkerStart() {
|
||||
// Reset all Placemark variables
|
||||
name = null;
|
||||
icon = null;
|
||||
description = null;
|
||||
activityType = null;
|
||||
activityTypeLocalized = null;
|
||||
photoUrl = null;
|
||||
latitude = null;
|
||||
longitude = null;
|
||||
@@ -262,13 +261,13 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
Marker marker = new Marker(null, new TrackPoint(TrackPoint.Type.TRACKPOINT, location, whenList.get(0))); //TODO Creating marker without need
|
||||
marker.setName(name != null ? name : "");
|
||||
marker.setDescription(description != null ? description : "");
|
||||
marker.setCategory(activityType != null ? activityType : "");
|
||||
marker.setCategory(activityTypeLocalized != null ? activityTypeLocalized : "");
|
||||
marker.setPhotoUrl(photoUrl);
|
||||
markers.add(marker);
|
||||
|
||||
name = null;
|
||||
description = null;
|
||||
activityType = null;
|
||||
activityTypeLocalized = null;
|
||||
photoUrl = null;
|
||||
whenList.clear();
|
||||
}
|
||||
|
||||
@@ -105,7 +105,6 @@ public class TrackImporter {
|
||||
if (activityTypeLocalized != null) {
|
||||
track.setActivityTypeLocalized(activityTypeLocalized);
|
||||
}
|
||||
|
||||
ActivityType activityType;
|
||||
if (activityTypeId == null) {
|
||||
activityType = ActivityType.findByLocalizedString(context, activityTypeLocalized);
|
||||
|
||||
Reference in New Issue
Block a user