Omnigraph
Graph engine for context assembly. Object-storage native. Agents work with graph data the way engineers work with code: branched, typed, reviewed, merged, audited, and governed.
Interaktive Karte der Verkehrsunfälle 2017–2025 aus dem Unfallatlas — filterbar nach Schwere, Beteiligung, Unfalltyp und Jahr, mit OSM-Kontextlayern und Analyse-Szenarien.
Translation pending
DataJavaScript · PythonGitHub @vizsimOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Interaktive Webkarte für Verkehrsunfälle in Deutschland. Über 2,2 Millionen polizeilich erfasste Unfälle mit Personenschaden aus den Jahren 2017–2025 — filterbar nach Schwere, Unfallart, Unfalltyp, Jahr und Beteiligung, und kombinierbar mit Kontextdaten: Schulen, Tempolimits, Verkehrsmengen, Lärm, Radinfrastruktur.Read the full README ↗
Interaktive Webkarte für Verkehrsunfälle in Deutschland. Über 2,2 Millionen polizeilich erfasste Unfälle mit Personenschaden aus den Jahren 2017–2025 — filterbar nach Schwere, Unfallart, Unfalltyp, Jahr und Beteiligung, und kombinierbar mit Kontextdaten: Schulen, Tempolimits, Verkehrsmengen, Lärm, Radinfrastruktur.
Darüber hinaus rechnet die Pipeline Szenarien: Fragen an die Daten, die man auf der Karte sonst nur ahnen kann — wo häufen sich Unfälle im Schulumfeld, wo unterbricht ein kurzes Tempo-50-Stück eine sonst durchgängige 30er-Zone, wo liegen Unfallhäufungen nach den Kriterien der Unfallkommissionen.
Die Unfälle lassen sich auch herunterladen: aus der Karte der aktuelle Ausschnitt als GeoJSON oder CSV, und alle Jahre 2016–2025 als eine GeoParquet-Datei auf data.vizsim.de/unfallorte — direkt aus dem Netz abfragbar, etwa mit DuckDB.
Quelle der Unfalldaten ist der Unfallatlas der Statistischen Ämter (dl-de/by-2-0). Rohdaten und OpenStreetMap werden zu PMTiles verarbeitet und in einer MapLibre-Karte gezeigt — ausschließlich über offene, frei gehostete Dienste, ohne kommerzielle Karten-API und ohne API-Key.
👉 vizsim.de/unfallkarte — die Karte
👉 data.vizsim.de/unfallorte — alle Unfälle als Datei, mit Anleitung
Zwei Teile in einem Repo:
pipeline/ — Python-Pipeline (uv): lädt Unfalldaten (2016–2025) und OSM, baut
PMTiles, rechnet die Szenarien, deployt nach Backblaze B2 und veröffentlicht alle Unfälle
als GeoParquet auf data.vizsim.de. Details und CLI: pipeline/README.md.index.html, main.js, js/), gebaut mit
Vite nach dist/. Die PMTiles kommen local-first aus data/, sonst per
B2-Fallback; gesteuert über ein generiertes manifest.json.Jede Zeile der Legende entspricht genau einem Eintrag in der Layer-Registry
(js/layers/): Quelle, Layer-Definitionen, Popup, Permalink-Zeichen und Legendentext
stehen dort an einer Stelle statt über acht Dateien verteilt.
Jedes Szenario verschneidet die Unfall- oder OSM-Daten mit einer Kontextebene. Die Schwellenwerte lassen sich in der Legende per Regler verändern.
| Was es zeigt | |
|---|---|
| sc1 | Unfall-Cluster auf Tempo-100-Straßen (DBSCAN, eps 50 m, min. 3 Unfälle) |
| sc2 | Unfälle im Schulumfeld (50 m Umkreis, Rad- und Fußunfälle ab 2020) |
| sc3 | Lücken in Tempo 30: kurze 50er-Abschnitte (< 400 m) zwischen 30er-Zonen |
| sc6 | Tempo 50 direkt vor Schulen (30 m Umkreis, ab 60 m Länge) |
| sc8 | Straßenlärm an Schulen (UBA-Lärmkartierung, Lden > 56 dB) |
| sc9 | Unfallhäufungen nach M-Uko-Kriterien (vereinfacht: 3-Jahres-Fenster + DBSCAN) |
Hinweis: sc9 bildet die Kriterien der Unfallkommissionen nach, ersetzt aber keine amtliche Feststellung — ob eine Stelle ein Unfallschwerpunkt ist, entscheidet die zuständige Unfallkommission.
Der Export in der Karte liest dieselbe Datei per HTTP-Range — einen Server dafür gibt es nicht. Beides ist eine Aufbereitung, kein amtlicher Datensatz (Lizenz dl-de/by-2-0, Quellenvermerk nötig). Die Karte zeigt 2017–2025; 2016 steht nur in der Datei.
Einzige Ausnahme: der optionale Mapillary-Layer braucht einen Mapillary-Client-Token
(.env.production, öffentlich by design — er steht ohnehin im ausgelieferten JS).
Pipeline-Secrets wie die B2-Keys liegen ausschließlich in pipeline/.env (gitignored).
npm install # einmalig: Vite, Playwright und die Karten-Libs
npm run dev # Dev-Server mit Hot-Reload -> http://localhost:5173
npm run build # Produktions-Build nach dist/
npm run preview # dist/ ausliefern -> http://127.0.0.1:4173
Ungebaut läuft das Repo-Root nicht mehr (die Module importieren maplibre-gl und pmtiles
aus npm) — immer über npm run dev bzw. den Build.
Deinen lokalen Mapillary-Token legst du in .env.development.local ab
(VITE_MAPILLARY_TOKEN=…, gitignored); ohne ihn bleibt nur der Mapillary-Layer leer. Der
Build nimmt den öffentlichen Token aus .env.production.
Local-first: liegt ein data/-Verzeichnis vor (typischerweise ein Symlink auf
pipeline/data/), kommen die PMTiles von dort — sonst automatisch aus dem B2-Bucket. Du
brauchst also keine lokalen Daten, um am Frontend zu arbeiten. Dev-Server und Preview
liefern data/ mit Range-Requests aus (Middleware in vite.config.js); ins dist/ kommt es
nie.
Exakt gepinnt in package.json. Upgrade = npm i -E [email protected], danach immer
npm run test:web — die letzten beiden MapLibre-Upgrades haben den Cluster-Hover still
gebrochen, gefangen hat es jeweils nur der Smoke-Test.
MapLibre wird nicht gebündelt. Es sucht seinen Worker zur Laufzeit neben der eigenen
Datei; gebündelt fände es ihn nicht (die Karte bleibt ohne jeden Fehler leer). Der Build
kopiert darum die drei .mjs nach dist/lib/maplibre-gl@<version>/ und löst den Import per
Importmap auf (vite.config.js). Alle Module importieren MapLibre über js/lib/maplibre.js.
pmtiles wird mitgebündelt, chart.js kommt als eigener Chunk erst beim ersten Uspeed-Chart,
der Export (hyparquet + fzstd) erst beim ersten Klick auf das Download-Symbol.
npm run test:unit # browserlos (node --test), Sekunden
npm run test:web # Frontend im Browser (Playwright, headless Chromium)
uv --directory pipeline run pytest # Pipeline (Dry-Run, keine Daten nötig)
(cd pipeline && uvx ruff check) # Lint
Die Browser-Tests in tests/web/ fahren die echte Seite: Lädt die Karte ohne JS-Fehler?
Liefert der Cluster-Hover das vergrößerte Tortendiagramm? Erscheint bei überlappenden
Objekten genau ein gestapeltes Popup? Überlebt ein Permalink das Kopieren und
Neuladen samt Reglern? Sie bauen dist/ und testen genau diesen Stand (vite preview),
nutzen Local-first/B2 wie im Betrieb und brauchen also keine lokalen Daten. Der Export-Test
liefert eine kleine Testdatei (tests/fixtures/export/) selbst mit Range-Antworten aus.
Zwei Tests sind das eigentliche Sicherheitsnetz für Umbauten:
golden.spec.js hält Quellen, alle Layer-Definitionen und das Verhalten jedes
Toggles über drei Zoomstufen als Snapshot fest. Nach einem Refactor muss er
unverändert grün sein; gewollte Änderungen mit --update-snapshots aufnehmen und den
Diff Zeile für Zeile prüfen.contract.spec.js liest die Metadaten der echten PMTiles und prüft jeden
source-layer und jedes im Style benutzte Attribut. Nötig, weil MapLibre bei PMTiles
nicht validiert — der Test fand auf Anhieb zwei Bugs, die monatelang unbemerkt waren.Alles läuft in der CI (.github/workflows/ci.yml). Vor jedem Lib-Upgrade laufen
lassen.
Ausführlich in pipeline/README.md. Kurzform:
cd pipeline
uv sync
uv run unfallkarte accidents fetch && uv run unfallkarte accidents build
uv run unfallkarte accidents tiles data/accidents/accidents_germany_2017-2025_oid.parquet
uv run unfallkarte osm fetch && uv run unfallkarte osm build all
uv run unfallkarte scenario run-all
uv run unfallkarte manifest && uv run unfallkarte deploy
uv run unfallkarte publish build && uv run unfallkarte publish deploy # data.vizsim.de/unfallorte
Ein neues Unfalljahr ist ein YAML-Block in pipeline/config/accidents.yaml — kein
Code-Edit. Jahre mit karte: false (derzeit 2016) gehen nur in die Veröffentlichung. Kontextlayer analog: uv run unfallkarte <hvs|laerm|obs|telraam> fetch|build
bzw. movebis build und census build (Zensus aus Archivkopien in data/raw/census/).
System-Binaries (nicht über pip): tippecanoe und tile-join, osmium-tool; die b2-CLI
über uv tool install b2. (ogr2ogr/gdal-bin wird nicht gebraucht — OSM-PBF liest
pyogrio direkt.)
main ist Arbeits- und Deploy-Branch: nach jedem Push baut die CI dist/, testet
genau diesen Stand und veröffentlicht ihn auf GitHub Pages — nur wenn die Frontend-Tests
grün sind (ein paar Minuten nach dem Push). Größere Umbauten laufen über einen
temp/*-Branch und werden erst nach grünen Tests gemergt. Der Stand vor dem
Pipeline-Refactor hängt als Tag v2025, der letzte Stand vor Vite als Tag pre-vite.
Die PMTiles liegen nicht im Git (data/ ist gitignored), sondern lokal und im
öffentlichen B2-Bucket. Ein Code-Deploy und ein Daten-Deploy
(uv run unfallkarte deploy) sind zwei getrennte Vorgänge; die Veröffentlichung auf
data.vizsim.de (publish deploy, eigener Bucket) ist ein dritter.
docs/TODO.md — alle offenen Punkte (UX, CI, Pipeline, Aufräumen);
Erledigtes mit Datum und Begründung in docs/DONE.md.docs/REFACTORING_PLAN.md — reine Historie: was beim Umbau von
Notebooks zur Pipeline entschieden wurde und warum (CRS-Disziplin, Bucket-Struktur,
Local-first, keyless Basemap, AGPL). Keine offenen Punkte mehr.docs/MLT_EVALUATION.md — Unfall-Kacheln als MLT: Messungen,
Entscheidung, offene Nacharbeiten.docs/PERFORMANCE_PLAN.md (Stufen, Ergebnisse,
Messmethode) und docs/PERFORMANCE_REPORT_2026-09-24.md
(Maßnahmenkatalog, Vergleich mit OpenTrailMap).CLAUDE.md — Regeln und Konventionen für die Arbeit im Repo.MapLibre GL JS · PMTiles · GeoParquet + hyparquet · Terra Draw · Vite · tippecanoe · osmium-tool · GeoPandas/pyogrio (Python-Pipeline mit uv) · DuckDB (Tests) · OpenFreeMap · Mapterhorn · Backblaze B2 · Photon · radinfra.de/TILDA.
AGPL-3.0-or-later © vizsim. (Früher MIT — bereits unter MIT veröffentlichte Stände bleiben MIT, künftige Versionen sind AGPL.) Der Quellcode-Link im UI erfüllt die AGPL-§13-Pflicht bei Netzwerknutzung.
Daten behalten ihre eigenen Lizenzen und Attribution: Unfallatlas (dl-de/by-2-0), OpenStreetMap (ODbL), Umweltbundesamt (Lärm, Verkehrsmengen), OpenFreeMap (ODbL), Mapterhorn, Mapillary, radinfra.de/TILDA, Telraam (CC BY-NC).