mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-09-30 16:52:21 +02:00
+131
@@ -0,0 +1,131 @@
|
||||
package de.dennisguse.opentracks.io.file.exporter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.rule.GrantPermissionRule;
|
||||
import androidx.test.rule.ServiceTestRule;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import de.dennisguse.opentracks.TestUtil;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Speed;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.io.file.importer.ExportImportTest;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class KMLTrackExporterTest {
|
||||
|
||||
@Rule
|
||||
public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS);
|
||||
|
||||
@Rule
|
||||
public GrantPermissionRule mGrantPermissionRule = TestUtil.createGrantPermissionRule();
|
||||
|
||||
private static final Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@BeforeClass
|
||||
public static void preSetUp() {
|
||||
// Prepare looper for Android's message queue
|
||||
if (Looper.myLooper() == null) Looper.prepare();
|
||||
|
||||
PreferencesUtils.resetPreferences(context, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoTrack_with_oneMarker() throws TimeoutException, IOException {
|
||||
// given
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
|
||||
TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class)))
|
||||
.getService();
|
||||
|
||||
TrackPointCreator trackPointCreator = service.getTrackPointCreator();
|
||||
|
||||
final Track.Id trackIdOne;
|
||||
{ // first track
|
||||
trackPointCreator.setClock("2020-02-02T02:02:02Z");
|
||||
trackIdOne = service.startNewTrack();
|
||||
|
||||
Position position = ExportImportTest.sendLocation(trackPointCreator, "2020-02-02T02:02:03Z", 3.1234567, 14.0014567, 10, 13, 15, 1020.25, 1f);
|
||||
contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackIdOne,
|
||||
"Marker 1",
|
||||
"Marker 1 desc",
|
||||
"Marker 1 typeLocalized",
|
||||
position,
|
||||
null
|
||||
));
|
||||
service.endCurrentTrack();
|
||||
}
|
||||
|
||||
final Track.Id trackIdTwo;
|
||||
{ // second track
|
||||
trackPointCreator.setClock("2022-02-02T02:02:02Z");
|
||||
trackIdTwo = service.startNewTrack();
|
||||
|
||||
Position position = ExportImportTest.sendLocation(trackPointCreator, "2022-02-02T02:02:03Z", 3.1234567, 14.0014567, 10, 13, 15, 1020.25, 1f);
|
||||
contentProviderUtils.insertMarker(
|
||||
new Marker(
|
||||
null,
|
||||
trackIdTwo,
|
||||
"Marker 2",
|
||||
"Marker 2 desc",
|
||||
"Marker 2 typeLocalized",
|
||||
position,
|
||||
null
|
||||
));
|
||||
service.endCurrentTrack();
|
||||
}
|
||||
|
||||
// when
|
||||
TrackExporter exporter = TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.createTrackExporter(context, new ContentProviderUtils(context));
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
exporter.writeTrack(
|
||||
List.of(contentProviderUtils.getTrack(trackIdOne), contentProviderUtils.getTrack(trackIdTwo)),
|
||||
outputStream
|
||||
);
|
||||
|
||||
// then
|
||||
try (InputStream inputStreamExpected = InstrumentationRegistry.getInstrumentation().getContext().getResources().openRawResource(de.dennisguse.opentracks.test.R.raw.kml23_twotracks)) {
|
||||
String expectation = new String(inputStreamExpected.readAllBytes(), StandardCharsets.UTF_8);
|
||||
String expectationAdjusted = expectation
|
||||
.replace("ece162fb-d614-4431-9d33-eb20f8ee8e1d", contentProviderUtils.getTrack(trackIdOne).uuid().toString())
|
||||
.replace("6712f4ca-3456-4739-841a-9e62760cc447", contentProviderUtils.getTrack(trackIdTwo).uuid().toString());
|
||||
assertEquals(expectationAdjusted, outputStream.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -127,6 +127,7 @@ public class ExportImportTest {
|
||||
|
||||
@Before
|
||||
public void fileSetup() throws IOException, TimeoutException {
|
||||
//TODO Replace with a ByteArrayOutputStream instead of storing a file?
|
||||
tmpFile = File.createTempFile("test", "test", context.getFilesDir());
|
||||
tmpFileUri = Uri.fromFile(tmpFile);
|
||||
|
||||
@@ -769,7 +770,8 @@ public class ExportImportTest {
|
||||
sensorManager.getAltitudeChangeHandler().setAggregator(aggregatorBarometer);
|
||||
}
|
||||
|
||||
public static void sendLocation(TrackPointCreator trackPointCreator, String time, double latitude, double longitude, float accuracy, float verticalAccuracy, float speed, double altitude, Float altitudeGain) {
|
||||
//TODO Use return value (for markers)
|
||||
public static Position sendLocation(TrackPointCreator trackPointCreator, String time, double latitude, double longitude, float accuracy, float verticalAccuracy, float speed, double altitude, Float altitudeGain) {
|
||||
Location location = new Location("mock");
|
||||
location.setLatitude(latitude);
|
||||
location.setLongitude(longitude);
|
||||
@@ -782,5 +784,7 @@ public class ExportImportTest {
|
||||
|
||||
trackPointCreator.setClock(time);
|
||||
trackPointCreator.getSensorManager().getGpsHandler().onDataReceived(location);
|
||||
|
||||
return Position.of(location, Instant.parse(time));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<kml xmlns="http://www.opengis.net/kml/2.3"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.opengis.net/kml/2.3 http://schemas.opengis.net/kml/2.3/ogckml23.xsd
|
||||
http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd">
|
||||
|
||||
<Document>
|
||||
<open>1</open>
|
||||
<visibility>1</visibility>
|
||||
<name><![CDATA[2020-02-02T03:02+01]]></name>
|
||||
<atom:generator><![CDATA[OpenTracks]]></atom:generator>
|
||||
<Style id="track">
|
||||
<LineStyle><color>7f0000ff</color><width>4</width></LineStyle>
|
||||
<IconStyle>
|
||||
<scale>1.3</scale>
|
||||
<Icon />
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<Style id="waypoint"><IconStyle>
|
||||
<Icon />
|
||||
</IconStyle></Style>
|
||||
<Schema id="schema">
|
||||
<SimpleArrayField name="speed" type="float">
|
||||
<displayName><![CDATA[Speed (m/s)]]></displayName>
|
||||
</SimpleArrayField>
|
||||
<SimpleArrayField name="power" type="float">
|
||||
<displayName><![CDATA[Power (W)]]></displayName>
|
||||
</SimpleArrayField>
|
||||
<SimpleArrayField name="cadence" type="float">
|
||||
<displayName><![CDATA[Cadence (rpm)]]></displayName>
|
||||
</SimpleArrayField>
|
||||
<SimpleArrayField name="heartrate" type="float">
|
||||
<displayName><![CDATA[Heart rate (bpm)]]></displayName>
|
||||
</SimpleArrayField>
|
||||
<SimpleArrayField name="temperature" type="float">
|
||||
<displayName><![CDATA[Temperature (Celsius)]]></displayName>
|
||||
</SimpleArrayField>
|
||||
</Schema>
|
||||
<Folder>
|
||||
<name><![CDATA[2020-02-02T03:02+01 Markers]]></name>
|
||||
<open>1</open>
|
||||
<Placemark>
|
||||
<name><![CDATA[Marker 1]]></name>
|
||||
<description><![CDATA[Marker 1 desc]]></description>
|
||||
<TimeStamp><when>2020-02-02T03:02:03+01:00</when></TimeStamp>
|
||||
<styleUrl>#waypoint</styleUrl>
|
||||
<ExtendedData>
|
||||
<Data name="type"><value><![CDATA[Marker 1 typeLocalized]]></value></Data>
|
||||
</ExtendedData>
|
||||
<Point>
|
||||
<coordinates>14.001456,3.123456,1020.25</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name><![CDATA[2022-02-02T03:02+01 Markers]]></name>
|
||||
<open>1</open>
|
||||
<Placemark>
|
||||
<name><![CDATA[Marker 2]]></name>
|
||||
<description><![CDATA[Marker 2 desc]]></description>
|
||||
<TimeStamp><when>2022-02-02T03:02:03+01:00</when></TimeStamp>
|
||||
<styleUrl>#waypoint</styleUrl>
|
||||
<ExtendedData>
|
||||
<Data name="type"><value><![CDATA[Marker 2 typeLocalized]]></value></Data>
|
||||
</ExtendedData>
|
||||
<Point>
|
||||
<coordinates>14.001456,3.123456,1020.25</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder id="tracks">
|
||||
<name>Tracks</name>
|
||||
<open>1</open>
|
||||
<Placemark>
|
||||
<name><![CDATA[2020-02-02T03:02+01]]></name>
|
||||
<description><![CDATA[]]></description>
|
||||
<opentracks:trackid>ece162fb-d614-4431-9d33-eb20f8ee8e1d</opentracks:trackid>
|
||||
<styleUrl>#track</styleUrl>
|
||||
<ExtendedData>
|
||||
<Data name="activityType"><value><![CDATA[unknown]]></value></Data>
|
||||
</ExtendedData>
|
||||
<ExtendedData>
|
||||
<Data name="type"><value><![CDATA[unknown]]></value></Data>
|
||||
</ExtendedData>
|
||||
<MultiTrack>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<interpolate>1</interpolate>
|
||||
<Track>
|
||||
<when>2020-02-02T03:02:02+01:00</when>
|
||||
<coord/>
|
||||
<when>2020-02-02T03:02:03+01:00</when>
|
||||
<coord>14.001456 3.123456 1020.25</coord>
|
||||
<when>2020-02-02T03:02:03+01:00</when>
|
||||
<coord/>
|
||||
<ExtendedData>
|
||||
<SchemaData schemaUrl="#schema">
|
||||
<SimpleArrayData name="trackpoint_type">
|
||||
<value>SEGMENT_START_MANUAL</value>
|
||||
<value>TRACKPOINT</value>
|
||||
<value>SEGMENT_END_MANUAL</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="speed">
|
||||
<value />
|
||||
<value>15</value>
|
||||
<value />
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="elevation_gain">
|
||||
<value />
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="elevation_loss">
|
||||
<value />
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="accuracy_horizontal">
|
||||
<value />
|
||||
<value>10</value>
|
||||
<value />
|
||||
</SimpleArrayData>
|
||||
</SchemaData>
|
||||
</ExtendedData>
|
||||
</Track>
|
||||
</MultiTrack>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name><![CDATA[2022-02-02T03:02+01]]></name>
|
||||
<description><![CDATA[]]></description>
|
||||
<opentracks:trackid>6712f4ca-3456-4739-841a-9e62760cc447</opentracks:trackid>
|
||||
<styleUrl>#track</styleUrl>
|
||||
<ExtendedData>
|
||||
<Data name="activityType"><value><![CDATA[unknown]]></value></Data>
|
||||
</ExtendedData>
|
||||
<ExtendedData>
|
||||
<Data name="type"><value><![CDATA[unknown]]></value></Data>
|
||||
</ExtendedData>
|
||||
<MultiTrack>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<interpolate>1</interpolate>
|
||||
<Track>
|
||||
<when>2022-02-02T03:02:02+01:00</when>
|
||||
<coord/>
|
||||
<when>2022-02-02T03:02:03+01:00</when>
|
||||
<coord>14.001456 3.123456 1020.25</coord>
|
||||
<when>2022-02-02T03:02:03+01:00</when>
|
||||
<coord/>
|
||||
<ExtendedData>
|
||||
<SchemaData schemaUrl="#schema">
|
||||
<SimpleArrayData name="trackpoint_type">
|
||||
<value>SEGMENT_START_MANUAL</value>
|
||||
<value>TRACKPOINT</value>
|
||||
<value>SEGMENT_END_MANUAL</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="speed">
|
||||
<value />
|
||||
<value>15</value>
|
||||
<value />
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="elevation_gain">
|
||||
<value />
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="elevation_loss">
|
||||
<value />
|
||||
<value>1</value>
|
||||
<value>1</value>
|
||||
</SimpleArrayData>
|
||||
<SimpleArrayData name="accuracy_horizontal">
|
||||
<value />
|
||||
<value>10</value>
|
||||
<value />
|
||||
</SimpleArrayData>
|
||||
</SchemaData>
|
||||
</ExtendedData>
|
||||
</Track>
|
||||
</MultiTrack>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
</Document>
|
||||
</kml>
|
||||
Reference in New Issue
Block a user