Postcodes op de kaart zetten

Je klanten of je storingen op een landkaart, gekleurd naar wat je wilt weten. Daar heb je geen kaartdienst en geen abonnement voor nodig: in de postcodetabel staan bij elke rij al coördinaten. Hieronder lees je hoe je die gebruikt in Power BI, Excel en QGIS, hoe je zelf een kaart in HTML bouwt, en wat je met de pandvormen uit de postcode database kunt. Inclusief de fouten die iedereen één keer maakt.

Een postcode is geen plek op de kaart

Dit is waar de meeste kaarten stranden. 3992 DG is een code, geen positie. Je kaartprogramma weet niet waar dat ligt, tenzij je het erbij levert. Wat je nodig hebt zijn coördinaten: twee getallen per rij.

In de postcodetabel van Brons en in de postcode database van Zilver en Goud staan die getallen al in vier kolommen:

  • Latitude en Longitude: graden, het stelsel van Google Maps, Power BI en elke webkaart (WGS84).
  • XCoordinaat en YCoordinaat: Rijksdriehoek, het Nederlandse stelsel in meters. Handig als je met afstanden rekent.

Je hoeft dus niets op te zoeken en niets te geocoderen. Je sleept twee kolommen naar je kaart en klaar. Wie een lijst postcodes zonder coördinaten heeft, koppelt die eerst op postcode aan de tabel; dat is één VLOOKUP of één JOIN.

De data komt uit de BAG van het Kadaster en bevat alleen fysieke verblijfsobjecten. Postbussen zitten er niet in, dus die verschijnen ook niet op je kaart.

Punten of vlakken: kies dit eerst

Postcodekaarten komen in twee soorten, en ze vragen om verschillende data. Kies verkeerd en je bent een middag kwijt.

Stippen (punten)

Elk adres of elke postcode wordt een bolletje op de kaart. Je hebt alleen coördinaten nodig, dus dit werkt meteen met onze bestanden. Goed voor de vraag waar je klanten wonen, of waar de storingen vandaan komen.

Gekleurde gebieden (vlakken)

Nederland opgedeeld in postcodegebieden, elk met een kleur naar omzet of aantal klanten. Dit heet een choropleet. Hiervoor heb je naast je cijfers ook de vórm van elk postcodegebied nodig, en die grenzen verkopen wij niet. Wij leveren adressen en panden, geen postcodegrenzen. Die vlakken haal je bij een open bron zoals het CBS, en je koppelt ze op de postcode aan jouw cijfers.

Een tussenweg die vaak genoeg is: tel je adressen per PC4 en zet één bolletje per postcodegebied, met de grootte naar aantal. Dat leest bijna net zo goed en kost je geen grensbestand.

PC4 of PC6

PC4 zijn de vier cijfers (3992). Ruim 4.000 gebieden, ter grootte van een wijk of dorp. Rustig op een landkaart en genoeg voor een overzicht per regio. PC6 is de volledige postcode (3992 DG): meestal één straat of een stuk daarvan. Dat zijn er ruim 450.000, dus op een kaart van heel Nederland wordt het één vlek. Gebruik PC6 als je op wijkniveau inzoomt, PC4 als je het hele land laat zien.

Postcodes op de kaart in Power BI

Power BI tekent de kaart voor je, maar het moet wel weten dat jouw getallen coördinaten zijn. Doe je dat niet, dan ziet het twee gewone getallen, telt ze op en zet één bolletje midden in de oceaan. Het is de fout die iedereen één keer maakt.

