summaryrefslogtreecommitdiff
path: root/android-app
diff options
context:
space:
mode:
Diffstat (limited to 'android-app')
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt9
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt27
2 files changed, 31 insertions, 5 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 35a0e91..b7db246 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
@@ -400,10 +400,8 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
mapView = findViewById(R.id.mapView)
particleWindView = findViewById(R.id.particle_wind_view)
- // Apply persisted particles preference immediately
- if (!layerManager.particlesEnabled) {
- particleWindView?.visibility = View.GONE
- }
+ // Always start hidden; revealed by the windArrow observer once data arrives
+ particleWindView?.visibility = View.GONE
if (NavApplication.isTesting) return
@@ -503,6 +501,9 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
if (arrow != null) {
mapHandler?.updateWindLayer(arrow)
particleWindView?.setWind(arrow.directionDeg, arrow.speedKt)
+ if (layerManager.particlesEnabled) {
+ particleWindView?.visibility = View.VISIBLE
+ }
}
}
}
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt
index e65cbd1..868b828 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt
@@ -170,11 +170,27 @@ class MainViewModel(
.create(AisHubApiService::class.java)
}
+ private var lastConditionsLat = Double.NaN
+ private var lastConditionsLon = Double.NaN
+ private var lastConditionsMs = 0L
+
/**
* Fetches current conditions snapshot for [lat]/[lon] and exposes it via [marineConditions].
- * Silently ignored on network failure — the UI keeps showing dashes.
+ * Throttled: skips if conditions loaded < 5 min ago and position < 2 nm from last load.
*/
fun loadConditions(lat: Double, lon: Double) {
+ val nowMs = System.currentTimeMillis()
+ val ageMs = nowMs - lastConditionsMs
+ val distNm = if (lastConditionsLat.isNaN()) Double.MAX_VALUE
+ else distanceNm(lastConditionsLat, lastConditionsLon, lat, lon)
+ if (ageMs < 5 * 60_000L && distNm < 2.0) {
+ NavLogger.i("conditions", "skip age=${ageMs / 1000}s dist=%.1fnm".format(distNm))
+ return
+ }
+ lastConditionsLat = lat
+ lastConditionsLon = lon
+ lastConditionsMs = nowMs
+
conditionsJob?.cancel()
conditionsJob = viewModelScope.launch {
_conditionsLoading.value = true
@@ -192,6 +208,15 @@ class MainViewModel(
}
}
+ private fun distanceNm(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
+ val dLat = Math.toRadians(lat2 - lat1)
+ val dLon = Math.toRadians(lon2 - lon1)
+ val a = sin(dLat / 2) * sin(dLat / 2) +
+ cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2)) *
+ sin(dLon / 2) * sin(dLon / 2)
+ return 3440.065 * 2 * kotlin.math.asin(kotlin.math.sqrt(a))
+ }
+
/**
* Fetch weather and wind arrow for [lat]/[lon]. Called once on first GPS fix.
*/