Skip to content
Stefan de Konink edited this page Apr 27, 2018 · 4 revisions

Vectortiles zijn een nieuwe manier om geoinformatie en attributen uit te wisselen met een kaartapplicatie. In tegenstelling tot rastertiles of WMS wordt geometrie uitgewisseld tezamen met attributen. Zoals in de naam al is opgesloten worden vectoren gebruikt, daarmee is het mogelijk om op iedere schermresolutie kaartmateriaal van een hoge kwaliteit te tonen. Dit geeft het extra voordeel dat iedere laag in het kaartmateriaal, binnen de applicatie zelf, interactief kan worden voorzien van een eigen vormgeving. De informatie die wordt uitgewisseld is inhoudelijk analoog aan een GeoJSON bestand, echter voor de uitwisseling wordt in de applicatie uitgewisseld middels het binaire ProtoBuf formaat. De bestanden worden via de bekende Z/X/Y mappenstructuur met de applicatie uitgewisseld.

Om vectortiles aan te maken zijn er verschillende methodes bekend, het materiaal kan vooraf worden gegenereerd of op verzoek worden aangemaakt. Bij de productie vooraf kan een pbf mappenstructuur gemaakt worden, of kunnen alle bestanden worden samengevoegd tot een enkel MBTiles bestand. In met een normale mappen structuur kan een standaard webserver dienen als vector tile server, wanneer mbtiles wordt of directe generatie van pbf wordt gebruikt, is een specialistisch product benodigd. Verschillende producten leveren ook een gecombineerde oplossing waar door het tijdelijk opslaan van pbf bestanden de belasting op de database wordt verlaagd en daarmee de snelheid aanzienlijk wordt verbeterd. In deze introductie kijken we naar methodes om vanuit open data tot een interactieve kaart te komen.

Van Open Geodata tot Kaartmateriaal

De geostandaarden die worden gebruikt om open data uit te wisselen staan niet in dezelfde vorm geschreven als het vectortile formaat waarmee we een kaartapplicatie willen voorzien. De data die we hebben ingewonnen zullen we daarom moeten vertalen in het vector tile formaat. In sommige gevallen zal het mogelijk zijn om rechtstreeks uit het bronformaat te converteren naar mbtiles, terwijl het voor andere producties eenvoudiger is om de data eerst in een database te laden en pas daarna te om te zetten.

Rechtstreekse conversie via GDAL

Vanaf GDAL 2.3 is het mogelijk om vanaf ieder bestandsformaat dat GDAL ondersteunt via de Mapbox Vector Tile (MVT) Driver MBTiles te produceren. Op het moment van schrijven deze versie nog niet beschikbaar in gangbare distributies.

De weg via een database

Op het moment dat er grootschalige bewerkingen moeten worden gedaan op data, is het vaak eenvoudiger en sneller om de gegevens eerst in een database te laden. Binnen het OSGeo domein wordt de PostgreSQL database met PostGIS extensie het meeste gebruikt om deze transformaties in uit te voeren. NLExtract levert de zowel de software om brongegevens zoals BAG of BRK in PostgreSQL te kunnen laden, als de bestanden welke rechtstreeks in PostgreSQL kunnen worden geladen.

Het laden van de brondata in PostgreSQL

Na het downloaden van de laatste database herstel bestanden van NLExtract, wordt de database herstel functie gedraaid. Het resultaat is een actuele en volledig gevulde database. In het voorbeeld wordt de gebruiker postgres ingezet om in de database te schrijven, het is voor veiligheid van het systeem verstandig om een nieuwe gebruiker aan te maken die alleen relevante tabellen mag lezen.

wget https://data.nlextract.nl/brk/postgis/brk-latest.backup
pg_restore -O -U postgres -d nlextract brk-latest.backup

wget https://data.nlextract.nl/bag/postgis/bag-laatst.backup
pg_restore -O -U postgres -d nlextract bag-laatst.backup

