summaryrefslogtreecommitdiff
path: root/android-app
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-05-20 09:59:26 +0000
committerClaude <noreply@anthropic.com>2026-05-20 09:59:26 +0000
commitddae982f561e1f812d55b5943f79dc76144d93d3 (patch)
tree09e51623dadf2ad380863cb47c25a4e7f56084bd /android-app
parentcdb3fa7c6167e108f46b4d411655f78a22e3bebe (diff)
Restyle past tracks: solid dark blue, dim/focus layers
All past tracks render as solid dark navy (#0B3050) at 45% opacity, 2.5px — no dashes. A second focus layer (#2B8FC4, full opacity, 4px) paints on top when a track is selected, making it pop without changing the dim layer's data. Active recording stays red. The dim layer always contains every past track; the focus layer gets the selected track's points independently via setFocusedTrackPoints(). Cleared on dismiss so all tracks return to equal dim opacity. https://claude.ai/code/session_01YUbuZNDAoLea4cf9UGQ9qn
Diffstat (limited to 'android-app')
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt3
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt71
2 files changed, 50 insertions, 24 deletions
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
index caabe40..6c54500 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt
@@ -818,10 +818,11 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
}
}
- // When a saved track is selected: zoom to it and show tack markers
+ // When a saved track is selected: zoom to it, highlight it, and show tack markers
lifecycleScope.launch {
viewModel.selectedTrack.collect { track ->
val style = loadedStyleFlow.value ?: return@collect
+ mapHandler?.setFocusedTrackPoints(track?.points)
if (track != null) {
mapHandler?.zoomToTrackBounds(track.points)
mapHandler?.updateTackLayer(style, track.tacks)
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt
index 32b3643..b8ce460 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MapHandler.kt
@@ -72,10 +72,12 @@ class MapHandler(private val maplibreMap: MapLibreMap) {
private val USER_POS_LAYER_ID = "user-pos-layer"
private val USER_ICON_ID = "user-icon"
- private val TRACK_ACTIVE_SOURCE_ID = "track-active-source"
- private val TRACK_ACTIVE_LAYER_ID = "track-line-active"
- private val TRACK_PAST_SOURCE_ID = "track-past-source"
- private val TRACK_PAST_LAYER_ID = "track-line-past"
+ private val TRACK_ACTIVE_SOURCE_ID = "track-active-source"
+ private val TRACK_ACTIVE_LAYER_ID = "track-line-active"
+ private val TRACK_PAST_DIM_SOURCE_ID = "track-past-dim-source"
+ private val TRACK_PAST_DIM_LAYER_ID = "track-line-past-dim"
+ private val TRACK_PAST_FOCUS_SOURCE_ID = "track-past-focus-source"
+ private val TRACK_PAST_FOCUS_LAYER_ID = "track-line-past-focus"
private val WIND_SOURCE_ID = "wind-arrows-source"
private val WIND_LAYER_ID = "wind-arrows"
@@ -91,7 +93,8 @@ class MapHandler(private val maplibreMap: MapLibreMap) {
private var tidalCurrentSource: GeoJsonSource? = null
private var userPosSource: GeoJsonSource? = null
private var trackActiveSource: GeoJsonSource? = null
- private var trackPastSource: GeoJsonSource? = null
+ private var trackPastDimSource: GeoJsonSource? = null
+ private var trackPastFocusSource: GeoJsonSource? = null
private var windSource: GeoJsonSource? = null
private var windGridSource: GeoJsonSource? = null
private var tackSource: GeoJsonSource? = null
@@ -306,6 +309,34 @@ class MapHandler(private val maplibreMap: MapLibreMap) {
* Updates the GPS track polyline on the map. Lazily initialises the layers on first call.
*/
fun updateTrackLayer(style: Style, activePoints: List<TrackPoint>, pastTracks: List<List<TrackPoint>>) {
+ if (trackPastDimSource == null) {
+ trackPastDimSource = GeoJsonSource(TRACK_PAST_DIM_SOURCE_ID)
+ style.addSource(trackPastDimSource!!)
+ style.addLayer(LineLayer(TRACK_PAST_DIM_LAYER_ID, TRACK_PAST_DIM_SOURCE_ID).apply {
+ setProperties(
+ PropertyFactory.lineColor("#0B3050"),
+ PropertyFactory.lineOpacity(0.45f),
+ PropertyFactory.lineWidth(2.5f),
+ PropertyFactory.lineCap("round"),
+ PropertyFactory.lineJoin("round")
+ )
+ })
+ }
+
+ if (trackPastFocusSource == null) {
+ trackPastFocusSource = GeoJsonSource(TRACK_PAST_FOCUS_SOURCE_ID)
+ style.addSource(trackPastFocusSource!!)
+ style.addLayer(LineLayer(TRACK_PAST_FOCUS_LAYER_ID, TRACK_PAST_FOCUS_SOURCE_ID).apply {
+ setProperties(
+ PropertyFactory.lineColor("#2B8FC4"),
+ PropertyFactory.lineOpacity(1.0f),
+ PropertyFactory.lineWidth(4f),
+ PropertyFactory.lineCap("round"),
+ PropertyFactory.lineJoin("round")
+ )
+ })
+ }
+
if (trackActiveSource == null) {
trackActiveSource = GeoJsonSource(TRACK_ACTIVE_SOURCE_ID)
style.addSource(trackActiveSource!!)
@@ -313,23 +344,16 @@ class MapHandler(private val maplibreMap: MapLibreMap) {
setProperties(
PropertyFactory.lineColor("#E53935"),
PropertyFactory.lineWidth(4f),
- PropertyFactory.lineCap("round")
+ PropertyFactory.lineCap("round"),
+ PropertyFactory.lineJoin("round")
)
})
}
- if (trackPastSource == null) {
- trackPastSource = GeoJsonSource(TRACK_PAST_SOURCE_ID)
- style.addSource(trackPastSource!!)
- style.addLayer(LineLayer(TRACK_PAST_LAYER_ID, TRACK_PAST_SOURCE_ID).apply {
- setProperties(
- PropertyFactory.lineColor("#E53935"),
- PropertyFactory.lineWidth(3f),
- PropertyFactory.lineDasharray(arrayOf(1f, 2f)),
- PropertyFactory.lineCap("round")
- )
- })
+ val dimFeatures = pastTracks.map { track ->
+ Feature.fromGeometry(LineString.fromLngLats(track.map { Point.fromLngLat(it.lon, it.lat) }))
}
+ trackPastDimSource?.setGeoJson(FeatureCollection.fromFeatures(dimFeatures))
if (activePoints.size >= 2) {
val coords = activePoints.map { Point.fromLngLat(it.lon, it.lat) }
@@ -337,15 +361,16 @@ class MapHandler(private val maplibreMap: MapLibreMap) {
} else {
trackActiveSource?.setGeoJson(FeatureCollection.fromFeatures(emptyList()))
}
+ }
- if (pastTracks.isNotEmpty()) {
- val features = pastTracks.map { track ->
- Feature.fromGeometry(LineString.fromLngLats(track.map { Point.fromLngLat(it.lon, it.lat) }))
- }
- trackPastSource?.setGeoJson(FeatureCollection.fromFeatures(features))
+ /** Highlights [points] in the focus layer (full-opacity bright blue over the dim layer). */
+ fun setFocusedTrackPoints(points: List<TrackPoint>?) {
+ val geojson = if (points != null && points.size >= 2) {
+ Feature.fromGeometry(LineString.fromLngLats(points.map { Point.fromLngLat(it.lon, it.lat) }))
} else {
- trackPastSource?.setGeoJson(FeatureCollection.fromFeatures(emptyList()))
+ FeatureCollection.fromFeatures(emptyList())
}
+ trackPastFocusSource?.setGeoJson(geojson)
}
/**