Eind november maakten we een interactieve kaart van het centrum van Valkenburg (Limburg) op basis van de gebouwen uit 3D Kaart NL met behulp van de JavaScript-bibliotheek OSM Buildings. In deze blog leggen we uit hoe we deze kaart hebben gemaakt en doen enkele aanbevelingen voor het leveren van 3D-gegevens.
Van geodatabase naar PostGIS
Het Kadaster biedt 3D Kaart NL aan als een gecomprimeerde Esri file geodatabase (FGDB). Geen ArcGIS softwarelicentie? Geen nood! Ook het open source programma ogr kan FGDB-bestanden lezen. Na het uitpakken van het ZIP-betand, kan met het commando ogrinfo
informatie worden opgevraagd over het bestand:
ogrinfo -so Valkenburg.gdb |
-so
(summary only) : Hiermee zorg je ervoor, dat alleen een korte samenvatting wordt weergegeven.
Dit commando geeft de volgende samenvatting weer over het bestand Valkenburg.gdb
:
Had to open data source read-only. |
Van de 14 thema’s in dit bestand lijkt het thema gebouw_3D_LOD0
het meest geëigend voor onze toepassing met OSM Buildings. We gebruiken opnieuw het commando ogrinfo
om uit te vinden, welke informatie in dit thema beschikbaar is:
ogrinfo -so Valkenburg.gdb gebouw_3D_LOD0 |
Een van de eigenschappen van het thema gebouw_3D_LOD0
is HOOGTE
. We gebruiken opnieuw het commando ogrinfo
om uit te vinden welke waarden deze eigenschap heeft:
ogrinfo -sql 'SELECT DISTINCT HOOGTE FROM gebouw_3D_LOD0' Valkenburg.gdb |
Dit commando geeft de volgende uitvoer:
Had to open data source read-only. |
Weliswaar is de geometrie van de gebouwen gemodelleerd als 3D Multi-polygonen, maar de eigenschap HOOGTE
bevat geen informatie! OSM Buildings heeft een GeoJSON-bestand nodig met de 2D-geometrie in WGS-84 coördinaten en met een eigenschap height
, die de hoogte in meters bevat. Die hoogte zullen we dus zelf moeten afleiden uit de 3D-geometrie. Hiervoor gebruiken we de ruimtelijke functies van PostGIS. Met het ogr2ogr
commando van ogr importeren we het thema gebouw_3D_LOD0
uit de FGDB in de database:
ogr2ogr -skipfailures -progress --config PG_USE_COPY YES -gt 65536 -s_srs "epsg:28992" -t_srs "epsg:28992" -lco GEOMETRY_NAME=geom -lco SPATIAL_INDEX=OFF -lco PRECISION=NO -nln valkenburg.buildings -f "PGDump" /vsistdout/ Valkenburg.gdb gebouw_3D_LOD1 | psql -q |
Gegevensbewerking in PostGIS
In de eerste plaats herprojecteren we de geometrie van de gebouwen van RD-coördinaten naar lengte- en breedtegraden in WGS-84 (ST_Transform). Vervolgens wordt de 3D-geometrie teruggebracht naar 2D (ST_Force_2D) om de GeoJSON kleiner te maken: OSM Buildings negeert de Z-coördinaat toch. Ten slotte zetten we de coördinaten in de juiste volgorde (ST_ForceRHR). Dit zorgt ervoor, dat OSM Buildings de muren kan visualiseren. Dankjewel voor de tip, @OSMBuildings!
Met de juiste functies is dit natuurlijk een koud kunstje voor PostGIS:
SELECT AddGeometryColumn ( |
Naast de 2D-geometrie willen we ook de hoogte van de gebouwen afleiden uit 3D-geometrie in het originele bestand. Met het commando ogrinfo
hadden we namelijk geconstateerd, dat de eigenschap HOOGTE
leeg is. Bovendien is deze eigenschap in het originele bestand als alfanumeriek veld (string) gedefinieerd. Dit kunnen we met PostGIS oplossen. In de eerste plaats veranderen we de definitie van de eigenschap HOOGTE
naar een numeriek veld tot op de meter om ruimte te besparen in het uiteindelijke GeoJSON-bestand. Vervolgens berekenen we het daadwerkelijke hoogteverschil, niet de maximale hoogte: de gebouwen zijn namelijk ook al op een hoogte geplaatst!
ALTER TABLE |
Ten slotte gebruiken we weer ogr
om de gegevens uit een tabel in PostGIS te converteren naar een GeoJSON-bestand. Als extra informatie nemen we het gebouwtype mee. Dit kunnen we gebruiken om gebouwen te classificeren:
ogr2ogr -f "GeoJSON" buildings.js PG:"host=${PGHOST} port=${PGPORT} dbname=${PGDATABASE} user=${PGUSER}" -sql "SELECT geometry, type_gebouw AS building_type, hoogte AS height FROM valkenburg.buildings" -lco COORDINATE_PRECISION=6 |
-lco
(layer creation option) COORDINATE_PRECISION=6
: Hiermee zorg je ervoor, dat je coördinaten slechts 6 decimalen hebben. Dit is nauwkeurig genoeg voor een webkaart!
Nu hebben we een GeoJSON-bestand, dat we kunnen gebruiken voor OSM Buildings.
OSM Buildings
Met de JavaScript-bibliotheek OSM Buildings kan je 3D gebouwen visualiseren in combinatie met OpenLayers 2.x en Leaflet. Inderdaad, de aanduiding OSM in OSM Buildings komt van OpenStreetMap. OSM Buildings gebruikt namelijk standaard de gebouwen uit de OpenStreetMap-database voor haar visualisaties, maar biedt je ook de optie om op basis van een eigen GeoJSON-bestand gebouwen te visualiseren. Deze laatste optie gebruiken we hier.
Op basis van het gebouwtype (de eigenschap building_type
) geven we muren en de daken een andere kleur:
var osmb = new OSMBuildings(map) |
De kleuren voor de verschillende gebouwtypes hebben we in een legenda-object gedefinieerd:
var Legend = { |
De benodigde bestanden zijn beschikbaar als een gist op GitHub. Zo krijgen we uiteindelijk de interactieve kaart van Valkenburg met gebouwen in 3D.
Aanbevelingen
Op basis van onze ervaringen hebben we drie aanbevelingen voor het leveren van 3D Kaart NL:
- Gebruik het veld
HOOGTE
: weliswaar is de geometrie beschikbaar in 3D, maar voor de meeste toepassingen is een hoogte al voldoende. We hebben nu het maximale hoogteverschil op basis van de 3D-geometrie gebruikt, maar je kan je ook voorstellen, dat je hiervoor bijvoorbeeld de meest voorkomende (modale) hoogte gebruikt. Definieer ten slotte de eigenschapHOOGTE
als een numeriek veld! - Maak de volgorde van de coördinaten rechtsdraaiend. Dit is een conventie om vectoren in 3 dimensies vast te leggen. De buitenste ring van een polygoon draait dan met de klok mee en de binnenringen draaien dan tegen de klok in. Gebruikten we de geometrienotatie 1:1 uit het bronbestand, dan tekende OSM Buildings de muren niet correct. Dit is wellicht ook voor andere grafische bibliotheken het geval.
- Verwijder fysieke kenmerken uit de eigenschap
GEBOUW_TYPE
. In het bronbestand is deze eigenschap een mengeling van gebruiksfuncties (gemeentehuis
,politiebureau
,sporthal
) en algemenere omschrijvingen (kasteel
,ruïne
). De waardereligieus gebouw, toren
voor de eigenschapGEBOUW_TYPE
duidt weer op een fysiek kenmerk. Dit fysieke kenmerk is in een 3D-bestand natuurlijk al impliciet vastgelegd.
In deze applicatie hebben we ons gericht op de gebouwen in 3D Kaart NL. Het vrijgeven van 3D Kaart NL was eerlijk gezegd vooral een aanleiding om eens met OSM Buildings aan de slag te gaan zónder eerst veel gegevensbewerking te moeten doen. Desalniettemin hebben we de smaak te pakken. Het is duidelijk: we staan aan het begin van een 3D-doorbraak!