summaryrefslogtreecommitdiff
path: root/android-app/app
diff options
context:
space:
mode:
Diffstat (limited to 'android-app/app')
-rw-r--r--android-app/app/build.gradle4
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/data/model/SensorData.kt10
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/data/storage/GribFileManager.kt4
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/data/weather/GribStalenessChecker.kt4
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/data/weather/SatelliteGribDownloader.kt8
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookFormatter.kt2
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookPdfExporter.kt2
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/routing/IsochroneRouter.kt4
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt11
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt4
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/wind/ApparentWind.kt3
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindCalculator.kt20
-rw-r--r--android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindData.kt3
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt2
14 files changed, 59 insertions, 22 deletions
diff --git a/android-app/app/build.gradle b/android-app/app/build.gradle
index 0c1a012..f6ad111 100644
--- a/android-app/app/build.gradle
+++ b/android-app/app/build.gradle
@@ -4,7 +4,7 @@ plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.appdistribution'
id 'com.google.firebase.crashlytics'
- id 'kotlin-kapt'
+ id 'com.google.devtools.ksp'
}
android {
@@ -94,7 +94,7 @@ dependencies {
// JSON parsing
implementation 'com.squareup.moshi:moshi-kotlin:1.15.0'
- kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.15.0'
+ ksp 'com.squareup.moshi:moshi-kotlin-codegen:1.15.0'
// Location
implementation 'com.google.android.gms:play-services-location:21.2.0'
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/data/model/SensorData.kt b/android-app/app/src/main/kotlin/com/example/androidapp/data/model/SensorData.kt
new file mode 100644
index 0000000..d427a5d
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/data/model/SensorData.kt
@@ -0,0 +1,10 @@
+package com.example.androidapp.data.model
+
+data class SensorData(
+ val latitude: Double? = null,
+ val longitude: Double? = null,
+ val headingTrueDeg: Double? = null,
+ val apparentWindSpeedKt: Double? = null,
+ val apparentWindAngleDeg: Double? = null,
+ val speedOverGroundKt: Double? = null
+)
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/data/storage/GribFileManager.kt b/android-app/app/src/main/kotlin/com/example/androidapp/data/storage/GribFileManager.kt
index b336818..d6f685a 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/data/storage/GribFileManager.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/data/storage/GribFileManager.kt
@@ -1,7 +1,7 @@
package com.example.androidapp.data.storage
-import com.example.androidapp.data.model.GribFile
-import com.example.androidapp.data.model.GribRegion
+import org.terst.nav.data.model.GribFile
+import org.terst.nav.data.model.GribRegion
import java.time.Instant
interface GribFileManager {
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/GribStalenessChecker.kt b/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/GribStalenessChecker.kt
index 63466b2..70f36d9 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/GribStalenessChecker.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/GribStalenessChecker.kt
@@ -1,8 +1,8 @@
package com.example.androidapp.data.weather
-import com.example.androidapp.data.model.GribFile
+import org.terst.nav.data.model.GribFile
import com.example.androidapp.data.storage.GribFileManager
-import com.example.androidapp.data.model.GribRegion
+import org.terst.nav.data.model.GribRegion
import java.time.Instant
/** Outcome of a freshness check. */
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/SatelliteGribDownloader.kt b/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/SatelliteGribDownloader.kt
index e2c884a..6e565b7 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/SatelliteGribDownloader.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/data/weather/SatelliteGribDownloader.kt
@@ -1,9 +1,9 @@
package com.example.androidapp.data.weather
-import com.example.androidapp.data.model.GribFile
-import com.example.androidapp.data.model.GribParameter
-import com.example.androidapp.data.model.GribRegion
-import com.example.androidapp.data.model.SatelliteDownloadRequest
+import org.terst.nav.data.model.GribFile
+import org.terst.nav.data.model.GribParameter
+import org.terst.nav.data.model.GribRegion
+import org.terst.nav.data.model.SatelliteDownloadRequest
import com.example.androidapp.data.storage.GribFileManager
import java.time.Instant
import kotlin.math.ceil
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookFormatter.kt b/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookFormatter.kt
index b0a910a..d4cf50d 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookFormatter.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookFormatter.kt
@@ -1,6 +1,6 @@
package com.example.androidapp.logbook
-import com.example.androidapp.data.model.LogbookEntry
+import org.terst.nav.data.model.LogbookEntry
import java.util.Calendar
import java.util.TimeZone
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookPdfExporter.kt b/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookPdfExporter.kt
index ff8ce9a..78ea834 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookPdfExporter.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/logbook/LogbookPdfExporter.kt
@@ -5,7 +5,7 @@ import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import android.graphics.pdf.PdfDocument
-import com.example.androidapp.data.model.LogbookEntry
+import org.terst.nav.data.model.LogbookEntry
import java.io.OutputStream
/**
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/routing/IsochroneRouter.kt b/android-app/app/src/main/kotlin/com/example/androidapp/routing/IsochroneRouter.kt
index 25055a8..901fdbc 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/routing/IsochroneRouter.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/routing/IsochroneRouter.kt
@@ -1,7 +1,7 @@
package com.example.androidapp.routing
-import com.example.androidapp.data.model.BoatPolars
-import com.example.androidapp.data.model.WindForecast
+import org.terst.nav.data.model.BoatPolars
+import org.terst.nav.data.model.WindForecast
import kotlin.math.asin
import kotlin.math.atan2
import kotlin.math.cos
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt b/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt
index 507736e..f544f63 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/safety/AnchorWatchState.kt
@@ -1,5 +1,7 @@
package com.example.androidapp.safety
+import kotlin.math.sqrt
+
/**
* Holds UI-facing state for the anchor watch setup screen and provides
* the suggested watch-circle radius derived from depth and rode out.
@@ -10,14 +12,13 @@ class AnchorWatchState {
* Returns the recommended watch-circle radius (metres) for the given depth
* and amount of rode deployed.
*
- * Uses the Pythagorean formula via [ScopeCalculator.watchCircleRadius] when
- * the geometry is valid (rode > depth + freeboard). Falls back to [rodeOutM]
- * itself as the maximum possible swing radius when the rode is too short to
- * form a catenary angle.
+ * Uses the Pythagorean formula sqrt(rode² - vertical²) when the geometry is
+ * valid (rode > depth + freeboard). Falls back to [rodeOutM] itself as the
+ * maximum possible swing radius when the rode is too short to form a catenary angle.
*/
fun calculateRecommendedWatchCircleRadius(depthM: Double, rodeOutM: Double): Double {
val vertical = depthM + 2.0 // 2 m default freeboard
- return if (rodeOutM > vertical) ScopeCalculator.watchCircleRadius(rodeOutM, depthM)
+ return if (rodeOutM > vertical) sqrt(rodeOutM * rodeOutM - vertical * vertical)
else rodeOutM
}
}
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt b/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt
index bc82795..289a857 100644
--- a/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/ui/anchorwatch/AnchorWatchHandler.kt
@@ -7,8 +7,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
-import com.example.androidapp.R
-import com.example.androidapp.databinding.FragmentAnchorWatchBinding
+import org.terst.nav.R
+import org.terst.nav.databinding.FragmentAnchorWatchBinding
import com.example.androidapp.safety.AnchorWatchState
class AnchorWatchHandler : Fragment() {
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/wind/ApparentWind.kt b/android-app/app/src/main/kotlin/com/example/androidapp/wind/ApparentWind.kt
new file mode 100644
index 0000000..01656a3
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/wind/ApparentWind.kt
@@ -0,0 +1,3 @@
+package com.example.androidapp.wind
+
+data class ApparentWind(val speedKt: Double, val angleDeg: Double)
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindCalculator.kt b/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindCalculator.kt
new file mode 100644
index 0000000..db32163
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindCalculator.kt
@@ -0,0 +1,20 @@
+package com.example.androidapp.wind
+
+import kotlin.math.atan2
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.math.sqrt
+
+class TrueWindCalculator {
+ fun update(apparent: ApparentWind, bsp: Double, hdgDeg: Double): TrueWindData {
+ val awaRad = Math.toRadians(apparent.angleDeg)
+ val awX = apparent.speedKt * cos(awaRad)
+ val awY = apparent.speedKt * sin(awaRad)
+ val twX = awX - bsp
+ val twY = awY
+ val tws = sqrt(twX * twX + twY * twY)
+ val twaDeg = Math.toDegrees(atan2(twY, twX))
+ val twdDeg = ((hdgDeg + twaDeg) % 360 + 360) % 360
+ return TrueWindData(speedKt = tws, directionDeg = twdDeg)
+ }
+}
diff --git a/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindData.kt b/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindData.kt
new file mode 100644
index 0000000..78e9558
--- /dev/null
+++ b/android-app/app/src/main/kotlin/com/example/androidapp/wind/TrueWindData.kt
@@ -0,0 +1,3 @@
+package com.example.androidapp.wind
+
+data class TrueWindData(val speedKt: Double, val directionDeg: Double)
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 d9dba73..61d8b9b 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
@@ -55,6 +55,7 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
override fun onResume() {
super.onResume()
+ mapView?.onResume()
if (pendingServiceStart) {
pendingServiceStart = false
startServices()
@@ -288,7 +289,6 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener {
}
override fun onStart() { super.onStart(); mapView?.onStart() }
- override fun onResume() { super.onResume(); mapView?.onResume() }
override fun onPause() { super.onPause(); mapView?.onPause() }
override fun onStop() { super.onStop(); mapView?.onStop() }
override fun onDestroy() { super.onDestroy(); mapView?.onDestroy() }