mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
TrackPoint has Location as delegate instead of inheritance.
This commit is contained in:
@@ -412,7 +412,7 @@ public class TrackDataHub implements DataSourceListener, SharedPreferences.OnSha
|
||||
samplingFrequency = 1 + (int) (numTotalPoints / targetNumPoints);
|
||||
}
|
||||
|
||||
if (!LocationUtils.isValidLocation(trackPoint)) { //This can be split markers (not anymore supported feature)
|
||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) { //This can be split markers (not anymore supported feature)
|
||||
includeNextPoint = true;
|
||||
} else {
|
||||
// Also include the last point if the selected track is not recording.
|
||||
|
||||
@@ -18,6 +18,8 @@ package de.dennisguse.opentracks.content.data;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
|
||||
/**
|
||||
@@ -25,34 +27,71 @@ import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
//TODO Check if we can drop inheritance from Location and use attributes instead.
|
||||
public class TrackPoint extends Location {
|
||||
public class TrackPoint {
|
||||
|
||||
public static TrackPoint createPause() {
|
||||
TrackPoint pause = new TrackPoint(LocationManager.GPS_PROVIDER);
|
||||
pause.setLongitude(0);
|
||||
pause.setLatitude(TrackPointsColumns.PAUSE_LATITUDE);
|
||||
pause.setTime(System.currentTimeMillis());
|
||||
return pause;
|
||||
private Location location;
|
||||
|
||||
public TrackPoint() {
|
||||
this.location = new Location("");
|
||||
}
|
||||
|
||||
public static TrackPoint createResume() {
|
||||
TrackPoint resume = new TrackPoint(LocationManager.GPS_PROVIDER);
|
||||
resume.setLongitude(0);
|
||||
resume.setLatitude(TrackPointsColumns.RESUME_LATITUDE);
|
||||
resume.setTime(System.currentTimeMillis());
|
||||
return resume;
|
||||
public TrackPoint(@NonNull Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public TrackPoint(@NonNull Location location, SensorDataSet sensorDataSet) {
|
||||
this.location = location;
|
||||
this.sensorDataSet = sensorDataSet;
|
||||
}
|
||||
|
||||
public TrackPoint(@NonNull TrackPoint trackPoint, SensorDataSet sensorDataSet) {
|
||||
this.location = trackPoint.getLocation();
|
||||
this.sensorDataSet = sensorDataSet;
|
||||
}
|
||||
|
||||
private SensorDataSet sensorDataSet = null;
|
||||
|
||||
public TrackPoint(Location location, SensorDataSet sensorDataSet) {
|
||||
super(location);
|
||||
this.sensorDataSet = sensorDataSet;
|
||||
public TrackPoint(double latitude, double longitude, Double altitude, long time) {
|
||||
location = new Location(LocationManager.GPS_PROVIDER);
|
||||
location.setLatitude(latitude);
|
||||
location.setLongitude(longitude);
|
||||
if (altitude != null) {
|
||||
location.setAltitude(altitude);
|
||||
}
|
||||
location.setTime(time);
|
||||
}
|
||||
|
||||
public TrackPoint(String provider) {
|
||||
super(provider);
|
||||
public static TrackPoint createPause() {
|
||||
return createPauseWithTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static TrackPoint createPauseWithTime(long time) {
|
||||
Location pause = new Location(LocationManager.GPS_PROVIDER);
|
||||
pause.setLongitude(0);
|
||||
pause.setLatitude(TrackPointsColumns.PAUSE_LATITUDE);
|
||||
pause.setTime(time);
|
||||
return new TrackPoint(pause);
|
||||
}
|
||||
|
||||
public static TrackPoint createResume() {
|
||||
return createResumeWithTime(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static TrackPoint createResumeWithTime(long time) {
|
||||
Location resume = new Location(LocationManager.GPS_PROVIDER);
|
||||
resume.setLongitude(0);
|
||||
resume.setLatitude(TrackPointsColumns.RESUME_LATITUDE);
|
||||
resume.setTime(time);
|
||||
return new TrackPoint(resume);
|
||||
}
|
||||
|
||||
public @NonNull
|
||||
Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(@NonNull Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public SensorDataSet getSensorDataSet() {
|
||||
@@ -63,8 +102,92 @@ public class TrackPoint extends Location {
|
||||
this.sensorDataSet = sensorDataSet;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return location.getLatitude();
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
location.setLatitude(latitude);
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return location.getLongitude();
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
location.setLongitude(longitude);
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return location.getTime();
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
location.setTime(time);
|
||||
}
|
||||
|
||||
public boolean hasAltitude() {
|
||||
return location.hasAltitude();
|
||||
}
|
||||
|
||||
public double getAltitude() {
|
||||
return location.getAltitude();
|
||||
}
|
||||
|
||||
public void setAltitude(double altitude) {
|
||||
location.setAltitude(altitude);
|
||||
}
|
||||
|
||||
public boolean hasSpeed() {
|
||||
return location.hasSpeed();
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return location.getSpeed();
|
||||
}
|
||||
|
||||
public void setSpeed(float speed) {
|
||||
location.setSpeed(speed);
|
||||
}
|
||||
|
||||
public boolean hasBearing() {
|
||||
return location.hasBearing();
|
||||
}
|
||||
|
||||
public float getBearing() {
|
||||
return location.getBearing();
|
||||
}
|
||||
|
||||
public void setBearing(float bearing) {
|
||||
location.setBearing(bearing);
|
||||
}
|
||||
|
||||
public boolean hasAccuracy() {
|
||||
return location.hasAccuracy();
|
||||
}
|
||||
|
||||
public float getAccuracy() {
|
||||
return location.getAccuracy();
|
||||
}
|
||||
|
||||
public void setAccuracy(float horizontalAccuracy) {
|
||||
location.setAccuracy(horizontalAccuracy);
|
||||
}
|
||||
|
||||
public float distanceTo(@NonNull TrackPoint dest) {
|
||||
return location.distanceTo(dest.getLocation());
|
||||
}
|
||||
|
||||
public float bearingTo(@NonNull TrackPoint dest) {
|
||||
return location.bearingTo(dest.getLocation());
|
||||
}
|
||||
|
||||
public float bearingTo(@NonNull Location dest) {
|
||||
return location.bearingTo(dest);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
location.reset();
|
||||
sensorDataSet = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package de.dennisguse.opentracks.content.data;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* A waypoint.
|
||||
*
|
||||
@@ -117,11 +119,12 @@ public final class Waypoint {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
public @NonNull
|
||||
Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
public void setLocation(@NonNull Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
@@ -755,7 +755,7 @@ public class ContentProviderUtils {
|
||||
* @param cursor the cursor pointing to the location
|
||||
*/
|
||||
public TrackPoint createTrackPoint(Cursor cursor) {
|
||||
TrackPoint location = new TrackPoint("");
|
||||
TrackPoint location = new TrackPoint();
|
||||
fillTrackPoint(cursor, new CachedTrackPointsIndexes(cursor), location);
|
||||
return location;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.dennisguse.opentracks.content.provider;
|
||||
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
@@ -16,6 +17,6 @@ public class TrackPointFactory {
|
||||
public static final TrackPointFactory DEFAULT_LOCATION_FACTORY = new TrackPointFactory();
|
||||
|
||||
public TrackPoint create() {
|
||||
return new TrackPoint(LocationManager.GPS_PROVIDER);
|
||||
return new TrackPoint(new Location(LocationManager.GPS_PROVIDER));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class TrackPointIterator implements Iterator<TrackPoint>, AutoCloseable {
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
private final long trackId;
|
||||
private final boolean descending;
|
||||
private final TrackPointFactory trackPointFactory;
|
||||
private final TrackPointFactory trackPointFactory; //TODO Remove; seems to be an old performance optimization.
|
||||
private final CachedTrackPointsIndexes indexes;
|
||||
private long lastTrackPointId = -1L;
|
||||
private Cursor cursor;
|
||||
|
||||
@@ -358,7 +358,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
||||
}
|
||||
|
||||
if (lastTrackPoint != null) {
|
||||
boolean hasFix = !LocationUtils.isLocationOld(lastTrackPoint);
|
||||
boolean hasFix = !LocationUtils.isLocationOld(lastTrackPoint.getLocation());
|
||||
boolean hasGoodFix = lastTrackPoint.hasAccuracy() && lastTrackPoint.getAccuracy() < recordingGpsAccuracy;
|
||||
|
||||
if (!hasFix || !hasGoodFix) {
|
||||
|
||||
@@ -139,7 +139,7 @@ public class FileTrackExporter implements TrackExporter {
|
||||
setLocationTime(trackPoint, offset);
|
||||
locationNumber++;
|
||||
|
||||
boolean isLocationValid = LocationUtils.isValidLocation(trackPoint);
|
||||
boolean isLocationValid = LocationUtils.isValidLocation(trackPoint.getLocation());
|
||||
boolean isSegmentValid = isLocationValid && isLastLocationValid;
|
||||
if (!wroteTrack && isSegmentValid) {
|
||||
// Found the first two consecutive locations that are valid
|
||||
@@ -193,7 +193,7 @@ public class FileTrackExporter implements TrackExporter {
|
||||
* Sets a trackPoint time.
|
||||
*
|
||||
* @param trackPoint the trackPoint
|
||||
* @param offset the time offset
|
||||
* @param offset the time offset
|
||||
*/
|
||||
private void setLocationTime(TrackPoint trackPoint, long offset) {
|
||||
if (trackPoint != null) {
|
||||
@@ -213,7 +213,7 @@ public class FileTrackExporter implements TrackExporter {
|
||||
@Override
|
||||
public TrackPoint create() {
|
||||
if (currentTrackPoint == null) {
|
||||
currentTrackPoint = new TrackPoint("");
|
||||
currentTrackPoint = new TrackPoint();
|
||||
}
|
||||
return currentTrackPoint;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class GpxTrackWriter implements TrackWriter {
|
||||
@Override
|
||||
public void writeTrackPoint(TrackPoint trackPoint) {
|
||||
if (printWriter != null) {
|
||||
printWriter.println("<trkpt " + formatLocation(trackPoint) + ">");
|
||||
printWriter.println("<trkpt " + formatLocation(trackPoint.getLocation()) + ">");
|
||||
if (trackPoint.hasAltitude()) {
|
||||
printWriter.println("<ele>" + ELEVATION_FORMAT.format(trackPoint.getAltitude()) + "</ele>");
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ public class KmlTrackWriter implements TrackWriter {
|
||||
this.startTrackPoint = startTrackPoint;
|
||||
if (printWriter != null) {
|
||||
String name = context.getString(R.string.marker_label_start, track.getName());
|
||||
writePlacemark(name, "", "", START_STYLE, startTrackPoint);
|
||||
writePlacemark(name, "", "", START_STYLE, startTrackPoint.getLocation());
|
||||
printWriter.println("<Placemark>");
|
||||
|
||||
if (exportTrackDetail) {
|
||||
@@ -218,7 +218,7 @@ public class KmlTrackWriter implements TrackWriter {
|
||||
if (exportTrackDetail) {
|
||||
String name = context.getString(R.string.marker_label_end, track.getName());
|
||||
String description = descriptionGenerator.generateTrackDescription(track, false);
|
||||
writePlacemark(name, "", description, END_STYLE, endTrackPoint);
|
||||
writePlacemark(name, "", description, END_STYLE, endTrackPoint.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,10 +259,10 @@ public class KmlTrackWriter implements TrackWriter {
|
||||
public void writeTrackPoint(TrackPoint trackPoint) {
|
||||
if (printWriter != null) {
|
||||
if (exportTrackDetail) {
|
||||
printWriter.println("<when>" + getTime(trackPoint) + "</when>");
|
||||
printWriter.println("<when>" + getTime(trackPoint.getLocation()) + "</when>");
|
||||
}
|
||||
|
||||
printWriter.println("<gx:coord>" + getCoordinates(trackPoint, " ") + "</gx:coord>");
|
||||
printWriter.println("<gx:coord>" + getCoordinates(trackPoint.getLocation(), " ") + "</gx:coord>");
|
||||
|
||||
if (exportSensorData) {
|
||||
SensorDataSet sensorDataSet = trackPoint.getSensorDataSet();
|
||||
@@ -386,7 +386,7 @@ public class KmlTrackWriter implements TrackWriter {
|
||||
if (trackPointId == -1L) {
|
||||
return location.getBearing();
|
||||
}
|
||||
Location viewLocation;
|
||||
TrackPoint viewLocation;
|
||||
try (Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackPointId, 10, true)) {
|
||||
if (cursor == null || cursor.getCount() == 0) {
|
||||
return location.getBearing();
|
||||
|
||||
+19
-46
@@ -17,8 +17,6 @@
|
||||
package de.dennisguse.opentracks.io.file.importer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -40,7 +38,6 @@ import javax.xml.parsers.SAXParserFactory;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.data.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.provider.TrackPointFactory;
|
||||
@@ -193,7 +190,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
waypoint = null;
|
||||
} else {
|
||||
// The waypoint trackPoint time matches the track point time
|
||||
if (!LocationUtils.isValidLocation(trackPoint)) {
|
||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||
// Invalid trackPoint, load the next trackPoint
|
||||
trackPoint = null;
|
||||
continue;
|
||||
@@ -207,7 +204,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
long duration = trackTripStatisticstrackUpdater.getTripStatistics().getTotalTime();
|
||||
|
||||
// Insert waypoint
|
||||
Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), length, duration, trackPoint, waypoint.getPhotoUrl());
|
||||
Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), length, duration, trackPoint.getLocation(), waypoint.getPhotoUrl());
|
||||
contentProviderUtils.insertWaypoint(newWaypoint);
|
||||
}
|
||||
|
||||
@@ -274,7 +271,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
|
||||
//If not the first segment, add a pause separator if there is at least one location in the last segment.
|
||||
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment != null) {
|
||||
insertLocation(createTrackPoint(TrackPointsColumns.PAUSE_LATITUDE, 0.0, 0.0, trackData.lastLocationInCurrentSegment.getTime()));
|
||||
insertLocation(TrackPoint.createPauseWithTime(trackData.lastLocationInCurrentSegment.getTime()));
|
||||
}
|
||||
trackData.lastLocationInCurrentSegment = null;
|
||||
}
|
||||
@@ -289,12 +286,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
}
|
||||
|
||||
Waypoint waypoint = new Waypoint();
|
||||
TrackPoint location = createTrackPoint();
|
||||
TrackPoint trackPoint = createTrackPoint();
|
||||
|
||||
if (!LocationUtils.isValidLocation(location)) {
|
||||
throw new SAXException(createErrorMessage("Invalid location detected: " + location));
|
||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||
throw new SAXException(createErrorMessage("Invalid location detected: " + trackPoint));
|
||||
}
|
||||
waypoint.setLocation(location);
|
||||
waypoint.setLocation(trackPoint.getLocation());
|
||||
|
||||
if (name != null) {
|
||||
waypoint.setName(name);
|
||||
@@ -316,11 +313,11 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
* Gets a track point.
|
||||
*/
|
||||
protected TrackPoint getTrackPoint() throws SAXException {
|
||||
TrackPoint location = createTrackPoint();
|
||||
TrackPoint trackPoint = createTrackPoint();
|
||||
|
||||
// Calculate derived attributes from the previous point
|
||||
if (trackData.lastLocationInCurrentSegment != null && trackData.lastLocationInCurrentSegment.getTime() != 0) {
|
||||
long timeDifference = location.getTime() - trackData.lastLocationInCurrentSegment.getTime();
|
||||
long timeDifference = trackPoint.getTime() - trackData.lastLocationInCurrentSegment.getTime();
|
||||
|
||||
// Check for negative time change
|
||||
if (timeDifference <= 0) {
|
||||
@@ -332,22 +329,22 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
* GPS points tend to have some inherent imprecision, speed and bearing will likely be off, so the statistics for things like max speed will also be off.
|
||||
*/
|
||||
double duration = timeDifference * UnitConversions.MS_TO_S;
|
||||
double speed = trackData.lastLocationInCurrentSegment.distanceTo(location) / duration;
|
||||
location.setSpeed((float) speed);
|
||||
double speed = trackData.lastLocationInCurrentSegment.distanceTo(trackPoint) / duration;
|
||||
trackPoint.setSpeed((float) speed);
|
||||
}
|
||||
location.setBearing(trackData.lastLocationInCurrentSegment.bearingTo(location));
|
||||
trackPoint.setBearing(trackData.lastLocationInCurrentSegment.bearingTo(trackPoint));
|
||||
}
|
||||
|
||||
if (!LocationUtils.isValidLocation(location)) {
|
||||
throw new SAXException(createErrorMessage("Invalid location detected: " + location));
|
||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||
throw new SAXException(createErrorMessage("Invalid location detected: " + trackPoint));
|
||||
}
|
||||
|
||||
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment == null) {
|
||||
// If not the first segment, add a resume separator before adding the first location.
|
||||
insertLocation(createTrackPoint(TrackPointsColumns.RESUME_LATITUDE, 0.0, 0.0, location.getTime()));
|
||||
insertLocation(TrackPoint.createResumeWithTime(trackPoint.getTime()));
|
||||
}
|
||||
trackData.lastLocationInCurrentSegment = location;
|
||||
return location;
|
||||
trackData.lastLocationInCurrentSegment = trackPoint;
|
||||
return trackPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,31 +413,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse time: %s", time)), e);
|
||||
}
|
||||
}
|
||||
return createTrackPoint(latitudeValue, longitudeValue, altitudeValue, timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a location.
|
||||
*
|
||||
* @param latitudeValue the latitude value
|
||||
* @param longitudeValue the longitude value
|
||||
* @param altitudeValue the altitude value
|
||||
* @param timeValue the time value
|
||||
*/
|
||||
private TrackPoint createTrackPoint(double latitudeValue, double longitudeValue, Double altitudeValue, long timeValue) {
|
||||
TrackPoint location = new TrackPoint(LocationManager.GPS_PROVIDER);
|
||||
location.setLatitude(latitudeValue);
|
||||
location.setLongitude(longitudeValue);
|
||||
if (altitudeValue != null) {
|
||||
location.setAltitude(altitudeValue);
|
||||
} else {
|
||||
location.removeAltitude();
|
||||
}
|
||||
location.setTime(timeValue);
|
||||
location.removeAccuracy();
|
||||
location.removeBearing();
|
||||
location.removeSpeed();
|
||||
return location;
|
||||
return new TrackPoint(latitudeValue, longitudeValue, altitudeValue, timeValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +472,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
int numberOfSegments = 0;
|
||||
|
||||
// The last location in the current segment; Null if the current segment doesn't have a last location
|
||||
Location lastLocationInCurrentSegment;
|
||||
TrackPoint lastLocationInCurrentSegment;
|
||||
|
||||
// The number of locations processed for the current track
|
||||
int numberOfLocations = 0;
|
||||
|
||||
@@ -311,7 +311,7 @@ public class TrackRecordingService extends Service {
|
||||
long duration = stats.getTotalTime();
|
||||
|
||||
// Insert waypoint
|
||||
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, length, duration, trackPoint, photoUrl);
|
||||
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, length, duration, trackPoint.getLocation(), photoUrl);
|
||||
Uri uri = contentProviderUtils.insertWaypoint(waypoint);
|
||||
return ContentUris.parseId(uri);
|
||||
}
|
||||
@@ -568,7 +568,8 @@ public class TrackRecordingService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
notificationManager.updateLocation(this, location, recordingGpsAccuracy);
|
||||
TrackPoint trackPoint = new TrackPoint(location, getSensorDataSet());
|
||||
notificationManager.updateTrackPoint(this, trackPoint, recordingGpsAccuracy);
|
||||
|
||||
if (!location.hasAccuracy() || location.getAccuracy() >= recordingGpsAccuracy) {
|
||||
Log.d(TAG, "Ignore onLocationChangedAsync. Poor accuracy.");
|
||||
@@ -583,15 +584,14 @@ public class TrackRecordingService extends Service {
|
||||
|
||||
TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
|
||||
long idleTime = 0L;
|
||||
if (lastValidTrackPoint != null && location.getTime() > lastValidTrackPoint.getTime()) {
|
||||
idleTime = location.getTime() - lastValidTrackPoint.getTime();
|
||||
if (lastValidTrackPoint != null && location.getTime() > lastValidTrackPoint.getLocation().getTime()) {
|
||||
idleTime = location.getTime() - lastValidTrackPoint.getLocation().getTime();
|
||||
}
|
||||
locationListenerPolicy.updateIdleTime(idleTime);
|
||||
if (currentRecordingInterval != locationListenerPolicy.getDesiredPollingInterval()) {
|
||||
registerLocationListener();
|
||||
}
|
||||
|
||||
TrackPoint trackPoint = new TrackPoint(location, getSensorDataSet());
|
||||
|
||||
// Always insert the first segment location
|
||||
if (!currentSegmentHasLocation) {
|
||||
@@ -601,14 +601,14 @@ public class TrackRecordingService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LocationUtils.isValidLocation(lastValidTrackPoint)) {
|
||||
if (!LocationUtils.isValidLocation(lastValidTrackPoint.getLocation())) {
|
||||
// Should not happen. The current segment should have a location. Just insert the current location.
|
||||
insertTrackPoint(track, trackPoint, null);
|
||||
lastTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
|
||||
double distanceToLastTrackLocation = location.distanceTo(lastValidTrackPoint);
|
||||
double distanceToLastTrackLocation = location.distanceTo(lastValidTrackPoint.getLocation());
|
||||
if (distanceToLastTrackLocation > maxRecordingDistance) {
|
||||
insertTrackPoint(track, lastTrackPoint, lastValidTrackPoint);
|
||||
insertTrackPoint(track, TrackPoint.createPause(), null);
|
||||
@@ -637,10 +637,10 @@ public class TrackRecordingService extends Service {
|
||||
* Inserts a trackPoint.
|
||||
*
|
||||
* @param track the track
|
||||
* @param trackPoint the trackPoint
|
||||
* @param trackPoint the trackPoint
|
||||
* @param lastValidTrackPoint the last valid track point, can be null
|
||||
*/
|
||||
private void insertTrackPoint(Track track, TrackPoint trackPoint, Location lastValidTrackPoint) {
|
||||
private void insertTrackPoint(Track track, TrackPoint trackPoint, TrackPoint lastValidTrackPoint) {
|
||||
if (trackPoint == null) {
|
||||
Log.w(TAG, "Ignore insertLocation. trackPoint is null.");
|
||||
return;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package de.dennisguse.opentracks.services;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
|
||||
/**
|
||||
@@ -82,8 +83,8 @@ class TrackRecordingServiceBinder extends android.os.Binder implements TrackReco
|
||||
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
public void insertTrackPoint(TrackPoint trackPoint) {
|
||||
trackRecordingService.onLocationChangedAsync(trackPoint);
|
||||
public void insertLocation(Location location) {
|
||||
trackRecordingService.onLocationChangedAsync(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package de.dennisguse.opentracks.services;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||
|
||||
/**
|
||||
@@ -95,15 +96,15 @@ public interface TrackRecordingServiceInterface {
|
||||
/**
|
||||
* ONLY FOR TESTING
|
||||
*
|
||||
* Inserts a track point in the current recording track.
|
||||
* Inserts a location in the current recording track.
|
||||
* <p>
|
||||
* When recording a track, GPS locations are automatically inserted. This is used for
|
||||
* inserting special track points or for testing.
|
||||
* When recording a track, GPS locations are automatically inserted.
|
||||
* This is used for inserting special track points or for testing.
|
||||
*
|
||||
* @param trackPoint the track point to be inserted
|
||||
* @param location the location to be inserted
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void insertTrackPoint(TrackPoint trackPoint);
|
||||
void insertLocation(Location location);
|
||||
|
||||
/**
|
||||
* Gets the current sensor data. Returns null if there is no data.
|
||||
|
||||
+5
-5
@@ -5,13 +5,13 @@ import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
|
||||
@@ -63,12 +63,12 @@ class TrackRecordingServiceNotificationManager {
|
||||
updateNotification();
|
||||
}
|
||||
|
||||
void updateLocation(Context context, Location location, int recordingGpsAccuracy) {
|
||||
void updateTrackPoint(Context context, TrackPoint trackPoint, int recordingGpsAccuracy) {
|
||||
String formattedAccuracy = context.getString(R.string.value_none);
|
||||
if (location.hasAccuracy()) {
|
||||
formattedAccuracy = StringUtils.formatDistance(context, location.getAccuracy(), PreferencesUtils.isMetricUnits(context));
|
||||
if (trackPoint.hasAccuracy()) {
|
||||
formattedAccuracy = StringUtils.formatDistance(context, trackPoint.getAccuracy(), PreferencesUtils.isMetricUnits(context));
|
||||
|
||||
boolean currentLocationWasAccurate = location.getAccuracy() < recordingGpsAccuracy;
|
||||
boolean currentLocationWasAccurate = trackPoint.getAccuracy() < recordingGpsAccuracy;
|
||||
boolean shouldAlert = !currentLocationWasAccurate && previousLocationWasAccurate;
|
||||
notificationBuilder.setOnlyAlertOnce(!shouldAlert);
|
||||
previousLocationWasAccurate = currentLocationWasAccurate;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package de.dennisguse.opentracks.stats;
|
||||
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -82,10 +81,10 @@ public class TripStatisticsUpdater {
|
||||
|
||||
// The current segment's trip statistics
|
||||
private TripStatistics currentSegment;
|
||||
// Current segment's last location.
|
||||
private Location lastLocation;
|
||||
// Current segment's last moving location
|
||||
private Location lastMovingLocation;
|
||||
// Current segment's last trackPoint
|
||||
private TrackPoint lastTrackPoint;
|
||||
// Current segment's last moving trackPoint
|
||||
private TrackPoint lastMovingTrackPoint;
|
||||
|
||||
/**
|
||||
* Creates a new trip statistics updater.
|
||||
@@ -131,18 +130,18 @@ public class TripStatisticsUpdater {
|
||||
*/
|
||||
public void addTrackPoint(TrackPoint trackPoint, int minRecordingDistance) {
|
||||
// Always update time
|
||||
updateTime(trackPoint.getTime());
|
||||
if (!LocationUtils.isValidLocation(trackPoint)) {
|
||||
updateTime(trackPoint.getLocation().getTime());
|
||||
if (!LocationUtils.isValidLocation(trackPoint.getLocation())) {
|
||||
// Either pause or resume marker
|
||||
if (trackPoint.getLatitude() == TrackPointsColumns.PAUSE_LATITUDE) {
|
||||
if (lastLocation != null && lastMovingLocation != null && lastLocation != lastMovingLocation) {
|
||||
currentSegment.addTotalDistance(lastMovingLocation.distanceTo(lastLocation));
|
||||
if (trackPoint.getLocation().getLatitude() == TrackPointsColumns.PAUSE_LATITUDE) {
|
||||
if (lastTrackPoint != null && lastMovingTrackPoint != null && lastTrackPoint != lastMovingTrackPoint) {
|
||||
currentSegment.addTotalDistance(lastMovingTrackPoint.distanceTo(lastTrackPoint));
|
||||
}
|
||||
tripStatistics.merge(currentSegment);
|
||||
}
|
||||
currentSegment = init(trackPoint.getTime());
|
||||
lastLocation = null;
|
||||
lastMovingLocation = null;
|
||||
currentSegment = init(trackPoint.getLocation().getTime());
|
||||
lastTrackPoint = null;
|
||||
lastMovingTrackPoint = null;
|
||||
elevationBuffer.reset();
|
||||
runBuffer.reset();
|
||||
gradeBuffer.reset();
|
||||
@@ -153,21 +152,21 @@ public class TripStatisticsUpdater {
|
||||
//TODO Use Barometer to compute elevation gain.
|
||||
double elevationDifference = trackPoint.hasAltitude() ? updateElevation(trackPoint.getAltitude()) : 0.0;
|
||||
|
||||
if (lastLocation == null || lastMovingLocation == null) {
|
||||
lastLocation = trackPoint;
|
||||
lastMovingLocation = trackPoint;
|
||||
if (lastTrackPoint == null || lastMovingTrackPoint == null) {
|
||||
lastTrackPoint = trackPoint;
|
||||
lastMovingTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
|
||||
double movingDistance = lastMovingLocation.distanceTo(trackPoint);
|
||||
double movingDistance = lastMovingTrackPoint.distanceTo(trackPoint);
|
||||
if (movingDistance < minRecordingDistance && (!trackPoint.hasSpeed() || trackPoint.getSpeed() < MAX_NO_MOVEMENT_SPEED)) {
|
||||
speedBuffer.reset();
|
||||
lastLocation = trackPoint;
|
||||
lastTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
long movingTime = trackPoint.getTime() - lastLocation.getTime();
|
||||
long movingTime = trackPoint.getTime() - lastTrackPoint.getTime();
|
||||
if (movingTime < 0) {
|
||||
lastLocation = trackPoint;
|
||||
lastTrackPoint = trackPoint;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -178,16 +177,16 @@ public class TripStatisticsUpdater {
|
||||
currentSegment.addMovingTime(movingTime);
|
||||
|
||||
// Update grade
|
||||
double run = lastLocation.distanceTo(trackPoint);
|
||||
double run = lastTrackPoint.distanceTo(trackPoint);
|
||||
updateGrade(run, elevationDifference);
|
||||
|
||||
// Update max speed
|
||||
if (trackPoint.hasSpeed() && lastLocation.hasSpeed()) {
|
||||
updateSpeed(trackPoint.getTime(), trackPoint.getSpeed(), lastLocation.getTime(), lastLocation.getSpeed());
|
||||
if (trackPoint.hasSpeed() && lastTrackPoint.hasSpeed()) {
|
||||
updateSpeed(trackPoint.getTime(), trackPoint.getSpeed(), lastTrackPoint.getTime(), lastTrackPoint.getSpeed());
|
||||
}
|
||||
|
||||
lastLocation = trackPoint;
|
||||
lastMovingLocation = trackPoint;
|
||||
lastTrackPoint = trackPoint;
|
||||
lastMovingTrackPoint = trackPoint;
|
||||
}
|
||||
|
||||
public void addTrackPoint(TrackPointIterator iterator, int minRecordingDistance) {
|
||||
|
||||
@@ -115,8 +115,7 @@ public class LocationUtils {
|
||||
current = stack.pop();
|
||||
maxDist = 0;
|
||||
for (idx = current[0] + 1; idx < current[1]; ++idx) {
|
||||
dist = LocationUtils.distance(
|
||||
trackPoints.get(idx), trackPoints.get(current[0]), trackPoints.get(current[1]));
|
||||
dist = LocationUtils.distance(trackPoints.get(idx).getLocation(), trackPoints.get(current[0]).getLocation(), trackPoints.get(current[1]).getLocation());
|
||||
if (dist > maxDist) {
|
||||
maxDist = dist;
|
||||
maxIdx = idx;
|
||||
@@ -165,7 +164,7 @@ public class LocationUtils {
|
||||
* @param location the location to test
|
||||
* @return true if the location is a valid location.
|
||||
*/
|
||||
//TODO Still needed?
|
||||
//TODO Move to TrackPoint
|
||||
public static boolean isValidLocation(Location location) {
|
||||
return location != null
|
||||
&& Math.abs(location.getLatitude()) <= 90
|
||||
|
||||
Reference in New Issue
Block a user