Rebased from master

This commit is contained in:
Arty Bishop committed 2020-09-19 20:19:25 +01:00
1 parent 770fb9b244
commit e90322d828
8 files changed
+229 -89

No files matched your search

+9 -14
View File
@@ -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"
}
+2
View File
@@ -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()
}
}
+18
View File
@@ -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.