Skip to content

feat(wasserfoerderung): draw Förderstrecken on a map with real elevation profiles (#150, Plan B) - #164

Open
DeepDiver1975 wants to merge 2 commits into
feat/wasserfoerderung-plan-afrom
feat/wasserfoerderung-plan-b
Open

feat(wasserfoerderung): draw Förderstrecken on a map with real elevation profiles (#150, Plan B)#164
DeepDiver1975 wants to merge 2 commits into
feat/wasserfoerderung-plan-afrom
feat/wasserfoerderung-plan-b

Conversation

@DeepDiver1975

@DeepDiver1975 DeepDiver1975 commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Zusammenfassung

Phase 2 von #150 (nach Plan A / #152): der Operator kann eine Wasserförderungs-Leitung jetzt auf einer Karte einzeichnen, statt Länge/Höhenunterschied von Hand einzutippen. Das Geländeprofil wird entlang der gezeichneten Route aus einem gebündelten DEM (eigenes Binärformat) gesampelt, und die Pumpenplatzierung wird streckenweise gegen das tatsächliche Profil berechnet statt gegen eine einzelne, gleichmäßige Steigung — dadurch werden innenliegende Kuppen (Anstieg + Abstieg zurück auf dieselbe Nettohöhe) erkannt, die die flache Plan-A-Formel übersehen würde.

Kartenkacheln kommen aus einer gebündelten MBTiles-Datei; beide Dateien werden über eine neue globale Stammdaten-Einstellung „Einsatzgebiet" referenziert. Vollständig offline wie der Rest der App, keine neue NuGet-Abhängigkeit: MBTiles wird über das bereits referenzierte Microsoft.Data.Sqlite gelesen, die Kartenansicht ist ein selbstgebautes Avalonia-Control mit Standard-Web-Mercator-Kachel-Mathematik. Die manuelle Eingabe (Plan A) bleibt unverändert verfügbar, überall wo kein Einsatzgebiet konfiguriert ist. Die Route bekommt zusätzlich einen kleinen Karten-Schnappschuss im PDF-Export neben ihrer Zahlenzeile.

Base-Branch ist feat/wasserfoerderung-plan-a (#152), da Phase 1 noch nicht in main gemerged ist — dieser PR baut auf Migration v18/Domain-Code von Plan A auf.

  • Domain-Fix: FörderstreckePlanner.PlanFromProfile läuft das Profil Bein für Bein ab und verfolgt das laufende Maximum des kumulativen Druckabfalls statt nur den Endpunkt zu prüfen — Plan A (Plan(...)) delegiert jetzt intern dorthin und bleibt für alle 9 bestehenden Tests bytegleich.
  • Persistenz: DemFileElevationSampler (eigenes DEM-Binärformat, bilineare Interpolation, NoData-/Außerhalb-Behandlung), MbTilesFileSource (TMS↔XYZ-Kachel-Mathematik).
  • Stammdaten: neue globale Sektion „Einsatzgebiet" (Name + Ordnerpfad zu region.mbtiles/region.dem).
  • Migration v19: route_points_json (NULL = manuelle Plan-A-Eingabe).
  • Sync: vollständige Befehlskette (Command → Applier → Snapshot → beide Session-Typen).
  • UI: MapCanvasControl (neues Custom-Control) + WebMercator-Kachel-Mathematik; Manuell/Karte-Umschalter im WASSERFÖRDERUNG-Tab.
  • PDF: IRouteOverviewRenderer-Port + Implementierung, bettet einen Karten-Schnappschuss pro routenbasierter Leitung ein.

Tests

826 → 882 Tests grün (54 neue, keine Regressionen).

Screenshots

Screenshots rendered via the headless test harness — paste them in below (see file paths in the session).

Bekannte Einschränkungen (bewusste Entscheidungen für diesen Umfang)

  • Kein Kartenschwenken per Drag — die Karte öffnet auf einem festen Standardmittelpunkt mit Zoom +/- Buttons.
  • Werkzeuge zum Erstellen/Verwalten der MBTiles/DEM-Pakete für beliebige Regionen sind bewusst Phase 3 vorbehalten (feat: plan mode for wasserförderung #150).

🤖 Generated with Claude Code

https://claude.ai/code/session_01UwN31QccH98YV9eEc2bue2

…ion profiles (#150, Plan B)

Phase 2 of #150: lets the operator draw a Wasserförderung route on a map
instead of typing length/rise by hand. Terrain is sampled from a bundled
DEM (custom binary heightmap) along the drawn polyline, and pump
placement is computed leg-by-leg against the actual profile instead of
assuming one uniform gradient — catching interior crests (a climb then
descent back to the same net height) that the flat Plan A formula would
miss. Map tiles come from a bundled MBTiles file, both referenced from a
new "Einsatzgebiet" (region of operation) global Stammdaten setting.

Fully offline like the rest of the app, no new NuGet dependency: MBTiles
is read via the already-referenced Microsoft.Data.Sqlite, and the map
canvas is a hand-rolled Avalonia control using standard Web Mercator
tile math. Manuell (Plan A) entry stays available unchanged wherever a
region isn't configured. The route also gets a small map snapshot
embedded in the PDF export next to its numeric row.

826 -> 882 tests, all green.

Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
… at small windows

The Karte-mode layout used a DockPanel with a fixed Height="360" map
plus stacked Bottom-docked input-dock panels and no ScrollViewer. In a
window short enough that the DataGrid's share of the DockPanel
collapsed to zero (confirmed at 1920x700), the map Border — later in
Z-order — rendered on top of and overlapped the mode-toggle header
buttons instead of being pushed below them. Separately, the Karte
input dock's unwrapped horizontal button row pushed "FERTIG" past the
window's right edge entirely at narrower widths (confirmed at 1080
wide).

Root-caused by reproducing both at exact window sizes via the headless
harness (not by guessing from the screenshot) after an initial
attempt to reproduce via the live desktop app under Xvfb touched a
real incident file's mtime through its native open dialog — that
route was abandoned once caught.

Fix: wrap everything below the header in a single ScrollViewer with
naturally-stacked content (same pattern already used by
ChecklistView/FilesView/etc. in this codebase) so insufficient space
scrolls instead of overlaps, and switch both input docks' button rows
from an unwrapped horizontal StackPanel to a WrapPanel so buttons wrap
instead of overflowing the window.

New regression test asserts the map never starts above the header's
bottom edge and FERTIG's right edge never exceeds the window width, at
the exact size that reproduced the bug.

882 -> 883 tests, all green.

Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant