plausibility check for the first location (which sometimes can be wrong)

This commit is contained in:
y20k 2020-03-24 15:26:01 +01:00
parent 3324f859b7
commit 1e0bb81a38
No known key found for this signature in database
GPG key ID: 824D4259F41FAFF6
5 changed files with 49 additions and 6 deletions

View file

@ -99,6 +99,7 @@ object Keys {
const val ADD_WAYPOINT_TO_TRACK_INTERVAL: Long = 15000L // 15 seconds in milliseconds const val ADD_WAYPOINT_TO_TRACK_INTERVAL: Long = 15000L // 15 seconds in milliseconds
const val SIGNIFICANT_TIME_DIFFERENCE: Long = 120000L // 2 minutes in milliseconds const val SIGNIFICANT_TIME_DIFFERENCE: Long = 120000L // 2 minutes in milliseconds
const val STOP_OVER_THRESHOLD: Long = 300000L // 5 minutes in milliseconds const val STOP_OVER_THRESHOLD: Long = 300000L // 5 minutes in milliseconds
const val IMPLAUSIBLE_TRACK_START_SPEED: Double = 250.0 // 250 km/h
const val DEFAULT_LATITUDE: Double = 71.172500 // latitude Nordkapp, Norway const val DEFAULT_LATITUDE: Double = 71.172500 // latitude Nordkapp, Norway
const val DEFAULT_LONGITUDE: Double = 25.784444 // longitude Nordkapp, Norway const val DEFAULT_LONGITUDE: Double = 25.784444 // longitude Nordkapp, Norway
const val DEFAULT_ACCURACY: Float = 300f // in meters const val DEFAULT_ACCURACY: Float = 300f // in meters

View file

@ -92,4 +92,17 @@ object LengthUnitHelper {
return imperialSystemCountries.contains(countryCode) return imperialSystemCountries.contains(countryCode)
} }
/* Coverts meters per second to either km/h or mph */
fun convertMetersPerSecond(metersPerSecond: Float, useImperial: Boolean = false): Double {
if (useImperial) {
// mph
return metersPerSecond * 2.2369362920544
} else {
// km/h
return metersPerSecond * 3.6
}
}
} }

View file

@ -155,6 +155,26 @@ object LocationHelper {
} }
/* Checks if the first location of track is plausible */
fun isFirstLocationPlausible(secondLocation: Location, track: Track): Boolean {
// speed in km/h
val speed: Double = calculateSpeed(firstLocation = track.wayPoints[0].toLocation(), secondLocation = secondLocation, firstTimestamp = track.recordingStart.time, secondTimestamp = GregorianCalendar.getInstance().time.time)
// plausible = speed under 250 km/h
return speed < Keys.IMPLAUSIBLE_TRACK_START_SPEED
}
/* Calculates speed */
private fun calculateSpeed(firstLocation: Location, secondLocation: Location, firstTimestamp: Long, secondTimestamp: Long, useImperial: Boolean = false): Double {
// time difference in seconds
val timeDifference: Long = (secondTimestamp - firstTimestamp) / 1000L
// distance in meters
val distance: Float = calculateDistance(firstLocation, secondLocation)
// speed in either km/h (default) or mph
return LengthUnitHelper.convertMetersPerSecond(distance / timeDifference, useImperial)
}
/* 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): Boolean { fun isDifferentEnough(previousLocation: Location?, location: Location): Boolean {
// check if previous location is (not) available // check if previous location is (not) available
@ -173,7 +193,7 @@ object LocationHelper {
} }
/* Calculates distance between two locations */ /* Calculates distance in meters between two locations */
fun calculateDistance(previousLocation: Location?, location: Location): Float { fun calculateDistance(previousLocation: Location?, location: Location): Float {
var distance: Float = 0f var distance: Float = 0f
// two data points needed to calculate distance // two data points needed to calculate distance

View file

@ -46,13 +46,22 @@ object TrackHelper {
/* Adds given locatiom as waypoint to track */ /* Adds given locatiom as waypoint to track */
fun addWayPointToTrack(track: Track, location: Location, locationAccuracyThreshold: Int, resumed: Boolean): Pair<Track, Boolean> { fun addWayPointToTrack(track: Track, location: Location, locationAccuracyThreshold: Int, resumed: Boolean): Pair<Track, Boolean> {
// get previous location // get previous location
val previousLocation: Location? val previousLocation: Location?
val numberOfWayPoints: Int = track.wayPoints.size var numberOfWayPoints: Int = track.wayPoints.size
// CASE: First location
if (numberOfWayPoints == 0) { if (numberOfWayPoints == 0) {
previousLocation = null previousLocation = null
} else { }
// CASE: Second location - check if first location was plausible & remove implausible location
else if (numberOfWayPoints == 1 && !LocationHelper.isFirstLocationPlausible(location, track)) {
previousLocation = null
numberOfWayPoints = 0
track.wayPoints.removeAt(0)
}
// CASE: Third location or second location (if first was plausible)
else {
previousLocation = track.wayPoints.get(numberOfWayPoints - 1).toLocation() previousLocation = track.wayPoints.get(numberOfWayPoints - 1).toLocation()
} }

View file

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.61' ext.kotlin_version = '1.3.71'
repositories { repositories {
google() google()
jcenter() jcenter()
@ -10,7 +10,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.1' classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.0" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.1"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }