# DamageFilterSystem **Zweck:** Filter-System für Feature Layer. Ermöglicht Filterung nach Schadenstyp, Bearbeitungsstatus und Datum (unabhängig kombinierbar). **Komponenten:** UI-Dialog + Extension-Funktionen für MapViewModel. --- ## FilterCheckboxItem ```kotlin @Composable fun FilterCheckboxItem( label: String, isChecked: Boolean, onCheckedChange: (Boolean) -> Unit, emoji: String = "•" ) ``` **Zweck:** Wiederverwendbare Checkbox-Komponente mit Label und Emoji. **Parameter:** | Name | Typ | Beschreibung | |------|-----|--------------| | `label` | String | Angezeigter Text | | `isChecked` | Boolean | Checkbox-Status | | `onCheckedChange` | (Boolean) -> Unit | Callback bei Status-Änderung | | `emoji` | String | Icon/Emoji rechts (default: "•") | --- ## DamageFilterDialog ```kotlin @Composable fun DamageFilterDialog( damageTypes: List, currentFilters: Set, onDismiss: () -> Unit, onApplyFilter: (Set, Set, LocalDate?, LocalDate?) -> Unit ) ``` **Zweck:** Vollbildschirm-Dialog zur Auswahl von Filter-Kriterien. **Parameter:** | Name | Typ | Beschreibung | |------|-----|--------------| | `damageTypes` | List | Verfügbare Schadenstypen (z.B. "Straße", "Gehweg") | | `currentFilters` | Set | Aktuell aktive Typ-Filter | | `onDismiss` | () -> Unit | Callback zum Schließen des Dialogs | | `onApplyFilter` | (Set, Set, LocalDate?, LocalDate?) -> Unit | Callback mit (Typen, Status, StartDatum, EndDatum) | ### Filter-Typen **1. Schadenstypen:** - Straße 🛣️ - Gehweg 🚶 - Fahrradweg 🚴 - Beleuchtung 💡 - Sonstiges 📍 **2. Bearbeitungsstatus:** - neu 🔴 - in Bearbeitung 🟠 - Schaden behoben 🟢 **3. Datums-Filter:** - Von-Datum (dd.MM.yyyy) - Bis-Datum (dd.MM.yyyy) - Optional aktivierbar via Checkbox ### State Management | State | Typ | Default | Beschreibung | |-------|-----|---------|--------------| | `selectedFilters` | Set | alle Typen | Ausgewählte Schadenstypen | | `selectedStatus` | Set | alle Status | Ausgewählte Status | | `startDateString` | String | "" | Eingabe Von-Datum | | `endDateString` | String | "" | Eingabe Bis-Datum | | `startDate` | LocalDate? | null | Geparste Von-Datum | | `endDate` | LocalDate? | null | Geparste Bis-Datum | | `useDateFilter` | Boolean | false | Datums-Filter aktiv | ### UI-Buttons | Button | Funktion | |--------|----------| | "Alle" | Wählt alle Typen + alle Status | | "Keine" | Deselektiert alle Typen + alle Status | | "Filter anwenden" | Ruft `onApplyFilter()` auf und schließt Dialog | ### Datums-Parsing **Format:** dd.MM.yyyy (z.B. 15.01.2024) **Validierung:** ```kotlin LocalDate.parse(input, DateTimeFormatter.ofPattern("dd.MM.yyyy")) ``` **Parsing:** Automatisch bei Eingabe (length == 10), fehlerhafte Eingaben werden ignoriert. --- ## applyDamageFilter (Extension Function) ```kotlin suspend fun MapViewModel.applyDamageFilter( selectedTypes: Set, selectedStatus: Set, startDate: LocalDate? = null, endDate: LocalDate? = null ): Boolean ``` **Zweck:** Wendet Filter auf FeatureLayer via SQL WHERE-Clause an. **Parameter:** | Name | Typ | Beschreibung | |------|-----|--------------| | `selectedTypes` | Set | Ausgewählte Schadenstypen | | `selectedStatus` | Set | Ausgewählte Status | | `startDate` | LocalDate? | Start-Datum (optional) | | `endDate` | LocalDate? | End-Datum (optional) | **Return:** `Boolean` - true bei Erfolg, false bei Fehler ### Filter-Logik **1. Typ-Filter:** ```sql Typ IN ('Straße', 'Gehweg') ``` - Nur hinzugefügt wenn nicht alle Typen ausgewählt - Verwendet SQL IN-Operator **2. Status-Filter:** ```sql status IN ('neu', 'in Bearbeitung') ``` - Nur hinzugefügt wenn nicht alle Status ausgewählt - Verwendet SQL IN-Operator **3. Datums-Filter:** ```sql EditDate >= timestamp '2024-01-01 00:00:00' AND EditDate <= timestamp '2024-12-31 23:59:59' ``` - Feldname: `EditDate` - Format: SQL timestamp - Unterstützt: Von, Bis, oder beides **Kombination:** ```sql Typ IN ('Straße') AND status IN ('neu') AND EditDate >= timestamp '...' ``` - Alle aktiven Filter werden mit AND verknüpft ### Snackbar-Feedback **Format:** "Filter: {Typ-Info} | {Status-Info} | {Datum-Info}" **Beispiele:** - "Filter: 3 Typ(en) | 2 Status" - "Filter: Datum: 01.01.2024 - 31.12.2024" - "Alle Schäden werden angezeigt" (keine Filter) ### Threading **Ausführung:** `withContext(Dispatchers.IO)` für Feature Query **UI-Updates:** `withContext(Dispatchers.Main)` für snackBarMessage --- ## getActiveFilters (Extension Function) ```kotlin fun MapViewModel.getActiveFilters(): Set ``` **Zweck:** Extrahiert aktuell aktive Filter aus FeatureLayer.definitionExpression. **Return:** Set - Menge der gefilterten Werte (z.B. {"Straße", "Gehweg"}) **Extraktion:** ```kotlin val regex = "'([^']+)'".toRegex() regex.findAll(expression).map { it.groupValues[1] }.toSet() ``` **Beispiel:** ``` Expression: "Typ IN ('Straße', 'Gehweg')" Return: {"Straße", "Gehweg"} ``` --- ## Verwendungsbeispiel ```kotlin // Dialog anzeigen var showFilterDialog by remember { mutableStateOf(false) } if (showFilterDialog) { DamageFilterDialog( damageTypes = MapViewModel.DAMAGE_TYPES, currentFilters = mapViewModel.getActiveFilters(), onDismiss = { showFilterDialog = false }, onApplyFilter = { types, status, start, end -> coroutineScope.launch { mapViewModel.applyDamageFilter(types, status, start, end) } } ) } // Aus MainScreen SliderMenuItem( text = "Schäden filtern", icon = Icons.Default.FilterAlt, onClick = { showFilterDialog = true } ) ``` --- ## SQL-Beispiele **Nur Typ:** ```sql Typ IN ('Straße', 'Gehweg') ``` **Nur Status:** ```sql status IN ('neu', 'in Bearbeitung') ``` **Nur Datum:** ```sql EditDate >= timestamp '2024-01-01 00:00:00' AND EditDate <= timestamp '2024-12-31 23:59:59' ``` **Alle kombiniert:** ```sql Typ IN ('Straße') AND status IN ('neu') AND EditDate >= timestamp '2024-01-01 00:00:00' ``` **Keine Filter (alle anzeigen):** ```sql (empty string) ``` --- ## Feature-Attribute **Erforderliche Felder im Feature Layer:** | Feldname | Typ | Werte | Beschreibung | |----------|-----|-------|--------------| | `Typ` | String | "Straße", "Gehweg", etc. | Schadenstyp | | `status` | String | "neu", "in Bearbeitung", "Schaden behoben" | Bearbeitungsstatus | | `EditDate` | Timestamp | SQL timestamp | Letzte Änderung | --- ## Technische Details - **UI Framework:** Jetpack Compose - **Dialog:** Material3 Card im Dialog - **State:** remember/mutableStateOf - **Threading:** Coroutines (Dispatchers.IO/Main) - **SQL:** ArcGIS SQL-Syntax (definitionExpression) - **Datum:** Java Time API (LocalDate, DateTimeFormatter)