forked from upstream-mirrors/OpenTracks
Segments: on import restore manual segment start/end if resume/pause trackpoints were exported.
This commit is contained in:
@@ -0,0 +1,142 @@
|
|||||||
|
package de.dennisguse.opentracks.io.file.importer;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import androidx.test.filters.LargeTest;
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||||
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that legacy KML/GPX formats can still be imported.
|
||||||
|
*/
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class LegacyImportTest {
|
||||||
|
|
||||||
|
private final Context context = ApplicationProvider.getApplicationContext();
|
||||||
|
private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||||
|
|
||||||
|
private Track.Id importTrackId;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
if (importTrackId != null) {
|
||||||
|
contentProviderUtils.deleteTrack(context, importTrackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that data with statistics markers is imported and those ignored.
|
||||||
|
* Statistics marker were created to avoid recomputing the track statistics (e.g., distance until a certain time).
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
@Test
|
||||||
|
public void kml_with_statistics_marker() {
|
||||||
|
// given
|
||||||
|
KmlFileTrackImporter trackImporter = new KmlFileTrackImporter(context);
|
||||||
|
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_kml_statistics_marker);
|
||||||
|
|
||||||
|
// when
|
||||||
|
// 1. import
|
||||||
|
importTrackId = trackImporter.importFile(inputStream);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// 1. track
|
||||||
|
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||||
|
assertNotNull(importedTrack);
|
||||||
|
assertEquals("unknown", importedTrack.getCategory());
|
||||||
|
assertEquals("Test Track", importedTrack.getDescription());
|
||||||
|
assertEquals("2020-11-28 18:06", importedTrack.getName());
|
||||||
|
assertEquals("UNKNOWN", importedTrack.getIcon());
|
||||||
|
|
||||||
|
// 2. markers
|
||||||
|
assertEquals(0, contentProviderUtils.getMarkerCount(importTrackId));
|
||||||
|
|
||||||
|
// 3. trackpoints
|
||||||
|
List<TrackPoint> importedTrackPoints = contentProviderUtils.getTrackPoints(importTrackId);
|
||||||
|
assertEquals(6, importedTrackPoints.size());
|
||||||
|
|
||||||
|
// first 3 trackpoints
|
||||||
|
assertTrackpoint(importedTrackPoints.get(0), TrackPoint.Type.SEGMENT_START_AUTOMATIC, "2020-11-28T17:06:22.401Z", 1.234156, 12.340097, 469.286376953125);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(1), TrackPoint.Type.TRACKPOINT, "2020-11-28T17:06:25.448Z", 1.23415, 12.340036, 439.1626281738281);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(2), TrackPoint.Type.TRACKPOINT, "2020-11-28T17:06:47.888Z", 1.23405, 12.340057, 421.8070983886719);
|
||||||
|
|
||||||
|
// created resume trackpoint with time of next valid trackpoint
|
||||||
|
assertTrackpoint(importedTrackPoints.get(3), TrackPoint.Type.SEGMENT_START_AUTOMATIC, "2020-11-28T17:06:55.861Z", 1.23405, 12.340057, 419.93902587890625);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(4), TrackPoint.Type.TRACKPOINT, "2020-11-28T17:06:56.905Z", 1.23405, 12.340057, 419.9036560058594);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(5), TrackPoint.Type.TRACKPOINT, "2020-11-28T17:07:20.870Z", 1.234046, 12.340082, 417.99432373046875);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that data that contains pause (lat=100, lng=0) and resume (lat=200, lng=0) locations are restored to a segment break.
|
||||||
|
*/
|
||||||
|
@LargeTest
|
||||||
|
@Test
|
||||||
|
public void gpx_with_pause_resume() {
|
||||||
|
// given
|
||||||
|
GpxFileTrackImporter trackImporter = new GpxFileTrackImporter(context);
|
||||||
|
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_gpx_pause_resume);
|
||||||
|
|
||||||
|
// when
|
||||||
|
// 1. import
|
||||||
|
importTrackId = trackImporter.importFile(inputStream);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// 1. track
|
||||||
|
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
||||||
|
assertNotNull(importedTrack);
|
||||||
|
assertEquals("the category", importedTrack.getCategory());
|
||||||
|
assertEquals("the description", importedTrack.getDescription());
|
||||||
|
assertEquals("2021-01-07 22:51", importedTrack.getName());
|
||||||
|
assertEquals("UNKNOWN", importedTrack.getIcon());
|
||||||
|
|
||||||
|
// 3. trackpoints
|
||||||
|
List<TrackPoint> importedTrackPoints = contentProviderUtils.getTrackPoints(importTrackId);
|
||||||
|
assertEquals(6, importedTrackPoints.size());
|
||||||
|
|
||||||
|
// first segment
|
||||||
|
assertTrackpoint(importedTrackPoints.get(0), TrackPoint.Type.SEGMENT_START_AUTOMATIC, "2021-01-07T21:51:59.179Z", 14.0, 3.0, 10.0);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(1), TrackPoint.Type.TRACKPOINT, "2021-01-07T21:52:00.653Z", 14.001, 3.0, 10.0);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(2), TrackPoint.Type.TRACKPOINT, "2021-01-07T21:52:01.010Z", 14.002, 3.0, 10.0);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(3), TrackPoint.Type.SEGMENT_END_MANUAL, "2021-01-07T21:52:02.658Z", null, null, null);
|
||||||
|
|
||||||
|
// created resume trackpoint with time of next valid trackpoint
|
||||||
|
assertTrackpoint(importedTrackPoints.get(4), TrackPoint.Type.SEGMENT_START_MANUAL, "2021-01-07T21:52:03.873Z", null, null, null);
|
||||||
|
assertTrackpoint(importedTrackPoints.get(5), TrackPoint.Type.TRACKPOINT, "2021-01-07T21:52:04.103Z", 14.003, 3.0, 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertTrackpoint(final TrackPoint trackPoint, final TrackPoint.Type type, final String when, final Double longitude, final Double latitude, final Double altitude) {
|
||||||
|
assertEquals(StringUtils.parseTime(when), trackPoint.getTime());
|
||||||
|
assertEquals(type, trackPoint.getType());
|
||||||
|
|
||||||
|
if (longitude == null) {
|
||||||
|
assertFalse(trackPoint.hasLocation());
|
||||||
|
} else {
|
||||||
|
assertEquals(latitude, (Double) trackPoint.getLatitude());
|
||||||
|
assertEquals(longitude, (Double) trackPoint.getLongitude());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (altitude == null) {
|
||||||
|
assertFalse(trackPoint.hasAltitude());
|
||||||
|
} else {
|
||||||
|
assertEquals(altitude, (Double) trackPoint.getAltitude());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
-90
@@ -1,90 +0,0 @@
|
|||||||
package de.dennisguse.opentracks.io.file.importer;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
|
||||||
import androidx.test.filters.LargeTest;
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.JUnit4;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
|
||||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Imports a legacy kml file with a statistics marker at the beginning
|
|
||||||
*/
|
|
||||||
@RunWith(JUnit4.class)
|
|
||||||
public class LegacyKmlImportTest {
|
|
||||||
|
|
||||||
private final Context context = ApplicationProvider.getApplicationContext();
|
|
||||||
private final ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
|
||||||
|
|
||||||
private Track.Id importTrackId;
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
if (importTrackId != null) {
|
|
||||||
contentProviderUtils.deleteTrack(context, importTrackId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@LargeTest
|
|
||||||
@Test
|
|
||||||
public void kml_legacy_track_import() {
|
|
||||||
// given
|
|
||||||
KmlFileTrackImporter trackImporter = new KmlFileTrackImporter(context);
|
|
||||||
InputStream inputStream = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.debug.test.R.raw.legacy_track);
|
|
||||||
|
|
||||||
// when
|
|
||||||
// 1. import
|
|
||||||
importTrackId = trackImporter.importFile(inputStream);
|
|
||||||
|
|
||||||
// then
|
|
||||||
// 1. track
|
|
||||||
Track importedTrack = contentProviderUtils.getTrack(importTrackId);
|
|
||||||
assertNotNull(importedTrack);
|
|
||||||
assertEquals("unknown", importedTrack.getCategory());
|
|
||||||
assertEquals("Test Track", importedTrack.getDescription());
|
|
||||||
assertEquals("2020-11-28 18:06", importedTrack.getName());
|
|
||||||
assertEquals("UNKNOWN", importedTrack.getIcon());
|
|
||||||
|
|
||||||
// 2. markers
|
|
||||||
assertEquals(0, contentProviderUtils.getMarkerCount(importTrackId));
|
|
||||||
|
|
||||||
// 3. trackpoints
|
|
||||||
List<TrackPoint> importedTrackPoints = contentProviderUtils.getTrackPoints(importTrackId);
|
|
||||||
assertEquals(6, importedTrackPoints.size());
|
|
||||||
|
|
||||||
// first 3 trackpoints
|
|
||||||
assertEquals(TrackPoint.Type.SEGMENT_START_AUTOMATIC, importedTrackPoints.get(0).getType());
|
|
||||||
assertTrackpoint(importedTrackPoints.get(0), "2020-11-28T17:06:22.401Z", 1.234156, 12.340097, 469.286376953125);
|
|
||||||
assertTrackpoint(importedTrackPoints.get(1), "2020-11-28T17:06:25.448Z", 1.23415, 12.340036, 439.1626281738281);
|
|
||||||
assertTrackpoint(importedTrackPoints.get(2), "2020-11-28T17:06:47.888Z", 1.23405, 12.340057, 421.8070983886719);
|
|
||||||
|
|
||||||
// created resume trackpoint with time of next valid trackpoint
|
|
||||||
assertEquals(TrackPoint.Type.SEGMENT_START_AUTOMATIC, importedTrackPoints.get(3).getType());
|
|
||||||
assertTrackpoint(importedTrackPoints.get(3), "2020-11-28T17:06:55.861Z", 1.23405, 12.340057, 419.93902587890625);
|
|
||||||
assertTrackpoint(importedTrackPoints.get(4), "2020-11-28T17:06:56.905Z", 1.23405, 12.340057, 419.9036560058594);
|
|
||||||
assertTrackpoint(importedTrackPoints.get(5), "2020-11-28T17:07:20.870Z", 1.234046, 12.340082, 417.99432373046875);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTrackpoint(final TrackPoint trackPoint, final String when, final double longitude, final double latitude, final double altitude) {
|
|
||||||
assertEquals(StringUtils.parseTime(when), trackPoint.getTime());
|
|
||||||
assertEquals(latitude, trackPoint.getLatitude(), 0.001d);
|
|
||||||
assertEquals(longitude, trackPoint.getLongitude(), 0.001d);
|
|
||||||
assertEquals(altitude, trackPoint.getAltitude(), 0.001d);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
This hidden file is here to ensure there is a res folder.
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gpxtpx="http://www.garmin.com/xmlschemes/TrackPointExtension/v2" xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1" xmlns:topografix="http://www.topografix.com/GPX/Private/TopoGrafix/0/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" creator="OpenTracks (Debug)" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.topografix.com/GPX/Private/TopoGrafix/0/1 http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd">
|
||||||
|
<metadata>
|
||||||
|
<name><![CDATA[2021-01-07 22:51]]></name>
|
||||||
|
<desc><![CDATA[the description]]></desc>
|
||||||
|
</metadata>
|
||||||
|
<wpt lat="3" lon="14">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:51:59.179Z</time>
|
||||||
|
<name><![CDATA[Marker 1]]></name>
|
||||||
|
<desc><![CDATA[Marker 1 desc]]></desc>
|
||||||
|
<type><![CDATA[Marker 1 category]]></type>
|
||||||
|
</wpt>
|
||||||
|
<wpt lat="3" lon="14.002">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:52:01.010Z</time>
|
||||||
|
<name><![CDATA[Marker 2]]></name>
|
||||||
|
<desc><![CDATA[Marker 2 desc]]></desc>
|
||||||
|
<type><![CDATA[Marker 2 category]]></type>
|
||||||
|
</wpt>
|
||||||
|
<trk>
|
||||||
|
<name><![CDATA[2021-01-07 22:51]]></name>
|
||||||
|
<desc><![CDATA[the description]]></desc>
|
||||||
|
<type><![CDATA[the category]]></type>
|
||||||
|
<extensions>
|
||||||
|
<topografix:color>c0c0c0</topografix:color>
|
||||||
|
<opentracks:trackid>7002101e-4198-4613-8c24-544e01ca3981</opentracks:trackid>
|
||||||
|
</extensions>
|
||||||
|
<trkseg>
|
||||||
|
<trkpt lat="3" lon="14">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:51:59.179Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="3" lon="14.001">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:52:00.653Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="3" lon="14.002">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:52:01.010Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="100" lon="0">
|
||||||
|
<time>2021-01-07T21:52:02.658Z</time>
|
||||||
|
</trkpt>
|
||||||
|
|
||||||
|
<trkpt lat="200" lon="0">
|
||||||
|
<time>2021-01-07T21:52:03.873Z</time>
|
||||||
|
</trkpt>
|
||||||
|
<trkpt lat="3" lon="14.003">
|
||||||
|
<ele>10</ele>
|
||||||
|
<time>2021-01-07T21:52:04.103Z</time>
|
||||||
|
</trkpt>
|
||||||
|
</trkseg>
|
||||||
|
</trk>
|
||||||
|
</gpx>
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1">
|
||||||
|
<Document>
|
||||||
|
<open>1</open>
|
||||||
|
<visibility>1</visibility>
|
||||||
|
<name><![CDATA[2020-11-28 18:06]]></name>
|
||||||
|
<atom:generator><![CDATA[OpenTracks (Debug)]]></atom:generator>
|
||||||
|
<Style id="track">
|
||||||
|
<LineStyle>
|
||||||
|
<color>7f0000ff</color>
|
||||||
|
<width>4</width>
|
||||||
|
</LineStyle>
|
||||||
|
<IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon>
|
||||||
|
<href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
|
||||||
|
</Icon>
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<Style id="start">
|
||||||
|
<IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon>
|
||||||
|
<href>http://maps.google.com/mapfiles/kml/paddle/grn-circle.png</href>
|
||||||
|
</Icon>
|
||||||
|
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels" />
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<Style id="end">
|
||||||
|
<IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon>
|
||||||
|
<href>http://maps.google.com/mapfiles/kml/paddle/red-circle.png</href>
|
||||||
|
</Icon>
|
||||||
|
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels" />
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<Style id="waypoint">
|
||||||
|
<IconStyle>
|
||||||
|
<scale>1.3</scale>
|
||||||
|
<Icon>
|
||||||
|
<href>http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png</href>
|
||||||
|
</Icon>
|
||||||
|
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<Schema id="schema">
|
||||||
|
<gx:SimpleArrayField name="speed" type="float">
|
||||||
|
<displayName><![CDATA[Speed (m/s)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="power" type="float">
|
||||||
|
<displayName><![CDATA[Power (W)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="cadence" type="float">
|
||||||
|
<displayName><![CDATA[Cadence (rpm)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
<gx:SimpleArrayField name="heart_rate" type="float">
|
||||||
|
<displayName><![CDATA[Heart rate (bpm)]]></displayName>
|
||||||
|
</gx:SimpleArrayField>
|
||||||
|
</Schema>
|
||||||
|
<Folder>
|
||||||
|
<name><![CDATA[Sun, 28 Nov 2020 18:06 Markers]]></name>
|
||||||
|
<open>1</open>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[Split 0]]></name>
|
||||||
|
<description><![CDATA[Total distance: 0.00 km (0.0 mi)
|
||||||
|
Total time: 00:00
|
||||||
|
Moving time: 00:00
|
||||||
|
Average speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average moving speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Max speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Average moving pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Fastest pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Max elevation: -9223372036854775808 m (-9223372036854775808 ft)
|
||||||
|
Min elevation: 9223372036854775807 m (9223372036854775807 ft)
|
||||||
|
Elevation gain: 0 m (0 ft)
|
||||||
|
Max grade: 0 %
|
||||||
|
Min grade: 0 %
|
||||||
|
Recorded: 6/23 11:29]]></description>
|
||||||
|
<TimeStamp>
|
||||||
|
<when>1970-01-01T00:00:00Z</when>
|
||||||
|
</TimeStamp>
|
||||||
|
<styleUrl>#waypoint</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>180.0,100.0</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
</Folder>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06 (Start)]]></name>
|
||||||
|
<description />
|
||||||
|
<TimeStamp>
|
||||||
|
<when>2020-11-28T17:06:22.401Z</when>
|
||||||
|
</TimeStamp>
|
||||||
|
<styleUrl>#start</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>1.234156,12.340097,469.286376953125</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06]]></name>
|
||||||
|
<description><![CDATA[Test Track]]></description>
|
||||||
|
<icon><![CDATA[UNKNOWN]]></icon>
|
||||||
|
<opentracks:trackid>2f170875-55d7-445d-b2b8-22a573c81dbc</opentracks:trackid>
|
||||||
|
<styleUrl>#track</styleUrl>
|
||||||
|
<ExtendedData>
|
||||||
|
<Data name="type">
|
||||||
|
<value><![CDATA[unknown]]></value>
|
||||||
|
</Data>
|
||||||
|
</ExtendedData>
|
||||||
|
<gx:MultiTrack>
|
||||||
|
<altitudeMode>absolute</altitudeMode>
|
||||||
|
<gx:interpolate>1</gx:interpolate>
|
||||||
|
<gx:Track>
|
||||||
|
<when>2020-11-28T17:06:22.401Z</when>
|
||||||
|
<gx:coord>1.234156 12.340097 469.286376953125</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:25.448Z</when>
|
||||||
|
<gx:coord>1.23415 12.340036 439.1626281738281</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:47.888Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 421.8070983886719</gx:coord>
|
||||||
|
<ExtendedData>
|
||||||
|
<SchemaData schemaUrl="#schema">
|
||||||
|
<gx:SimpleArrayData name="speed">
|
||||||
|
<gx:value>0.5391469</gx:value>
|
||||||
|
<gx:value>0.15777911</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
<gx:SimpleArrayData name="elevation_gain">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
</SchemaData>
|
||||||
|
</ExtendedData>
|
||||||
|
</gx:Track>
|
||||||
|
<gx:Track>
|
||||||
|
<when>2020-11-28T17:06:55.861Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 419.93902587890625</gx:coord>
|
||||||
|
<when>2020-11-28T17:06:56.905Z</when>
|
||||||
|
<gx:coord>1.23405 12.340057 419.9036560058594</gx:coord>
|
||||||
|
<when>2020-11-28T17:07:20.870Z</when>
|
||||||
|
<gx:coord>1.234046 12.340082 417.99432373046875</gx:coord>
|
||||||
|
<ExtendedData>
|
||||||
|
<SchemaData schemaUrl="#schema">
|
||||||
|
<gx:SimpleArrayData name="speed">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
<gx:SimpleArrayData name="elevation_gain">
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
<gx:value>0.0</gx:value>
|
||||||
|
</gx:SimpleArrayData>
|
||||||
|
</SchemaData>
|
||||||
|
</ExtendedData>
|
||||||
|
</gx:Track>
|
||||||
|
</gx:MultiTrack>
|
||||||
|
</Placemark>
|
||||||
|
<Placemark>
|
||||||
|
<name><![CDATA[2020-11-28 18:06 (End)]]></name>
|
||||||
|
<description><![CDATA[OpenTracks (Debug)
|
||||||
|
|
||||||
|
Name: 2020-11-28 18:06
|
||||||
|
Activity type: unknown
|
||||||
|
Description: -
|
||||||
|
Total distance: 0.01 km (0.0 mi)
|
||||||
|
Total time: 01:04
|
||||||
|
Moving time: 00:00
|
||||||
|
Average speed: 0.49 km/h (0.3 mi/h)
|
||||||
|
Average moving speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Max speed: 0.00 km/h (0.0 mi/h)
|
||||||
|
Average pace: 122:30 min/km (197:08 min/mi)
|
||||||
|
Average moving pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Fastest pace: 0:00 min/km (0:00 min/mi)
|
||||||
|
Max elevation: 469 m (1540 ft)
|
||||||
|
Min elevation: 419 m (1376 ft)
|
||||||
|
Elevation gain: 0 m (0 ft)
|
||||||
|
Recorded: 11/28 18:06]]></description>
|
||||||
|
<TimeStamp>
|
||||||
|
<when>2020-11-28T17:07:20.870Z</when>
|
||||||
|
</TimeStamp>
|
||||||
|
<styleUrl>#end</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>1.234046,12.340082,417.99432373046875</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
</Document>
|
||||||
|
</kml>
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<kml xmlns="http://www.opengis.net/kml/2.2"
|
|
||||||
xmlns:gx="http://www.google.com/kml/ext/2.2"
|
|
||||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
|
||||||
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1">
|
|
||||||
<Document>
|
|
||||||
<open>1</open>
|
|
||||||
<visibility>1</visibility>
|
|
||||||
<name><![CDATA[2020-11-28 18:06]]></name>
|
|
||||||
<atom:generator><![CDATA[OpenTracks (Debug)]]></atom:generator>
|
|
||||||
<Style id="track">
|
|
||||||
<LineStyle><color>7f0000ff</color><width>4</width></LineStyle>
|
|
||||||
<IconStyle>
|
|
||||||
<scale>1.3</scale>
|
|
||||||
<Icon><href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href></Icon>
|
|
||||||
</IconStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="start"><IconStyle>
|
|
||||||
<scale>1.3</scale>
|
|
||||||
<Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-circle.png</href></Icon>
|
|
||||||
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
|
|
||||||
</IconStyle></Style>
|
|
||||||
<Style id="end"><IconStyle>
|
|
||||||
<scale>1.3</scale>
|
|
||||||
<Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-circle.png</href></Icon>
|
|
||||||
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
|
|
||||||
</IconStyle></Style>
|
|
||||||
<Style id="waypoint"><IconStyle>
|
|
||||||
<scale>1.3</scale>
|
|
||||||
<Icon><href>http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png</href></Icon>
|
|
||||||
<hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
|
|
||||||
</IconStyle></Style>
|
|
||||||
<Schema id="schema">
|
|
||||||
<gx:SimpleArrayField name="speed" type="float">
|
|
||||||
<displayName><![CDATA[Speed (m/s)]]></displayName>
|
|
||||||
</gx:SimpleArrayField>
|
|
||||||
<gx:SimpleArrayField name="power" type="float">
|
|
||||||
<displayName><![CDATA[Power (W)]]></displayName>
|
|
||||||
</gx:SimpleArrayField>
|
|
||||||
<gx:SimpleArrayField name="cadence" type="float">
|
|
||||||
<displayName><![CDATA[Cadence (rpm)]]></displayName>
|
|
||||||
</gx:SimpleArrayField>
|
|
||||||
<gx:SimpleArrayField name="heart_rate" type="float">
|
|
||||||
<displayName><![CDATA[Heart rate (bpm)]]></displayName>
|
|
||||||
</gx:SimpleArrayField>
|
|
||||||
</Schema>
|
|
||||||
<Folder>
|
|
||||||
<name><![CDATA[Sun, 28 Nov 2020 18:06 Markers]]></name>
|
|
||||||
<open>1</open>
|
|
||||||
<Placemark>
|
|
||||||
<name><![CDATA[Split 0]]></name>
|
|
||||||
<description><![CDATA[Total distance: 0.00 km (0.0 mi)
|
|
||||||
Total time: 00:00
|
|
||||||
Moving time: 00:00
|
|
||||||
Average speed: 0.00 km/h (0.0 mi/h)
|
|
||||||
Average moving speed: 0.00 km/h (0.0 mi/h)
|
|
||||||
Max speed: 0.00 km/h (0.0 mi/h)
|
|
||||||
Average pace: 0:00 min/km (0:00 min/mi)
|
|
||||||
Average moving pace: 0:00 min/km (0:00 min/mi)
|
|
||||||
Fastest pace: 0:00 min/km (0:00 min/mi)
|
|
||||||
Max elevation: -9223372036854775808 m (-9223372036854775808 ft)
|
|
||||||
Min elevation: 9223372036854775807 m (9223372036854775807 ft)
|
|
||||||
Elevation gain: 0 m (0 ft)
|
|
||||||
Max grade: 0 %
|
|
||||||
Min grade: 0 %
|
|
||||||
Recorded: 6/23 11:29
|
|
||||||
]]></description>
|
|
||||||
<TimeStamp><when>1970-01-01T00:00:00Z</when></TimeStamp>
|
|
||||||
<styleUrl>#waypoint</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<coordinates>180.0,100.0</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Placemark>
|
|
||||||
<name><![CDATA[2020-11-28 18:06 (Start)]]></name>
|
|
||||||
<description><![CDATA[]]></description>
|
|
||||||
<TimeStamp><when>2020-11-28T17:06:22.401Z</when></TimeStamp>
|
|
||||||
<styleUrl>#start</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<coordinates>1.234156,12.340097,469.286376953125</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name><![CDATA[2020-11-28 18:06]]></name>
|
|
||||||
<description><![CDATA[Test Track]]></description>
|
|
||||||
<icon><![CDATA[UNKNOWN]]></icon>
|
|
||||||
<opentracks:trackid>2f170875-55d7-445d-b2b8-22a573c81dbc</opentracks:trackid>
|
|
||||||
<styleUrl>#track</styleUrl>
|
|
||||||
<ExtendedData>
|
|
||||||
<Data name="type"><value><![CDATA[unknown]]></value></Data>
|
|
||||||
</ExtendedData>
|
|
||||||
<gx:MultiTrack>
|
|
||||||
<altitudeMode>absolute</altitudeMode>
|
|
||||||
<gx:interpolate>1</gx:interpolate>
|
|
||||||
<gx:Track>
|
|
||||||
<when>2020-11-28T17:06:22.401Z</when>
|
|
||||||
<gx:coord>1.234156 12.340097 469.286376953125</gx:coord>
|
|
||||||
<when>2020-11-28T17:06:25.448Z</when>
|
|
||||||
<gx:coord>1.23415 12.340036 439.1626281738281</gx:coord>
|
|
||||||
<when>2020-11-28T17:06:47.888Z</when>
|
|
||||||
<gx:coord>1.23405 12.340057 421.8070983886719</gx:coord>
|
|
||||||
<ExtendedData>
|
|
||||||
<SchemaData schemaUrl="#schema">
|
|
||||||
<gx:SimpleArrayData name="speed">
|
|
||||||
<gx:value>0.5391469</gx:value>
|
|
||||||
<gx:value>0.15777911</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
</gx:SimpleArrayData>
|
|
||||||
<gx:SimpleArrayData name="elevation_gain">
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
</gx:SimpleArrayData>
|
|
||||||
</SchemaData>
|
|
||||||
</ExtendedData>
|
|
||||||
</gx:Track>
|
|
||||||
<gx:Track>
|
|
||||||
<when>2020-11-28T17:06:55.861Z</when>
|
|
||||||
<gx:coord>1.23405 12.340057 419.93902587890625</gx:coord>
|
|
||||||
<when>2020-11-28T17:06:56.905Z</when>
|
|
||||||
<gx:coord>1.23405 12.340057 419.9036560058594</gx:coord>
|
|
||||||
<when>2020-11-28T17:07:20.870Z</when>
|
|
||||||
<gx:coord>1.234046 12.340082 417.99432373046875</gx:coord>
|
|
||||||
<ExtendedData>
|
|
||||||
<SchemaData schemaUrl="#schema">
|
|
||||||
<gx:SimpleArrayData name="speed">
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
</gx:SimpleArrayData>
|
|
||||||
<gx:SimpleArrayData name="elevation_gain">
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
<gx:value>0.0</gx:value>
|
|
||||||
</gx:SimpleArrayData>
|
|
||||||
</SchemaData>
|
|
||||||
</ExtendedData>
|
|
||||||
</gx:Track>
|
|
||||||
</gx:MultiTrack>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name><![CDATA[2020-11-28 18:06 (End)]]></name>
|
|
||||||
<description><![CDATA[OpenTracks (Debug)
|
|
||||||
|
|
||||||
Name: 2020-11-28 18:06
|
|
||||||
Activity type: unknown
|
|
||||||
Description: -
|
|
||||||
Total distance: 0.01 km (0.0 mi)
|
|
||||||
Total time: 01:04
|
|
||||||
Moving time: 00:00
|
|
||||||
Average speed: 0.49 km/h (0.3 mi/h)
|
|
||||||
Average moving speed: 0.00 km/h (0.0 mi/h)
|
|
||||||
Max speed: 0.00 km/h (0.0 mi/h)
|
|
||||||
Average pace: 122:30 min/km (197:08 min/mi)
|
|
||||||
Average moving pace: 0:00 min/km (0:00 min/mi)
|
|
||||||
Fastest pace: 0:00 min/km (0:00 min/mi)
|
|
||||||
Max elevation: 469 m (1540 ft)
|
|
||||||
Min elevation: 419 m (1376 ft)
|
|
||||||
Elevation gain: 0 m (0 ft)
|
|
||||||
Recorded: 11/28 18:06
|
|
||||||
]]></description>
|
|
||||||
<TimeStamp><when>2020-11-28T17:07:20.870Z</when></TimeStamp>
|
|
||||||
<styleUrl>#end</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<coordinates>1.234046,12.340082,417.99432373046875</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
</Document>
|
|
||||||
</kml>
|
|
||||||
@@ -279,7 +279,7 @@ public class ExportActivity extends FragmentActivity implements ExportServiceRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onExportCompleted(Track.Id trackId) {
|
private void onExportCompleted(Track.Id trackId) {
|
||||||
trackIds.remove(trackId);
|
trackIds.remove(trackId);
|
||||||
setProgress();
|
setProgress();
|
||||||
if (trackIds.isEmpty()) {
|
if (trackIds.isEmpty()) {
|
||||||
onExportEnded();
|
onExportEnded();
|
||||||
|
|||||||
+20
-6
@@ -29,6 +29,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -284,7 +285,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
//If not the first segment, add a pause separator if there is at least one TrackPoint in the last segment.
|
//If not the first segment, add a pause separator if there is at least one TrackPoint in the last segment.
|
||||||
if (trackData.numberOfSegments > 1
|
if (trackData.numberOfSegments > 1
|
||||||
&& trackData.lastLocationInCurrentSegment != null
|
&& trackData.lastLocationInCurrentSegment != null
|
||||||
&& (trackData.lastLocationInCurrentSegment.getType().equals(TrackPoint.Type.SEGMENT_START_MANUAL) || trackData.lastLocationInCurrentSegment.getType().equals(TrackPoint.Type.SEGMENT_START_AUTOMATIC))
|
&& (trackData.lastLocationInCurrentSegment.getType().equals(TrackPoint.Type.SEGMENT_START_MANUAL))
|
||||||
) {
|
) {
|
||||||
insertTrackPoint(TrackPoint.createSegmentEndWithTime(trackData.lastLocationInCurrentSegment.getTime()));
|
insertTrackPoint(TrackPoint.createSegmentEndWithTime(trackData.lastLocationInCurrentSegment.getTime()));
|
||||||
}
|
}
|
||||||
@@ -336,6 +337,23 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
protected TrackPoint getTrackPoint() throws SAXException {
|
protected TrackPoint getTrackPoint() throws SAXException {
|
||||||
TrackPoint trackPoint = createTrackPoint();
|
TrackPoint trackPoint = createTrackPoint();
|
||||||
|
|
||||||
|
if (trackPoint.hasLocation()) {
|
||||||
|
long time = trackPoint.getTime();
|
||||||
|
Date d = new Date(time);
|
||||||
|
if (trackPoint.getLatitude() == 100) {
|
||||||
|
//TODO Remove by 31st December 2021.
|
||||||
|
trackPoint = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL);
|
||||||
|
trackPoint.setTime(time);
|
||||||
|
} else if (trackPoint.getLatitude() == 200) {
|
||||||
|
//TODO Remove by 31st December 2021.
|
||||||
|
trackPoint = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL);
|
||||||
|
trackPoint.setTime(time);
|
||||||
|
|
||||||
|
} else if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||||
|
throw new SAXException(createErrorMessage("Invalid location detected: " + trackPoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate derived attributes from the previous point
|
// Calculate derived attributes from the previous point
|
||||||
if (trackData.lastLocationInCurrentSegment != null && trackData.lastLocationInCurrentSegment.getTime() != 0) {
|
if (trackData.lastLocationInCurrentSegment != null && trackData.lastLocationInCurrentSegment.getTime() != 0) {
|
||||||
if (!trackPoint.hasSpeed()) {
|
if (!trackPoint.hasSpeed()) {
|
||||||
@@ -368,10 +386,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackPoint.hasLocation() && !LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
|
||||||
throw new SAXException(createErrorMessage("Invalid location detected: " + trackPoint));
|
|
||||||
}
|
|
||||||
|
|
||||||
trackData.lastLocationInCurrentSegment = trackPoint;
|
trackData.lastLocationInCurrentSegment = trackPoint;
|
||||||
return trackPoint;
|
return trackPoint;
|
||||||
}
|
}
|
||||||
@@ -525,7 +539,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
|||||||
*
|
*
|
||||||
* @author Jimmy Shih
|
* @author Jimmy Shih
|
||||||
*/
|
*/
|
||||||
// TODO Why private inner class?
|
// TODO Why private inner class?
|
||||||
private static class TrackData {
|
private static class TrackData {
|
||||||
// The current track
|
// The current track
|
||||||
final Track track = new Track();
|
final Track track = new Track();
|
||||||
|
|||||||
Reference in New Issue
Block a user