Praktijkrichtlijn Vector Tiling

Geonovum Praktijkrichtlijn
Vastgestelde versie

Deze versie:
https://docs.geostandaarden.nl/serv/def-pr-vt-20251013
Laatst gepubliceerde versie:
https://docs.geostandaarden.nl/serv/vt/
Laatste werkversie:
https://geonovum.github.io/praktijkrichtlijn-vector-tiling/
Vorige versie:
https://docs.geostandaarden.nl/serv/def-pr-vt-20210830/
Redacteurs:
Niene Boeijen (This Way Cartography)
Thijs Brentjens (Geonovum)
Rolf Jonker (Geonovum)
Doe mee:
GitHub geonovum/praktijkrichtlijn-vector-tiling
Dien een melding in
Revisiehistorie
Pull requests

Samenvatting

De Praktijkrichtlijn Vector Tiling formuleert eisen en aanbevelingen hoe vector tiles te gebruiken voor Nederlandse toepassingen. De praktijkrichtlijn richt zich op het aanbieden, publiceren en gebruiken van vector tiles in (web)applicaties, waarbij visualisatie het hoofddoel is. Dit moet het voor gebruikers makkelijker maken vector tiles van derden te gebruiken.

Enkele van de belangrijkste punten zijn:

Aanvullend op de praktijkrichtlijn is er een document met Best practices.

Status van dit document

Dit is de definitieve versie van dit document. Wijzigingen naar aanleiding van consultaties zijn doorgevoerd.

1. Inleiding

1.1 Doel

De Prakrijktrichtlijn specificeert hoe het beste vector tiles aangeboden kunnen worden om breed gebruik mogelijk te maken (maximale interoperabiliteit), voor Nederlandse toepassingen. Dit moet het ook makkelijker maken om vector tiles van derden te gebruiken. Zie verder het hoofdstuk over de scope.

Deze praktijkrichtlijn is geen verplichting.

1.2 Totstandkoming

Dit document is opgesteld onder redactie van Geonovum. De inhoud is met Nederlandse experts in enkele werksessies afgestemd.

1.2.1 Werkgroepleden

Onder andere de volgende mensen hebben een bijdrage geleverd aan deze praktijkrichtlijn via de werksessies of op een andere manier:

  • Joris Bak, Esri Nederland
  • Anton Bakker, Kadaster
  • Niene Boeijen, This Way Cartography (redactie)
  • Thijs Brentjens, Geonovum (redactie)
  • Stefan de Konink, Stichting OpenGeo
  • Jeroen Hogeboom, Kadaster
  • Edward Mac Gillavry, Webmapper
  • Just van den Broecke, Just Objects
  • Wouter Visscher, Kadaster
  • Roel van den Berg, Kadaster
  • John Schaap, Kadaster

1.3 Aansluiten bij internationale standaarden

Deze Prakrijktrichtlijn gebruikt zoveel mogelijk internationale standaarden en specificaties. Waar dat nog niet goed mogelijk is, kiezen we de meest gangbare oplossing uit de praktijk. Deze richtlijn is niet gebonden aan specifieke software.

1.4 Best practices

Er zijn ook onderwerpen die niet per se gaan over interoperabiliteit, maar wel van belang kunnen zijn om op een goede, geschikte manier vector tiles aan te bieden. Deze staan in een apart Best practices document.

1.5 Doelgroep

De praktijkrichtlijn is bedoeld voor o.a.:

1.6 Leeswijzer

Na dit hoofdstuk komt eerst de Scope van deze Praktijkrichtlijn. Hoofdstuk 3 bevat vervolgens de specificaties waarop deze Praktijkrichtlijn gebaseerd is. Hoofdstuk 4 TileMatrixSet werkt de details van de te gebruiken TileMatrixSets uit. Hoofdstuk 5 Publicatie behandelt hoe de vector tiles aan te bieden. Hoofdstuk 6 Documentatie specificeert hoe de aangeboden vector tiles en API te documenteren. Het weergeven van vector tiles is onderwerp van hoofdstuk 7 Styling.

De bijlagen bevatten verdiepende informatie over Coördinaat Referentie Systemen en de uitwerking van de TileMatrixSet voor het Rijksdriehoekstelsel.

Dit document bevat kenmerken waaraan een implementatie moet voldoen (eisen) en waaraan een implementatie idealiter voldoet, maar niet noodzakelijk voor alle implementaties (aanbevelingen).

De Praktijkrichtlijn zelf is geen verplichting. Om een onderscheid te maken in prioriteit, hanteert de Prakrijktrichtlijn wel de termen EIS en AANBEVELING om de minimaal benodigde set van kenmerken aan te geven (eisen) voor hergebruik van vector tiles en de gewenste set (aanbevelingen) om het zo goed mogelijk te doen.

Eisen staan geformuleerd in oranje blokken, bijvoorbeeld:

EIS Dit is een vereist kenmerk

Aanbevelingen zonder extra opmaak:

AANBEVELING Dit is een aanbeveling

2. Scope

