6.7 KiB
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
@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
@Composable
fun DamageFilterDialog(
damageTypes: List<String>,
currentFilters: Set<String>,
onDismiss: () -> Unit,
onApplyFilter: (Set<String>, Set<String>, 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:
LocalDate.parse(input, DateTimeFormatter.ofPattern("dd.MM.yyyy"))
Parsing: Automatisch bei Eingabe (length == 10), fehlerhafte Eingaben werden ignoriert.
applyDamageFilter (Extension Function)
suspend fun MapViewModel.applyDamageFilter(
selectedTypes: Set<String>,
selectedStatus: Set<String>,
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:
Typ IN ('Straße', 'Gehweg')
- Nur hinzugefügt wenn nicht alle Typen ausgewählt
- Verwendet SQL IN-Operator
2. Status-Filter:
status IN ('neu', 'in Bearbeitung')
- Nur hinzugefügt wenn nicht alle Status ausgewählt
- Verwendet SQL IN-Operator
3. Datums-Filter:
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:
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)
fun MapViewModel.getActiveFilters(): Set<String>
Zweck: Extrahiert aktuell aktive Filter aus FeatureLayer.definitionExpression.
Return: Set - Menge der gefilterten Werte (z.B. {"Straße", "Gehweg"})
Extraktion:
val regex = "'([^']+)'".toRegex()
regex.findAll(expression).map { it.groupValues[1] }.toSet()
Beispiel:
Expression: "Typ IN ('Straße', 'Gehweg')"
Return: {"Straße", "Gehweg"}
Verwendungsbeispiel
// 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:
Typ IN ('Straße', 'Gehweg')
Nur Status:
status IN ('neu', 'in Bearbeitung')
Nur Datum:
EditDate >= timestamp '2024-01-01 00:00:00'
AND EditDate <= timestamp '2024-12-31 23:59:59'
Alle kombiniert:
Typ IN ('Straße')
AND status IN ('neu')
AND EditDate >= timestamp '2024-01-01 00:00:00'
Keine Filter (alle anzeigen):
(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)