Kommunale Inspektions-App: GIS, Offline-Funktionalität und Architektur

Kommunale Inspektions-App: GIS, Offline-Funktionalität und Architektur

Die Arbeit von Stadtinspektoren findet in der Regel weit entfernt vom Schreibtisch statt. Sie müssen Hydranten überprüfen, Baustellen begehen, Parks kontrollieren und Verstöße gegen Vorschriften Block für Block dokumentieren. Eine kommunale Inspektions-App muss unter solchen Bedingungen zuverlässig funktionieren: bei fehlender stabiler WLAN-Verbindung ebenso wie bei lückenhaftem Mobilfunkempfang in Kellern oder Industriegebieten. Gleichzeitig muss sie eine Karte anzeigen, die tatsächlich dem Grundstück entspricht, auf dem sich der Inspektor gerade befindet.

Wie eine solche App konzipiert werden kann, behandeln wir in diesem Artikel. Dabei betrachten wir GIS und Offline-Funktionalität als grundlegende Anforderungen und nicht als Funktionen, die erst am Ende ergänzt werden. Wir gehen auf Datenmodell, Architektur, Synchronisationslogik und die Abwägungen ein, die Teams bei der Entwicklung kommunaler Inspektionssoftware für den Einsatz vor Ort berücksichtigen müssen.

Warum GIS das Rückgrat und nicht nur eine Funktion ist

Einige Teams behandeln die Karte bei der Entwicklung lediglich als visuelle Ebene, die über einer formularbasierten App liegt. Während dieser Ansatz in anderen Anwendungsfällen funktionieren kann, ist er bei kommunalen Inspektionen vor Ort nicht sinnvoll.

In einer mobilen GIS-Anwendung für den Außeneinsatz ist die Karte das zentrale Instrument, mit dem Inspektoren ihre Aufgaben organisieren und bearbeiten. Ein typischer Ablauf sieht beispielsweise so aus: Ein Inspektor öffnet die App, sieht Grundstücke oder Objekte auf einer Karte, wählt eines davon aus und beginnt mit der Inspektion. Formular, Fotos und Notizen sind dabei vollständig mit diesem räumlichen Kontext verknüpft.

Diese Unterscheidung hat praktische Konsequenzen. Objekte benötigen dauerhafte Identifikatoren, die auch dann unverändert bleiben, wenn sich ihre Geometrie oder Attribute ändern. Jeder Objektdatensatz sollte diesen Identifikator mit einer Punkt-, Linien- oder Polygongeometrie sowie, falls erforderlich, mit der entsprechenden ID aus dem GIS- oder Asset-Management-System der Kommune kombinieren. All diese Aspekte sollten bereits zu Beginn der Entwicklung berücksichtigt werden.

Eine kommunale Inspektions-App benötigt mindestens vier Entitäten: Objekte, Inspektionsvorlagen, Inspektionsdatensätze und Medienanhänge.

Entität Zweck Wichtige Felder
Objekt Das zu inspizierende Objekt ID, Geometrie, Typ, Zuständigkeitsbereich, Status
Inspektionsvorlage Struktur der Checkliste Felder, bedingte Logik, Version
Inspektionsdatensatz Eine abgeschlossene oder laufende Inspektion Objekt-ID, Inspektor-ID, Zeitstempel, Geolokalisierung, Antworten
Medienanhang Fotos oder Dateien, die einem Datensatz zugeordnet sind Anhang-ID, Datensatz-ID, Datei-Hash, lokaler Pfad, Upload-Status, Aufnahmeort, Speicherreferenz

Eine korrekte Versionierung von Vorlagen ist wichtiger, als es zunächst erscheinen mag. Wenn beispielsweise Gesundheitsvorschriften aktualisiert oder neue Gefahrenkategorien hinzugefügt werden, darf sich die Bedeutung älterer Inspektionsdatensätze nicht nachträglich verändern. Das Team von Chudovo ist bei früheren kommunalen Projekten bereits auf dieses Problem gestoßen: Eine Mitte des Jahres geänderte Vorlage führte unbemerkt zu Fehlern in historischen Berichten, weil das Schema nicht versioniert worden war.

