checkpoint

master
voussoir 2023-03-15 18:08:08 -07:00
parent 0133524fa2
commit 3532704102
5 changed files with 44 additions and 65 deletions

View File

@ -80,7 +80,6 @@ class MapFragment : Fragment()
private lateinit var mapView: MapView private lateinit var mapView: MapView
private var current_position_overlays = ArrayList<Overlay>() private var current_position_overlays = ArrayList<Overlay>()
private var currentTrackOverlay: SimpleFastPointOverlay? = null private var currentTrackOverlay: SimpleFastPointOverlay? = null
private var currentTrackSpecialMarkerOverlay: ItemizedIconOverlay<OverlayItem>? = null
private lateinit var locationErrorBar: Snackbar private lateinit var locationErrorBar: Snackbar
private lateinit var controller: IMapController private lateinit var controller: IMapController
private var zoomLevel: Double = Keys.DEFAULT_ZOOM_LEVEL private var zoomLevel: Double = Keys.DEFAULT_ZOOM_LEVEL
@ -211,7 +210,6 @@ class MapFragment : Fragment()
// initialize track overlays // initialize track overlays
currentTrackOverlay = null currentTrackOverlay = null
currentTrackSpecialMarkerOverlay = null
// initialize main button state // initialize main button state
update_main_button() update_main_button()
@ -535,15 +533,13 @@ class MapFragment : Fragment()
/* Overlay current track on map */ /* Overlay current track on map */
fun create_current_track_overlay(trkpts: Collection<Trkpt>, trackingState: Int) fun create_current_track_overlay(trkpts: Collection<Trkpt>, trackingState: Int)
{ {
if (currentTrackOverlay != null) { if (currentTrackOverlay != null)
{
mapView.overlays.remove(currentTrackOverlay) mapView.overlays.remove(currentTrackOverlay)
} }
if (currentTrackSpecialMarkerOverlay != null) { if (trkpts.isNotEmpty())
mapView.overlays.remove(currentTrackSpecialMarkerOverlay) {
}
if (trkpts.isNotEmpty()) {
currentTrackOverlay = createTrackOverlay(requireContext(), mapView, trkpts, trackingState) currentTrackOverlay = createTrackOverlay(requireContext(), mapView, trkpts, trackingState)
currentTrackSpecialMarkerOverlay = createSpecialMakersTrackOverlay(requireContext(), mapView, trkpts, trackingState)
} }
} }

View File

@ -160,7 +160,7 @@ data class Track (
return stats return stats
} }
stats.duration = last.time - first.time stats.duration = last.time - first.time
stats.velocity = stats.distance / stats.duration stats.velocity = stats.distance / (stats.duration / 1000)
return stats return stats
} }

View File

