Extracted station position management to a separate class
This commit is contained in:
1 parent
5ef79148bd
commit
1a59b5e3e1
31 files changed
+233
-502
No files matched your search
@@ -15,11 +15,6 @@ android {
|
|||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 240
|
versionCode 240
|
||||||
versionName "2.4.0"
|
versionName "2.4.0"
|
||||||
kapt {
|
|
||||||
arguments {
|
|
||||||
arg("room.schemaLocation", "$projectDir/schemas")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
{
|
|
||||||
"formatVersion": 1,
|
|
||||||
"database": {
|
|
||||||
"version": 2,
|
|
||||||
"identityHash": "24170ecaf2ab85adb66aa3b557134997",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"tableName": "entries",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tle` TEXT NOT NULL, `isSelected` INTEGER NOT NULL, `catNum` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`catNum`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "tle",
|
|
||||||
"columnName": "tle",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isSelected",
|
|
||||||
"columnName": "isSelected",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "name",
|
|
||||||
"columnName": "name",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"catNum"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "transmitters",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uuid` TEXT NOT NULL, `description` TEXT NOT NULL, `isAlive` INTEGER NOT NULL, `uplink` INTEGER, `downlink` INTEGER, `mode` TEXT, `isInverted` INTEGER NOT NULL, `catNum` INTEGER NOT NULL, PRIMARY KEY(`uuid`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "uuid",
|
|
||||||
"columnName": "uuid",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "description",
|
|
||||||
"columnName": "description",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isAlive",
|
|
||||||
"columnName": "isAlive",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "uplink",
|
|
||||||
"columnName": "uplink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "downlink",
|
|
||||||
"columnName": "downlink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "mode",
|
|
||||||
"columnName": "mode",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isInverted",
|
|
||||||
"columnName": "isInverted",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"uuid"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [],
|
|
||||||
"setupQueries": [
|
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '24170ecaf2ab85adb66aa3b557134997')"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
{
|
|
||||||
"formatVersion": 1,
|
|
||||||
"database": {
|
|
||||||
"version": 3,
|
|
||||||
"identityHash": "53fa623fc55b279c50d33e6263866a89",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"tableName": "entries",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tle` TEXT NOT NULL, `isSelected` INTEGER NOT NULL, `catNum` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`catNum`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "tle",
|
|
||||||
"columnName": "tle",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isSelected",
|
|
||||||
"columnName": "isSelected",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "name",
|
|
||||||
"columnName": "name",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"catNum"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "transmitters",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uuid` TEXT NOT NULL, `info` TEXT NOT NULL, `isAlive` INTEGER NOT NULL, `downlink` INTEGER, `uplink` INTEGER, `mode` TEXT, `isInverted` INTEGER NOT NULL, `catNum` INTEGER NOT NULL, PRIMARY KEY(`uuid`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "uuid",
|
|
||||||
"columnName": "uuid",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "info",
|
|
||||||
"columnName": "info",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isAlive",
|
|
||||||
"columnName": "isAlive",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "downlink",
|
|
||||||
"columnName": "downlink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "uplink",
|
|
||||||
"columnName": "uplink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "mode",
|
|
||||||
"columnName": "mode",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isInverted",
|
|
||||||
"columnName": "isInverted",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"uuid"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [],
|
|
||||||
"setupQueries": [
|
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '53fa623fc55b279c50d33e6263866a89')"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
{
|
|
||||||
"formatVersion": 1,
|
|
||||||
"database": {
|
|
||||||
"version": 1,
|
|
||||||
"identityHash": "53fa623fc55b279c50d33e6263866a89",
|
|
||||||
"entities": [
|
|
||||||
{
|
|
||||||
"tableName": "entries",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tle` TEXT NOT NULL, `catNum` INTEGER NOT NULL, `name` TEXT NOT NULL, `isSelected` INTEGER NOT NULL, PRIMARY KEY(`catNum`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "tle",
|
|
||||||
"columnName": "tle",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "name",
|
|
||||||
"columnName": "name",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isSelected",
|
|
||||||
"columnName": "isSelected",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"catNum"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "transmitters",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uuid` TEXT NOT NULL, `info` TEXT NOT NULL, `isAlive` INTEGER NOT NULL, `downlink` INTEGER, `uplink` INTEGER, `mode` TEXT, `isInverted` INTEGER NOT NULL, `catNum` INTEGER NOT NULL, PRIMARY KEY(`uuid`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "uuid",
|
|
||||||
"columnName": "uuid",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "info",
|
|
||||||
"columnName": "info",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isAlive",
|
|
||||||
"columnName": "isAlive",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "downlink",
|
|
||||||
"columnName": "downlink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "uplink",
|
|
||||||
"columnName": "uplink",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "mode",
|
|
||||||
"columnName": "mode",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "isInverted",
|
|
||||||
"columnName": "isInverted",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "catNum",
|
|
||||||
"columnName": "catNum",
|
|
||||||
"affinity": "INTEGER",
|
|
||||||
"notNull": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"uuid"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [],
|
|
||||||
"setupQueries": [
|
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '53fa623fc55b279c50d33e6263866a89')"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,11 +18,12 @@
|
|||||||
package com.rtbishop.look4sat.di
|
package com.rtbishop.look4sat.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.location.LocationManager
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import com.rtbishop.look4sat.data.DefaultSatelliteRepo
|
import com.rtbishop.look4sat.data.*
|
||||||
import com.rtbishop.look4sat.data.LocalDataSource
|
import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
|
||||||
import com.rtbishop.look4sat.data.RemoteDataSource
|
import com.rtbishop.look4sat.framework.DefaultLocationSource
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
|
||||||
import com.rtbishop.look4sat.framework.api.NetworkDataSource
|
import com.rtbishop.look4sat.framework.api.NetworkDataSource
|
||||||
import com.rtbishop.look4sat.framework.api.SatelliteService
|
import com.rtbishop.look4sat.framework.api.SatelliteService
|
||||||
import com.rtbishop.look4sat.framework.db.RoomConverters
|
import com.rtbishop.look4sat.framework.db.RoomConverters
|
||||||
@@ -51,12 +52,30 @@ object DataSourceModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideDefaultRepository(
|
fun provideLocationSource(
|
||||||
|
locationManager: LocationManager,
|
||||||
|
preferences: SharedPreferences
|
||||||
|
): LocationSource {
|
||||||
|
return DefaultLocationSource(locationManager, preferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideLocationRepo(
|
||||||
|
locationSource: LocationSource,
|
||||||
|
qthConverter: QthConverter
|
||||||
|
): LocationRepo {
|
||||||
|
return LocationRepo(locationSource, qthConverter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideSatelliteRepo(
|
||||||
localSource: LocalDataSource,
|
localSource: LocalDataSource,
|
||||||
remoteSource: RemoteDataSource,
|
remoteSource: RemoteDataSource,
|
||||||
@IoDispatcher ioDispatcher: CoroutineDispatcher
|
@IoDispatcher ioDispatcher: CoroutineDispatcher
|
||||||
): SatelliteRepo {
|
): SatelliteRepo {
|
||||||
return DefaultSatelliteRepo(localSource, remoteSource, ioDispatcher)
|
return SatelliteRepo(localSource, remoteSource, ioDispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.di
|
package com.rtbishop.look4sat.di
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.interactors.*
|
import com.rtbishop.look4sat.interactors.*
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.rtbishop.look4sat.framework
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.hardware.GeomagneticField
|
||||||
|
import android.location.LocationManager
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import com.rtbishop.look4sat.data.LocationSource
|
||||||
|
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
||||||
|
import com.rtbishop.look4sat.utility.round
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class DefaultLocationSource @Inject constructor(
|
||||||
|
private val locationManager: LocationManager,
|
||||||
|
private val preferences: SharedPreferences
|
||||||
|
) : LocationSource {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val keyLatitude = "stationLat"
|
||||||
|
const val keyLongitude = "stationLon"
|
||||||
|
const val keyAltitude = "stationAlt"
|
||||||
|
const val keyPositionGPS = "setPositionGPS"
|
||||||
|
const val keyPositionQTH = "setPositionQTH"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLastKnownLocation(): StationPosition? {
|
||||||
|
return try {
|
||||||
|
val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
|
||||||
|
if (location == null) null
|
||||||
|
else {
|
||||||
|
val latitude = location.latitude.round(4)
|
||||||
|
val longitude = location.longitude.round(4)
|
||||||
|
val altitude = location.altitude.round(1)
|
||||||
|
return StationPosition(latitude, longitude, altitude)
|
||||||
|
}
|
||||||
|
} catch (exception: SecurityException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMagDeclination(position: StationPosition): Float {
|
||||||
|
val lat = position.latitude.toFloat()
|
||||||
|
val lon = position.longitude.toFloat()
|
||||||
|
val alt = position.altitude.toFloat()
|
||||||
|
return GeomagneticField(lat, lon, alt, System.currentTimeMillis()).declination
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadStationPosition(): StationPosition {
|
||||||
|
val defaultSP = "0.0"
|
||||||
|
val latitude = preferences.getString(keyLatitude, null) ?: defaultSP
|
||||||
|
val longitude = preferences.getString(keyLongitude, null) ?: defaultSP
|
||||||
|
val altitude = preferences.getString(keyAltitude, null) ?: defaultSP
|
||||||
|
return StationPosition(latitude.toDouble(), longitude.toDouble(), altitude.toDouble())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveStationPosition(position: StationPosition) {
|
||||||
|
preferences.edit {
|
||||||
|
putString(keyLatitude, position.latitude.toString())
|
||||||
|
putString(keyLongitude, position.longitude.toString())
|
||||||
|
putString(keyAltitude, position.altitude.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.utility
|
package com.rtbishop.look4sat.framework
|
||||||
|
|
||||||
import android.hardware.Sensor
|
import android.hardware.Sensor
|
||||||
import android.hardware.SensorEvent
|
import android.hardware.SensorEvent
|
||||||
+2
-33
@@ -15,20 +15,18 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.utility
|
package com.rtbishop.look4sat.framework
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.hardware.GeomagneticField
|
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.rtbishop.look4sat.framework.model.TleSource
|
import com.rtbishop.look4sat.framework.model.TleSource
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.squareup.moshi.Types
|
import com.squareup.moshi.Types
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PrefsManager @Inject constructor(val preferences: SharedPreferences, moshi: Moshi) {
|
class PrefsManager @Inject constructor(private val preferences: SharedPreferences, moshi: Moshi) {
|
||||||
|
|
||||||
private val sourcesType = Types.newParameterizedType(List::class.java, TleSource::class.java)
|
private val sourcesType = Types.newParameterizedType(List::class.java, TleSource::class.java)
|
||||||
private val sourcesAdapter = moshi.adapter<List<TleSource>>(sourcesType)
|
private val sourcesAdapter = moshi.adapter<List<TleSource>>(sourcesType)
|
||||||
@@ -36,16 +34,11 @@ class PrefsManager @Inject constructor(val preferences: SharedPreferences, moshi
|
|||||||
companion object {
|
companion object {
|
||||||
const val keySources = "sourcesListJson"
|
const val keySources = "sourcesListJson"
|
||||||
const val keyModes = "satModes"
|
const val keyModes = "satModes"
|
||||||
const val keyLatitude = "latitude"
|
|
||||||
const val keyLongitude = "longitude"
|
|
||||||
const val keyAltitude = "altitude"
|
|
||||||
const val keyCompass = "compass"
|
const val keyCompass = "compass"
|
||||||
const val keyTextLabels = "shouldUseTextLabels"
|
const val keyTextLabels = "shouldUseTextLabels"
|
||||||
const val keyTimeUTC = "timeUTC"
|
const val keyTimeUTC = "timeUTC"
|
||||||
const val keyHoursAhead = "hoursAhead"
|
const val keyHoursAhead = "hoursAhead"
|
||||||
const val keyMinElevation = "minElevation"
|
const val keyMinElevation = "minElevation"
|
||||||
const val keyPositionGPS = "setPositionGPS"
|
|
||||||
const val keyPositionQTH = "setPositionQTH"
|
|
||||||
const val keyIsFirstLaunch = "shouldShowSplash"
|
const val keyIsFirstLaunch = "shouldShowSplash"
|
||||||
const val keyRotator = "isRotatorEnabled"
|
const val keyRotator = "isRotatorEnabled"
|
||||||
const val keyRotatorAddress = "rotatorAddress"
|
const val keyRotatorAddress = "rotatorAddress"
|
||||||
@@ -59,30 +52,6 @@ class PrefsManager @Inject constructor(val preferences: SharedPreferences, moshi
|
|||||||
fun getMinElevation(): Double {
|
fun getMinElevation(): Double {
|
||||||
return preferences.getInt(keyMinElevation, 16).toDouble()
|
return preferences.getInt(keyMinElevation, 16).toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStationPosition(): StationPosition {
|
|
||||||
val defaultGSP = "0.0"
|
|
||||||
val latitude = preferences.getString(keyLatitude, null) ?: defaultGSP
|
|
||||||
val longitude = preferences.getString(keyLongitude, null) ?: defaultGSP
|
|
||||||
val altitude = preferences.getString(keyAltitude, null) ?: defaultGSP
|
|
||||||
return StationPosition(latitude.toDouble(), longitude.toDouble(), altitude.toDouble())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setStationPosition(latitude: Double, longitude: Double, altitude: Double) {
|
|
||||||
preferences.edit {
|
|
||||||
putString(keyLatitude, latitude.toString())
|
|
||||||
putString(keyLongitude, longitude.toString())
|
|
||||||
putString(keyAltitude, altitude.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getMagDeclination(): Float {
|
|
||||||
val stationPosition = getStationPosition()
|
|
||||||
val lat = stationPosition.latitude.toFloat()
|
|
||||||
val lon = stationPosition.longitude.toFloat()
|
|
||||||
val alt = stationPosition.altitude.toFloat()
|
|
||||||
return GeomagneticField(lat, lon, alt, System.currentTimeMillis()).declination
|
|
||||||
}
|
|
||||||
|
|
||||||
fun shouldUseTextLabels(): Boolean {
|
fun shouldUseTextLabels(): Boolean {
|
||||||
return preferences.getBoolean(keyTextLabels, false)
|
return preferences.getBoolean(keyTextLabels, false)
|
||||||
@@ -23,7 +23,7 @@ import androidx.room.TypeConverters
|
|||||||
import com.rtbishop.look4sat.framework.model.SatEntry
|
import com.rtbishop.look4sat.framework.model.SatEntry
|
||||||
import com.rtbishop.look4sat.framework.model.SatTrans
|
import com.rtbishop.look4sat.framework.model.SatTrans
|
||||||
|
|
||||||
@Database(entities = [SatEntry::class, SatTrans::class], version = 1)
|
@Database(entities = [SatEntry::class, SatTrans::class], version = 1, exportSchema = false)
|
||||||
@TypeConverters(RoomConverters::class)
|
@TypeConverters(RoomConverters::class)
|
||||||
abstract class SatelliteDb : RoomDatabase() {
|
abstract class SatelliteDb : RoomDatabase() {
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.presentation
|
package com.rtbishop.look4sat.presentation
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -24,16 +25,18 @@ import androidx.navigation.fragment.NavHostFragment
|
|||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.databinding.ActivityMainBinding
|
import com.rtbishop.look4sat.databinding.ActivityMainBinding
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
|
import com.rtbishop.look4sat.utility.navigateSafe
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class Look4SatActivity : AppCompatActivity() {
|
class Look4SatActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var prefsManager: PrefsManager
|
lateinit var prefsManager: PrefsManager
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
setTheme(R.style.AppTheme)
|
setTheme(R.style.AppTheme)
|
||||||
@@ -44,7 +47,7 @@ class Look4SatActivity : AppCompatActivity() {
|
|||||||
binding.navBottom.setupWithNavController(navHost.navController)
|
binding.navBottom.setupWithNavController(navHost.navController)
|
||||||
if (prefsManager.isFirstLaunch()) {
|
if (prefsManager.isFirstLaunch()) {
|
||||||
prefsManager.setFirstLaunchDone()
|
prefsManager.setFirstLaunchDone()
|
||||||
navHost.navController.navigate(R.id.nav_dialog_splash)
|
navHost.navController.navigateSafe(R.id.nav_dialog_splash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -32,7 +32,7 @@ import com.rtbishop.look4sat.interactors.GetSatItems
|
|||||||
import com.rtbishop.look4sat.interactors.ImportDataFromStream
|
import com.rtbishop.look4sat.interactors.ImportDataFromStream
|
||||||
import com.rtbishop.look4sat.interactors.ImportDataFromWeb
|
import com.rtbishop.look4sat.interactors.ImportDataFromWeb
|
||||||
import com.rtbishop.look4sat.interactors.UpdateEntriesSelection
|
import com.rtbishop.look4sat.interactors.UpdateEntriesSelection
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -156,8 +156,8 @@ class EntriesViewModel @Inject constructor(
|
|||||||
items.filter { it.catNum == query.toInt() }
|
items.filter { it.catNum == query.toInt() }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
items.filter { item ->
|
items.filter { item ->
|
||||||
val itemName = item.name.toLowerCase(Locale.getDefault())
|
val itemName = item.name.lowercase(Locale.getDefault())
|
||||||
itemName.contains(query.toLowerCase(Locale.getDefault()))
|
itemName.contains(query.lowercase(Locale.getDefault()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.presentation.mapScreen
|
package com.rtbishop.look4sat.presentation.mapScreen
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.ColorMatrix
|
import android.graphics.ColorMatrix
|
||||||
import android.graphics.ColorMatrixColorFilter
|
import android.graphics.ColorMatrixColorFilter
|
||||||
@@ -40,10 +41,14 @@ import org.osmdroid.views.MapView
|
|||||||
import org.osmdroid.views.overlay.*
|
import org.osmdroid.views.overlay.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MapFragment : Fragment(R.layout.fragment_map) {
|
class MapFragment : Fragment(R.layout.fragment_map) {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var sharedPreferences: SharedPreferences
|
||||||
|
|
||||||
private val viewModel: MapViewModel by viewModels()
|
private val viewModel: MapViewModel by viewModels()
|
||||||
private val minLat = MapView.getTileSystem().minLatitude
|
private val minLat = MapView.getTileSystem().minLatitude
|
||||||
private val maxLat = MapView.getTileSystem().maxLatitude
|
private val maxLat = MapView.getTileSystem().maxLatitude
|
||||||
@@ -63,7 +68,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
Configuration.getInstance().load(requireContext(), viewModel.getPreferences())
|
Configuration.getInstance().load(requireContext(), sharedPreferences)
|
||||||
val binding = FragmentMapBinding.bind(view).apply {
|
val binding = FragmentMapBinding.bind(view).apply {
|
||||||
mapView.apply {
|
mapView.apply {
|
||||||
setMultiTouchControls(true)
|
setMultiTouchControls(true)
|
||||||
@@ -183,7 +188,8 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||||||
|
|
||||||
private fun renderSatData(satData: SatData, binding: FragmentMapBinding) {
|
private fun renderSatData(satData: SatData, binding: FragmentMapBinding) {
|
||||||
binding.apply {
|
binding.apply {
|
||||||
idName.text = String.format(getString(R.string.pat_osm_idName), satData.catNum, satData.name)
|
idName.text =
|
||||||
|
String.format(getString(R.string.pat_osm_idName), satData.catNum, satData.name)
|
||||||
qthLocator.text = String.format(getString(R.string.map_qth), satData.qthLoc)
|
qthLocator.text = String.format(getString(R.string.map_qth), satData.qthLoc)
|
||||||
altitude.text = String.format(getString(R.string.pat_altitude), satData.altitude)
|
altitude.text = String.format(getString(R.string.pat_altitude), satData.altitude)
|
||||||
distance.text = String.format(getString(R.string.pat_distance), satData.range)
|
distance.text = String.format(getString(R.string.pat_distance), satData.range)
|
||||||
|
|||||||
@@ -17,16 +17,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.presentation.mapScreen
|
package com.rtbishop.look4sat.presentation.mapScreen
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
|
import com.rtbishop.look4sat.data.LocationRepo
|
||||||
import com.rtbishop.look4sat.di.DefaultDispatcher
|
import com.rtbishop.look4sat.di.DefaultDispatcher
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.Position
|
import com.rtbishop.look4sat.domain.predict4kotlin.Position
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
|
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
||||||
import com.rtbishop.look4sat.framework.model.SatData
|
import com.rtbishop.look4sat.framework.model.SatData
|
||||||
import com.rtbishop.look4sat.interactors.GetSelectedSatellites
|
import com.rtbishop.look4sat.interactors.GetSelectedSatellites
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -40,11 +39,11 @@ import kotlin.math.sqrt
|
|||||||
class MapViewModel @Inject constructor(
|
class MapViewModel @Inject constructor(
|
||||||
private val getSelectedSatellites: GetSelectedSatellites,
|
private val getSelectedSatellites: GetSelectedSatellites,
|
||||||
private val prefsManager: PrefsManager,
|
private val prefsManager: PrefsManager,
|
||||||
private val qthConverter: QthConverter,
|
private val locationRepo: LocationRepo,
|
||||||
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher
|
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val gsp = prefsManager.getStationPosition()
|
private val gsp = locationRepo.getStationPosition()
|
||||||
private var dataUpdateJob: Job? = null
|
private var dataUpdateJob: Job? = null
|
||||||
private var allSatList = listOf<Satellite>()
|
private var allSatList = listOf<Satellite>()
|
||||||
private lateinit var selectedSat: Satellite
|
private lateinit var selectedSat: Satellite
|
||||||
@@ -78,10 +77,6 @@ class MapViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPreferences(): SharedPreferences {
|
|
||||||
return prefsManager.preferences
|
|
||||||
}
|
|
||||||
|
|
||||||
fun shouldUseTextLabels(): Boolean {
|
fun shouldUseTextLabels(): Boolean {
|
||||||
return prefsManager.shouldUseTextLabels()
|
return prefsManager.shouldUseTextLabels()
|
||||||
}
|
}
|
||||||
@@ -177,7 +172,7 @@ class MapViewModel @Inject constructor(
|
|||||||
val osmLat = getOsmLat(Math.toDegrees(satPos.latitude))
|
val osmLat = getOsmLat(Math.toDegrees(satPos.latitude))
|
||||||
val osmLon = getOsmLon(Math.toDegrees(satPos.longitude))
|
val osmLon = getOsmLon(Math.toDegrees(satPos.longitude))
|
||||||
val osmPos = Position(osmLat, osmLon)
|
val osmPos = Position(osmLat, osmLon)
|
||||||
val qthLoc = qthConverter.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --"
|
val qthLoc = locationRepo.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --"
|
||||||
val velocity = getOrbitalVelocity(satPos.altitude)
|
val velocity = getOrbitalVelocity(satPos.altitude)
|
||||||
val satData = SatData(
|
val satData = SatData(
|
||||||
sat, sat.tle.catnum, sat.tle.name, satPos.range,
|
sat, sat.tle.catnum, sat.tle.name, satPos.range,
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import com.rtbishop.look4sat.framework.model.Result
|
|||||||
import com.rtbishop.look4sat.utility.PassesRepo
|
import com.rtbishop.look4sat.utility.PassesRepo
|
||||||
import com.rtbishop.look4sat.interactors.GetSelectedSatellites
|
import com.rtbishop.look4sat.interactors.GetSelectedSatellites
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
|
|||||||
@@ -18,13 +18,14 @@
|
|||||||
package com.rtbishop.look4sat.presentation.polarScreen
|
package com.rtbishop.look4sat.presentation.polarScreen
|
||||||
|
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
|
import com.rtbishop.look4sat.data.LocationRepo
|
||||||
import com.rtbishop.look4sat.di.IoDispatcher
|
import com.rtbishop.look4sat.di.IoDispatcher
|
||||||
import com.rtbishop.look4sat.domain.model.SatTrans
|
import com.rtbishop.look4sat.domain.model.SatTrans
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
||||||
import com.rtbishop.look4sat.interactors.GetTransmittersForSat
|
import com.rtbishop.look4sat.interactors.GetTransmittersForSat
|
||||||
import com.rtbishop.look4sat.utility.OrientationProvider
|
import com.rtbishop.look4sat.framework.OrientationProvider
|
||||||
import com.rtbishop.look4sat.utility.PassesRepo
|
import com.rtbishop.look4sat.utility.PassesRepo
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import com.rtbishop.look4sat.utility.round
|
import com.rtbishop.look4sat.utility.round
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@@ -36,6 +37,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class PolarViewModel @Inject constructor(
|
class PolarViewModel @Inject constructor(
|
||||||
|
private val locationRepo: LocationRepo,
|
||||||
private val orientationProvider: OrientationProvider,
|
private val orientationProvider: OrientationProvider,
|
||||||
private val prefsManager: PrefsManager,
|
private val prefsManager: PrefsManager,
|
||||||
private val passesRepo: PassesRepo,
|
private val passesRepo: PassesRepo,
|
||||||
@@ -68,7 +70,7 @@ class PolarViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
|
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
|
||||||
_orientation.value = Triple(azimuth + prefsManager.getMagDeclination(), pitch, roll)
|
_orientation.value = Triple(azimuth + locationRepo.getMagDeclination(), pitch, roll)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initRotatorControl(satPass: SatPass) {
|
private fun initRotatorControl(satPass: SatPass) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.rtbishop.look4sat.presentation.prefsScreen
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.location.LocationManager
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.util.Patterns
|
import android.util.Patterns
|
||||||
@@ -31,9 +30,9 @@ import androidx.preference.Preference
|
|||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.data.LocationRepo
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
|
import com.rtbishop.look4sat.framework.DefaultLocationSource
|
||||||
import com.rtbishop.look4sat.utility.round
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -41,16 +40,15 @@ import javax.inject.Inject
|
|||||||
class PrefsFragment : PreferenceFragmentCompat() {
|
class PrefsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var locationManager: LocationManager
|
lateinit var locationRepo: LocationRepo
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var prefsManager: PrefsManager
|
lateinit var prefsManager: PrefsManager
|
||||||
@Inject
|
|
||||||
lateinit var qthConverter: QthConverter
|
|
||||||
|
|
||||||
private val requestPermissionLauncher =
|
private val requestPermissionLauncher =
|
||||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
|
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
|
||||||
if (isGranted) {
|
if (isGranted) {
|
||||||
setPositionFromGPS()
|
updatePositionFromGPS()
|
||||||
} else {
|
} else {
|
||||||
showSnack(getString(R.string.pref_pos_gps_error))
|
showSnack(getString(R.string.pref_pos_gps_error))
|
||||||
}
|
}
|
||||||
@@ -63,16 +61,16 @@ class PrefsFragment : PreferenceFragmentCompat() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
findPreference<Preference>(PrefsManager.keyPositionGPS)?.apply {
|
findPreference<Preference>(DefaultLocationSource.keyPositionGPS)?.apply {
|
||||||
setOnPreferenceClickListener {
|
setOnPreferenceClickListener {
|
||||||
setPositionFromGPS()
|
updatePositionFromGPS()
|
||||||
return@setOnPreferenceClickListener true
|
return@setOnPreferenceClickListener true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findPreference<Preference>(PrefsManager.keyPositionQTH)?.apply {
|
findPreference<Preference>(DefaultLocationSource.keyPositionQTH)?.apply {
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
setPositionFromQth(newValue.toString())
|
updatePositionFromQth(newValue.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,34 +99,29 @@ class PrefsFragment : PreferenceFragmentCompat() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setPositionFromQth(qthString: String): Boolean {
|
private fun updatePositionFromQth(qthString: String): Boolean {
|
||||||
qthConverter.qthToPosition(qthString)?.let { gsp ->
|
return if (locationRepo.updatePositionFromQTH(qthString)) {
|
||||||
prefsManager.setStationPosition(gsp.latitude, gsp.longitude, 0.0)
|
|
||||||
showSnack(getString(R.string.pref_pos_success))
|
showSnack(getString(R.string.pref_pos_success))
|
||||||
return true
|
true
|
||||||
|
} else {
|
||||||
|
showSnack(getString(R.string.pref_pos_qth_error))
|
||||||
|
false
|
||||||
}
|
}
|
||||||
showSnack(getString(R.string.pref_pos_qth_error))
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setPositionFromGPS() {
|
private fun updatePositionFromGPS() {
|
||||||
val locPermString = Manifest.permission.ACCESS_FINE_LOCATION
|
val locPermString = Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
val locPermResult = ContextCompat.checkSelfPermission(requireContext(), locPermString)
|
val locPermResult = ContextCompat.checkSelfPermission(requireContext(), locPermString)
|
||||||
if (locPermResult == PackageManager.PERMISSION_GRANTED) {
|
if (locPermResult == PackageManager.PERMISSION_GRANTED) {
|
||||||
val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
|
if (locationRepo.updatePositionFromGPS()) {
|
||||||
if (location != null) {
|
|
||||||
val latitude = location.latitude.round(4)
|
|
||||||
val longitude = location.longitude.round(4)
|
|
||||||
val altitude = location.altitude.round(1)
|
|
||||||
prefsManager.setStationPosition(latitude, longitude, altitude)
|
|
||||||
showSnack(getString(R.string.pref_pos_success))
|
showSnack(getString(R.string.pref_pos_success))
|
||||||
} else showSnack(getString(R.string.pref_pos_gps_null))
|
} else showSnack(getString(R.string.pref_pos_gps_null))
|
||||||
} else requestPermissionLauncher.launch(locPermString)
|
} else requestPermissionLauncher.launch(locPermString)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSnack(message: String) {
|
private fun showSnack(message: String) {
|
||||||
Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT)
|
Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT).apply {
|
||||||
.setAnchorView(R.id.nav_bottom)
|
setAnchorView(R.id.nav_bottom)
|
||||||
.show()
|
}.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ import android.view.WindowManager
|
|||||||
import androidx.appcompat.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.rtbishop.look4sat.R
|
import com.rtbishop.look4sat.R
|
||||||
import com.rtbishop.look4sat.utility.PrefsManager
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import com.rtbishop.look4sat.databinding.DialogSourcesBinding
|
import com.rtbishop.look4sat.databinding.DialogSourcesBinding
|
||||||
import com.rtbishop.look4sat.utility.setNavResult
|
import com.rtbishop.look4sat.utility.setNavResult
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.rtbishop.look4sat.utility
|
package com.rtbishop.look4sat.utility
|
||||||
|
|
||||||
|
import com.rtbishop.look4sat.data.LocationRepo
|
||||||
import com.rtbishop.look4sat.di.DefaultDispatcher
|
import com.rtbishop.look4sat.di.DefaultDispatcher
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
||||||
|
import com.rtbishop.look4sat.framework.PrefsManager
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
@@ -30,6 +32,7 @@ import javax.inject.Singleton
|
|||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class PassesRepo @Inject constructor(
|
class PassesRepo @Inject constructor(
|
||||||
|
private val locationRepo: LocationRepo,
|
||||||
private val prefsManager: PrefsManager,
|
private val prefsManager: PrefsManager,
|
||||||
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher
|
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher
|
||||||
) {
|
) {
|
||||||
@@ -61,7 +64,7 @@ class PassesRepo @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getPasses(satellite: Satellite, refDate: Date): List<SatPass> {
|
private fun getPasses(satellite: Satellite, refDate: Date): List<SatPass> {
|
||||||
val predictor = satellite.getPredictor(prefsManager.getStationPosition())
|
val predictor = satellite.getPredictor(locationRepo.getStationPosition())
|
||||||
return predictor.getPasses(refDate, prefsManager.getHoursAhead(), true)
|
return predictor.getPasses(refDate, prefsManager.getHoursAhead(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.rtbishop.look4sat.data
|
||||||
|
|
||||||
|
import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
|
||||||
|
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
||||||
|
|
||||||
|
class LocationRepo(
|
||||||
|
private val locationSource: LocationSource,
|
||||||
|
private val qthConverter: QthConverter
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun getStationPosition(): StationPosition {
|
||||||
|
return locationSource.loadStationPosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMagDeclination(): Float {
|
||||||
|
return locationSource.getMagDeclination(getStationPosition())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun positionToQTH(lat: Double, lon: Double): String? {
|
||||||
|
return qthConverter.positionToQTH(lat, lon)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePositionFromGPS(): Boolean {
|
||||||
|
val stationPosition = locationSource.getLastKnownLocation() ?: return false
|
||||||
|
locationSource.saveStationPosition(stationPosition)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePositionFromQTH(qthString: String): Boolean {
|
||||||
|
val position = qthConverter.qthToPosition(qthString) ?: return false
|
||||||
|
val stationPosition = StationPosition(position.latitude, position.longitude, 0.0)
|
||||||
|
locationSource.saveStationPosition(stationPosition)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.rtbishop.look4sat.data
|
||||||
|
|
||||||
|
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
|
||||||
|
|
||||||
|
interface LocationSource {
|
||||||
|
|
||||||
|
fun getLastKnownLocation(): StationPosition?
|
||||||
|
|
||||||
|
fun getMagDeclination(position: StationPosition): Float
|
||||||
|
|
||||||
|
fun loadStationPosition(): StationPosition
|
||||||
|
|
||||||
|
fun saveStationPosition(position: StationPosition)
|
||||||
|
}
|
||||||
+8
-9
@@ -1,6 +1,5 @@
|
|||||||
package com.rtbishop.look4sat.data
|
package com.rtbishop.look4sat.data
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
|
||||||
import com.rtbishop.look4sat.domain.model.SatEntry
|
import com.rtbishop.look4sat.domain.model.SatEntry
|
||||||
import com.rtbishop.look4sat.domain.model.SatItem
|
import com.rtbishop.look4sat.domain.model.SatItem
|
||||||
import com.rtbishop.look4sat.domain.model.SatTrans
|
import com.rtbishop.look4sat.domain.model.SatTrans
|
||||||
@@ -13,30 +12,30 @@ import kotlinx.coroutines.withContext
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
class DefaultSatelliteRepo(
|
class SatelliteRepo(
|
||||||
private val localSource: LocalDataSource,
|
private val localSource: LocalDataSource,
|
||||||
private val remoteSource: RemoteDataSource,
|
private val remoteSource: RemoteDataSource,
|
||||||
private val ioDispatcher: CoroutineDispatcher
|
private val ioDispatcher: CoroutineDispatcher
|
||||||
) : SatelliteRepo {
|
) {
|
||||||
|
|
||||||
override fun getSatItems(): Flow<List<SatItem>> {
|
fun getSatItems(): Flow<List<SatItem>> {
|
||||||
return localSource.getSatItems()
|
return localSource.getSatItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTransmittersForSat(catNum: Int): Flow<List<SatTrans>> {
|
fun getTransmittersForSat(catNum: Int): Flow<List<SatTrans>> {
|
||||||
return localSource.getTransmittersForSat(catNum)
|
return localSource.getTransmittersForSat(catNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getSelectedSatellites(): List<Satellite> {
|
suspend fun getSelectedSatellites(): List<Satellite> {
|
||||||
return localSource.getSelectedSatellites()
|
return localSource.getSelectedSatellites()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun importDataFromStream(stream: InputStream) = withContext(ioDispatcher) {
|
suspend fun importDataFromStream(stream: InputStream) = withContext(ioDispatcher) {
|
||||||
val importedEntries = Satellite.importElements(stream).map { tle -> SatEntry(tle) }
|
val importedEntries = Satellite.importElements(stream).map { tle -> SatEntry(tle) }
|
||||||
localSource.updateEntries(importedEntries)
|
localSource.updateEntries(importedEntries)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun importDataFromWeb(sources: List<String>) {
|
suspend fun importDataFromWeb(sources: List<String>) {
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
launch(ioDispatcher) {
|
launch(ioDispatcher) {
|
||||||
val importedEntries = mutableListOf<SatEntry>()
|
val importedEntries = mutableListOf<SatEntry>()
|
||||||
@@ -64,7 +63,7 @@ class DefaultSatelliteRepo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean) {
|
suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean) {
|
||||||
localSource.updateEntriesSelection(catNums, isSelected)
|
localSource.updateEntriesSelection(catNums, isSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.rtbishop.look4sat.domain
|
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.model.SatItem
|
|
||||||
import com.rtbishop.look4sat.domain.model.SatTrans
|
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
interface SatelliteRepo {
|
|
||||||
|
|
||||||
fun getSatItems(): Flow<List<SatItem>>
|
|
||||||
|
|
||||||
fun getTransmittersForSat(catNum: Int): Flow<List<SatTrans>>
|
|
||||||
|
|
||||||
suspend fun getSelectedSatellites(): List<Satellite>
|
|
||||||
|
|
||||||
suspend fun importDataFromStream(stream: InputStream)
|
|
||||||
|
|
||||||
suspend fun importDataFromWeb(sources: List<String>)
|
|
||||||
|
|
||||||
suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean)
|
|
||||||
}
|
|
||||||
@@ -24,12 +24,12 @@ class QthConverter {
|
|||||||
fun qthToPosition(qthString: String): Position? {
|
fun qthToPosition(qthString: String): Position? {
|
||||||
val trimmedQth = qthString.take(6)
|
val trimmedQth = qthString.take(6)
|
||||||
if (!isValidQTH(trimmedQth)) return null
|
if (!isValidQTH(trimmedQth)) return null
|
||||||
val lonFirst = (trimmedQth[0].toUpperCase().toInt() - 65) * 20
|
val lonFirst = (trimmedQth[0].uppercaseChar().code - 65) * 20
|
||||||
val latFirst = (trimmedQth[1].toUpperCase().toInt() - 65) * 10
|
val latFirst = (trimmedQth[1].uppercaseChar().code - 65) * 10
|
||||||
val lonSecond = trimmedQth[2].toString().toInt() * 2
|
val lonSecond = trimmedQth[2].toString().toInt() * 2
|
||||||
val latSecond = trimmedQth[3].toString().toInt()
|
val latSecond = trimmedQth[3].toString().toInt()
|
||||||
val lonThird = (((trimmedQth[4].toLowerCase().toInt() - 97) / 12.0) + (1.0 / 24.0)) - 180
|
val lonThird = (((trimmedQth[4].lowercaseChar().code - 97) / 12.0) + (1.0 / 24.0)) - 180
|
||||||
val latThird = (((trimmedQth[5].toLowerCase().toInt() - 97) / 24.0) + (1.0 / 48.0)) - 90
|
val latThird = (((trimmedQth[5].lowercaseChar().code - 97) / 24.0) + (1.0 / 48.0)) - 90
|
||||||
val longitude = (lonFirst + lonSecond + lonThird).roundToDecimals(4)
|
val longitude = (lonFirst + lonSecond + lonThird).roundToDecimals(4)
|
||||||
val latitude = (latFirst + latSecond + latThird).roundToDecimals(4)
|
val latitude = (latFirst + latSecond + latThird).roundToDecimals(4)
|
||||||
return Position(latitude, longitude)
|
return Position(latitude, longitude)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.model.SatItem
|
import com.rtbishop.look4sat.domain.model.SatItem
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
|
||||||
|
|
||||||
class GetSelectedSatellites(private val satelliteRepo: SatelliteRepo) {
|
class GetSelectedSatellites(private val satelliteRepo: SatelliteRepo) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import com.rtbishop.look4sat.domain.model.SatTrans
|
import com.rtbishop.look4sat.domain.model.SatTrans
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
class ImportDataFromStream(private val satelliteRepo: SatelliteRepo) {
|
class ImportDataFromStream(private val satelliteRepo: SatelliteRepo) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
|
|
||||||
class ImportDataFromWeb(private val satelliteRepo: SatelliteRepo) {
|
class ImportDataFromWeb(private val satelliteRepo: SatelliteRepo) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.rtbishop.look4sat.interactors
|
package com.rtbishop.look4sat.interactors
|
||||||
|
|
||||||
import com.rtbishop.look4sat.domain.SatelliteRepo
|
import com.rtbishop.look4sat.data.SatelliteRepo
|
||||||
|
|
||||||
class UpdateEntriesSelection(private val satelliteRepo: SatelliteRepo) {
|
class UpdateEntriesSelection(private val satelliteRepo: SatelliteRepo) {
|
||||||
|
|
||||||
|
|||||||
@@ -21,40 +21,40 @@ import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class QthConverterTest {
|
class QthConverterTest {
|
||||||
|
|
||||||
private val converter = QthConverter()
|
private val qthConverter = QthConverter()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Given valid QTH returns correct location`() {
|
fun `Given valid QTH returns correct POS`() {
|
||||||
var result = converter.qthToPosition("io91VL39FX")
|
var result = qthConverter.qthToPosition("io91VL39FX")
|
||||||
assert(result?.latitude == 51.4792 && result.longitude == -0.2083)
|
assert(result?.latitude == 51.4792 && result.longitude == -0.2083)
|
||||||
result = converter.qthToPosition("JN58TD")
|
result = qthConverter.qthToPosition("JN58TD")
|
||||||
assert(result?.latitude == 48.1458 && result.longitude == 11.6250)
|
assert(result?.latitude == 48.1458 && result.longitude == 11.6250)
|
||||||
result = converter.qthToPosition("gf15vc")
|
result = qthConverter.qthToPosition("gf15vc")
|
||||||
assert(result?.latitude == -34.8958 && result.longitude == -56.2083)
|
assert(result?.latitude == -34.8958 && result.longitude == -56.2083)
|
||||||
result = converter.qthToPosition("fm18LW")
|
result = qthConverter.qthToPosition("fm18LW")
|
||||||
assert(result?.latitude == 38.9375 && result.longitude == -77.0417)
|
assert(result?.latitude == 38.9375 && result.longitude == -77.0417)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Given invalid QTH returns null`() {
|
fun `Given invalid QTH returns null`() {
|
||||||
var result = converter.qthToPosition("ZZ00zz")
|
var result = qthConverter.qthToPosition("ZZ00zz")
|
||||||
assert(result == null)
|
assert(result == null)
|
||||||
result = converter.qthToPosition("JN58tz")
|
result = qthConverter.qthToPosition("JN58tz")
|
||||||
assert(result == null)
|
assert(result == null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Given valid location returns correct QTH`() {
|
fun `Given valid POS returns correct QTH`() {
|
||||||
assert(converter.positionToQTH(51.4878, -0.2146) == "IO91vl")
|
assert(qthConverter.positionToQTH(51.4878, -0.2146) == "IO91vl")
|
||||||
assert(converter.positionToQTH(48.1466, 11.6083) == "JN58td")
|
assert(qthConverter.positionToQTH(48.1466, 11.6083) == "JN58td")
|
||||||
assert(converter.positionToQTH(-34.91, -56.2116) == "GF15vc")
|
assert(qthConverter.positionToQTH(-34.91, -56.2116) == "GF15vc")
|
||||||
assert(converter.positionToQTH(38.92, -77.065) == "FM18lw")
|
assert(qthConverter.positionToQTH(38.92, -77.065) == "FM18lw")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Given invalid location returns null`() {
|
fun `Given invalid location returns null`() {
|
||||||
assert(converter.positionToQTH(91.0542, -170.1142) == null)
|
assert(qthConverter.positionToQTH(91.0542, -170.1142) == null)
|
||||||
assert(converter.positionToQTH(89.0542, -240.1142) == null)
|
assert(qthConverter.positionToQTH(89.0542, -240.1142) == null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user