Stap voor stap

  1. Laad het CSV-bestand: Gegevens ophalen › Tekst/CSV. Zet het scheidingsteken op puntkomma en de bestandsoorsprong op UTF-8, anders lopen straatnamen met accenten in de war.
  2. Controleer het kolomtype van Latitude en Longitude. Die moeten Decimaal getal zijn, niet Tekst en niet Geheel getal. Staat er tekst, dan komt dat meestal door een komma als decimaalteken; zet de landinstelling van die stap op Engels (Verenigde Staten).
  3. Selecteer de kolom Latitude, ga naar het tabblad Kolomhulpmiddelen en zet Gegevenscategorie op Breedtegraad. Doe hetzelfde voor Longitude met Lengtegraad. Sla je dit over, dan klopt er niets van je kaart.
  4. Zet de visual Kaart op je rapport. Sleep Latitude naar Breedtegraad en Longitude naar Lengtegraad, niet naar Locatie.
  5. Sleep een getal naar Grootte, bijvoorbeeld het aantal adressen of je omzet. Nu zie je in één oogopslag waar het zwaartepunt ligt.

Waarom niet gewoon de postcode in Locatie slepen

Dat kan, en soms werkt het. Power BI stuurt die postcode dan naar Bing om er een plek van te maken. Drie bezwaren. Het is traag bij duizenden rijen. Het raadt er soms naast, want 1000 AA bestaat ook in andere landen. En je stuurt je adreslijst naar een dienst buiten je eigen omgeving, wat bij klantgegevens een gesprek met je privacyfunctionaris oplevert. Met eigen coördinaten gebeurt het rekenwerk gewoon op je eigen scherm.

Wil je toch gebieden inkleuren, dan is Vormkaart de visual die je zoekt. Die vraagt om een TopoJSON-bestand met de postcodegrenzen; dezelfde grenzen als hierboven, en dus niet iets wat in onze bestanden zit.

Het volledige bestand van Zilver en Goud telt ruim negen miljoen adressen. Dat past niet in Excel en het is ook zwaar voor één kaart. Filter eerst op de gemeente of de provincie die je wilt zien, of tel samen per postcode. Negen miljoen bolletjes worden één grote vlek.

Zelf een kaart bouwen in HTML

Je hebt geen dure kaartdienst nodig om adressen op een webpagina te zetten. Een kaart is niet meer dan een raster van plaatjes met jouw stippen eroverheen. Twee routes.

Met een bibliotheek: Leaflet

De makkelijkste weg. Leaflet is gratis, klein en werkt met kaarttegels van OpenStreetMap. Onderstaand voorbeeld zet een handvol adressen op de kaart; vervang de lijst door je eigen rijen uit de postcodetabel en je bent klaar.

Adressen op een kaart met Leaflet
<!-- Zet er een vast versienummer bij. Zonder nummer krijg je altijd de
     nieuwste, en breekt je kaart op een dag zonder dat je iets wijzigde. -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<div id="kaart" style="height: 500px"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
  // Rijen uit de postcodetabel: [latitude, longitude, label]
  const adressen = [
    [52.0907, 5.1214, "3511 LN Utrecht"],
    [51.9244, 4.4777, "3011 AA Rotterdam"],
    [52.3676, 4.9041, "1011 AB Amsterdam"],
  ];

  const kaart = L.map("kaart").setView([52.1, 5.1], 8);
  L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
    attribution: "&copy; OpenStreetMap-bijdragers",
    maxZoom: 19,
  }).addTo(kaart);

  for (const [lat, lon, label] of adressen) {
    L.circleMarker([lat, lon], { radius: 6 }).addTo(kaart).bindPopup(label);
  }
</script>

Zonder bibliotheek

Het kan ook kaal, met gewone plaatjes. Een kaarttegel is een plaatje van 256 bij 256 pixels op een vast adres: zoom, kolom, rij. Het rekenwerk van een coördinaat naar een tegelnummer past in vier regels.

Van coördinaat naar tegelnummer
function tegelX(lon, zoom) {
  return ((lon + 180) / 360) * 2 ** zoom;
}

function tegelY(lat, zoom) {
  const rad = (lat * Math.PI) / 180;
  return ((1 - Math.log(Math.tan(rad) + 1 / Math.cos(rad)) / Math.PI) / 2) * 2 ** zoom;
}