2.1 Binnen scope

De Praktijkrichtlijn richt zich op het aanbieden, publiceren en gebruiken van vector tiles in (web)applicaties, van data van Nederlandse organisaties.

Meer concreet gaat het om 2D vector tiles voor visualisatie / portrayal door derden (applicatie onwikkelaars en geo-specialisten), zoals voor achtergrondkaarten. Het gaat dus niet om het delen van objectgegevens / features of nauwkeurige metingen. Typisch gebruik van vector tiles is het visualiseren van grotere datasets en cartografische producten zoals topografische achtergrond kaarten. Waarbij de aanname is dat de data hiervoor voorbewerkt is en versimpeld om tot een goed uitgewerkte visualisatie te komen. En als gevolg daarvan niet per se de kwalitatief nauwkeurige coördinaten van de originele geodata bevat.

Deze vector tiles kunnen aangeboden worden als service / via een API of als bulk download. In dit document wordt er voor vector tiles via een service geen verschil gemaakt of de vector tiles al voorberekend zijn ("pre-cooked" / "pre-processed") en al dan niet uit een cache aangeboden worden, of dynamisch worden opgebouwd (on-the-fly).

Door ons te beperken tot visualisatie ontstaat het gevolg dat niet alle geschikte mogelijkheden van vector tiles hier behandeld worden. Maar het doel van deze praktijkrichtlijn is om de verschillende vector tile aanbieders hun vector tile sets zo aan te laten bieden dat deze makkelijk te gebruiken, combineren en hergebruiken zijn. Niet alleen met andere vector tile sets maar ook te combineren met de OGC standaarden, zoals WMS, WFS, met gangbare online kaartdiensten/platformen (Google Maps, Mapbox, etc) en met de OGC API standaarden. Daarom sluiten we in deze praktijktichtlijn ook zo veel mogelijk aan bij bestaande richtlijnen en standaarden.

2.2 Buiten scope

Hoewel het mogelijk is om vector tiling te gebruiken om alleen de (feature/object) data uit te wisselen (al dan niet met nauwkeurige geometrie), is dit buiten scope van deze Praktijkrichtlijn.

Buiten scope van de Praktijkrichtlijn zijn:

De Best practices bevatten ook enkele onderwerpen die buiten scope zijn van de praktijkrichtlijn, maar wel relevant voor het handig kunnen maken en aanbieden van vector tiles. Dit zijn zaken als:

Voor eigen applicaties en specifieke toepassingen staat het uiteraard vrij om op een andere manier vector tiles aan te bieden dan deze praktijkrichtlijn beschrijft.

3. Basis specificaties

Dit hoofdstuk beschrijft de specificaties waar deze praktijkrichtlijn op gebaseerd is.

3.1 Vector tiles maken

Bij het maken van vector tiles gaat deze richtlijn uit van het gebruik van de technische specificatie zoals beschreven door de [Mapbox-Vector-Tile-Specification]. Deze specificatie bevat de belangrijkste standaarden en instellingen over hoe geografische data opgeslagen en gecodeerd wordt in een vector tile. Deze bevat informatie over bestandsformaten, extensies, projecties, bounds, en de interne structuur van een vector tile.

3.2 Eis: Mapbox Vector Tile specification versie 2.1

EIS Gebruik [Mapbox-Vector-Tile-Specification] versie 2.1 (January 19th, 2016) om vector tiles op te bouwen

In het kort gaat deze specificatie uit van:

In deze praktijkrichtlijn wijken wij af van de beschreven bestand extensie .mvt zoals genoemd in 2.1 File extension van de Mapbox specificatie. Ook wijken wij af van de paragraaf 2.2 Multipurpose Internet Mail Extensions (MIME).

3.2.1 Eis: Vrije Bestands Extensie

EIS De bestandsextensie voor vectortiles is vrij in te vullen. Het Media Type van vectortiles moet volgens mapbox specificatie altijd application/vnd.mapbox-vector-tile zijn.

Deze praktijkrichtlijn wijkt hiermee af van Hoofdstuk 2. File Format definities van de Mapbox Vector tile specification.

3.2.2 Eis: Encoding PBF

EIS Gebruik voor de encoding van de data [PBF] (Google Protobuf)

3.2.3 Eis: Clockwise Winding order

[Mapbox-Vector-Tile-Specification] vereist een clockwise Winding order. Zie de de Mapbox documentatie over Winding order voor een toelichting. Omdat de winding order vaak mis gaat bij implementaties, bevat de Praktijkrichtlijn hiervoor een expliciete eis. Het niet aanhouden van de correcte winding order levert problemen op in sommige vectortile clients. Het probleem wat in deze situatie kan optreden is dat voor vectoren die gaten bevatten, het gat niet door de betreffende client kan worden herkend en worden ingekleurd.

Let op! de winding order van vector tiles is tegengesteld aan de Winding order voor geschreven door OGC in o.a. de OGC Simple Features.

