checkpoint
This commit is contained in:
		
							parent
							
								
									8cbfa729f0
								
							
						
					
					
						commit
						aca4cf20c0
					
				
					 7 changed files with 52 additions and 57 deletions
				
			
		|  | @ -6,9 +6,8 @@ import android.util.Log | |||
| import java.io.File | ||||
| import java.util.* | ||||
| 
 | ||||
| class Database(trackbook: Trackbook) | ||||
| class Database(val trackbook: Trackbook) | ||||
| { | ||||
|     val trackbook = trackbook | ||||
|     var ready: Boolean = false | ||||
|     lateinit var file: File | ||||
|     lateinit var connection: SQLiteDatabase | ||||
|  | @ -96,8 +95,12 @@ class Database(trackbook: Trackbook) | |||
|     fun update_homepoint(id: Long, name: String, radius: Double) | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "Database.update_homepoint") | ||||
|         val values = ContentValues().apply { | ||||
|             put("name", name) | ||||
|             put("radius", radius) | ||||
|         } | ||||
|         begin_transaction() | ||||
|         connection.rawQuery("UPDATE homepoints SET name = ?, radius = ? WHERE id = ?", arrayOf(name, radius.toString(), id.toString())) | ||||
|         connection.update("homepoints", values, "id = ?", arrayOf(id.toString())) | ||||
|         commit() | ||||
|     } | ||||
| 
 | ||||
