Een uitgebreide stap-voor-stap handleiding voor het converteren van Nederlandse adressen naar GPS-coördinaten, inclusief edge cases en validatie.
Het converteren van Nederlandse adressen naar coördinaten lijkt eenvoudig, maar in de praktijk zijn er veel subtiliteiten. Deze handleiding behandelt het volledige proces: van adresformaat tot validatie, inclusief alle edge cases die je in Nederland tegenkomt.
Nederlandse adresformaten
Nederlandse adressen volgen een specifieke structuur. De API herkent verschillende formaten:
Volledig adres
{"address": "Kalverstraat 1, 1012 NX Amsterdam"}
Gestructureerd adres
Voor hogere nauwkeurigheid kun je het adres ook gestructureerd aanleveren:
{"street": "Kalverstraat","house_number": "1","postcode": "1012 NX","city": "Amsterdam"}
Gestructureerd = betrouwbaarder
Wanneer mogelijk, gebruik het gestructureerde formaat. Dit voorkomt parsing-fouten en levert een hogere confidence score op.
Alleen postcode + huisnummer
In Nederland is de combinatie van postcode en huisnummer uniek. Dit is de meest compacte vorm:
{"postcode": "1012 NX","house_number": "1"}
Stap-voor-stap implementatie
Stap 1: Adresvalidatie
Voordat je een adres naar de API stuurt, valideer het lokaal:
const validateDutchAddress = (address) => {const errors = [];// Postcode validatie (formaat: 1234 AB)const postcodeRegex = /^[1-9][0-9]{3}\s?[A-Z]{2}$/i;if (address.postcode && !postcodeRegex.test(address.postcode)) {errors.push('Ongeldig postcodeformaat');}// Huisnummer validatieif (address.house_number) {const houseNumberRegex = /^[1-9][0-9]{0,4}([-\s]?[a-zA-Z0-9]+)?$/;if (!houseNumberRegex.test(address.house_number)) {errors.push('Ongeldig huisnummerformaat');}}// Verplichte veldenif (!address.postcode && !address.city) {errors.push('Postcode of woonplaats is verplicht');}return {valid: errors.length === 0,errors};};
Stap 2: API Request
const geocodeAddress = async (address, token) => {// Valideer eerstconst validation = validateDutchAddress(address);if (!validation.valid) {throw new Error(`Validatiefouten: ${validation.errors.join(', ')}`);}// Bouw het adres als stringconst parts = [];if (address.street) parts.push(address.street);if (address.houseNumber) parts.push(address.houseNumber);if (address.postcode) parts.push(address.postcode.replace(/\s/g, ''));if (address.city) parts.push(address.city);const query = encodeURIComponent(parts.join(' '));const response = await fetch(`https://api.georex.nl/geocode?q=${query}&token=${token}`);return response.json();};
Stap 3: Response verwerken
const processGeocodeResult = (result) => {// GeoJSON response verwerkenif (!result.features || result.features.length === 0) {return {found: false,error: 'Adres niet gevonden'};}const feature = result.features[0];const [lon, lat] = feature.geometry.coordinates;const props = feature.properties;return {found: true,coordinates: { lat, lng: lon },formattedAddress: `${props.street || ''} ${props.housenumber || ''}, ${props.postcode || ''} ${props.city || ''}`.trim(),type: props.type,components: {street: props.street,houseNumber: props.housenumber,postcode: props.postcode,city: props.city,state: props.state,country: props.country}};};
Edge cases: Nederlandse adresuitdagingen
Huisnummer toevoegingen
Nederland kent diverse huisnummer toevoegingen. De API herkent ze allemaal:
| Toevoeging | Voorbeeld | API Input |
|---|---|---|
| Letter | Kalverstraat 1A | "house_number": "1A" |
| Bis | Prinsengracht 12bis | "house_number": "12bis" |
| Romeins | Herengracht 5-III | "house_number": "5-III" |
| Onder/Boven | Singel 8-hs | "house_number": "8-hs" |
| Bereik | Dam 1-3 | "house_number": "1-3" |
const parseHouseNumber = (input) => {// Patronen voor Nederlandse huisnummersconst patterns = [/^(\d+)([a-zA-Z])$/, // 1A/^(\d+)[-\s]?(bis)$/i, // 12bis, 12-bis/^(\d+)[-\s]?(I{1,3}|IV|V)$/i, // 5-III (Romeins)/^(\d+)[-\s]?(hs|huis|sous)$/i, // 8-hs/^(\d+)[-\s](\d+)$/ // 1-3 (bereik)];for (const pattern of patterns) {const match = input.match(pattern);if (match) {return {number: match[1],addition: match[2] || null};}}return { number: input, addition: null };};
Straatnamen met speciale tekens
Sommige Nederlandse straatnamen bevatten apostrofes, accenten of streepjes:
- 's-Gravenhage (Den Haag)
- 't Zand
- IJsselstein (IJ als één letter)
- Café-eigenaar straat (historisch)
Automatische normalisatie
De GeoRex API normaliseert automatisch variaties zoals "Den Haag", "'s-Gravenhage", en "s-Gravenhage" naar dezelfde locatie.
Complete implementatie
Hier is een complete class die alle bovenstaande aspecten combineert:
class DutchGeocoder {constructor(apiKey) {this.apiKey = apiKey;this.token = null;this.tokenExpiry = 0;}/*** Haal een geldig token op (vernieuw indien nodig)*/async getToken() {// Vernieuw token als bijna verlopen (binnen 1 minuut)if (!this.token || Date.now() > this.tokenExpiry - 60000) {const res = await fetch('https://api.georex.nl/api/token', {method: 'POST',headers: { 'X-API-Key': this.apiKey }});const data = await res.json();this.token = data.token;this.tokenExpiry = Date.now() + (data.expires_in * 1000);}return this.token;}/*** Geocodeer een Nederlands adres* @param {Object|string} address - Adres object of string* @returns {Promise<Object>} Geocoding resultaat*/async geocode(address) {// Converteer string naar object indien nodigconst addressObj = typeof address === 'string'? this.parseAddressString(address): address;// Valideerconst validation = this.validate(addressObj);if (!validation.valid) {throw new Error(validation.errors.join(', '));}// Normaliseerconst normalized = this.normalize(addressObj);// Haal token opconst token = await this.getToken();// API call met tokenconst query = encodeURIComponent(normalized.address);const response = await fetch(`https://api.georex.nl/geocode?q=${query}&token=${token}`);const result = await response.json();// Verwerk GeoJSON resultaatreturn this.processResult(result);}parseAddressString(str) {// Probeer postcode + huisnummer te extractenconst postcodeMatch = str.match(/([1-9][0-9]{3})\s?([A-Z]{2})/i);const houseNumberMatch = str.match(/(\d+[a-zA-Z]?[-\s]?[a-zA-Z0-9]*)/);return {address: str,postcode: postcodeMatch ? `${postcodeMatch[1]}${postcodeMatch[2]}` : null,house_number: houseNumberMatch ? houseNumberMatch[1] : null};}validate(address) {const errors = [];const postcodeRegex = /^[1-9][0-9]{3}[A-Z]{2}$/i;if (address.postcode && !postcodeRegex.test(address.postcode.replace(/\s/g, ''))) {errors.push('Ongeldig postcodeformaat');}return { valid: errors.length === 0, errors };}normalize(address) {return {...address,postcode: address.postcode?.replace(/\s/g, '').toUpperCase()};}processResult(result) {// GeoJSON response verwerkenif (!result.features || result.features.length === 0) {return { found: false, error: 'Adres niet gevonden' };}const feature = result.features[0];const [lon, lat] = feature.geometry.coordinates;const props = feature.properties;return {found: true,lat: lat,lng: lon,address: `${props.street} ${props.housenumber}, ${props.postcode} ${props.city}`,components: props};}}// Gebruikconst geocoder = new DutchGeocoder('gx_live_your_api_key');const result = await geocoder.geocode('Damrak 1, 1012LG Amsterdam');console.log(result);// { found: true, lat: 52.3738, lng: 4.8910, address: "Damrak 1, 1012LG Amsterdam", ... }
Samenvatting
Het geocoderen van Nederlandse adressen vereist aandacht voor lokale conventies. Door validatie, normalisatie en correcte error handling te implementeren, kun je betrouwbare resultaten behalen. Gebruik waar mogelijk gestructureerde adressen en let op de confidence score voor kwaliteitscontrole.
Gerelateerde artikelen

Je eerste geocoding API call in 5 minuten
Leer hoe je in slechts 5 minuten je eerste geocoding API call maakt met GeoRex. Complete voorbeelden in JavaScript, Python, PHP en cURL.
Lees meer
Geocoding vs Reverse Geocoding: Wat is het verschil?
Ontdek het verschil tussen geocoding en reverse geocoding, wanneer je welke methode gebruikt, en hoe je beide implementeert met praktische voorbeelden.
Lees meer
GeoRex API authenticatie en best practices
Leer hoe je veilig authenticeert met de GeoRex API, je API keys beheert, en best practices implementeert voor productie-omgevingen.
Lees meer