Was bei einem Code Review wie ein Sonderfall erscheinen mag, stellt bei einem Compliance-Audit ein reales Risiko dar.

Architekturüberblick

Bei einer praktikablen GIS-Integrationsarchitektur für eine Inspektions-App im Außeneinsatz lassen sich drei Ebenen unterscheiden. Die erste Ebene ist der mobile Client, der Inspektionen und Aufgaben typischerweise in SQLite speichert. SpatiaLite oder OGC GeoPackage können eingesetzt werden, wenn die App auch offline räumliche Abfragen durchführen muss.

Die zweite Ebene ist die Synchronisations-Engine, die für den Umgang mit der Netzwerkverbindung zuständig ist. Änderungen werden lokal in eine Warteschlange gestellt und übertragen, sobald wieder eine Verbindung verfügbar ist. Das kann fünf Sekunden später geschehen – oder erst fünf Stunden später.

Die dritte Ebene umfasst die Backend-GIS- und Inspektionsdienste. Diese basieren auf PostGIS oder einer vergleichbaren räumlichen Datenbank und stellen einen Tile-Server für Kartendaten sowie eine REST- oder GraphQL-API für Inspektionsdatensätze bereit.

Das folgende Diagramm zeigt beispielhaft, wie eine solche Architektur aussehen kann:

Architektur einer GIS-fähigen Offline-Inspektions-App für Kommunen

Entwicklung einer Offline-Inspektions-App: Wo die Synchronisation scheitert

Die Offline-Datensynchronisation klingt in einer Präsentation zunächst einfach. In der Praxis müssen jedoch Konflikte bei Änderungen, unvollständige Uploads, doppelt übermittelte Fotos und Sonderfälle berücksichtigt werden. Dazu gehört beispielsweise die Situation, dass zwei Inspektoren dasselbe Objekt auf unterschiedlichen Geräten bearbeiten, weil ein Vorgesetzter eine Route während der laufenden Schicht neu zugewiesen hat.

Eine sinnvolle Synchronisationsstrategie weist in der Regel jeder Inspektion und jeder in der Warteschlange befindlichen Änderung eine UUID zu. Diese wird auf dem Gerät erzeugt und dient gleichzeitig als Idempotenzschlüssel. Dadurch kann der Server wiederholte Anfragen erkennen, ohne doppelte Datensätze zu erstellen. Anschließend wird jede Änderung in einer lokalen Outbox mit einem Status gespeichert, beispielsweise pending, syncing, failed, conflict, rejected oder synced. Bei einem wiederholbaren Fehler werden außerdem die Anzahl der bisherigen Versuche und der frühestmögliche Zeitpunkt für den nächsten Versuch gespeichert.

Bevor eine Änderung hochgeladen wird, reserviert der Client sie atomar, indem er ihren Status von pending oder failed auf syncing setzt. Einträge, die nach einem Absturz oder einer unterbrochenen Anfrage im Status syncing verbleiben, werden nach Ablauf eines Timeouts wieder in die Warteschlange für erneute Versuche aufgenommen. Jede Anfrage enthält den Idempotenzschlüssel sowie die Version des Serverdatensatzes, auf der die lokale Änderung basiert. Zeitstempel der Datenerfassung und Geräte-IDs können für Audit-Zwecke gespeichert werden. Zur Erkennung paralleler Änderungen verwendet der Server jedoch seine eigenen Versionen.

Der Server prüft anhand der jeweiligen fachlichen Regeln, ob sich Änderungen überschneiden. Sofern zulässig, werden die Änderungen zusammengeführt. Konkurrierende Änderungen an Inspektionsergebnissen, Zuweisungen oder Compliance-Feldern bleiben erhalten und werden zur Überprüfung weitergeleitet, anstatt sich gegenseitig unbemerkt zu überschreiben. Nach der Verarbeitung der Outbox fordert der Client mithilfe eines vom Server bereitgestellten Synchronisations-Cursors Zuweisungen, Objekte, Vorlagen und weitere serverseitige Änderungen an. Eingehende Änderungen werden innerhalb einer lokalen Transaktion übernommen, ohne noch nicht synchronisierte lokale Daten zu überschreiben.

Die Entwickler von Chudovo setzen dies üblicherweise als kleines Queue-Modul um, von dessen interner Funktionsweise der Rest der App kaum etwas wissen muss:

