Files
SnapAndSolve/docs/DamageFilterSystem.md
si2503 8342723e09 - Dokumentation
- Bereinigung von Code
2026-02-13 10:33:21 +01:00

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)