Open data, PostGIS & Node.js

Hoe maak je van ruwe open data een interactief online dashboard?

Een volledige workflow met QGIS, PostgreSQL/PostGIS, Node.js, Leaflet en Chart.js voor een ongevallendashboard.

Illustratie bij Hoe maak je van ruwe open data een interactief online dashboard?

De use case: een ongevallendashboard per gemeente

Voor dit voorbeeld gebruikte ik publiek beschikbare gegevens over verkeersongevallen in Vlaanderen in 2023 en 2024.

In dit artikel neem ik je mee door het volledige proces: van het verzamelen en verrijken van de data tot het bouwen en online publiceren van het dashboard. Daarbij komen verschillende tools en technologieën aan bod, waaronder QGIS, PostgreSQL/PostGIS, Neon, Node.js, Express, Leaflet en Chart.js.

Het resultaat is een interactief dashboard dat niet alleen toont waar ongevallen plaatsvinden, maar ook helpt om sneller patronen en inzichten te ontdekken in publieke data. En dat allemaal met — relatief eenvoudige — open-sourcetools, aangevuld met AI als productiviteitshulp tijdens het ontwikkelproces.

Het doel van deze demo was niet alleen om een kaart met ongevallenpunten te tonen. Ik wilde vooral aantonen hoe je van losse databestanden naar een bruikbaar monitoringdashboard gaat.

In het dashboard kan een gebruiker een gemeente zoeken en daarna meteen de bijhorende ongevallendata bekijken. De toepassing toont onder meer de gemeentegrens, de ongevallenpunten, het aantal ongevallen, ongevallen per 1.000 inwoners, de straat met de meeste ongevallen en verschillende grafieken.

Het voorbeeld gebruikt verkeersongevallen, maar dezelfde aanpak kan ook toegepast worden op verkoopcijfers, klantenlocaties, leveringsstromen, meldingen, patrimoniumbeheer, productflows of interne bedrijfsprocessen.

💡
Kort samengevat
Ik verzamelde open data over verkeersongevallen, wegen, gemeentegrenzen en bevolking. Daarna schoondde ik de data op in QGIS, verrijkte ik de ongevallenpunten met straatnamen, sloeg ik de data op in een lokale PostgreSQL/PostGIS-databank en testte ik de nodige SQL-query’s. Vervolgens bouwde ik in Visual Studio Code een Node.js-app met Express-routes en API’s voor kaartlagen, filters, KPI’s en grafieken. Daarna zette ik de databank online via Neon, verbond ik de app met de online databank en publiceerde ik het dashboard als interactieve demo.

De workflow in tien stappen

1. Data verzamelen

Open data verzamelen via Statbel en Datavindplaats: ongevallen, wegenregister, gemeentegrenzen en bevolkingsstatistieken.

2. Opschonen

Onnodige velden verwijderen, datatypes afstemmen en ongevallenpunten verrijken met straatnamen.

3. Data opslaan

De voorbereide datasets via QGIS importeren naar een lokale PostgreSQL/PostGIS-databank.

4. Query’s testen

SQL-query’s testen voor gemeentegrenzen, ongevallenpunten, KPI’s, filters en grafieken.

5. Node.js-app ontwikkelen

De applicatie bouwen in Visual Studio Code met Node.js, Express, API-routes, Leaflet en Chart.js, met AI als productiviteitshulp.

6. Online databank aanmaken

Een online PostgreSQL-databank aanmaken in Neon en PostGIS activeren.

7. Lokale databank exporteren

Een databankdump maken met pg_dump om de lokale PostgreSQL/PostGIS-databank over te zetten.

8. Dump importeren

De lokale dump importeren in Neon met pg_restore.

9. App verbinden

De Node.js-app verbinden met Neon via een environment variable en een veilige databaseverbinding.

10. App online zetten

De toepassing publiceren en het dashboard online beschikbaar maken.

1) Data verzamelen

De eerste stap was het verzamelen van de nodige brondata. Voor deze demo gebruikte ik verschillende open databronnen. In de tabel hieronder staat per dataset waarvoor ik ze gebruikte en waar de brondata terug te vinden is.

DatasetBronGebruik in het dashboard
VerkeersongevallenStatbel · geolocalisatie van verkeersongevallen 2017-2024 Basislaag met ongevallen en coördinaten.
WegenregisterDigitaal Vlaanderen · Wegenregister Verrijking van ongevallenpunten met straatnamen.
Gemeentegrenzengeo.api.vlaanderen.be/VRBG/wfs Zoeken en tonen van de geselecteerde gemeente.
BevolkingsstatistiekenStatbel · bevolkingsdichtheid en bevolkingsstructuur Berekening van ongevallen per 1.000 inwoners.
Belangrijk: een dashboard begint niet bij grafieken of design, maar bij het begrijpen van de brondata, de definities, de datakwaliteit en de gewenste analyses.
2) Data opschonen en verrijken in QGIS