async function syncOutbox(db, api) {
  await db.requeueStaleSyncingRecords();

  const records = await db.getReadyRecords({
    statuses: ['pending', 'failed'],
    before: new Date()
  });

  for (const record of records) {
    const claimed = await db.claimForSync(record.id);

    if (!claimed) {
      continue;
    }

    try {
      const response = await api.submitInspection({
        inspection: record.payload,
        idempotencyKey: record.idempotencyKey,
        baseVersion: record.baseVersion,
        deviceId: record.deviceId,
        capturedAt: record.capturedAt
      });

      if (response.conflict) {
        await db.markConflict(record.id, response.conflictDetails);
      } else {
        await db.markSynced(record.id, response.serverVersion);
      }
    } catch (error) {
      if (isPermanentSyncError(error)) {
        await db.markRejected(record.id, getErrorDetails(error));
      } else {
        await db.scheduleRetry(record.id, {
          retryCount: record.retryCount + 1,
          nextAttemptAt: calculateBackoff(record.retryCount + 1)
        });
      }
    }
  }

  const cursor = await db.getSyncCursor();
  const changes = await api.getChangesSince(cursor);

  await db.applyServerChanges(changes.items);
  await db.saveSyncCursor(changes.nextCursor);
}

Bei einem Timeout oder einem nicht verfügbaren Server sollte der Vorgang mit exponentiellem Backoff wieder in die Warteschlange aufgenommen werden. Eine ungültige Vorlagenversion oder eine fehlgeschlagene Validierung erfordert dagegen das Eingreifen eines Benutzers oder Vorgesetzten. Der Idempotenzschlüssel deckt auch den unklaren Fall ab, in dem der Server eine Anfrage akzeptiert, das Gerät jedoch die Verbindung verliert, bevor es die Antwort erhält.

Für Mediendateien empfiehlt sich eine separate Warteschlange, anstatt sie direkt in den Inspektions-Payload einzubetten. Das bedeutet, dass jeder Anhang eine eigene UUID und weitere Eigenschaften erhält, beispielsweise Datei-Hash, Upload-Status und eine Referenz auf den lokalen Inspektionsdatensatz. Die Synchronisation beginnt mit dem Formular. Sobald diese abgeschlossen ist, zeigt die Benutzeroberfläche beispielsweise den Status „Inspektion synchronisiert, Fotos ausstehend“ an, während größere Dateien im Hintergrund weiter hochgeladen werden.

Damit die App nach jedem Verbindungsabbruch eine 20-MB-Datei nicht vollständig neu übertragen muss, können fortsetzbare oder Multipart-Uploads verwendet werden. Mithilfe des Datei-Hashes kann der Server die Integrität überprüfen und doppelte Übermittlungen erkennen. Nach Abschluss des Uploads übermittelt der Client die entsprechende Speicherreferenz an die Inspektion. Wenn Fotobelege verpflichtend sind, kann die Inspektion als übermittelt gelten, aber unvollständig bleiben, bis alle erforderlichen Anhänge bestätigt wurden.

GPS im Außeneinsatz ist komplexer, als es scheint

GPS-basierte Inspektionen wirken auf dem Papier präzise, doch die Positionsgenauigkeit kann sich in der Nähe hoher Gebäude, unter dichtem Baumbestand und innerhalb von Gebäuden deutlich verschlechtern. Dadurch kann ein Inspektionspunkt mehrere Meter vom tatsächlichen Objekt entfernt liegen.

Um dieses Problem zu berücksichtigen, kann das System die ursprünglichen Koordinaten zusammen mit der gemeldeten Genauigkeit speichern, sodass nachgelagerte Systeme Positionsdaten mit geringer Zuverlässigkeit erkennen können. Wenn die Position offensichtlich falsch ist, kann der Inspektor den Marker an die richtige Stelle verschieben. Sowohl die ursprüngliche Messung als auch die korrigierte Position bleiben dabei für Audit-Zwecke erhalten.

Beginnt eine Inspektion bei einem bereits bekannten Objekt, kann die Benutzeroberfläche sie direkt mit dessen Geometrie verknüpfen. Die im Außeneinsatz erfassten ursprünglichen GPS-Daten sollten dadurch jedoch nicht überschrieben werden.

