summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/temp/HeadingDataProcessor.kt
diff options
context:
space:
mode:
authorClaudomator Agent <agent@claudomator>2026-03-14 00:50:39 +0000
committerClaudomator Agent <agent@claudomator>2026-03-14 00:50:39 +0000
commit3f18f770e9d33c5e5d0657c6160fa8f30b21831f (patch)
treea1df48d383c8627b4111fd55a7066b6afcb84ae1 /android-app/app/src/main/temp/HeadingDataProcessor.kt
parent9fb49aebfc01b5df68e67e97ee088318a3621c26 (diff)
Implement barometric pressure trend monitoring and visualization
Diffstat (limited to 'android-app/app/src/main/temp/HeadingDataProcessor.kt')
-rwxr-xr-xandroid-app/app/src/main/temp/HeadingDataProcessor.kt108
1 files changed, 108 insertions, 0 deletions
diff --git a/android-app/app/src/main/temp/HeadingDataProcessor.kt b/android-app/app/src/main/temp/HeadingDataProcessor.kt
new file mode 100755
index 0000000..7625f90
--- /dev/null
+++ b/android-app/app/src/main/temp/HeadingDataProcessor.kt
@@ -0,0 +1,108 @@
+package org.terst.nav.temp // Temporarily placing in 'temp' due to permissions
+
+import android.hardware.GeomagneticField
+import android.location.Location
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
+import java.util.Date
+
+/**
+ * Data class representing processed heading information.
+ * @param trueHeading The heading relative to true North (0-359.9 degrees).
+ * @param magneticHeading The heading relative to magnetic North (0-359.9 degrees).
+ * @param magneticVariation The difference between true and magnetic North at the current location (+E, -W).
+ * @param cog Course Over Ground (0-359.9 degrees).
+ */
+data class HeadingInfo(
+ val trueHeading: Float,
+ val magneticHeading: Float,
+ val magneticVariation: Float,
+ val cog: Float
+)
+
+/**
+ * Processor for handling heading data, including magnetic variation calculations
+ * using the Android GeomagneticField.
+ */
+class HeadingDataProcessor {
+
+ private val _headingInfoFlow = MutableStateFlow(HeadingInfo(0f, 0f, 0f, 0f))
+ val headingInfoFlow: StateFlow<HeadingInfo> = _headingInfoFlow.asStateFlow()
+
+ private var currentLatitude: Double = 0.0
+ private var currentLongitude: Double = 0.0
+ private var currentAltitude: Double = 0.0
+
+ /**
+ * Updates the current geographic location for magnetic variation calculations.
+ */
+ fun updateLocation(latitude: Double, longitude: Double, altitude: Double) {
+ currentLatitude = latitude
+ currentLongitude = longitude
+ currentAltitude = altitude
+ // Recalculate magnetic variation if location changes
+ updateHeadingInfo(_headingInfoFlow.value.trueHeading, _headingInfoFlow.value.cog, true)
+ }
+
+ /**
+ * Processes a new true heading and Course Over Ground (COG) value.
+ * @param newTrueHeading The new true heading in degrees.
+ * @param newCog The new COG in degrees.
+ */
+ fun updateTrueHeadingAndCog(newTrueHeading: Float, newCog: Float) {
+ updateHeadingInfo(newTrueHeading, newCog, true)
+ }
+
+ /**
+ * Processes a new magnetic heading and Course Over Ground (COG) value.
+ * @param newMagneticHeading The new magnetic heading in degrees.
+ * @param newCog The new COG in degrees.
+ */
+ fun updateMagneticHeadingAndCog(newMagneticHeading: Float, newCog: Float) {
+ updateHeadingInfo(newMagneticHeading, newCog, false)
+ }
+
+ private fun updateHeadingInfo(heading: Float, cog: Float, isTrueHeadingInput: Boolean) {
+ val magneticVariation = calculateMagneticVariation()
+ val (finalTrueHeading, finalMagneticHeading) = if (isTrueHeadingInput) {
+ Pair(heading, (heading - magneticVariation + 360) % 360)
+ } else {
+ Pair((heading + magneticVariation + 360) % 360, heading)
+ }
+
+ _headingInfoFlow.update {
+ it.copy(
+ trueHeading = finalTrueHeading,
+ magneticHeading = finalMagneticHeading,
+ magneticVariation = magneticVariation,
+ cog = cog
+ )
+ }
+ }
+
+ /**
+ * Calculates the magnetic variation (declination) for the current location.
+ * @return Magnetic variation in degrees (+E, -W).
+ */
+ private fun calculateMagneticVariation(): Float {
+ // GeomagneticField requires current time in milliseconds
+ val currentTimeMillis = System.currentTimeMillis()
+
+ // Create a dummy Location object to get altitude if only lat/lon are updated
+ // GeomagneticField needs altitude, using 0 if not provided
+ val geoField = GeomagneticField(
+ currentLatitude.toFloat(),
+ currentLongitude.toFloat(),
+ currentAltitude.toFloat(), // Altitude in meters
+ currentTimeMillis
+ )
+ return geoField.declination // Declination is the magnetic variation
+ }
+
+ // Helper function to normalize angles (0-359.9) - though modulo handles this for positive floats
+ private fun normalizeAngle(angle: Float): Float {
+ return (angle % 360 + 360) % 360
+ }
+}