EIS Voor de volgorde van coördinaten bij polygonen, gebruik de zogenaamde clockwise (buitenste ring met de klok mee, binnenste ring tegen de klok in) winding order zoals in Mapbox vectortile specificatie is beschreven.

3.3 Vector tiles aanbieden

Voor het aanbieden en publiceren van vector tiles via het web is nog geen open standaard gereed. De vector tiles kunnen als download aangeboden worden of als webservice, via een API, of als statische directory structure.

Het OGC biedt verscheidene nieuwe specificaties aan voor het publiceren en aanbieden van geografische data via APIs: voor features, maps en vector tiles. Zie de website OGC APIs Building Blocks for Location voor een overzicht van APIs voor het web. Voor vector tiles is de [OGC-API-Tiles-Core] specificatie relevant.

Deze praktijkrichtlijn schrijft het gebruik van [OGC-API-Tiles-Core] voor. Dit is een open standaard voor publicatie van vector tiles door middel van web services. Deze standaard is door OGC vastgesteld.

3.3.1 Eis: OGC API Tiles

EIS Als vector tiles via een API aangeboden worden, gebruik dan [OGC-API-Tiles-Core].

Hoofdstuk 5 werkt het gebruik van OGC API Tiles verder uit. Daar worden ook alternatieven aangegeven voor wanneer het nog niet mogelijk is te voldoen aan de OGC API Tiles specificatie.

4. TileMatrixSet

Het OGC definieert in [OGC-Two-Dimensional-Tile-Matrix-Set-and-Tile-Set-Metadata] enkele zogenaamde TileMatrixSets, internationaal te gebruiken tiling schema's voor raster en vector tiling. Deze nemen we als basis voor de praktijkrichtlijn.

Een TileMatrixSet bestaat uit een oorsprong, grid indeling en zoomniveaus voor een bepaald Coördinaat Referentie Systeen (CRS).

4.1 Coördinaat Referentie Systemen

Voor het te gebruiken CRS en grid kan het beste aangesloten worden bij bestaande standaarden. Het OGC en W3C beschrijven in de Spatial Data on the Web Best Practices [SDW-BP] dat het CRS WGS84 vaak de voorkeur heeft. Web Mercator en andere WGS84 gebaseerde CRSen zijn veelgebruikt bij vector tiles en tools hebben hier brede ondersteuning voor.

Maar WGS84 is voor Nederland (en andere Europese landen) tot op zekere hoogte onnauwkeurig. Afhankelijk van de toepassing kan dit ongewenste effecten hebben. De bijlage Coördinaat referentie systemen voor vector tiles bevat meer informatie over deze (on)nauwkeurigheid en wat de impact is voor vector tiles.

Voor de meeste toepassingen die vector tiles gebruiken binnen de scope van deze Prakrijktrichtlijn is Web Mercator voldoende nauwkeurig.

4.2 Eis: te gebruiken TileMatrixSets

[OGC-API-Tiles-Core] beschrijft alleen een beperkte standaardset van 8 TileMatrixSets, uit [OGC-Two-Dimensional-Tile-Matrix-Set-and-Tile-Set-Metadata]. Omdat er nog geen OGC TileMatrixSet voor het Rijksdriehoekstelsel is, hebben wij deze opgesteld en opgenomen als bijlage voor deze praktijkrichtlijn. Zie de bijlage: NetherlandsRDNewQuad.json

Vooruitlopend op een extensie om andere TileMatrixSets te ondersteunen, kiezen we in deze Praktijkrichtlijn voor een zelfde mechanisme om de TileMatrixSet te publiceren als eentje uit de standaardset van [OGC-API-Tiles-Core].

EIS Biedt vector tiles aan in tenminste één van de volgende TileMatrixSets voor de coördinaat referentie systemen:

Als vector tiles via OGC API Tiles worden aangeboden, is de TileMatrixSetId onderdeel van de URL en beschrijving van de vector tiles. Daarmee is het gebruikte CRS gepubliceerd.

5. Vector tiles aanbieden

5.1 Eis: gebruik OGC API Tiles

De OGC API Tiles [OGC-API-Tiles-Core] is de open standaard voor het opstellen van tiles. Deze praktijkrichtlijn schrijft deze API-specificatie daarom voor.

EIS Als vector tiles via een API aangeboden worden, gebruik dan [OGC-API-Tiles-Core].

5.2 Eis: Content-Type

EIS Als vector tiles via een API aangeboden worden, gebruik dan de HTTP Header Content-Type om het gebruikte media type van de vector tiles weer te geven.

Omdat deze Prakrijktrichtlijn voorschrijft om Mapbox Vector Tile specification te gebruiken, geldt:

EIS Gebruik application/vnd.mapbox-vector-tile als media type (MIME) bij het aanbieden via het web.

5.3 Eis: gebruik HTTP Header Content-Encoding gzip

