checkpoint

This commit is contained in:
voussoir 2023-03-19 11:19:24 -07:00
parent d943b206fa
commit e26bd2bf9a
9 changed files with 106 additions and 49 deletions

View file

@ -53,11 +53,11 @@ class Database(val trackbook: Trackbook)
this.connection.endTransaction()
}
fun insert_trkpt(device_id: String, trkpt: Trkpt)
fun insert_trkpt(trkpt: Trkpt)
{
Log.i("VOUSSOIR", "Database.insert_trkpt")
val values = ContentValues().apply {
put("device_id", device_id)
put("device_id", trkpt.device_id)
put("lat", trkpt.latitude)
put("lon", trkpt.longitude)
put("time", GregorianCalendar.getInstance().time.time)

View file

@ -98,7 +98,7 @@ object Keys {
const val DEFAULT_ACCURACY: Float = 300f // in meters
const val DEFAULT_ALTITUDE: Double = 0.0
const val DEFAULT_TIME: Long = 0L
const val COMMIT_INTERVAL: Int = 30
const val COMMIT_INTERVAL: Long = 30 * ONE_SECOND_IN_MILLISECONDS
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

View file

@ -40,6 +40,7 @@ import androidx.fragment.app.Fragment
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import org.osmdroid.api.IGeoPoint
import org.osmdroid.api.IMapController
import org.osmdroid.events.MapEventsReceiver
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
@ -136,8 +137,7 @@ class MapFragment : Fragment()
mapView.setTileSource(TileSourceFactory.MAPNIK)
mapView.setMultiTouchControls(true)
mapView.zoomController.setVisibility(org.osmdroid.views.CustomZoomButtonsController.Visibility.NEVER)
zoomLevel = PreferencesHelper.loadZoomLevel()
mapView.controller.setZoom(zoomLevel)
mapView.controller.setZoom(Keys.DEFAULT_ZOOM_LEVEL)
if (AppThemeHelper.isDarkModeOn(requireActivity()))
{
@ -214,7 +214,6 @@ class MapFragment : Fragment()
mapView.setOnTouchListener { v, event ->
continuous_auto_center = false
zoomLevel = mapView.zoomLevelDouble
false
}
@ -226,12 +225,10 @@ class MapFragment : Fragment()
centerMap(currentBestLocation, animated=true)
}
zoom_in_button.setOnClickListener {
zoomLevel += 0.5
mapView.controller.zoomTo(mapView.zoomLevelDouble + 0.5, 0)
mapView.controller.setZoom(mapView.zoomLevelDouble + 0.5)
}
zoom_out_button.setOnClickListener {
zoomLevel -= 0.5
mapView.controller.zoomTo(mapView.zoomLevelDouble - 0.5, 0)
mapView.controller.setZoom(mapView.zoomLevelDouble - 0.5)
}
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
@ -533,15 +530,15 @@ class MapFragment : Fragment()
}
/* Overlay current track on map */
fun create_current_track_overlay(trkpts: Collection<Trkpt>, trackingState: Int)
fun create_current_track_overlay(geopoints: MutableList<IGeoPoint>, trackingState: Int)
{
if (currentTrackOverlay != null)
{
mapView.overlays.remove(currentTrackOverlay)
}
if (trkpts.isNotEmpty())
if (geopoints.isNotEmpty())
{
currentTrackOverlay = createTrackOverlay(requireContext(), mapView, trkpts, trackingState)
currentTrackOverlay = createTrackOverlay(requireContext(), mapView, geopoints, trackingState)
}
}
@ -620,7 +617,7 @@ class MapFragment : Fragment()
trackingState = trackerService.trackingState
// update location and track
create_current_position_overlays(currentBestLocation, trackingState)
create_current_track_overlay(trackerService.recent_trkpts, trackingState)
create_current_track_overlay(trackerService.recent_trackpoints_for_mapview, trackingState)
// center map, if it had not been dragged/zoomed before
if (continuous_auto_center)
{

View file

@ -42,6 +42,9 @@ data class Track (
fun delete()
{
Log.i("VOUSSOIR", "Track.delete ${device_id} ${start_time} -- ${end_time}.")
database.begin_transaction()
database.connection.delete("trkpt", "device_id = ? AND time > ? AND time < ?", arrayOf(device_id, start_time.time.toString(), end_time.time.toString()))
database.commit()
}
fun export_gpx(context: Context, fileuri: Uri): Uri?
@ -183,6 +186,7 @@ data class Track (
while (cursor.moveToNext())
{
val trkpt = Trkpt(
device_id=device_id,
provider="",
latitude=cursor.getDouble(COLUMN_LAT),
longitude=cursor.getDouble(COLUMN_LON),

View file

@ -38,7 +38,9 @@ import androidx.constraintlayout.widget.Group
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.textview.MaterialTextView
import org.osmdroid.api.IGeoPoint
import org.osmdroid.api.IMapController
import org.osmdroid.events.MapListener
import org.osmdroid.events.ScrollEvent
@ -65,6 +67,8 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
lateinit var rootView: View
lateinit var save_track_button: ImageButton
lateinit var deleteButton: ImageButton
lateinit var zoom_in_button: FloatingActionButton
lateinit var zoom_out_button: FloatingActionButton
lateinit var trackNameView: MaterialTextView
lateinit var track_query_start_date: DatePicker
lateinit var track_query_start_time: TimePicker
@ -113,6 +117,8 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
mapView = rootView.findViewById(R.id.map)
save_track_button = rootView.findViewById(R.id.save_button)
deleteButton = rootView.findViewById(R.id.delete_button)
zoom_in_button = rootView.findViewById(R.id.zoom_in_button)
zoom_out_button = rootView.findViewById(R.id.zoom_out_button)
trackNameView = rootView.findViewById(R.id.statistics_track_name_headline)
controller = mapView.controller
@ -235,6 +241,13 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
)
}
zoom_in_button.setOnClickListener {
mapView.controller.zoomTo(mapView.zoomLevelDouble + 0.5, 0)
}
zoom_out_button.setOnClickListener {
mapView.controller.zoomTo(mapView.zoomLevelDouble - 0.5, 0)
}
statisticsSheetBehavior = BottomSheetBehavior.from<View>(statisticsSheet)
statisticsSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
@ -260,9 +273,14 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
{
mapView.overlays.remove(track_overlay)
}
val geopoints: MutableList<IGeoPoint> = mutableListOf()
for (trkpt in track.trkpts)
{
geopoints.add(trkpt)
}
if (track.trkpts.isNotEmpty())
{
track_overlay = createTrackOverlay(requireContext(), mapView, track.trkpts, Keys.STATE_TRACKING_STOPPED)
track_overlay = createTrackOverlay(requireContext(), mapView, geopoints, Keys.STATE_TRACKING_STOPPED)
special_points_overlay = create_start_end_markers(requireContext(), mapView, track.trkpts)
}
setupStatisticsViews()

View file

@ -30,6 +30,9 @@ import android.Manifest
import android.os.*
import android.util.Log
import androidx.core.content.ContextCompat
import org.osmdroid.api.IGeoPoint
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.overlay.simplefastpoint.LabelledGeoPoint
import java.util.*
import org.y20k.trackbook.helpers.*
@ -53,6 +56,7 @@ class TrackerService: Service()
private val RECENT_TRKPT_COUNT = 7200
lateinit var recent_trkpts: Deque<Trkpt>
lateinit var recent_displacement_trkpts: Deque<Trkpt>
var recent_trackpoints_for_mapview: MutableList<IGeoPoint> = mutableListOf()
var gpsLocationListenerRegistered: Boolean = false
var networkLocationListenerRegistered: Boolean = false
var bound: Boolean = false
@ -197,14 +201,20 @@ class TrackerService: Service()
return
}
val trkpt = Trkpt(location=location)
trackbook.database.insert_trkpt(device_id, trkpt)
val trkpt = Trkpt(device_id=device_id, location=location)
trackbook.database.insert_trkpt(trkpt)
recent_trkpts.add(trkpt)
while (recent_trkpts.size > RECENT_TRKPT_COUNT)
{
recent_trkpts.removeFirst()
}
recent_trackpoints_for_mapview.add(trkpt)
while (recent_trackpoints_for_mapview.size > RECENT_TRKPT_COUNT)
{
recent_trackpoints_for_mapview.removeFirst()
}
recent_displacement_trkpts.add(trkpt)
while (recent_displacement_trkpts.size > 5)
{
@ -266,6 +276,7 @@ class TrackerService: Service()
trackbook.load_homepoints()
recent_trkpts = ArrayDeque<Trkpt>(RECENT_TRKPT_COUNT)
recent_displacement_trkpts = ArrayDeque<Trkpt>(5)
recent_trackpoints_for_mapview = mutableListOf()
use_gps_location = PreferencesHelper.load_location_gps()
use_network_location = PreferencesHelper.load_location_network()
device_id = PreferencesHelper.load_device_id()

View file

@ -17,19 +17,23 @@
package org.y20k.trackbook
import android.location.Location
import org.osmdroid.api.IGeoPoint
import org.osmdroid.util.GeoPoint
import org.y20k.trackbook.helpers.getNumberOfSatellites
data class Trkpt(
class Trkpt(
val device_id: String,
val provider: String,
val latitude: Double,
val longitude: Double,
val altitude: Double,
latitude: Double,
longitude: Double,
altitude: Double,
val accuracy: Float,
val time: Long,
val numberSatellites: Int = 0,
)
) : GeoPoint(latitude, longitude, altitude)
{
constructor(location: Location) : this (
constructor(device_id: String, location: Location) : this(
device_id=device_id,
provider=location.provider.toString(),
latitude=location.latitude,
longitude=location.longitude,
@ -48,4 +52,4 @@ data class Trkpt(
location.time = this.time
return location
}
}
}

View file

@ -37,16 +37,10 @@ import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
fun createTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int): SimpleFastPointOverlay
fun createTrackOverlay(context: Context, map_view: MapView, geopoints: MutableList<IGeoPoint>, trackingState: Int): SimpleFastPointOverlay
{
Log.i("VOUSSOIR", "MapOverlayHelper.createTrackOverlay")
val trackpoints: MutableList<IGeoPoint> = mutableListOf()
for (trkpt in trkpts)
{
val label = "${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault()).format(trkpt.time)} | ${context.getString(R.string.marker_description_accuracy)}: ${DecimalFormat("#0.00").format(trkpt.accuracy)} (${trkpt.provider})"
trackpoints.add(LabelledGeoPoint(trkpt.latitude, trkpt.longitude, trkpt.altitude, label))
}
val pointTheme = SimplePointTheme(trackpoints, false)
val pointTheme = SimplePointTheme(geopoints, false)
val style = Paint()
style.style = Paint.Style.FILL
style.color = if (trackingState == Keys.STATE_TRACKING_ACTIVE) context.getColor(R.color.default_red) else context.getColor(R.color.default_blue)
@ -60,23 +54,24 @@ 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.
var overlay = SimpleFastPointOverlay(pointTheme, overlayOptions)
// overlay.setOnClickListener(object : SimpleFastPointOverlay.OnClickListener {
// override fun onClick(points: SimpleFastPointOverlay.PointAdapter?, point: Int?)
// {
// if (points == null || point == null || point == 0)
// {
// return
// }
// Log.i("VOUSSOIR", "Clicked ${points[point]}")
// trackpoints.remove(points[point])
// map_view.overlays.remove(overlay)
// overlay = SimpleFastPointOverlay(pointTheme, overlayOptions)
// overlay.setOnClickListener(this)
// map_view.overlays.add(overlay)
// map_view.postInvalidate()
// return
// }
// })
overlay.setOnClickListener(object : SimpleFastPointOverlay.OnClickListener {
override fun onClick(points: SimpleFastPointOverlay.PointAdapter?, point: Int?)
{
if (points == null || point == null || point == 0)
{
return
}
val trkpt = (points[point]) as Trkpt
Log.i("VOUSSOIR", "Clicked ${trkpt.device_id} ${trkpt.time}")
// trackpoints.remove(points[point])
// map_view.overlays.remove(overlay)
// overlay = SimpleFastPointOverlay(pointTheme, overlayOptions)
// overlay.setOnClickListener(this)
// map_view.overlays.add(overlay)
// map_view.postInvalidate()
return
}
})
map_view.overlays.add(overlay)
return overlay

View file

@ -79,7 +79,35 @@
</org.osmdroid.views.MapView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/zoom_out_button"
style="@style/Widget.MaterialComponents.FloatingActionButton"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="70dp"
android:contentDescription="@string/descr_button_zoom_out"
android:src="@drawable/ic_zoom_out_24dp"
app:backgroundTint="@color/location_button_background"
app:fabSize="mini"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:tint="@color/location_button_icon" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/zoom_in_button"
style="@style/Widget.MaterialComponents.FloatingActionButton"
android:layout_width="wrap_content"
android:layout_height="56dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:contentDescription="@string/descr_button_zoom_in"
android:src="@drawable/ic_zoom_in_24dp"
app:backgroundTint="@color/location_button_background"
app:fabSize="mini"
app:layout_constraintBottom_toTopOf="@+id/zoom_out_button"
app:layout_constraintEnd_toEndOf="parent"
app:tint="@color/location_button_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>