kopia lustrzana https://github.com/rt-bishop/Look4Sat
Cleaned up the MapFragment.kt, changed satTrack color
rodzic
ca92f8581e
commit
b7f7f0b477
|
@ -1,11 +0,0 @@
|
|||
package com.rtbishop.look4sat.data
|
||||
|
||||
import org.osmdroid.api.IGeoPoint
|
||||
import org.osmdroid.views.overlay.OverlayItem
|
||||
|
||||
data class SatItem(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val position: IGeoPoint,
|
||||
val pass: SatPass
|
||||
) : OverlayItem(name, description, position)
|
|
@ -4,20 +4,17 @@ import android.graphics.Color
|
|||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.Position
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.SharedViewModel
|
||||
import com.rtbishop.look4sat.data.Result
|
||||
import com.rtbishop.look4sat.data.SatItem
|
||||
import com.rtbishop.look4sat.data.SatPass
|
||||
import com.rtbishop.look4sat.databinding.FragmentMapBinding
|
||||
import com.rtbishop.look4sat.utility.PrefsManager
|
||||
|
@ -27,7 +24,7 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase
|
||||
import org.osmdroid.tileprovider.tilesource.ITileSource
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourcePolicy
|
||||
import org.osmdroid.tileprovider.tilesource.XYTileSource
|
||||
import org.osmdroid.util.BoundingBox
|
||||
|
@ -45,43 +42,27 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
@Inject
|
||||
lateinit var prefsManager: PrefsManager
|
||||
|
||||
private lateinit var mainActivity: FragmentActivity
|
||||
private lateinit var binding: FragmentMapBinding
|
||||
private lateinit var trackPaint: Paint
|
||||
private lateinit var footprintPaint: Paint
|
||||
private lateinit var selectedPass: SatPass
|
||||
private val dateNow = Date(System.currentTimeMillis())
|
||||
private val dateNow = Date()
|
||||
private val viewModel: SharedViewModel by activityViewModels()
|
||||
private var iconPos: Drawable? = null
|
||||
private var iconSat: Drawable? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentMapBinding.bind(view)
|
||||
mainActivity = requireActivity()
|
||||
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(mainActivity.applicationContext)
|
||||
Configuration.getInstance().load(mainActivity.applicationContext, prefs)
|
||||
|
||||
trackPaint = Paint().apply {
|
||||
strokeWidth = 2f
|
||||
style = Paint.Style.STROKE
|
||||
color = ContextCompat.getColor(mainActivity, R.color.satTrack)
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
strokeJoin = Paint.Join.ROUND
|
||||
isAntiAlias = true
|
||||
}
|
||||
|
||||
footprintPaint = Paint().apply {
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
color = ContextCompat.getColor(mainActivity, R.color.satFootprint)
|
||||
isAntiAlias = true
|
||||
}
|
||||
|
||||
setupMapView()
|
||||
setupPosOverlay(prefsManager.getStationPosition())
|
||||
setupPosOverlay()
|
||||
setupObservers()
|
||||
}
|
||||
|
||||
private fun setupMapView() {
|
||||
Configuration.getInstance()
|
||||
.load(requireContext().applicationContext, prefsManager.preferences)
|
||||
val filter = getColorFilter(ContextCompat.getColor(requireContext(), R.color.satTrack))
|
||||
binding.mapView.apply {
|
||||
setMultiTouchControls(true)
|
||||
setTileSource(getWikimediaTileSource())
|
||||
|
@ -89,36 +70,52 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
maxZoomLevel = 6.0
|
||||
controller.setZoom(3.0)
|
||||
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
|
||||
isHorizontalMapRepetitionEnabled = false
|
||||
isVerticalMapRepetitionEnabled = false
|
||||
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.setColorFilter(filter)
|
||||
setScrollableAreaLimitDouble(BoundingBox(85.05, 180.0, -85.05, -180.0))
|
||||
|
||||
// apply filter
|
||||
val tilesFilter = getColorFilter(Color.parseColor("#D50000"))
|
||||
overlayManager.tilesOverlay.setColorFilter(tilesFilter)
|
||||
|
||||
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
|
||||
val layers = listOf(FolderOverlay(), FolderOverlay(), FolderOverlay(), FolderOverlay())
|
||||
overlays.addAll(layers)
|
||||
}
|
||||
trackPaint = Paint().apply {
|
||||
strokeWidth = 2f
|
||||
style = Paint.Style.STROKE
|
||||
color = ContextCompat.getColor(requireContext(), R.color.satTrack)
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
strokeJoin = Paint.Join.ROUND
|
||||
isAntiAlias = true
|
||||
}
|
||||
footprintPaint = Paint().apply {
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
color = ContextCompat.getColor(requireContext(), R.color.satFootprint)
|
||||
isAntiAlias = true
|
||||
}
|
||||
iconPos = ContextCompat.getDrawable(requireContext(), R.drawable.ic_map_pos)
|
||||
iconSat = ContextCompat.getDrawable(requireContext(), R.drawable.ic_map_sat)
|
||||
}
|
||||
|
||||
private fun getWikimediaTileSource(): OnlineTileSourceBase {
|
||||
return XYTileSource(
|
||||
"wikimedia",
|
||||
2,
|
||||
6,
|
||||
256,
|
||||
".png",
|
||||
arrayOf("https://maps.wikimedia.org/osm-intl/"),
|
||||
resources.getString(R.string.map_copyright),
|
||||
TileSourcePolicy(
|
||||
1, TileSourcePolicy.FLAG_NO_BULK and TileSourcePolicy.FLAG_NO_PREVENTIVE and
|
||||
TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL and TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED
|
||||
)
|
||||
private fun getWikimediaTileSource(): ITileSource {
|
||||
val copyright = resources.getString(R.string.map_copyright)
|
||||
val sources = arrayOf("https://maps.wikimedia.org/osm-intl/")
|
||||
val policy = TileSourcePolicy(
|
||||
1, TileSourcePolicy.FLAG_NO_BULK and TileSourcePolicy.FLAG_NO_PREVENTIVE and
|
||||
TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL and TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED
|
||||
)
|
||||
return XYTileSource("wikimedia", 2, 6, 256, ".png", sources, copyright, policy)
|
||||
}
|
||||
|
||||
private fun setupPosOverlay() {
|
||||
val gsp = prefsManager.getStationPosition()
|
||||
Marker(binding.mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
icon = iconPos
|
||||
position = GeoPoint(gsp.latitude, gsp.longitude)
|
||||
binding.mapView.overlays[0] = this
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
|
@ -133,63 +130,39 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
})
|
||||
}
|
||||
|
||||
private fun setupPosOverlay(gsp: GroundStationPosition) {
|
||||
Marker(binding.mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
icon = ResourcesCompat.getDrawable(resources, R.drawable.ic_map_pos, mainActivity.theme)
|
||||
position = GeoPoint(gsp.latitude, gsp.longitude)
|
||||
binding.mapView.overlays[0] = this
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSatOverlay(passList: List<SatPass>) {
|
||||
lifecycleScope.launch {
|
||||
while (true) {
|
||||
dateNow.time = System.currentTimeMillis()
|
||||
binding.mapView.overlays[3] = getSatIcons(passList)
|
||||
binding.mapView.overlays[3] = getSatMarkers(passList)
|
||||
binding.mapView.overlays[2] = getSatFootprint(selectedPass)
|
||||
setSatInfo(selectedPass)
|
||||
binding.mapView.invalidate()
|
||||
delay(3000)
|
||||
delay(2000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getSatIcons(passList: List<SatPass>): Overlay =
|
||||
private suspend fun getSatMarkers(passList: List<SatPass>): Overlay =
|
||||
withContext(Dispatchers.Default) {
|
||||
val icon =
|
||||
ResourcesCompat.getDrawable(resources, R.drawable.ic_map_sat, mainActivity.theme)
|
||||
val items = mutableListOf<SatItem>()
|
||||
|
||||
passList.forEach {
|
||||
val satPos = it.predictor.getSatPos(dateNow)
|
||||
var lat = Math.toDegrees(satPos.latitude)
|
||||
if (lat > 85.05) lat = 85.05
|
||||
else if (lat < -85.05) lat = -85.05
|
||||
var lon = Math.toDegrees(satPos.longitude)
|
||||
if (lon > 180.0) lon -= 360.0
|
||||
|
||||
SatItem(it.tle.name, it.tle.name, GeoPoint(lat, lon), it).apply {
|
||||
markerHotspot = OverlayItem.HotspotPlace.CENTER
|
||||
val items = FolderOverlay()
|
||||
passList.forEach { satPass ->
|
||||
val satPos = satPass.predictor.getSatPos(dateNow)
|
||||
val osmPos = getOsmPosition(satPos.latitude, satPos.longitude, true)
|
||||
Marker(binding.mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
|
||||
icon = iconSat
|
||||
position = GeoPoint(osmPos.lat, osmPos.lon)
|
||||
setOnMarkerClickListener { _, _ ->
|
||||
selectedPass = satPass
|
||||
setSatDetails(satPass)
|
||||
true
|
||||
}
|
||||
items.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
val listener = object : ItemizedIconOverlay.OnItemGestureListener<SatItem> {
|
||||
override fun onItemLongPress(index: Int, item: SatItem): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onItemSingleTapUp(index: Int, item: SatItem): Boolean {
|
||||
selectedPass = item.pass
|
||||
setSatDetails(item.pass)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return@withContext ItemizedIconOverlay(items, icon, listener, mainActivity)
|
||||
return@withContext items
|
||||
}
|
||||
|
||||
private fun setSatDetails(satPass: SatPass) {
|
||||
|
@ -201,31 +174,17 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
|
||||
private fun setSatInfo(satPass: SatPass) {
|
||||
val satPos = satPass.predictor.getSatPos(dateNow)
|
||||
|
||||
var satLat = Math.toDegrees(satPos.latitude)
|
||||
if (satLat > 85.05) satLat = 85.05
|
||||
else if (satLat < -85.05) satLat = -85.05
|
||||
|
||||
var satLon = Math.toDegrees(satPos.longitude)
|
||||
if (satLon > 180f) satLon -= 360f
|
||||
|
||||
binding.idName.text =
|
||||
String.format(
|
||||
mainActivity.getString(R.string.pat_osm_idName),
|
||||
satPass.tle.catnum,
|
||||
satPass.tle.name
|
||||
)
|
||||
binding.altitude.text =
|
||||
String.format(mainActivity.getString(R.string.pat_altitude), satPos.altitude)
|
||||
binding.distance.text =
|
||||
String.format(mainActivity.getString(R.string.pat_distance), satPos.range)
|
||||
binding.velocity.text =
|
||||
String.format(
|
||||
mainActivity.getString(R.string.pat_osm_vel),
|
||||
getSatVelocity(satPos.altitude)
|
||||
)
|
||||
binding.latLon.text =
|
||||
String.format(mainActivity.getString(R.string.pat_osm_latLon), satLat, satLon)
|
||||
val osmPos = getOsmPosition(satPos.latitude, satPos.longitude, true)
|
||||
val catNum = satPass.tle.catnum
|
||||
val name = satPass.tle.name
|
||||
val satVelocity = getSatVelocity(satPos.altitude)
|
||||
binding.apply {
|
||||
idName.text = String.format(getString(R.string.pat_osm_idName), catNum, name)
|
||||
altitude.text = String.format(getString(R.string.pat_altitude), satPos.altitude)
|
||||
distance.text = String.format(getString(R.string.pat_distance), satPos.range)
|
||||
velocity.text = String.format(getString(R.string.pat_osm_vel), satVelocity)
|
||||
latLon.text = String.format(getString(R.string.pat_osm_latLon), osmPos.lat, osmPos.lon)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSatVelocity(satAlt: Double): Double {
|
||||
|
@ -240,17 +199,11 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
val positions = pass.predictor.getPositions(dateNow, 20, 0, period * 3)
|
||||
val trackOverlay = FolderOverlay()
|
||||
val trackPoints = mutableListOf<GeoPoint>()
|
||||
|
||||
var oldLon = 0.0
|
||||
|
||||
positions.forEach {
|
||||
var newLat = Math.toDegrees(it.latitude)
|
||||
if (newLat > 85.05) newLat = 85.05
|
||||
else if (newLat < -85.05) newLat = -85.05
|
||||
|
||||
var newLon = Math.toDegrees(it.longitude)
|
||||
if (newLon > 180.0) newLon -= 360.0
|
||||
|
||||
if (oldLon < -170.0 && newLon > 170.0 || oldLon > 170.0 && newLon < -170.0) {
|
||||
val osmPos = getOsmPosition(it.latitude, it.longitude, true)
|
||||
if (oldLon < -170.0 && osmPos.lon > 170.0 || oldLon > 170.0 && osmPos.lon < -170.0) {
|
||||
val currentPoints = mutableListOf<GeoPoint>()
|
||||
currentPoints.addAll(trackPoints)
|
||||
Polyline().apply {
|
||||
|
@ -260,8 +213,8 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
}
|
||||
trackPoints.clear()
|
||||
}
|
||||
oldLon = newLon
|
||||
trackPoints.add(GeoPoint(newLat, newLon))
|
||||
oldLon = osmPos.lon
|
||||
trackPoints.add(GeoPoint(osmPos.lat, osmPos.lon))
|
||||
}
|
||||
|
||||
Polyline().apply {
|
||||
|
@ -269,7 +222,6 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
setPoints(trackPoints)
|
||||
trackOverlay.add(this)
|
||||
}
|
||||
|
||||
return trackOverlay
|
||||
}
|
||||
|
||||
|
@ -279,18 +231,12 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
var zeroPoint = GeoPoint(0.0, 0.0)
|
||||
|
||||
rangeCircle.withIndex().forEach {
|
||||
var lat = it.value.lat
|
||||
if (lat > 85.05) lat = 85.05
|
||||
else if (lat < -85.05) lat = -85.05
|
||||
|
||||
var lon = it.value.lon
|
||||
if (lon > 180.0) lon -= 360.0
|
||||
|
||||
if (it.index == 0) zeroPoint = GeoPoint(lat, lon)
|
||||
rangePoints.add(GeoPoint(lat, lon))
|
||||
val osmPos = getOsmPosition(it.value.lat, it.value.lon, false)
|
||||
if (it.index == 0) zeroPoint = GeoPoint(osmPos.lat, osmPos.lon)
|
||||
rangePoints.add(GeoPoint(osmPos.lat, osmPos.lon))
|
||||
}
|
||||
rangePoints.add(zeroPoint)
|
||||
|
||||
rangePoints.add(zeroPoint)
|
||||
return Polygon().apply {
|
||||
fillPaint.set(footprintPaint)
|
||||
outlinePaint.set(footprintPaint)
|
||||
|
@ -302,7 +248,6 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
val newR = Color.red(targetColor) / 255f
|
||||
val newG = Color.green(targetColor) / 255f
|
||||
val newB = Color.blue(targetColor) / 255f
|
||||
|
||||
val negativeMatrix = ColorMatrix(
|
||||
floatArrayOf(
|
||||
-1f, 0f, 0f, 0f, 255f,
|
||||
|
@ -311,7 +256,6 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
0f, 0f, 0f, 1f, 0f
|
||||
)
|
||||
)
|
||||
|
||||
val tintedMatrix = ColorMatrix(
|
||||
floatArrayOf(
|
||||
newR, newG, newB, 0f, 0f,
|
||||
|
@ -320,18 +264,21 @@ class MapFragment : Fragment(R.layout.fragment_map) {
|
|||
0f, 0f, 0f, 0f, 255f
|
||||
)
|
||||
)
|
||||
|
||||
tintedMatrix.preConcat(negativeMatrix)
|
||||
return ColorMatrixColorFilter(tintedMatrix)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
binding.mapView.onPause()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.mapView.onResume()
|
||||
private fun getOsmPosition(lat: Double, lon: Double, inRadians: Boolean): Position {
|
||||
return if (inRadians) {
|
||||
var osmLat = Math.toDegrees(lat)
|
||||
var osmLon = Math.toDegrees(lon)
|
||||
if (osmLat > 85.05) osmLat = 85.05 else if (osmLat < -85.05) osmLat = -85.05
|
||||
if (osmLon > 180f) osmLon -= 360f
|
||||
Position(osmLat, osmLon)
|
||||
} else {
|
||||
val osmLat = if (lat > 85.05) 85.05 else if (lat < -85.05) -85.05 else lat
|
||||
val osmLon = if (lon > 180.0) lon - 360.0 else lon
|
||||
Position(osmLat, osmLon)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ import com.github.amsacode.predict4java.GroundStationPosition
|
|||
import com.rtbishop.look4sat.data.PassPrefs
|
||||
import javax.inject.Inject
|
||||
|
||||
class PrefsManager @Inject constructor(private val preferences: SharedPreferences) {
|
||||
class PrefsManager @Inject constructor(val preferences: SharedPreferences) {
|
||||
companion object {
|
||||
const val keyLatitude = "latitude"
|
||||
const val keyLongitude = "longitude"
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<color name="greyDivider">#808080</color>
|
||||
<color name="greySurface">#1e1e1e</color>
|
||||
<!-- map colors -->
|
||||
<color name="satTrack">#B00020</color>
|
||||
<color name="satTrack">#D50000</color>
|
||||
<color name="satFootprint">#26FFE082</color>
|
||||
<color name="mapInfoLayout">#66000000</color>
|
||||
</resources>
|
||||
|
|
Ładowanie…
Reference in New Issue