Voor allerlei bestanden wordt gzip compressie toegepast om de bestanden kleiner te maken bij het ophalen van de webserver. Via de generieke HTTP Header Content-Encoding: gzip wordt dit aangegeven. Ook voor vector tiles is deze gzip compressie vaak in gebruik. Als de gzip compressie niet kenbaar is gemaakt via de HTTP Header Content-Encoding, kunnen (bepaalde) clients de tiles niet goed verwerken. Bijvoorbeeld van OpenLayers is bekend dat deze de vector tiles dan helemaal niet kan verwerken.

EIS Als GZIP compressie gebruikt wordt op de webserver, geef dan de HTTP Header Content-Encoding: gzip mee.

5.4 Downloaden van vector tiles

Voor sommige doelen, zoals gebruik in offline systemen of voor het kopiëren van vector tiles voor installatie van een eigen vector tileserver, is het handig om meerdere vector tiles of een hele set van vector tiles in één bestand te kunnen downloaden. Er zijn meerdere manieren in gebruik, zoals in filebased databases als MBTiles of GeoPackage of het comprimeren (ZIPpen) van een directorystructuur met vector tiles. Elk van deze manieren kan geschikt zijn. Er is op dit moment geen specifieke eis of aanbeveling over op te nemen.

6. Documentatie

Het is belangrijk bij het aanleveren van een vector tile set (download of service) om de juiste metadata beschrijvingen en bron beschrijvingen mee te geven. Dit heeft een aantal technische voordelen en tegelijkertijd ook voordelen voor het delen, vinden en hergebruiken van bronnen.

6.1 Eis: OGC API Tiles "TileSet" requirement class

Als de vector tiles via de OGC API Tiles standaard worden aangeboden dan is in de core van de OGC standaard een TileSet requirement class beschreven. Deze bevat de beschrijving van de aangeboden vector tiles set en de bron beschrijving van de vector tiles (ook raster).

EIS Sluit aan bij de OGC API Tiles definitie en de TileSet requirement class endpoint.

De respons voorziet in metadata zoals beschreven door OGC Two Dimensional Tile Matrix Set and Tile Set Metadata 2.0 Standard.

Essentiele elementen van deze metadata zijn:

De metadata kan aanvullende informatie bevatten als:

6.2 Minimale aanbevelingen

In deze paragraaf staan meer details voor de verschillende metadata onderdelen die men kan aanleveren bij een vector tile set.

6.2.1 Aanbeveling: Data lagen

AANBEVELING Zorg in een JSON bestand voor een beschrijving van welke data lagen er aanwezig zijn in de vector tile set bij het onderdeel "Layers"

6.2.2 Aanbeveling: Overzooming

Voor een tiles endpoint is in de OGC API een tileMatrixSet te definiëren. Iedere tilematrix kan voorzien worden van tileMatrixSetLimits. Hierin wordt door middel van maxTileRow, minTileRow, maxTileCol en minTileCol voor ieder tileMatrix aangegeven welke tiles beschikbaar zijn voor welke zoomlevels . Deze definitie zorgt ervoor dat de client kan overzoomen op de vector tiles. Dit houdt in dat, wanneer vector tiles niet beschikbaar zijn op een bepaald zoom level, een client de vector tiles op kan halen van een bovenliggend zoomniveau voor de tileMatrixSet.

AANBEVELING tileMatrixsetlimits definiëren in de OGC API Tiles tilematrix beschrijving.

6.2.3 Aanbeveling: Data Attributen

AANBEVELING Geef aan welke attributen (properties) er beschikbaar zijn per data laag.

6.2.4 Aanbeveling: Bron annotatie

AANBEVELING Een JSON bestand kan de bronhouder bevatten, wat soms gewenst of vereist is om op te nemen in een applicatie. Zoals mogelijke copyright annotatie. Gebruik hiervoor 'Attribution'.

Optioneel kan ook een TileJSON worden toegevoegd. De bijlage TileJSON voorbeeld bevat als voorbeeld een minimale TileJSON response met een Custom projection in Rijksdriehoekstelsel (RD New), EPSG:28992.

AANBEVELING Lever een TileJSON document aan bij een vectortile set.

In TILEJSON:

6.2.5 Aanbeveling: Projection in TileJSON

AANBEVELING Lever een TileJSON met projectie (CRS) indien andere projectie dan EPSG:3857 gebruikt wordt. Gebruik hiervoor een Custom projection TileJSON

6.2.6 Aanbeveling: Gebruik format is tilejson parameter in het TileJSON path

Voeg 'f=tilejson' als parameter toe aan de url die de TileJSON levert. Voorbeeld: * https://example.com/ogc/v1/tiles/NetherlandsRDNewQuad?f=tilejson

6.2.7 Aanbeveling: Data lagen TileJSON

AANBEVELING Zorg in een TileJSON bestand voor een beschrijving van welke data lagen er aanwezig zijn in de vector tile set bij het onderdeel "Vector Layers"

6.2.8 Aanbeveling: Over- en underzooming TileJSON

Eén van de voordelen van het gebruik van een TileJSON bestand voor vector tiles is zogenaamde overzooming op lagen.

