checkpoint
This commit is contained in:
parent
d943b206fa
commit
e26bd2bf9a
9 changed files with 106 additions and 49 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in a new issue