mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-04 19:47:22 +00:00
Changes to RadarFragment's satellite data views
This commit is contained in:
1 parent
6189fb497e
commit
0c71c4db29
10 files changed
+99
-46
No files matched your search
@@ -164,7 +164,7 @@ class MapViewModel @Inject constructor(
|
|||||||
val osmPos = GeoPos(osmLat, osmLon)
|
val osmPos = GeoPos(osmLat, osmLon)
|
||||||
val qthLoc = QthConverter.positionToQth(osmPos.latitude, osmPos.longitude) ?: "-- --"
|
val qthLoc = QthConverter.positionToQth(osmPos.latitude, osmPos.longitude) ?: "-- --"
|
||||||
val satData = MapData(
|
val satData = MapData(
|
||||||
satellite, satellite.data.catnum, satellite.data.name, satPos.range,
|
satellite, satellite.data.catnum, satellite.data.name, satPos.distance,
|
||||||
satPos.altitude, satPos.getOrbitalVelocity(), qthLoc, osmPos
|
satPos.altitude, satPos.getOrbitalVelocity(), qthLoc, osmPos
|
||||||
)
|
)
|
||||||
_satData.postValue(satData)
|
_satData.postValue(satData)
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ class PassesViewModel @Inject constructor(
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_passes.postValue(DataState.Loading)
|
_passes.postValue(DataState.Loading)
|
||||||
passesProcessing?.cancelAndJoin()
|
passesProcessing?.cancelAndJoin()
|
||||||
delay(3000)
|
|
||||||
selection?.let { items -> repository.setEntriesSelection(items) }
|
selection?.let { items -> repository.setEntriesSelection(items) }
|
||||||
settings.setHoursAhead(hoursAhead)
|
settings.setHoursAhead(hoursAhead)
|
||||||
settings.setMinElevation(minElevation)
|
settings.setMinElevation(minElevation)
|
||||||
|
|||||||
@@ -102,14 +102,14 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
|||||||
|
|
||||||
private fun setPassText(satPass: SatPass, satPos: SatPos) {
|
private fun setPassText(satPass: SatPass, satPos: SatPos) {
|
||||||
val timeNow = System.currentTimeMillis()
|
val timeNow = System.currentTimeMillis()
|
||||||
val polarAz = getString(R.string.pat_azimuth)
|
val radarAzim = getString(R.string.radar_az_value)
|
||||||
val polarEl = getString(R.string.pat_elevation)
|
val radarElev = getString(R.string.radar_el_value)
|
||||||
val polarRng = getString(R.string.pat_distance)
|
val radarAlt = getString(R.string.radar_alt_value)
|
||||||
val polarAlt = getString(R.string.pat_altitude)
|
val radarDist = getString(R.string.radar_dist_value)
|
||||||
binding.radarAz.text = String.format(polarAz, Math.toDegrees(satPos.azimuth))
|
binding.radarAzValue.text = String.format(radarAzim, Math.toDegrees(satPos.azimuth))
|
||||||
binding.radarEl.text = String.format(polarEl, Math.toDegrees(satPos.elevation))
|
binding.radarElValue.text = String.format(radarElev, Math.toDegrees(satPos.elevation))
|
||||||
binding.radarDst.text = String.format(polarRng, satPos.range)
|
binding.radarAltValue.text = String.format(radarAlt, satPos.altitude)
|
||||||
binding.radarAlt.text = String.format(polarAlt, satPos.altitude)
|
binding.radarDstValue.text = String.format(radarDist, satPos.distance)
|
||||||
// binding.radarName.text = satPass.name
|
// binding.radarName.text = satPass.name
|
||||||
|
|
||||||
if (!satPass.isDeepSpace) {
|
if (!satPass.isDeepSpace) {
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ class RadarView(context: Context) : View(context) {
|
|||||||
|
|
||||||
private val defaultColor = ContextCompat.getColor(context, R.color.accent)
|
private val defaultColor = ContextCompat.getColor(context, R.color.accent)
|
||||||
private val scale = resources.displayMetrics.density
|
private val scale = resources.displayMetrics.density
|
||||||
private val radarWidth = resources.displayMetrics.widthPixels
|
|
||||||
private val radarRadius = radarWidth * 0.48f
|
|
||||||
private val piDiv2 = Math.PI / 2.0
|
private val piDiv2 = Math.PI / 2.0
|
||||||
private val strokeSize = scale * 2f
|
private val strokeSize = scale * 2f
|
||||||
private var position: SatPos? = null
|
private var position: SatPos? = null
|
||||||
@@ -125,12 +123,12 @@ class RadarView(context: Context) : View(context) {
|
|||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
val radarWidth = width - paddingLeft - paddingRight
|
val radarWidth = width - paddingLeft - paddingRight
|
||||||
val radarHeight = height - paddingTop - paddingBottom
|
val radarHeight = height - paddingTop - paddingBottom
|
||||||
val radarRadius = min(width, height) * 0.49f
|
val radarRadius = min(width, height) * 0.48f
|
||||||
val cx = paddingLeft + radarWidth / 2f
|
val cx = paddingLeft + radarWidth / 2f
|
||||||
val cy = paddingTop + radarHeight / 2f
|
val cy = paddingTop + radarHeight / 2f
|
||||||
|
|
||||||
if (positions.isNotEmpty() && !isTrackCreated) {
|
if (positions.isNotEmpty() && !isTrackCreated) {
|
||||||
createPassTrajectory()
|
createPassTrajectory(radarRadius)
|
||||||
createPassTrajectoryArrow()
|
createPassTrajectoryArrow()
|
||||||
isTrackCreated = true
|
isTrackCreated = true
|
||||||
}
|
}
|
||||||
@@ -146,10 +144,10 @@ class RadarView(context: Context) : View(context) {
|
|||||||
canvas.drawPath(trackPath, arrowPaint)
|
canvas.drawPath(trackPath, arrowPaint)
|
||||||
}
|
}
|
||||||
if (shouldShowBeacons) {
|
if (shouldShowBeacons) {
|
||||||
drawSatellite(canvas)
|
drawSatellite(canvas, radarRadius)
|
||||||
}
|
}
|
||||||
if (shouldShowAim) {
|
if (shouldShowAim) {
|
||||||
drawCrosshair(canvas, azimuth, pitch)
|
drawCrosshair(canvas, azimuth, pitch, radarRadius)
|
||||||
}
|
}
|
||||||
if (shouldShowSweep) {
|
if (shouldShowSweep) {
|
||||||
canvas.translate(-cx, -cy)
|
canvas.translate(-cx, -cy)
|
||||||
@@ -177,7 +175,7 @@ class RadarView(context: Context) : View(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawSatellite(canvas: Canvas) {
|
private fun drawSatellite(canvas: Canvas, radarRadius: Float) {
|
||||||
position?.let { satPos ->
|
position?.let { satPos ->
|
||||||
if (satPos.elevation > 0) {
|
if (satPos.elevation > 0) {
|
||||||
val satX = sph2CartX(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
val satX = sph2CartX(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
||||||
@@ -187,7 +185,7 @@ class RadarView(context: Context) : View(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawCrosshair(canvas: Canvas, azimuth: Float, pitch: Float) {
|
private fun drawCrosshair(canvas: Canvas, azimuth: Float, pitch: Float, radarRadius: Float) {
|
||||||
val azimuthRad = Math.toRadians(azimuth.toDouble())
|
val azimuthRad = Math.toRadians(azimuth.toDouble())
|
||||||
val tmpElevation = Math.toRadians(pitch.toDouble())
|
val tmpElevation = Math.toRadians(pitch.toDouble())
|
||||||
val elevationRad = if (tmpElevation > 0.0) 0.0 else tmpElevation
|
val elevationRad = if (tmpElevation > 0.0) 0.0 else tmpElevation
|
||||||
@@ -208,7 +206,7 @@ class RadarView(context: Context) : View(context) {
|
|||||||
return (radius * sin(piDiv2 - azimuth)).toFloat()
|
return (radius * sin(piDiv2 - azimuth)).toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPassTrajectory() {
|
private fun createPassTrajectory(radarRadius: Float) {
|
||||||
positions.forEachIndexed { index, satPos ->
|
positions.forEachIndexed { index, satPos ->
|
||||||
val passX = sph2CartX(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
val passX = sph2CartX(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
||||||
val passY = sph2CartY(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
val passY = sph2CartY(satPos.azimuth, satPos.elevation, radarRadius.toDouble())
|
||||||
|
|||||||
@@ -45,49 +45,81 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/radar_toolbar" />
|
app:layout_constraintTop_toBottomOf="@+id/radar_toolbar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/radar_az_value"
|
||||||
|
style="@style/RadarValue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/radar_az_value"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/radar_card"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/radar_card" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/radar_az"
|
android:id="@+id/radar_az"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
android:text="@string/radar_az_text"
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:text="@string/pat_azimuth"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
app:layout_constraintStart_toStartOf="@+id/radar_card"
|
app:layout_constraintStart_toStartOf="@+id/radar_az_value"
|
||||||
app:layout_constraintTop_toTopOf="@+id/radar_card" />
|
app:layout_constraintTop_toBottomOf="@+id/radar_az_value" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/radar_el_value"
|
||||||
|
style="@style/RadarValue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/radar_el_value"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@+id/radar_az_value"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/radar_card" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/radar_el"
|
android:id="@+id/radar_el"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:text="@string/radar_el_text"
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:text="@string/pat_elevation"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/radar_card"
|
app:layout_constraintBaseline_toBaselineOf="@+id/radar_az"
|
||||||
app:layout_constraintTop_toTopOf="@+id/radar_card" />
|
app:layout_constraintEnd_toEndOf="@+id/radar_el_value" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/radar_alt_value"
|
||||||
|
style="@style/RadarValue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:text="@string/radar_alt_value"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/radar_card"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/radar_az_value" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/radar_alt"
|
android:id="@+id/radar_alt"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
android:text="@string/radar_alt_text"
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:text="@string/pat_altitude"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/radar_card"
|
app:layout_constraintBottom_toTopOf="@+id/radar_alt_value"
|
||||||
app:layout_constraintStart_toStartOf="@+id/radar_card" />
|
app:layout_constraintStart_toStartOf="@+id/radar_alt_value" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/radar_dst_value"
|
||||||
|
style="@style/RadarValue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/radar_dist_value"
|
||||||
|
app:layout_constraintBaseline_toBaselineOf="@+id/radar_alt_value"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/radar_el_value" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/radar_dst"
|
android:id="@+id/radar_dst"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="4dp"
|
android:text="@string/radar_dist_text"
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:text="@string/pat_distance"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/radar_card"
|
app:layout_constraintBaseline_toBaselineOf="@+id/radar_alt"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/radar_card" />
|
app:layout_constraintEnd_toEndOf="@+id/radar_dst_value" />
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
<androidx.cardview.widget.CardView
|
||||||
android:id="@+id/radar_list_card"
|
android:id="@+id/radar_list_card"
|
||||||
|
|||||||
@@ -64,6 +64,15 @@
|
|||||||
<string name="map_qth">QTH Локатор: %s</string>
|
<string name="map_qth">QTH Локатор: %s</string>
|
||||||
<string name="map_coverage">Покрытие: %.0fкм</string>
|
<string name="map_coverage">Покрытие: %.0fкм</string>
|
||||||
|
|
||||||
|
<string name="radar_az_text">Азим.</string>
|
||||||
|
<string name="radar_az_value">%.1f°</string>
|
||||||
|
<string name="radar_el_text">Элев.</string>
|
||||||
|
<string name="radar_el_value">%.1f°</string>
|
||||||
|
<string name="radar_alt_text">Выс.</string>
|
||||||
|
<string name="radar_alt_value">%.0f km</string>
|
||||||
|
<string name="radar_dist_text">Дальн.</string>
|
||||||
|
<string name="radar_dist_value">%.0f km</string>
|
||||||
|
|
||||||
<string name="pat_azimuth">Азимут: %.1f°</string>
|
<string name="pat_azimuth">Азимут: %.1f°</string>
|
||||||
<string name="pat_elevation">Элевация: %.1f°</string>
|
<string name="pat_elevation">Элевация: %.1f°</string>
|
||||||
<string name="pat_distance">Дистанция: %.0fкм</string>
|
<string name="pat_distance">Дистанция: %.0fкм</string>
|
||||||
|
|||||||
@@ -76,6 +76,15 @@
|
|||||||
<string name="map_coverage">Coverage: %.0f km</string>
|
<string name="map_coverage">Coverage: %.0f km</string>
|
||||||
<string name="map_copyright" translatable="false">Wikimedia maps | Map data © OpenStreetMap contributors</string>
|
<string name="map_copyright" translatable="false">Wikimedia maps | Map data © OpenStreetMap contributors</string>
|
||||||
|
|
||||||
|
<string name="radar_az_text">Azimuth</string>
|
||||||
|
<string name="radar_az_value">%.1f°</string>
|
||||||
|
<string name="radar_el_text">Elevation</string>
|
||||||
|
<string name="radar_el_value">%.1f°</string>
|
||||||
|
<string name="radar_alt_text">Altitude</string>
|
||||||
|
<string name="radar_alt_value">%.0f km</string>
|
||||||
|
<string name="radar_dist_text">Distance</string>
|
||||||
|
<string name="radar_dist_value">%.0f km</string>
|
||||||
|
|
||||||
<string name="pat_azimuth">Azimuth: %.1f°</string>
|
<string name="pat_azimuth">Azimuth: %.1f°</string>
|
||||||
<string name="pat_elevation">Elevation: %.1f°</string>
|
<string name="pat_elevation">Elevation: %.1f°</string>
|
||||||
<string name="pat_distance">Range: %.0f km</string>
|
<string name="pat_distance">Range: %.0f km</string>
|
||||||
|
|||||||
@@ -132,6 +132,12 @@
|
|||||||
<item name="fabCradleRoundedCornerRadius">@dimen/view_default_margin</item>
|
<item name="fabCradleRoundedCornerRadius">@dimen/view_default_margin</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="RadarValue">
|
||||||
|
<item name="android:textSize">@dimen/text_size_large</item>
|
||||||
|
<item name="android:textColor">@color/textMain</item>
|
||||||
|
<item name="android:includeFontPadding">false</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="WorldMapText">
|
<style name="WorldMapText">
|
||||||
<item name="android:textSize">@dimen/text_size_medium</item>
|
<item name="android:textSize">@dimen/text_size_medium</item>
|
||||||
<item name="android:textColor">@color/textMain</item>
|
<item name="android:textColor">@color/textMain</item>
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ data class SatPos(
|
|||||||
var latitude: Double = 0.0,
|
var latitude: Double = 0.0,
|
||||||
var longitude: Double = 0.0,
|
var longitude: Double = 0.0,
|
||||||
var altitude: Double = 0.0,
|
var altitude: Double = 0.0,
|
||||||
var range: Double = 0.0,
|
var distance: Double = 0.0,
|
||||||
var rangeRate: Double = 0.0,
|
var distanceRate: Double = 0.0,
|
||||||
var theta: Double = 0.0,
|
var theta: Double = 0.0,
|
||||||
var time: Long = 0L
|
var time: Long = 0L
|
||||||
) {
|
) {
|
||||||
@@ -34,11 +34,11 @@ data class SatPos(
|
|||||||
private val speedOfLight = 2.99792458E8
|
private val speedOfLight = 2.99792458E8
|
||||||
|
|
||||||
fun getDownlinkFreq(freq: Long): Long {
|
fun getDownlinkFreq(freq: Long): Long {
|
||||||
return (freq.toDouble() * (speedOfLight - this.rangeRate * 1000.0) / speedOfLight).toLong()
|
return (freq.toDouble() * (speedOfLight - distanceRate * 1000.0) / speedOfLight).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUplinkFreq(freq: Long): Long {
|
fun getUplinkFreq(freq: Long): Long {
|
||||||
return (freq.toDouble() * (speedOfLight + this.rangeRate * 1000.0) / speedOfLight).toLong()
|
return (freq.toDouble() * (speedOfLight + distanceRate * 1000.0) / speedOfLight).toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOrbitalVelocity(): Double {
|
fun getOrbitalVelocity(): Double {
|
||||||
@@ -50,7 +50,7 @@ data class SatPos(
|
|||||||
|
|
||||||
fun getRangeCircle(): List<GeoPos> {
|
fun getRangeCircle(): List<GeoPos> {
|
||||||
val positions = mutableListOf<GeoPos>()
|
val positions = mutableListOf<GeoPos>()
|
||||||
val beta = acos(earthRadiusKm / (earthRadiusKm + this.altitude))
|
val beta = acos(earthRadiusKm / (earthRadiusKm + altitude))
|
||||||
// val radiusKm = earthRadiusKm * acos(earthRadiusKm / (earthRadiusKm + altitude))
|
// val radiusKm = earthRadiusKm * acos(earthRadiusKm / (earthRadiusKm + altitude))
|
||||||
var tempAzimuth = 0
|
var tempAzimuth = 0
|
||||||
while (tempAzimuth < 360) {
|
while (tempAzimuth < 360) {
|
||||||
|
|||||||
@@ -146,8 +146,8 @@ abstract class Satellite(val data: OrbitalData) {
|
|||||||
if (azim < 0.0) azim += twoPi
|
if (azim < 0.0) azim += twoPi
|
||||||
satPos.azimuth = azim
|
satPos.azimuth = azim
|
||||||
satPos.elevation = asin(topZ / range.w)
|
satPos.elevation = asin(topZ / range.w)
|
||||||
satPos.range = range.w
|
satPos.distance = range.w
|
||||||
satPos.rangeRate = dot(range, rgvel) / range.w
|
satPos.distanceRate = dot(range, rgvel) / range.w
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the ECI position and velocity of the observer
|
// Returns the ECI position and velocity of the observer
|
||||||
|
|||||||
Reference in new issue
Block a user