De layer definition met minzoom en maxzoom level definitie zorgt ervoor dat de client kan overzoomen op de vector tiles. Dit houdt in dat, wanneer vector tiles niet beschikbaar zijn op een bepaald zoom level, een client de vector tiles op kan halen van een bovenliggend zoomniveau.

AANBEVELING minzoom en maxzoom definiëren in de data lagen beschrijving.

6.2.9 Aanbeveling: Data Attributen TileJSON

AANBEVELING Geef aan welke attributen (fields) er beschikbaar zijn per data laag. Een TileJSON bestand bevat verder geen beschrijving van de attributen die beschikbaar zijn per data laag. Wij bevelen aan deze beschrijving los te documenteren of op te nemen als additionalProperties of description in de data laag beschrijving.

6.2.10 Aanbeveling: Bron annotatie TileJSON

Een TileJSON bestand kan de bronhouder bevatten, wat soms gewenst of vereist is om op te nemen in een applicatie. Zoals mogelijke copyright annotatie.

AANBEVELING Geef de bron attribution op in een TileJSON bestand, zodat deze zichtbaar is als annotatie op de kaart in de client.

6.3 API design rules Nederlandse Overheid

Verder raden wij aan ook te kijken naar de [API-Designrules] voor de Nederlandse overheid. Deze bevatten principes voor het aanbieden van APIs door Nederlandse overheidsorganisaties.

AANBEVELING Volg de aanbevelingen over documentatie uit de [API-Designrules] voor de Nederlandse overheid: https://docs.geostandaarden.nl/api/API-Designrules/#documentation

6.3.1 Aanbeveling: tile bestandsgrootte

De bestandsgrootte van rastertiles wordt beperkt door het aantal pixels (breedte en hoogte), de kleurdiepte en de variatie in pixelwaarden. De bestandsgrootte van vectortiles wordt bepaald door meerdere factoren:

  • het aantal objecten dat in een vectortile zitten
  • het aantal coördinaten dat de contouren van die objecten beschrijft
  • het aantal atributen van het object
  • de attribuutwaarden van het object

Het zorgvuldig kiezen van welke attributen worden opgenomen in tiles-datasets is van belang voor efficiënt gegevensbeheer. Door enkel de essentiële attributen toe te voegen, wordt onnodige gegevensuitwisseling voorkomen, wat de prestaties verbetert en de netwerkbelasting vermindert. Daarnaast kan het selectief opnemen van attributen waarop veelvuldig gefilterd wordt helpen bij het optimaliseren van de dataset voor specifieke gebruiksscenario's.

Het opvragen van extra informatie via een andere server op basis van een unieke identificatie die wel in de vectortegel beschikbaar is biedt real-time toegang tot actuele gegevens. Dit is vooral gunstig bij dynamische datasets, waarbij voorkomen wordt dat vectortiles herhaaldelijk gegenereerd moeten worden, of in situaties waar een hoge mate van actualiteit vereist is.

Bovendien maakt deze aanpak gecontroleerde toegang mogelijk op basis van autorisatie, waardoor bijvoorbeeld de privacy en beveiliging van persoonsgegevens worden gewaarborgd.

AANBEVELING Beperk de bestandsgrootte van een vectortile, in omvang en hoeveelheid vectoren. bijvoorbeeld 500kb of 100.000 features.

7. Styling

Voor het weergeven van vector tiles is een weergavestijl specificatie nodig die beschrijft welke data te tekenen, in welke volgorde, en in welke stijl.

7.1 Aanbeveling: Styling publiceren via OGC API Styles

Het OGC ontwikkelt [OGC-API-Styles] voor het publiceren, delen en vinden van kaart stijlen en bijbehorende resources.

AANBEVELING Lever de styling aan door middel van de OGC API Styles specificatie.

7.2 Aanbeveling: Styling specificatie encoding

[OGC-API-Styles] ondersteunt verschillende styling encodings, zoals JSON, HTML, CSS, SLD encoding en ook de Mapbox styling.

In de praktijk ondersteunt veel tooling de [Mapbox-Style-Specification] en zien we dat deze het meest wordt gebruikt.

AANBEVELING Specificeer de stijl conform de [Mapbox-Style-Specification]

7.3 Eis: Standaard stijl

Een vector tile set is moeilijk te gebruiken zonder styling. Door het aanleveren van minimaal 1 default stijl is de instap voor delen, hergebruik en aanpassing makkelijker. Dit zorgt ervoor dat de gebruiker / applicatie ontwikkelaar direct aan de slag kan.

EIS Lever altijd minimaal 1 standaard stijl aan bij een vector tile set.

7.4 Best practices styling

De styling hangt direct samen met de aangeleverde data in de vector tiles. Een goede inrichting van de data en de data attributen in samenhang met een goede styling opzet, is cruciaal voor de snelheid en gebruiksvriendelijkheid van de kaart en de vector tile service. Voor meer tips en tricks hierover zie het Best Practices document.

A. Coördinaat referentie systemen voor vector tiles

A.1 Coördinaat referentie systemen bij beoogd gebruik

