mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-04 03:37:21 +00:00
Added various minor fixes, cleaned up classes
This commit is contained in:
1 parent
5a8108384f
commit
fc0b995bac
35 files changed
+295
-310
No files matched your search
@@ -19,8 +19,6 @@ package com.rtbishop.look4sat.domain.model
|
||||
|
||||
sealed class DataState<out T> {
|
||||
data class Success<out T>(val data: T) : DataState<T>()
|
||||
data class Error(val resId: Int?) : DataState<Nothing>()
|
||||
data class Exception(val message: String?) : DataState<Nothing>()
|
||||
data object Handled : DataState<Nothing>()
|
||||
data object Loading : DataState<Nothing>()
|
||||
}
|
||||
@@ -21,7 +21,7 @@ interface IDatabaseRepo {
|
||||
|
||||
suspend fun updateFromFile(uri: String)
|
||||
|
||||
suspend fun updateFromWeb()
|
||||
suspend fun updateFromRemote()
|
||||
|
||||
suspend fun clearAllData()
|
||||
}
|
||||
+1
-4
@@ -19,9 +19,6 @@ package com.rtbishop.look4sat.domain.source
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
interface IDataSource {
|
||||
|
||||
interface IFileSource {
|
||||
suspend fun getFileStream(uri: String): InputStream?
|
||||
|
||||
suspend fun getNetworkStream(url: String): InputStream?
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ import com.rtbishop.look4sat.domain.model.SatItem
|
||||
import com.rtbishop.look4sat.domain.model.SatRadio
|
||||
import com.rtbishop.look4sat.domain.predict.Satellite
|
||||
|
||||
interface ILocalStorage {
|
||||
interface ILocalSource {
|
||||
|
||||
suspend fun getEntriesTotal(): Int
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 Arty Bishop (bishop.arty@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.domain.source
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
interface IRemoteSource {
|
||||
suspend fun getRemoteStream(url: String): InputStream?
|
||||
}
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 Arty Bishop (bishop.arty@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.domain.utility
|
||||
|
||||
import com.rtbishop.look4sat.domain.predict.DEG2RAD
|
||||
|
||||
@@ -19,43 +19,40 @@ package com.rtbishop.look4sat.domain.utility
|
||||
|
||||
import com.rtbishop.look4sat.domain.predict.GeoPos
|
||||
|
||||
object QthConverter {
|
||||
|
||||
fun qthToPosition(locator: String): GeoPos? {
|
||||
val trimmedQth = locator.take(6)
|
||||
if (!isValidLocator(trimmedQth)) return null
|
||||
val lonFirst = (trimmedQth[0].uppercaseChar().code - 65) * 20
|
||||
val latFirst = (trimmedQth[1].uppercaseChar().code - 65) * 10
|
||||
val lonSecond = trimmedQth[2].toString().toInt() * 2
|
||||
val latSecond = trimmedQth[3].toString().toInt()
|
||||
val lonThird = (((trimmedQth[4].lowercaseChar().code - 97) / 12.0) + (1.0 / 24.0)) - 180
|
||||
val latThird = (((trimmedQth[5].lowercaseChar().code - 97) / 24.0) + (1.0 / 48.0)) - 90
|
||||
val longitude = (lonFirst + lonSecond + lonThird).round(4)
|
||||
val latitude = (latFirst + latSecond + latThird).round(4)
|
||||
return GeoPos(latitude, longitude)
|
||||
}
|
||||
|
||||
fun positionToQth(latitude: Double, longitude: Double): String? {
|
||||
if (!isValidPosition(latitude, longitude)) return null
|
||||
val tempLon = if (longitude > 180.0) longitude - 180 else longitude
|
||||
val upper = "ABCDEFGHIJKLMNOPQRSTUVWX"
|
||||
val lower = "abcdefghijklmnopqrstuvwx"
|
||||
val newLongitude = tempLon + 180
|
||||
val newLatitude = latitude + 90
|
||||
val lonFirst = upper[(newLongitude / 20).toInt()]
|
||||
val latFirst = upper[(newLatitude / 10).toInt()]
|
||||
val lonSecond = ((newLongitude / 2) % 10).toInt().toString()
|
||||
val latSecond = (newLatitude % 10).toInt().toString()
|
||||
val lonThird = lower[((newLongitude % 2) * 12).toInt()]
|
||||
val latThird = lower[((newLatitude % 1) * 24).toInt()]
|
||||
return "$lonFirst$latFirst$lonSecond$latSecond$lonThird$latThird"
|
||||
}
|
||||
|
||||
private fun isValidPosition(lat: Double, lon: Double): Boolean {
|
||||
return (lat >= -90.0 && lat <= 90.0) && (lon >= -180.0 && lon <= 360.0)
|
||||
}
|
||||
|
||||
private fun isValidLocator(locator: String): Boolean {
|
||||
return locator.matches("[a-xA-X][a-xA-X]\\d\\d[a-xA-X][a-xA-X]".toRegex())
|
||||
}
|
||||
fun qthToPosition(locator: String): GeoPos? {
|
||||
val trimmedQth = locator.take(6)
|
||||
if (!isValidLocator(trimmedQth)) return null
|
||||
val lonFirst = (trimmedQth[0].uppercaseChar().code - 65) * 20
|
||||
val latFirst = (trimmedQth[1].uppercaseChar().code - 65) * 10
|
||||
val lonSecond = trimmedQth[2].toString().toInt() * 2
|
||||
val latSecond = trimmedQth[3].toString().toInt()
|
||||
val lonThird = (((trimmedQth[4].lowercaseChar().code - 97) / 12.0) + (1.0 / 24.0)) - 180
|
||||
val latThird = (((trimmedQth[5].lowercaseChar().code - 97) / 24.0) + (1.0 / 48.0)) - 90
|
||||
val longitude = (lonFirst + lonSecond + lonThird).round(4)
|
||||
val latitude = (latFirst + latSecond + latThird).round(4)
|
||||
return GeoPos(latitude, longitude)
|
||||
}
|
||||
|
||||
fun positionToQth(latitude: Double, longitude: Double): String? {
|
||||
if (!isValidPosition(latitude, longitude)) return null
|
||||
val tempLon = if (longitude > 180.0) longitude - 180 else longitude
|
||||
val upper = "ABCDEFGHIJKLMNOPQRSTUVWX"
|
||||
val lower = "abcdefghijklmnopqrstuvwx"
|
||||
val newLongitude = tempLon + 180
|
||||
val newLatitude = latitude + 90
|
||||
val lonFirst = upper[(newLongitude / 20).toInt()]
|
||||
val latFirst = upper[(newLatitude / 10).toInt()]
|
||||
val lonSecond = ((newLongitude / 2) % 10).toInt().toString()
|
||||
val latSecond = (newLatitude % 10).toInt().toString()
|
||||
val lonThird = lower[((newLongitude % 2) * 12).toInt()]
|
||||
val latThird = lower[((newLatitude % 1) * 24).toInt()]
|
||||
return "$lonFirst$latFirst$lonSecond$latSecond$lonThird$latThird"
|
||||
}
|
||||
|
||||
private fun isValidPosition(lat: Double, lon: Double): Boolean {
|
||||
return (lat >= -90.0 && lat <= 90.0) && (lon >= -180.0 && lon <= 360.0)
|
||||
}
|
||||
|
||||
private fun isValidLocator(locator: String): Boolean {
|
||||
return locator.matches("[a-xA-X][a-xA-X]\\d\\d[a-xA-X][a-xA-X]".toRegex())
|
||||
}
|
||||
@@ -17,37 +17,38 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.domain
|
||||
|
||||
import com.rtbishop.look4sat.domain.utility.QthConverter
|
||||
import com.rtbishop.look4sat.domain.utility.positionToQth
|
||||
import com.rtbishop.look4sat.domain.utility.qthToPosition
|
||||
import org.junit.Test
|
||||
|
||||
class QthConverterTest {
|
||||
|
||||
@Test
|
||||
fun `Given valid QTH returns correct POS`() {
|
||||
var result = QthConverter.qthToPosition("io91VL39FX")
|
||||
var result = qthToPosition("io91VL39FX")
|
||||
assert(result?.latitude == 51.4792 && result.longitude == -0.2083)
|
||||
result = QthConverter.qthToPosition("JN58TD")
|
||||
result = qthToPosition("JN58TD")
|
||||
assert(result?.latitude == 48.1458 && result.longitude == 11.6250)
|
||||
result = QthConverter.qthToPosition("gf15vc")
|
||||
result = qthToPosition("gf15vc")
|
||||
assert(result?.latitude == -34.8958 && result.longitude == -56.2083)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Given invalid QTH returns null`() {
|
||||
assert(QthConverter.qthToPosition("ZZ00zz") == null)
|
||||
assert(QthConverter.qthToPosition("JN58") == null)
|
||||
assert(qthToPosition("ZZ00zz") == null)
|
||||
assert(qthToPosition("JN58") == null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Given valid POS returns correct QTH`() {
|
||||
assert(QthConverter.positionToQth(51.4878, -0.2146) == "IO91vl")
|
||||
assert(QthConverter.positionToQth(48.1466, 11.6083) == "JN58td")
|
||||
assert(QthConverter.positionToQth(-34.91, -56.2116) == "GF15vc")
|
||||
assert(positionToQth(51.4878, -0.2146) == "IO91vl")
|
||||
assert(positionToQth(48.1466, 11.6083) == "JN58td")
|
||||
assert(positionToQth(-34.91, -56.2116) == "GF15vc")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Given invalid POS returns null`() {
|
||||
assert(QthConverter.positionToQth(91.0542, -170.1142) == null)
|
||||
assert(QthConverter.positionToQth(89.0542, -240.1142) == null)
|
||||
assert(positionToQth(91.0542, -170.1142) == null)
|
||||
assert(positionToQth(89.0542, -240.1142) == null)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user