Further map setup

This commit is contained in:
Arty Bishop committed 2020-09-19 20:19:41 +01:00
1 parent 8c56c31b8c
commit 4346cedbdc
2 files changed
+245 -125

No files matched your search

@@ -1,14 +1,16 @@
package com.rtbishop.look4sat.ui.fragments package com.rtbishop.look4sat.ui.fragments
import android.graphics.Color import android.graphics.Color
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.github.amsacode.predict4java.GroundStationPosition import com.github.amsacode.predict4java.GroundStationPosition
import com.github.amsacode.predict4java.SatPos import com.github.amsacode.predict4java.SatPos
import com.rtbishop.look4sat.Look4SatApp import com.rtbishop.look4sat.Look4SatApp
@@ -19,22 +21,21 @@ import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.databinding.FragmentMapOsmBinding import com.rtbishop.look4sat.databinding.FragmentMapOsmBinding
import com.rtbishop.look4sat.ui.MainActivity import com.rtbishop.look4sat.ui.MainActivity
import com.rtbishop.look4sat.ui.SharedViewModel import com.rtbishop.look4sat.ui.SharedViewModel
import com.rtbishop.look4sat.utility.GeneralUtils import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.mapsforge.map.rendertheme.XmlRenderTheme import kotlinx.coroutines.withContext
import org.mapsforge.map.rendertheme.XmlRenderThemeMenuCallback import org.osmdroid.config.Configuration
import org.osmdroid.mapsforge.MapsForgeTileProvider import org.osmdroid.tileprovider.tilesource.TileSourceFactory
import org.osmdroid.mapsforge.MapsForgeTileSource import org.osmdroid.util.BoundingBox
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver
import org.osmdroid.util.GeoPoint import org.osmdroid.util.GeoPoint
import org.osmdroid.views.overlay.Marker import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.overlay.Polygon import org.osmdroid.views.overlay.*
import org.osmdroid.views.overlay.Polyline
import org.osmdroid.views.overlay.compass.CompassOverlay import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import java.io.File import org.osmdroid.views.overlay.gridlines.LatLonGridlineOverlay2
import java.io.InputStream import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@@ -45,8 +46,6 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
private lateinit var mainActivity: MainActivity private lateinit var mainActivity: MainActivity
private lateinit var viewModel: SharedViewModel private lateinit var viewModel: SharedViewModel
private lateinit var binding: FragmentMapOsmBinding private lateinit var binding: FragmentMapOsmBinding
private var satPassList = emptyList<SatPass>()
private var gsp = GroundStationPosition(0.0, 0.0, 0.0)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
@@ -55,108 +54,241 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
(mainActivity.application as Look4SatApp).appComponent.inject(this) (mainActivity.application as Look4SatApp).appComponent.inject(this)
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java) viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
val prefs = PreferenceManager.getDefaultSharedPreferences(mainActivity.applicationContext)
Configuration.getInstance().load(mainActivity.applicationContext, prefs)
setupMapView()
setupObservers() setupObservers()
} }
private fun setupObservers() { private fun setupMapView() {
viewModel.getGSP().observe(viewLifecycleOwner, Observer { result ->
when (result) {
is Result.Success -> gsp = result.data
}
})
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 { binding.mapView.apply {
setTileSource(TileSourceFactory.MAPNIK)
// General settings
// isHorizontalMapRepetitionEnabled = false
// isVerticalMapRepetitionEnabled = false
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
overlayManager.tilesOverlay.loadingLineColor = 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)
// Zoom settings
minZoomLevel = 2.5
maxZoomLevel = 6.5
controller.setZoom(minZoomLevel)
// controller.setCenter(GeoPoint(0.0, 0.0))
setMultiTouchControls(true) setMultiTouchControls(true)
setScrollableAreaLimitLatitude(85.0, -85.0, 0) zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
lifecycleScope.launch { // Scroll limits
while (true) { // setScrollableAreaLimitLatitude(85.0, -85.0, 0)
delay(3000) // setScrollableAreaLimitLongitude(-180.0, 180.0, 0)
dateNow = Date(System.currentTimeMillis()) setScrollableAreaLimitDouble(BoundingBox(85.0, 180.0, -85.0, -180.0))
positions =
selectedSat.predictor.getPositions(dateNow, 60, 0, orbitalPeriod * 3) addLocationOverlay()
drawPosition(GeoPoint(positions[0].latitude, positions[0].longitude)) addMapScaleBarOverlay()
binding.mapView.invalidate() addSomeIcons()
addColorFilter()
}
}
private fun setupObservers() {
viewModel.getGSP().observe(viewLifecycleOwner, Observer { stationPosition ->
when (stationPosition) {
is Result.Success -> {
// setUserLocation(stationPosition.data)
} }
} }
})
viewModel.getPassList().observe(viewLifecycleOwner, Observer { satPasses ->
when (satPasses) {
is Result.Success -> {
val filteredPasses = satPasses.data.distinctBy { it.tle }
// setupSatOverlay(filteredPasses)
}
}
})
}
private fun setUserLocation(position: GroundStationPosition) {
val startPoint = GeoPoint(position.latitude, position.longitude)
Marker(binding.mapView).apply {
this.position = startPoint
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
title = "Ground Station Position"
} }
} }
private fun addCompassOverlay() {
val overlay =
CompassOverlay(context, InternalCompassOrientationProvider(context), binding.mapView)
overlay.enableCompass()
binding.mapView.overlays.add(overlay)
}
private fun addLocationOverlay() {
val overlay = MyLocationNewOverlay(GpsMyLocationProvider(mainActivity), binding.mapView)
overlay.enableMyLocation()
binding.mapView.overlays.add(overlay)
}
private fun addGridLineOverlay() {
val overlay = LatLonGridlineOverlay2()
binding.mapView.overlays.add(overlay)
}
private fun addMapScaleBarOverlay() {
val dm = mainActivity.resources.displayMetrics
val overlay = ScaleBarOverlay(binding.mapView).apply {
setCentred(true)
setScaleBarOffset(dm.widthPixels / 2, 10)
}
binding.mapView.overlays.add(overlay)
}
private fun addMiniMap() {
val dm = mainActivity.resources.displayMetrics
val overlay =
MinimapOverlay(mainActivity, binding.mapView.tileRequestCompleteHandler).apply {
width = dm.widthPixels / 5
height = dm.heightPixels / 5
}
binding.mapView.overlays.add(overlay)
}
private fun addSomeIcons() {
val items = mutableListOf<OverlayItem>()
items.add(OverlayItem("Title", "Description", GeoPoint(0.0, 0.0)))
val listener = object : ItemizedIconOverlay.OnItemGestureListener<OverlayItem> {
override fun onItemLongPress(index: Int, item: OverlayItem?): Boolean {
return true
}
override fun onItemSingleTapUp(index: Int, item: OverlayItem?): Boolean {
Log.d("myTag", "${item?.title}")
return true
}
}
val overlay = ItemizedIconOverlay(mainActivity, items, listener)
binding.mapView.overlays.add(overlay)
}
private fun addColorFilter() {
val negativeArray = floatArrayOf(
-1.0f, .0f, .0f, .0f, 255.0f,
.0f, -1.0f, .0f, .0f, 255.0f,
.0f, .0f, -1.0f, .0f, 255.0f,
.0f, .0f, .0f, 1.0f, .0f
)
val negativeMatrix = ColorMatrix(negativeArray)
val destinationColor = Color.parseColor("#FF2A2A2A")
val lr = (255.0f - Color.red(destinationColor)) / 255.0f
val lg = (255.0f - Color.green(destinationColor)) / 255.0f
val lb = (255.0f - Color.blue(destinationColor)) / 255.0f
val grayScaleArray = floatArrayOf(
lr, lg, lb, 0f, 0f, //
lr, lg, lb, 0f, 0f, //
lr, lg, lb, 0f, 0f, //
0f, 0f, 0f, 0f, 255f //
)
val grayScaleMatrix = ColorMatrix(grayScaleArray)
grayScaleMatrix.preConcat(negativeMatrix)
val dr = Color.red(destinationColor)
val dg = Color.green(destinationColor)
val db = Color.blue(destinationColor)
val drf = dr / 255f
val dgf = dg / 255f
val dbf = db / 255f
val tintArray = floatArrayOf(
drf, 0f, 0f, 0f, 0f, //
0f, dgf, 0f, 0f, 0f, //
0f, 0f, dbf, 0f, 0f, //
0f, 0f, 0f, 1f, 0f //
)
val tintMatrix = ColorMatrix(tintArray)
tintMatrix.preConcat(grayScaleMatrix)
val lDest = drf * lr + dgf * lg + dbf * lb
val scale = 1f - lDest
val translate = 1 - scale * 0.5f
val scaleArray = floatArrayOf(
scale, 0f, 0f, 0f, dr * translate, //
0f, scale, 0f, 0f, dg * translate, //
0f, 0f, scale, 0f, db * translate, //
0f, 0f, 0f, 1f, 0f
)
val scaleMatrix = ColorMatrix(scaleArray)
scaleMatrix.preConcat(tintMatrix)
val filter = ColorMatrixColorFilter(scaleMatrix)
binding.mapView.overlayManager.tilesOverlay.setColorFilter(filter)
}
private fun setupSatOverlay(passList: List<SatPass>) {
lifecycleScope.launch {
while (true) {
// val markers = showSatIcons(data)
// satLayer.removeAllItems()
// satLayer.addItems(markers)
delay(1000)
}
}
}
private suspend fun drawGroundTrack(data: List<SatPass>) {
withContext(Dispatchers.IO) {
data[1].apply {
val dateNow = Date(System.currentTimeMillis())
val period = (24 * 60 / this.tle.meanmo).toInt()
val positions = this.predictor.getPositions(dateNow, 15, 0, period)
positions.forEach {
val lat = Math.toDegrees(it.latitude)
var lon = Math.toDegrees(it.longitude)
// Log.d("myTag", "$lat, $lon")
if (lon > 180.0) {
// path.addPoint(GeoPoint(lat, 180.0))
lon -= 360.0
}
Log.d("myTag", "$lat, $lon")
}
}
// binding.mapView.map().layers().add(path)
// binding.mapView.map().render()
}
}
private fun drawGroundTrack(list: List<SatPos>) {
val groundTrack = Polyline(binding.mapView)
val trackPoints = mutableListOf<GeoPoint>()
list.forEach {
val lat = Math.toDegrees(it.latitude) * -1
var lon = Math.toDegrees(it.longitude)
if (lon > 180.0) lon -= 360.0
trackPoints.add(GeoPoint(lat, lon))
}
groundTrack.setPoints(trackPoints)
groundTrack.setDensityMultiplier(0.5f)
binding.mapView.overlays.add(groundTrack)
binding.mapView.invalidate()
}
private fun drawPosition(position: GeoPoint) { private fun drawPosition(position: GeoPoint) {
val satPosition = Polygon(binding.mapView) val satPosition = Polygon(binding.mapView)
val trackPoints = mutableListOf<GeoPoint>() val trackPoints = mutableListOf<GeoPoint>()
Log.d("myTag", "${position.latitude}, ${position.longitude}") val lat = Math.toDegrees(position.latitude)
var lon = Math.toDegrees(position.longitude)
val lat = GeneralUtils.rad2Deg(position.latitude)
var lon = GeneralUtils.rad2Deg(position.longitude)
if (lon > 180.0) lon -= 360.0 if (lon > 180.0) lon -= 360.0
trackPoints.add(GeoPoint(lat, lon)) trackPoints.add(GeoPoint(lat, lon))
@@ -166,43 +298,31 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
startMarker.title = "Sat Position" startMarker.title = "Sat Position"
binding.mapView.overlays.add(startMarker) binding.mapView.overlays.add(startMarker)
Log.d("myTag", "$lat, $lon")
binding.mapView.overlays.add(satPosition) binding.mapView.overlays.add(satPosition)
satPosition.points = trackPoints satPosition.points = trackPoints
binding.mapView.invalidate() binding.mapView.invalidate()
} }
private fun drawGroundTrack(list: List<SatPos>) { private suspend fun showSatIcons(data: List<SatPass>) {
val groundTrack = Polyline(binding.mapView) withContext(Dispatchers.Default) {
val trackPoints = mutableListOf<GeoPoint>() val dateNow = Date(System.currentTimeMillis())
var lat = 0.0 data.forEach {
var lon = 0.0 val satPos = it.predictor.getSatPos(dateNow)
val lat = Math.toDegrees(satPos.latitude)
Log.d("myTag", "${list[1].latitude}, ${list[1].longitude}") var lon = Math.toDegrees(satPos.longitude)
if (lon > 180) lon -= 360
list.forEach { Log.d("myTag", "${it.tle.name}, $lat, $lon")
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") override fun onPause() {
binding.mapView.onPause()
groundTrack.setPoints(trackPoints) super.onPause()
groundTrack.setDensityMultiplier(0.5f)
binding.mapView.overlays.add(groundTrack)
binding.mapView.invalidate()
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
binding.mapView.onResume() binding.mapView.onResume()
} }
override fun onPause() {
super.onPause()
binding.mapView.onPause()
}
} }
+2 -2
View File
@@ -18,13 +18,13 @@
*/ */
buildscript { buildscript {
ext.gradle_version = '4.0.0' ext.gradle_version = '4.0.1'
ext.gradle_plugin_version = '1.3.72' ext.gradle_plugin_version = '1.3.72'
ext.material_version = '1.1.0' ext.material_version = '1.1.0'
ext.app_compat_version = '1.1.0' ext.app_compat_version = '1.1.0'
ext.support_lib_version = '1.0.0' ext.support_lib_version = '1.0.0'
ext.constraint_layout_version = '1.1.3' ext.constraint_layout_version = '1.1.3'
ext.ktx_version = '1.3.0' ext.ktx_version = '1.3.1'
ext.preference_version = '1.1.1' ext.preference_version = '1.1.1'
ext.navigation_version = '2.3.0' ext.navigation_version = '2.3.0'
ext.lifecycle_version = '2.2.0' ext.lifecycle_version = '2.2.0'