Het OGC en W3C beschrijven in de Spatial Data on the Web Best Practices [SDW-BP] dat het CRS WGS84 vaak de voorkeur heeft. Een CRS kiezen dat bij de potentiële gebruikers breed bekend is, heeft voordelen in de adoptatie en het kunnen hergebruiken van data. Zie de paragrafen CRS background en Best practice 7:

Best Practice 7: Choose coordinate reference systems to suit your user's applications

Consider your user's intended application when choosing the coordinate reference system(s) used to publish spatial data

Veel tools ondersteunen latitude en longitude in WGS84 en bevatten vaak ook methodes om andere CRSen te ondersteunen. OGC APIs gaan in de basis uit van WGS84 als CRS. Via extensies kunnen andere CRSen ondersteund worden. De [Mapbox-Vector-Tile-Specification] gaat uit van de Web Mercator projectie (met WGS84 als datum) maar bevat verder geen verplichting voor een specifiek Coördinaat Referentie Systeem (CRS) voor vector tiles.

A.2 Onnauwkeurigheid WGS84 en bijstelling

Door tektonische verschuiving van Europa veranderen coördinaten in WGS84 en ITRS van punten in Nederland met 2,5 cm/jaar. Coördinaten in ETRS89 veranderen in Nederland niet vanwege tektonische verschuiving. Het verschil tussen WGS84 en ETRS89 is daardoor opgelopen tot ruim 0,8 m in 2020. WGS84 is daarom minder geschikt voor nauwkeurige toepassingen.

WGS84 wordt periodiek bijgesteld op basis van nieuwe metingen. Voor nauwkeurige eenduidige definitie van het CRS is het daarom nodig een specifieke realisatie van WGS84 te vermelden (bijvoorbeeld WGS84-G1762, EPSG:9057). Vanwege de tektonische verschuiving van Europa is het daarnaast nodig het tijdstip (epoche) van de geldigheid van de coördinaten te vermelden. Bij coördinaten die direct in WGS84 gemeten zijn (zoals met een niet-landmeetkundige GPS-ontvanger) is het epoche het tijdstip van de meting. Bij transformatie van RD/ETRS89 naar een WGS84-realisatie wordt impliciet een referentie-epoche gebruikt of moet de gebruiker een epoche opgeven. Wanneer geen specifieke WGS84-realisatie gespecificeerd wordt, dan wordt meestal een onnauwkeurige nul-transformatie tussen ETRS89 en WGS84 gebruikt.

Strikt genomen wordt met Web Mercator bij voorkeur bedoeld: Web Mercator op basis van WGS84-G1762, wat gelijkgesteld kan worden aan ITRF2008.

Voor publicatiedoeleinden bij de meeste (web)applicaties geldt dat WGS84 acceptabel is, ondanks de beschreven onnauwkeurigheid. En voor visualisatie van achtergrondkaarten betekent dat in web applicaties vaak Web Mercator. Als de vector tiles bedoeld zijn voor toepassingen die niet nauwkeuriger zijn dan 1 meter, is dit een voldoende nauwkeurig coördinaat referentie systeem.

In de Praktijkrichtlijn hanteren we voor Web Mercator de gangbare EPSG code EPSG:3857 (WGS84 / Pseudo-Mercator), met als Geodetisch CRS WGS84 conform EPSG:4326.

A.3 Impact onnauwkeurigheid gering voor beoogde vector tiling toepassingen

Voor het maken van vector tiles zullen geometriëen omgerekend worden naar het lokale stelsel van een vector tile, in integers (vaak in een bereik van 0-4096 bij 0-4096). Dit betekent dat de originele geometrie nauwkeurigheid verliest in een vector tile. De impact hiervan is voor de meeste datasets gering.

B. Bijlage TileMatrixSet Rijksdriehoekstelsel

Deze bijlage bevat encodings van de TileMatrixSet voor het Rijksdriehoekstelsel.

B.1 JSON encoding

