# GPS2Audio v2.5.35 — Phantom GPX Line Fix — Handoff ## Versionsinfo - **VersionName:** 2.5.35 - **VersionCode:** 89 - **applicationId:** de.waypointaudio - **Keystore:** GPS2Audio_release_keystore_v2.jks - **Alias:** gps2audio_release_v2 - **Basis:** v2.5.34 (Explorer-Kontext-Fix) --- ## Konkrete Ursache des Phantom-Linien-Bugs In v2.5.34 wurde bereits der in-memory Phantom-Track-Tap-Bug behoben, aber eine tiefere Ursache blieb: ### Drei unabhängige Phantom-Linien-Quellen: **1. `savedRouteLine` (TourRoute-Polyline)** In `ExplorerScreenMapLibre.kt` wird `savedRouteLine` aus `activeTourRoute` berechnet. `activeTourRoute` ist die Tour-gebundene Route aus `repository.tourRoutes`, einer persistierten Map `tourName → TourRoute`. Wenn für den Schlüssel `"Standard"` (= `Waypoint.DEFAULT_TOUR_NAME`) je eine TourRoute gespeichert wurde (z. B. durch Backup-Import, durch versehentliches Zeichnen/Berechnen während Standard aktiv war), wird diese als grüne oder weiße Linie auf der Karte angezeigt — auch wenn 0 Wegpunkte vorhanden sind. **2. `persistedTrack` (GPS-Aufzeichnung)** `visibleTrack` fällt auf `persistedTrack` zurück, wenn keine Aufzeichnung läuft und kein Draft aktiv ist. `persistedTrack` wird per `loadPersistedTrackForCurrentTour()` aus `repository.gpsTracks[selectedTour]` geladen. Wenn unter dem Schlüssel `"Standard"` je ein GPS-Track aufgezeichnet wurde (z. B. bevor der Nutzer eine Tour auswählte), erscheint dieser als weiße Track-Polyline — ebenfalls ohne Wegpunkte. **3. `manualRoutePoints` (manuell gezeichnete Route)** Im `LaunchedEffect(selectedTour, activeTourRoute?.id, activeTourRoute?.source)` werden MANUAL-Routen aus `activeTourRoute` geladen, ohne Einschränkung auf nicht-Standard-Touren. Eine manuell gezeichnete Route für Standard würde als Phantom-Linie erscheinen. ### Warum erscheinen die Daten trotz „0 Wegpunkte"? Waypoints, GPS-Tracks und TourRoutes sind **unabhängig persistiert**. Wegpunkte liegen in einem eigenen Storage, GPS-Tracks in einem anderen (`gpsTracks`-Flow), und TourRoutes in einem dritten (`tourRoutes`-Flow). Die UI zeigt „0 Wegpunkte", weil keine `Waypoint`-Objekte für die Standard-Tour existieren — aber die Track-/Route-Daten existieren unabhängig davon. --- ## Geänderte Dateien und Funktionen ### `app/src/main/kotlin/de/waypointaudio/ui/ExplorerScreenMapLibre.kt` **Drei Fixes, alle defensiv (kein Datenverlust):** #### Fix 1: `isNeutralStandard`-Flag (neu, ~Zeile 221) ```kotlin val isNeutralStandard: Boolean = selectedTour == de.waypointaudio.data.Waypoint.DEFAULT_TOUR_NAME ``` Dieses Flag wird von allen drei Phantom-Guards verwendet. Es ist `true`, wenn die Standardtour aktiv ist. Laufende Aufzeichnung (`isRecording`) und aktive Drafts (`activeDraft`) übersteuern die Unterdrückung individuell je Fix. #### Fix 2: `savedRouteLine` — Phantom-Guard (Zeile ~237) ```kotlin val savedRouteLine: List = remember(activeTourRoute, isNeutralStandard, isRecording) { val r = activeTourRoute if (r == null || r.source == RouteSourceKind.MANUAL) emptyList() else if (isNeutralStandard && !isRecording) emptyList() // NEU else r.polyline.map { LatLng(it.lat, it.lon) } } ``` Im neutralen Standard-Kontext (keine Aufzeichnung) wird `savedRouteLine` als leer zurückgegeben, auch wenn in `activeTourRoute` eine Polyline persistiert ist. Die Daten in `repository.tourRoutes["Standard"]` bleiben unverändert. #### Fix 3: `visibleTrack` — Phantom-Guard (Zeile ~440) ```kotlin val visibleTrack: List = when { isRecording -> currentTrack activeDraft != null -> activeDraft.points currentTrack.isNotEmpty() -> currentTrack isNeutralStandard -> emptyList() // NEU else -> persistedTrack } ``` Für die Standard-Tour wird `persistedTrack` nicht in `visibleTrack` übernommen. Die Daten in `repository.gpsTracks["Standard"]` bleiben unverändert. #### Fix 4: `manualRoutePoints` — Phantom-Guard (Zeile ~338) ```kotlin manualRoutePoints = if ( r?.source == RouteSourceKind.MANUAL && !isNeutralStandard // NEU ) { r.polyline.map { LatLng(it.lat, it.lon) } } else emptyList() ``` Für die Standard-Tour werden keine manuell gezeichneten Routen aus `activeTourRoute` geladen. ### `app/build.gradle.kts` - `versionCode`: 88 → **89** - `versionName`: "2.5.34" → **"2.5.35"** --- ## Wie die Standardkarte isoliert wird ``` selectedTour == "Standard" │ ├─ isRecording == true → Track läuft: currentTrack normal anzeigen │ savedRouteLine: LEER (kein Route-Phantom) │ ├─ activeDraft != null → Draft aktiv: draft.points normal anzeigen │ savedRouteLine: LEER │ └─ (neutral) → isNeutralStandard = true visibleTrack = LEER (persistedTrack unterdrückt) savedRouteLine = LEER manualRoutePoints = LEER → Karte optisch leer ✓ ``` Für **echte Touren** (`selectedTour != "Standard"`) bleibt alles wie in v2.5.34: Tour-Routen, Waypoints, Routing-Linien und Drafts werden normal angezeigt. --- ## Testfälle ### TC-1: Phantom-Linie Standard-Karte (Hauptbug) 1. App starten, Explorer öffnen (kein Tour-Kontext / via Audio-Bibliothek → Standard) 2. Karte zeigt "Standard" + "Karte · 0 Wegpunkte" 3. **Erwartet:** Keine weiße/grüne Linie auf der Karte. Karte ist optisch leer. ### TC-2: Aufzeichnung in Standard-Tour 1. Auf Standard-Tour GPS-Track aufzeichnen 2. Während Aufzeichnung: `currentTrack` wird angezeigt (isRecording → kein Guard) 3. Nach Stop: Track ist im Archiv (Draft gespeichert), Standard-Karte wieder leer 4. **Erwartet:** Aufzeichnung sichtbar während sie läuft; danach keine Phantom-Linie ### TC-3: Echte Tour — Route und Track erhalten 1. Explorer aus konkreter Tour (z. B. "Tour Wien") öffnen 2. Gespeicherte TourRoute wird als Linie angezeigt 3. Persistierter GPS-Track wird als Track angezeigt 4. **Erwartet:** Alle Linien sichtbar (isNeutralStandard = false → Guards inaktiv) ### TC-4: GPX-Import erzeugt neue Tour, nicht Standard 1. GPX-Datei importieren ("Als neue Tour") 2. Neue Tour "GPX-Import YYYY-MM-DD" wird erstellt, selectedTour wechselt dahin 3. Standard-Karte bleibt leer wenn zurückgekehrt 4. **Erwartet:** Import-Waypoints in neuer Tour; Standard optisch leer ### TC-5: Backup-Import mit alten Tracks 1. Backup importieren, das TourRoutes für Standard enthält 2. Standard-Karte öffnen 3. **Erwartet:** Daten sind persistiert (kein Datenverlust), werden aber nicht als Linie gerendert ### TC-6: Manuelle Route in echter Tour 1. Tour "Meine Tour" auswählen, Explorer öffnen 2. "Route zeichnen" aktivieren, Linie auf Karte zeichnen 3. Route wird angezeigt und gespeichert 4. Zu Standard wechseln → Standard leer 5. Zu "Meine Tour" zurück → Route wieder sichtbar 6. **Erwartet:** Route Tour-gebunden, Standard bleibt leer --- ## Signatur- und ABI-Status | Prüfpunkt | Ergebnis | |---|---| | APK-Datei | GPS2Audio_v2_5_35_phantom_gpx_line_fix_universal_signed.apk | | Größe | 57 MB | | versionCode | 89 | | versionName | 2.5.35 | | applicationId | de.waypointaudio | | ABI arm64-v8a | ✓ | | ABI armeabi-v7a | ✓ | | ABI x86 | ✓ | | ABI x86_64 | ✓ | | Signatur-Schema | APK Signature Scheme v2 ✓ | | Signer DN | CN=GPS2Audio, OU=NesoHub, O=GPS2Audio, L=Germany, C=DE | | Cert SHA-256 | 490511f350557083808cdf9e39fdb0a2d4d76d2224726b56018d1ac0dd9ed4e5 | | Keystore | GPS2Audio_release_keystore_v2.jks / Alias gps2audio_release_v2 | --- ## Artefakte | Datei | Beschreibung | |---|---| | `GPS2Audio_v2_5_35_phantom_gpx_line_fix_universal_signed.apk` | Universelle Release-APK, alle 4 ABIs, signiert | | `GPS2Audio_v2_5_35_phantom_gpx_line_fix_source.zip` | Vollständiger Quellcode v2.5.35 | | `GPS2Audio_v2_5_35_phantom_gpx_line_fix_handoff.md` | Dieses Dokument | --- ## Beibehaltene Features aus v2.5.34 und davor Alle Features unverändert: - Lizenzsystem / Feature-Gates - Multi-Clip, PTT, Tour-Zähler - Backup / Cover-Bilder - GPX-Import (additiv, neue Tour oder bestehende Tour) - Explorer / MapLibre / Routing (OSRM) - Tour- / Waypoint-Kopien - Hintergrundwiedergabe - Track-Drafts / TrackDraftEditorScreen - Waypoint-Radius, Audio-Trigger, Audio-Lines - Manuelle Route zeichnen (in echten Touren) - v2.5.34: selectDefaultTour() beim Einstieg aus Audio-Bibliothek - v2.5.33: TrackRecordingManager clearTrack() bei Tour-Wechsel --- ## Keine Gitea-Veröffentlichung durchgeführt (gemäß Aufgabe)