Abwägungen und Einschränkungen

Wie bei jeder Softwareentwicklung ist auch hier keine Architektur ohne Nachteile. Eine Local-First-Datenspeicherung erhöht zwar die Zuverlässigkeit, macht Schemaänderungen jedoch komplexer, da Migrationen sicher auf allen eingesetzten Geräten durchgeführt werden müssen und nicht nur in einer zentralen Datenbank.

Durch vollständiges Offline-Caching von Karten können Inspektoren auch ohne Netzabdeckung weiterarbeiten. Der Preis dafür sind höhere Speicheranforderungen sowie die Notwendigkeit eines klar definierten Prozesses für Tile-Updates, damit zwischengespeicherte Karten nicht veralten.

Ein Systemdesign mit versionsbasierter Konflikterkennung schützt Inspektionsergebnisse davor, unbemerkt überschrieben zu werden. Gleichzeitig erfordert es zusätzliche serverseitige Logik und einen Prüfprozess für Änderungen, die nicht automatisch zusammengeführt werden können.

Keine dieser Entscheidungen ist für sich genommen ein Ausschlusskriterium. Es ist jedoch sinnvoll, sie bereits in einer frühen Phase zu berücksichtigen. Werden solche Entscheidungen aufgeschoben, zeigen sich die Lücken häufig erstmals während eines Pilotprojekts – etwa in Form eines Screenshots eines Inspektors, dessen Änderung verschwunden ist.

Sicherheits- und Zugriffsaspekte

Kommunale Daten enthalten häufig Informationen, die nicht öffentlich zugänglich sein sollten. Dazu gehören beispielsweise noch nicht behobene Verstöße gegen Vorschriften, Standorte sensibler Infrastruktur und Details zu Bürgerbeschwerden, die mit einer bestimmten Adresse verknüpft sind.

Eine angemessene rollenbasierte Zugriffskontrolle auf API-Ebene sollte bei jeder Smart-City-Inspektionssoftware standardmäßig vorgesehen sein. Eine gesperrte Ansicht innerhalb der mobilen App reicht nicht aus, da sie niemanden daran hindert, direkt auf die API zuzugreifen.

Ein Gerät kann außerdem verloren gehen oder gestohlen werden. Um kommunale Informationen in solchen Fällen zu schützen, sollten auch die auf dem Gerät gespeicherten Daten verschlüsselt werden.

Einordnung in einen umfassenderen Rollout

Eine GIS-Inspektions-App für die Kontrolle kommunaler Objekte wird nur selten als eigenständige Lösung eingeführt. In der Regel ist sie mit einem Bürgerportal für Meldungen, einem Asset-Management-System und manchmal auch mit einer älteren Genehmigungsdatenbank verbunden, die niemand anfassen möchte. Das Team von Chudovo hat für Kunden aus dem öffentlichen Sektor bereits vergleichbare Integrationen umgesetzt und Daten aus Vor-Ort-Inspektionen mit bestehenden kommunalen Asset-Management-Plattformen verbunden, damit die Inspektions-App nicht zu einem weiteren Datensilo wird.

Der operative Ablauf geht jedoch über die eigentliche Inspektion hinaus. Eine nicht bestandene Prüfung kann einen Fall oder Arbeitsauftrag für die zuständige Abteilung auslösen. Dringende Feststellungen können einem separaten Eskalationsprozess folgen. Nach der Behebung überprüft eine Folgeinspektion das Ergebnis, das anschließend in die Historie des jeweiligen Objekts aufgenommen werden muss.

Auch Bürgerberichte können in denselben Workflow einfließen. Das System sollte jedoch ihre Herkunft beibehalten und den entsprechenden Validierungsprozess anwenden, bevor kommunale Arbeiten zugewiesen werden.

Tests der App vor dem Einsatz im Außendienst