{
    "title": "Amersfoort / RD New schema for the Netherlands",
    "id": "NetherlandsRDNewQuad",
    "uri" : "http://www.opengis.net/def/tilematrixset/OGC/1.0/NetherlandsRDNewQuad",
    "boundingBox": {
        "crs": "http://www.opengis.net/def/crs/EPSG/0/28992",
        "lowerLeft": [
            -285401.92,
            22598.08
        ],
        "upperRight": [
            595401.92,
            903401.92
        ]
    },
    "crs": "http://www.opengis.net/def/crs/EPSG/0/28992",
    "orderedAxes": ["X", "Y"],
    "tileMatrices": [
        {
            "id": "0",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 1.2288E7,
            "cellSize": 3440.64,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 1,
            "matrixHeight": 1
        },
        {
            "id": "1",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 6144000.0,
            "cellSize": 1720.32,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 2,
            "matrixHeight": 2
        },
        {
            "id": "2",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 3072000.0,
            "cellSize": 860.16,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 4,
            "matrixHeight": 4
        },
        {
            "id": "3",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 1536000.0,
            "cellSize": 430.08,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 8,
            "matrixHeight": 8
        },
        {
           "id": "4",
           "type": "TileMatrixType",
            "identifier": "4",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 768000.0,
            "cellSize": 215.04,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 16,
            "matrixHeight": 16
        },
        {

            "id": "5",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 384000.0,
            "cellSize": 107.52,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 32,
            "matrixHeight": 32
        },
        {
            "id": "6",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 192000.0,
            "cellSize": 53.76,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 64,
            "matrixHeight": 64
        },
        {
            "id": "7",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 96000.0,
            "cellSize": 26.88,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 128,
            "matrixHeight": 128
        },
        {
            "id": "8",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 48000.0,
            "cellSize": 13.44,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 256,
            "matrixHeight": 256
        },
        {
            "id": "9",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 24000.0,
            "cellSize": 6.72,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 512,
            "matrixHeight": 512
        },
        {
            "id": "10",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 12000.0,
            "cellSize": 3.36,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 1024,
            "matrixHeight": 1024
        },
        {
            "id": "11",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 6000.0,
            "cellSize": 1.68,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 2048,
            "matrixHeight": 2048
        },
        {
            "id": "12",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 3000.0,
            "cellSize": 0.84,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 4096,
            "matrixHeight": 4096
        },
        {
            "id": "13",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 1500.0,
            "cellSize": 0.42,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 8192,
            "matrixHeight": 8192
        },
        {
            "id": "14",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 750.0,
            "cellSize": 0.21,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 16384,
            "matrixHeight": 16384
        },
        {
            "id": "15",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 375.0,
            "cellSize": 0.105,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 32768,
            "matrixHeight": 32768
        },
        {
            "id": "16",
            "pointOfOrigin": [
                -285401.92,
                903401.92
            ],
            "scaleDenominator": 187.5,
            "cellSize": 0.0525,
            "tileWidth": 256,
            "tileHeight": 256,
            "matrixWidth": 65536,
            "matrixHeight": 65536
        }
    ]
}

B.2 XML Encoding

<?xml version="1.0" encoding="UTF-8"?>
<TileMatrixSet id="NetherlandsRDNewQuad"
               xmlns="http://www.opengis.net/tms/2.0"
               xmlns:tmsc="http://www.opengis.net/tms/2.0/common"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.opengis.net/tms/2.0 https://schemas.opengis.net/tms/2.0/xml/tilematrixset.xsd">
    <tmsc:Title>Amersfoort / RD New schema for the Netherlands</tmsc:Title>
    <tmsc:Identifier>NetherlandsRDNewQuad</tmsc:Identifier>
    <uri>http://www.opengis.net/def/tilematrixset/OGC/1.0/NetherlandsRDNewQuad</uri>
    <tmsc:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/28992" orderedAxes="X,Y">
        <tmsc:LowerLeft>-285401.92 22598.08</tmsc:LowerLeft>
        <tmsc:UpperRight>595401.92 903401.92</tmsc:UpperRight>
    </tmsc:BoundingBox>
    <tmsc:CRS>
        <tmsc:URI>http://www.opengis.net/def/crs/EPSG/0/28992</tmsc:URI>
    </tmsc:CRS>
    <OrderedAxes>X,Y</OrderedAxes>
    <TileMatrix>
        <tmsc:Identifier>0</tmsc:Identifier>
        <ScaleDenominator>1.2288E7</ScaleDenominator>
        <CellSize>3440.64</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>1</MatrixWidth>
        <MatrixHeight>1</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>1</tmsc:Identifier>
        <ScaleDenominator>6144000.0</ScaleDenominator>
        <CellSize>1720.32</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>2</MatrixWidth>
        <MatrixHeight>2</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>2</tmsc:Identifier>
        <ScaleDenominator>3072000.0</ScaleDenominator>
        <CellSize>860.16</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>4</MatrixWidth>
        <MatrixHeight>4</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>3</tmsc:Identifier>
        <ScaleDenominator>1536000.0</ScaleDenominator>
        <CellSize>430.08</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>8</MatrixWidth>
        <MatrixHeight>8</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>4</tmsc:Identifier>
        <ScaleDenominator>768000.0</ScaleDenominator>
        <CellSize>215.04</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>16</MatrixWidth>
        <MatrixHeight>16</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>5</tmsc:Identifier>
        <ScaleDenominator>384000.0</ScaleDenominator>
        <CellSize>107.52</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>32</MatrixWidth>
        <MatrixHeight>32</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>6</tmsc:Identifier>
        <ScaleDenominator>192000.0</ScaleDenominator>
        <CellSize>53.76</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>64</MatrixWidth>
        <MatrixHeight>64</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>7</tmsc:Identifier>
        <ScaleDenominator>96000.0</ScaleDenominator>
        <CellSize>26.88</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>128</MatrixWidth>
        <MatrixHeight>128</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>8</tmsc:Identifier>
        <ScaleDenominator>48000.0</ScaleDenominator>
        <CellSize>13.44</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>256</MatrixWidth>
        <MatrixHeight>256</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>9</tmsc:Identifier>
        <ScaleDenominator>24000.0</ScaleDenominator>
        <CellSize>6.72</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>512</MatrixWidth>
        <MatrixHeight>512</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>10</tmsc:Identifier>
        <ScaleDenominator>12000.0</ScaleDenominator>
        <CellSize>3.36</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>1024</MatrixWidth>
        <MatrixHeight>1024</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>11</tmsc:Identifier>
        <ScaleDenominator>6000.0</ScaleDenominator>
        <CellSize>1.68</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>2048</MatrixWidth>
        <MatrixHeight>2048</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>12</tmsc:Identifier>
        <ScaleDenominator>3000.0</ScaleDenominator>
        <CellSize>0.84</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>4096</MatrixWidth>
        <MatrixHeight>4096</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>13</tmsc:Identifier>
        <ScaleDenominator>1500.0</ScaleDenominator>
        <CellSize>0.42</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>8192</MatrixWidth>
        <MatrixHeight>8192</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>14</tmsc:Identifier>
        <ScaleDenominator>750.0</ScaleDenominator>
        <CellSize>0.21</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>16384</MatrixWidth>
        <MatrixHeight>16384</MatrixHeight>
    </TileMatrix>
     <TileMatrix>
        <tmsc:Identifier>15</tmsc:Identifier>
        <ScaleDenominator>375.0</ScaleDenominator>
        <CellSize>0.105</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>32768</MatrixWidth>
        <MatrixHeight>32768</MatrixHeight>
    </TileMatrix>
    <TileMatrix>
        <tmsc:Identifier>16</tmsc:Identifier>
        <ScaleDenominator>187.5</ScaleDenominator>
        <CellSize>0.0525</CellSize>
        <PointOfOrigin>-285401.92 903401.92</PointOfOrigin>
        <TileWidth>256</TileWidth>
        <TileHeight>256</TileHeight>
        <MatrixWidth>65536</MatrixWidth>
        <MatrixHeight>65536</MatrixHeight>
    </TileMatrix>