// De tegel waarin een adres valt, op zoomniveau 17:
const x = Math.floor(tegelX(5.9512, 17));
const y = Math.floor(tegelY(52.0043, 17));
const url = `https://tile.openstreetmap.org/17/${x}/${y}.png`;

Het niet-hele deel van die uitkomst vertelt je waar in de tegel het punt ligt: vermenigvuldig met 256 en je hebt de pixel. Zo tekenen wij de kaart op onze eigen demopagina, zonder kaartbibliotheek. Bekijk hem gerust en haal de aanpak eruit.

Tegels van OpenStreetMap zijn gratis, maar niet onbeperkt. Hun gebruiksvoorwaarden staan zwaar geautomatiseerd verkeer niet toe. Bouw je iets dat druk bezocht wordt, neem dan een betaalde tegeldienst of draai je eigen tegelserver. Vermeld altijd © OpenStreetMap-bijdragers.

Bekijk de werkende kaart op de demopagina: alle panden van één gemeente, gekleurd op woningtype, getekend met de techniek hierboven.

Van stip naar gebouw: Panden Plus

Een stip zegt dat er iets staat. Een pandvorm laat zien wát er staat. Panden Plus bevat de omtrek van elk gebouw in Nederland als polygoon. Ruim 12,7 miljoen panden, met het woningtype dat uit die vorm volgt: vrijstaand, hoekwoning, twee-onder-een-kap, tussenwoning of appartement.

Op een kaart is het verschil meteen zichtbaar. In plaats van bolletjes op een straat zie je de daken zelf, en kun je ze kleuren op bouwjaar, oppervlakte of woningtype. Een wijk uit de jaren dertig ziet er dan anders uit dan een nieuwbouwplan, zonder dat je één cijfer hoeft te lezen.

Wat je ermee doet

  • Oppervlakte rechtstreeks uit de vorm rekenen, in plaats van schatten.
  • Controleren of een punt binnen een pand valt, handig om losse data zoals een energielabel aan het juiste gebouw te hangen.
  • Filteren op vorm en grootte: alle vrijstaande woningen van vóór 1990 in één gemeente, voor een isolatie- of zonnepanelenactie.
  • Risico inschatten per pandtype, zoals verzekeraars doen: een vrijstaand pand brandt anders dan een rij tussenwoningen.
  • De woningmix van een wijk in kaart brengen, voor beleid of voor een haalbaarheidsstudie.
  • Kabels, leidingen of bezorgroutes plannen op de echte pandvorm in plaats van op een adrespunt.

In welke vorm het komt

Eén zip met twee bestanden die dezelfde panden bevatten. Een CSV met de vorm als WKT-tekst, voor Excel, SQL Server of Power BI. En een GeoPackage (.gpkg) waarin de vorm al echte geometrie is: die sleep je zo in QGIS of ArcGIS, en met ogr2ogr laad je hem in PostGIS of SQL Server. Er zit een leesmij bij met alle kolommen.

Bekijk de werkende kaart op de demopagina: alle panden van één gemeente, gekleurd op woningtype, getekend met de techniek hierboven.

Postcodes op de kaart in Excel

Excel heeft 3D-kaarten ingebouwd, onder Invoegen › 3D-kaart. Selecteer je tabel, open 3D-kaarten en sleep Latitude en Longitude naar Locatie; geef bij elk veld aan welke het is. Je kunt de hoogte of kleur van de staafjes op een getal zetten.

Twee grenzen om vooraf te kennen. Een werkblad houdt op bij ruim een miljoen rijen, dus Zilver en Goud passen er niet in; Brons met ruim 450.000 rijen wel. En 3D-kaarten zit alleen in de Windows-versies van Microsoft 365 en Office, niet in Excel voor het web en niet op een Mac. Werk je daarop, gebruik dan Power BI of de HTML-route hierboven.

Postcodes op de kaart in QGIS

