From 50127e311a32e620cbaa4e59db9ab8d20df3959b Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sun, 2 May 2021 18:54:32 +0200 Subject: [PATCH] Introduced value object for Altitude. --- .../io/file/importer/ExportImportTest.java | 5 ++- .../io/file/importer/LegacyImportTest.java | 2 +- .../stats/TrackStatisticsUpdaterTest.java | 21 +++++----- .../opentracks/content/data/Altitude.java | 39 +++++++++++++++++++ .../opentracks/content/data/Marker.java | 16 ++++---- .../opentracks/content/data/TrackPoint.java | 26 ++++++++----- .../provider/ContentProviderUtils.java | 9 +++-- .../StatisticsRecordingFragment.java | 2 +- .../io/file/exporter/GPXTrackExporter.java | 4 +- .../importer/AbstractFileTrackImporter.java | 3 +- .../stats/TrackStatisticsUpdater.java | 2 +- 11 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/content/data/Altitude.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index 12b1491d5..e8ca6204e 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; 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.Marker; import de.dennisguse.opentracks.content.data.Speed; @@ -416,7 +417,7 @@ public class ExportImportTest { } assertEquals(trackPoint.hasAltitude(), importedTrackPoint.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)) { @@ -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) { - 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.setSpeed(Speed.of(speed)); tp.setHeartRate_bpm(heartRate); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java index 7bfbcffef..5c83e1773 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/LegacyImportTest.java @@ -152,7 +152,7 @@ public class LegacyImportTest { if (altitude == null) { assertFalse(trackPoint.hasAltitude()); } else { - assertEquals(altitude, (Double) trackPoint.getAltitude()); + assertEquals(altitude, (Double) trackPoint.getAltitude().toM()); } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java index 96c4c5cc8..3288e73c1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java @@ -9,6 +9,7 @@ import org.junit.runner.RunWith; import java.time.Duration; import java.time.Instant; +import de.dennisguse.opentracks.content.data.Altitude; import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.content.data.TestDataUtil; @@ -53,8 +54,8 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); - TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); - TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); + TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000)); + TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000)); // when subject.addTrackPoint(tp1, GPS_DISTANCE); @@ -71,8 +72,8 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); - TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); - TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); + TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000)); + TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000)); tp3.setSpeed(Speed.of(5f)); // when @@ -90,11 +91,11 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); 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)); - 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)); - 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)); tp4.setSensorDistance(Distance.of(5f)); TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000)); @@ -122,9 +123,9 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); TrackPoint tp1 = new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochMilli(1000)); - TrackPoint tp2 = new TrackPoint(0, 0, 5.0, Instant.ofEpochMilli(2000)); - TrackPoint tp3 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(3000)); - TrackPoint tp4 = new TrackPoint(0.00001, 0, 5.0, Instant.ofEpochMilli(4000)); + TrackPoint tp2 = new TrackPoint(0, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(2000)); + TrackPoint tp3 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(3000)); + TrackPoint tp4 = new TrackPoint(0.00001, 0, Altitude.WGS84.of(5.0), Instant.ofEpochMilli(4000)); tp4.setSensorDistance(Distance.of(5f)); TrackPoint tp5 = new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochMilli(5000)); tp5.setSensorDistance(Distance.of(10f)); diff --git a/src/main/java/de/dennisguse/opentracks/content/data/Altitude.java b/src/main/java/de/dennisguse/opentracks/content/data/Altitude.java new file mode 100644 index 000000000..77c467a07 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/content/data/Altitude.java @@ -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); + } + } +} + diff --git a/src/main/java/de/dennisguse/opentracks/content/data/Marker.java b/src/main/java/de/dennisguse/opentracks/content/data/Marker.java index e127278dc..9b2054566 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/Marker.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/Marker.java @@ -50,7 +50,7 @@ public final class Marker { private Double latitude; private Double longitude; private Float accuracy; - private Double altitude_m; + private Altitude altitude; private Float bearing; //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.longitude = trackPoint.getLongitude(); 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(); this.length = Distance.of(0); //TODO Not cool! @@ -167,7 +167,7 @@ public final class Marker { location.setAccuracy(accuracy); } if (hasAltitude()) { - location.setAltitude(altitude_m); + location.setAltitude(altitude.toM()); } return location; @@ -202,15 +202,15 @@ public final class Marker { } public boolean hasAltitude() { - return altitude_m != null; + return altitude != null; } - public Double getAltitude() { - return altitude_m; + public Altitude getAltitude() { + return altitude; } - public void setAltitude(double altitude_m) { - this.altitude_m = altitude_m; + public void setAltitude(Altitude altitude) { + this.altitude = altitude; } public boolean hasBearing() { diff --git a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java index 66f9f36d5..c3cd10448 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java @@ -20,6 +20,7 @@ import android.os.Parcel; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import java.time.Duration; import java.time.Instant; @@ -51,7 +52,7 @@ public class TrackPoint { private Double latitude; private Double longitude; private Float accuracy; - private Double altitude_m; + private Altitude altitude; private Speed speed; private Float bearing; private Distance sensorDistance_m; @@ -102,7 +103,7 @@ public class TrackPoint { this.latitude = location.getLatitude(); this.longitude = location.getLongitude(); - this.altitude_m = location.getAltitude(); + this.altitude = Altitude.WGS84.of(location.getAltitude()); this.speed = Speed.of(location.getSpeed()); this.accuracy = location.getAccuracy(); @@ -114,11 +115,11 @@ public class TrackPoint { 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.latitude = latitude; this.longitude = longitude; - this.altitude_m = altitude; + this.altitude = altitude; this.time = time; } @@ -212,7 +213,7 @@ public class TrackPoint { location.setAccuracy(accuracy); } if (hasAltitude()) { - location.setAltitude(altitude_m); + location.setAltitude(altitude.toM()); } return location; @@ -257,15 +258,20 @@ public class TrackPoint { public boolean hasAltitude() { - return altitude_m != null; + return altitude != null; } - public double getAltitude() { - return altitude_m; + public Altitude getAltitude() { + return altitude; } - public void setAltitude(double altitude) { - this.altitude_m = altitude; + @VisibleForTesting + public void setAltitude(double altitude_m) { + this.altitude = Altitude.WGS84.of(altitude_m); + } + + public void setAltitude(Altitude altitude) { + this.altitude = altitude; } public boolean hasSpeed() { diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java index fdbac7b28..5df06f523 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java @@ -39,6 +39,7 @@ import java.util.List; import java.util.UUID; 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.Marker; import de.dennisguse.opentracks.content.data.MarkerColumns; @@ -320,7 +321,7 @@ public class ContentProviderUtils { marker.setLatitude(((double) cursor.getInt(latitudeIndex)) / 1E6); } if (!cursor.isNull(altitudeIndex)) { - marker.setAltitude(cursor.getFloat(altitudeIndex)); + marker.setAltitude(Altitude.WGS84.of(cursor.getFloat(altitudeIndex))); } if (!cursor.isNull(accuracyIndex)) { marker.setAccuracy(cursor.getFloat(accuracyIndex)); @@ -489,7 +490,7 @@ public class ContentProviderUtils { values.put(MarkerColumns.LATITUDE, (int) (marker.getLatitude() * 1E6)); values.put(MarkerColumns.TIME, marker.getTime().toEpochMilli()); if (marker.hasAltitude()) { - values.put(MarkerColumns.ALTITUDE, marker.getAltitude()); + values.put(MarkerColumns.ALTITUDE, marker.getAltitude().toM()); } if (marker.hasAccuracy()) { values.put(MarkerColumns.ACCURACY, marker.getAccuracy()); @@ -539,7 +540,7 @@ public class ContentProviderUtils { trackPoint.setTime(Instant.ofEpochMilli(cursor.getLong(indexes.timeIndex))); } 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)) { trackPoint.setAccuracy(cursor.getFloat(indexes.accuracyIndex)); @@ -690,7 +691,7 @@ public class ContentProviderUtils { } values.put(TrackPointsColumns.TIME, trackPoint.getTime().toEpochMilli()); if (trackPoint.hasAltitude()) { - values.put(TrackPointsColumns.ALTITUDE, trackPoint.getAltitude()); + values.put(TrackPointsColumns.ALTITUDE, trackPoint.getAltitude().toM()); } if (trackPoint.hasAccuracy()) { values.put(TrackPointsColumns.ACCURACY, trackPoint.getAccuracy()); diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java index 7d88841b3..bce046f16 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java @@ -444,7 +444,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi if (preferenceShowAltitude) { // Current altitude - Float altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? (float) lastTrackPoint.getAltitude() : null; + Float altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? (float) lastTrackPoint.getAltitude().toM() : null; Pair parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits); viewBinding.statsAltitudeCurrentValue.setText(parts.first); viewBinding.statsAltitudeCurrentUnit.setText(parts.second); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index c6c760636..5e45416b2 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -237,7 +237,7 @@ public class GPXTrackExporter implements TrackExporter { if (printWriter != null) { printWriter.println(""); if (marker.hasAltitude()) { - printWriter.println("" + ALTITUDE_FORMAT.format(marker.getAltitude()) + ""); + printWriter.println("" + ALTITUDE_FORMAT.format(marker.getAltitude().toM()) + ""); } printWriter.println(""); printWriter.println("" + StringUtils.formatCData(marker.getName()) + ""); @@ -281,7 +281,7 @@ public class GPXTrackExporter implements TrackExporter { printWriter.println(""); if (trackPoint.hasAltitude()) { - printWriter.println("" + ALTITUDE_FORMAT.format(trackPoint.getAltitude()) + ""); + printWriter.println("" + ALTITUDE_FORMAT.format(trackPoint.getAltitude().toM()) + ""); } printWriter.println(""); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java index 440c6453c..da7d036b2 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java @@ -36,6 +36,7 @@ import java.util.Locale; import java.util.UUID; 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.Marker; import de.dennisguse.opentracks.content.data.Speed; @@ -428,7 +429,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements XMLIm if (altitude != null) { try { - trackPoint.setAltitude(Double.parseDouble(altitude)); + trackPoint.setAltitude(Altitude.WGS84.of(Double.parseDouble(altitude))); } catch (NumberFormatException e) { throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude: %s", altitude)), e); } diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index ca24bf032..f1e1f946e 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -148,7 +148,7 @@ public class TrackStatisticsUpdater { //Update absolute (GPS-based) altitude if (trackPoint.hasAltitude()) { - updateAbsoluteAltitude(trackPoint.getAltitude()); + updateAbsoluteAltitude(trackPoint.getAltitude().toM()); } if (lastTrackPoint == null || lastMovingTrackPoint == null) {