mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Rebased from master
This commit is contained in:
1 parent
770fb9b244
commit
e90322d828
8 files changed
+229
-89
No files matched your search
+9
-14
@@ -66,11 +66,8 @@ dependencies {
|
||||
implementation "androidx.appcompat:appcompat:$appCompat"
|
||||
implementation "androidx.legacy:legacy-support-v4:$supportLib"
|
||||
implementation "androidx.constraintlayout:constraintlayout:$constraintLayout"
|
||||
|
||||
implementation "androidx.core:core-ktx:$ktx"
|
||||
implementation "androidx.preference:preference:$preference"
|
||||
|
||||
// architecture components
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:$navigation"
|
||||
implementation "androidx.navigation:navigation-runtime-ktx:$navigation"
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$navigation"
|
||||
@@ -78,24 +75,22 @@ dependencies {
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle"
|
||||
|
||||
// room
|
||||
implementation "androidx.room:room-runtime:$room"
|
||||
implementation "androidx.room:room-ktx:$room"
|
||||
kapt "androidx.room:room-compiler:$room"
|
||||
|
||||
// retrofit
|
||||
implementation "com.google.dagger:dagger:$dagger"
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger"
|
||||
|
||||
implementation "com.squareup.retrofit2:retrofit:$retrofit"
|
||||
implementation "com.squareup.retrofit2:converter-gson:$retrofit"
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttp"
|
||||
|
||||
//dagger
|
||||
implementation "com.google.dagger:dagger:$dagger"
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger"
|
||||
|
||||
// predict4java
|
||||
implementation "com.github.davidmoten:predict4java:$predict4java"
|
||||
|
||||
// openStreetMaps
|
||||
implementation "org.osmdroid:osmdroid-android:$openStreetMap"
|
||||
implementation "org.osmdroid:osmdroid-mapsforge:$openStreetMap"
|
||||
implementation "org.mapsforge:mapsforge-map-android:$mapsForge"
|
||||
implementation "org.mapsforge:mapsforge-map:$mapsForge"
|
||||
implementation "org.mapsforge:mapsforge-themes:$mapsForge"
|
||||
|
||||
implementation "com.github.davidmoten:predict4java:$predict4java"
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name="com.rtbishop.look4sat.Look4SatApp"
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.rtbishop.look4sat.dagger
|
||||
import android.content.Context
|
||||
import com.rtbishop.look4sat.dagger.modules.*
|
||||
import com.rtbishop.look4sat.ui.MainActivity
|
||||
import com.rtbishop.look4sat.ui.fragments.MapOsmFragment
|
||||
import com.rtbishop.look4sat.ui.fragments.MapViewFragment
|
||||
import com.rtbishop.look4sat.ui.fragments.PassListFragment
|
||||
import com.rtbishop.look4sat.ui.fragments.PolarViewFragment
|
||||
@@ -45,4 +46,5 @@ interface AppComponent {
|
||||
fun inject(mapViewFragment: MapViewFragment)
|
||||
fun inject(passListFragment: PassListFragment)
|
||||
fun inject(polarViewFragment: PolarViewFragment)
|
||||
fun inject(mapOsmFragment: MapOsmFragment)
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package com.rtbishop.look4sat.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.PackageManager
|
||||
@@ -30,7 +31,6 @@ import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -54,10 +54,13 @@ import javax.inject.Inject
|
||||
|
||||
class MainActivity : AppCompatActivity(), TleSourcesDialogFragment.SourcesSubmitListener {
|
||||
|
||||
private val pickFileReqCode = 111
|
||||
private val permLocationCode = 101
|
||||
private val permLocation = Manifest.permission.ACCESS_FINE_LOCATION
|
||||
private val permGranted = PackageManager.PERMISSION_GRANTED
|
||||
private val pickFileReqCode = 1001
|
||||
private val permissionsReqCode = 1000
|
||||
private val permissions = arrayOf(
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
@@ -83,6 +86,10 @@ class MainActivity : AppCompatActivity(), TleSourcesDialogFragment.SourcesSubmit
|
||||
setupDrawer()
|
||||
|
||||
viewModel.setDefaultTleSources()
|
||||
|
||||
if (!hasPermissions(this, permissions)) {
|
||||
ActivityCompat.requestPermissions(this, permissions, permissionsReqCode)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
@@ -154,7 +161,7 @@ class MainActivity : AppCompatActivity(), TleSourcesDialogFragment.SourcesSubmit
|
||||
|
||||
private fun setupDrawer() {
|
||||
drawerBinding.drawerBtnLoc.setOnClickListener {
|
||||
requestLocationUpdate()
|
||||
viewModel.updatePosition()
|
||||
it.lockButton()
|
||||
}
|
||||
drawerBinding.drawerBtnTleFile.setOnClickListener {
|
||||
@@ -193,27 +200,10 @@ class MainActivity : AppCompatActivity(), TleSourcesDialogFragment.SourcesSubmit
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestLocationUpdate() {
|
||||
if (ContextCompat.checkSelfPermission(this, permLocation) != permGranted) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permLocation)) {
|
||||
getString(R.string.err_no_permissions).toast(this)
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(permLocation), permLocationCode)
|
||||
}
|
||||
} else {
|
||||
viewModel.updatePosition()
|
||||
private fun hasPermissions(context: Context, permissions: Array<String>): Boolean =
|
||||
permissions.all {
|
||||
ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(reqCode: Int, perms: Array<out String>, res: IntArray) {
|
||||
when (reqCode) {
|
||||
permLocationCode -> {
|
||||
if (res.isNotEmpty() && res[0] == permGranted) {
|
||||
viewModel.updatePosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
val navController = findNavController(R.id.nav_host)
|
||||
|
||||
@@ -1,73 +1,208 @@
|
||||
package com.rtbishop.look4sat.ui.fragments
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.SatPos
|
||||
import com.rtbishop.look4sat.Look4SatApp
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.dagger.ViewModelFactory
|
||||
import com.rtbishop.look4sat.data.Result
|
||||
import com.rtbishop.look4sat.data.SatPass
|
||||
import com.rtbishop.look4sat.databinding.FragmentMapOsmBinding
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
||||
import com.rtbishop.look4sat.ui.MainActivity
|
||||
import com.rtbishop.look4sat.ui.SharedViewModel
|
||||
import com.rtbishop.look4sat.utility.GeneralUtils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mapsforge.map.rendertheme.XmlRenderTheme
|
||||
import org.mapsforge.map.rendertheme.XmlRenderThemeMenuCallback
|
||||
import org.osmdroid.mapsforge.MapsForgeTileProvider
|
||||
import org.osmdroid.mapsforge.MapsForgeTileSource
|
||||
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver
|
||||
import org.osmdroid.util.GeoPoint
|
||||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.OverlayItem
|
||||
import org.osmdroid.views.overlay.Marker
|
||||
import org.osmdroid.views.overlay.Polygon
|
||||
import org.osmdroid.views.overlay.Polyline
|
||||
import org.osmdroid.views.overlay.compass.CompassOverlay
|
||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
|
||||
|
||||
@Inject
|
||||
lateinit var modelFactory: ViewModelFactory
|
||||
private lateinit var mainActivity: MainActivity
|
||||
private lateinit var viewModel: SharedViewModel
|
||||
private lateinit var binding: FragmentMapOsmBinding
|
||||
private lateinit var mapView: MapView
|
||||
private var satPassList = emptyList<SatPass>()
|
||||
private var gsp = GroundStationPosition(0.0, 0.0, 0.0)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val appContext = requireActivity().applicationContext
|
||||
|
||||
binding = FragmentMapOsmBinding.bind(view)
|
||||
binding.mapView.apply {
|
||||
controller.animateTo(mapCenter)
|
||||
controller.setZoom(2.5)
|
||||
setMultiTouchControls(true)
|
||||
maxZoomLevel = 7.5
|
||||
minZoomLevel = 2.5
|
||||
// isClickable = true
|
||||
// setScrollableAreaLimitLatitude(-90.0, 90.0, 0)
|
||||
// setScrollableAreaLimitLongitude(-180.0, 180.0, 0)
|
||||
}
|
||||
mainActivity = requireActivity() as MainActivity
|
||||
(mainActivity.application as Look4SatApp).appComponent.inject(this)
|
||||
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
|
||||
|
||||
Configuration
|
||||
.getInstance()
|
||||
.load(appContext, PreferenceManager.getDefaultSharedPreferences(appContext))
|
||||
|
||||
init()
|
||||
setupObservers()
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE)
|
||||
val gPt = GeoPoint(28.6337874, 77.35767599999997)
|
||||
val gPt2 = GeoPoint(28.638472, 77.360667)
|
||||
mapView.controller.setCenter(gPt)
|
||||
private fun setupObservers() {
|
||||
viewModel.getGSP().observe(viewLifecycleOwner, Observer { result ->
|
||||
when (result) {
|
||||
is Result.Success -> gsp = result.data
|
||||
}
|
||||
})
|
||||
|
||||
/*place icon on map*/
|
||||
val items = ArrayList<OverlayItem>()
|
||||
items.add(OverlayItem("Current Location", "Amrapali Village, Indirapuram", gPt))
|
||||
items.add(OverlayItem("Destination", "Aditya Mall, Indirapuram", gPt2))
|
||||
viewModel.getPassList().observe(viewLifecycleOwner, Observer { result ->
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
satPassList = result.data
|
||||
setupMapWithAdapter()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inner class MyRenderTheme : XmlRenderTheme {
|
||||
|
||||
override fun getRenderThemeAsStream(): InputStream {
|
||||
return resources.openRawResource(R.raw.customrender)
|
||||
}
|
||||
|
||||
override fun getMenuCallback(): XmlRenderThemeMenuCallback? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getRelativePathPrefix(): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun setMenuCallback(menuCallback: XmlRenderThemeMenuCallback) {}
|
||||
|
||||
}
|
||||
|
||||
private fun setupMapWithAdapter() {
|
||||
val mapsArray = arrayOf(File(Environment.getExternalStorageDirectory(), "world.map"))
|
||||
val tileSource = MapsForgeTileSource.createFromFiles(mapsArray, MyRenderTheme(), null)
|
||||
val registerReceiver = SimpleRegisterReceiver(mainActivity.applicationContext)
|
||||
val tileProvider = MapsForgeTileProvider(registerReceiver, tileSource, null)
|
||||
|
||||
binding.mapView.tileProvider = tileProvider
|
||||
|
||||
binding.mapView.apply {
|
||||
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
|
||||
minZoomLevel = 3.00
|
||||
maxZoomLevel = 8.00
|
||||
controller.setZoom(5.0)
|
||||
|
||||
val startPoint = GeoPoint(gsp.latitude, gsp.longitude)
|
||||
controller.setCenter(startPoint)
|
||||
|
||||
val startMarker = Marker(binding.mapView)
|
||||
startMarker.position = startPoint
|
||||
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
startMarker.title = "Ground Station Position"
|
||||
overlays.add(startMarker)
|
||||
|
||||
var dateNow = Date(System.currentTimeMillis())
|
||||
val selectedSat = satPassList[3]
|
||||
val orbitalPeriod = (24 * 60 / selectedSat.tle.meanmo).toInt()
|
||||
var positions = selectedSat.predictor.getPositions(dateNow, 60, 0, orbitalPeriod * 3)
|
||||
|
||||
drawGroundTrack(positions)
|
||||
Log.d("myTag", selectedSat.tle.name)
|
||||
|
||||
val compassOverlay = CompassOverlay(
|
||||
context,
|
||||
InternalCompassOrientationProvider(context),
|
||||
binding.mapView
|
||||
)
|
||||
compassOverlay.enableCompass()
|
||||
overlays.add(compassOverlay)
|
||||
|
||||
setMultiTouchControls(true)
|
||||
setScrollableAreaLimitLatitude(85.0, -85.0, 0)
|
||||
|
||||
lifecycleScope.launch {
|
||||
while (true) {
|
||||
delay(3000)
|
||||
dateNow = Date(System.currentTimeMillis())
|
||||
positions =
|
||||
selectedSat.predictor.getPositions(dateNow, 60, 0, orbitalPeriod * 3)
|
||||
drawPosition(GeoPoint(positions[0].latitude, positions[0].longitude))
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawPosition(position: GeoPoint) {
|
||||
val satPosition = Polygon(binding.mapView)
|
||||
val trackPoints = mutableListOf<GeoPoint>()
|
||||
|
||||
Log.d("myTag", "${position.latitude}, ${position.longitude}")
|
||||
|
||||
val lat = GeneralUtils.rad2Deg(position.latitude)
|
||||
var lon = GeneralUtils.rad2Deg(position.longitude)
|
||||
if (lon > 180.0) lon -= 360.0
|
||||
trackPoints.add(GeoPoint(lat, lon))
|
||||
|
||||
val startMarker = Marker(binding.mapView)
|
||||
startMarker.position = GeoPoint(lat, lon)
|
||||
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
startMarker.title = "Sat Position"
|
||||
binding.mapView.overlays.add(startMarker)
|
||||
|
||||
Log.d("myTag", "$lat, $lon")
|
||||
|
||||
binding.mapView.overlays.add(satPosition)
|
||||
satPosition.points = trackPoints
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
|
||||
private fun drawGroundTrack(list: List<SatPos>) {
|
||||
val groundTrack = Polyline(binding.mapView)
|
||||
val trackPoints = mutableListOf<GeoPoint>()
|
||||
var lat = 0.0
|
||||
var lon = 0.0
|
||||
|
||||
Log.d("myTag", "${list[1].latitude}, ${list[1].longitude}")
|
||||
|
||||
list.forEach {
|
||||
lat = GeneralUtils.rad2Deg(it.latitude) * -1
|
||||
lon = GeneralUtils.rad2Deg(it.longitude)
|
||||
if (lon > 180.0) lon -= 360.0
|
||||
trackPoints.add(GeoPoint(lat, lon))
|
||||
}
|
||||
|
||||
Log.d("myTag", "$lat, $lon")
|
||||
|
||||
groundTrack.setPoints(trackPoints)
|
||||
groundTrack.setDensityMultiplier(0.5f)
|
||||
binding.mapView.overlays.add(groundTrack)
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
//this will refresh the osmdroid configuration on resuming.
|
||||
//if you make changes to the configuration, use
|
||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
//Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this));
|
||||
mapView.onResume() //needed for compass, my location overlays, v6.0.0 and up
|
||||
binding.mapView.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
//this will refresh the osmdroid configuration on resuming.
|
||||
//if you make changes to the configuration, use
|
||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
//Configuration.getInstance().save(this, prefs);
|
||||
mapView.onPause() //needed for compass, my location overlays, v6.0.0 and up
|
||||
binding.mapView.onPause()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rendertheme version="5">
|
||||
|
||||
<rule
|
||||
e="way"
|
||||
k="natural"
|
||||
v="issea|sea">
|
||||
<area fill="#242424" />
|
||||
</rule>
|
||||
|
||||
<rule
|
||||
e="way"
|
||||
k="natural"
|
||||
v="nosea">
|
||||
<area fill="#606060" />
|
||||
</rule>
|
||||
|
||||
</rendertheme>
|
||||
Binary file not shown.
+4
-6
@@ -48,21 +48,19 @@ ext {
|
||||
appCompat = '1.1.0'
|
||||
supportLib = '1.0.0'
|
||||
constraintLayout = '1.1.3'
|
||||
|
||||
ktx = '1.3.0'
|
||||
preference = '1.1.1'
|
||||
|
||||
navigation = '2.2.2'
|
||||
lifecycle = '2.2.0'
|
||||
|
||||
room = '2.2.5'
|
||||
|
||||
dagger = '2.28'
|
||||
|
||||
retrofit = '2.9.0'
|
||||
okhttp = '4.7.2'
|
||||
|
||||
dagger = '2.28'
|
||||
openStreetMap = '6.1.6'
|
||||
mapsForge = '0.13.0'
|
||||
|
||||
predict4java = '1.3.1'
|
||||
|
||||
openStreetMap = '6.1.6'
|
||||
}
|
||||
Reference in new issue
Block a user