</TileMatrixSet>

C. Bijlage TileJSON voorbeeld

Deze bijlage bevat een voorbeeld van een (minimale) TileJSON response met de NetherlandsRDNewQuad tilematrixset in Rijksdriehoekstelsel (RD New), EPSG:28992.

C.1 JSON encoding

{
  "tilejson": "2.2.0",
  "name": "NetherlandsRDNewQuad",
  "description": "NetherlandsRDNewQuad as TileJSON (https://github.com/maptiler/tilejson-spec/tree/custom-projection/2.2.0)",
  "version": "1.0.0",
  "scheme": "xyz",
  "tiles": [
    "https://example.com/ogc/v1/tiles/NetherlandsRDNewQuad/{z}/{y}/{x}?f=mvt"
  ],
  "minzoom": 9,
  "maxzoom": 11,
  "profile": "custom",
  "crs": "EPSG:28992",
  "tile_matrix": [
    {
      "id": "9",
      "tile_size": [256, 256],
      "scale_denominator": 24000,
      "origin": [-285401.92, 903401.92]
    },
    {
      "id": "10",
      "tile_size": [256, 256],
      "scale_denominator": 12000,
      "origin": [-285401.92, 903401.92]
    },
    {
      "id": "11",
      "tile_size": [256, 256],
      "scale_denominator": 6000,
      "origin": [-285401.92, 903401.92]
    }
  ]
}

D. Lijst van afbeeldingen

E. Referenties

E.1 Informatieve referenties

[API-Designrules]
API Designrules (Nederlandse API Strategie IIa). W3C en OGC. Geonovum Standaard. URL: https://docs.geostandaarden.nl/api/API-Designrules/
[Mapbox-Style-Specification]
Mapbox Style Specification. Mapbox. v13.18.0. URL: https://docs.mapbox.com/mapbox-gl-js/style-spec/
[Mapbox-Vector-Tile-Specification]
Mapbox Vector Tile Specification. Mapbox. V2.1. URL: https://github.com/mapbox/vector-tile-spec/tree/master/2.1
[OGC-API-Styles]
OGC API Styles. OGC. DRAFT. URL: https://docs.ogc.org/DRAFTS/20-009.html
[OGC-API-Tiles-Core]
OGC API - Tiles - Part 1: Core. OGC. 1.0. URL: https://docs.ogc.org/is/20-057/20-057.html
[OGC-Two-Dimensional-Tile-Matrix-Set-and-Tile-Set-Metadata]
OGC Two Dimensional Tile Matrix Set and Tile Set Metadata. OGC. 2.0. URL: https://docs.ogc.org/is/17-083r4/17-083r4.html
[PBF]
Google Proto Buffers. Google. URL: https://developers.google.com/protocol-buffers/
[SDW-BP]
Spatial Data on the Web Best Practices. W3C en OGC. Best practice. URL: https://www.w3.org/TR/sdw-bp/
Geonovum Praktijkrichtlijn - Vastgestelde versie