Created
July 15, 2026 08:02
-
-
Save bartzwemmer/bc91fde4976299ce1aaabfb14a7c5c7f to your computer and use it in GitHub Desktop.
DuckDB SQL query to retrieve all current Panden (building foorprints) in The Netherlands from local BAG data.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Extensions, so we can read the zipped GML files | |
| INSTALL spatial; LOAD spatial; | |
| -- Combined Relational Model of BAG Objects (Panden, Verblijfsobjecten, Addresses, Public Spaces, Cities) | |
| -- Filters active records (eindGeldigheid IS NULL AND tijdstipInactief IS NULL) to prevent historical duplicate versions. | |
| WITH wpl_active AS ( | |
| SELECT | |
| identificatie, | |
| naam, | |
| status, | |
| geom | |
| FROM ST_Read('/vsizip/panden/9999WPL08072026.zip') | |
| WHERE eindGeldigheid IS NULL AND tijdstipInactief IS NULL | |
| ), | |
| opr_active AS ( | |
| SELECT | |
| identificatie, | |
| naam, | |
| type, | |
| woonplaatsRef, | |
| status, | |
| geom | |
| FROM ST_Read('/vsizip/panden/9999OPR08072026.zip') | |
| WHERE eindGeldigheid IS NULL AND tijdstipInactief IS NULL | |
| ), | |
| num_active AS ( | |
| SELECT | |
| identificatie, | |
| huisnummer, | |
| huisletter, | |
| huisnummerToevoeging, | |
| postcode, | |
| typeAdresseerbaarObject, | |
| openbareruimteRef, | |
| woonplaatsRef, | |
| status, | |
| geom | |
| FROM ST_Read('/vsizip/panden/9999NUM08072026.zip') | |
| WHERE eindGeldigheid IS NULL AND tijdstipInactief IS NULL | |
| ), | |
| vbo_active AS ( | |
| SELECT | |
| identificatie, | |
| gebruiksdoel, | |
| oppervlakte, | |
| hoofdadresNummeraanduidingRef, | |
| nevenadresNummeraanduidingRef, | |
| pandRef, | |
| status, | |
| geom | |
| FROM ST_Read('/vsizip/panden/9999VBO08072026.zip') | |
| WHERE eindGeldigheid IS NULL AND tijdstipInactief IS NULL | |
| ), | |
| pnd_active AS ( | |
| SELECT | |
| identificatie, | |
| oorspronkelijkBouwjaar, | |
| status, | |
| geom | |
| FROM ST_Read('/vsizip/panden/9999PND08072026.zip') | |
| WHERE eindGeldigheid IS NULL AND tijdstipInactief IS NULL | |
| ), | |
| -- Flatten Verblijfsobjecten by unnesting the pandRef list to support optimized hash joining | |
| vbo_flat AS ( | |
| SELECT | |
| identificatie, | |
| gebruiksdoel, | |
| oppervlakte, | |
| hoofdadresNummeraanduidingRef, | |
| nevenadresNummeraanduidingRef, | |
| unnest(pandRef) AS single_pand_ref, | |
| status, | |
| geom | |
| FROM vbo_active | |
| ) | |
| SELECT | |
| -- Pand attributes | |
| p.identificatie AS pand_identificatie, | |
| p.oorspronkelijkBouwjaar AS pand_oorspronkelijkBouwjaar, | |
| p.status AS pand_status, | |
| p.geom AS pand_geom, | |
| -- Verblijfsobject attributes | |
| v.identificatie AS vbo_identificatie, | |
| v.gebruiksdoel AS vbo_gebruiksdoel, | |
| v.oppervlakte AS vbo_oppervlakte, | |
| v.nevenadresNummeraanduidingRef AS vbo_nevenadres_refs, | |
| v.status AS vbo_status, | |
| v.geom AS vbo_geom, | |
| -- Nummeraanduiding (Address) attributes | |
| num.identificatie AS num_identificatie, | |
| num.huisnummer AS num_huisnummer, | |
| num.huisletter AS num_huisletter, | |
| num.huisnummerToevoeging AS num_huisnummer_toevoeging, | |
| num.postcode AS num_postcode, | |
| num.typeAdresseerbaarObject AS num_type_adresseerbaar_object, | |
| num.status AS num_status, | |
| num.geom AS num_geom, | |
| -- OpenbareRuimte (Public Space / Street) attributes | |
| opr.identificatie AS opr_identificatie, | |
| opr.naam AS opr_naam, | |
| opr.type AS opr_type, | |
| opr.status AS opr_status, | |
| -- Woonplaats (City/Town) attributes | |
| w.identificatie AS wpl_identificatie, | |
| w.naam AS wpl_naam, | |
| w.status AS wpl_status, | |
| w.geom AS wpl_geom | |
| FROM pnd_active p | |
| -- LEFT JOIN ensures all panden are returned, even if they have no verblijfsobject, address, or town | |
| LEFT JOIN vbo_flat v ON v.single_pand_ref = p.identificatie | |
| LEFT JOIN num_active num ON v.hoofdadresNummeraanduidingRef = num.identificatie | |
| LEFT JOIN opr_active opr ON num.openbareruimteRef = opr.identificatie | |
| -- COALESCE resolves the Woonplaats: use the override on the Nummeraanduiding if present, | |
| -- otherwise fall back to the Woonplaats of the OpenbareRuimte | |
| LEFT JOIN wpl_active w ON COALESCE(num.woonplaatsRef, opr.woonplaatsRef) = w.identificatie | |
| -- WHERE w.naam = 'Dordrecht' | |
| -- AND unnest(v.gebruiksdoel) = 'Woonfunctie' | |
| ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment