Replace high/low accuracy with omit rests option.
I have been feeling that the high/low accuracy switch is a bit misleading because while it can help us choose waypoints that are sufficiently far apart from each other, the accuracy of any individual waypoint isn't inherently better than normal. However, the option to omit or keep rests allows the user to keep the raw data or postprocess it in their own way; or accept the default different-enough detection.
This commit is contained in:
parent
981e8806b1
commit
3741d0baf5
7 changed files with 41 additions and 35 deletions
|
@ -56,7 +56,7 @@ object Keys {
|
||||||
const val PREF_TRACKING_STATE: String = "prefTrackingState"
|
const val PREF_TRACKING_STATE: String = "prefTrackingState"
|
||||||
const val PREF_USE_IMPERIAL_UNITS: String = "prefUseImperialUnits"
|
const val PREF_USE_IMPERIAL_UNITS: String = "prefUseImperialUnits"
|
||||||
const val PREF_GPS_ONLY: String = "prefGpsOnly"
|
const val PREF_GPS_ONLY: String = "prefGpsOnly"
|
||||||
const val PREF_RECORDING_ACCURACY_HIGH: String = "prefRecordingAccuracyHigh"
|
const val PREF_OMIT_RESTS: String = "prefOmitRests"
|
||||||
const val PREF_ALTITUDE_SMOOTHING_VALUE: String = "prefAltitudeSmoothingValue"
|
const val PREF_ALTITUDE_SMOOTHING_VALUE: String = "prefAltitudeSmoothingValue"
|
||||||
const val PREF_LOCATION_ACCURACY_THRESHOLD: String = "prefLocationAccuracyThreshold"
|
const val PREF_LOCATION_ACCURACY_THRESHOLD: String = "prefLocationAccuracyThreshold"
|
||||||
const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold"
|
const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold"
|
||||||
|
|
|
@ -65,6 +65,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
|
|
||||||
// set up "Restrict to GPS" preference
|
// set up "Restrict to GPS" preference
|
||||||
val preferenceGpsOnly: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
val preferenceGpsOnly: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
||||||
|
preferenceGpsOnly.isSingleLineTitle = false
|
||||||
preferenceGpsOnly.title = getString(R.string.pref_gps_only_title)
|
preferenceGpsOnly.title = getString(R.string.pref_gps_only_title)
|
||||||
preferenceGpsOnly.setIcon(R.drawable.ic_gps_24dp)
|
preferenceGpsOnly.setIcon(R.drawable.ic_gps_24dp)
|
||||||
preferenceGpsOnly.key = Keys.PREF_GPS_ONLY
|
preferenceGpsOnly.key = Keys.PREF_GPS_ONLY
|
||||||
|
@ -74,6 +75,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
|
|
||||||
// set up "Use Imperial Measurements" preference
|
// set up "Use Imperial Measurements" preference
|
||||||
val preferenceImperialMeasurementUnits: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
val preferenceImperialMeasurementUnits: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
||||||
|
preferenceImperialMeasurementUnits.isSingleLineTitle = false
|
||||||
preferenceImperialMeasurementUnits.title = getString(R.string.pref_imperial_measurement_units_title)
|
preferenceImperialMeasurementUnits.title = getString(R.string.pref_imperial_measurement_units_title)
|
||||||
preferenceImperialMeasurementUnits.setIcon(R.drawable.ic_square_foot_24px)
|
preferenceImperialMeasurementUnits.setIcon(R.drawable.ic_square_foot_24px)
|
||||||
preferenceImperialMeasurementUnits.key = Keys.PREF_USE_IMPERIAL_UNITS
|
preferenceImperialMeasurementUnits.key = Keys.PREF_USE_IMPERIAL_UNITS
|
||||||
|
@ -110,13 +112,15 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up "Recording Accuracy" preference
|
// set up "Recording Accuracy" preference
|
||||||
val preferenceRecordingAccuracy: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
val DEFAULT_OMIT_RESTS = true
|
||||||
preferenceRecordingAccuracy.title = getString(R.string.pref_recording_accuracy_title)
|
val preferenceOmitRests: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
|
||||||
preferenceRecordingAccuracy.setIcon(R.drawable.ic_timeline_24dp)
|
preferenceOmitRests.isSingleLineTitle = false
|
||||||
preferenceRecordingAccuracy.key = Keys.PREF_RECORDING_ACCURACY_HIGH
|
preferenceOmitRests.title = getString(R.string.pref_omit_rests_title)
|
||||||
preferenceRecordingAccuracy.summaryOn = getString(R.string.pref_recording_accuracy_summary_high)
|
preferenceOmitRests.setIcon(R.drawable.ic_timeline_24dp)
|
||||||
preferenceRecordingAccuracy.summaryOff = getString(R.string.pref_recording_accuracy_summary_default)
|
preferenceOmitRests.key = Keys.PREF_OMIT_RESTS
|
||||||
preferenceRecordingAccuracy.setDefaultValue(false)
|
preferenceOmitRests.summaryOn = getString(R.string.pref_omit_rests_on)
|
||||||
|
preferenceOmitRests.summaryOff = getString(R.string.pref_omit_rests_off)
|
||||||
|
preferenceOmitRests.setDefaultValue(DEFAULT_OMIT_RESTS)
|
||||||
|
|
||||||
// set up "Altitude Smoothing" preference
|
// set up "Altitude Smoothing" preference
|
||||||
// val preferenceAltitudeSmoothingValue: SeekBarPreference = SeekBarPreference(activity as Context)
|
// val preferenceAltitudeSmoothingValue: SeekBarPreference = SeekBarPreference(activity as Context)
|
||||||
|
@ -136,8 +140,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
preferenceResetAdvanced.setIcon(R.drawable.ic_undo_24dp)
|
preferenceResetAdvanced.setIcon(R.drawable.ic_undo_24dp)
|
||||||
preferenceResetAdvanced.summary = getString(R.string.pref_reset_advanced_summary)
|
preferenceResetAdvanced.summary = getString(R.string.pref_reset_advanced_summary)
|
||||||
preferenceResetAdvanced.setOnPreferenceClickListener{
|
preferenceResetAdvanced.setOnPreferenceClickListener{
|
||||||
// reset "Recording Accuracy" preference
|
preferenceOmitRests.isChecked = DEFAULT_OMIT_RESTS
|
||||||
preferenceRecordingAccuracy.isChecked = false
|
|
||||||
// preferenceAltitudeSmoothingValue.value = Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE
|
// preferenceAltitudeSmoothingValue.value = Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE
|
||||||
return@setOnPreferenceClickListener true
|
return@setOnPreferenceClickListener true
|
||||||
}
|
}
|
||||||
|
@ -168,7 +171,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
|
|
||||||
val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context)
|
val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context)
|
||||||
preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title)
|
preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title)
|
||||||
preferenceCategoryAdvanced.contains(preferenceRecordingAccuracy)
|
preferenceCategoryAdvanced.contains(preferenceOmitRests)
|
||||||
// preferenceCategoryAdvanced.contains(preferenceAltitudeSmoothingValue)
|
// preferenceCategoryAdvanced.contains(preferenceAltitudeSmoothingValue)
|
||||||
preferenceCategoryAdvanced.contains(preferenceResetAdvanced)
|
preferenceCategoryAdvanced.contains(preferenceResetAdvanced)
|
||||||
|
|
||||||
|
@ -184,7 +187,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
|
||||||
screen.addPreference(preferenceCategoryMaintenance)
|
screen.addPreference(preferenceCategoryMaintenance)
|
||||||
screen.addPreference(preferenceDeleteNonStarred)
|
screen.addPreference(preferenceDeleteNonStarred)
|
||||||
screen.addPreference(preferenceCategoryAdvanced)
|
screen.addPreference(preferenceCategoryAdvanced)
|
||||||
screen.addPreference(preferenceRecordingAccuracy)
|
screen.addPreference(preferenceOmitRests)
|
||||||
// screen.addPreference(preferenceAltitudeSmoothingValue)
|
// screen.addPreference(preferenceAltitudeSmoothingValue)
|
||||||
screen.addPreference(preferenceResetAdvanced)
|
screen.addPreference(preferenceResetAdvanced)
|
||||||
screen.addPreference(preferenceCategoryAbout)
|
screen.addPreference(preferenceCategoryAbout)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class TrackerService: Service(), SensorEventListener {
|
||||||
var networkProviderActive: Boolean = false
|
var networkProviderActive: Boolean = false
|
||||||
var useImperial: Boolean = false
|
var useImperial: Boolean = false
|
||||||
var gpsOnly: Boolean = false
|
var gpsOnly: Boolean = false
|
||||||
var accuracyMultiplier: Int = 1
|
var omitRests: Boolean = true
|
||||||
var currentBestLocation: Location = LocationHelper.getDefaultLocation()
|
var currentBestLocation: Location = LocationHelper.getDefaultLocation()
|
||||||
var lastSave: Date = Keys.DEFAULT_DATE
|
var lastSave: Date = Keys.DEFAULT_DATE
|
||||||
var stepCountOffset: Float = 0f
|
var stepCountOffset: Float = 0f
|
||||||
|
@ -81,7 +81,7 @@ class TrackerService: Service(), SensorEventListener {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
gpsOnly = PreferencesHelper.loadGpsOnly()
|
gpsOnly = PreferencesHelper.loadGpsOnly()
|
||||||
useImperial = PreferencesHelper.loadUseImperialUnits()
|
useImperial = PreferencesHelper.loadUseImperialUnits()
|
||||||
accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier()
|
omitRests = PreferencesHelper.loadOmitRests()
|
||||||
|
|
||||||
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||||
|
@ -438,8 +438,8 @@ class TrackerService: Service(), SensorEventListener {
|
||||||
useImperial = PreferencesHelper.loadUseImperialUnits()
|
useImperial = PreferencesHelper.loadUseImperialUnits()
|
||||||
}
|
}
|
||||||
// preference "Recording Accuracy"
|
// preference "Recording Accuracy"
|
||||||
Keys.PREF_RECORDING_ACCURACY_HIGH -> {
|
Keys.PREF_OMIT_RESTS -> {
|
||||||
accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier()
|
omitRests = PreferencesHelper.loadOmitRests()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ class TrackerService: Service(), SensorEventListener {
|
||||||
private val periodicTrackUpdate: Runnable = object : Runnable {
|
private val periodicTrackUpdate: Runnable = object : Runnable {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
// add waypoint to track - step count is continuously updated in onSensorChanged
|
// add waypoint to track - step count is continuously updated in onSensorChanged
|
||||||
val result: Pair<Boolean, Track> = TrackHelper.addWayPointToTrack(track, currentBestLocation, accuracyMultiplier, resumed)
|
val result: Pair<Boolean, Track> = TrackHelper.addWayPointToTrack(track, currentBestLocation, omitRests, resumed)
|
||||||
// get results
|
// get results
|
||||||
val successfullyAdded: Boolean = result.first
|
val successfullyAdded: Boolean = result.first
|
||||||
track = result.second
|
track = result.second
|
||||||
|
|
|
@ -178,10 +178,17 @@ object LocationHelper {
|
||||||
|
|
||||||
|
|
||||||
/* Checks if given location is different enough compared to previous location */
|
/* Checks if given location is different enough compared to previous location */
|
||||||
fun isDifferentEnough(previousLocation: Location?, location: Location, accuracyMultiplier: Int): Boolean {
|
fun isDifferentEnough(previousLocation: Location?, location: Location, omitRests: Boolean): Boolean {
|
||||||
// check if previous location is (not) available
|
// check if previous location is (not) available
|
||||||
if (previousLocation == null) return true
|
if (previousLocation == null)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! omitRests)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
}
|
||||||
// location.accuracy is given as 1 standard deviation, with a 68% chance
|
// location.accuracy is given as 1 standard deviation, with a 68% chance
|
||||||
// that the true position is within a circle of this radius.
|
// that the true position is within a circle of this radius.
|
||||||
// These formulas determine if the difference between the last point and
|
// These formulas determine if the difference between the last point and
|
||||||
|
@ -194,7 +201,7 @@ object LocationHelper {
|
||||||
// With 1*accuracyDelta we have 68% confidence that the points are
|
// With 1*accuracyDelta we have 68% confidence that the points are
|
||||||
// different. We can multiply this number to increase confidence but
|
// different. We can multiply this number to increase confidence but
|
||||||
// decrease point recording frequency if needed.
|
// decrease point recording frequency if needed.
|
||||||
return distance > accuracyDelta * accuracyMultiplier
|
return distance > accuracyDelta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,16 +101,10 @@ object PreferencesHelper {
|
||||||
// return sharedPreferences.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false)
|
// return sharedPreferences.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
fun loadOmitRests(): Boolean {
|
||||||
/* Loads current accuracy multiplier */
|
return sharedPreferences.getBoolean(Keys.PREF_OMIT_RESTS, true)
|
||||||
fun loadAccuracyMultiplier(): Int {
|
|
||||||
// load current setting
|
|
||||||
val recordingAccuracyHigh: Boolean = sharedPreferences.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false)
|
|
||||||
// return multiplier based on state
|
|
||||||
return if (recordingAccuracyHigh) 2 else 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// /* Load altitude smoothing value */
|
// /* Load altitude smoothing value */
|
||||||
// fun loadAltitudeSmoothingValue(): Int {
|
// fun loadAltitudeSmoothingValue(): Int {
|
||||||
// // load current setting
|
// // load current setting
|
||||||
|
|
|
@ -41,7 +41,7 @@ object TrackHelper {
|
||||||
private val TAG: String = LogHelper.makeLogTag(TrackHelper::class.java)
|
private val TAG: String = LogHelper.makeLogTag(TrackHelper::class.java)
|
||||||
|
|
||||||
/* Adds given locatiom as waypoint to track */
|
/* Adds given locatiom as waypoint to track */
|
||||||
fun addWayPointToTrack(track: Track, location: Location, accuracyMultiplier: Int, resumed: Boolean): Pair<Boolean, Track> {
|
fun addWayPointToTrack(track: Track, location: Location, omitRests: Boolean, resumed: Boolean): Pair<Boolean, Track> {
|
||||||
// Step 1: Get previous location
|
// Step 1: Get previous location
|
||||||
val previousLocation: Location?
|
val previousLocation: Location?
|
||||||
var numberOfWayPoints: Int = track.wayPoints.size
|
var numberOfWayPoints: Int = track.wayPoints.size
|
||||||
|
@ -68,9 +68,11 @@ object TrackHelper {
|
||||||
track.recordingStop = now
|
track.recordingStop = now
|
||||||
|
|
||||||
// Step 3: Add waypoint, ifrecent and accurate and different enough
|
// Step 3: Add waypoint, ifrecent and accurate and different enough
|
||||||
val shouldBeAdded: Boolean = (LocationHelper.isRecentEnough(location) &&
|
val shouldBeAdded: Boolean = (
|
||||||
|
LocationHelper.isRecentEnough(location) &&
|
||||||
LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) &&
|
LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) &&
|
||||||
LocationHelper.isDifferentEnough(previousLocation, location, accuracyMultiplier))
|
LocationHelper.isDifferentEnough(previousLocation, location, omitRests)
|
||||||
|
)
|
||||||
if (shouldBeAdded) {
|
if (shouldBeAdded) {
|
||||||
// Step 3.1: Update distance (do not update if resumed -> we do not want to add values calculated during a recording pause)
|
// Step 3.1: Update distance (do not update if resumed -> we do not want to add values calculated during a recording pause)
|
||||||
if (!resumed) {
|
if (!resumed) {
|
||||||
|
|
|
@ -96,9 +96,9 @@
|
||||||
<string name="pref_imperial_measurement_units_summary_metric">Currently using metric units (Kilometer, Meter).</string>
|
<string name="pref_imperial_measurement_units_summary_metric">Currently using metric units (Kilometer, Meter).</string>
|
||||||
<string name="pref_imperial_measurement_units_summary_imperial">Currently using imperial units (Miles, Feet).</string>
|
<string name="pref_imperial_measurement_units_summary_imperial">Currently using imperial units (Miles, Feet).</string>
|
||||||
<string name="pref_imperial_measurement_units_title">Use Imperial Measurements</string>
|
<string name="pref_imperial_measurement_units_title">Use Imperial Measurements</string>
|
||||||
<string name="pref_recording_accuracy_summary_high">Waypoints have higher accuracy but are less frequent.</string>
|
<string name="pref_omit_rests_on">Waypoints will not be recorded if they are too close to the previous waypoint.</string>
|
||||||
<string name="pref_recording_accuracy_summary_default">Waypoints have lower accuracy but are more frequent.</string>
|
<string name="pref_omit_rests_off">All waypoints will be recorded, even while standing still.</string>
|
||||||
<string name="pref_recording_accuracy_title">Recording Accuracy</string>
|
<string name="pref_omit_rests_title">Omit points during rests</string>
|
||||||
<string name="pref_report_issue_summary">Report bugs and suggest improvements on GitHub.</string>
|
<string name="pref_report_issue_summary">Report bugs and suggest improvements on GitHub.</string>
|
||||||
<string name="pref_report_issue_title">Report Issue</string>
|
<string name="pref_report_issue_title">Report Issue</string>
|
||||||
<string name="pref_reset_advanced_summary">Reset advanced settings to defaults.</string>
|
<string name="pref_reset_advanced_summary">Reset advanced settings to defaults.</string>
|
||||||
|
|
Loading…
Reference in a new issue