Blog • Open data • PostgreSQL • PostGIS • Neon • Node.js • QGIS
Van ruwe data naar GEO dashboard met QGIS, PostGIS, Neon en Node.js
Open data is vandaag overal beschikbaar. Overheden en organisaties publiceren enorme hoeveelheden gegevens die vrij kunnen worden gedownload en hergebruikt. Maar wie ooit een dataset heeft geopend, weet dat de realiteit vaak minder aantrekkelijk is: eindeloze Excel-bestanden met duizenden rijen data waaruit het niet altijd eenvoudig is om patronen, trends of bruikbare inzichten te halen.
Net daar ligt de kracht van datavisualisatie. Door gegevens om te zetten naar kaarten, grafieken, diagrammen en interactieve filters worden cijfers plots veel toegankelijker en betekenisvoller. Wat in een spreadsheet verborgen blijft, springt in een dashboard vaak meteen in het oog. Omdat ik nu eenmaal graag met data, kaarten en technologie experimenteer, besloot ik een praktijkgerichte demo uit te werken. Lees verder en volg stap voor stap hoe ik ruwe open data omzet in een interactief geografisch dashboard waarmee je ongevallen kunt verkennen, filteren en analyseren.
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.
De workflow in tien stappen
Open data verzamelen via Statbel en Datavindplaats: ongevallen, wegenregister, gemeentegrenzen en bevolkingsstatistieken.
Onnodige velden verwijderen, datatypes afstemmen en ongevallenpunten verrijken met straatnamen.
De voorbereide datasets via QGIS importeren naar een lokale PostgreSQL/PostGIS-databank.
SQL-query’s testen voor gemeentegrenzen, ongevallenpunten, KPI’s, filters en grafieken.
De applicatie bouwen in Visual Studio Code met Node.js, Express, API-routes, Leaflet en Chart.js, met AI als productiviteitshulp.
Een online PostgreSQL-databank aanmaken in Neon en PostGIS activeren.
Een databankdump maken met pg_dump om de lokale PostgreSQL/PostGIS-databank over te zetten.
De lokale dump importeren in Neon met pg_restore.
De Node.js-app verbinden met Neon via een environment variable en een veilige databaseverbinding.
De toepassing publiceren en het dashboard online beschikbaar maken.
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.
| Dataset | Bron | Gebruik in het dashboard |
|---|---|---|
| Verkeersongevallen | Statbel · geolocalisatie van verkeersongevallen 2017-2024 | Basislaag met ongevallen en coördinaten. |
| Wegenregister | Digitaal Vlaanderen · Wegenregister | Verrijking van ongevallenpunten met straatnamen. |
| Gemeentegrenzen | geo.api.vlaanderen.be/VRBG/wfs | Zoeken en tonen van de geselecteerde gemeente. |
| Bevolkingsstatistieken | Statbel · bevolkingsdichtheid en bevolkingsstructuur | Berekening van ongevallen per 1.000 inwoners. |
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.
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.
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.
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/:gemeenteElke 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.
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;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"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.
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=requireDe 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.
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.
- Login of registreer om te reageren