Na het verzamelen van de data begon de voorbereiding in QGIS. De ongevallenlijst bevatte heel wat velden die voor deze demo niet nodig waren. Die overbodige velden heb ik verwijderd om de dataset overzichtelijker te maken.

Omdat de ongevallen coördinaten bevatten, kunnen ze naar punten op een kaart getransformeerd worden. Eens ingeladen in QGIS, heb ik daarna de ongevallenpunten ruimtelijk gekoppeld aan het wegenregister. Zo kon ik de dataset verrijken met straatnamen.

Ook de gemeentegrenzen en bevolkingsstatistieken moesten op elkaar afgestemd worden. Beide datasets bevatten een veld NISCODE. Door veldnamen en datatypes gelijk te zetten, wordt de latere koppeling eenvoudiger en betrouwbaarder.

Opmerking: ETL processen deed ik via QGIS, maar dit had evengoed ook via FME, Python of andere tools gekund.
3) Data opslaan in lokale PostgreSQL/PostGIS

Na de voorbereiding heb ik de opgeschoonde en verrijkte data via QGIS geïmporteerd naar een lokale PostgreSQL-databank met PostGIS.

PostGIS maakt van PostgreSQL een ruimtelijke databank. Daardoor kan je geometrieën opslaan, ruimtelijke analyses uitvoeren en data voorbereiden voor gebruik in een webkaart. Voor organisaties betekent dit dat data niet langer vastzit in losse bestanden, maar terechtkomt in een centrale, bevraagbare databank die geschikt is voor API’s, dashboards en automatisering.

4) Query’s testen voor kaart, KPI’s en grafieken

Voor ik de databank online zette, testte ik lokaal de query’s die ik later in de Node.js-app zou gebruiken. Denk aan het ophalen van gemeenten en hun grenzen, ongevallenpunten, straatinformatie, totalen per gemeente en gegevens voor grafieken en trends. Hiervoor gebruik ik meestal via de open-source databasetool DBeaver. Ik gebruik het voor aanpassingen/controles op datatypes, joins, aantallen records en SQL-queryresultaten. Deze controle is belangrijk. Een dashboard kan er visueel mooi uitzien, maar als de onderliggende data verkeerd geïnterpreteerd wordt, zijn de inzichten niet betrouwbaar.

5) De Node.js-app ontwikkelen in Visual Studio Code

Nadat de belangrijkste SQL-query’s lokaal getest waren, begon ik met de ontwikkeling van de Node.js-app. Die applicatie bouwde ik in Visual Studio Code, met Node.js en Express als basis. Het doel was om geen statische kaart te maken, maar een echte webapplicatie waarin de gebruiker een gemeente kan zoeken en daarna automatisch de juiste kaartlagen, KPI’s, tabellen en grafieken te zien krijgt.

De app bestaat grofweg uit twee delen. Aan de backend-kant zorgt Node.js ervoor dat de juiste data uit PostgreSQL/PostGIS wordt opgehaald. Aan de frontend-kant worden die gegevens getoond op een interactieve Leaflet-kaart en in grafieken via Chart.js. De frontend maakt dus niet rechtstreeks verbinding met de databank, maar vraagt data op via zelfgemaakte API-routes.

In Express maakte ik verschillende routes en API-endpoints aan. Zo kan de applicatie bijvoorbeeld een lijst met gemeenten ophalen, de grens van een geselecteerde gemeente tonen, ongevallenpunten binnen die gemeente opvragen en statistieken berekenen voor KPI’s en grafieken.

/api/gemeenten
/api/gemeente/:naam
/api/ongevallen/:gemeente
/api/statistieken/trends/:gemeente

Elke API-route heeft een duidelijke taak. Sommige routes geven GeoJSON terug voor de kaart, andere routes leveren samengevatte cijfers voor de dashboardkaarten of datasets voor grafieken. Daardoor blijft de applicatie overzichtelijker: de database doet het zware rekenwerk met SQL en PostGIS, terwijl Node.js de resultaten netjes doorgeeft aan de frontend.

Over het maken van API’s schreef ik eerder al een apart artikel op mijn blog: API’s maken en ernaar connecteren . In dit dashboard paste ik hetzelfde principe toe: je maakt gestructureerde eindpunten waar je frontend veilig en voorspelbaar data kan ophalen.

Ik moet daar ook eerlijk in zijn: bij het ontwikkelen van deze demo heb ik veel hulp gehad van AI. Zonder AI zou het veel langer geduurd hebben om alle nodige code voor zo’n applicatie volledig uit te schrijven. Data manipuleren, uitzoeken welke gegevens waar zitten, bepalen welke tabellen en velden met elkaar gecombineerd moeten worden, SQL-query’s testen, JavaScript aanpassen, HTML finetunen en de applicatie stap voor stap verbeteren: dat doe ik graag. Maar de volledige Node.js-app helemaal vanaf nul uitschrijven zonder AI? Nee, dan had ik deze demo waarschijnlijk niet op deze manier kunnen maken.

