From 7bbbb6e70ed2e9a2450f127f238e8c1c1f75fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= <1005065+DeepDiver1975@users.noreply.github.com> Date: Mon, 31 Aug 2026 10:36:29 +0200 Subject: [PATCH 1/4] feat(wasserfoerderung): downloadable region packs for Einsatzgebiet (#150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stammdaten's Einsatzgebiet config was a raw folder-path text field with no way to actually get map data onto a machine. Replace it with a dropdown fed by a published region-pack catalog (regions.json + GitHub Releases, one pack per Landkreis): pick a region, hit "Herunterladen", the app fetches and extracts region.mbtiles/region.dem via IRegionPackCatalogService and IRegionPackInstaller. Manual folder entry stays available under an "Erweitert" fallback for a self-built or hand-placed pack. The pack-building side (osmium extract, raster tile rendering, SRTM elevation conversion) stays a documented external runbook under tools/build-region-pack/, deliberately kept out of LageBuch.sln — it's a one-time-per-region maintainer task, not something every installation needs to run itself. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01UwN31QccH98YV9eEc2bue2 Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com> --- src/LageBuch.App.Android/MainActivity.cs | 1 + .../Services/AndroidAppPaths.cs | 3 + src/LageBuch.App.Shared/CompositionRoot.cs | 13 +- .../Views/MasterDataEditorView.axaml | 66 +++++-- src/LageBuch.App/AppPaths.cs | 3 + src/LageBuch.App/Program.cs | 1 + .../Services/IRegionPackCatalogService.cs | 28 +++ .../Services/IRegionPackInstaller.cs | 8 + .../Services/RegionPackCatalogJson.cs | 79 ++++++++ .../Services/RegionPackCatalogService.cs | 23 +++ .../Services/RegionPackInstaller.cs | 56 ++++++ .../ViewModels/EinsatzgebietSection.cs | 91 +++++++++- .../ViewModels/MasterDataEditorViewModel.cs | 12 +- .../AboutRenderTests.cs | 14 +- .../MasterDataEditorRenderTests.cs | 67 ++++++- .../EinsatzgebietSectionTests.cs | 169 ++++++++++++++++++ .../MainWindowViewModelTests.cs | 6 +- .../MasterDataEditorViewModelTests.cs | 17 +- .../RegionPackCatalogJsonTests.cs | 73 ++++++++ .../RegionPackCatalogServiceTests.cs | 73 ++++++++ .../RegionPackInstallerTests.cs | 109 +++++++++++ tools/build-region-pack/README.md | 157 ++++++++++++++++ 22 files changed, 1042 insertions(+), 27 deletions(-) create mode 100644 src/LageBuch.AppLogic/Services/IRegionPackCatalogService.cs create mode 100644 src/LageBuch.AppLogic/Services/IRegionPackInstaller.cs create mode 100644 src/LageBuch.AppLogic/Services/RegionPackCatalogJson.cs create mode 100644 src/LageBuch.AppLogic/Services/RegionPackCatalogService.cs create mode 100644 src/LageBuch.AppLogic/Services/RegionPackInstaller.cs create mode 100644 tests/LageBuch.AppLogic.Tests/EinsatzgebietSectionTests.cs create mode 100644 tests/LageBuch.AppLogic.Tests/RegionPackCatalogJsonTests.cs create mode 100644 tests/LageBuch.AppLogic.Tests/RegionPackCatalogServiceTests.cs create mode 100644 tests/LageBuch.AppLogic.Tests/RegionPackInstallerTests.cs create mode 100644 tools/build-region-pack/README.md diff --git a/src/LageBuch.App.Android/MainActivity.cs b/src/LageBuch.App.Android/MainActivity.cs index 21d06b6..0aee49d 100644 --- a/src/LageBuch.App.Android/MainActivity.cs +++ b/src/LageBuch.App.Android/MainActivity.cs @@ -65,6 +65,7 @@ protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) new NoopIncidentHostController(), new LageBuch.App.Shared.Services.AvaloniaUiDispatcher(), typeof(MainActivity).Assembly.GetName().Version?.ToString() ?? "0.0.0", + AndroidAppPaths.RegionsDir(this), lastSaveFolder: null, attachmentCacheRoot: AndroidAppPaths.AttachmentCacheDir(this)); return base.CustomizeAppBuilder(builder).WithInterFont(); diff --git a/src/LageBuch.App.Android/Services/AndroidAppPaths.cs b/src/LageBuch.App.Android/Services/AndroidAppPaths.cs index 62deec0..d053fb9 100644 --- a/src/LageBuch.App.Android/Services/AndroidAppPaths.cs +++ b/src/LageBuch.App.Android/Services/AndroidAppPaths.cs @@ -27,4 +27,7 @@ public static string RecentFilesJsonPath(Context context) => public static string AttachmentCacheDir(Context context) => System.IO.Path.Combine(CacheDir(context), "attachment-cache"); + + public static string RegionsDir(Context context) => + System.IO.Path.Combine(context.FilesDir!.AbsolutePath, "regions"); } diff --git a/src/LageBuch.App.Shared/CompositionRoot.cs b/src/LageBuch.App.Shared/CompositionRoot.cs index 9d7bd52..d8a09e9 100644 --- a/src/LageBuch.App.Shared/CompositionRoot.cs +++ b/src/LageBuch.App.Shared/CompositionRoot.cs @@ -14,6 +14,13 @@ namespace LageBuch.App.Shared; /// public static class CompositionRoot { + /// + /// Raw-served manifest of published Wasserförderung region packs (#150 follow-up) — see + /// tools/build-region-pack/README.md for how a pack is built and published here. + /// + public const string RegionPackManifestUrl = + "https://raw.githubusercontent.com/CodeForFire/lagebuch-regions/main/regions.json"; + public static MainWindowViewModel CreateMainWindowViewModel( IIncidentStore store, IMasterDataProvider masterData, @@ -26,11 +33,15 @@ public static MainWindowViewModel CreateMainWindowViewModel( IIncidentHostController hostController, IUiDispatcher uiDispatcher, string appVersion, + string regionsDir, ILastSaveFolderStore? lastSaveFolder = null, string? attachmentCacheRoot = null) { var home = new HomeViewModel(store, masterData, recent, dialogs, clock, ticker, alarm, hostController, appVersion, uiDispatcher, lastSaveFolder, attachmentCacheRoot, new RouteOverviewRenderer()); - var editor = new MasterDataEditorViewModel(masterData, dialogs, masterDataFileService); + var httpClient = new HttpClient(); + var regionCatalog = new RegionPackCatalogService(httpClient, RegionPackManifestUrl); + var regionInstaller = new RegionPackInstaller(httpClient, regionsDir); + var editor = new MasterDataEditorViewModel(masterData, dialogs, masterDataFileService, regionCatalog, regionInstaller); return new MainWindowViewModel(home, editor, dialogs, appVersion); } } diff --git a/src/LageBuch.App.Shared/Views/MasterDataEditorView.axaml b/src/LageBuch.App.Shared/Views/MasterDataEditorView.axaml index 2561551..8bdea8f 100644 --- a/src/LageBuch.App.Shared/Views/MasterDataEditorView.axaml +++ b/src/LageBuch.App.Shared/Views/MasterDataEditorView.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:LageBuch.AppLogic.ViewModels;assembly=LageBuch.AppLogic" xmlns:md="clr-namespace:LageBuch.Persistence.MasterData;assembly=LageBuch.Persistence" + xmlns:services="clr-namespace:LageBuch.AppLogic.Services;assembly=LageBuch.AppLogic" x:Class="LageBuch.App.Shared.Views.MasterDataEditorView" x:DataType="vm:MasterDataEditorViewModel"> @@ -108,18 +109,63 @@ - + - - - - - - - - + + + + + + + + + + + + +