mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75d162301b | ||
|
|
07c09ec3e9 |
No files matched your search
+17
-13
@@ -2,11 +2,12 @@ package com.rtbishop.look4sat.core.domain.utility
|
||||
|
||||
/**
|
||||
* Compares two version strings of the form "<major>.<minor>.<patch>[-<build>]" used by the
|
||||
* BA7OPF fork releases (e.g. "4.4.6-ba7opf.6" or "v4.4.6-ba7opf.7").
|
||||
* BA7OPF fork releases (e.g. "4.4.6-ba7opf.6" or "v4.4.6-ba7opf.9.1").
|
||||
*
|
||||
* The comparison is done on the numeric version segments first; when the base versions are
|
||||
* equal, the trailing build number (if any) decides. This lets a "4.4.6-ba7opf.7" release be
|
||||
* detected as newer than "4.4.6-ba7opf.6" while "4.5.0" trumps any "4.4.x" build.
|
||||
* equal, the trailing build numbers of the suffix decide. All numeric segments of the suffix
|
||||
* are compared as a sequence, so multi-level suffixes work correctly:
|
||||
* "4.4.6-ba7opf.9.1" > "4.4.6-ba7opf.9" > "4.4.6-ba7opf.8".
|
||||
*/
|
||||
object VersionComparator {
|
||||
|
||||
@@ -20,25 +21,28 @@ object VersionComparator {
|
||||
val k = curr.first.getOrElse(i) { 0 }
|
||||
if (c != k) return c > k
|
||||
}
|
||||
return cand.second > curr.second
|
||||
val maxBuild = maxOf(cand.second.size, curr.second.size)
|
||||
for (i in 0 until maxBuild) {
|
||||
val c = cand.second.getOrElse(i) { 0 }
|
||||
val k = curr.second.getOrElse(i) { 0 }
|
||||
if (c != k) return c > k
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a version string into (numeric base segments, trailing build number).
|
||||
* "v4.4.6-ba7opf.7" -> ([4,4,6], 7); "4.4.6" -> ([4,4,6], 0); "4.4.6-ba7opf" -> ([4,4,6], 0).
|
||||
* Parses a version string into (numeric base segments, numeric suffix segments).
|
||||
* "v4.4.6-ba7opf.9.1" -> ([4,4,6], [9,1]); "4.4.6-ba7opf.8" -> ([4,4,6], [8]);
|
||||
* "4.4.6" -> ([4,4,6], []); "4.4.6-ba7opf" -> ([4,4,6], []).
|
||||
*/
|
||||
fun parse(version: String): Pair<List<Int>, Int> {
|
||||
fun parse(version: String): Pair<List<Int>, List<Int>> {
|
||||
val cleaned = version.trim().removePrefix("v")
|
||||
val dashIndex = cleaned.indexOf('-')
|
||||
val basePart = if (dashIndex >= 0) cleaned.substring(0, dashIndex) else cleaned
|
||||
val suffixPart = if (dashIndex >= 0) cleaned.substring(dashIndex + 1) else ""
|
||||
val base = basePart.split('.').mapNotNull { it.toIntOrNull() }
|
||||
// The build number is the trailing numeric segment of the suffix (e.g. "ba7opf.7" -> 7).
|
||||
val build = suffixPart
|
||||
.split('.')
|
||||
.lastOrNull()
|
||||
?.toIntOrNull()
|
||||
?: 0
|
||||
// All numeric segments of the suffix, in order (e.g. "ba7opf.9.1" -> [9, 1]).
|
||||
val build = suffixPart.split('.').mapNotNull { it.toIntOrNull() }
|
||||
return base to build
|
||||
}
|
||||
}
|
||||
+14
-4
@@ -40,9 +40,19 @@ class VersionComparatorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse extracts base and build number`() {
|
||||
assertEquals(listOf(4, 4, 6) to 7, VersionComparator.parse("v4.4.6-ba7opf.7"))
|
||||
assertEquals(listOf(4, 4, 6) to 0, VersionComparator.parse("4.4.6"))
|
||||
assertEquals(listOf(4, 4, 6) to 0, VersionComparator.parse("4.4.6-ba7opf"))
|
||||
fun `multi level suffixes compare correctly`() {
|
||||
// The .9.1 hotfix case that exposed the old single-build-number logic.
|
||||
assertTrue(VersionComparator.isNewer("4.4.6-ba7opf.9.1", "4.4.6-ba7opf.9"))
|
||||
assertTrue(VersionComparator.isNewer("v4.4.6-ba7opf.9.1", "4.4.6-ba7opf.8"))
|
||||
assertFalse(VersionComparator.isNewer("4.4.6-ba7opf.9", "4.4.6-ba7opf.9.1"))
|
||||
assertTrue(VersionComparator.isNewer("4.4.6-ba7opf.10", "4.4.6-ba7opf.9.1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse extracts base and suffix segments`() {
|
||||
assertEquals(listOf(4, 4, 6) to listOf(7), VersionComparator.parse("v4.4.6-ba7opf.7"))
|
||||
assertEquals(listOf(4, 4, 6) to listOf(9, 1), VersionComparator.parse("v4.4.6-ba7opf.9.1"))
|
||||
assertEquals(listOf(4, 4, 6) to emptyList<Int>(), VersionComparator.parse("4.4.6"))
|
||||
assertEquals(listOf(4, 4, 6) to emptyList<Int>(), VersionComparator.parse("4.4.6-ba7opf"))
|
||||
}
|
||||
}
|
||||
+15
-6
@@ -84,6 +84,7 @@ class MaidenheadGridOverlay : Overlay() {
|
||||
// crosses the antimeridian; index arithmetic still works (PMxx at 360° == same grid)
|
||||
val firstCol = floor(leftLon / cellLon).toInt()
|
||||
val lastCol = ceil(rightLon / cellLon).toInt()
|
||||
val centerLon = (leftLon + rightLon) / 2.0
|
||||
|
||||
// Worked-grid highlight fills (only meaningful at sub-square zoom)
|
||||
if (workedGrids.isNotEmpty() && zoom >= GRID_ZOOM_SUB) {
|
||||
@@ -97,8 +98,8 @@ class MaidenheadGridOverlay : Overlay() {
|
||||
if (yTop == null || yBottom == null) continue
|
||||
for (col in firstCol..lastCol) {
|
||||
val lon = col * cellLon
|
||||
val xLeft = projectionToX(projection, lon) ?: continue
|
||||
val xRight = projectionToX(projection, lon + cellLon) ?: continue
|
||||
val xLeft = projectionToX(projection, lon, centerLon) ?: continue
|
||||
val xRight = projectionToX(projection, lon + cellLon, centerLon) ?: continue
|
||||
if (xRight < 0f || xLeft > canvas.width) continue
|
||||
if (cellLabel(lat, lon, zoom) in workedGrids) {
|
||||
canvas.drawRect(xLeft, yTop, xRight, yBottom, workedPaint)
|
||||
@@ -110,7 +111,7 @@ class MaidenheadGridOverlay : Overlay() {
|
||||
// Vertical lines (meridians)
|
||||
for (col in firstCol..lastCol) {
|
||||
val lon = col * cellLon
|
||||
val x = projectionToX(projection, lon)
|
||||
val x = projectionToX(projection, lon, centerLon)
|
||||
if (x == null) continue
|
||||
canvas.drawLine(x, 0f, x, canvas.height.toFloat(), linePaint)
|
||||
}
|
||||
@@ -149,7 +150,7 @@ class MaidenheadGridOverlay : Overlay() {
|
||||
if (y < -labelPaint.textSize || y > canvas.height) continue
|
||||
for (col in firstCol..lastCol) {
|
||||
val lon = col * cellLon
|
||||
val x = projectionToX(projection, lon) ?: continue
|
||||
val x = projectionToX(projection, lon, centerLon) ?: continue
|
||||
if (x < -200f || x > canvas.width) continue
|
||||
val label = cellLabel(lat, lon, zoom)
|
||||
canvas.drawText(label, x + labelOffset, y + labelPaint.textSize + labelOffset, labelPaint)
|
||||
@@ -158,8 +159,16 @@ class MaidenheadGridOverlay : Overlay() {
|
||||
}
|
||||
|
||||
/** X pixel for a longitude (meridians are vertical in Web Mercator). */
|
||||
private fun projectionToX(projection: Projection, lon: Double): Float? {
|
||||
val geo = org.osmdroid.util.GeoPoint(0.0, lon)
|
||||
private fun projectionToX(projection: Projection, lon: Double, centerLon: Double): Float? {
|
||||
// osmdroid clips Mercator X to [0, mapSize], which destroys the projection of
|
||||
// longitudes outside the [0, 360) window of the current view (visible at low
|
||||
// zoom where the whole world is narrower than the viewport). Normalizing the
|
||||
// longitude to the equivalent value closest to the view center keeps every
|
||||
// meridian's X near the center, safely inside the clip window.
|
||||
var normalized = lon
|
||||
while (normalized < centerLon - 180.0) normalized += 360.0
|
||||
while (normalized > centerLon + 180.0) normalized -= 360.0
|
||||
val geo = org.osmdroid.util.GeoPoint(0.0, normalized)
|
||||
val p = projection.toPixels(geo, null)
|
||||
return if (p.x in -MAX_OVERSHOOT_PX..MAX_OVERSHOOT_PX + 4096) p.x.toFloat() else null
|
||||
}
|
||||
|
||||
@@ -173,7 +173,9 @@ private fun MapScreen(uiState: MapState, onAction: (MapAction) -> Unit, mapView:
|
||||
view.invalidate()
|
||||
}
|
||||
uiState.mapData?.let { mapData ->
|
||||
if (isVertical) MapDataCard(mapData) else MapDataCards(mapData)
|
||||
if (!uiState.isGridMode) {
|
||||
if (isVertical) MapDataCard(mapData) else MapDataCards(mapData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[versions]
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
appVersionCode = "453"
|
||||
appVersionCode = "454"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
appVersionName = "4.4.6-ba7opf.9.1"
|
||||
appVersionName = "4.4.6-ba7opf.9.2"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
compileSdk = "37"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
|
||||
Reference in new issue
Block a user