# Maps-service in Apps Script [[TOC]] ## Maps-service overzicht De Maps-service is een ingebouwde service in Apps Script (geen Advanced Service). Je hebt geen aparte API-key nodig voor standaardgebruik, maar de service verbruikt het quotum van het Google-account dat het script uitvoert. Optioneel kun je via `Maps.setAuthentication()` een API-key koppelen om hogere quota te benutten. Voor zwaar of commercieel gebruik kies je beter de Geocoding API rechtstreeks via `UrlFetchApp`. De service is in juni 2026 nog volledig beschikbaar en ondersteunt geocodering, omgekeerde geocodering, routes met reistijden en statische kaartafbeeldingen. ```javascript function testMapsService() { const geocoder = Maps.newGeocoder(); const resultaat = geocoder.geocode('Damrak 1, Amsterdam'); if (resultaat.status === 'OK') { const locatie = resultaat.results[0].geometry.location; Logger.log(`Lat: ${locatie.lat}, Lng: ${locatie.lng}`); } } ``` ## Geocodering: adres naar coördinaten Met geocodering zet je een tekstadres om naar breedte- en lengtegraad. Stel `setRegion` en `setLanguage` in op `nl` zodat Nederlandse adressen correct worden herkend en teruggegeven. ```javascript function geocodeerAdressen() { const blad = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const data = blad.getDataRange().getValues(); const geocoder = Maps.newGeocoder().setRegion('nl').setLanguage('nl'); for (let i = 1; i < data.length; i++) { const adres = data[i][0]; if (!adres || data[i][1]) continue; try { const resultaat = geocoder.geocode(adres); if (resultaat.status === 'OK' && resultaat.results.length > 0) { const loc = resultaat.results[0].geometry.location; blad.getRange(i + 1, 2).setValue(loc.lat); blad.getRange(i + 1, 3).setValue(loc.lng); } else { blad.getRange(i + 1, 2).setValue('Niet gevonden'); } } catch (e) { Logger.log(`Fout bij ${adres}: ${e.message}`); } Utilities.sleep(200); } } ``` :::info title="Let op het dagquotum" Het exacte aantal geocodeer-aanroepen per dag publiceert Google niet officieel, maar in de praktijk ligt het rond de 1.000 per dag voor consumentenaccounts en hoger voor Workspace-accounts. Overschrijd je dit, dan krijg je de melding `Service invoked too many times for one day: geocode`. Cache resultaten in `PropertiesService` en gebruik `Utilities.sleep(200)` tussen aanroepen om quota te sparen. ::: ## Omgekeerde geocodering: coördinaten naar adres Bij omgekeerde geocodering zet je coördinaten om naar een leesbaar adres. De `address_components` bevatten losse onderdelen zoals straat, huisnummer en plaats die je los kunt uitlezen. ```javascript function omgekeerdeGeocodering(lat, lng) { const geocoder = Maps.newGeocoder(); const resultaat = geocoder.reverseGeocode(lat, lng); if (resultaat.status !== 'OK') { return 'Onbekend adres'; } const components = resultaat.results[0].address_components; const straat = components.find(c => c.types.includes('route'))?.long_name || ''; const nummer = components.find(c => c.types.includes('street_number'))?.long_name || ''; const stad = components.find(c => c.types.includes('locality'))?.long_name || ''; return `${straat} ${nummer}, ${stad}`; } ``` ## Route en reistijd berekenen Met `Maps.newDirectionFinder()` bereken je een route tussen twee punten, inclusief afstand, reistijd en losse navigatiestappen. Kies de modus via `setMode`: `DRIVING`, `WALKING`, `BICYCLING` of `TRANSIT`. ```javascript function berekenRoute() { const directions = Maps.newDirectionFinder() .setOrigin('Amsterdam Centraal, Amsterdam') .setDestination('Centraal Station, Rotterdam') .setMode(Maps.DirectionFinder.Mode.DRIVING) .setAvoidTolls(false) .getDirections(); if (directions.status !== 'OK') { Logger.log('Geen route gevonden'); return; } const route = directions.routes[0].legs[0]; Logger.log(`Afstand: ${route.distance.text}`); Logger.log(`Reistijd: ${route.duration.text}`); route.steps.forEach((stap, idx) => { Logger.log(`Stap ${idx + 1}: ${stap.html_instructions} (${stap.distance.text})`); }); } ``` ## Afstanden tussen meerdere locaties De Maps-service heeft geen kant-en-klare afstandsmatrix, maar je kunt eenvoudig per origin-bestemmingspaar een `DirectionFinder` aanroepen en de reistijden verzamelen. Houd `Utilities.sleep()` tussen de aanroepen aan om binnen je quotum te blijven. ```javascript function berekenAfstanden() { const origins = ['Amsterdam', 'Rotterdam', 'Utrecht']; const destinations = ['Den Haag', 'Eindhoven']; origins.forEach(origin => { destinations.forEach(dest => { const richtingen = Maps.newDirectionFinder() .setOrigin(origin) .setDestination(dest) .setMode(Maps.DirectionFinder.Mode.TRANSIT) .getDirections(); if (richtingen.status === 'OK') { const been = richtingen.routes[0].legs[0]; Logger.log(`${origin} -> ${dest}: ${been.duration.text}`); } Utilities.sleep(300); }); }); } ``` ## Statische kaartafbeelding genereren Met `Maps.newStaticMap()` maak je een kaartafbeelding als blob, die je direct in Drive kunt opslaan of in een e-mail of document kunt invoegen. ```javascript function genereerKaartafbeelding() { const kaart = Maps.newStaticMap() .setSize(600, 400) .setZoom(12) .setCenter('Amsterdam, Nederland') .addMarker('Damrak 1, Amsterdam') .addMarker('Leidseplein, Amsterdam') .setMapType(Maps.StaticMap.Type.ROADMAP); const blob = kaart.getMapImage(); blob.setName('amsterdam_kaart.png'); DriveApp.getFolderById('MAP_ID').createFile(blob); Logger.log('Kaart opgeslagen'); } ``` :::tip title="Cache geocodeer-resultaten" Dezelfde adressen geocodeer je liefst maar één keer. Sla het resultaat op in `PropertiesService` of `CacheService` met het adres als sleutel. Bij een herhaalde aanroep haal je het uit de cache in plaats van je dagquotum te belasten. Dat scheelt fors bij grote spreadsheets die vaak draaien. ::: :::howto title="Klantadressen verrijken met coördinaten" 1. Exporteer klantadressen uit je CRM naar een spreadsheet. 2. Loop met een lus door de adres-kolom. 3. Sla rijen over waar de coördinaten-kolom al gevuld is. 4. Geocodeer het adres met `Maps.newGeocoder().geocode(adres)`. 5. Schrijf `lat` en `lng` terug naar de spreadsheet. 6. Voeg `Utilities.sleep(200)` toe om je quotum te respecteren. ::: :::faq ### Kan ik de Maps-service gebruiken in een standalone script? Ja, de Maps-service werkt in zowel gebonden als standalone scripts. De quota zijn gebonden aan het Google-account dat het script uitvoert. ### Hoe bereken ik de afstand in een rechte lijn? De Maps-service biedt geen directe haversine-berekening, maar je kunt de haversine-formule zelf in JavaScript implementeren op basis van de geocodeer-coördinaten. ### Ondersteunt de service OV-routes? Ja, gebruik `Maps.DirectionFinder.Mode.TRANSIT` voor openbaar vervoer. Aankomst- en vertrektijden stel je in met `.setDepartureTime(datum)` of `.setArrive(datum)`. ### Hoe vermijd ik quotum-overschrijding bij veel adressen? Cache geocodeer-resultaten in `PropertiesService`, verwerk adressen in batches over meerdere triggerlopen en gebruik `Utilities.sleep()` tussen aanroepen. ### Heb ik een API-key nodig? Voor standaardgebruik niet, de ingebouwde service werkt zonder key binnen het accountquotum. Met `Maps.setAuthentication()` koppel je optioneel een API-key om hogere quota te benutten. ::: De Maps-service maakt geografische verrijking van spreadsheetdata eenvoudig zonder externe API-keys. Handig voor routeplanning, reiskosten-berekening en geografische analyses.