3D Basisregistratie Adressen en Gebouwen (BAG)

Map Downloads Data quality Documentation Software Terms of use Contact


The Basisregistraties Adressen en Gebouwen (BAG) is the most detailed, openly available data set on buildings and addresses in the Netherlands. It contains information about each address in a building, such as its current use, construction date or registration status. The polygons in the BAG represent the footprint of the building as the projection of the roof’s outline. The data set is regularly updated as new buildings are registered, built or demolished. The project NLExtract prepares a monthly PostgreSQL backup of the BAG, which is then used as basis for the 3D BAG.

The Actueel Hoogtebestand Nederland (AHN) is the openly available elevation model of the Netherlands obtained by aerial laser scanning. It is accessible in raster and raw point cloud (LAZ) format. The current is the third version which does not cover the whole country yet, therefore it needs to be extended with the previous version to obtain full coverage. The for disseminating the AHN efficiently, the area of the Netherlands is split into 1377 tiles.

The missions for acquiring the AHN2 and AHN3 lasted 2007–2012 and 2014–2019 respectively. Thus AHN3 does not cover the whole Netherlands yet and it is expected to be complete by the end of 2019. Until then, parts of the previous version (AHN2) need to be used for achieving a complete coverage of heights. One of the main arguments against the AHN in general that is deemed to be out dated by design, due to long mission times for acquiring the scans. However, the building stock changes in a relatively slow pace, this pace being faster in metropolitan regions and even slower in remote areas of the country. In fact, our analysis shows that 96.33% of the measured building heights are still valid. This means that the respective point cloud and the age of the building are related.

The engine behind the software that is used for generating the 3D BAG (see Software) is 3dfier which takes 2D GIS data sets (eg BAG) and 3dfies them by lifting each polygon to a height obtained from a point cloud (eg AHN), thus generating LoD1 models (block models). Although for LoD1 building models the top surface (or roof) is set to a uniform height per building, one of the strengths of 3dfier is the possibility to set the height of the top surface at the desired height relative to the points representing the building.

The last piece is PostgreSQL which is used for storing the BAG, the tile indices and finally storing and serving the 3D BAG. The AHN files are stored in the local file system.

Description of the 3D BAG attributes

The table below describes the attributes that we add to the BAG attributes.

Attribute Description
ground-00, ground-10, ground-20, ground-30, ground-40, ground-50 The height of the ground surface of the building at the given percentile.
roof-00, roof-10, roof-25, roof-50, roof-75, roof-90, roof-95, roof-99 The height of the roof surface of the building at the given percentile. For example roof-99 is the height of the building when the roof surface is set at the 99th percentile of the z-coordinates of the point cloud of the building.
rmse-00, rmse-10, rmse-25, rmse-50, rmse-75, rmse-90, rmse-95, rmse-99 The Root Mean Square Error or the geometric difference between the 3D building model and the point cloud that was used for generating the model. Or, the average discrepancy in meters between the 3D building model and the real-world building. This measure also accounts for the whole building, not only the roof.
roof_flat Indicates that roof of the real-world building is flat or not. The value 1 means a flat roof, the value 0 means a not flat roof.
The classification is still under development, with a current accuracy of 80%.
nr_ground_pts The number of points in the point cloud that were used for determining the ground-height of the building model. If this value is 0, that means that the ground-points are missing from the point cloud at given model.
nr_roof_pts The number of points in the point cloud that were used for determining the roof-height of the building model. If this value is 0, that means that the roof-points are missing from the point cloud at given model.
ahn_version The version of the AHN that was used to obtain the height information.
ahn_file_date The creation date of the AHN file that was used to obtain the height information. This is not the same as the timestamp of the LiDAR points of a particular building.
tile_id The ID of the tile where the building belongs to.

Frequently Asked Questions

What is LoD1?

LoD is an abbreviation of Level of Detail and it is a term used by the CityGML standard for 3D city models. In short, the LoD decribes the amount of abstraction in a 3D city model. The graphic below shows the five levels of detail that CityGML defines. From the 3D BAG you can easily generate 3D building models of LoD1.

The Levels of Detail in CityGML 2.0. For more detail see: DOI

What do the roof percentiles correspond to?

In the 3D BAG we report the height of the top surface at seven different levels and leave to the user to choose what best fits its requirements. However, representing the roof with a single height has its own challenges, particularly when the height information is derived from aerial LiDAR such as the AHN. The graphic below shows how to interpret the height values at different percentiles in the 3D BAG. At the same time it shows the case when the point cloud of a building (red points) includes points on the wall and how that might influence the height of the top surface of the model (blue) in particular at lower percentiles such as percentile 00–25. The “wall points” skew the percentiles therefore the range 00–25 might be less accurate for determining the roof height.


How do we filter the BAG?

Not all buildings are used for the 3D BAG that are present in the BAG. The NLExtract delivers a database table called "pandactueelbestand", and this is what is used as input for the 3D BAG. The "pandactueelbestand" contains only those buildings that satisfy the following condition:

begindatumtijdvakgeldigheid <= now
AND (einddatumtijdvakgeldigheid IS NULL OR einddatumtijdvakgeldigheid >= now)
AND aanduidingrecordinactief = FALSE
AND geom_valid = TRUE
AND pandstatus IS NOT 'Niet gerealiseerd pand'
AND pandstatus IS NOT 'Pand gesloopt'
AND pandstatus IS NOT 'Bouwvergunning verleend'

How do we partition the BAG?

Furthermore, in order to be able to 3dfy any size of data set the input is processed parallel, tile by tile. Therefore the bottleneck becomes the size of a single tile. Both footprint and point cloud tiles need to be small enough, so that 3dfier can process them on your machine. Therefore a central element for bag3d is the tile index.

In bag3d the term tile refers to a data subset (footprints or point cloud), that falls within the limits of a tile index unit. A footprint belongs to a tile, if its centroid is in the interior of a tile index unit or on the left or lower edge of a tile index unit. Therefore a footprint is guaranteed to belong to only a single tile.

A tile index is a polygonal tesselation of the BAG or the AHN. A tile index unit is one polygon in the tile index and it usually has an ID (e.g. 1) and a name (e.g. 25gn1) that uniquely identifies it. This concept is used by the AHN tile index, which served as an example for development.

In the 3D BAG, the AHN tile index is used for partitioning the BAG thus the AHN and BAG tiles are equivalent, both in geometry and ID. But matching footprint and point cloud tiles is not a requirement as for each footprint tile the intersecting point cloud tiles are selected. And in case you are wondering how to generate a tile index, the Create grid Processing algorithm in QGIS might be a good starting point.

Which LAS classes do we use from the AHN?

For the building roof heights:

For the building ground heights:

This is true also for the tiles that are on the border of the AHN2 and AHN3 coverage. These tiles are generated twice, then merged in order to really use the latest available height data for each building. The reason for doing this merging is that the AHN3 tiles on the border with AHN2 only partially contain data (see for example PDOK forum).