Ein häufiger Fehler von Entwicklungsteams besteht darin, eine App bereits nach einigen Tests am Schreibtisch als vollständig validiert zu betrachten. Während dies in anderen Fällen ausreichen kann, muss eine Offline-Inspektions-App unter Bedingungen getestet werden, die die Unterbrechungen eines normalen Arbeitstags von Inspektoren nachbilden. Dafür ist es nicht zwingend erforderlich, selbst nach draußen zu gehen und den Arbeitsablauf eines Inspektors nachzustellen – auch wenn das natürlich möglich ist. Ein sinnvoller Ausgangspunkt zur Simulation solcher Bedingungen am Arbeitsplatz ist folgendes Szenario:

  • Eine zugewiesene Route herunterladen
  • Flugmodus aktivieren
  • Mehrere Inspektionen durchführen und Fotos anhängen
  • Die App schließen
  • Das Gerät neu starten

Wenn alles wie erwartet funktioniert, sollten anschließend sowohl alle noch nicht abgeschlossenen als auch alle bereits abgeschlossenen Arbeiten weiterhin verfügbar sein.

Eine umfassende Testsitzung sollte außerdem berücksichtigen, was passiert, wenn die Synchronisation in unterschiedlichen Phasen unterbrochen wird. Relevante Fragen sind beispielsweise: Was passiert, wenn die Verbindung während des Uploads eines Fotos abbricht? Was passiert, wenn der Server eine Inspektion akzeptiert, die Antwort das Gerät jedoch nie erreicht? In beiden Fällen ist das erwartete Verhalten eindeutig: Eine Wiederholung der Anfrage darf keinen zweiten Datensatz erzeugen. Weitere Testszenarien sollten Sonderfälle wie abgelaufene Authentifizierungstoken, ein Vorlagen-Update bei gleichzeitig noch nicht abgeschlossener älterer Inspektion sowie die Bearbeitung desselben Datensatzes auf zwei Geräten auf Basis unterschiedlicher Ausgangsversionen abdecken.

GPS-Tests sollten in offenen Bereichen, dicht bebauten Straßen und an Orten mit schwachem Satellitenempfang durchgeführt werden, anstatt sich auf eine einzelne Messung vor dem Entwicklungsbüro zu verlassen. Zwischengespeicherte Grundstücke, Straßen und kommunale Objekte sollten auf allen erforderlichen Zoomstufen sichtbar bleiben. Die App benötigt außerdem ein klares Verhalten für den Fall, dass eine Aufgabe außerhalb des heruntergeladenen Kartenbereichs liegt oder ein zwischengespeichertes Kartenpaket veraltet ist.

Während eines vollständigen Arbeitstags im kommunalen Außendienst können Dutzende Fotos entstehen. Dadurch werden Speicherplatz, Akkulaufzeit und Hintergrundverarbeitung dauerhaft beansprucht. Tests sollten deshalb Situationen mit wenig verfügbarem Speicher, Einschränkungen des Betriebssystems für Hintergrundprozesse sowie große Warteschlangen simulieren, die gleichzeitig wieder eine Verbindung herstellen.

Vor einer Ausweitung des Rollouts empfiehlt sich ein Pilotprojekt mit Inspektoren aus verschiedenen Abteilungen. Dabei können Kennzahlen wie Alter der Warteschlange, fehlgeschlagene Uploads, Häufigkeit von Konflikten, Größe der Kartendownloads und Akkuverbrauch erfasst werden. Die Protokolle sollten erkennen lassen, welcher Vorgang fehlgeschlagen ist, ohne Details zu Beschwerden oder andere sensible Daten offenzulegen. Die erste Version ist erst dann für eine breitere Einführung bereit, wenn Inspektoren ihre Schicht beenden können, ohne sich fragen zu müssen, ob ihre Arbeit tatsächlich gespeichert wurde.

Fazit

Eine kommunale Inspektions-App bewährt sich im Außeneinsatz, wenn Offline-Funktionalität und räumliche Daten als grundlegende Anforderungen behandelt werden und nicht als Einstellungen, die später konfiguriert werden können. Das Datenmodell sollte auch Änderungen an Vorlagen während des laufenden Jahres zuverlässig abbilden. Ebenso sollte bereits vor dem Produktiveinsatz berücksichtigt werden, dass zwei Inspektoren gleichzeitig dasselbe Objekt bearbeiten können. GPS-Daten aus dem Außeneinsatz sind zudem deutlich ungenauer, als es eine Demo-Umgebung vermuten lässt.