@ -27,7 +27,6 @@ data class Trkpt(
val accuracy: Float, val accuracy: Float,
val time: Long, val time: Long,
val numberSatellites: Int = 0, val numberSatellites: Int = 0,
var starred: Boolean = false
) )
{ {
constructor(location: Location) : this ( constructor(location: Location) : this (

View File

@ -18,6 +18,7 @@ package org.y20k.trackbook.helpers
import android.content.Context import android.content.Context
import android.graphics.Paint import android.graphics.Paint
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import org.osmdroid.api.IGeoPoint import org.osmdroid.api.IGeoPoint
@ -36,80 +37,60 @@ import java.text.DecimalFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
/* Creates icon overlay for track */
fun createTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int): SimpleFastPointOverlay 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() val points: MutableList<IGeoPoint> = mutableListOf()
trkpts.forEach { trkpt -> 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})"
// only add normal points
if (!trkpt.starred)
{ {
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})"
points.add(LabelledGeoPoint(trkpt.latitude, trkpt.longitude, trkpt.altitude, label)) points.add(LabelledGeoPoint(trkpt.latitude, trkpt.longitude, trkpt.altitude, label))
} }
} val pointTheme = SimplePointTheme(points, false)
val pointTheme: SimplePointTheme = SimplePointTheme(points, false)
val style = Paint() val style = Paint()
style.style = Paint.Style.FILL style.style = Paint.Style.FILL
style.color = color style.color = if (trackingState == Keys.STATE_TRACKING_ACTIVE) context.getColor(R.color.default_red) else context.getColor(R.color.default_blue)
style.flags = Paint.ANTI_ALIAS_FLAG style.flags = Paint.ANTI_ALIAS_FLAG
val scalingFactor: Float = UiHelper.getDensityScalingFactor(context)
val overlayOptions: SimpleFastPointOverlayOptions = SimpleFastPointOverlayOptions.getDefaultStyle() val overlayOptions: SimpleFastPointOverlayOptions = SimpleFastPointOverlayOptions.getDefaultStyle()
.setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION) .setAlgorithm(SimpleFastPointOverlayOptions.RenderingAlgorithm.MAXIMUM_OPTIMIZATION)
.setSymbol(SimpleFastPointOverlayOptions.Shape.CIRCLE) .setSymbol(SimpleFastPointOverlayOptions.Shape.CIRCLE)
.setPointStyle(style) .setPointStyle(style)
.setRadius(6F * scalingFactor) // radius is set in px - scaling factor makes that display density independent (= dp) .setRadius(6F * UiHelper.getDensityScalingFactor(context)) // radius is set in px - scaling factor makes that display density independent (= dp)
.setIsClickable(false) .setIsClickable(true)
.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. .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) val 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]}")
}
})
map_view.overlays.add(overlay) map_view.overlays.add(overlay)
return overlay return overlay
} }
/* Creates overlay containing start, stop, stopover and starred markers for track */ fun create_start_end_markers(context: Context, map_view: MapView, trkpts: Collection<Trkpt>): ItemizedIconOverlay<OverlayItem>?
fun createSpecialMakersTrackOverlay(context: Context, map_view: MapView, trkpts: Collection<Trkpt>, trackingState: Int, displayStartEndMarker: Boolean = false): ItemizedIconOverlay<OverlayItem>
{ {
val overlayItems: ArrayList<OverlayItem> = ArrayList<OverlayItem>() if (trkpts.size == 0)
val trackingActive: Boolean = trackingState == Keys.STATE_TRACKING_ACTIVE {
val maxIndex: Int = trkpts.size - 1 return null
}
trkpts.forEachIndexed { index: Int, trkpt: Trkpt -> val overlayItems: ArrayList<OverlayItem> = ArrayList<OverlayItem>()
var overlayItem: OverlayItem? = null val startpoint = trkpts.first()
if (!trackingActive && index == 0 && displayStartEndMarker && trkpt.starred) val endpoint = trkpts.last()
val startmarker: OverlayItem = createOverlayItem(context, startpoint.latitude, startpoint.longitude, startpoint.accuracy, startpoint.provider, startpoint.time)
startmarker.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_start_blue_48dp)!!)
overlayItems.add(startmarker)
if (trkpts.size > 1)
{ {
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time) val endmarker: OverlayItem = createOverlayItem(context, endpoint.latitude, endpoint.longitude, endpoint.accuracy, endpoint.provider, endpoint.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_start_starred_blue_48dp)!!) endmarker.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_end_blue_48dp)!!)
} overlayItems.add(endmarker)
else if (!trackingActive && index == 0 && displayStartEndMarker && !trkpt.starred)
{
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_start_blue_48dp)!!)
}
else if (!trackingActive && index == maxIndex && displayStartEndMarker && trkpt.starred)
{
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_end_starred_blue_48dp)!!)
}
else if (!trackingActive && index == maxIndex && displayStartEndMarker && !trkpt.starred)
{
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_marker_track_end_blue_48dp)!!)
}
else if (!trackingActive && trkpt.starred)
{
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_star_blue_24dp)!!)
}
else if (trackingActive && trkpt.starred)
{
overlayItem = createOverlayItem(context, trkpt.latitude, trkpt.longitude, trkpt.accuracy, trkpt.provider, trkpt.time)
overlayItem.setMarker(ContextCompat.getDrawable(context, R.drawable.ic_star_red_24dp)!!)
}
if (overlayItem != null)
{
overlayItems.add(overlayItem)
}
} }
val overlay: ItemizedIconOverlay<OverlayItem> = createOverlay(context, overlayItems) val overlay: ItemizedIconOverlay<OverlayItem> = createOverlay(context, overlayItems)
map_view.overlays.add(overlay) map_view.overlays.add(overlay)

View File

@ -216,12 +216,15 @@ data class TrackFragmentLayoutHolder(
if (special_points_overlay != null) if (special_points_overlay != null)
{ {
mapView.overlays.remove(special_points_overlay) mapView.overlays.remove(special_points_overlay)
}
if (track_overlay != null)
{
mapView.overlays.remove(track_overlay) mapView.overlays.remove(track_overlay)
} }
if (track.trkpts.isNotEmpty()) if (track.trkpts.isNotEmpty())
{ {
special_points_overlay = createSpecialMakersTrackOverlay(context, mapView, track.trkpts, Keys.STATE_TRACKING_STOPPED, displayStartEndMarker = true)
track_overlay = createTrackOverlay(context, mapView, track.trkpts, Keys.STATE_TRACKING_STOPPED) track_overlay = createTrackOverlay(context, mapView, track.trkpts, Keys.STATE_TRACKING_STOPPED)
special_points_overlay = create_start_end_markers(context, mapView, track.trkpts)
} }
setupStatisticsViews() setupStatisticsViews()
} }