feat(train): routes kept as sealed rows, planned on the map (ADR 0030, D44)

Routes are synced `route` rows (the model `SavedRoute`, as Flutter has a
`Route`), sealed as plans are; the migration `routes` only creates the
table, its space index and its cascade to the sync engine's spaces. A
route's payload holds its name, activity, profile, waypoints and the way
planned, points and elevations delta-coded and gzipped.

Home gets a fourth tab, Routes, and the planner: waypoints tapped on the
map, held and dragged, the last undone, a new route's first where the
phone is (GPS through the recorder's channel), the way planned by the
instance's BRouter after each change, an earlier answer dropped; its
distance, climb, descent, elevation and surfaces under the map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-29 00:37:44 +01:00
commit aea99c68ca
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -376,5 +376,45 @@
"dayBreathing": "{rate} Atemzüge pro Minute",
"daySkin": "Hauttemperatur",
"dayCelsius": "{value} °C",
"daySkinDeviation": "{value} °C gegenüber deinen Nächten sonst"
"daySkinDeviation": "{value} °C gegenüber deinen Nächten sonst",
"homeRoutes": "Routen",
"routesNew": "Neue Route",
"routesEmptyTitle": "Noch keine Routen",
"routesEmptyHint": "Tipp auf die Karte, um Wegpunkte zu setzen, und deine Instanz plant den Weg dazwischen über Wege und Straßen, mit Anstieg und Untergrund.",
"routeLocked": "Eine Route, die sich hier nicht öffnet",
"routeTitle": "Route",
"routeNewTitle": "Neue Route",
"routeName": "Name",
"routeActivity": "Für",
"routeActivityAny": "Jede Aktivität",
"routeProfile": "Geplant für",
"routeProfileRun": "Laufen",
"routeProfileHike": "Wandern",
"routeProfileRoadBike": "Rennrad",
"routeProfileTrekkingBike": "Trekkingrad",
"routeProfileGravel": "Gravelbike",
"routeProfileMtb": "Mountainbike",
"routeTapHint": "Tipp auf die Karte, um einen Wegpunkt hinzuzufügen; halt einen gedrückt und zieh ihn, um ihn zu verschieben.",
"routeUndo": "Letzten Wegpunkt entfernen",
"routePlanning": "Wird geplant …",
"routeRefusedInvalid": "Ein Wegpunkt zu viel, oder einer außerhalb der Karte.",
"routeRefusedTooOften": "Zu oft geplant: versuch es in einer Minute wieder.",
"routeRefusedNoRoute": "Dort wurde kein Weg gefunden: Ein Wegpunkt liegt vielleicht abseits der Wege oder außerhalb des Gebiets, in dem deine Instanz plant.",
"routeRefusedUnreachable": "Deine Instanz ist nicht erreichbar, um den Weg zu planen.",
"routeNotOffered": "Deine Instanz plant keine Routen.",
"routeAscent": "{metres} m bergauf",
"routeDescent": "{metres} m bergab",
"routeSummary": "{distance} · {ascent}",
"routeSurfaces": "Untergrund",
"surfacePaved": "Befestigt",
"surfaceCompacted": "Verdichtet",
"surfaceGravel": "Schotter",
"surfaceNatural": "Naturboden",
"surfaceUnknown": "Unbekannt",
"routeSave": "Speichern",
"routeNotSaved": "Die Route wurde nicht gespeichert.",
"routeDelete": "Löschen",
"routeDeleteTitle": "Diese Route löschen?",
"routeDeleteMessage": "Sie wird auf all deinen Geräten gelöscht.",
"routeDeleted": "Route gelöscht"
}