Voor mij toont dit net de kracht van AI in zo’n ontwikkelproces. AI neemt het denkwerk niet volledig over, maar helpt wel om sneller codevoorstellen te maken, fouten op te sporen, routes op te bouwen, API’s te structureren en bestaande code te verbeteren. Daardoor kan je productiever werken en sneller van een idee naar een werkende demo gaan.

6) Online PostgreSQL-databank aanmaken in Neon

Omdat de demo online moest draaien, had de Node.js-app ook online toegang nodig tot de databank. Een lokale PostgreSQL-databank is handig tijdens ontwikkeling, maar niet geschikt voor een publieke online demo.

En aangezien het om een hobbyproject gaat, wou ik ook niet meteen een betalende databankoplossing gebruiken. Ik zocht naar gratis of betaalbare PostgreSQL-services en kwam uiteindelijk uit bij Neon, een online PostgreSQL-platform waarmee je snel een PostgreSQL-databank beschikbaar maakt voor een gehoste webapplicatie. Bij Neon zit je data in een cloudomgeving bij AWS.

Omdat mijn data geometrieën bevat, activeerde ik ook in Neon PostGIS:

CREATE EXTENSION IF NOT EXISTS postgis;
Belangrijk: activeer PostGIS vóór je een dump met geometriekolommen importeert. Anders kan de restore falen op ruimtelijke types.
7) Lokale databank exporteren met pg_dump

Daarna maakte ik een dump van mijn lokale databank. Op Windows kan dat bijvoorbeeld via PowerShell.

& "C:\Program Files\PostgreSQL\18\bin\pg_dump.exe" `
-h localhost `
-p 5432 `
-U postgres `
-d verkeersongevallen `
-F c `
-f "$env:XXXXX\verkeersongevallen.dump"
Goed om te weten: een dump is een momentopname. Als je later lokaal data wijzigt, moet je opnieuw een dump maken en importeren.
8) Dump importeren naar Neon met pg_restore

Ik zette de lokale dump online in Neon met pg_restore. Voor het importeren gebruikte ik de directe Neon-connection string.

& "C:\Program Files\PostgreSQL\18\bin\pg_restore.exe" `
-v `
-O `
--no-privileges `
--no-tablespaces `
-d "postgresql://neondb_username:WACHTWOORD@ep-xxxx.eu-central-1.aws.neon.tech/neondb?sslmode=require" `
"$env:USERPROFILE\Documents\verkeersongevallen.dump"

De opties -O, --no-privileges en --no-tablespaces vermijden dat lokale gebruikers, rechten of tablespaces letterlijk moeten bestaan in Neon.

Voor de import gebruikte ik de directe host. Voor de Node.js-app zelf is de pooled host nuttig, omdat een webapplicatie vaak veel korte connecties maakt.

9) Node.js-app verbinden met de online databank

Toen de databank online stond, kon de Node.js-app verbinden met Neon via een environment variable (.env).

DATABASE_URL=postgresql://neondb_username:WACHTWOORD@ep-xxxx-pooler.eu-central-1.aws.neon.tech/neondb?sslmode=require

De app gebruikt API-routes om data op te halen voor de kaart, filters, KPI’s en grafieken. De frontend maakt dus geen rechtstreekse verbinding met de databank.

10) App online zetten

De laatste stap was het online plaatsen van de Node.js-app. Het resultaat is een online dashboard hier op mijn blog waarin gebruikers per gemeente verkeersongevallen kunnen bekijken, filteren en analyseren.

Conclusie

Dit project toont hoe je van ruwe open data naar een bruikbaar online dashboard kan gaan. De belangrijkste stap is niet het maken van grafieken, maar het opzetten van een goede dataflow: verzamelen, opschonen, opslaan, query’s testen, API’s bouwen, verbinden en publiceren.

Door QGIS, PostgreSQL/PostGIS, Neon en Node.js te combineren, kon ik een flexibel dashboard bouwen zonder afhankelijk te zijn van een klassiek BI-platform.

Tegelijk toont deze demo ook hoe AI het ontwikkelproces kan versnellen. Niet door de inhoudelijke kennis over data, GIS of analyse te vervangen, maar wel door te helpen bij het schrijven, testen en verfijnen van code. Daardoor kan je sneller experimenteren, sneller fouten opsporen en sneller tot een werkend prototype komen.

Dezelfde aanpak is bruikbaar voor veel andere toepassingen: verkoop per regio, klantenkaarten, meldingen, leveringsstromen, infrastructuurbeheer, terreinopvolging of interne KPI-monitoring.

Bekijk het eindresultaat

Test zelf het interactieve ongevallendashboard.

Open het dashboard

QGISPostGISNode.jsLeafletChart.jsOpen data
Arnout Verhoeve
Over de auteur

Arnout Verhoeve

GIS-deskundige, data engineer en webdeveloper met meer dan vijftien jaar ervaring in geodata, databanken en webtechnologie.

Lees het profiel →
Samenwerken

Ook van ruwe data naar een bruikbare toepassing?

Vertel welke data vandaag verspreid zit en wat je ermee wilt opvolgen of beslissen. Samen bepalen we een haalbare eerste versie.