Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions OsmAnd/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4481,6 +4481,8 @@ Download tile maps directly, or copy them as SQLite database files to OsmAnd\'s
<string name="stop_navigation_service">Stop</string>
<string name="confirm_every_run">Always ask</string>
<string name="save_global_track_interval">General logging interval</string>
<string name="save_track_unfiltered_title">Save full track</string>
<string name="save_track_unfiltered_descr">If enabled, both full and filtered tracks will be saved</string>
<string name="background_service_int">GPS Wake-up interval</string>
<string name="enable_sleep_mode">Enable GPS background mode</string>
<string name="save_track_to_gpx_globally_headline">On demand track logging</string>
Expand Down
7 changes: 7 additions & 0 deletions OsmAnd/res/xml/monitoring_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@
android:layout="@layout/preference_category_with_descr"
android:title="@string/save_track_logging_accuracy" />

<net.osmand.plus.settings.preferences.SwitchPreferenceEx
android:key="save_track_unfiltered"
android:layout="@layout/preference_with_descr_dialog_and_switch"
android:summaryOff="@string/shared_string_disabled"
android:summaryOn="@string/shared_string_enabled"
android:title="@string/save_track_unfiltered_title" />

<net.osmand.plus.settings.preferences.ListPreferenceEx
android:key="save_global_track_interval"
android:layout="@layout/preference_with_descr"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public Bundle buildArguments() {
protected void setupPreferences() {
setupDisableBatteryOptimizationPref();
setupShowStartDialog();

setupSaveTrackUnfiltered();
setupSaveTrackToGpxPref();
setupSaveTrackIntervalPref();

Expand Down Expand Up @@ -147,6 +147,11 @@ private void setupShowStartDialog() {
showStartDialog.setIcon(getPersistentPrefIcon(R.drawable.ic_action_dialog));
}

private void setupSaveTrackUnfiltered() {
SwitchPreferenceEx showStartDialog = findPreference(settings.SAVE_TRACK_UNFILTERED.getId());
showStartDialog.setDescription(getString(R.string.save_track_unfiltered_descr));
}

private void setupSaveTrackToGpxPref() {
SwitchPreferenceCompat saveTrackToGpx = findPreference(settings.SAVE_TRACK_TO_GPX.getId());
saveTrackToGpx.setSummary(getString(R.string.save_track_to_gpx_descrp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public OsmandMonitoringPlugin(OsmandApplication app) {
pluginPreferences.add(settings.SAVE_TRACK_INTERVAL);
pluginPreferences.add(settings.SAVE_TRACK_MIN_DISTANCE);
pluginPreferences.add(settings.SAVE_TRACK_PRECISION);
pluginPreferences.add(settings.SAVE_TRACK_UNFILTERED);
pluginPreferences.add(settings.AUTO_SPLIT_RECORDING);
pluginPreferences.add(settings.DISABLE_RECORDING_ONCE_APP_KILLED);
pluginPreferences.add(settings.SHOW_TRIP_REC_NOTIFICATION);
Expand Down
159 changes: 112 additions & 47 deletions OsmAnd/src/net/osmand/plus/plugins/monitoring/SavingTrackHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,15 @@ public synchronized SaveGpxResult saveDataToGpx(@NonNull File dir) {
for (Map.Entry<String, GpxFile> entry : data.entrySet()) {
String f = entry.getKey();
GpxFile gpx = entry.getValue();
log.debug("Filename: " + f);

GpxFile filteredGpx = SavedTrackFilter.filterGpxFile(gpx, settings);

File fout = new File(dir, f + IndexConstants.GPX_FILE_EXT);
if (!gpx.isEmpty()) {
WptPt pt = gpx.findPointToShow();
long time = pt != null ? pt.getTime() : System.currentTimeMillis();
String fileName = f + "_" + GPX_FILE_DATE_FORMAT.format(new Date(time));
WptPt pt = filteredGpx.findPointToShow();
long time = pt != null ? pt.getTime() : System.currentTimeMillis();
String fileName = f + "_" + GPX_FILE_DATE_FORMAT.format(new Date(time));

if (!filteredGpx.isEmpty()) {
Integer trackStorageDirectory = app.getSettings().TRACK_STORAGE_DIRECTORY.get();
if (!OsmandSettings.REC_DIRECTORY.equals(trackStorageDirectory)) {
SimpleDateFormat dateDirFormat = new SimpleDateFormat("yyyy-MM", Locale.US);
Expand All @@ -256,24 +259,40 @@ public synchronized SaveGpxResult saveDataToGpx(@NonNull File dir) {
fileName = dateDirName + File.separator + fileName;
}
}
gpxFilesByName.put(fileName, gpx);
gpxFilesByName.put(fileName, filteredGpx);
fout = new File(dir, fileName + IndexConstants.GPX_FILE_EXT);
int ind = 1;
while (fout.exists()) {
fout = new File(dir, fileName + "_" + (++ind) + IndexConstants.GPX_FILE_EXT); //$NON-NLS-1$
}
}
savePreselectedRouteActivity(gpx);
savePreselectedRouteActivity(filteredGpx);

KFile fKout = SharedUtil.kFile(fout);
Exception warn = SharedUtil.writeGpxFile(fKout, gpx);
Exception warn = SharedUtil.writeGpxFile(fKout, filteredGpx);
if (warn != null) {
warnings.add(warn.getMessage());
return new SaveGpxResult(warnings, new HashMap<>());
}

if (settings.SAVE_TRACK_UNFILTERED.get()) {
File dir_un = new File(dir, "unfiltered");
File fout_un = new File(dir_un, fileName + IndexConstants.GPX_FILE_EXT);
int ind = 1;
while (fout_un.exists()) {
fout_un = new File(dir_un, fileName + "_" + (++ind) + "_unfiltered" + IndexConstants.GPX_FILE_EXT); //$NON-NLS-1$
}

KFile fKout_un = SharedUtil.kFile(fout_un);
warn = SharedUtil.writeGpxFile(fKout_un, gpx);
if (warn != null) {
warnings.add(warn.getMessage());
return new SaveGpxResult(warnings, new HashMap<>());
}
}

GpxDataItem item = new GpxDataItem(fKout);
item.setAnalysis(gpx.getAnalysis(fout.lastModified()));
item.setAnalysis(filteredGpx.getAnalysis(fout.lastModified()));
app.getGpxDbHelper().add(item);
lastTimeFileSaved = fout.lastModified();
saveTrackAppearance(item);
Expand Down Expand Up @@ -521,49 +540,20 @@ public void updateLocation(@Nullable Location location, @Nullable Float heading)
} else if (settings.getApplicationMode() == settings.DEFAULT_APPLICATION_MODE.get()) {
lastRoutingApplicationMode = null;
}
boolean record = shouldRecordLocation(location, time);
if (record) {
heading = getAdjustedHeading(heading);

WptPt wptPt = new WptPt(location.getLatitude(), location.getLongitude(), time,
location.getAltitude(), location.getSpeed(), location.getAccuracy(), heading);
heading = getAdjustedHeading(heading);

String pluginsInfo = getPluginsInfo(location);
Map<String, String> extensions = getPluginsExtensions(pluginsInfo);
if (!Algorithms.isEmpty(extensions)) {
GpxUtilities.INSTANCE.assignExtensionWriter(wptPt, extensions, "plugins");
}
WptPt wptPt = new WptPt(location.getLatitude(), location.getLongitude(), time,
location.getAltitude(), location.getSpeed(), location.getAccuracy(), heading);

insertData(wptPt, pluginsInfo);
app.getNotificationHelper().refreshNotification(NotificationType.GPX);
String pluginsInfo = getPluginsInfo(location);
Map<String, String> extensions = getPluginsExtensions(pluginsInfo);
if (!Algorithms.isEmpty(extensions)) {
GpxUtilities.INSTANCE.assignExtensionWriter(wptPt, extensions, "plugins");
}
}

private boolean shouldRecordLocation(@Nullable Location location, long locationTime) {
boolean record = false;
if (location != null && SimulationProvider.isNotSimulatedLocation(location)
&& PluginsHelper.isActive(OsmandMonitoringPlugin.class)) {
if (isRecordingAutomatically() && locationTime - lastTimeUpdated > settings.SAVE_TRACK_INTERVAL.get()) {
record = true;
} else if (settings.SAVE_GLOBAL_TRACK_TO_GPX.get()
&& locationTime - lastTimeUpdated > settings.SAVE_GLOBAL_TRACK_INTERVAL.get()) {
record = true;
}
float minDistance = settings.SAVE_TRACK_MIN_DISTANCE.get();
if (minDistance > 0 && lastPoint != null
&& MapUtils.getDistance(lastPoint, location.getLatitude(), location.getLongitude()) < minDistance) {
record = false;
}
float precision = settings.SAVE_TRACK_PRECISION.get();
if (precision > 0 && (!location.hasAccuracy() || location.getAccuracy() > precision)) {
record = false;
}
float minSpeed = settings.SAVE_TRACK_MIN_SPEED.get();
if (minSpeed > 0 && (!location.hasSpeed() || location.getSpeed() < minSpeed)) {
record = false;
}
}
return record;
insertData(wptPt, pluginsInfo);
app.getNotificationHelper().refreshNotification(NotificationType.GPX);
}

private float getAdjustedHeading(@Nullable Float heading) {
Expand Down Expand Up @@ -913,4 +903,79 @@ public void routeWasCancelled() {
public void routeWasFinished() {
shouldAutomaticallyRecord = true;
}

private static class SavedTrackFilter {
LatLon lastFilteredPoint = null;
long lastFilteredTime = -1;
OsmandSettings settings;

public static GpxFile filterGpxFile(@NonNull GpxFile gpx, @NonNull OsmandSettings settings) {
SavedTrackFilter inst = new SavedTrackFilter(settings);

assert (gpx.getTracks().isEmpty() == false) : "GpxFile contains no tracks";
Track track = gpx.getTracks().get(0);
var filteredSegments = new ArrayList<TrkSegment>();

for (TrkSegment segment : track.getSegments()) {
var filteredPoints = new ArrayList<WptPt>();
for(WptPt point : segment.getPoints()) {
var latlon = new LatLon(point.getLat(), point.getLon());
if (inst.isFiltered(latlon, point.getTime(), point.getSpeed(), point.getHdop())) {
filteredPoints.add(point);
}
}

var filteredSegment = new TrkSegment();
filteredSegment.setPoints(filteredPoints);
filteredSegments.add(filteredSegment);
}

var filteredTrack = new Track();
filteredTrack.setSegments(filteredSegments);

var filteredTrackArray = new ArrayList<Track>();
filteredTrackArray.add(filteredTrack);

GpxFile res = gpx.clone();
res.setTracks(filteredTrackArray);
return res;
};

private SavedTrackFilter(@NonNull OsmandSettings _settings)
{
this.settings = _settings;
}

private boolean isFiltered(@Nullable LatLon location, long locationTime, double speed, double accuracy) {
boolean record = false;
if ((location != null)
// && SimulationProvider.isNotSimulatedLocation(location)
&& PluginsHelper.isActive(OsmandMonitoringPlugin.class)) {
// if (isRecordingAutomatically() &&
if( locationTime - lastFilteredTime > settings.SAVE_TRACK_INTERVAL.get()) {
lastFilteredTime = locationTime;
record = true;
} else if (settings.SAVE_GLOBAL_TRACK_TO_GPX.get()
&& locationTime - lastFilteredTime > settings.SAVE_GLOBAL_TRACK_INTERVAL.get()) {
lastFilteredTime = locationTime;
record = true;
}
float minDistance = settings.SAVE_TRACK_MIN_DISTANCE.get();
if (minDistance > 0 && lastFilteredPoint != null
&& MapUtils.getDistance(lastFilteredPoint, location) < minDistance) {
record = false;
lastFilteredPoint = location;
}
float precision = settings.SAVE_TRACK_PRECISION.get();
if (precision > 0 && (Double.isNaN(accuracy) || accuracy > precision)) {
record = false;
}
float minSpeed = settings.SAVE_TRACK_MIN_SPEED.get();
if (minSpeed > 0 && (Double.isNaN(speed) || speed < minSpeed)) {
record = false;
}
}
return record;
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,8 @@ public boolean isProxyEnabled() {
SAVE_TRACK_TO_GPX.setModeDefaultValue(ApplicationMode.PEDESTRIAN, false);
}

public final CommonPreference<Boolean> SAVE_TRACK_UNFILTERED = new BooleanPreference(this, "save_track_unfiltered", false).makeProfile().cache();

public static final Integer REC_DIRECTORY = 0;
public static final Integer MONTHLY_DIRECTORY = 1;
// public static final Integer DAILY_DIRECTORY = 2;
Expand Down