Het bewerken van brondata

Vector tiles kunnen dezelfde informatie bevatten als we gewend zijn van een GeoJSON of een ESRI Shape bestand. Het is een goed gebruik om alleen de attributen mee te nemen in de vector tiles die daadwerkelijk invloed zullen hebben op de vormgeving van het kaartmateriaal. Ook kan het interessant zijn om attributen of geometrie vooraf te generaliseren, zodat de complexiteit wordt beperkt. Door hierbij een goede afweging te maken worden de vector tiles in omvang kleiner en is het sneller in de applicatie te bekijken, zonder dat dit invloed is op de gewenste cartografie.

Op dit moment zijn de bibliotheken om vector tiles weer te geven beperkt tot 2D objecten en de Web Mercator projectie (EPSG:3857). Een geokolom welke al is geprojecteerd zal sneller tot een data selectie en weergave kunnen komen. Omdat de geokolom constant wordt gebruik voor het maken van een selectie, kan een verdere versnelling worden gerealiseerd door het indexeren van de geokolom. Om bovenstaande te realiseren kan er in de database een materialized view worden gemaakt. Deze tabel bestaat uit het resultaat van de query en haar kolomen zijn zelfstandig te indexeren. De brontabel kan vanaf dat moment worden aangepast, zonder dat dit invloed heeft op de productieproces van het kaartmateriaal, daarnaast blijft ook de query behouden die tot de tabel heeft geleid. Na het verversen van de materialized view lopen beide tabellen weer synchroon.

CREATE SCHEMA vt;
CREATE MATERIALIZED VIEW vt.perceel SELECT ogc_fid AS gid, sectie, perceelnummer, waarde, ST_Transform(begrenzing, 3857) AS geom FROM latest.perceel;
CREATE INDEX vt.perceel_geom_idx ON vt.perceel USING gist(geom);
CREATE MATERIALIZED VIEW vt.pand SELECT gid, bouwjaar, ST_Transform(ST_Force2D(geovlak), 3857) AS geom FROM bagactueel.pand;
CREATE INDEX vt.pand_geom_idx ON vt.pand USING gist(geom);
CREATE MATERIALIZED VIEW vt.adres SELECT gid, openbareruimtenaam, huisnummer, huisletter, huisnummertoevoeging, postcode, woonplaatsnaam, gemeentenaam, provincienaam, ST_Transform(ST_Force2D(geopunt), 3857) AS geom FROM bagactueel.adres;
CREATE INDEX vt.adres_geom_idx ON vt.adres USING gist(geom);
CREATE USER vt WITH PASSWORD 'kortwachtwoord';
GRANT SELECT ON ALL TABLES IN SCHEMA vt TO vt;

Onderstaande is alleen nodig na het bijwerken van de tabellen latest.perceel en bagactueel.pand.

REFRESH MATERIALIZED VIEW vt.perceel;
REFRESH MATERIALIZED VIEW vt.pand;

Het serveren van vectortiles

Voorgegenereerde bestanden

Tileserver GL (MBTiles)

Met Tileserver GL kunnen zowel applicaties die alleen rastertiles kunnen tonen, als applicaties die vectortiles kunnen verwerken op basis van dezelfde brondata worden voorzien van dezelfde informatie.

mbtileserver (MBTiles)

Een implementatie van een kleine webserver in de programmeertaal Go welke direct kan worden ingezet om kaartmateriaal in MBTiles te serveren.

Een standaard webserver (PBF)

Op het moment dat pbf bestanden worden gegenereerd kan met een standaard webserver de mappenstructuur worden geserveerd.

Vanuit een database

Vanuit een PostgreSQL database met PostGIS extensies kunnen we rechtstreeks een vector tile server draaien, hiervoor zijn verschillende producten beschikbaar met elk voor en nadelen.

Tegola

Tegola is een server geschreven in de programmeertaal Go, welke op basis van een handgeschreven configuratie werkt. Wanneer de configuratie wordt opgeslagen als config.toml, kan de applicatie worden gestart met tegola_linux_amd64 serve.

