diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 9cb891f..68a272a 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -43,27 +43,6 @@ jobs: java-version: '17' architecture: x64 - - name: Set up Golang - uses: actions/setup-go@v4 - with: - go-version-file: ${{ github.workspace }}/app/src/main/golang/go.mod - cache-dependency-path: ${{ github.workspace }}/app/src/main/golang/go.sum - - - name: Set up NDK - uses: nttld/setup-ndk@v1 - with: - ndk-version: r26 - add-to-path: false - local-cache: true - - - name: Build Golang library - run: | - go install golang.org/x/mobile/cmd/gomobile@latest - gomobile init - go generate app/src/main/golang/Geomag.go - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - - name: Set up Gradle uses: gradle/gradle-build-action@v2 with: diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91f78e3..2e1c21e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -81,6 +81,12 @@ android { } } + sourceSets { + getByName("main") { + jniLibs.srcDir("src/main/libs") + } + } + splits { abi { reset() diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 43d9569..39644fc 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -11,4 +11,10 @@ ; } +# Keep Native library +-keep class dev.sanmer.geomag.MagneticField { *; } +-keepclassmembers class dev.sanmer.geomag.Geomag { + native ; +} + -repackageclasses com.sanmer.geomag \ No newline at end of file diff --git a/app/src/main/golang/.gitignore b/app/src/main/golang/.gitignore deleted file mode 100644 index 2f36f26..0000000 --- a/app/src/main/golang/.gitignore +++ /dev/null @@ -1 +0,0 @@ -libs/ \ No newline at end of file diff --git a/app/src/main/golang/Geomag.go b/app/src/main/golang/Geomag.go deleted file mode 100644 index 9d2c211..0000000 --- a/app/src/main/golang/Geomag.go +++ /dev/null @@ -1,67 +0,0 @@ -package geomag - -//go:generate bash -c "if [ ! -d libs ]; then mkdir libs; fi" -//go:generate gomobile bind -target android -androidapi 26 -javapkg com.sanmer -trimpath -v -o libs/geomag.aar - -import ( - "github.com/proway2/go-igrf/igrf" - "github.com/westphae/geomag/pkg/egm96" - "github.com/westphae/geomag/pkg/wmm" - "time" -) - -//export igrf -func IGRF(lat, lon, alt, date float64) *MagneticField { - data := igrf.New() - mag, _ := data.IGRF(lat, lon, alt, date) - - return newMagneticField( - mag.Declination, - mag.DeclinationSV, - mag.Inclination, - mag.InclinationSV, - mag.HorizontalIntensity, - mag.HorizontalSV, - mag.NorthComponent, - mag.NorthSV, - mag.EastComponent, - mag.EastSV, - mag.VerticalComponent, - mag.VerticalSV, - mag.TotalIntensity, - mag.TotalSV, - ) -} - -//export wmm -func WMM(lat, lon, alt, date float64) *MagneticField { - tt := wmm.DecimalYear(date) - loc := egm96.NewLocationGeodetic(lat, lon, alt) - mag, _ := wmm.CalculateWMMMagneticField(loc, tt.ToTime()) - x, y, z, dx, dy, dz := mag.Ellipsoidal() - - return newMagneticField( - mag.D(), - mag.DD(), - mag.I(), - mag.DI(), - mag.H(), - mag.DH(), - x, - dx, - y, - dy, - z, - dz, - mag.F(), - mag.DF(), - ) -} - -//export toDecimalYears -func ToDecimalYears(year, month, day, hour, min, sec, nsec int) float64 { - dateTime := time.Date(year, time.Month(month), day, - hour, min, sec, nsec, time.UTC) - - return float64(wmm.TimeToDecimalYears(dateTime)) -} diff --git a/app/src/main/golang/MagneticField.go b/app/src/main/golang/MagneticField.go deleted file mode 100644 index c536488..0000000 --- a/app/src/main/golang/MagneticField.go +++ /dev/null @@ -1,45 +0,0 @@ -package geomag - -type MagneticField struct { - Declination float64 - DeclinationSV float64 - Inclination float64 - InclinationSV float64 - HorizontalIntensity float64 - HorizontalSV float64 - NorthComponent float64 - NorthSV float64 - EastComponent float64 - EastSV float64 - VerticalComponent float64 - VerticalSV float64 - TotalIntensity float64 - TotalSV float64 -} - -func newMagneticField( - declination, declinationSV, - inclination, inclinationSV, - horizontalIntensity, horizontalSV, - northComponent, northSV, - eastComponent, eastSV, - verticalComponent, verticalSV, - totalIntensity, totalSV float64, -) *MagneticField { - return &MagneticField{ - Declination: declination, - DeclinationSV: declinationSV, - Inclination: inclination, - InclinationSV: inclinationSV, - HorizontalIntensity: horizontalIntensity, - HorizontalSV: horizontalSV, - NorthComponent: northComponent, - NorthSV: northSV, - EastComponent: eastComponent, - EastSV: eastSV, - VerticalComponent: verticalComponent, - VerticalSV: verticalSV, - TotalIntensity: totalIntensity, - TotalSV: totalSV, - } -} diff --git a/app/src/main/golang/go.mod b/app/src/main/golang/go.mod deleted file mode 100644 index 9258df6..0000000 --- a/app/src/main/golang/go.mod +++ /dev/null @@ -1,16 +0,0 @@ -module geomag - -go 1.21 - -require ( - github.com/proway2/go-igrf v0.5.1 - github.com/westphae/geomag v1.0.2 -) - -require ( - golang.org/x/mobile v0.0.0-20230901161150-52620a4a7557 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 // indirect -) diff --git a/app/src/main/golang/go.sum b/app/src/main/golang/go.sum deleted file mode 100644 index 85a1260..0000000 --- a/app/src/main/golang/go.sum +++ /dev/null @@ -1,14 +0,0 @@ -github.com/proway2/go-igrf v0.5.1 h1:GLxkN5hHGJHoAVfrkFHgJ8SfKKCTzGWHg3aZweX1lwc= -github.com/proway2/go-igrf v0.5.1/go.mod h1:nkA3o+7eci3SXLj0nx2yi14e9Td+AAwHFdglavT+oZI= -github.com/westphae/geomag v1.0.2 h1:dpcizAXfjKV0PR6ohY7PX3hHfiIPVjJC03M8KyJjqRI= -github.com/westphae/geomag v1.0.2/go.mod h1:xOwtBFVzYXv+tutDPYOuV3PSwS1f9hHuGQsPAUzVYf8= -golang.org/x/mobile v0.0.0-20230901161150-52620a4a7557 h1:mLrcd+qwh23kzD7ej1VxCa+A23UNr+BCjSj2tNX8/NM= -golang.org/x/mobile v0.0.0-20230901161150-52620a4a7557/go.mod h1:f0gjFM6UTH7y1WEZBm/kquBYsogL+NQtllKFy4Rdulc= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 h1:o4bs4seAAlSiZQAZbO6/RP5XBCZCooQS3Pgc0AUjWts= -golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= diff --git a/app/src/main/kotlin/com/sanmer/geomag/GeomagExt.kt b/app/src/main/kotlin/com/sanmer/geomag/GeomagExt.kt index dc8a0ab..42d50d7 100644 --- a/app/src/main/kotlin/com/sanmer/geomag/GeomagExt.kt +++ b/app/src/main/kotlin/com/sanmer/geomag/GeomagExt.kt @@ -2,98 +2,29 @@ package com.sanmer.geomag import com.sanmer.geomag.model.MagneticFieldExt import com.sanmer.geomag.model.Position -import com.sanmer.geomag.model.Record -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import kotlinx.datetime.LocalDateTime +import dev.sanmer.geomag.Geomag -@Suppress( - "MemberVisibilityCanBePrivate", - "SpellCheckingInspection" -) object GeomagExt { - private fun toDecimalYears( - year: Int, month: Int, day: Int, - hour: Int, min: Int, - sec: Int, nsec: Int, - ) = Geomag.toDecimalYears( - year.toLong(), - month.toLong(), - day.toLong(), - hour.toLong(), - min.toLong(), - sec.toLong(), - nsec.toLong() - ) - - private fun igrf( - latitude: Double, - longitude: Double, - altKm: Double, + fun igrf( + position: Position, decimalYears: Double ) = Geomag.igrf( - latitude, - longitude, - altKm, - decimalYears - ) - - private fun wmm( - latitude: Double, - longitude: Double, - altKm: Double, - decimalYears: Double - ) = Geomag.wmm( - latitude, - longitude, - altKm, - decimalYears - ) - - fun toDecimalYears(dateTime: LocalDateTime) = toDecimalYears( - dateTime.year, dateTime.monthNumber, dateTime.dayOfMonth, - dateTime.hour, dateTime.minute, - dateTime.second, dateTime.nanosecond - ) - - fun igrf( - dataTime: LocalDateTime, - position: Position - ) = igrf( latitude = position.latitude, longitude = position.longitude, - altKm = position.altitude, - decimalYears = toDecimalYears(dataTime) + altitude = position.altitude, + decimalYears = decimalYears ).let { MagneticFieldExt(it) } fun wmm( - dataTime: LocalDateTime, - position: Position - ) = wmm( + position: Position, + decimalYears: Double + ) = Geomag.wmm( latitude = position.latitude, longitude = position.longitude, - altKm = position.altitude, - decimalYears = toDecimalYears(dataTime) + altitude = position.altitude, + decimalYears = decimalYears ).let { MagneticFieldExt(it) } - suspend fun run( - model: Models, - dataTime: LocalDateTime, - position: Position - ): Record = withContext(Dispatchers.Default) { - val cal: (LocalDateTime, Position) -> MagneticFieldExt = when (model) { - Models.IGRF -> ::igrf - Models.WMM -> ::wmm - } - - return@withContext Record( - model = model, - time = dataTime, - position = position, - values = cal(dataTime, position) - ) - } - enum class Models { IGRF, WMM diff --git a/app/src/main/kotlin/com/sanmer/geomag/model/MagneticFieldExt.kt b/app/src/main/kotlin/com/sanmer/geomag/model/MagneticFieldExt.kt index 1da6a9d..7b290f6 100644 --- a/app/src/main/kotlin/com/sanmer/geomag/model/MagneticFieldExt.kt +++ b/app/src/main/kotlin/com/sanmer/geomag/model/MagneticFieldExt.kt @@ -1,6 +1,6 @@ package com.sanmer.geomag.model -import com.sanmer.geomag.MagneticField +import dev.sanmer.geomag.MagneticField data class MagneticFieldExt( val declination: Double, @@ -19,20 +19,20 @@ data class MagneticFieldExt( val totalSV: Double ) { constructor(field: MagneticField) : this( - declination = field.declination, - declinationSV = field.declinationSV.orZero(), - inclination = field.inclination, - inclinationSV = field.inclinationSV.orZero(), - horizontalIntensity = field.horizontalIntensity, - horizontalSV = field.horizontalSV.orZero(), - northComponent = field.northComponent, - northSV = field.northSV.orZero(), - eastComponent = field.eastComponent, - eastSV = field.eastSV.orZero(), - verticalComponent = field.verticalComponent, - verticalSV = field.verticalSV.orZero(), - totalIntensity = field.totalIntensity, - totalSV = field.totalSV.orZero() + declination = field.d, + declinationSV = field.dDot, + inclination = field.i, + inclinationSV = field.iDot, + horizontalIntensity = field.h, + horizontalSV = field.hDot, + northComponent = field.x, + northSV = field.xDot, + eastComponent = field.y, + eastSV = field.yDot, + verticalComponent = field.z, + verticalSV = field.zDot, + totalIntensity = field.f, + totalSV = field.fDot ) companion object { @@ -46,6 +46,4 @@ data class MagneticFieldExt( 0.0, 0.0 ) } -} - -private fun Double.orZero() = if (isNaN()) 0.0 else this +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/sanmer/geomag/ui/screens/records/view/items/RecordInfoItem.kt b/app/src/main/kotlin/com/sanmer/geomag/ui/screens/records/view/items/RecordInfoItem.kt index a317a08..d8afbce 100644 --- a/app/src/main/kotlin/com/sanmer/geomag/ui/screens/records/view/items/RecordInfoItem.kt +++ b/app/src/main/kotlin/com/sanmer/geomag/ui/screens/records/view/items/RecordInfoItem.kt @@ -12,9 +12,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.sanmer.geomag.GeomagExt import com.sanmer.geomag.R import com.sanmer.geomag.model.Record +import dev.sanmer.geomag.Geomag @Composable fun RecordInfoItem( @@ -57,7 +57,7 @@ fun RecordInfoItem( ValueItem( key = stringResource(id = R.string.overview_decimal), - value = GeomagExt.toDecimalYears(record.time).toString() + value = Geomag.toDecimalYears(record.time).toString() ) } } diff --git a/app/src/main/kotlin/com/sanmer/geomag/viewmodel/HomeViewModel.kt b/app/src/main/kotlin/com/sanmer/geomag/viewmodel/HomeViewModel.kt index 57ecf27..16411e1 100644 --- a/app/src/main/kotlin/com/sanmer/geomag/viewmodel/HomeViewModel.kt +++ b/app/src/main/kotlin/com/sanmer/geomag/viewmodel/HomeViewModel.kt @@ -17,6 +17,7 @@ import com.sanmer.geomag.repository.UserPreferencesRepository import com.sanmer.geomag.service.LocationService import com.sanmer.geomag.utils.extensions.now import dagger.hilt.android.lifecycle.HiltViewModel +import dev.sanmer.geomag.Geomag import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.delay @@ -59,7 +60,7 @@ class HomeViewModel @Inject constructor( } private fun LocalDateTime.withDecimalYears(): Pair = - this to GeomagExt.toDecimalYears(this) + this to Geomag.toDecimalYears(this) fun toggleDateTime() { isTimeRunning = !isTimeRunning @@ -78,12 +79,18 @@ class HomeViewModel @Inject constructor( val userPreferences = userPreferencesRepository.data.first() val model = userPreferences.fieldModel val enableRecords = userPreferences.enableRecords - val dateTime = dateTimeFlow.first().first + val dateTime = dateTimeFlow.first() - record = GeomagExt.run( + val calc = when (model) { + GeomagExt.Models.IGRF -> GeomagExt::igrf + GeomagExt.Models.WMM -> GeomagExt::wmm + } + + record = Record( model = model, - dataTime = dateTime, - position = position + time = dateTime.first, + position = position, + values = calc(position, dateTime.second) ) if (enableRecords) { diff --git a/app/src/main/kotlin/dev/sanmer/geomag/Geomag.kt b/app/src/main/kotlin/dev/sanmer/geomag/Geomag.kt new file mode 100644 index 0000000..bd2065e --- /dev/null +++ b/app/src/main/kotlin/dev/sanmer/geomag/Geomag.kt @@ -0,0 +1,23 @@ +package dev.sanmer.geomag + +import kotlinx.datetime.LocalDateTime + + +object Geomag { + init { + System.loadLibrary("geomag-jni") + } + + external fun toDecimalYears(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int): Double + external fun wmm(longitude: Double, latitude: Double, altitude: Double, decimalYears: Double): MagneticField + external fun igrf(longitude: Double, latitude: Double, altitude: Double, decimalYears: Double): MagneticField + + fun toDecimalYears(date: LocalDateTime) = + toDecimalYears(date.year, date.monthNumber, date.dayOfMonth, date.hour, date.minute, date.second) + + fun wmm(longitude: Double, latitude: Double, altitude: Double, date: LocalDateTime) = + wmm(longitude, latitude, altitude, toDecimalYears(date)) + + fun igrf(longitude: Double, latitude: Double, altitude: Double, date: LocalDateTime) = + igrf(longitude, latitude, altitude, toDecimalYears(date)) +} \ No newline at end of file diff --git a/app/src/main/kotlin/dev/sanmer/geomag/MagneticField.kt b/app/src/main/kotlin/dev/sanmer/geomag/MagneticField.kt new file mode 100644 index 0000000..8699375 --- /dev/null +++ b/app/src/main/kotlin/dev/sanmer/geomag/MagneticField.kt @@ -0,0 +1,18 @@ +package dev.sanmer.geomag + +data class MagneticField( + val x: Double, + val xDot: Double, + val y: Double, + val yDot: Double, + val z: Double, + val zDot: Double, + val h: Double, + val hDot: Double, + val f: Double, + val fDot: Double, + val d: Double, + val dDot: Double, + val i: Double, + val iDot: Double +) diff --git a/app/src/main/libs/arm64-v8a/libgeomag-jni.so b/app/src/main/libs/arm64-v8a/libgeomag-jni.so new file mode 100755 index 0000000..5e079bb Binary files /dev/null and b/app/src/main/libs/arm64-v8a/libgeomag-jni.so differ diff --git a/app/src/main/libs/x86_64/libgeomag-jni.so b/app/src/main/libs/x86_64/libgeomag-jni.so new file mode 100755 index 0000000..918c087 Binary files /dev/null and b/app/src/main/libs/x86_64/libgeomag-jni.so differ