|  | @ -107,6 +110,7 @@ class Database(trackbook: Trackbook) | |||
|         this.connection.execSQL("CREATE TABLE IF NOT EXISTS meta(name TEXT PRIMARY KEY, value TEXT)") | ||||
|         this.connection.execSQL("CREATE TABLE IF NOT EXISTS trkpt(lat REAL NOT NULL, lon REAL NOT NULL, time INTEGER NOT NULL, accuracy REAL, device_id INTEGER NOT NULL, ele INTEGER, sat INTEGER, PRIMARY KEY(lat, lon, time, device_id))") | ||||
|         this.connection.execSQL("CREATE TABLE IF NOT EXISTS homepoints(id INTEGER PRIMARY KEY, lat REAL NOT NULL, lon REAL NOT NULL, radius REAL NOT NULL, name TEXT)") | ||||
|         this.connection.execSQL("PRAGMA user_version = ${Keys.CURRENT_TRACKLIST_FORMAT_VERSION}") | ||||
|         this.connection.setTransactionSuccessful() | ||||
|         this.connection.endTransaction() | ||||
|     } | ||||
|  |  | |||
|  | @ -77,18 +77,9 @@ object Keys { | |||
|     const val DIALOG_EMPTY_PAYLOAD_STRING: String = "" | ||||
|     const val DIALOG_EMPTY_PAYLOAD_INT: Int = -1 | ||||
| 
 | ||||
|     // folder names | ||||
|     const val FOLDER_TEMP: String  = "temp" | ||||
|     const val FOLDER_TRACKS: String = "tracks" | ||||
|     const val FOLDER_GPX: String = "gpx" | ||||
| 
 | ||||
|     // file names and extensions | ||||
|     const val MIME_TYPE_GPX: String = "application/gpx+xml" | ||||
|     const val GPX_FILE_EXTENSION: String = ".gpx" | ||||
|     const val TRACKBOOK_LEGACY_FILE_EXTENSION: String = ".trackbook" | ||||
|     const val TRACKBOOK_FILE_EXTENSION: String = ".json" | ||||
|     const val TEMP_FILE: String = "temp.json" | ||||
|     const val TRACKLIST_FILE: String = "tracklist.json" | ||||
| 
 | ||||
|     // view types | ||||
|     const val VIEW_TYPE_STATISTICS: Int = 1 | ||||
|  | @ -96,13 +87,11 @@ object Keys { | |||
| 
 | ||||
|     // default values | ||||
|     val DEFAULT_DATE: Date = Date(0L) | ||||
|     const val DEFAULT_RFC2822_DATE: String = "Thu, 01 Jan 1970 01:00:00 +0100"  // --> Date(0) | ||||
|     const val ONE_SECOND_IN_MILLISECONDS: Long = 1000 | ||||
|     const val ONE_MINUTE_IN_MILLISECONDS: Long = 60 * ONE_SECOND_IN_MILLISECONDS | ||||
|     const val ONE_HOUR_IN_MILLISECONDS: Long = 60 * ONE_MINUTE_IN_MILLISECONDS | ||||
|     const val EMPTY_STRING_RESOURCE: Int = 0 | ||||
|     const val REQUEST_CURRENT_LOCATION_INTERVAL: Long = 1 * ONE_SECOND_IN_MILLISECONDS | ||||
|     const val TRACKING_INTERVAL: Long = 1 * ONE_SECOND_IN_MILLISECONDS | ||||
|     const val SAVE_TEMP_TRACK_INTERVAL: Long = 30 * ONE_SECOND_IN_MILLISECONDS | ||||
|     const val SIGNIFICANT_TIME_DIFFERENCE: Long = 1 * ONE_MINUTE_IN_MILLISECONDS | ||||
|     const val STOP_OVER_THRESHOLD: Long = 5 * ONE_MINUTE_IN_MILLISECONDS | ||||
|  | @ -113,7 +102,6 @@ object Keys { | |||
|     const val DEFAULT_ALTITUDE: Double = 0.0 | ||||
|     const val DEFAULT_TIME: Long = 0L | ||||
|     const val COMMIT_INTERVAL: Int = 30 | ||||
|     const val DEFAULT_ALTITUDE_SMOOTHING_VALUE: Int = 13 | ||||
|     const val DEFAULT_THRESHOLD_LOCATION_ACCURACY: Int = 30                     // 30 meters | ||||
|     const val DEFAULT_THRESHOLD_LOCATION_AGE: Long = 5_000_000_000L             // 5s in nanoseconds | ||||
|     const val DEFAULT_THRESHOLD_DISTANCE: Float = 15f                           // 15 meters | ||||
|  |  | |||
|  | @ -138,6 +138,7 @@ class MapFragment : Fragment() | |||
|         // basic map setup | ||||
|         controller = mapView.controller | ||||
|         mapView.isTilesScaledToDpi = true | ||||
|         mapView.isVerticalMapRepetitionEnabled = false | ||||
|         mapView.setTileSource(TileSourceFactory.MAPNIK) | ||||
|         mapView.setMultiTouchControls(true) | ||||
|         mapView.zoomController.setVisibility(org.osmdroid.views.CustomZoomButtonsController.Visibility.NEVER) | ||||
|  | @ -538,7 +539,8 @@ class MapFragment : Fragment() | |||
|                             dialog.dismiss() | ||||
|                         } | ||||
|                         save_button.setOnClickListener { | ||||
|                             trackbook.database.update_homepoint(homepoint.id, name=name_input.text.toString(), radius=radius_input.text.toString().toDouble()) | ||||
|                             val radius = radius_input.text.toString().toDoubleOrNull() ?: 25.0 | ||||
|                             trackbook.database.update_homepoint(homepoint.id, name=name_input.text.toString(), radius=radius) | ||||
|                             trackbook.load_homepoints() | ||||
|                             create_homepoint_overlays(requireContext(), mapView, trackbook.homepoints) | ||||
|                             dialog.dismiss() | ||||
|  | @ -568,8 +570,8 @@ class MapFragment : Fragment() | |||
|             mapView.overlays.remove(currentTrackSpecialMarkerOverlay) | ||||
|         } | ||||
|         if (trkpts.isNotEmpty()) { | ||||
|             createTrackOverlay(requireContext(), mapView, trkpts, trackingState) | ||||
|             createSpecialMakersTrackOverlay(requireContext(), mapView, trkpts, trackingState) | ||||
|             currentTrackOverlay = createTrackOverlay(requireContext(), mapView, trkpts, trackingState) | ||||
|             currentTrackSpecialMarkerOverlay = createSpecialMakersTrackOverlay(requireContext(), mapView, trkpts, trackingState) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -85,7 +85,7 @@ data class Track ( | |||
|         var previous: Trkpt? = null | ||||
|         for (trkpt in trkpt_generator()) | ||||
|         { | ||||
|             if (previous != null && (trkpt.time - previous.time) > (5 * Keys.ONE_MINUTE_IN_MILLISECONDS)) | ||||
|             if (previous != null && (trkpt.time - previous.time) > (Keys.STOP_OVER_THRESHOLD)) | ||||
|             { | ||||
|                 write("\t\t</trkseg>") | ||||
|                 write("\t\t<trkseg>") | ||||
|  |  | |||
|  | @ -57,7 +57,7 @@ class TrackerService: Service(), SensorEventListener | |||
|     var recording_started: Date = GregorianCalendar.getInstance().time | ||||
|     var commitInterval: Int = Keys.COMMIT_INTERVAL | ||||
|     var currentBestLocation: Location = getDefaultLocation() | ||||
|     var lastCommit: Date = Keys.DEFAULT_DATE | ||||
|     var lastCommit: Long = 0 | ||||
|     var location_min_time_ms: Long = 0 | ||||
|     private val RECENT_TRKPT_COUNT = 7200 | ||||
|     var stepCountOffset: Float = 0f | ||||
|  | @ -150,9 +150,36 @@ class TrackerService: Service(), SensorEventListener | |||
|         return object : LocationListener { | ||||
|             override fun onLocationChanged(location: Location) | ||||
|             { | ||||
|                 if (isBetterLocation(location, currentBestLocation)) { | ||||
|                     currentBestLocation = location | ||||
|                 if (! isBetterLocation(location, currentBestLocation)) | ||||
|                 { | ||||
|                     return | ||||
|                 } | ||||
|                 currentBestLocation = location | ||||
|                 if (trackingState != Keys.STATE_TRACKING_ACTIVE) | ||||
|                 { | ||||
|                     return | ||||
|                 } | ||||
|                 Log.i("VOUSSOIR", "Processing point ${location.latitude}, ${location.longitude} ${location.time}.") | ||||
|                 if (should_keep_point((location))) | ||||
|                 { | ||||
|                     val now: Long = location.time | ||||
|                     // val now: Date = GregorianCalendar.getInstance().time | ||||
|                     val trkpt = Trkpt(location=location) | ||||
|                     trackbook.database.insert_trkpt(device_id, trkpt) | ||||
|                     recent_trkpts.add(trkpt) | ||||
| 
 | ||||
|                     while (recent_trkpts.size > RECENT_TRKPT_COUNT) | ||||
|                     { | ||||
|                         recent_trkpts.removeFirst() | ||||
|                     } | ||||
| 
 | ||||
|                     if (now - lastCommit > Keys.SAVE_TEMP_TRACK_INTERVAL) | ||||
|                     { | ||||
|                         trackbook.database.commit() | ||||
|                         lastCommit  = now | ||||
|                     } | ||||
|                 } | ||||
|                 displayNotification() | ||||
|             } | ||||
|             override fun onProviderEnabled(provider: String) | ||||
|             { | ||||
|  | @ -353,7 +380,6 @@ class TrackerService: Service(), SensorEventListener | |||
|         } | ||||
|         PreferencesHelper.saveTrackingState(trackingState) | ||||
|         startStepCounter() | ||||
|         handler.postDelayed(periodicTrackUpdate, 0) | ||||
|         startForeground(Keys.TRACKER_SERVICE_NOTIFICATION_ID, displayNotification()) | ||||
|     } | ||||
| 
 | ||||
|  | @ -365,7 +391,6 @@ class TrackerService: Service(), SensorEventListener | |||
|         PreferencesHelper.saveTrackingState(trackingState) | ||||
| 
 | ||||
|         sensorManager.unregisterListener(this) | ||||
|         handler.removeCallbacks(periodicTrackUpdate) | ||||
| 
 | ||||
|         displayNotification() | ||||
|         stopForeground(STOP_FOREGROUND_DETACH) | ||||
|  | @ -452,31 +477,4 @@ class TrackerService: Service(), SensorEventListener | |||
|         } | ||||
|         return true | ||||
|     } | ||||
| 
 | ||||
|     private val periodicTrackUpdate: Runnable = object : Runnable | ||||
|     { | ||||
|         override fun run() { | ||||
|             val now: Date = GregorianCalendar.getInstance().time | ||||
|             val trkpt = Trkpt(location=currentBestLocation) | ||||
|             Log.i("VOUSSOIR", "Processing point ${currentBestLocation.latitude}, ${currentBestLocation.longitude} ${now.time}.") | ||||
|             if (should_keep_point((currentBestLocation))) | ||||
|             { | ||||
|                 trackbook.database.insert_trkpt(device_id, trkpt) | ||||
|                 recent_trkpts.add(trkpt) | ||||
| 
 | ||||
|                 while (recent_trkpts.size > RECENT_TRKPT_COUNT) | ||||
|                 { | ||||
|                     recent_trkpts.removeFirst() | ||||
|                 } | ||||
| 
 | ||||
|                 if (now.time - lastCommit.time > Keys.SAVE_TEMP_TRACK_INTERVAL) | ||||
|                 { | ||||
|                     trackbook.database.commit() | ||||
|                     lastCommit  = now | ||||
|                 } | ||||
|             } | ||||
|             displayNotification() | ||||
|             handler.postDelayed(this, Keys.TRACKING_INTERVAL) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ import java.text.SimpleDateFormat | |||
| import java.util.* | ||||
| 
 | ||||
| /* Creates icon overlay for track */ | ||||
| fun createTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int) | ||||
| fun createTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int): SimpleFastPointOverlay | ||||
| { | ||||
|     val color = if (trackingState == Keys.STATE_TRACKING_ACTIVE) context.getColor(R.color.default_red) else context.getColor(R.color.default_blue) | ||||
|     val points: MutableList<IGeoPoint> = mutableListOf() | ||||
|  | @ -64,10 +64,11 @@ fun createTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<T | |||
|         .setCellSize(12) // Sets the grid cell size used for indexing, in pixels. Larger cells result in faster rendering speed, but worse fidelity. Default is 10 pixels, for large datasets (>10k points), use 15. | ||||
|     val overlay = SimpleFastPointOverlay(pointTheme, overlayOptions) | ||||
|     map_view.overlays.add(overlay) | ||||
|     return overlay | ||||
| } | ||||
| 
 | ||||
| /* Creates overlay containing start, stop, stopover and starred markers for track */ | ||||
| fun createSpecialMakersTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int, displayStartEndMarker: Boolean = false) | ||||
| fun createSpecialMakersTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int, displayStartEndMarker: Boolean = false): ItemizedIconOverlay<OverlayItem> | ||||
| { | ||||
|     val overlayItems: ArrayList<OverlayItem> = ArrayList<OverlayItem>() | ||||
|     val trackingActive: Boolean = trackingState == Keys.STATE_TRACKING_ACTIVE | ||||
|  | @ -110,7 +111,9 @@ fun createSpecialMakersTrackOverlay(context: Context, map_view: MapView, trkpts: | |||
|             overlayItems.add(overlayItem) | ||||
|         } | ||||
|     } | ||||
|     map_view.overlays.add(createOverlay(context, overlayItems)) | ||||
|     val overlay: ItemizedIconOverlay<OverlayItem> = createOverlay(context, overlayItems) | ||||
|     map_view.overlays.add(overlay) | ||||
|     return overlay | ||||
| } | ||||
| 
 | ||||
| fun createOverlayItem(context: Context, latitude: Double, longitude: Double, accuracy: Float, provider: String, time: Long): OverlayItem | ||||
|  |  | |||
|  | @ -86,7 +86,7 @@ | |||
|     <string name="pref_altitude_smoothing_value_title" translatable="false">Altitude Smoothing</string> | ||||
|     <string name="pref_auto_export_interval_summary">Automatically export GPX file after this many hours.</string> | ||||
|     <string name="pref_device_id_summary">A unique ID to distinguish tracks recorded across multiple devices:</string> | ||||
|     <string name="pref_database_folder_summary">Directory to contain your database file. You could use Syncthing to sync with your PC!</string> | ||||
|     <string name="pref_database_folder_summary">Directory to contain your database file. You could use Syncthing to sync with your PC.</string> | ||||
|     <string name="pref_auto_export_interval_title">Auto Export Interval</string> | ||||
|     <string name="pref_device_id">Device ID</string> | ||||
|     <string name="pref_database_folder">Database directory</string> | ||||
|  | @ -96,8 +96,8 @@ | |||
|     <string name="pref_general_title">General</string> | ||||
|     <string name="pref_maintenance_title">Maintenance</string> | ||||
|     <string name="pref_gps_only_title">Restrict to GPS</string> | ||||
|     <string name="pref_gps_only_summary_gps_and_network">Currently using GPS and Network for localization.</string> | ||||
|     <string name="pref_gps_only_summary_gps_only">Currently using only GPS for localization.</string> | ||||
|     <string name="pref_gps_only_summary_gps_and_network">Currently using GPS and Network for location.</string> | ||||
|     <string name="pref_gps_only_summary_gps_only">Currently using only GPS for location.</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_title">Use Imperial Measurements</string> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue