Elevation now visible in statistics sheet - works for new tracks only (see #28)
This commit is contained in:
parent
ed0d53e336
commit
03d5513df6
13 changed files with 514 additions and 50 deletions
|
@ -27,6 +27,7 @@ import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.constraint.ConstraintLayout;
|
import android.support.constraint.ConstraintLayout;
|
||||||
|
import android.support.constraint.Group;
|
||||||
import android.support.design.widget.BottomSheetBehavior;
|
import android.support.design.widget.BottomSheetBehavior;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
@ -41,6 +42,7 @@ import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.osmdroid.api.IMapController;
|
import org.osmdroid.api.IMapController;
|
||||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
||||||
|
@ -89,6 +91,11 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
||||||
private TextView mDurationView;
|
private TextView mDurationView;
|
||||||
private TextView mRecordingStartView;
|
private TextView mRecordingStartView;
|
||||||
private TextView mRecordingStopView;
|
private TextView mRecordingStopView;
|
||||||
|
private TextView mMaxAltitudeView;
|
||||||
|
private TextView mMinAltitudeView;
|
||||||
|
private TextView mPositiveElevationView;
|
||||||
|
private TextView mNegativeElevationView;
|
||||||
|
private Group mElevationDataViews;
|
||||||
private BottomSheetBehavior mStatisticsSheetBehavior;
|
private BottomSheetBehavior mStatisticsSheetBehavior;
|
||||||
private int mCurrentTrack;
|
private int mCurrentTrack;
|
||||||
private Track mTrack;
|
private Track mTrack;
|
||||||
|
@ -204,6 +211,14 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
||||||
mDurationView = (TextView) mRootView.findViewById(R.id.statistics_data_duration);
|
mDurationView = (TextView) mRootView.findViewById(R.id.statistics_data_duration);
|
||||||
mRecordingStartView = (TextView) mRootView.findViewById(R.id.statistics_data_recording_start);
|
mRecordingStartView = (TextView) mRootView.findViewById(R.id.statistics_data_recording_start);
|
||||||
mRecordingStopView = (TextView) mRootView.findViewById(R.id.statistics_data_recording_stop);
|
mRecordingStopView = (TextView) mRootView.findViewById(R.id.statistics_data_recording_stop);
|
||||||
|
mMaxAltitudeView = (TextView) mRootView.findViewById(R.id.statistics_data_max_altitude);
|
||||||
|
mMinAltitudeView = (TextView) mRootView.findViewById(R.id.statistics_data_min_altitude);
|
||||||
|
mPositiveElevationView = (TextView) mRootView.findViewById(R.id.statistics_data_positive_elevation);
|
||||||
|
mNegativeElevationView = (TextView) mRootView.findViewById(R.id.statistics_data_negative_elevation);
|
||||||
|
mElevationDataViews = (Group) mRootView.findViewById(R.id.elevation_data);
|
||||||
|
|
||||||
|
// attach listners for taps on elevation views
|
||||||
|
attachTapListeners();
|
||||||
|
|
||||||
// display map and statistics
|
// display map and statistics
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
|
@ -359,9 +374,23 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
||||||
mDurationView.setText(mTrack.getTrackDurationString());
|
mDurationView.setText(mTrack.getTrackDurationString());
|
||||||
mRecordingStartView.setText(recordingStart);
|
mRecordingStartView.setText(recordingStart);
|
||||||
mRecordingStopView.setText(recordingStop);
|
mRecordingStopView.setText(recordingStop);
|
||||||
|
mPositiveElevationView.setText(mTrack.getPositiveElevationString());
|
||||||
|
mNegativeElevationView.setText(mTrack.getNegativeElevationString());
|
||||||
|
mMaxAltitudeView.setText(mTrack.getMaxAltitudeString());
|
||||||
|
mMinAltitudeView.setText(mTrack.getMinAltitudeString());
|
||||||
|
|
||||||
|
// show/hide elevation views depending on file format version
|
||||||
|
if (mTrack.getTrackFormatVersion() > 1 || mTrack.getMinAltitude() > 0) {
|
||||||
|
// show elevation views
|
||||||
|
mElevationDataViews.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
// hide elevation views
|
||||||
|
mElevationDataViews.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
// draw track on map
|
// draw track on map
|
||||||
drawTrackOverlay(mTrack);
|
drawTrackOverlay(mTrack);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
position = new GeoPoint(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
position = new GeoPoint(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
||||||
}
|
}
|
||||||
|
@ -531,6 +560,21 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add tap listners to elevation data views */
|
||||||
|
private void attachTapListeners() {
|
||||||
|
int referencedIds[] = mElevationDataViews.getReferencedIds();
|
||||||
|
for (int id : referencedIds) {
|
||||||
|
mRootView.findViewById(id).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
// inform user about possible issues with altitude measurements
|
||||||
|
Toast.makeText(mActivity, R.string.toast_message_elevation_info, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class: Loads track from external storage using AsyncTask
|
* Inner class: Loads track from external storage using AsyncTask
|
||||||
*/
|
*/
|
||||||
|
@ -559,10 +603,6 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
||||||
protected void onPostExecute(Void aVoid) {
|
protected void onPostExecute(Void aVoid) {
|
||||||
super.onPostExecute(aVoid);
|
super.onPostExecute(aVoid);
|
||||||
|
|
||||||
// todo remove
|
|
||||||
StorageHelper storageHelper = new StorageHelper(mActivity);
|
|
||||||
storageHelper.calculateTrackElevation(mTrack);
|
|
||||||
|
|
||||||
// display track on map
|
// display track on map
|
||||||
displayTrack();
|
displayTrack();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,32 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
private float mStepCount;
|
private float mStepCount;
|
||||||
private final Date mRecordingStart;
|
private final Date mRecordingStart;
|
||||||
private Date mRecordingStop;
|
private Date mRecordingStop;
|
||||||
|
private double mMaxAltitude;
|
||||||
|
private double mMinAltitude;
|
||||||
|
private double mPositiveElevation;
|
||||||
|
private double mNegativeElevation;
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic Constructor */
|
||||||
|
public Track(int trackFormatVersion, List<WayPoint> wayPoints, float trackLength, long duration, float stepCount, Date recordingStart, Date recordingStop, double maxAltitude, double minAltitude, double positiveElevation, double negativeElevation) {
|
||||||
|
mTrackFormatVersion = trackFormatVersion;
|
||||||
|
mWayPoints = wayPoints;
|
||||||
|
mTrackLength = trackLength;
|
||||||
|
mDuration = duration;
|
||||||
|
mStepCount = stepCount;
|
||||||
|
mRecordingStart = recordingStart;
|
||||||
|
mRecordingStop = recordingStop;
|
||||||
|
mMaxAltitude = maxAltitude;
|
||||||
|
mMinAltitude = minAltitude;
|
||||||
|
mPositiveElevation = positiveElevation;
|
||||||
|
mNegativeElevation = negativeElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy Constructor */
|
||||||
|
public Track(Track track) {
|
||||||
|
this(track.getTrackFormatVersion(), track.getWayPoints(), track.getTrackLength(), track.getTrackDuration(), track.getStepCount(), track.getRecordingStart(), track.getRecordingStop(), track.getMaxAltitude(), track.getMinAltitude(), track.getPositiveElevation(), track.getNegativeElevation());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
|
@ -60,6 +86,10 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
mStepCount = 0f;
|
mStepCount = 0f;
|
||||||
mRecordingStart = GregorianCalendar.getInstance().getTime();
|
mRecordingStart = GregorianCalendar.getInstance().getTime();
|
||||||
mRecordingStop = mRecordingStart;
|
mRecordingStop = mRecordingStart;
|
||||||
|
mMaxAltitude = 0f;
|
||||||
|
mMinAltitude = 0f;
|
||||||
|
mPositiveElevation = 0f;
|
||||||
|
mNegativeElevation = 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +102,10 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
mStepCount = in.readFloat();
|
mStepCount = in.readFloat();
|
||||||
mRecordingStart = new Date(in.readLong());
|
mRecordingStart = new Date(in.readLong());
|
||||||
mRecordingStop = new Date(in.readLong());
|
mRecordingStop = new Date(in.readLong());
|
||||||
|
mMaxAltitude = in.readDouble();
|
||||||
|
mMinAltitude = in.readDouble();
|
||||||
|
mPositiveElevation = in.readDouble();
|
||||||
|
mNegativeElevation = in.readDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,6 +170,36 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for maximum altitude of recording */
|
||||||
|
public void setMaxAltitude(double maxAltitude) {
|
||||||
|
mMaxAltitude = maxAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for lowest altitude of recording */
|
||||||
|
public void setMinAltitude(double minAltitude) {
|
||||||
|
mMinAltitude = minAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for positive elevation of recording (cumulative altitude difference) */
|
||||||
|
public void setPositiveElevation(double positiveElevation) {
|
||||||
|
mPositiveElevation = positiveElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for negative elevation of recording (cumulative altitude difference) */
|
||||||
|
public void setNegativeElevation(double megativeElevation) {
|
||||||
|
mNegativeElevation = megativeElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for file/track fornat version */
|
||||||
|
public int getTrackFormatVersion() {
|
||||||
|
return mTrackFormatVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for mWayPoints */
|
/* Getter for mWayPoints */
|
||||||
public List<WayPoint> getWayPoints() {
|
public List<WayPoint> getWayPoints() {
|
||||||
return mWayPoints;
|
return mWayPoints;
|
||||||
|
@ -148,6 +212,12 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for track length */
|
||||||
|
public float getTrackLength() {
|
||||||
|
return mTrackLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for duration of track */
|
/* Getter for duration of track */
|
||||||
public long getTrackDuration() {
|
public long getTrackDuration() {
|
||||||
return mDuration;
|
return mDuration;
|
||||||
|
@ -171,26 +241,64 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for maximum altitude of recording */
|
||||||
|
public double getMaxAltitude() {
|
||||||
|
return mMaxAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for lowest altitude of recording */
|
||||||
|
public double getMinAltitude() {
|
||||||
|
return mMinAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for positive elevation of recording (cumulative altitude difference) */
|
||||||
|
public double getPositiveElevation() {
|
||||||
|
return mPositiveElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for negative elevation of recording (cumulative altitude difference) */
|
||||||
|
public double getNegativeElevation() {
|
||||||
|
return mNegativeElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for string representation of maximum altitude of recording */
|
||||||
|
public String getMaxAltitudeString() {
|
||||||
|
return convertDistanceToString(mMaxAltitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for string representation of lowest altitude of recording */
|
||||||
|
public String getMinAltitudeString() {
|
||||||
|
return convertDistanceToString(mMinAltitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for string representation of positive elevation of recording (cumulative altitude difference) */
|
||||||
|
public String getPositiveElevationString() {
|
||||||
|
return convertDistanceToString(mPositiveElevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for string representation of negative elevation of recording (cumulative altitude difference) */
|
||||||
|
public String getNegativeElevationString() {
|
||||||
|
return convertDistanceToString(mNegativeElevation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for string representation of track duration */
|
/* Getter for string representation of track duration */
|
||||||
public String getTrackDurationString() {
|
public String getTrackDurationString() {
|
||||||
return LocationHelper.convertToReadableTime(mDuration, true);
|
return LocationHelper.convertToReadableTime(mDuration, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for string representation of track distance */
|
/* Getter for string representation of track distance */
|
||||||
public String getTrackDistanceString() {
|
public String getTrackDistanceString() {
|
||||||
float trackDistance;
|
double trackDistance = (double) mWayPoints.get(mWayPoints.size()-1).getDistanceToStartingPoint();
|
||||||
String unit;
|
return convertDistanceToString(trackDistance);
|
||||||
|
|
||||||
if (getUnitSystem(Locale.getDefault()) == IMPERIAL) {
|
|
||||||
// get track distance and convert to feet
|
|
||||||
trackDistance = mWayPoints.get(mWayPoints.size()-1).getDistanceToStartingPoint() * 3.28084f;
|
|
||||||
unit = "ft";
|
|
||||||
} else {
|
|
||||||
// get track distance
|
|
||||||
trackDistance = mWayPoints.get(mWayPoints.size()-1).getDistanceToStartingPoint();
|
|
||||||
unit = "m";
|
|
||||||
}
|
|
||||||
return String.format (Locale.ENGLISH, "%.0f", trackDistance) + unit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,6 +324,23 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Converts a given distance value to a readable string */
|
||||||
|
private String convertDistanceToString(double distance) {
|
||||||
|
// check for locale and set unit system accordingly
|
||||||
|
String unit;
|
||||||
|
if (getUnitSystem(Locale.getDefault()) == IMPERIAL) {
|
||||||
|
// convert distance to feet
|
||||||
|
distance = distance * 3.28084f;
|
||||||
|
// set measurement unit
|
||||||
|
unit = "ft";
|
||||||
|
} else {
|
||||||
|
// set measurement unit
|
||||||
|
unit = "m";
|
||||||
|
}
|
||||||
|
return String.format (Locale.ENGLISH, "%.0f", distance) + unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Determines which unit system the device is using (metric or imperial) */
|
/* Determines which unit system the device is using (metric or imperial) */
|
||||||
private int getUnitSystem(Locale locale) {
|
private int getUnitSystem(Locale locale) {
|
||||||
// America (US), Liberia (LR), Myanmar(MM) use the imperial system
|
// America (US), Liberia (LR), Myanmar(MM) use the imperial system
|
||||||
|
@ -245,8 +370,11 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
parcel.writeFloat(mStepCount);
|
parcel.writeFloat(mStepCount);
|
||||||
parcel.writeLong(mRecordingStart.getTime());
|
parcel.writeLong(mRecordingStart.getTime());
|
||||||
parcel.writeLong(mRecordingStop.getTime());
|
parcel.writeLong(mRecordingStop.getTime());
|
||||||
|
parcel.writeDouble(mMaxAltitude);
|
||||||
|
parcel.writeDouble(mMinAltitude);
|
||||||
|
parcel.writeDouble(mPositiveElevation);
|
||||||
|
parcel.writeDouble(mNegativeElevation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
80
app/src/main/java/org/y20k/trackbook/core/TrackBuilder.java
Normal file
80
app/src/main/java/org/y20k/trackbook/core/TrackBuilder.java
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* TrackBuilder.java
|
||||||
|
* Implements a builder for the Track class
|
||||||
|
* A TrackBuilder can build a track object depending on the version of its file format
|
||||||
|
*
|
||||||
|
* This file is part of
|
||||||
|
* TRACKBOOK - Movement Recorder for Android
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-18 - Y20K.org
|
||||||
|
* Licensed under the MIT-License
|
||||||
|
* http://opensource.org/licenses/MIT
|
||||||
|
*
|
||||||
|
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
|
||||||
|
* https://github.com/osmdroid/osmdroid
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.y20k.trackbook.core;
|
||||||
|
|
||||||
|
import org.y20k.trackbook.helpers.LogHelper;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TrackBuilder class
|
||||||
|
*/
|
||||||
|
public class TrackBuilder {
|
||||||
|
|
||||||
|
/* Define log tag */
|
||||||
|
private static final String LOG_TAG = TrackBuilder.class.getSimpleName();
|
||||||
|
|
||||||
|
|
||||||
|
/* Main class variables */
|
||||||
|
private final int mTrackFormatVersion;
|
||||||
|
private final List<WayPoint> mWayPoints;
|
||||||
|
private float mTrackLength;
|
||||||
|
private long mDuration;
|
||||||
|
private float mStepCount;
|
||||||
|
private final Date mRecordingStart;
|
||||||
|
private Date mRecordingStop;
|
||||||
|
private double mMaxAltitude;
|
||||||
|
private double mMinAltitude;
|
||||||
|
private double mPositiveElevation;
|
||||||
|
private double mNegativeElevation;
|
||||||
|
|
||||||
|
|
||||||
|
/* Generic Constructor */
|
||||||
|
public TrackBuilder(int trackFormatVersion, List<WayPoint> wayPoints, float trackLength, long duration, float stepCount, Date recordingStart, Date recordingStop, double maxAltitude, double minAltitude, double positiveElevation, double negativeElevation) {
|
||||||
|
mTrackFormatVersion = trackFormatVersion;
|
||||||
|
mWayPoints = wayPoints;
|
||||||
|
mTrackLength = trackLength;
|
||||||
|
mDuration = duration;
|
||||||
|
mStepCount = stepCount;
|
||||||
|
mRecordingStart = recordingStart;
|
||||||
|
mRecordingStop = recordingStop;
|
||||||
|
mMaxAltitude = maxAltitude;
|
||||||
|
mMinAltitude = minAltitude;
|
||||||
|
mPositiveElevation = positiveElevation;
|
||||||
|
mNegativeElevation = negativeElevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Builds and return a Track object */
|
||||||
|
public Track toTrack() {
|
||||||
|
switch (mTrackFormatVersion) {
|
||||||
|
case 1:
|
||||||
|
// file format version 1 - does not have elevation data stored
|
||||||
|
return new Track(mTrackFormatVersion, mWayPoints, mTrackLength, mDuration, mStepCount, mRecordingStart, mRecordingStop, 0f, 0f, 0f, 0f);
|
||||||
|
case 2:
|
||||||
|
// file format version 2 (current version)
|
||||||
|
return new Track(mTrackFormatVersion, mWayPoints, mTrackLength, mDuration, mStepCount, mRecordingStart, mRecordingStop, mMaxAltitude, mMinAltitude, mPositiveElevation, mNegativeElevation);
|
||||||
|
default:
|
||||||
|
LogHelper.e(LOG_TAG, "Unknown file format version: " + mTrackFormatVersion);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,7 +17,6 @@
|
||||||
package org.y20k.trackbook.helpers;
|
package org.y20k.trackbook.helpers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.location.Location;
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.os.EnvironmentCompat;
|
import android.support.v4.os.EnvironmentCompat;
|
||||||
|
@ -28,6 +27,7 @@ import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
import org.y20k.trackbook.R;
|
import org.y20k.trackbook.R;
|
||||||
import org.y20k.trackbook.core.Track;
|
import org.y20k.trackbook.core.Track;
|
||||||
|
import org.y20k.trackbook.core.TrackBuilder;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
|
@ -101,6 +101,9 @@ public class StorageHelper implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFolder != null && mFolder.exists() && mFolder.isDirectory() && mFolder.canWrite() && recordingStart != null && track != null) {
|
if (mFolder != null && mFolder.exists() && mFolder.isDirectory() && mFolder.canWrite() && recordingStart != null && track != null) {
|
||||||
|
// calculate elevation and store it in track
|
||||||
|
track = calculateElevation(track);
|
||||||
|
|
||||||
// create file object
|
// create file object
|
||||||
String fileName;
|
String fileName;
|
||||||
if (fileType == FILE_TEMP_TRACK) {
|
if (fileType == FILE_TEMP_TRACK) {
|
||||||
|
@ -221,22 +224,19 @@ public class StorageHelper implements TrackbookKeys {
|
||||||
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
|
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
|
||||||
LogHelper.v(LOG_TAG, "Loading track from external storage: " + file.toString());
|
LogHelper.v(LOG_TAG, "Loading track from external storage: " + file.toString());
|
||||||
|
|
||||||
|
// read until last line reached
|
||||||
String line;
|
String line;
|
||||||
StringBuilder sb = new StringBuilder("");
|
StringBuilder sb = new StringBuilder("");
|
||||||
|
|
||||||
// read until last line reached
|
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
sb.append(line);
|
sb.append(line);
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement a format version check before handing the file to GSON
|
// prepare GsonBuilder and return Track object
|
||||||
|
|
||||||
// get track from JSON
|
|
||||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||||
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
|
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
|
||||||
Gson gson = gsonBuilder.create();
|
Gson gson = gsonBuilder.create();
|
||||||
return gson.fromJson(sb.toString(), Track.class);
|
return gson.fromJson(sb.toString(), TrackBuilder.class).toTrack();
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.e(LOG_TAG, "Unable to read file from external storage: " + file.toString());
|
LogHelper.e(LOG_TAG, "Unable to read file from external storage: " + file.toString());
|
||||||
|
@ -360,38 +360,105 @@ public class StorageHelper implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculates positive and negative elevation of track */ // todo make private
|
/* Calculates positive and negative elevation of track */
|
||||||
public Track calculateTrackElevation(@Nullable Track track) {
|
private Track calculateElevation(@Nullable Track track) {
|
||||||
|
double maxAltitude = 0;
|
||||||
|
double minAltitude = 0;
|
||||||
double positiveElevation = 0;
|
double positiveElevation = 0;
|
||||||
double negativeElevation = 0;
|
double negativeElevation = 0;
|
||||||
double LIKELY_MEASUREMENT_ERROR = 25; // move to TrackbookKeys
|
|
||||||
|
|
||||||
if (track != null && track.getWayPoints().size() > 0 && track.getWayPointLocation(0).getAltitude() != 0) {
|
if (track != null && track.getWayPoints().size() > 0 && track.getWayPointLocation(0).getAltitude() != 0) {
|
||||||
Location previousLocation;
|
double previousLocationHeight;
|
||||||
Location nextLocation;
|
double currentLocationHeight;
|
||||||
|
long previousTimeStamp;
|
||||||
|
long currentTimeStamp;
|
||||||
|
|
||||||
|
// initial values for max height and min height - first waypoint
|
||||||
|
maxAltitude = track.getWayPointLocation(0).getAltitude();
|
||||||
|
minAltitude = maxAltitude;
|
||||||
|
|
||||||
|
// apply filter & smooth data
|
||||||
|
// track = lowPass(track, 15f, 35f);
|
||||||
|
|
||||||
// iterate over track
|
// iterate over track
|
||||||
for (int i = 0; i < track.getWayPoints().size() - 1; i++ ) {
|
for (int i = 1; i < track.getWayPoints().size(); i++ ) {
|
||||||
// calculate elevation difference
|
|
||||||
previousLocation = track.getWayPointLocation(i);
|
|
||||||
nextLocation = track.getWayPointLocation(i + 1);
|
|
||||||
double difference = nextLocation.getAltitude() - previousLocation.getAltitude();
|
|
||||||
LogHelper.i(LOG_TAG, "next:" + nextLocation.getAltitude() + " | prev:" + previousLocation.getAltitude() + " | diff:" + difference); // todo remove
|
|
||||||
|
|
||||||
// add difference to elevation
|
// get time difference
|
||||||
if (difference > 0 && difference < LIKELY_MEASUREMENT_ERROR) {
|
previousTimeStamp = track.getWayPointLocation(i -1).getTime();
|
||||||
positiveElevation = positiveElevation + difference;
|
currentTimeStamp = track.getWayPointLocation(i).getTime();
|
||||||
} else if (difference < 0 && difference > -LIKELY_MEASUREMENT_ERROR) {
|
double timeDiff = (currentTimeStamp - previousTimeStamp);
|
||||||
negativeElevation = negativeElevation + difference;
|
|
||||||
|
// factor is bigger than 1 if the time stamp difference is larger than the movement recording interval (usually 15 seconds)
|
||||||
|
double timeDiffFactor = timeDiff / FIFTEEN_SECONDS_IN_MILLISECONDS;
|
||||||
|
|
||||||
|
// height of previous and current waypoints
|
||||||
|
previousLocationHeight = track.getWayPointLocation(i -1).getAltitude();
|
||||||
|
currentLocationHeight = track.getWayPointLocation(i).getAltitude();
|
||||||
|
|
||||||
|
// check for new min and max heights
|
||||||
|
if (currentLocationHeight > maxAltitude) {
|
||||||
|
maxAltitude = currentLocationHeight;
|
||||||
|
} else if (minAltitude == 0 || currentLocationHeight < minAltitude) {
|
||||||
|
minAltitude = currentLocationHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get elevation difference and sum it up
|
||||||
|
double altitudeDiff = currentLocationHeight - previousLocationHeight;
|
||||||
|
if (altitudeDiff > 0 && altitudeDiff < MEASUREMENT_ERROR_THRESHOLD * timeDiffFactor && currentLocationHeight != 0) {
|
||||||
|
positiveElevation = positiveElevation + altitudeDiff;
|
||||||
|
} else if (altitudeDiff < 0 && altitudeDiff > -MEASUREMENT_ERROR_THRESHOLD * timeDiffFactor && currentLocationHeight != 0) {
|
||||||
|
negativeElevation = negativeElevation + altitudeDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String toastString = "Calculated elevation: +" + positiveElevation + " / " + negativeElevation + " meters"; // todo remove
|
// store elevation data in track
|
||||||
Toast.makeText(mContext, toastString, Toast.LENGTH_LONG).show(); // todo remove
|
track.setMaxAltitude(maxAltitude);
|
||||||
LogHelper.i(LOG_TAG, toastString); // todo remove
|
track.setMinAltitude(minAltitude);
|
||||||
|
track.setPositiveElevation(positiveElevation);
|
||||||
|
track.setNegativeElevation(negativeElevation);
|
||||||
}
|
}
|
||||||
return track;
|
return track;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tries to smooth the elevation data using a low pass filter */
|
||||||
|
private Track lowPass(Track input, float dt, float rc) {
|
||||||
|
/* The following code is adapted from https://en.wikipedia.org/wiki/Low-pass_filter
|
||||||
|
*
|
||||||
|
* // Return RC low-pass filter output samples, given input samples,
|
||||||
|
* // time interval dt, and time constant RC
|
||||||
|
* function lowpass(real[0..n] x, real dt, real RC)
|
||||||
|
* var real[0..n] y
|
||||||
|
* var real α := dt / (RC + dt)
|
||||||
|
* y[0] := α * x[0]
|
||||||
|
* for i from 1 to n
|
||||||
|
* y[i] := α * x[i] + (1-α) * y[i-1]
|
||||||
|
* return y
|
||||||
|
*/
|
||||||
|
|
||||||
|
// copy input track
|
||||||
|
Track output = new Track(input);
|
||||||
|
|
||||||
|
// calculate alpha
|
||||||
|
float alpha = dt / (rc + dt);
|
||||||
|
|
||||||
|
// set initial value for first waypoint
|
||||||
|
double outputInitialAltituteValue = alpha * input.getWayPoints().get(0).getLocation().getAltitude();
|
||||||
|
output.getWayPoints().get(0).getLocation().setAltitude(outputInitialAltituteValue);
|
||||||
|
|
||||||
|
double inputCurrentAltitudeValue;
|
||||||
|
double outputPreviousAltitudeValue;
|
||||||
|
double outputCurrentAltitudeValue;
|
||||||
|
for (int i = 1; i < input.getSize(); i++) {
|
||||||
|
inputCurrentAltitudeValue = input.getWayPoints().get(i).getLocation().getAltitude();
|
||||||
|
outputPreviousAltitudeValue = output.getWayPoints().get(i-1).getLocation().getAltitude();
|
||||||
|
|
||||||
|
outputCurrentAltitudeValue = alpha * inputCurrentAltitudeValue + (1 - alpha) * outputPreviousAltitudeValue;
|
||||||
|
|
||||||
|
output.getWayPoints().get(i).getLocation().setAltitude(outputCurrentAltitudeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,10 +111,10 @@ public interface TrackbookKeys {
|
||||||
String NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL ="notificationChannelIdRecordingChannel";
|
String NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL ="notificationChannelIdRecordingChannel";
|
||||||
|
|
||||||
/* MISC */
|
/* MISC */
|
||||||
|
int CURRENT_TRACK_FORMAT_VERSION = 2; // incremental version number to prevent issues in case the Track format evolves
|
||||||
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
||||||
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
||||||
int CURRENT_TRACK_FORMAT_VERSION = 1; // incremental version number to prevent issues in case the Track format evolves
|
int MEASUREMENT_ERROR_THRESHOLD = 10; // altitude changes of 10 meter or more (per 15 seconds) are being discarded
|
||||||
int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
||||||
int INFOSHEET_CONTENT_ABOUT = 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<android.support.constraint.Group
|
||||||
|
android:id="@+id/elevation_data"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:constraint_referenced_ids="statistics_p_positive_elevation, statistics_data_positive_elevation, statistics_p_negative_elevation, statistics_data_negative_elevation, statistics_p_max_altitude, statistics_data_max_altitude, statistics_p_min_altitude, statistics_data_min_altitude" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/statistics_headline"
|
android:id="@+id/statistics_headline"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -148,11 +154,9 @@
|
||||||
android:id="@+id/statistics_p_recording_stop"
|
android:id="@+id/statistics_p_recording_stop"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:contentDescription="@string/descr_statistics_sheet_p_recording_end"
|
android:contentDescription="@string/descr_statistics_sheet_p_recording_end"
|
||||||
android:text="@string/statistics_sheet_p_recording_stop"
|
android:text="@string/statistics_sheet_p_recording_stop"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/statistics_p_recording_start"
|
app:layout_constraintStart_toStartOf="@+id/statistics_p_recording_start"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/statistics_p_recording_start" />
|
app:layout_constraintTop_toBottomOf="@+id/statistics_p_recording_start" />
|
||||||
|
|
||||||
|
@ -168,4 +172,90 @@
|
||||||
app:layout_constraintStart_toEndOf="@+id/statistics_p_recording_stop"
|
app:layout_constraintStart_toEndOf="@+id/statistics_p_recording_stop"
|
||||||
app:layout_constraintTop_toTopOf="@+id/statistics_p_recording_stop" />
|
app:layout_constraintTop_toTopOf="@+id/statistics_p_recording_stop" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_p_positive_elevation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="@string/descr_statistics_sheet_p_positive_elevation"
|
||||||
|
android:text="@string/statistics_sheet_p_positive_elevation"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/statistics_p_recording_stop"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/statistics_p_recording_stop" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_data_positive_elevation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/statistics_sheet_p_default_data"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/statistics_p_positive_elevation"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/statistics_p_positive_elevation"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/statistics_p_positive_elevation" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_p_negative_elevation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="@string/descr_statistics_sheet_p_negative_elevation"
|
||||||
|
android:text="@string/statistics_sheet_p_negative_elevation"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/statistics_p_positive_elevation"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/statistics_p_positive_elevation" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_data_negative_elevation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/statistics_sheet_p_default_data"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/statistics_p_negative_elevation"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/statistics_p_negative_elevation"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/statistics_p_negative_elevation" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_p_max_altitude"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="@string/descr_statistics_sheet_p_max_altitude"
|
||||||
|
android:text="@string/statistics_sheet_p_max_altitude"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/statistics_p_negative_elevation"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/statistics_p_negative_elevation" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_data_max_altitude"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/statistics_sheet_p_default_data"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/statistics_p_max_altitude"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/statistics_p_max_altitude"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/statistics_p_max_altitude" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_p_min_altitude"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="@string/descr_statistics_sheet_p_min_altitude"
|
||||||
|
android:text="@string/statistics_sheet_p_min_altitude"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/statistics_p_max_altitude"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/statistics_p_max_altitude" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/statistics_data_min_altitude"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/statistics_sheet_p_default_data"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/statistics_p_min_altitude"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/statistics_p_min_altitude"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/statistics_p_min_altitude" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
|
@ -56,8 +56,9 @@
|
||||||
<string name="toast_message_save_track">Aufzeichnung wird gespeichert.</string>
|
<string name="toast_message_save_track">Aufzeichnung wird gespeichert.</string>
|
||||||
<string name="toast_message_last_location_age_one_hour">über eine Stunde</string>
|
<string name="toast_message_last_location_age_one_hour">über eine Stunde</string>
|
||||||
<string name="toast_message_track_clear">Aufzeichnung zurückgesetzt.</string>
|
<string name="toast_message_track_clear">Aufzeichnung zurückgesetzt.</string>
|
||||||
<string name="toast_message_export_success">GPX export successful:</string>
|
<string name="toast_message_export_success">GPX-Export erfolgreich:</string>
|
||||||
<string name="toast_message_export_fail">GPX export failed:</string>
|
<string name="toast_message_export_fail">GPX-Export fehlgeschlagen:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hinweis: Die Genauogkeit der Höhenmeter-Werte ist geräteabhängig. Gemessen werden die Steigungen und Gefälle der Gesamtstrecke.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Quelle</string>
|
<string name="marker_description_source">Quelle</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Dauer (gesamt):</string>
|
<string name="statistics_sheet_p_duration">Dauer (gesamt):</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Start der Aufzeichnung:</string>
|
<string name="statistics_sheet_p_recording_start">Start der Aufzeichnung:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Ende der Aufzeichnung:</string>
|
<string name="statistics_sheet_p_recording_stop">Ende der Aufzeichnung:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Höchster Wegpunkt:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Tiefster Wegpunkt:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Höhenmeter (bergauf):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Höhenmeter (bergab):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">Wert: Dauer</string>
|
<string name="descr_statistics_sheet_p_duration_value">Wert: Dauer</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">Wert: Start der Aufzeichnung</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">Wert: Start der Aufzeichnung</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">Wert: Ende der Aufzeichnung</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">Wert: Ende der Aufzeichnung</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Wert: Höchster Wegpunkt</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Wert: Tiefster Wegpunkt:</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Wert: Höhenmeter (bergauf)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Wert Höhenmeter (bergab)</string>
|
||||||
<string name="descr_track_selector">Auswahl-Menü für weitere Aufzeichnungen</string>
|
<string name="descr_track_selector">Auswahl-Menü für weitere Aufzeichnungen</string>
|
||||||
<string name="descr_export_button">Button Track Exportierem</string>
|
<string name="descr_export_button">Button Track Exportierem</string>
|
||||||
<string name="descr_delete_button">Button Track Löschen</string>
|
<string name="descr_delete_button">Button Track Löschen</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">Current track data removed.</string>
|
<string name="toast_message_track_clear">Current track data removed.</string>
|
||||||
<string name="toast_message_export_success">GPX export successful:</string>
|
<string name="toast_message_export_success">GPX export successful:</string>
|
||||||
<string name="toast_message_export_fail">GPX export failed:</string>
|
<string name="toast_message_export_fail">GPX export failed:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Source</string>
|
<string name="marker_description_source">Source</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Total duration:</string>
|
<string name="statistics_sheet_p_duration">Total duration:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Recording started:</string>
|
<string name="statistics_sheet_p_recording_start">Recording started:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Recording stopped:</string>
|
<string name="statistics_sheet_p_recording_stop">Recording stopped:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Hello</string>
|
<string name="layout_onboarding_h1_welcome">Hello</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">Value: Duration</string>
|
<string name="descr_statistics_sheet_p_duration_value">Value: Duration</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">Value: Start of recording</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">Value: Start of recording</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">Value: End of recording</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">Value: End of recording</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Value: Highest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Value: Lowest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Value: Elevation (uphill)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Value: Elevation (downhill)</string>
|
||||||
<string name="descr_track_selector">Dropdown menu for further tracks</string>
|
<string name="descr_track_selector">Dropdown menu for further tracks</string>
|
||||||
<string name="descr_export_button">Track export button</string>
|
<string name="descr_export_button">Track export button</string>
|
||||||
<string name="descr_delete_button">Track delete button</string>
|
<string name="descr_delete_button">Track delete button</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">Dati della traccia corrente rimossi.</string>
|
<string name="toast_message_track_clear">Dati della traccia corrente rimossi.</string>
|
||||||
<string name="toast_message_export_success">L\'esportazione GPX è riuscita:</string>
|
<string name="toast_message_export_success">L\'esportazione GPX è riuscita:</string>
|
||||||
<string name="toast_message_export_fail">L\'esportazione GPX non è riuscita:</string>
|
<string name="toast_message_export_fail">L\'esportazione GPX non è riuscita:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Fonte</string>
|
<string name="marker_description_source">Fonte</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Durata totale:</string>
|
<string name="statistics_sheet_p_duration">Durata totale:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Registrazione avviata il:</string>
|
<string name="statistics_sheet_p_recording_start">Registrazione avviata il:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Registrazione interrotta il:</string>
|
<string name="statistics_sheet_p_recording_stop">Registrazione interrotta il:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Ciao</string>
|
<string name="layout_onboarding_h1_welcome">Ciao</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">Valore: Durata</string>
|
<string name="descr_statistics_sheet_p_duration_value">Valore: Durata</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">Valore: Inizio della registrazione</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">Valore: Inizio della registrazione</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">Valore: Fine della registrazione</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">Valore: Fine della registrazione</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Value: Highest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Value: Lowest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Value: Elevation (uphill)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Value: Elevation (downhill)</string>
|
||||||
<string name="descr_track_selector">Elenco registrazioni</string>
|
<string name="descr_track_selector">Elenco registrazioni</string>
|
||||||
<string name="descr_export_button">Pulsante di esportazione della traccia</string>
|
<string name="descr_export_button">Pulsante di esportazione della traccia</string>
|
||||||
<string name="descr_delete_button">Pulsante di eliminazione della traccia</string>
|
<string name="descr_delete_button">Pulsante di eliminazione della traccia</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">現在のトレース データを削除しました。</string>
|
<string name="toast_message_track_clear">現在のトレース データを削除しました。</string>
|
||||||
<string name="toast_message_export_success">GPX export successful:</string>
|
<string name="toast_message_export_success">GPX export successful:</string>
|
||||||
<string name="toast_message_export_fail">GPX export failed:</string>
|
<string name="toast_message_export_fail">GPX export failed:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">ソース</string>
|
<string name="marker_description_source">ソース</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">合計時間:</string>
|
<string name="statistics_sheet_p_duration">合計時間:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">記録の開始:</string>
|
<string name="statistics_sheet_p_recording_start">記録の開始:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">記録の停止:</string>
|
<string name="statistics_sheet_p_recording_stop">記録の停止:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">こんにちは</string>
|
<string name="layout_onboarding_h1_welcome">こんにちは</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">値: 期間</string>
|
<string name="descr_statistics_sheet_p_duration_value">値: 期間</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">値: 記録の開始</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">値: 記録の開始</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">値: 記録の終了</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">値: 記録の終了</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Value: Highest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Value: Lowest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Value: Elevation (uphill)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Value: Elevation (downhill)</string>
|
||||||
<string name="descr_track_selector">ドロップダウン メニューでさらにトレース</string>
|
<string name="descr_track_selector">ドロップダウン メニューでさらにトレース</string>
|
||||||
<string name="descr_export_button">Track export button</string>
|
<string name="descr_export_button">Track export button</string>
|
||||||
<string name="descr_delete_button">トレース削除ボタン</string>
|
<string name="descr_delete_button">トレース削除ボタン</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">Nåværende turdata fjernet.</string>
|
<string name="toast_message_track_clear">Nåværende turdata fjernet.</string>
|
||||||
<string name="toast_message_export_success">GPX-eksportering vellykket:</string>
|
<string name="toast_message_export_success">GPX-eksportering vellykket:</string>
|
||||||
<string name="toast_message_export_fail">GPX-eksportering mislyktes:</string>
|
<string name="toast_message_export_fail">GPX-eksportering mislyktes:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Kilde</string>
|
<string name="marker_description_source">Kilde</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Total varighet:</string>
|
<string name="statistics_sheet_p_duration">Total varighet:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Opptak startet:</string>
|
<string name="statistics_sheet_p_recording_start">Opptak startet:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Opptak stoppet:</string>
|
<string name="statistics_sheet_p_recording_stop">Opptak stoppet:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">Verdi: Varighet</string>
|
<string name="descr_statistics_sheet_p_duration_value">Verdi: Varighet</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">Verdi: Opptaksstart</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">Verdi: Opptaksstart</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">Verdi: Opptaksslutt</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">Verdi: Opptaksslutt</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Value: Highest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Value: Lowest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Value: Elevation (uphill)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Value: Elevation (downhill)</string>
|
||||||
<string name="descr_track_selector">Nedtrekksmeny for ytterligere turer</string>
|
<string name="descr_track_selector">Nedtrekksmeny for ytterligere turer</string>
|
||||||
<string name="descr_export_button">Tureksportknapp</string>
|
<string name="descr_export_button">Tureksportknapp</string>
|
||||||
<string name="descr_delete_button">Turslettingsknapp</string>
|
<string name="descr_delete_button">Turslettingsknapp</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">Huidige baangegevens verwijderd.</string>
|
<string name="toast_message_track_clear">Huidige baangegevens verwijderd.</string>
|
||||||
<string name="toast_message_export_success">GPX export successful:</string>
|
<string name="toast_message_export_success">GPX export successful:</string>
|
||||||
<string name="toast_message_export_fail">GPX export failed:</string>
|
<string name="toast_message_export_fail">GPX export failed:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Bron</string>
|
<string name="marker_description_source">Bron</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Totale duur:</string>
|
<string name="statistics_sheet_p_duration">Totale duur:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Bijhouden gestart:</string>
|
<string name="statistics_sheet_p_recording_start">Bijhouden gestart:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Bijhouden gestopt:</string>
|
<string name="statistics_sheet_p_recording_stop">Bijhouden gestopt:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
<string name="layout_onboarding_h1_welcome">Hallo</string>
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<string name="toast_message_track_clear">Current track data removed.</string>
|
<string name="toast_message_track_clear">Current track data removed.</string>
|
||||||
<string name="toast_message_export_success">GPX export successful:</string>
|
<string name="toast_message_export_success">GPX export successful:</string>
|
||||||
<string name="toast_message_export_fail">GPX export failed:</string>
|
<string name="toast_message_export_fail">GPX export failed:</string>
|
||||||
|
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
<string name="marker_description_source">Source</string>
|
<string name="marker_description_source">Source</string>
|
||||||
|
@ -74,6 +75,10 @@
|
||||||
<string name="statistics_sheet_p_duration">Total duration:</string>
|
<string name="statistics_sheet_p_duration">Total duration:</string>
|
||||||
<string name="statistics_sheet_p_recording_start">Recording started:</string>
|
<string name="statistics_sheet_p_recording_start">Recording started:</string>
|
||||||
<string name="statistics_sheet_p_recording_stop">Recording stopped:</string>
|
<string name="statistics_sheet_p_recording_stop">Recording stopped:</string>
|
||||||
|
<string name="statistics_sheet_p_max_altitude">Highest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
|
||||||
|
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
|
||||||
|
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
|
||||||
|
|
||||||
<!-- onboarding layout -->
|
<!-- onboarding layout -->
|
||||||
<string name="layout_onboarding_h1_welcome">Hello</string>
|
<string name="layout_onboarding_h1_welcome">Hello</string>
|
||||||
|
@ -114,6 +119,10 @@
|
||||||
<string name="descr_statistics_sheet_p_duration_value">Value: Duration</string>
|
<string name="descr_statistics_sheet_p_duration_value">Value: Duration</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_start_value">Value: Start of recording</string>
|
<string name="descr_statistics_sheet_p_recording_start_value">Value: Start of recording</string>
|
||||||
<string name="descr_statistics_sheet_p_recording_end_value">Value: End of recording</string>
|
<string name="descr_statistics_sheet_p_recording_end_value">Value: End of recording</string>
|
||||||
|
<string name="descr_statistics_sheet_p_max_altitude">Value: Highest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_min_altitude">Value: Lowest waypoint</string>
|
||||||
|
<string name="descr_statistics_sheet_p_positive_elevation">Value: Elevation (uphill)</string>
|
||||||
|
<string name="descr_statistics_sheet_p_negative_elevation">Value: Elevation (downhill)</string>
|
||||||
<string name="descr_track_selector">Dropdown menu for further tracks</string>
|
<string name="descr_track_selector">Dropdown menu for further tracks</string>
|
||||||
<string name="descr_export_button">Track export button</string>
|
<string name="descr_export_button">Track export button</string>
|
||||||
<string name="descr_delete_button">Track delete button</string>
|
<string name="descr_delete_button">Track delete button</string>
|
||||||
|
|
Loading…
Reference in a new issue