Refactoring: move TrackPointDataSet directly into TrackPoint.

This commit is contained in:
Dennis Guse
2020-04-24 23:32:12 +02:00
parent ddb17f61cb
commit 3408ea97f4
15 changed files with 166 additions and 256 deletions
@@ -3,7 +3,7 @@ package de.dennisguse.opentracks.chart;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.UnitConversions;
@@ -25,7 +25,7 @@ public class ChartPoint {
this.elevation = elevation;
}
public ChartPoint(@NonNull TrackStatisticsUpdater trackStatisticsUpdater, TrackPointSensorDataSet sensorDataSet, boolean chartByDistance, boolean metricUnits) {
public ChartPoint(@NonNull TrackStatisticsUpdater trackStatisticsUpdater, TrackPoint trackPoint, boolean chartByDistance, boolean metricUnits) {
TrackStatistics trackStatistics = trackStatisticsUpdater.getTrackStatistics();
if (chartByDistance) {
@@ -48,15 +48,15 @@ public class ChartPoint {
speed *= UnitConversions.KM_TO_MI;
}
pace = speed == 0 ? 0.0 : 60.0 / speed;
if (sensorDataSet != null) {
if (sensorDataSet.hasHeartRate()) {
heartRate = sensorDataSet.getHeartRate_bpm();
if (trackPoint != null) {
if (trackPoint.hasHeartRate()) {
heartRate = trackPoint.getHeartRate_bpm();
}
if (sensorDataSet.hasCyclingCadence()) {
cadence = sensorDataSet.getCyclingCadence_rpm();
if (trackPoint.hasCyclingCadence()) {
cadence = trackPoint.getCyclingCadence_rpm();
}
if (sensorDataSet.hasPower()) {
power = sensorDataSet.getPower();
if (trackPoint.hasPower()) {
power = trackPoint.getPower();
}
}
}
@@ -29,6 +29,10 @@ public class TrackPoint {
private final Location location;
private Float heartRate_bpm = null;
private Float cyclingCadence_rpm = null;
private Float power = null;
public TrackPoint() {
this.location = new Location("");
}
@@ -37,17 +41,13 @@ public class TrackPoint {
this.location = location;
}
public TrackPoint(@NonNull Location location, TrackPointSensorDataSet sensorDataSet) {
this.location = location;
this.sensorDataSet = sensorDataSet;
}
public TrackPoint(@NonNull TrackPoint trackPoint, TrackPointSensorDataSet sensorDataSet) {
public TrackPoint(@NonNull TrackPoint trackPoint) {
this.location = trackPoint.getLocation();
this.sensorDataSet = sensorDataSet;
}
private TrackPointSensorDataSet sensorDataSet = null;
this.heartRate_bpm = trackPoint.getHeartRate_bpm();
this.cyclingCadence_rpm = trackPoint.getCyclingCadence_rpm();
this.power = trackPoint.getPower();
}
public TrackPoint(double latitude, double longitude, Double altitude, long time) {
location = new Location(LocationManager.GPS_PROVIDER);
@@ -88,14 +88,6 @@ public class TrackPoint {
return location;
}
public TrackPointSensorDataSet getSensorDataSet() {
return sensorDataSet;
}
public void setSensorDataSet(TrackPointSensorDataSet sensorDataSet) {
this.sensorDataSet = sensorDataSet;
}
public double getLatitude() {
return location.getLatitude();
}
@@ -180,6 +172,47 @@ public class TrackPoint {
return location.bearingTo(dest);
}
// Sensor data
public boolean hasSensorData() {
return hasHeartRate() || hasCyclingCadence() || hasPower();
}
public boolean hasHeartRate() {
return heartRate_bpm != null && heartRate_bpm > 0;
}
public float getHeartRate_bpm() {
return heartRate_bpm;
}
public void setHeartRate_bpm(Float heartRate_bpm) {
this.heartRate_bpm = heartRate_bpm;
}
public boolean hasCyclingCadence() {
return cyclingCadence_rpm != null;
}
public Float getCyclingCadence_rpm() {
return cyclingCadence_rpm;
}
public void setCyclingCadence_rpm(Float cyclingCadence_rpm) {
this.cyclingCadence_rpm = cyclingCadence_rpm;
}
public boolean hasPower() {
return power != null;
}
public Float getPower() {
return power;
}
public void setPower(Float power) {
this.power = power;
}
@NonNull
@Override
public String toString() {
@@ -1,99 +0,0 @@
package de.dennisguse.opentracks.content.data;
import androidx.annotation.NonNull;
//TODO Rename.
public final class TrackPointSensorDataSet {
private long time_ms;
private Float heartRate_bpm = null;
private Float cyclingCadence = null;
private Float cyclingSpeed = null;
private Float power = null;
public TrackPointSensorDataSet() {
this(System.currentTimeMillis());
}
public TrackPointSensorDataSet(long time_ms) {
this.time_ms = time_ms;
}
public boolean hasHeartRate() {
return heartRate_bpm != null && heartRate_bpm > 0;
}
public float getHeartRate_bpm() {
return heartRate_bpm;
}
public void setHeartRate_bpm(Float heartRate_bpm) {
this.heartRate_bpm = heartRate_bpm;
}
public boolean hasCyclingCadence() {
return cyclingCadence != null;
}
public Float getCyclingCadence_rpm() {
return cyclingCadence;
}
public void setCyclingCadence(Float cyclingCadence) {
this.cyclingCadence = cyclingCadence;
}
public void setCyclingCadence(Integer cyclingCadence) {
this.cyclingCadence = cyclingCadence != null ? cyclingCadence.floatValue() : null;
}
public boolean hasCyclingSpeed() {
return cyclingSpeed != null;
}
public Float getCyclingSpeed() {
return cyclingSpeed;
}
public void setCyclingSpeed(Float cyclingSpeed) {
this.cyclingSpeed = cyclingSpeed;
}
public boolean hasPower() {
return power != null;
}
public Float getPower() {
return power;
}
public void setPower(Float power) {
this.power = power;
}
public long getTime() {
return time_ms;
}
public void setTime(long time_ms) {
this.time_ms = time_ms;
}
/**
* Is the data recent considering the current time.
*
* @param maxAge the maximal age in milliseconds.
*/
public boolean isRecent(long maxAge) {
return time_ms + maxAge > System.currentTimeMillis();
}
@NonNull
@Override
public String toString() {
return "time=" + getTime()
+ (hasHeartRate() ? " heart=" + getHeartRate_bpm() : "")
+ (hasCyclingCadence() ? " cyclingCad=" + getCyclingCadence_rpm() : "")
+ (hasCyclingSpeed() ? " cyclingSpeed=" + getCyclingSpeed() : "");
}
}
@@ -36,7 +36,6 @@ import de.dennisguse.opentracks.android.ContentResolverWrapper;
import de.dennisguse.opentracks.android.IContentResolver;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
import de.dennisguse.opentracks.content.data.TracksColumns;
import de.dennisguse.opentracks.content.data.Waypoint;
@@ -621,19 +620,16 @@ public class ContentProviderUtils {
trackPoint.setBearing(cursor.getFloat(indexes.bearingIndex));
}
TrackPointSensorDataSet sensorDataSet = new TrackPointSensorDataSet();
if (cursor.isNull(indexes.sensorHeartRateIndex)) {
sensorDataSet.setHeartRate_bpm(cursor.getFloat(indexes.sensorHeartRateIndex));
if (!cursor.isNull(indexes.sensorHeartRateIndex)) {
trackPoint.setHeartRate_bpm(cursor.getFloat(indexes.sensorHeartRateIndex));
}
if (cursor.isNull(indexes.sensorCadenceIndex)) {
sensorDataSet.setCyclingCadence(cursor.getFloat(indexes.sensorCadenceIndex));
if (!cursor.isNull(indexes.sensorCadenceIndex)) {
trackPoint.setCyclingCadence_rpm(cursor.getFloat(indexes.sensorCadenceIndex));
}
if (cursor.isNull(indexes.sensorPowerIndex)) {
sensorDataSet.setCyclingSpeed(cursor.getFloat(indexes.sensorPowerIndex));
if (!cursor.isNull(indexes.sensorPowerIndex)) {
trackPoint.setPower(cursor.getFloat(indexes.sensorPowerIndex));
}
trackPoint.setSensorDataSet(sensorDataSet);
return trackPoint;
}
@@ -812,16 +808,14 @@ public class ContentProviderUtils {
values.put(TrackPointsColumns.BEARING, trackPoint.getBearing());
}
//SensorData
TrackPointSensorDataSet sensorDataSet = trackPoint.getSensorDataSet();
if (sensorDataSet != null && sensorDataSet.hasHeartRate()) {
values.put(TrackPointsColumns.SENSOR_HEARTRATE, sensorDataSet.getHeartRate_bpm());
if (trackPoint.hasHeartRate()) {
values.put(TrackPointsColumns.SENSOR_HEARTRATE, trackPoint.getHeartRate_bpm());
}
if (sensorDataSet != null && sensorDataSet.hasCyclingCadence()) {
values.put(TrackPointsColumns.SENSOR_CADENCE, sensorDataSet.getCyclingCadence_rpm());
if (trackPoint.hasCyclingCadence()) {
values.put(TrackPointsColumns.SENSOR_CADENCE, trackPoint.getCyclingCadence_rpm());
}
if (sensorDataSet != null && sensorDataSet.hasPower()) {
values.put(TrackPointsColumns.SENSOR_POWER, sensorDataSet.getPower());
if (trackPoint.hasPower()) {
values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower());
}
return values;
}
@@ -1,9 +1,8 @@
package de.dennisguse.opentracks.content.sensor;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.TrackPoint;
/**
*
@@ -19,13 +18,6 @@ public final class SensorDataSet {
public SensorDataSet() {
}
@VisibleForTesting
public SensorDataSet(SensorDataHeartRate heartRate, SensorDataCycling.Cadence cyclingCadence, SensorDataCycling.Speed cyclingSpeed) {
this.heartRate = heartRate;
this.cyclingCadence = cyclingCadence;
this.cyclingSpeed = cyclingSpeed;
}
public SensorDataHeartRate getHeartRate() {
return heartRate;
}
@@ -70,21 +62,18 @@ public final class SensorDataSet {
this.cyclingSpeed = null;
}
public TrackPointSensorDataSet createTrackPointSensorDataSet() {
TrackPointSensorDataSet sensorDataSet = new TrackPointSensorDataSet();
public void fillTrackPoint(TrackPoint trackPoint) {
if (heartRate != null) {
sensorDataSet.setHeartRate_bpm(heartRate.getHeartRate_bpm());
trackPoint.setHeartRate_bpm(heartRate.getHeartRate_bpm());
}
if (cyclingCadence != null && cyclingCadence.hasCadence_rpm()) {
sensorDataSet.setCyclingCadence(cyclingCadence.getCadence_rpm());
trackPoint.setCyclingCadence_rpm(cyclingCadence.getCadence_rpm());
}
if (cyclingSpeed != null && cyclingSpeed.hasSpeed()) {
sensorDataSet.setCyclingCadence(cyclingSpeed.getSpeed_ms());
trackPoint.setSpeed(cyclingSpeed.getSpeed_ms());
}
return sensorDataSet;
}
@NonNull
@@ -313,7 +313,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@VisibleForTesting
ChartPoint createPendingPoint(@NonNull TrackPoint trackPoint) {
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
return new ChartPoint(trackStatisticsUpdater, trackPoint.getSensorDataSet(), chartByDistance, chartView.getMetricUnits());
return new ChartPoint(trackStatisticsUpdater, trackPoint, chartByDistance, chartView.getMetricUnits());
}
@VisibleForTesting
@@ -39,7 +39,6 @@ import de.dennisguse.opentracks.content.TrackDataHub;
import de.dennisguse.opentracks.content.TrackDataListener;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.Waypoint;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
@@ -436,7 +435,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
}
/**
* Tries to fetch most recent {@link TrackPointSensorDataSet} from {@link de.dennisguse.opentracks.services.TrackRecordingService}.
* Tries to fetch most recent {@link SensorDataSet} from {@link de.dennisguse.opentracks.services.TrackRecordingService}.
*/
private void updateSensorDataUI() {
TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
@@ -28,7 +28,6 @@ import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.DescriptionGenerator;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.Waypoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.util.FileUtils;
@@ -75,7 +74,7 @@ public class KmlTrackWriter implements TrackWriter {
* @param context the context
* @param hasMultipleTracks should encode multiple tracks into one file?
* @param exportTrackDetail should detailed information about the track be exported (e.g., title, description, waypoints, timing)?
* @param exportSensorData should {@link TrackPointSensorDataSet} be exported?
* @param exportSensorData should {@link TrackPointSensorDataSet} be exported?
* @param exportPhotos should pictures be exported (if true: exports to KMZ)?
*/
public KmlTrackWriter(Context context, boolean hasMultipleTracks, boolean exportTrackDetail, boolean exportSensorData, boolean exportPhotos) {
@@ -268,17 +267,14 @@ public class KmlTrackWriter implements TrackWriter {
printWriter.println("<gx:coord>" + getCoordinates(trackPoint.getLocation(), " ") + "</gx:coord>");
if (exportSensorData) {
TrackPointSensorDataSet sensorDataSet = trackPoint.getSensorDataSet();
if (sensorDataSet != null) {
if (sensorDataSet.hasHeartRate()) {
heartRateList.add(sensorDataSet.getHeartRate_bpm());
}
if (sensorDataSet.hasCyclingCadence()) {
cadenceList.add(sensorDataSet.getCyclingCadence_rpm());
}
if (sensorDataSet.hasPower()) {
powerList.add(sensorDataSet.getPower());
}
if (trackPoint.hasHeartRate()) {
heartRateList.add(trackPoint.getHeartRate_bpm());
}
if (trackPoint.hasCyclingCadence()) {
cadenceList.add(trackPoint.getCyclingCadence_rpm());
}
if (trackPoint.hasPower()) {
powerList.add(trackPoint.getPower());
}
}
}
@@ -27,7 +27,6 @@ import org.xml.sax.SAXException;
import java.util.ArrayList;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.io.file.exporter.KmlTrackWriter;
@@ -223,25 +222,16 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
for (int i = 0; i < trackPoints.size(); i++) {
TrackPoint trackPoint = trackPoints.get(i);
boolean hasSensorData = false;
TrackPointSensorDataSet sensorDataSet = new TrackPointSensorDataSet(trackPoint.getTime());
if (i < heartRateList.size()) {
sensorDataSet.setHeartRate_bpm(heartRateList.get(i));
hasSensorData = true;
trackPoint.setHeartRate_bpm(heartRateList.get(i));
}
if (i < cadenceList.size()) {
sensorDataSet.setCyclingCadence(cadenceList.get(i));
hasSensorData = true;
trackPoint.setCyclingCadence_rpm(cadenceList.get(i));
}
if (i < powerList.size()) {
sensorDataSet.setPower(cadenceList.get(i));
hasSensorData = true;
trackPoint.setPower(cadenceList.get(i));
}
if (!hasSensorData) {
trackPoint.setSensorDataSet(sensorDataSet);
}
insertTrackPoint(trackPoint);
}
}
@@ -45,7 +45,6 @@ import de.dennisguse.opentracks.TrackDetailActivity;
import de.dennisguse.opentracks.TrackListActivity;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.data.TrackPointSensorDataSet;
import de.dennisguse.opentracks.content.data.Waypoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.CustomContentProvider;
@@ -576,7 +575,9 @@ public class TrackRecordingService extends Service {
return;
}
TrackPoint trackPoint = new TrackPoint(location, getTrackPointSensorDataSet());
TrackPoint trackPoint = new TrackPoint(location);
fillWithSensorDataSet(trackPoint);
notificationManager.updateTrackPoint(this, trackPoint, recordingGpsAccuracy);
if (!TrackPointUtils.fulfillsAccuracy(trackPoint, recordingGpsAccuracy)) {
@@ -627,7 +628,7 @@ public class TrackRecordingService extends Service {
return;
}
if (trackPoint.getSensorDataSet() != null || distanceToLastTrackLocation >= recordingDistanceInterval) {
if (trackPoint.hasSensorData() || distanceToLastTrackLocation >= recordingDistanceInterval) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = false;
@@ -716,13 +717,11 @@ public class TrackRecordingService extends Service {
return remoteSensorManager.getSensorData();
}
TrackPointSensorDataSet getTrackPointSensorDataSet() {
void fillWithSensorDataSet(TrackPoint trackPoint) {
SensorDataSet sensorData = getSensorDataSet();
if (sensorData != null) {
return sensorData.createTrackPointSensorDataSet();
sensorData.fillTrackPoint(trackPoint);
}
return null;
}
private void registerLocationListener() {