[webserver]
port = ":8111"                            # de poort waar de webserver op draait

[cache]
type="file"                               # cache type
basepath="/var/tmp/brk/cache"             # cache specific config

[[providers]]
name = "postgresql"                    # provider naam wordt uit de maplagen aangeroepen
type = "postgis"                       # op dit moment is alleen de optie postgis beschikbaar
host = "localhost"                     # postgresql database host
port = 5432                            # postgresql database poort
database = "nlextract"                 # postgresql database naam
user = "vt"                            # postgresql database gebruiker
password = "kortwachtwoord"            # postgresql database wachtwoord
srid = 3857                            # The standaard srid voor deze this provider.

    [[providers.layers]]
    name = "pand"                      # wordt de laagnaam in de tiletile
    tablename = "vt.pand"              # tabelnaam
    id_fieldname = "gid"               # geom id veld. default is gid
    geometry_fieldname = "geom"        # geom veld. standaard is geom
    srid = 3857                        # de SRID van het geom veld, als het afwijkt
    fields = [ "bouwjaar" ]            # overige velden voor het select statement

    # Analoog aan bovenstaande zou zijn:
    # name = "pand"
    # id_fieldname = "gid"
    # geometry_fieldname = "geom"
    # srid = 3857
    # sql = "SELECT gid, ST_AsBinary(geom) AS geom, bouwjaar FROM vt.pand WHERE geom && !BBOX!"

    [[providers.layers]]
    name = "perceel"
    tablename = "vt.perceel"
    fields = [ "sectie", "perceelnummer", "waarde" ]

    [[providers.layers]]
    name = "adres"
    tablename = "vt.adres"
    fields = [ "openbareruimtenaam", "huisnummer", "huisletter", "huisnummertoevoeging", "postcode", "woonplaatsnaam", "gemeentenaam", "provincienaam" ]


# maps are made up of layers
[[maps]]
name = "nlextract"                     # wordt gebruikt in de URL naar deze kaart (/maps/:map_name)
    [[maps.layers]]
    provider_layer = "postgresql.pand" # moet verwijzen naar de data provider laag
    min_zoom = 14                      # minimum zoom niveau voor deze laag
    max_zoom = 18                      # maximale zoom niveau voor deze laagthis layer

    [[maps.layers]]
    provider_layer = "postgresql.perceel" 
    min_zoom = 14
    max_zoom = 18

    [[maps.layers]]
    provider_layer = "postgresql.adres"
    min_zoom = 13
    max_zoom = 18

T-rex

T-rex is een server geschreven in de programmeertaal rust, welke op basis van een nagenoeg automatisch gegenereerde configuratie kan werken, bij het schrijven van deze handleiding hebben we handmatig een configuratie moeten maken.

./t_rex genconfig --dbconn postgresql://vt@localhost/nlextract > t_rex.conf
[service.mvt]
viewer = true

[[datasource]]
name = "database"
dbconn = "postgresql://[email protected]/top10nl"


[grid]
# Predefined grids: web_mercator, wgs84
predefined = "web_mercator"

[[tileset]]
name = "percelen"

[[tileset.layer]]
name = "percelen"
table_name = "vt.perceel"
geometry_field = "geom"
geometry_type = "POLYGON"
fid_field = "gid"
tile_size = 4096
simplify = false
#buffer_size = 10

[[tileset.layer.query]]
minzoom = 0
maxzoom = 22
sql = "SELECT gid, waarde, geom FROM vt.perceel"

# [cache.file]
# base = "/tmp/mvtcache"
# baseurl = "http://example.com/tiles"

[webserver]
# Bind address. Use 0.0.0.0 om op alle netwerk adressen te luisteren.
bind = "0.0.0.0"
port = 6767
threads = 4

Het opstarten van de server:

./t_rex serve -c t_rex.conf