Introduced value object for Altitude.

This commit is contained in:
Dennis Guse
2021-05-02 18:54:32 +02:00
parent f83a1b3a4c
commit 50127e311a
11 changed files with 89 additions and 40 deletions
@@ -32,6 +32,7 @@ import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker; import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
@@ -416,7 +417,7 @@ public class ExportImportTest {
} }
assertEquals(trackPoint.hasAltitude(), importedTrackPoint.hasAltitude()); assertEquals(trackPoint.hasAltitude(), importedTrackPoint.hasAltitude());
if (trackPoint.hasAltitude()) { if (trackPoint.hasAltitude()) {
assertEquals(trackPoint.getAltitude(), importedTrackPoint.getAltitude(), 0.001); assertEquals(trackPoint.getAltitude().toM(), importedTrackPoint.getAltitude().toM(), 0.001);
} }
if (type.equals(TrackPoint.Type.SEGMENT_START_MANUAL) || type.equals(TrackPoint.Type.SEGMENT_END_MANUAL)) { if (type.equals(TrackPoint.Type.SEGMENT_START_MANUAL) || type.equals(TrackPoint.Type.SEGMENT_END_MANUAL)) {
@@ -486,7 +487,7 @@ public class ExportImportTest {
} }
private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) { private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) {
TrackPoint tp = new TrackPoint(latitude, longitude, (double) altitude, Instant.ofEpochMilli(time)); TrackPoint tp = new TrackPoint(latitude, longitude, Altitude.WGS84.of(altitude), Instant.ofEpochMilli(time));
tp.setAccuracy(accuracy); tp.setAccuracy(accuracy);
tp.setSpeed(Speed.of(speed)); tp.setSpeed(Speed.of(speed));
tp.setHeartRate_bpm(heartRate); tp.setHeartRate_bpm(heartRate);
@@ -152,7 +152,7 @@ public class LegacyImportTest {
if (altitude == null) { if (altitude == null) {
assertFalse(trackPoint.hasAltitude()); assertFalse(trackPoint.hasAltitude());
} else { } else {
assertEquals(altitude, (Double) trackPoint.getAltitude()); assertEquals(altitude, (Double) trackPoint.getAltitude().toM());
} }
} }
@@ -9,6 +9,7 @@ import org.junit.runner.RunWith;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestDataUtil;
@@ -53,8 +54,8 @@ public class TrackStatisticsUpdaterTest {
TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
// when // when
subject.addTrackPoint(tp1, GPS_DISTANCE); subject.addTrackPoint(tp1, GPS_DISTANCE);
@@ -71,8 +72,8 @@ public class TrackStatisticsUpdaterTest {
TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
tp3.setSpeed(Speed.of(5f)); tp3.setSpeed(Speed.of(5f));
// when // when
@@ -90,11 +91,11 @@ public class TrackStatisticsUpdaterTest {
TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
tp2.setSpeed(Speed.of(5f)); tp2.setSpeed(Speed.of(5f));
TrackPoint tp3 = new TrackPoint(0.001, 0, 5.0, Instant.ofEpochMilli(3000)); TrackPoint tp3 = new TrackPoint(0.001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
tp2.setSpeed(Speed.of(5f)); tp2.setSpeed(Speed.of(5f));
TrackPoint tp4 = new TrackPoint(0.001, 0, 5.0, Instant.ofEpochMilli(4000)); TrackPoint tp4 = new TrackPoint(0.001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
tp2.setSpeed(Speed.of(5f)); tp2.setSpeed(Speed.of(5f));
tp4.setSensorDistance(Distance.of(5f)); tp4.setSensorDistance(Distance.of(5f));
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000)); TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
@@ -122,9 +123,9 @@ public class TrackStatisticsUpdaterTest {
TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackStatisticsUpdater subject = new TrackStatisticsUpdater();
TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000));
TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000));
TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000));
TrackPoint tp4 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(4000)); TrackPoint tp4 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000));
tp4.setSensorDistance(Distance.of(5f)); tp4.setSensorDistance(Distance.of(5f));
TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000)); TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000));
tp5.setSensorDistance(Distance.of(10f)); tp5.setSensorDistance(Distance.of(10f));
@@ -0,0 +1,39 @@
package de.dennisguse.opentracks.content.data;
public abstract class Altitude {
private final double altitude_m;
private Altitude(double altitude_m) {
this.altitude_m = altitude_m;
}
public double toM() {
return altitude_m;
}
public static class WGS84 extends Altitude {
private WGS84(double altitude_m) {
super(altitude_m);
}
public static Altitude of(double altitude_m) {
return new WGS84(altitude_m);
}
}
public static class EGM2008 extends Altitude {
private EGM2008(double altitude_m) {
super(altitude_m);
}
public static Altitude of(double altitude_m) {
return new EGM2008(altitude_m);
}
}
}
@@ -50,7 +50,7 @@ public final class Marker {
private Double latitude; private Double latitude;
private Double longitude; private Double longitude;
private Float accuracy; private Float accuracy;
private Double altitude_m; private Altitude altitude;
private Float bearing; private Float bearing;
//TODO It is the distance from the track starting point; rename to something more meaningful //TODO It is the distance from the track starting point; rename to something more meaningful
@@ -77,7 +77,7 @@ public final class Marker {
this.latitude = trackPoint.getLatitude(); this.latitude = trackPoint.getLatitude();
this.longitude = trackPoint.getLongitude(); this.longitude = trackPoint.getLongitude();
if (trackPoint.hasAccuracy()) this.accuracy = trackPoint.getAccuracy(); if (trackPoint.hasAccuracy()) this.accuracy = trackPoint.getAccuracy();
if (trackPoint.hasAltitude()) this.altitude_m = trackPoint.getAltitude(); if (trackPoint.hasAltitude()) this.altitude = trackPoint.getAltitude();
if (trackPoint.hasBearing()) this.bearing = trackPoint.getBearing(); if (trackPoint.hasBearing()) this.bearing = trackPoint.getBearing();
this.length = Distance.of(0); //TODO Not cool! this.length = Distance.of(0); //TODO Not cool!
@@ -167,7 +167,7 @@ public final class Marker {
location.setAccuracy(accuracy); location.setAccuracy(accuracy);
} }
if (hasAltitude()) { if (hasAltitude()) {
location.setAltitude(altitude_m); location.setAltitude(altitude.toM());
} }
return location; return location;
@@ -202,15 +202,15 @@ public final class Marker {
} }
public boolean hasAltitude() { public boolean hasAltitude() {
return altitude_m != null; return altitude != null;
} }
public Double getAltitude() { public Altitude getAltitude() {
return altitude_m; return altitude;
} }
public void setAltitude(double altitude_m) { public void setAltitude(Altitude altitude) {
this.altitude_m = altitude_m; this.altitude = altitude;
} }
public boolean hasBearing() { public boolean hasBearing() {
@@ -20,6 +20,7 @@ import android.os.Parcel;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
@@ -51,7 +52,7 @@ public class TrackPoint {
private Double latitude; private Double latitude;
private Double longitude; private Double longitude;
private Float accuracy; private Float accuracy;
private Double altitude_m; private Altitude altitude;
private Speed speed; private Speed speed;
private Float bearing; private Float bearing;
private Distance sensorDistance_m; private Distance sensorDistance_m;
@@ -102,7 +103,7 @@ public class TrackPoint {
this.latitude = location.getLatitude(); this.latitude = location.getLatitude();
this.longitude = location.getLongitude(); this.longitude = location.getLongitude();
this.altitude_m = location.getAltitude(); this.altitude = Altitude.WGS84.of(location.getAltitude());
this.speed = Speed.of(location.getSpeed()); this.speed = Speed.of(location.getSpeed());
this.accuracy = location.getAccuracy(); this.accuracy = location.getAccuracy();
@@ -114,11 +115,11 @@ public class TrackPoint {
this.time = time; this.time = time;
} }
public TrackPoint(double latitude, double longitude, Double altitude, Instant time) { public TrackPoint(double latitude, double longitude, Altitude altitude, Instant time) {
this(Type.TRACKPOINT); this(Type.TRACKPOINT);
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
this.altitude_m = altitude; this.altitude = altitude;
this.time = time; this.time = time;
} }
@@ -212,7 +213,7 @@ public class TrackPoint {
location.setAccuracy(accuracy); location.setAccuracy(accuracy);
} }
if (hasAltitude()) { if (hasAltitude()) {
location.setAltitude(altitude_m); location.setAltitude(altitude.toM());
} }
return location; return location;
@@ -257,15 +258,20 @@ public class TrackPoint {
public boolean hasAltitude() { public boolean hasAltitude() {
return altitude_m != null; return altitude != null;
} }
public double getAltitude() { public Altitude getAltitude() {
return altitude_m; return altitude;
} }
public void setAltitude(double altitude) { @VisibleForTesting
this.altitude_m = altitude; public void setAltitude(double altitude_m) {
this.altitude = Altitude.WGS84.of(altitude_m);
}
public void setAltitude(Altitude altitude) {
this.altitude = altitude;
} }
public boolean hasSpeed() { public boolean hasSpeed() {
@@ -39,6 +39,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import de.dennisguse.opentracks.BuildConfig; import de.dennisguse.opentracks.BuildConfig;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker; import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.MarkerColumns; import de.dennisguse.opentracks.content.data.MarkerColumns;
@@ -320,7 +321,7 @@ public class ContentProviderUtils {
marker.setLatitude(((double) cursor.getInt(latitudeIndex)) / 1E6); marker.setLatitude(((double) cursor.getInt(latitudeIndex)) / 1E6);
} }
if (!cursor.isNull(altitudeIndex)) { if (!cursor.isNull(altitudeIndex)) {
marker.setAltitude(cursor.getFloat(altitudeIndex)); marker.setAltitude(Altitude.WGS84.of(cursor.getFloat(altitudeIndex)));
} }
if (!cursor.isNull(accuracyIndex)) { if (!cursor.isNull(accuracyIndex)) {
marker.setAccuracy(cursor.getFloat(accuracyIndex)); marker.setAccuracy(cursor.getFloat(accuracyIndex));
@@ -489,7 +490,7 @@ public class ContentProviderUtils {
values.put(MarkerColumns.LATITUDE, (int) (marker.getLatitude() * 1E6)); values.put(MarkerColumns.LATITUDE, (int) (marker.getLatitude() * 1E6));
values.put(MarkerColumns.TIME, marker.getTime().toEpochMilli()); values.put(MarkerColumns.TIME, marker.getTime().toEpochMilli());
if (marker.hasAltitude()) { if (marker.hasAltitude()) {
values.put(MarkerColumns.ALTITUDE, marker.getAltitude()); values.put(MarkerColumns.ALTITUDE, marker.getAltitude().toM());
} }
if (marker.hasAccuracy()) { if (marker.hasAccuracy()) {
values.put(MarkerColumns.ACCURACY, marker.getAccuracy()); values.put(MarkerColumns.ACCURACY, marker.getAccuracy());
@@ -539,7 +540,7 @@ public class ContentProviderUtils {
trackPoint.setTime(Instant.ofEpochMilli(cursor.getLong(indexes.timeIndex))); trackPoint.setTime(Instant.ofEpochMilli(cursor.getLong(indexes.timeIndex)));
} }
if (!cursor.isNull(indexes.altitudeIndex)) { if (!cursor.isNull(indexes.altitudeIndex)) {
trackPoint.setAltitude(cursor.getFloat(indexes.altitudeIndex)); trackPoint.setAltitude(Altitude.WGS84.of(cursor.getFloat(indexes.altitudeIndex)));
} }
if (!cursor.isNull(indexes.accuracyIndex)) { if (!cursor.isNull(indexes.accuracyIndex)) {
trackPoint.setAccuracy(cursor.getFloat(indexes.accuracyIndex)); trackPoint.setAccuracy(cursor.getFloat(indexes.accuracyIndex));
@@ -690,7 +691,7 @@ public class ContentProviderUtils {
} }
values.put(TrackPointsColumns.TIME, trackPoint.getTime().toEpochMilli()); values.put(TrackPointsColumns.TIME, trackPoint.getTime().toEpochMilli());
if (trackPoint.hasAltitude()) { if (trackPoint.hasAltitude()) {
values.put(TrackPointsColumns.ALTITUDE, trackPoint.getAltitude()); values.put(TrackPointsColumns.ALTITUDE, trackPoint.getAltitude().toM());
} }
if (trackPoint.hasAccuracy()) { if (trackPoint.hasAccuracy()) {
values.put(TrackPointsColumns.ACCURACY, trackPoint.getAccuracy()); values.put(TrackPointsColumns.ACCURACY, trackPoint.getAccuracy());
@@ -444,7 +444,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
if (preferenceShowAltitude) { if (preferenceShowAltitude) {
// Current altitude // Current altitude
Float altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? (float) lastTrackPoint.getAltitude() : null; Float altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? (float) lastTrackPoint.getAltitude().toM() : null;
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits); Pair<String, String> parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits);
viewBinding.statsAltitudeCurrentValue.setText(parts.first); viewBinding.statsAltitudeCurrentValue.setText(parts.first);
viewBinding.statsAltitudeCurrentUnit.setText(parts.second); viewBinding.statsAltitudeCurrentUnit.setText(parts.second);
@@ -237,7 +237,7 @@ public class GPXTrackExporter implements TrackExporter {
if (printWriter != null) { 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()) + "</ele>"); printWriter.println("<ele>" + ALTITUDE_FORMAT.format(marker.getAltitude().toM()) + "</ele>");
} }
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(marker.getTime()) + "</time>"); printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(marker.getTime()) + "</time>");
printWriter.println("<name>" + StringUtils.formatCData(marker.getName()) + "</name>"); printWriter.println("<name>" + StringUtils.formatCData(marker.getName()) + "</name>");
@@ -281,7 +281,7 @@ public class GPXTrackExporter implements TrackExporter {
printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">"); printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">");
if (trackPoint.hasAltitude()) { if (trackPoint.hasAltitude()) {
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude()) + "</ele>"); printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude().toM()) + "</ele>");
} }
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(trackPoint.getTime()) + "</time>"); printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(trackPoint.getTime()) + "</time>");
@@ -36,6 +36,7 @@ import java.util.Locale;
import java.util.UUID; import java.util.UUID;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Altitude;
import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker; import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.Speed;
@@ -428,7 +429,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements XMLIm
if (altitude != null) { if (altitude != null) {
try { try {
trackPoint.setAltitude(Double.parseDouble(altitude)); trackPoint.setAltitude(Altitude.WGS84.of(Double.parseDouble(altitude)));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude: %s", altitude)), e); throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude: %s", altitude)), e);
} }
@@ -148,7 +148,7 @@ public class TrackStatisticsUpdater {
//Update absolute (GPS-based) altitude //Update absolute (GPS-based) altitude
if (trackPoint.hasAltitude()) { if (trackPoint.hasAltitude()) {
updateAbsoluteAltitude(trackPoint.getAltitude()); updateAbsoluteAltitude(trackPoint.getAltitude().toM());
} }
if (lastTrackPoint == null || lastMovingTrackPoint == null) { if (lastTrackPoint == null || lastMovingTrackPoint == null) {