mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Further map setup
This commit is contained in:
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
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.SatPos
|
||||
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.ui.MainActivity
|
||||
import com.rtbishop.look4sat.ui.SharedViewModel
|
||||
import com.rtbishop.look4sat.utility.GeneralUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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 kotlinx.coroutines.withContext
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
||||
import org.osmdroid.util.BoundingBox
|
||||
import org.osmdroid.util.GeoPoint
|
||||
import org.osmdroid.views.overlay.Marker
|
||||
import org.osmdroid.views.overlay.Polygon
|
||||
import org.osmdroid.views.overlay.Polyline
|
||||
import org.osmdroid.views.CustomZoomButtonsController
|
||||
import org.osmdroid.views.overlay.*
|
||||
import org.osmdroid.views.overlay.compass.CompassOverlay
|
||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import org.osmdroid.views.overlay.gridlines.LatLonGridlineOverlay2
|
||||
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
|
||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -45,8 +46,6 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
|
||||
private lateinit var mainActivity: MainActivity
|
||||
private lateinit var viewModel: SharedViewModel
|
||||
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?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -55,108 +54,241 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
|
||||
(mainActivity.application as Look4SatApp).appComponent.inject(this)
|
||||
viewModel = ViewModelProvider(mainActivity, modelFactory).get(SharedViewModel::class.java)
|
||||
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(mainActivity.applicationContext)
|
||||
Configuration.getInstance().load(mainActivity.applicationContext, prefs)
|
||||
|
||||
setupMapView()
|
||||
setupObservers()
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
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
|
||||
|
||||
private fun setupMapView() {
|
||||
binding.mapView.apply {
|
||||
setTileSource(TileSourceFactory.MAPNIK)
|
||||
|
||||
// General settings
|
||||
// isHorizontalMapRepetitionEnabled = false
|
||||
// isVerticalMapRepetitionEnabled = false
|
||||
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)
|
||||
|
||||
// Zoom settings
|
||||
minZoomLevel = 2.5
|
||||
maxZoomLevel = 6.5
|
||||
controller.setZoom(minZoomLevel)
|
||||
// controller.setCenter(GeoPoint(0.0, 0.0))
|
||||
setMultiTouchControls(true)
|
||||
setScrollableAreaLimitLatitude(85.0, -85.0, 0)
|
||||
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
|
||||
|
||||
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()
|
||||
// Scroll limits
|
||||
// setScrollableAreaLimitLatitude(85.0, -85.0, 0)
|
||||
// setScrollableAreaLimitLongitude(-180.0, 180.0, 0)
|
||||
setScrollableAreaLimitDouble(BoundingBox(85.0, 180.0, -85.0, -180.0))
|
||||
|
||||
addLocationOverlay()
|
||||
addMapScaleBarOverlay()
|
||||
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) {
|
||||
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)
|
||||
val lat = Math.toDegrees(position.latitude)
|
||||
var lon = Math.toDegrees(position.longitude)
|
||||
if (lon > 180.0) lon -= 360.0
|
||||
trackPoints.add(GeoPoint(lat, lon))
|
||||
|
||||
@@ -166,43 +298,31 @@ class MapOsmFragment : Fragment(R.layout.fragment_map_osm) {
|
||||
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))
|
||||
private suspend fun showSatIcons(data: List<SatPass>) {
|
||||
withContext(Dispatchers.Default) {
|
||||
val dateNow = Date(System.currentTimeMillis())
|
||||
data.forEach {
|
||||
val satPos = it.predictor.getSatPos(dateNow)
|
||||
val lat = Math.toDegrees(satPos.latitude)
|
||||
var lon = Math.toDegrees(satPos.longitude)
|
||||
if (lon > 180) lon -= 360
|
||||
Log.d("myTag", "${it.tle.name}, $lat, $lon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.d("myTag", "$lat, $lon")
|
||||
|
||||
groundTrack.setPoints(trackPoints)
|
||||
groundTrack.setDensityMultiplier(0.5f)
|
||||
binding.mapView.overlays.add(groundTrack)
|
||||
binding.mapView.invalidate()
|
||||
override fun onPause() {
|
||||
binding.mapView.onPause()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.mapView.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
binding.mapView.onPause()
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -18,13 +18,13 @@
|
||||
*/
|
||||
|
||||
buildscript {
|
||||
ext.gradle_version = '4.0.0'
|
||||
ext.gradle_version = '4.0.1'
|
||||
ext.gradle_plugin_version = '1.3.72'
|
||||
ext.material_version = '1.1.0'
|
||||
ext.app_compat_version = '1.1.0'
|
||||
ext.support_lib_version = '1.0.0'
|
||||
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.navigation_version = '2.3.0'
|
||||
ext.lifecycle_version = '2.2.0'
|
||||
|
||||
Reference in new issue
Block a user