Rename elevation to altitude (without translations).

Fixes #678.
This commit is contained in:
Dennis Guse
2021-04-02 18:29:05 +02:00
parent e09b04308c
commit bc1b4e3cd2
101 changed files with 893 additions and 934 deletions
@@ -13,7 +13,7 @@ public class ChartPoint {
private double timeOrDistance;
//Y-axis
private double elevation;
private double altitude;
private double speed;
private double pace;
private double heartRate = Double.NaN;
@@ -21,8 +21,8 @@ public class ChartPoint {
private double power = Double.NaN;
@VisibleForTesting
ChartPoint(double elevation) {
this.elevation = elevation;
ChartPoint(double altitude) {
this.altitude = altitude;
}
public ChartPoint(@NonNull TrackStatisticsUpdater trackStatisticsUpdater, TrackPoint trackPoint, boolean chartByDistance, boolean metricUnits) {
@@ -38,9 +38,9 @@ public class ChartPoint {
timeOrDistance = trackStatistics.getTotalTime().toMillis();
}
elevation = trackStatisticsUpdater.getSmoothedElevation();
altitude = trackStatisticsUpdater.getSmoothedAltitude();
if (!metricUnits) {
elevation *= UnitConversions.M_TO_FT;
altitude *= UnitConversions.M_TO_FT;
}
speed = trackStatisticsUpdater.getSmoothedSpeed() * UnitConversions.MPS_TO_KMH;
@@ -65,8 +65,8 @@ public class ChartPoint {
return timeOrDistance;
}
public double getElevation() {
return elevation;
public double getAltitude() {
return altitude;
}
public double getSpeed() {
@@ -200,15 +200,15 @@ public class ChartView extends View {
Integer.MIN_VALUE,
Integer.MAX_VALUE,
new int[]{5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000},
R.string.description_elevation_metric,
R.string.description_elevation_imperial,
R.color.chart_elevation_fill,
R.color.chart_elevation_border,
R.string.description_altitude_metric,
R.string.description_altitude_imperial,
R.color.chart_altitude_fill,
R.color.chart_altitude_border,
fontSizeSmall,
fontSizeMedium) {
@Override
protected double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
return chartPoint.getElevation();
return chartPoint.getAltitude();
}
@Override
@@ -127,24 +127,24 @@ public class DescriptionGenerator {
// Fastest pace
writePace(stats.getMaxSpeed(), builder, R.string.description_fastest_pace_in_minute, lineBreak);
// Max elevation
if (stats.hasElevationMax()) {
writeElevation(stats.getMaxElevation(), builder, R.string.description_max_elevation, lineBreak);
// Max altitude
if (stats.hasAltitudeMax()) {
writeAltitude(stats.getMaxAltitude(), builder, R.string.description_max_altitude, lineBreak);
}
// Min elevation
if (stats.hasElevationMin()) {
writeElevation(stats.getMinElevation(), builder, R.string.description_min_elevation, lineBreak);
// Min altitude
if (stats.hasAltitudeMin()) {
writeAltitude(stats.getMinAltitude(), builder, R.string.description_min_altitude, lineBreak);
}
// Elevation gain
if (stats.hasTotalElevationGain()) {
writeElevation(stats.getTotalElevationGain(), builder, R.string.description_elevation_gain, lineBreak);
// Altitude gain
if (stats.hasTotalAltitudeGain()) {
writeAltitude(stats.getTotalAltitudeGain(), builder, R.string.description_altitude_gain, lineBreak);
}
// Elevation loss
if (stats.hasTotalElevationLoss()) {
writeElevation(stats.getTotalElevationLoss(), builder, R.string.description_elevation_loss, lineBreak);
// Altitude loss
if (stats.hasTotalAltitudeLoss()) {
writeAltitude(stats.getTotalAltitudeLoss(), builder, R.string.description_altitude_loss, lineBreak);
}
// Recorded time
@@ -201,8 +201,6 @@ public class DescriptionGenerator {
}
/**
* Writes pace.
*
* @param speed speed in meters per second
* @param builder StringBuilder to append pace
* @param resId resource id of pace string
@@ -221,18 +219,16 @@ public class DescriptionGenerator {
}
/**
* Writes elevation.
*
* @param elevation elevation in meters
* @param builder StringBuilder to append elevation
* @param resId resource id of elevation string
* @param lineBreak line break string
* @param altitude_m altitude_m in meters
* @param builder StringBuilder to append
* @param resId resource id of altitude string
* @param lineBreak line break string
*/
@VisibleForTesting
void writeElevation(double elevation, StringBuilder builder, int resId, String lineBreak) {
long elevationInM = Math.round(elevation);
long elevationInFt = Math.round(elevation * UnitConversions.M_TO_FT);
builder.append(context.getString(resId, elevationInM, elevationInFt));
void writeAltitude(double altitude_m, StringBuilder builder, int resId, String lineBreak) {
long altitudeInM = Math.round(altitude_m);
long altitudeInFt = Math.round(altitude_m * UnitConversions.M_TO_FT);
builder.append(context.getString(resId, altitudeInM, altitudeInFt));
builder.append(lineBreak);
}
}
@@ -48,7 +48,7 @@ public interface MarkerColumns extends BaseColumns {
String LONGITUDE = "longitude"; // longitude
String LATITUDE = "latitude"; // latitude
String TIME = "time"; // time
String ALTITUDE = "elevation"; // altitude
String ALTITUDE = "elevation"; // altitude //TODO RENAME column
String ACCURACY = "accuracy"; // accuracy
String BEARING = "bearing"; // bearing
@@ -93,8 +93,8 @@ public class TrackPoint {
private Float heartRate_bpm = null;
private Float cyclingCadence_rpm = null;
private Float power = null;
private Float elevationGain = null;
private Float elevationLoss = null;
private Float altitudeGain_m = null;
private Float altitudeLoss_m = null;
public TrackPoint(@NonNull Type type) {
this.type = type;
@@ -221,28 +221,28 @@ public class TrackPoint {
return location;
}
public boolean hasElevationGain() {
return elevationGain != null;
public boolean hasAltitudeGain() {
return altitudeGain_m != null;
}
public float getElevationGain() {
return elevationGain;
public float getAltitudeGain() {
return altitudeGain_m;
}
public void setElevationGain(Float elevationGain) {
this.elevationGain = elevationGain;
public void setAltitudeGain(Float altitudeGain_m) {
this.altitudeGain_m = altitudeGain_m;
}
public boolean hasElevationLoss() {
return elevationLoss != null;
public boolean hasAltitudeLoss() {
return altitudeLoss_m != null;
}
public float getElevationLoss() {
return elevationLoss;
public float getAltitudeLoss() {
return altitudeLoss_m;
}
public void setElevationLoss(Float elevationLoss) {
this.elevationLoss = elevationLoss;
public void setAltitudeLoss(Float altitudeLoss_m) {
this.altitudeLoss_m = altitudeLoss_m;
}
public Instant getTime() {
@@ -52,8 +52,8 @@ public interface TrackPointsColumns extends BaseColumns {
String SENSOR_CADENCE = "sensor_cadence";
String SENSOR_DISTANCE = "sensor_distance"; //DISTANCE from previous TrackPoint
String SENSOR_POWER = "sensor_power";
String ELEVATION_GAIN = "elevation_gain";
String ELEVATION_LOSS = "elevation_loss";
String ALTITUDE_GAIN = "elevation_gain";
String ALTITUDE_LOSS = "elevation_loss";
// Alias for sensor statistics
String ALIAS_AVG_HR = "avg_hr";
@@ -75,8 +75,8 @@ public interface TrackPointsColumns extends BaseColumns {
+ SENSOR_HEARTRATE + " FLOAT, "
+ SENSOR_CADENCE + " FLOAT, "
+ SENSOR_POWER + " FLOAT, "
+ ELEVATION_GAIN + " FLOAT, "
+ ELEVATION_LOSS + " FLOAT, "
+ ALTITUDE_GAIN + " FLOAT, "
+ ALTITUDE_LOSS + " FLOAT, "
+ TYPE + " TEXT CHECK(type IN (-2, -1, 0, 1)), "
+ SENSOR_DISTANCE + " FLOAT, "
+ "FOREIGN KEY (" + TRACKID + ") REFERENCES " + TracksColumns.TABLE_NAME + "(" + TracksColumns._ID + ") ON UPDATE CASCADE ON DELETE CASCADE"
@@ -52,10 +52,10 @@ public interface TracksColumns extends BaseColumns {
String AVGSPEED = "avgspeed"; // average speed
String AVGMOVINGSPEED = "avgmovingspeed"; // average moving speed
String MAXSPEED = "maxspeed"; // maximum speed
String MINELEVATION = "minelevation"; // minimum elevation
String MAXELEVATION = "maxelevation"; // maximum elevation
String ELEVATIONGAIN = "elevationgain"; // elevation gain
String ELEVATIONLOSS = "elevationloss"; // elevation loss
String MIN_ALTITUDE = "minelevation"; // minimum altitude //TODO RENAME column
String MAX_ALTITUDE = "maxelevation"; // maximum altitude //TODO RENAME column
String ALTITUDE_GAIN = "elevationgain"; // altitude gain //TODO RENAME column
String ALTITUDE_LOSS = "elevationloss"; // altitude loss //TODO RENAME column
String ICON = "icon"; // track activity type icon
String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
@@ -72,12 +72,12 @@ public interface TracksColumns extends BaseColumns {
+ AVGSPEED + " FLOAT, "
+ AVGMOVINGSPEED + " FLOAT, "
+ MAXSPEED + " FLOAT, "
+ MINELEVATION + " FLOAT, "
+ MAXELEVATION + " FLOAT, "
+ ELEVATIONGAIN + " FLOAT, "
+ MIN_ALTITUDE + " FLOAT, "
+ MAX_ALTITUDE + " FLOAT, "
+ ALTITUDE_GAIN + " FLOAT, "
+ ICON + " TEXT, "
+ UUID + " BLOB, "
+ ELEVATIONLOSS + " FLOAT)";
+ ALTITUDE_LOSS + " FLOAT)";
String CREATE_TABLE_INDEX = "CREATE UNIQUE INDEX " + TABLE_NAME + "_" + UUID + "_index ON " + TABLE_NAME + "(" + UUID + ")";
@@ -21,8 +21,8 @@ class CachedTrackPointsIndexes {
final int sensorCadenceIndex;
final int sensorDistanceIndex;
final int sensorPowerIndex;
final int elevationGainIndex;
final int elevationLossIndex;
final int altitudeGainIndex;
final int altitudeLossIndex;
CachedTrackPointsIndexes(Cursor cursor) {
idIndex = cursor.getColumnIndex(TrackPointsColumns._ID);
@@ -38,7 +38,7 @@ class CachedTrackPointsIndexes {
sensorCadenceIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_CADENCE);
sensorDistanceIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_DISTANCE);
sensorPowerIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_POWER);
elevationGainIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ELEVATION_GAIN);
elevationLossIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ELEVATION_LOSS);
altitudeGainIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALTITUDE_GAIN);
altitudeLossIndex = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALTITUDE_LOSS);
}
}
@@ -97,10 +97,10 @@ public class ContentProviderUtils {
int totalTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
int movingTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.MOVINGTIME);
int maxSpeedIndex = cursor.getColumnIndexOrThrow(TracksColumns.MAXSPEED);
int minElevationIndex = cursor.getColumnIndexOrThrow(TracksColumns.MINELEVATION);
int maxElevationIndex = cursor.getColumnIndexOrThrow(TracksColumns.MAXELEVATION);
int elevationGainIndex = cursor.getColumnIndexOrThrow(TracksColumns.ELEVATIONGAIN);
int elevationLossIndex = cursor.getColumnIndexOrThrow(TracksColumns.ELEVATIONLOSS);
int minAltitudeIndex = cursor.getColumnIndexOrThrow(TracksColumns.MIN_ALTITUDE);
int maxAltitudeIndex = cursor.getColumnIndexOrThrow(TracksColumns.MAX_ALTITUDE);
int altitudeGainIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_GAIN);
int altitudeLossIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_LOSS);
int iconIndex = cursor.getColumnIndexOrThrow(TracksColumns.ICON);
Track track = new Track();
@@ -138,17 +138,17 @@ public class ContentProviderUtils {
if (!cursor.isNull(maxSpeedIndex)) {
trackStatistics.setMaxSpeed(cursor.getFloat(maxSpeedIndex));
}
if (!cursor.isNull(minElevationIndex)) {
trackStatistics.setMinElevation(cursor.getFloat(minElevationIndex));
if (!cursor.isNull(minAltitudeIndex)) {
trackStatistics.setMinAltitude(cursor.getFloat(minAltitudeIndex));
}
if (!cursor.isNull(maxElevationIndex)) {
trackStatistics.setMaxElevation(cursor.getFloat(maxElevationIndex));
if (!cursor.isNull(maxAltitudeIndex)) {
trackStatistics.setMaxAltitude(cursor.getFloat(maxAltitudeIndex));
}
if (!cursor.isNull(elevationGainIndex)) {
trackStatistics.setTotalElevationGain(cursor.getFloat(elevationGainIndex));
if (!cursor.isNull(altitudeGainIndex)) {
trackStatistics.setTotalAltitudeGain(cursor.getFloat(altitudeGainIndex));
}
if (!cursor.isNull(elevationLossIndex)) {
trackStatistics.setTotalElevationLoss(cursor.getFloat(elevationLossIndex));
if (!cursor.isNull(altitudeLossIndex)) {
trackStatistics.setTotalAltitudeLoss(cursor.getFloat(altitudeLossIndex));
}
if (!cursor.isNull(iconIndex)) {
track.setIcon(cursor.getString(iconIndex));
@@ -284,10 +284,10 @@ public class ContentProviderUtils {
values.put(TracksColumns.AVGSPEED, trackStatistics.getAverageSpeed());
values.put(TracksColumns.AVGMOVINGSPEED, trackStatistics.getAverageMovingSpeed());
values.put(TracksColumns.MAXSPEED, trackStatistics.getMaxSpeed());
values.put(TracksColumns.MINELEVATION, trackStatistics.getMinElevation());
values.put(TracksColumns.MAXELEVATION, trackStatistics.getMaxElevation());
values.put(TracksColumns.ELEVATIONGAIN, trackStatistics.getTotalElevationGain());
values.put(TracksColumns.ELEVATIONLOSS, trackStatistics.getTotalElevationLoss());
values.put(TracksColumns.MIN_ALTITUDE, trackStatistics.getMinAltitude());
values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude());
values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain());
values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss());
values.put(TracksColumns.ICON, track.getIcon());
return values;
@@ -562,11 +562,11 @@ public class ContentProviderUtils {
trackPoint.setPower(cursor.getFloat(indexes.sensorPowerIndex));
}
if (!cursor.isNull(indexes.elevationGainIndex)) {
trackPoint.setElevationGain(cursor.getFloat(indexes.elevationGainIndex));
if (!cursor.isNull(indexes.altitudeGainIndex)) {
trackPoint.setAltitudeGain(cursor.getFloat(indexes.altitudeGainIndex));
}
if (!cursor.isNull(indexes.elevationLossIndex)) {
trackPoint.setElevationLoss(cursor.getFloat(indexes.elevationLossIndex));
if (!cursor.isNull(indexes.altitudeLossIndex)) {
trackPoint.setAltitudeLoss(cursor.getFloat(indexes.altitudeLossIndex));
}
return trackPoint;
@@ -713,11 +713,11 @@ public class ContentProviderUtils {
values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower());
}
if (trackPoint.hasElevationGain()) {
values.put(TrackPointsColumns.ELEVATION_GAIN, trackPoint.getElevationGain());
if (trackPoint.hasAltitudeGain()) {
values.put(TrackPointsColumns.ALTITUDE_GAIN, trackPoint.getAltitudeGain());
}
if (trackPoint.hasElevationLoss()) {
values.put(TrackPointsColumns.ELEVATION_LOSS, trackPoint.getElevationLoss());
if (trackPoint.hasAltitudeLoss()) {
values.put(TrackPointsColumns.ALTITUDE_LOSS, trackPoint.getAltitudeLoss());
}
return values;
@@ -231,24 +231,24 @@ public class StatisticsRecordedFragment extends Fragment {
viewBinding.statsMovingSpeedUnit.setText(parts.second);
}
// Set elevation gain and loss
// Set altitude gain and loss
{
// Make elevation visible?
boolean showElevation = PreferencesUtils.isShowStatsElevation(sharedPreferences, getContext());
viewBinding.statsElevationGroup.setVisibility(showElevation ? View.VISIBLE : View.GONE);
// Make altitude visible?
boolean show = PreferencesUtils.isShowStatsAltitude(sharedPreferences, getContext());
viewBinding.statsAltitudeGroup.setVisibility(show ? View.VISIBLE : View.GONE);
Float elevationGain_m = trackStatistics.getTotalElevationGain();
Float elevationLoss_m = trackStatistics.getTotalElevationLoss();
Float altitudeGain_m = trackStatistics.getTotalAltitudeGain();
Float altitudeLoss_m = trackStatistics.getTotalAltitudeLoss();
Pair<String, String> parts;
parts = StringUtils.formatElevation(getContext(), elevationGain_m, preferenceMetricUnits);
viewBinding.statsElevationGainValue.setText(parts.first);
viewBinding.statsElevationGainUnit.setText(parts.second);
parts = StringUtils.formatAltitude(getContext(), altitudeGain_m, preferenceMetricUnits);
viewBinding.statsAltitudeGainValue.setText(parts.first);
viewBinding.statsAltitudeGainUnit.setText(parts.second);
parts = StringUtils.formatElevation(getContext(), elevationLoss_m, preferenceMetricUnits);
viewBinding.statsElevationLossValue.setText(parts.first);
viewBinding.statsElevationLossUnit.setText(parts.second);
parts = StringUtils.formatAltitude(getContext(), altitudeLoss_m, preferenceMetricUnits);
viewBinding.statsAltitudeLossValue.setText(parts.first);
viewBinding.statsAltitudeLossUnit.setText(parts.second);
}
}
@@ -73,7 +73,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
private SharedPreferences sharedPreferences;
private boolean preferenceMetricUnits;
private boolean preferenceReportSpeed;
private boolean preferenceShowElevation;
private boolean preferenceShowAltitude;
private boolean preferenceShowCoordinate;
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
@@ -89,9 +89,9 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
preferenceReportSpeed = PreferencesUtils.isReportSpeed(sharedPreferences, getContext(), category);
}
if (PreferencesUtils.isKey(getContext(), R.string.stats_show_grade_elevation_key, key)) {
if (PreferencesUtils.isKey(getContext(), R.string.stats_show_grade_altitude_key, key)) {
updateUInecessary = true;
preferenceShowElevation = PreferencesUtils.isShowStatsElevation(sharedPreferences, getContext());
preferenceShowAltitude = PreferencesUtils.isShowStatsAltitude(sharedPreferences, getContext());
}
if (PreferencesUtils.isKey(getContext(), R.string.stats_show_coordinate_key, key)) {
@@ -303,7 +303,7 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
/**
* Tries to fetch most recent {@link SensorDataSet} from {@link de.dennisguse.opentracks.services.TrackRecordingService}.
* Also sets elevation gain and loss.
* Also sets altitude gain and loss.
*/
private void updateSensorDataUI() {
TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
@@ -326,44 +326,44 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
sensorsAdapter.swapData(sensorDataList);
setSpeedSensorData(sensorDataSet);
}
//TODO Check if we can distribute the total elevation gain and loss via trackStatistics instead of doing some computation in the UI layer.
setTotalElevationGain(trackRecordingService.getElevationGain_m());
setTotalElevationLoss(trackRecordingService.getElevationLoss_m());
//TODO Check if we can get the total altitude gain and loss via trackStatistics instead of doing some computation in the UI layer.
setTotalAltitudeGain(trackRecordingService.getAltitudeGain_m());
setTotalAltitudeLoss(trackRecordingService.getAltitudeLoss_m());
}
}
// Set elevation gain
private void setTotalElevationGain(Float elevationGain_m) {
Float totalElevationGain = elevationGain_m;
// Set altitude gain
private void setTotalAltitudeGain(Float altitudeGain_m) {
Float totalAltitudeGain = altitudeGain_m;
if (lastTrackStatistics != null && lastTrackStatistics.hasTotalElevationGain()) {
if (elevationGain_m == null) {
totalElevationGain = lastTrackStatistics.getTotalElevationGain();
if (lastTrackStatistics != null && lastTrackStatistics.hasTotalAltitudeGain()) {
if (altitudeGain_m == null) {
totalAltitudeGain = lastTrackStatistics.getTotalAltitudeGain();
} else {
totalElevationGain += lastTrackStatistics.getTotalElevationGain();
totalAltitudeGain += lastTrackStatistics.getTotalAltitudeGain();
}
}
Pair<String, String> parts = StringUtils.formatElevation(getContext(), totalElevationGain, preferenceMetricUnits);
viewBinding.statsElevationGainValue.setText(parts.first);
viewBinding.statsElevationGainUnit.setText(parts.second);
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), totalAltitudeGain, preferenceMetricUnits);
viewBinding.statsAltitudeGainValue.setText(parts.first);
viewBinding.statsAltitudeGainUnit.setText(parts.second);
}
// Set elevation loss
private void setTotalElevationLoss(Float elevationLoss_m) {
Float totalElevationLoss = elevationLoss_m;
// Set altitude loss
private void setTotalAltitudeLoss(Float altitudeLoss_m) {
Float totalAltitudeLoss = altitudeLoss_m;
if (lastTrackStatistics != null && lastTrackStatistics.hasTotalElevationLoss()) {
if (elevationLoss_m == null) {
totalElevationLoss = lastTrackStatistics.getTotalElevationLoss();
if (lastTrackStatistics != null && lastTrackStatistics.hasTotalAltitudeLoss()) {
if (altitudeLoss_m == null) {
totalAltitudeLoss = lastTrackStatistics.getTotalAltitudeLoss();
} else {
totalElevationLoss += lastTrackStatistics.getTotalElevationLoss();
totalAltitudeLoss += lastTrackStatistics.getTotalAltitudeLoss();
}
}
Pair<String, String> parts = StringUtils.formatElevation(getContext(), totalElevationLoss, preferenceMetricUnits);
viewBinding.statsElevationLossValue.setText(parts.first);
viewBinding.statsElevationLossUnit.setText(parts.second);
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), totalAltitudeLoss, preferenceMetricUnits);
viewBinding.statsAltitudeLossValue.setText(parts.first);
viewBinding.statsAltitudeLossUnit.setText(parts.second);
}
private void setSpeedSensorData(SensorDataSet sensorDataSet) {
@@ -429,9 +429,9 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
viewBinding.statsMovingSpeedUnit.setText(parts.second);
}
// Set elevation gain and loss
// Set altitude gain and loss
{
viewBinding.statsElevationGroup.setVisibility(preferenceShowElevation ? View.VISIBLE : View.GONE);
viewBinding.statsAltitudeGroup.setVisibility(preferenceShowAltitude ? View.VISIBLE : View.GONE);
}
}
@@ -452,15 +452,15 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN;
setSpeed(speed);
// Set elevation
viewBinding.statsElevationGroup.setVisibility(preferenceShowElevation ? View.VISIBLE : View.GONE);
// Set altitude
viewBinding.statsAltitudeGroup.setVisibility(preferenceShowAltitude ? View.VISIBLE : View.GONE);
if (preferenceShowElevation) {
// Current elevation
if (preferenceShowAltitude) {
// Current altitude
Float altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? (float) lastTrackPoint.getAltitude() : null;
Pair<String, String> parts = StringUtils.formatElevation(getContext(), altitude, preferenceMetricUnits);
viewBinding.statsElevationCurrentValue.setText(parts.first);
viewBinding.statsElevationCurrentUnit.setText(parts.second);
Pair<String, String> parts = StringUtils.formatAltitude(getContext(), altitude, preferenceMetricUnits);
viewBinding.statsAltitudeCurrentValue.setText(parts.first);
viewBinding.statsAltitudeCurrentUnit.setText(parts.second);
}
// Set coordinate
@@ -46,7 +46,7 @@ public class GPXTrackExporter implements TrackExporter {
private static final String TAG = GPXTrackExporter.class.getSimpleName();
private static final NumberFormat ELEVATION_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat ALTITUDE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat COORDINATE_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat SPEED_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat DISTANCE_FORMAT = NumberFormat.getInstance(Locale.US);
@@ -59,8 +59,8 @@ public class GPXTrackExporter implements TrackExporter {
* GPX readers expect to see fractional numbers with US-style punctuation.
* That is, they want periods for decimal points, rather than commas.
*/
ELEVATION_FORMAT.setMaximumFractionDigits(1);
ELEVATION_FORMAT.setGroupingUsed(false);
ALTITUDE_FORMAT.setMaximumFractionDigits(1);
ALTITUDE_FORMAT.setGroupingUsed(false);
COORDINATE_FORMAT.setMaximumFractionDigits(6);
COORDINATE_FORMAT.setMaximumIntegerDigits(3);
@@ -237,7 +237,7 @@ public class GPXTrackExporter implements TrackExporter {
if (printWriter != null) {
printWriter.println("<wpt " + formatLocation(marker.getLatitude(), marker.getLongitude()) + ">");
if (marker.hasAltitude()) {
printWriter.println("<ele>" + ELEVATION_FORMAT.format(marker.getAltitude()) + "</ele>");
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(marker.getAltitude()) + "</ele>");
}
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(marker.getTime()) + "</time>");
printWriter.println("<name>" + StringUtils.formatCData(marker.getName()) + "</name>");
@@ -281,12 +281,12 @@ public class GPXTrackExporter implements TrackExporter {
printWriter.println("<trkpt " + formatLocation(trackPoint.getLatitude(), trackPoint.getLongitude()) + ">");
if (trackPoint.hasAltitude()) {
printWriter.println("<ele>" + ELEVATION_FORMAT.format(trackPoint.getAltitude()) + "</ele>");
printWriter.println("<ele>" + ALTITUDE_FORMAT.format(trackPoint.getAltitude()) + "</ele>");
}
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(trackPoint.getTime()) + "</time>");
if (trackPoint.hasSpeed() || trackPoint.hasHeartRate() || trackPoint.hasCyclingCadence() || trackPoint.hasElevationGain() || trackPoint.hasElevationLoss()) {
if (trackPoint.hasSpeed() || trackPoint.hasHeartRate() || trackPoint.hasCyclingCadence() || trackPoint.hasAltitudeGain() || trackPoint.hasAltitudeLoss()) {
printWriter.println("<extensions><gpxtpx:TrackPointExtension>");
if (trackPoint.hasSpeed()) {
@@ -305,16 +305,16 @@ public class GPXTrackExporter implements TrackExporter {
printWriter.println("<pwr:PowerInWatts>" + POWER_FORMAT.format(trackPoint.getPower()) + "</pwr:PowerInWatts>");
}
if (trackPoint.hasElevationGain()) {
printWriter.println("<opentracks:gain>" + ELEVATION_FORMAT.format(trackPoint.getElevationGain()) + "</opentracks:gain>");
if (trackPoint.hasAltitudeGain()) {
printWriter.println("<opentracks:gain>" + ALTITUDE_FORMAT.format(trackPoint.getAltitudeGain()) + "</opentracks:gain>");
}
if (trackPoint.hasElevationLoss()) {
printWriter.println("<opentracks:loss>" + ELEVATION_FORMAT.format(trackPoint.getElevationLoss()) + "</opentracks:loss>");
if (trackPoint.hasAltitudeLoss()) {
printWriter.println("<opentracks:loss>" + ALTITUDE_FORMAT.format(trackPoint.getAltitudeLoss()) + "</opentracks:loss>");
}
if (trackPoint.hasSensorDistance()) {
printWriter.println("<opentracks:distance>" + DISTANCE_FORMAT.format(trackPoint.getElevationLoss()) + "</opentracks:distance>");
printWriter.println("<opentracks:distance>" + DISTANCE_FORMAT.format(trackPoint.getAltitudeLoss()) + "</opentracks:distance>");
}
printWriter.println("</gpxtpx:TrackPointExtension></extensions>");
@@ -61,8 +61,8 @@ public class KMLTrackExporter implements TrackExporter {
public static final String EXTENDED_DATA_TYPE_CADENCE = "cadence";
public static final String EXTENDED_DATA_TYPE_HEART_RATE = "heart_rate";
public static final String EXTENDED_DATA_TYPE_POWER = "power";
public static final String EXTENDED_DATA_TYPE_ELEVATION_GAIN = "elevation_gain";
public static final String EXTENDED_DATA_TYPE_ELEVATION_LOSS = "elevation_loss";
public static final String EXTENDED_DATA_TYPE_ALTITUDE_GAIN = "elevation_gain";
public static final String EXTENDED_DATA_TYPE_ALTITUDE_LOSS = "elevation_loss";
private static final String MARKER_ICON = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
private static final String TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png";
@@ -79,8 +79,8 @@ public class KMLTrackExporter implements TrackExporter {
private final List<Float> powerList = new ArrayList<>();
private final List<Float> cadenceList = new ArrayList<>();
private final List<Float> heartRateList = new ArrayList<>();
private final List<Float> elevationGainList = new ArrayList<>();
private final List<Float> elevationLossList = new ArrayList<>();
private final List<Float> altitudeGainList = new ArrayList<>();
private final List<Float> altitudeLossList = new ArrayList<>();
@Deprecated // Figure out a better way to do this! (if needed)
private TrackPoint startTrackPoint;
@@ -344,8 +344,8 @@ public class KMLTrackExporter implements TrackExporter {
powerList.clear();
cadenceList.clear();
heartRateList.clear();
elevationGainList.clear();
elevationLossList.clear();
altitudeGainList.clear();
altitudeLossList.clear();
}
}
@@ -370,11 +370,11 @@ public class KMLTrackExporter implements TrackExporter {
if (heartRateList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(heartRateList, EXTENDED_DATA_TYPE_HEART_RATE);
}
if (elevationGainList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(elevationGainList, EXTENDED_DATA_TYPE_ELEVATION_GAIN);
if (altitudeGainList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(altitudeGainList, EXTENDED_DATA_TYPE_ALTITUDE_GAIN);
}
if (elevationLossList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(elevationLossList, EXTENDED_DATA_TYPE_ELEVATION_LOSS);
if (altitudeLossList.stream().anyMatch(Objects::nonNull)) {
writeSimpleArrayData(altitudeLossList, EXTENDED_DATA_TYPE_ALTITUDE_LOSS);
}
}
printWriter.println("</SchemaData>");
@@ -403,8 +403,8 @@ public class KMLTrackExporter implements TrackExporter {
cadenceList.add(trackPoint.hasCyclingCadence() ? trackPoint.getCyclingCadence_rpm() : null);
powerList.add(trackPoint.hasPower() ? trackPoint.getPower() : null);
elevationGainList.add(trackPoint.hasElevationGain() ? trackPoint.getElevationGain() : null);
elevationLossList.add(trackPoint.hasElevationLoss() ? trackPoint.getElevationLoss() : null);
altitudeGainList.add(trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : null);
altitudeLossList.add(trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : null);
}
}
}
@@ -491,16 +491,16 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
if (gain != null) {
try {
trackPoint.setElevationGain(Float.parseFloat(gain));
trackPoint.setAltitudeGain(Float.parseFloat(gain));
} catch (Exception e) {
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse elevation gain: %s", gain)), e);
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude gain: %s", gain)), e);
}
}
if (loss != null) {
try {
trackPoint.setElevationLoss(Float.parseFloat(loss));
trackPoint.setAltitudeLoss(Float.parseFloat(loss));
} catch (Exception e) {
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse elevation loss: %s", loss)), e);
throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude loss: %s", loss)), e);
}
}
if (distance != null) {
@@ -42,7 +42,7 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
private static final String TAG_DESCRIPTION = "desc";
private static final String TAG_COMMENT = "cmt";
private static final String TAG_ELEVATION = "ele";
private static final String TAG_ALTITUDE = "ele";
private static final String TAG_GPX = "gpx";
private static final String TAG_NAME = "name";
private static final String TAG_TIME = "time";
@@ -135,7 +135,7 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter {
time = content.trim();
}
break;
case TAG_ELEVATION:
case TAG_ALTITUDE:
if (content != null) {
altitude = content.trim();
}
@@ -70,8 +70,8 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
private final ArrayList<Float> cadenceList = new ArrayList<>();
private final ArrayList<Float> heartRateList = new ArrayList<>();
private final ArrayList<Float> powerList = new ArrayList<>();
private final ArrayList<Float> elevationGainList = new ArrayList<>();
private final ArrayList<Float> elevationLossList = new ArrayList<>();
private final ArrayList<Float> altitudeGainList = new ArrayList<>();
private final ArrayList<Float> altitudeLossList = new ArrayList<>();
public KmlFileTrackImporter(Context context) {
this(context, new ContentProviderUtils(context));
@@ -221,8 +221,8 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
heartRateList.clear();
cadenceList.clear();
powerList.clear();
elevationGainList.clear();
elevationLossList.clear();
altitudeGainList.clear();
altitudeLossList.clear();
}
protected void onTrackSegmentEnd() {
@@ -246,11 +246,11 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
if (i < powerList.size()) {
trackPoint.setPower(powerList.get(i));
}
if (i < elevationGainList.size()) {
trackPoint.setElevationGain(elevationGainList.get(i));
if (i < altitudeGainList.size()) {
trackPoint.setAltitudeGain(altitudeGainList.get(i));
}
if (i < elevationLossList.size()) {
trackPoint.setElevationLoss(elevationLossList.get(i));
if (i < altitudeLossList.size()) {
trackPoint.setAltitudeLoss(altitudeLossList.get(i));
}
insertTrackPoint(trackPoint);
@@ -327,11 +327,11 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
case KMLTrackExporter.EXTENDED_DATA_TYPE_CADENCE:
cadenceList.add(value);
break;
case KMLTrackExporter.EXTENDED_DATA_TYPE_ELEVATION_GAIN:
elevationGainList.add(value);
case KMLTrackExporter.EXTENDED_DATA_TYPE_ALTITUDE_GAIN:
altitudeGainList.add(value);
break;
case KMLTrackExporter.EXTENDED_DATA_TYPE_ELEVATION_LOSS:
elevationLossList.add(value);
case KMLTrackExporter.EXTENDED_DATA_TYPE_ALTITUDE_LOSS:
altitudeLossList.add(value);
break;
default:
Log.w(TAG, "Data from extended data " + extendedDataType + " is not (yet) supported.");
@@ -50,8 +50,8 @@ import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.io.file.exporter.ExportServiceResultReceiver;
import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
import de.dennisguse.opentracks.services.handlers.HandlerServer;
import de.dennisguse.opentracks.services.sensors.AltitudeSumManager;
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
import de.dennisguse.opentracks.services.sensors.ElevationSumManager;
import de.dennisguse.opentracks.services.tasks.AnnouncementPeriodicTaskFactory;
import de.dennisguse.opentracks.services.tasks.PeriodicTaskExecutor;
import de.dennisguse.opentracks.settings.SettingsActivity;
@@ -109,7 +109,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
// The following variables are set when recording:
private WakeLock wakeLock;
private BluetoothRemoteSensorManager remoteSensorManager;
private ElevationSumManager elevationSumManager;
private AltitudeSumManager altitudeSumManager;
private TrackStatisticsUpdater trackStatisticsUpdater;
private TrackPoint lastTrackPoint;
@@ -159,9 +159,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
remoteSensorManager = null;
}
if (elevationSumManager != null) {
elevationSumManager.stop(this);
elevationSumManager = null;
if (altitudeSumManager != null) {
altitudeSumManager.stop(this);
altitudeSumManager = null;
}
// Reverse order from onCreate
@@ -340,8 +340,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
remoteSensorManager = new BluetoothRemoteSensorManager(this);
remoteSensorManager.start();
elevationSumManager = new ElevationSumManager();
elevationSumManager.start(this);
altitudeSumManager = new AltitudeSumManager();
altitudeSumManager.start(this);
lastTrackPoint = null;
isIdle = false;
@@ -434,9 +434,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
remoteSensorManager.stop();
remoteSensorManager = null;
}
if (elevationSumManager != null) {
elevationSumManager.stop(this);
elevationSumManager = null;
if (altitudeSumManager != null) {
altitudeSumManager.stop(this);
altitudeSumManager = null;
}
lastTrackPoint = null;
@@ -592,10 +592,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
*/
private void insertTrackPoint(@NonNull Track track, @NonNull TrackPoint trackPoint) {
try {
if (elevationSumManager != null) {
trackPoint.setElevationGain(elevationSumManager.getElevationGain_m());
trackPoint.setElevationLoss(elevationSumManager.getElevationLoss_m());
elevationSumManager.reset();
if (altitudeSumManager != null) {
trackPoint.setAltitudeGain(altitudeSumManager.getAltitudeGain_m());
trackPoint.setAltitudeLoss(altitudeSumManager.getAltitudeLoss_m());
altitudeSumManager.reset();
}
if (remoteSensorManager != null) {
fillWithSensorDataSet(trackPoint);
@@ -632,25 +632,25 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
}
/**
* Returns the relative elevation gain (since last trackpoint).
* Returns the relative altitude gain (since last trackpoint).
*/
Float getElevationGain_m() {
if (elevationSumManager == null || !elevationSumManager.isConnected()) {
Float getAltitudeGain_m() {
if (altitudeSumManager == null || !altitudeSumManager.isConnected()) {
return null;
}
return elevationSumManager.getElevationGain_m();
return altitudeSumManager.getAltitudeGain_m();
}
/**
* Returns the relative elevation loss (since last trackpoint).
* Returns the relative altitude loss (since last trackpoint).
*/
Float getElevationLoss_m() {
if (elevationSumManager == null || !elevationSumManager.isConnected()) {
Float getAltitudeLoss_m() {
if (altitudeSumManager == null || !altitudeSumManager.isConnected()) {
return null;
}
return elevationSumManager.getElevationLoss_m();
return altitudeSumManager.getAltitudeLoss_m();
}
private void showNotification(boolean isGpsStarted) {
@@ -98,13 +98,13 @@ class TrackRecordingServiceBinder extends android.os.Binder implements TrackReco
}
@Override
public Float getElevationGain_m() {
return trackRecordingService.getElevationGain_m();
public Float getAltitudeGain_m() {
return trackRecordingService.getAltitudeGain_m();
}
@Override
public Float getElevationLoss_m() {
return trackRecordingService.getElevationLoss_m();
public Float getAltitudeLoss_m() {
return trackRecordingService.getAltitudeLoss_m();
}
@VisibleForTesting
@@ -74,18 +74,18 @@ public interface TrackRecordingServiceInterface {
SensorDataSet getSensorData();
/**
* Gets the current elevation gain.
* Gets the current altitude gain.
*
* @return elevation gain in m or null.
* @return altitude gain in m or null.
*/
Float getElevationGain_m();
Float getAltitudeGain_m();
/**
* Gets the current elevation loss.
* Gets the current altitude loss.
*
* @return elevation loss in m or null.
* @return altitude loss in m or null.
*/
Float getElevationLoss_m();
Float getAltitudeLoss_m();
@VisibleForTesting
void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager);
@@ -14,11 +14,11 @@ import de.dennisguse.opentracks.util.PressureSensorUtils;
import de.dennisguse.opentracks.util.UnitConversions;
/**
* Estimates the elevation gain and elevation loss using the device's pressure sensor (i.e., barometer).
* Estimates the altitude gain and altitude loss using the device's pressure sensor (i.e., barometer).
*/
public class ElevationSumManager implements SensorEventListener {
public class AltitudeSumManager implements SensorEventListener {
private static final String TAG = ElevationSumManager.class.getSimpleName();
private static final String TAG = AltitudeSumManager.class.getSimpleName();
private static final int SAMPLING_RATE = 3 * (int) UnitConversions.ONE_SECOND_US;
@@ -28,8 +28,8 @@ public class ElevationSumManager implements SensorEventListener {
private float lastSeenSensorValue_hPa;
private float elevationGain_m;
private float elevationLoss_m;
private float altitudeGain_m;
private float altitudeLoss_m;
public void start(Context context) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
@@ -66,19 +66,19 @@ public class ElevationSumManager implements SensorEventListener {
}
public @Nullable
Float getElevationGain_m() {
return isConnected ? elevationGain_m : null;
Float getAltitudeGain_m() {
return isConnected ? altitudeGain_m : null;
}
public @Nullable
Float getElevationLoss_m() {
return isConnected ? elevationLoss_m : null;
Float getAltitudeLoss_m() {
return isConnected ? altitudeLoss_m : null;
}
public void reset() {
Log.d(TAG, "Reset");
elevationGain_m = 0;
elevationLoss_m = 0;
altitudeGain_m = 0;
altitudeLoss_m = 0;
}
@Override
@@ -103,15 +103,15 @@ public class ElevationSumManager implements SensorEventListener {
return;
}
PressureSensorUtils.ElevationChange elevationChange = PressureSensorUtils.computeChangesWithSmoothing_m(lastAcceptedPressureValue_hPa, lastSeenSensorValue_hPa, value_hPa);
if (elevationChange != null) {
elevationGain_m += elevationChange.getElevationGain_m();
elevationLoss_m += elevationChange.getElevationLoss_m();
lastAcceptedPressureValue_hPa = elevationChange.getCurrentSensorValue_hPa();
PressureSensorUtils.AltitudeChange altitudeChange = PressureSensorUtils.computeChangesWithSmoothing_m(lastAcceptedPressureValue_hPa, lastSeenSensorValue_hPa, value_hPa);
if (altitudeChange != null) {
altitudeGain_m += altitudeChange.getAltitudeGain_m();
altitudeLoss_m += altitudeChange.getAltitudeLoss_m();
lastAcceptedPressureValue_hPa = altitudeChange.getCurrentSensorValue_hPa();
}
lastSeenSensorValue_hPa = value_hPa;
Log.v(TAG, "elevation gain: " + elevationGain_m + ", elevation loss: " + elevationLoss_m);
Log.v(TAG, "altitude gain: " + altitudeGain_m + ", altitude loss: " + altitudeLoss_m);
}
}
@@ -32,8 +32,8 @@ import java.time.Instant;
//TODO Check that data ranges are valid (not less than zero etc.)
public class TrackStatistics {
// The min and max elevation (meters) seen on this track.
private final ExtremityMonitor elevationExtremities = new ExtremityMonitor();
// The min and max altitude (meters) seen on this track.
private final ExtremityMonitor altitudeExtremities = new ExtremityMonitor();
// The track start time.
private Instant startTime;
@@ -47,10 +47,8 @@ public class TrackStatistics {
private Duration movingTime;
// The maximum speed (meters/second) that we believe is valid.
private double maxSpeed_mps;
// The total elevation gained (meters).
private Float totalElevationGain_m = null;
// The total elevation lost (meters).
private Float totalElevationLoss_m = null;
private Float totalAltitudeGain_m = null;
private Float totalAltitudeLoss_m = null;
public TrackStatistics() {
reset();
@@ -68,9 +66,9 @@ public class TrackStatistics {
totalTime = other.totalTime;
movingTime = other.movingTime;
maxSpeed_mps = other.maxSpeed_mps;
elevationExtremities.set(other.elevationExtremities.getMin(), other.elevationExtremities.getMax());
totalElevationGain_m = other.totalElevationGain_m;
totalElevationLoss_m = other.totalElevationLoss_m;
altitudeExtremities.set(other.altitudeExtremities.getMin(), other.altitudeExtremities.getMax());
totalAltitudeGain_m = other.totalAltitudeGain_m;
totalAltitudeLoss_m = other.totalAltitudeLoss_m;
}
/**
@@ -95,26 +93,26 @@ public class TrackStatistics {
totalTime = totalTime.plus(other.totalTime);
movingTime = movingTime.plus(other.movingTime);
maxSpeed_mps = Math.max(maxSpeed_mps, other.maxSpeed_mps);
if (other.elevationExtremities.hasData()) {
elevationExtremities.update(other.elevationExtremities.getMin());
elevationExtremities.update(other.elevationExtremities.getMax());
if (other.altitudeExtremities.hasData()) {
altitudeExtremities.update(other.altitudeExtremities.getMin());
altitudeExtremities.update(other.altitudeExtremities.getMax());
}
if (totalElevationGain_m == null) {
if (other.totalElevationGain_m != null) {
totalElevationGain_m = other.totalElevationGain_m;
if (totalAltitudeGain_m == null) {
if (other.totalAltitudeGain_m != null) {
totalAltitudeGain_m = other.totalAltitudeGain_m;
}
} else {
if (other.totalElevationGain_m != null) {
totalElevationGain_m += other.totalElevationGain_m;
if (other.totalAltitudeGain_m != null) {
totalAltitudeGain_m += other.totalAltitudeGain_m;
}
}
if (totalElevationLoss_m == null) {
if (other.totalElevationLoss_m != null) {
totalElevationLoss_m = other.totalElevationLoss_m;
if (totalAltitudeLoss_m == null) {
if (other.totalAltitudeLoss_m != null) {
totalAltitudeLoss_m = other.totalAltitudeLoss_m;
}
} else {
if (other.totalElevationLoss_m != null) {
totalElevationLoss_m += other.totalElevationLoss_m;
if (other.totalAltitudeLoss_m != null) {
totalAltitudeLoss_m += other.totalAltitudeLoss_m;
}
}
}
@@ -127,8 +125,8 @@ public class TrackStatistics {
setTotalTime(Duration.ofSeconds(0));
setMovingTime(Duration.ofSeconds(0));
setMaxSpeed(0);
setTotalElevationGain(null);
setTotalElevationLoss(null);
setTotalAltitudeGain(null);
setTotalAltitudeLoss(null);
}
public void reset(Instant startTime) {
@@ -224,104 +222,80 @@ public class TrackStatistics {
return Math.max(maxSpeed_mps, getAverageMovingSpeed());
}
/**
* Sets the maximum speed.
*
* @param maxSpeed the maximum speed in meters/second
*/
public void setMaxSpeed(double maxSpeed) {
this.maxSpeed_mps = maxSpeed;
public void setMaxSpeed(double maxSpeed_mps) {
this.maxSpeed_mps = maxSpeed_mps;
}
public boolean hasElevationMin() {
return !Double.isInfinite(getMinElevation());
public boolean hasAltitudeMin() {
return !Double.isInfinite(getMinAltitude());
}
public double getMinAltitude() {
return altitudeExtremities.getMin();
}
public void setMinAltitude(double altitude_m) {
altitudeExtremities.setMin(altitude_m);
}
public boolean hasAltitudeMax() {
return !Double.isInfinite(getMaxAltitude());
}
/**
* Gets the minimum elevation.
* This is calculated from the smoothed elevation, so this can actually be more than the current elevation.
* Gets the maximum altitude.
* This is calculated from the smoothed altitude, so this can actually be less than the current altitude.
*/
public double getMinElevation() {
return elevationExtremities.getMin();
public double getMaxAltitude() {
return altitudeExtremities.getMax();
}
/**
* Sets the minimum elevation.
*
* @param elevation the minimum elevation in meters
*/
public void setMinElevation(double elevation) {
elevationExtremities.setMin(elevation);
public void setMaxAltitude(double altitude_m) {
altitudeExtremities.setMax(altitude_m);
}
public boolean hasElevationMax() {
return !Double.isInfinite(getMaxElevation());
public void updateAltitudeExtremities(double altitude_m) {
altitudeExtremities.update(altitude_m);
}
/**
* Gets the maximum elevation.
* This is calculated from the smoothed elevation, so this can actually be less than the current elevation.
*/
public double getMaxElevation() {
return elevationExtremities.getMax();
}
/**
* Sets the maximum elevation.
*
* @param elevation_m the maximum elevation in meters
*/
public void setMaxElevation(double elevation_m) {
elevationExtremities.setMax(elevation_m);
}
/**
* Updates a new elevation.
*
* @param elevation_m the elevation value in meters
*/
public void updateElevationExtremities(double elevation_m) {
elevationExtremities.update(elevation_m);
}
public boolean hasTotalElevationGain() {
return totalElevationGain_m != null;
public boolean hasTotalAltitudeGain() {
return totalAltitudeGain_m != null;
}
@Nullable
public Float getTotalElevationGain() {
return totalElevationGain_m;
public Float getTotalAltitudeGain() {
return totalAltitudeGain_m;
}
public void setTotalElevationGain(Float totalElevationGain_m) {
this.totalElevationGain_m = totalElevationGain_m;
public void setTotalAltitudeGain(Float totalAltitudeGain_m) {
this.totalAltitudeGain_m = totalAltitudeGain_m;
}
public void addTotalElevationGain(float gain_m) {
if (totalElevationGain_m == null) {
totalElevationGain_m = 0f;
public void addTotalAltitudeGain(float gain_m) {
if (totalAltitudeGain_m == null) {
totalAltitudeGain_m = 0f;
}
totalElevationGain_m += gain_m;
totalAltitudeGain_m += gain_m;
}
public boolean hasTotalElevationLoss() {
return totalElevationLoss_m != null;
public boolean hasTotalAltitudeLoss() {
return totalAltitudeLoss_m != null;
}
@Nullable
public Float getTotalElevationLoss() {
return totalElevationLoss_m;
public Float getTotalAltitudeLoss() {
return totalAltitudeLoss_m;
}
public void setTotalElevationLoss(Float totalElevationLoss_m) {
this.totalElevationLoss_m = totalElevationLoss_m;
public void setTotalAltitudeLoss(Float totalAltitudeLoss_m) {
this.totalAltitudeLoss_m = totalAltitudeLoss_m;
}
public void addTotalElevationLoss(float loss_m) {
if (totalElevationLoss_m == null) {
totalElevationLoss_m = 0f;
public void addTotalAltitudeLoss(float loss_m) {
if (totalAltitudeLoss_m == null) {
totalAltitudeLoss_m = 0f;
}
totalElevationLoss_m += loss_m;
totalAltitudeLoss_m += loss_m;
}
@NonNull
@@ -330,8 +304,8 @@ public class TrackStatistics {
return "TrackStatistics { Start Time: " + getStartTime() + "; Stop Time: " + getStopTime()
+ "; Total Distance: " + getTotalDistance() + "; Total Time: " + getTotalTime()
+ "; Moving Time: " + getMovingTime() + "; Max Speed: " + getMaxSpeed()
+ "; Min Elevation: " + getMinElevation() + "; Max Elevation: " + getMaxElevation()
+ "; Elevation Gain: " + getTotalElevationGain()
+ "; Elevation Loss: " + getTotalElevationLoss() + "}";
+ "; Min Altitude: " + getMinAltitude() + "; Max Altitude: " + getMaxAltitude()
+ "; Altitude Gain: " + getTotalAltitudeGain()
+ "; Altitude Loss: " + getTotalAltitudeLoss() + "}";
}
}
@@ -38,10 +38,10 @@ import de.dennisguse.opentracks.content.provider.TrackPointIterator;
public class TrackStatisticsUpdater {
/**
* The number of elevation readings to smooth to get a somewhat accurate signal.
* The number of altitude readings to smooth to get a somewhat accurate signal.
*/
@VisibleForTesting
private static final int ELEVATION_SMOOTHING_FACTOR = 25;
private static final int ALTITUDE_SMOOTHING_FACTOR = 25;
/**
* The number of speed reading to smooth to get a somewhat accurate signal.
@@ -60,13 +60,10 @@ public class TrackStatisticsUpdater {
private boolean trackInitialized = false;
private boolean segmentInitialized = false;
// The track's statistics
private final TrackStatistics trackStatistics;
// A buffer of the recent elevation readings (m)
private final DoubleRingBuffer elevationBuffer_m = new DoubleRingBuffer(ELEVATION_SMOOTHING_FACTOR);
// A buffer of the recent speed readings (m/s) for calculating max speed
private final DoubleRingBuffer speedBuffer_ms = new DoubleRingBuffer(SPEED_SMOOTHING_FACTOR);
private final DoubleRingBuffer altitudeBuffer_m = new DoubleRingBuffer(ALTITUDE_SMOOTHING_FACTOR);
private final DoubleRingBuffer speedBuffer_mps = new DoubleRingBuffer(SPEED_SMOOTHING_FACTOR);
// The current segment's statistics
private final TrackStatistics currentSegment = new TrackStatistics();
@@ -131,12 +128,12 @@ public class TrackStatisticsUpdater {
}
// Process sensor data
if (trackPoint.hasElevationGain()) {
currentSegment.addTotalElevationGain(trackPoint.getElevationGain());
if (trackPoint.hasAltitudeGain()) {
currentSegment.addTotalAltitudeGain(trackPoint.getAltitudeGain());
}
if (trackPoint.hasElevationLoss()) {
currentSegment.addTotalElevationLoss(trackPoint.getElevationLoss());
if (trackPoint.hasAltitudeLoss()) {
currentSegment.addTotalAltitudeLoss(trackPoint.getAltitudeLoss());
}
if (trackPoint.hasSensorDistance()) {
@@ -148,9 +145,9 @@ public class TrackStatisticsUpdater {
return;
}
//Update absolute (GPS-based) elevation
//Update absolute (GPS-based) altitude
if (trackPoint.hasAltitude()) {
updateAbsoluteElevation(trackPoint.getAltitude());
updateAbsoluteAltitude(trackPoint.getAltitude());
}
if (lastTrackPoint == null || lastMovingTrackPoint == null) {
@@ -163,7 +160,7 @@ public class TrackStatisticsUpdater {
// GPS-based distance/speed
float movingDistance = lastMovingTrackPoint.distanceToPrevious(trackPoint);
if (movingDistance < minGPSDistance && !trackPoint.isMoving()) {
speedBuffer_ms.reset();
speedBuffer_mps.reset();
lastTrackPoint = trackPoint;
return;
}
@@ -195,8 +192,8 @@ public class TrackStatisticsUpdater {
lastTrackPoint = null;
lastMovingTrackPoint = null;
elevationBuffer_m.reset();
speedBuffer_ms.reset();
altitudeBuffer_m.reset();
speedBuffer_mps.reset();
}
public void addTrackPoint(TrackPointIterator iterator, int minRecordingDistance) {
@@ -207,15 +204,15 @@ public class TrackStatisticsUpdater {
}
/**
* Gets the smoothed elevation over several readings.
* The elevation readings is noisy so the smoothed elevation is better than the raw elevation for many tasks.
* Gets the smoothed altitude over several readings.
* The altitude readings is noisy so the smoothed altitude is better than the raw altitude for many tasks.
*/
public double getSmoothedElevation() {
return elevationBuffer_m.getAverage();
public double getSmoothedAltitude() {
return altitudeBuffer_m.getAverage();
}
public double getSmoothedSpeed() {
return speedBuffer_ms.getAverage();
return speedBuffer_mps.getAverage();
}
/**
@@ -224,27 +221,24 @@ public class TrackStatisticsUpdater {
@VisibleForTesting
private void updateSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
if (!trackPoint.isMoving()) {
speedBuffer_ms.reset();
speedBuffer_mps.reset();
} else if (isValidSpeed(trackPoint, lastTrackPoint)) {
speedBuffer_ms.setNext(trackPoint.getSpeed());
if (speedBuffer_ms.getAverage() > currentSegment.getMaxSpeed()) {
currentSegment.setMaxSpeed(speedBuffer_ms.getAverage());
speedBuffer_mps.setNext(trackPoint.getSpeed());
if (speedBuffer_mps.getAverage() > currentSegment.getMaxSpeed()) {
currentSegment.setMaxSpeed(speedBuffer_mps.getAverage());
}
} else {
Log.d(TAG, "Invalid speed. speed: " + trackPoint.getSpeed() + " lastLocationSpeed: " + lastTrackPoint.getSpeed());
}
}
/**
* Updates an elevation reading.
*/
private void updateAbsoluteElevation(double elevation) {
// Update elevation using the smoothed average
double oldAverage = elevationBuffer_m.getAverage();
elevationBuffer_m.setNext(elevation);
double newAverage = elevationBuffer_m.getAverage();
private void updateAbsoluteAltitude(double altitude) {
// Update altitude using the smoothed average
double oldAverage = altitudeBuffer_m.getAverage();
altitudeBuffer_m.setNext(altitude);
double newAverage = altitudeBuffer_m.getAverage();
currentSegment.updateElevationExtremities(newAverage);
currentSegment.updateAltitudeExtremities(newAverage);
}
private boolean isValidSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
@@ -266,8 +260,8 @@ public class TrackStatisticsUpdater {
}
// Only check if the speed buffer is full. Check that the speed is less than 10X the smoothed average and the speed difference doesn't imply 2g acceleration.
if (speedBuffer_ms.isFull()) {
double average = speedBuffer_ms.getAverage();
if (speedBuffer_mps.isFull()) {
double average = speedBuffer_mps.getAverage();
double diff = Math.abs(average - trackPoint.getSpeed());
return (trackPoint.getSpeed() < average * 10) && (diff < MAX_ACCELERATION * timeDifference.toMillis());
}
@@ -165,9 +165,9 @@ public class PreferencesUtils {
return getBoolean(sharedPreferences, context, R.string.stats_fullscreen_while_recording_key, DEFAULT);
}
public static boolean isShowStatsElevation(SharedPreferences sharedPreferences, Context context) {
final boolean STATS_SHOW_ELEVATION = context.getResources().getBoolean(R.bool.stats_show_elevation_default);
return getBoolean(sharedPreferences, context, R.string.stats_show_grade_elevation_key, STATS_SHOW_ELEVATION);
public static boolean isShowStatsAltitude(SharedPreferences sharedPreferences, Context context) {
final boolean STATS_SHOW_ALTITUDE = context.getResources().getBoolean(R.bool.stats_show_altitude_default);
return getBoolean(sharedPreferences, context, R.string.stats_show_grade_altitude_key, STATS_SHOW_ALTITUDE);
}
public static boolean isStatsShowCoordinate(SharedPreferences sharedPreferences, Context context) {
@@ -4,76 +4,76 @@ import android.hardware.SensorManager;
public class PressureSensorUtils {
//Everything above is considered a meaningful change in elevation.
private static final float ELEVATION_CHANGE_DIFF_M = 3.0f;
//Everything above is considered a meaningful change in altitude.
private static final float ALTITUDE_CHANGE_DIFF_M = 3.0f;
private static final float EXPONENTIAL_SMOOTHING = 0.3f;
private PressureSensorUtils() {
}
public static class ElevationChange {
public static class AltitudeChange {
private final float currentSensorValue_hPa;
private final float elevationChange_m;
private final float altitudeChange_m;
public ElevationChange(float currentSensorValue_hPa, float elevationChange_m) {
public AltitudeChange(float currentSensorValue_hPa, float altitudeChange_m) {
this.currentSensorValue_hPa = currentSensorValue_hPa;
this.elevationChange_m = elevationChange_m;
this.altitudeChange_m = altitudeChange_m;
}
public float getCurrentSensorValue_hPa() {
return currentSensorValue_hPa;
}
public float getElevationChange_m() {
return elevationChange_m;
public float getAltitudeChange_m() {
return altitudeChange_m;
}
public float getElevationGain_m() {
return elevationChange_m > 0 ? elevationChange_m : 0;
public float getAltitudeGain_m() {
return altitudeChange_m > 0 ? altitudeChange_m : 0;
}
public float getElevationLoss_m() {
return elevationChange_m < 0 ? -1 * elevationChange_m : 0;
public float getAltitudeLoss_m() {
return altitudeChange_m < 0 ? -1 * altitudeChange_m : 0;
}
}
/**
* Applies exponential smoothing to sensor value before computation.
*/
public static ElevationChange computeChangesWithSmoothing_m(float lastAcceptedSensorValue_hPa, float lastSeenSensorValue_hPa, float currentSensorValue_hPa) {
public static AltitudeChange computeChangesWithSmoothing_m(float lastAcceptedSensorValue_hPa, float lastSeenSensorValue_hPa, float currentSensorValue_hPa) {
float nextSensorValue_hPa = EXPONENTIAL_SMOOTHING * currentSensorValue_hPa + (1 - EXPONENTIAL_SMOOTHING) * lastSeenSensorValue_hPa;
return computeChanges_m(lastAcceptedSensorValue_hPa, nextSensorValue_hPa);
}
/**
* Computes the elevation gain and elevation loss.
* Computes the altitude gain and altitude loss.
*
* @return null if no meaningful elevation change occurred.
* @return null if no meaningful altitudeC change occurred.
*/
public static ElevationChange computeChanges_m(float lastAcceptedSensorValue_hPa, float currentSensorValue_hPa) {
public static AltitudeChange computeChanges_m(float lastAcceptedSensorValue_hPa, float currentSensorValue_hPa) {
float lastSensorValue_m = SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastAcceptedSensorValue_hPa);
float currentSensorValue_m = SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, currentSensorValue_hPa);
float elevationChange_m = currentSensorValue_m - lastSensorValue_m;
if (Math.abs(elevationChange_m) < ELEVATION_CHANGE_DIFF_M) {
float altitudeChange_m = currentSensorValue_m - lastSensorValue_m;
if (Math.abs(altitudeChange_m) < ALTITUDE_CHANGE_DIFF_M) {
return null;
}
// Limit elevation change by ELEVATION_CHANGE_DIFF and computes pressure value accordingly.
ElevationChange elevationChange = new ElevationChange(currentSensorValue_hPa, elevationChange_m);
if (elevationChange.getElevationChange_m() > 0) {
return new ElevationChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m + ELEVATION_CHANGE_DIFF_M), ELEVATION_CHANGE_DIFF_M);
// Limit altitudeC change by ALTITUDE_CHANGE_DIFF and computes pressure value accordingly.
AltitudeChange altitudeChange = new AltitudeChange(currentSensorValue_hPa, altitudeChange_m);
if (altitudeChange.getAltitudeChange_m() > 0) {
return new AltitudeChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m + ALTITUDE_CHANGE_DIFF_M), ALTITUDE_CHANGE_DIFF_M);
} else {
return new ElevationChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m - ELEVATION_CHANGE_DIFF_M), -1 * ELEVATION_CHANGE_DIFF_M);
return new AltitudeChange(getBarometricPressure(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, lastSensorValue_m - ALTITUDE_CHANGE_DIFF_M), -1 * ALTITUDE_CHANGE_DIFF_M);
}
}
/*
* Barometeric pressure to elevation estimation; inverts of SensorManager.getAltitude(float, float)
* Barometeric pressure to altitude estimation; inverts of SensorManager.getAltitude(float, float)
* https://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Internationale_H%C3%B6henformel
* {\color{White} p(h)} = p_0 \cdot \left( 1 - \frac{0{,}0065 \frac{\mathrm K}{\mathrm m} \cdot h}{T_0\ } \right)^{5{,}255}
*/
@@ -320,21 +320,16 @@ public class StringUtils {
}
/**
* Sets an elevation_m value.
*
* @param context the context
* @param elevation_m the elevation_m
* @param metricUnits true if metric units
* @return the formatted elevation_m (or null) and it's unit as {@link Pair}
* @return the formatted altitude_m (or null) and it's unit as {@link Pair}
*/
public static Pair<String, String> formatElevation(Context context, Float elevation_m, boolean metricUnits) {
public static Pair<String, String> formatAltitude(Context context, Float altitude_m, boolean metricUnits) {
String value = context.getString(R.string.value_unknown);
String unit = context.getString(metricUnits ? R.string.unit_meter : R.string.unit_feet);
if (elevation_m != null) {
if (altitude_m != null) {
if (!metricUnits) {
elevation_m *= (float) UnitConversions.M_TO_FT;
altitude_m *= (float) UnitConversions.M_TO_FT;
}
value = StringUtils.formatDecimal(elevation_m, 0);
value = StringUtils.formatDecimal(altitude_m, 0);
}
return new Pair<>(value, unit);
}
@@ -26,8 +26,8 @@ public class IntervalStatistics {
}
Interval interval = new Interval();
interval.gain_m += trackPoints.get(0).hasElevationGain() ? trackPoints.get(0).getElevationGain() : 0;
interval.loss_m += trackPoints.get(0).hasElevationLoss() ? trackPoints.get(0).getElevationLoss() : 0;
interval.gain_m += trackPoints.get(0).hasAltitudeGain() ? trackPoints.get(0).getAltitudeGain() : 0;
interval.loss_m += trackPoints.get(0).hasAltitudeLoss() ? trackPoints.get(0).getAltitudeLoss() : 0;
for (int i = 1; i < trackPoints.size(); i++) {
TrackPoint prevTrackPoint = trackPoints.get(i - 1);
TrackPoint trackPoint = trackPoints.get(i);
@@ -35,8 +35,8 @@ public class IntervalStatistics {
if (trackPoint.hasLocation() && prevTrackPoint.hasLocation()) {
interval.distance_m += prevTrackPoint.distanceToPrevious(trackPoint);
interval.time = interval.time.plus(Duration.between(prevTrackPoint.getTime(), trackPoint.getTime()));
interval.gain_m += trackPoint.hasElevationGain() ? trackPoint.getElevationGain() : 0;
interval.loss_m += trackPoint.hasElevationLoss() ? trackPoint.getElevationLoss() : 0;
interval.gain_m += trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : 0;
interval.loss_m += trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : 0;
if (interval.distance_m >= distanceInterval_m) {
float adjustFactor = distanceInterval_m / interval.distance_m;