forked from upstream-mirrors/OpenTracks
@@ -153,24 +153,18 @@ public class CSVTrackExporter implements TrackExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
if (printWriter != null) {
|
printWriter.flush();
|
||||||
printWriter.flush();
|
printWriter = null;
|
||||||
printWriter = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeHeader(List<Column> columns) {
|
public void writeHeader(List<Column> columns) {
|
||||||
if (printWriter != null) {
|
String columnNames = columns.stream().map(c -> c.columnName).reduce((s, s2) -> s + "," + s2).orElseThrow(() -> new RuntimeException("No columns defined"));
|
||||||
String columnNames = columns.stream().map(c -> c.columnName).reduce((s, s2) -> s + "," + s2).orElseThrow(() -> new RuntimeException("No columns defined"));
|
printWriter.println("#" + columnNames);
|
||||||
printWriter.println("#" + columnNames);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeTrackPoint(List<Column> columns, TrackPoint trackPoint) {
|
public void writeTrackPoint(List<Column> columns, TrackPoint trackPoint) {
|
||||||
if (printWriter != null) {
|
String columnNames = columns.stream().map(c -> c.extractor.apply(trackPoint)).reduce((s, s2) -> s + "," + s2).orElseThrow(() -> new RuntimeException("No columns defined"));
|
||||||
String columnNames = columns.stream().map(c -> c.extractor.apply(trackPoint)).reduce((s, s2) -> s + "," + s2).orElseThrow(() -> new RuntimeException("No columns defined"));
|
printWriter.println(columnNames);
|
||||||
printWriter.println(columnNames);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Column {
|
private static class Column {
|
||||||
|
|||||||
@@ -199,42 +199,36 @@ public class GPXTrackExporter implements TrackExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
if (printWriter != null) {
|
printWriter.flush();
|
||||||
printWriter.flush();
|
printWriter = null;
|
||||||
printWriter = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeHeader() {
|
public void writeHeader() {
|
||||||
if (printWriter != null) {
|
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||||
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
printWriter.println("<gpx");
|
||||||
printWriter.println("<gpx");
|
printWriter.println("version=\"1.1\"");
|
||||||
printWriter.println("version=\"1.1\"");
|
printWriter.println("creator=\"" + creator + "\"");
|
||||||
printWriter.println("creator=\"" + creator + "\"");
|
printWriter.println("xmlns=\"http://www.topografix.com/GPX/1/1\"");
|
||||||
printWriter.println("xmlns=\"http://www.topografix.com/GPX/1/1\"");
|
printWriter.println("xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\"");
|
||||||
printWriter.println("xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\"");
|
printWriter.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
|
||||||
printWriter.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
|
printWriter.println("xmlns:opentracks=\"http://opentracksapp.com/xmlschemas/v1\"");
|
||||||
printWriter.println("xmlns:opentracks=\"http://opentracksapp.com/xmlschemas/v1\"");
|
printWriter.println("xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v2\"");
|
||||||
printWriter.println("xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v2\"");
|
printWriter.println("xmlns:gpxtrkx=\"http://www.garmin.com/xmlschemas/TrackStatsExtension/v1\"");
|
||||||
printWriter.println("xmlns:gpxtrkx=\"http://www.garmin.com/xmlschemas/TrackStatsExtension/v1\"");
|
printWriter.println("xmlns:cluetrust=\"http://www.cluetrust.com/Schemas/\"");
|
||||||
printWriter.println("xmlns:cluetrust=\"http://www.cluetrust.com/Schemas/\"");
|
printWriter.println("xmlns:pwr=\"http://www.garmin.com/xmlschemas/PowerExtension/v1\"");
|
||||||
printWriter.println("xmlns:pwr=\"http://www.garmin.com/xmlschemas/PowerExtension/v1\"");
|
printWriter.println("xsi:schemaLocation=" +
|
||||||
printWriter.println("xsi:schemaLocation=" +
|
"\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
|
||||||
"\"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.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://www.garmin.com/xmlschemas/TrackPointExtension/v2 https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd"
|
+ " http://www.garmin.com/xmlschemas/PowerExtension/v1 https://www8.garmin.com/xmlschemas/PowerExtensionv1.xsd"
|
||||||
+ " http://www.garmin.com/xmlschemas/PowerExtension/v1 https://www8.garmin.com/xmlschemas/PowerExtensionv1.xsd"
|
+ " http://www.garmin.com/xmlschemas/TrackStatsExtension/v1"
|
||||||
+ " http://www.garmin.com/xmlschemas/TrackStatsExtension/v1"
|
+ " http://www.cluetrust.com/Schemas http://www.cluetrust.com/Schemas/gpxdata10.xsd"
|
||||||
+ " http://www.cluetrust.com/Schemas http://www.cluetrust.com/Schemas/gpxdata10.xsd"
|
+ " http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd\">");
|
||||||
+ " http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd\">");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeFooter() {
|
public void writeFooter() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</gpx>");
|
||||||
printWriter.println("</gpx>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMarkers(Track track) throws InterruptedException {
|
private void writeMarkers(Track track) throws InterruptedException {
|
||||||
@@ -254,49 +248,43 @@ public class GPXTrackExporter implements TrackExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeMarker(ZoneOffset zoneOffset, Marker marker) {
|
public void writeMarker(ZoneOffset zoneOffset, Marker marker) {
|
||||||
if (printWriter != null) {
|
printWriter.println("<wpt " + formatLocation(marker.getLatitude(), marker.getLongitude()) + ">");
|
||||||
printWriter.println("<wpt " + formatLocation(marker.getLatitude(), marker.getLongitude()) + ">");
|
if (marker.hasAltitude()) {
|
||||||
if (marker.hasAltitude()) {
|
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(marker.getAltitude().toM()) + "</ele>");
|
||||||
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(marker.getAltitude().toM()) + "</ele>");
|
|
||||||
}
|
|
||||||
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("</wpt>");
|
|
||||||
}
|
}
|
||||||
|
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("</wpt>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBeginTrack(Track track) {
|
public void writeBeginTrack(Track track) {
|
||||||
if (printWriter != null) {
|
printWriter.println("<trk>");
|
||||||
printWriter.println("<trk>");
|
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
||||||
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>");
|
||||||
printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>");
|
printWriter.println("<type>" + StringUtils.formatCData(track.getActivityTypeLocalized()) + "</type>");
|
||||||
printWriter.println("<type>" + StringUtils.formatCData(track.getActivityTypeLocalized()) + "</type>");
|
|
||||||
|
|
||||||
printWriter.println("<extensions>");
|
printWriter.println("<extensions>");
|
||||||
printWriter.println("<topografix:color>c0c0c0</topografix:color>");
|
printWriter.println("<topografix:color>c0c0c0</topografix:color>");
|
||||||
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
||||||
|
|
||||||
TrackStatistics trackStatistics = track.getTrackStatistics();
|
TrackStatistics trackStatistics = track.getTrackStatistics();
|
||||||
printWriter.println("<gpxtrkx:TrackStatsExtension>");
|
printWriter.println("<gpxtrkx:TrackStatsExtension>");
|
||||||
printWriter.println("<gpxtrkx:Distance>" + trackStatistics.getTotalDistance().toM() + "</gpxtrkx:Distance>");
|
printWriter.println("<gpxtrkx:Distance>" + trackStatistics.getTotalDistance().toM() + "</gpxtrkx:Distance>");
|
||||||
printWriter.println("<gpxtrkx:TimerTime>" + trackStatistics.getTotalTime().getSeconds() + "</gpxtrkx:TimerTime>");
|
printWriter.println("<gpxtrkx:TimerTime>" + trackStatistics.getTotalTime().getSeconds() + "</gpxtrkx:TimerTime>");
|
||||||
printWriter.println("<gpxtrkx:MovingTime>" + trackStatistics.getMovingTime().getSeconds() + "</gpxtrkx:MovingTime>");
|
printWriter.println("<gpxtrkx:MovingTime>" + trackStatistics.getMovingTime().getSeconds() + "</gpxtrkx:MovingTime>");
|
||||||
printWriter.println("<gpxtrkx:StoppedTime>" + trackStatistics.getStoppedTime().getSeconds() + "</gpxtrkx:StoppedTime>");
|
printWriter.println("<gpxtrkx:StoppedTime>" + trackStatistics.getStoppedTime().getSeconds() + "</gpxtrkx:StoppedTime>");
|
||||||
printWriter.println("<gpxtrkx:MaxSpeed>" + trackStatistics.getMaxSpeed().toMPS() + "</gpxtrkx:MaxSpeed>");
|
printWriter.println("<gpxtrkx:MaxSpeed>" + trackStatistics.getMaxSpeed().toMPS() + "</gpxtrkx:MaxSpeed>");
|
||||||
printWriter.println("<gpxtrkx:Ascent>" + trackStatistics.getTotalAltitudeGain() + "</gpxtrkx:Ascent>");
|
printWriter.println("<gpxtrkx:Ascent>" + trackStatistics.getTotalAltitudeGain() + "</gpxtrkx:Ascent>");
|
||||||
printWriter.println("<gpxtrkx:Descent>" + trackStatistics.getTotalAltitudeLoss() + "</gpxtrkx:Descent>");
|
printWriter.println("<gpxtrkx:Descent>" + trackStatistics.getTotalAltitudeLoss() + "</gpxtrkx:Descent>");
|
||||||
printWriter.println("</gpxtrkx:TrackStatsExtension>");
|
printWriter.println("</gpxtrkx:TrackStatsExtension>");
|
||||||
|
|
||||||
printWriter.println("</extensions>");
|
printWriter.println("</extensions>");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeEndTrack() {
|
public void writeEndTrack() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</trk>");
|
||||||
printWriter.println("</trk>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeOpenSegment() {
|
public void writeOpenSegment() {
|
||||||
@@ -310,67 +298,65 @@ public class GPXTrackExporter implements TrackExporter {
|
|||||||
public Distance writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint, List<TrackPoint> sensorPoints, Distance trackDistance) {
|
public Distance writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint, List<TrackPoint> sensorPoints, Distance trackDistance) {
|
||||||
Distance cumulativeDistance = null;
|
Distance cumulativeDistance = null;
|
||||||
|
|
||||||
if (printWriter != null) {
|
printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">");
|
||||||
|
|
||||||
printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">");
|
if (trackPoint.hasAltitude()) {
|
||||||
|
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude().toM()) + "</ele>");
|
||||||
if (trackPoint.hasAltitude()) {
|
|
||||||
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude().toM()) + "</ele>");
|
|
||||||
}
|
|
||||||
|
|
||||||
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(trackPoint.getTime(), zoneOffset) + "</time>");
|
|
||||||
|
|
||||||
{
|
|
||||||
String trackPointExtensionContent = "";
|
|
||||||
|
|
||||||
if (trackPoint.hasSpeed()) {
|
|
||||||
trackPointExtensionContent += "<gpxtpx:speed>" + SPEED_FORMAT.format(trackPoint.getSpeed().toMPS()) + "</gpxtpx:speed>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackPoint.hasHeartRate()) {
|
|
||||||
trackPointExtensionContent += "<gpxtpx:hr>" + HEARTRATE_FORMAT.format(trackPoint.getHeartRate().getBPM()) + "</gpxtpx:hr>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackPoint.hasCadence()) {
|
|
||||||
trackPointExtensionContent += "<gpxtpx:cad>" + CADENCE_FORMAT.format(trackPoint.getCadence().getRPM()) + "</gpxtpx:cad>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackPoint.hasPower()) {
|
|
||||||
trackPointExtensionContent += "<pwr:PowerInWatts>" + POWER_FORMAT.format(trackPoint.getPower().getW()) + "</pwr:PowerInWatts>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
Double cumulativeGain = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGain() ? (double) tp.getAltitudeGain() : null);
|
|
||||||
if (cumulativeGain != null) {
|
|
||||||
trackPointExtensionContent += ("<opentracks:gain>" + ALTITUDE_FORMAT.format(cumulativeGain) + "</opentracks:gain>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
Double cumulativeLoss = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeLoss() ? (double) tp.getAltitudeLoss() : null);
|
|
||||||
if (cumulativeLoss != null) {
|
|
||||||
trackPointExtensionContent += ("<opentracks:loss>" + ALTITUDE_FORMAT.format(cumulativeLoss) + "</opentracks:loss>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackPoint.hasHorizontalAccuracy()) {
|
|
||||||
trackPointExtensionContent += ("<opentracks:accuracy_horizontal>" + DISTANCE_FORMAT.format(trackPoint.getHorizontalAccuracy().toM()) + "</opentracks:accuracy_horizontal>");
|
|
||||||
}
|
|
||||||
if (trackPoint.hasVerticalAccuracy()) {
|
|
||||||
trackPointExtensionContent += ("<opentracks:accuracy_vertical>" + DISTANCE_FORMAT.format(trackPoint.getVerticalAccuracy().toM()) + "</opentracks:accuracy_vertical>");
|
|
||||||
}
|
|
||||||
|
|
||||||
cumulativeDistance = Distance.ofOrNull(cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasSensorDistance() ? tp.getSensorDistance().toM() : null));
|
|
||||||
if (cumulativeDistance != null) {
|
|
||||||
trackPointExtensionContent += ("<opentracks:distance>" + DISTANCE_FORMAT.format(cumulativeDistance.toM()) + "</opentracks:distance>\n");
|
|
||||||
trackPointExtensionContent += ("<cluetrust:distance>" + DISTANCE_FORMAT.format(trackDistance.plus(cumulativeDistance).toM()) + "</cluetrust:distance>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!trackPointExtensionContent.isEmpty()) {
|
|
||||||
printWriter.println("<extensions><gpxtpx:TrackPointExtension>");
|
|
||||||
printWriter.print(trackPointExtensionContent);
|
|
||||||
printWriter.println("</gpxtpx:TrackPointExtension></extensions>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printWriter.println("</trkpt>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(trackPoint.getTime(), zoneOffset) + "</time>");
|
||||||
|
|
||||||
|
{
|
||||||
|
String trackPointExtensionContent = "";
|
||||||
|
|
||||||
|
if (trackPoint.hasSpeed()) {
|
||||||
|
trackPointExtensionContent += "<gpxtpx:speed>" + SPEED_FORMAT.format(trackPoint.getSpeed().toMPS()) + "</gpxtpx:speed>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackPoint.hasHeartRate()) {
|
||||||
|
trackPointExtensionContent += "<gpxtpx:hr>" + HEARTRATE_FORMAT.format(trackPoint.getHeartRate().getBPM()) + "</gpxtpx:hr>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackPoint.hasCadence()) {
|
||||||
|
trackPointExtensionContent += "<gpxtpx:cad>" + CADENCE_FORMAT.format(trackPoint.getCadence().getRPM()) + "</gpxtpx:cad>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackPoint.hasPower()) {
|
||||||
|
trackPointExtensionContent += "<pwr:PowerInWatts>" + POWER_FORMAT.format(trackPoint.getPower().getW()) + "</pwr:PowerInWatts>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
Double cumulativeGain = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGain() ? (double) tp.getAltitudeGain() : null);
|
||||||
|
if (cumulativeGain != null) {
|
||||||
|
trackPointExtensionContent += ("<opentracks:gain>" + ALTITUDE_FORMAT.format(cumulativeGain) + "</opentracks:gain>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Double cumulativeLoss = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeLoss() ? (double) tp.getAltitudeLoss() : null);
|
||||||
|
if (cumulativeLoss != null) {
|
||||||
|
trackPointExtensionContent += ("<opentracks:loss>" + ALTITUDE_FORMAT.format(cumulativeLoss) + "</opentracks:loss>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackPoint.hasHorizontalAccuracy()) {
|
||||||
|
trackPointExtensionContent += ("<opentracks:accuracy_horizontal>" + DISTANCE_FORMAT.format(trackPoint.getHorizontalAccuracy().toM()) + "</opentracks:accuracy_horizontal>");
|
||||||
|
}
|
||||||
|
if (trackPoint.hasVerticalAccuracy()) {
|
||||||
|
trackPointExtensionContent += ("<opentracks:accuracy_vertical>" + DISTANCE_FORMAT.format(trackPoint.getVerticalAccuracy().toM()) + "</opentracks:accuracy_vertical>");
|
||||||
|
}
|
||||||
|
|
||||||
|
cumulativeDistance = Distance.ofOrNull(cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasSensorDistance() ? tp.getSensorDistance().toM() : null));
|
||||||
|
if (cumulativeDistance != null) {
|
||||||
|
trackPointExtensionContent += ("<opentracks:distance>" + DISTANCE_FORMAT.format(cumulativeDistance.toM()) + "</opentracks:distance>\n");
|
||||||
|
trackPointExtensionContent += ("<cluetrust:distance>" + DISTANCE_FORMAT.format(trackDistance.plus(cumulativeDistance).toM()) + "</cluetrust:distance>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trackPointExtensionContent.isEmpty()) {
|
||||||
|
printWriter.println("<extensions><gpxtpx:TrackPointExtension>");
|
||||||
|
printWriter.print(trackPointExtensionContent);
|
||||||
|
printWriter.println("</gpxtpx:TrackPointExtension></extensions>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printWriter.println("</trkpt>");
|
||||||
|
|
||||||
if (cumulativeDistance != null) {
|
if (cumulativeDistance != null) {
|
||||||
return cumulativeDistance;
|
return cumulativeDistance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,196 +212,170 @@ public class KMLTrackExporter implements TrackExporter {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void close() {
|
void close() {
|
||||||
if (printWriter != null) {
|
printWriter.flush();
|
||||||
printWriter.flush();
|
printWriter = null;
|
||||||
printWriter = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeHeader(List<Track> tracks) {
|
private void writeHeader(List<Track> tracks) {
|
||||||
if (printWriter != null) {
|
printWriter.println(
|
||||||
printWriter.println(
|
"""
|
||||||
"""
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
""");
|
||||||
""");
|
printWriter.println(
|
||||||
printWriter.println(
|
"""
|
||||||
"""
|
<kml xmlns="http://www.opengis.net/kml/2.3"
|
||||||
<kml xmlns="http://www.opengis.net/kml/2.3"
|
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1"
|
||||||
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
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
|
||||||
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">
|
||||||
http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd">
|
"""); //TODO ADD xsi:schemaLocation for atom
|
||||||
"""); //TODO ADD xsi:schemaLocation for atom
|
printWriter.println("<Document>");
|
||||||
printWriter.println("<Document>");
|
printWriter.println("<open>1</open>");
|
||||||
printWriter.println("<open>1</open>");
|
printWriter.println("<visibility>1</visibility>");
|
||||||
printWriter.println("<visibility>1</visibility>");
|
|
||||||
|
|
||||||
Track track = tracks.get(0);
|
Track track = tracks.get(0);
|
||||||
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
||||||
printWriter.println("<atom:generator>" + StringUtils.formatCData(context.getString(R.string.app_name)) + "</atom:generator>");
|
printWriter.println("<atom:generator>" + StringUtils.formatCData(context.getString(R.string.app_name)) + "</atom:generator>");
|
||||||
|
|
||||||
writeTrackStyle();
|
writeTrackStyle();
|
||||||
writePlacemarkerStyle();
|
writePlacemarkerStyle();
|
||||||
printWriter.println("<Schema id=\"" + SCHEMA_ID + "\">");
|
printWriter.println("<Schema id=\"" + SCHEMA_ID + "\">");
|
||||||
|
|
||||||
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_SPEED, context.getString(R.string.description_speed_ms));
|
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_SPEED, context.getString(R.string.description_speed_ms));
|
||||||
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_POWER, context.getString(R.string.description_sensor_power));
|
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_POWER, context.getString(R.string.description_sensor_power));
|
||||||
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_CADENCE, context.getString(R.string.description_sensor_cadence));
|
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_CADENCE, context.getString(R.string.description_sensor_cadence));
|
||||||
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
|
writeSimpleArrayStyle(EXTENDED_DATA_TYPE_HEART_RATE, context.getString(R.string.description_sensor_heart_rate));
|
||||||
|
|
||||||
printWriter.println("</Schema>");
|
printWriter.println("</Schema>");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeFooter() {
|
private void writeFooter() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</Document>");
|
||||||
printWriter.println("</Document>");
|
printWriter.println("</kml>");
|
||||||
printWriter.println("</kml>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBeginMarkers(Track track) {
|
private void writeBeginMarkers(Track track) {
|
||||||
if (printWriter != null) {
|
printWriter.println("<Folder>");
|
||||||
printWriter.println("<Folder>");
|
printWriter.println("<name>" + StringUtils.formatCData(context.getString(R.string.track_markers, track.getName())) + "</name>");
|
||||||
printWriter.println("<name>" + StringUtils.formatCData(context.getString(R.string.track_markers, track.getName())) + "</name>");
|
printWriter.println("<open>1</open>");
|
||||||
printWriter.println("<open>1</open>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMarker(Marker marker, ZoneOffset zoneOffset) {
|
private void writeMarker(Marker marker, ZoneOffset zoneOffset) {
|
||||||
if (printWriter != null) {
|
boolean existsPhoto = MarkerUtils.buildInternalPhotoFile(context, marker.getTrackId(), marker.getPhotoURI()) != null;
|
||||||
boolean existsPhoto = MarkerUtils.buildInternalPhotoFile(context, marker.getTrackId(), marker.getPhotoURI()) != null;
|
if (marker.hasPhoto() && exportPhotos && existsPhoto) {
|
||||||
if (marker.hasPhoto() && exportPhotos && existsPhoto) {
|
float heading = getHeading(marker.getTrackId(), marker.getLocation());
|
||||||
float heading = getHeading(marker.getTrackId(), marker.getLocation());
|
writePhotoOverlay(marker, heading, zoneOffset);
|
||||||
writePhotoOverlay(marker, heading, zoneOffset);
|
} else {
|
||||||
} else {
|
writePlacemark(marker.getName(), marker.getCategory(), marker.getDescription(), marker.getLocation(), zoneOffset);
|
||||||
writePlacemark(marker.getName(), marker.getCategory(), marker.getDescription(), marker.getLocation(), zoneOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeEndMarkers() {
|
private void writeEndMarkers() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</Folder>");
|
||||||
printWriter.println("</Folder>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMultiTrackBegin() {
|
private void writeMultiTrackBegin() {
|
||||||
if (printWriter != null) {
|
printWriter.println("<Folder id=\"tracks\">");
|
||||||
printWriter.println("<Folder id=\"tracks\">");
|
printWriter.println("<name>" + context.getString(R.string.generic_tracks) + "</name>");
|
||||||
printWriter.println("<name>" + context.getString(R.string.generic_tracks) + "</name>");
|
printWriter.println("<open>1</open>");
|
||||||
printWriter.println("<open>1</open>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMultiTrackEnd() {
|
private void writeMultiTrackEnd() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</Folder>");
|
||||||
printWriter.println("</Folder>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBeginTrack(Track track) {
|
private void writeBeginTrack(Track track) {
|
||||||
if (printWriter != null) {
|
printWriter.println("<Placemark>");
|
||||||
printWriter.println("<Placemark>");
|
|
||||||
|
|
||||||
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
|
||||||
printWriter.println("<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
|
printWriter.println("<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
|
||||||
printWriter.println("<icon>" + StringUtils.formatCData(track.getActivityType().getIconId()) + "</icon>");
|
printWriter.println("<icon>" + StringUtils.formatCData(track.getActivityType().getIconId()) + "</icon>");
|
||||||
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
printWriter.println("<opentracks:trackid>" + track.getUuid() + "</opentracks:trackid>");
|
||||||
|
|
||||||
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
|
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
|
||||||
writeActivityType(track.getActivityTypeLocalized());
|
writeActivityType(track.getActivityTypeLocalized());
|
||||||
printWriter.println("<MultiTrack>");
|
printWriter.println("<MultiTrack>");
|
||||||
printWriter.println("<altitudeMode>absolute</altitudeMode>");
|
printWriter.println("<altitudeMode>absolute</altitudeMode>");
|
||||||
printWriter.println("<interpolate>1</interpolate>");
|
printWriter.println("<interpolate>1</interpolate>");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeEndTrack() {
|
private void writeEndTrack() {
|
||||||
if (printWriter != null) {
|
printWriter.println("</MultiTrack>");
|
||||||
printWriter.println("</MultiTrack>");
|
printWriter.println("</Placemark>");
|
||||||
printWriter.println("</Placemark>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void writeOpenSegment() {
|
void writeOpenSegment() {
|
||||||
if (printWriter != null) {
|
printWriter.println("<Track>");
|
||||||
printWriter.println("<Track>");
|
speedList.clear();
|
||||||
speedList.clear();
|
distanceList.clear();
|
||||||
distanceList.clear();
|
powerList.clear();
|
||||||
powerList.clear();
|
cadenceList.clear();
|
||||||
cadenceList.clear();
|
heartRateList.clear();
|
||||||
heartRateList.clear();
|
altitudeGainList.clear();
|
||||||
altitudeGainList.clear();
|
altitudeLossList.clear();
|
||||||
altitudeLossList.clear();
|
accuracyHorizontal.clear();
|
||||||
accuracyHorizontal.clear();
|
accuracyVertical.clear();
|
||||||
accuracyVertical.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void writeCloseSegment() {
|
void writeCloseSegment() {
|
||||||
if (printWriter != null) {
|
printWriter.println("<ExtendedData>");
|
||||||
printWriter.println("<ExtendedData>");
|
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
|
||||||
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
|
if (speedList.stream().anyMatch(Objects::nonNull)) {
|
||||||
if (speedList.stream().anyMatch(Objects::nonNull)) {
|
writeSimpleArrayData(speedList, EXTENDED_DATA_TYPE_SPEED);
|
||||||
writeSimpleArrayData(speedList, EXTENDED_DATA_TYPE_SPEED);
|
|
||||||
}
|
|
||||||
if (distanceList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(distanceList, EXTENDED_DATA_TYPE_DISTANCE);
|
|
||||||
}
|
|
||||||
if (powerList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(powerList, EXTENDED_DATA_TYPE_POWER);
|
|
||||||
}
|
|
||||||
if (cadenceList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(cadenceList, EXTENDED_DATA_TYPE_CADENCE);
|
|
||||||
}
|
|
||||||
if (heartRateList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(heartRateList, EXTENDED_DATA_TYPE_HEART_RATE);
|
|
||||||
}
|
|
||||||
if (altitudeGainList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(altitudeGainList, EXTENDED_DATA_TYPE_ALTITUDE_GAIN);
|
|
||||||
}
|
|
||||||
if (altitudeLossList.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(altitudeLossList, EXTENDED_DATA_TYPE_ALTITUDE_LOSS);
|
|
||||||
}
|
|
||||||
if (accuracyHorizontal.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(accuracyHorizontal, EXTENDED_DATA_TYPE_ACCURACY_HORIZONTAL);
|
|
||||||
}
|
|
||||||
if (accuracyVertical.stream().anyMatch(Objects::nonNull)) {
|
|
||||||
writeSimpleArrayData(accuracyVertical, EXTENDED_DATA_TYPE_ACCURACY_VERTICAL);
|
|
||||||
}
|
|
||||||
printWriter.println("</SchemaData>");
|
|
||||||
printWriter.println("</ExtendedData>");
|
|
||||||
printWriter.println("</Track>");
|
|
||||||
}
|
}
|
||||||
|
if (distanceList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(distanceList, EXTENDED_DATA_TYPE_DISTANCE);
|
||||||
|
}
|
||||||
|
if (powerList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(powerList, EXTENDED_DATA_TYPE_POWER);
|
||||||
|
}
|
||||||
|
if (cadenceList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(cadenceList, EXTENDED_DATA_TYPE_CADENCE);
|
||||||
|
}
|
||||||
|
if (heartRateList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(heartRateList, EXTENDED_DATA_TYPE_HEART_RATE);
|
||||||
|
}
|
||||||
|
if (altitudeGainList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(altitudeGainList, EXTENDED_DATA_TYPE_ALTITUDE_GAIN);
|
||||||
|
}
|
||||||
|
if (altitudeLossList.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(altitudeLossList, EXTENDED_DATA_TYPE_ALTITUDE_LOSS);
|
||||||
|
}
|
||||||
|
if (accuracyHorizontal.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(accuracyHorizontal, EXTENDED_DATA_TYPE_ACCURACY_HORIZONTAL);
|
||||||
|
}
|
||||||
|
if (accuracyVertical.stream().anyMatch(Objects::nonNull)) {
|
||||||
|
writeSimpleArrayData(accuracyVertical, EXTENDED_DATA_TYPE_ACCURACY_VERTICAL);
|
||||||
|
}
|
||||||
|
printWriter.println("</SchemaData>");
|
||||||
|
printWriter.println("</ExtendedData>");
|
||||||
|
printWriter.println("</Track>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint) {
|
void writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint) {
|
||||||
if (printWriter != null) {
|
printWriter.println("<when>" + getTime(zoneOffset, trackPoint.getLocation()) + "</when>");
|
||||||
printWriter.println("<when>" + getTime(zoneOffset, trackPoint.getLocation()) + "</when>");
|
|
||||||
|
|
||||||
if (trackPoint.hasLocation()) {
|
if (trackPoint.hasLocation()) {
|
||||||
printWriter.println("<coord>" + getCoordinates(trackPoint.getLocation(), " ") + "</coord>");
|
printWriter.println("<coord>" + getCoordinates(trackPoint.getLocation(), " ") + "</coord>");
|
||||||
} else {
|
} else {
|
||||||
printWriter.println("<coord/>");
|
printWriter.println("<coord/>");
|
||||||
}
|
|
||||||
speedList.add(trackPoint.hasSpeed() ? (float) trackPoint.getSpeed().toMPS() : null);
|
|
||||||
|
|
||||||
distanceList.add(trackPoint.hasSensorDistance() ? (float) trackPoint.getSensorDistance().toM() : null);
|
|
||||||
heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate().getBPM() : null);
|
|
||||||
cadenceList.add(trackPoint.hasCadence() ? trackPoint.getCadence().getRPM() : null);
|
|
||||||
powerList.add(trackPoint.hasPower() ? trackPoint.getPower().getW() : null);
|
|
||||||
|
|
||||||
altitudeGainList.add(trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : null);
|
|
||||||
altitudeLossList.add(trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : null);
|
|
||||||
accuracyHorizontal.add(trackPoint.hasHorizontalAccuracy() ? (float) trackPoint.getHorizontalAccuracy().toM() : null);
|
|
||||||
accuracyVertical.add(trackPoint.hasVerticalAccuracy() ? (float) trackPoint.getVerticalAccuracy().toM() : null);
|
|
||||||
}
|
}
|
||||||
|
speedList.add(trackPoint.hasSpeed() ? (float) trackPoint.getSpeed().toMPS() : null);
|
||||||
|
|
||||||
|
distanceList.add(trackPoint.hasSensorDistance() ? (float) trackPoint.getSensorDistance().toM() : null);
|
||||||
|
heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate().getBPM() : null);
|
||||||
|
cadenceList.add(trackPoint.hasCadence() ? trackPoint.getCadence().getRPM() : null);
|
||||||
|
powerList.add(trackPoint.hasPower() ? trackPoint.getPower().getW() : null);
|
||||||
|
|
||||||
|
altitudeGainList.add(trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : null);
|
||||||
|
altitudeLossList.add(trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : null);
|
||||||
|
accuracyHorizontal.add(trackPoint.hasHorizontalAccuracy() ? (float) trackPoint.getHorizontalAccuracy().toM() : null);
|
||||||
|
accuracyVertical.add(trackPoint.hasVerticalAccuracy() ? (float) trackPoint.getVerticalAccuracy().toM() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user