QGIS is gratis, en het is de enige route hier waarmee je echt met vormen kunt rekenen: snijden, bufferen, tellen binnen een gebied. Voor Panden Plus is het de kortste weg, want daar sleep je het .gpkg-bestand zo in.

Een CSV met coördinaten inladen

  1. Laag › Laag toevoegen › Tekstbestand met scheidingstekens toevoegen.
  2. Kies het bestand, zet het scheidingsteken op puntkomma en de codering op UTF-8.
  3. Bij Geometriedefinitie: X-veld op Longitude, Y-veld op Latitude. Let op de volgorde: X is de lengtegraad, niet de breedtegraad.
  4. Zet het coördinaatstelsel op EPSG:4326 (WGS84). Gebruik je liever XCoordinaat en YCoordinaat, kies dan EPSG:28992.
  5. Voeg toe. Een achtergrondkaart krijg je met de plug-in QuickMapServices, of via XYZ Tiles › OpenStreetMap.

Kleuren op een kolom doe je via Eigenschappen › Symbologie › Gecategoriseerd. Kies bijvoorbeeld het veld woningtype en klik op Classificeren.

Rijksdriehoek of WGS84: het verschil dat kaarten sloopt

Nederland heeft een eigen coördinaatstelsel: Rijksdriehoek, kortweg RD, ook bekend als EPSG:28992. Het rekent in meters vanaf een nulpunt bij Amersfoort. De rest van de wereld gebruikt WGS84 (EPSG:4326), dat in graden rekent: de breedte- en lengtegraden die je van Google Maps kent.

Je herkent ze meteen aan de getallen. Een RD-coördinaat in Nederland ziet eruit als 155000 en 463000. Een WGS84-coördinaat als 52,09 en 5,12. Haal je ze door elkaar, dan verdwijnt je kaart: RD-getallen in een webkaart plaatsen je punt ergens ver buiten de aarde, en dan zie je niets.

  • Webkaart, Power BI, Google Maps, Leaflet: gebruik Latitude en Longitude (WGS84).
  • Afstanden en oppervlaktes in meters: gebruik XCoordinaat en YCoordinaat (RD). In graden rekenen levert scheve uitkomsten, want een graad lengte is in Nederland korter dan een graad breedte.

Omzetten kan altijd. In PostGIS is dat ST_Transform(geom, 4326), en met ogr2ogr zet je er -t_srs EPSG:4326 achter. De geometrie van Panden Plus staat in RD; de kolommen Latitude en Longitude staan er voor het gemak al naast.

Wat er in de praktijk misgaat

Alle punten liggen op één hoop bij Afrika

Coördinaat 0,0 ligt in de Golf van Guinee. Zie je daar een stapel punten, dan heeft je import lege coördinaten op nul gezet. Filter rijen zonder coördinaat eruit voordat je tekent.

Nederland ligt ineens in Somalië

Breedte- en lengtegraad omgewisseld. 52,09 en 5,12 is Utrecht; 5,12 en 52,09 is de Indische Oceaan. In QGIS is X de lengtegraad, in Power BI hoort Latitude in Breedtegraad. Draai ze om en je punt verhuist.

Eén bolletje in plaats van duizend

Power BI telt je coördinaten op in plaats van ze te tonen. De kolom staat op Som. Zet hem op Niet samenvatten, en zet de gegevenscategorie op Breedtegraad en Lengtegraad.

De komma

52,0907 is voor een Nederlandse computer een getal en voor een Engelse twee kolommen. Loopt je import scheef of worden coördinaten tekst, kijk dan naar het decimaalteken en naar de landinstelling van de importstap.

Het is traag

Negen miljoen punten tekenen kost tijd, ook op een snelle machine. Tel samen per PC4 of per gemeente, of filter op het gebied dat je nodig hebt. Voor een landkaart is één punt per postcodegebied bijna altijd genoeg.

Vragen over postcodes op een kaart

Eerst zien of het past?Download een demobestand van 1.000 rijen, met dezelfde kolommen als het volledige bestand.