Start_date=1900 bij oudere gebouwen

Veel gebouwen hebben de tag start_date=1900 terwijl ze (veel) eerder zijn gebouwd. Nadat de gegevens in OSM zijn geïmporteerd heeft het Kadaster het bouwjaar van oude gebouwen bijgewerkt.

Hier een voorbeeld van de gegevens uit de BAG-viewer over de Sint Jan in Den Bosch.

Wat is een handige manier om de nieuwe data in OSM te krijgen?

Simpel: Als dit het enige is waarin de BAG afwijkt voor een specifiek gebouw, gewoon de datum overschrijven.

Als de actuele waarde in BAG 1900 is en je weet de correcte datum, terugmelding BAG doen en na verwerken hiervan de datum overschrijven.

Wijken er meer zaken af dan alleen de start_date dan is het wellicht verstandiger een (her)import aan te vragen op dit forum (BAG-topic)

1 Like

Ik denk dat bij veel oude gebouwen 1900 als startdatum staat. Ter vergelijking het centrum van Den Bosch voor 3 opeenvolgende jaren 1899, 1900 en 1901.



Het is nog leuker. Ik heb zelf een beetje een analyse gedaan van alle BAG gebouwen in nederland, en er zijn best wel veel gebouwen met een incorrecte start_Date. Een goed aantal zijn overduidelijk typfouten 1097 of 197 ipv 1997 bijvoorbeeld, er zijn een aantal met 9999. En dan is er ‘The big one’, er zijn 10471 gebouwen met de start_date 1005, allemaal in Amsterdam. Volgens mij stond dit vroeger zo in BAG, want ik heb gezien dat een aantal oude verwijderde gebouwen in BAG deze start_date hebben.

Klinkt alsof er in het OSM-universum niet heel veel met die datum gedaan wordt.

Ik was hier al een beetje mee bezig geweest een paar weken geleden.

Ik heb code geschreven om alle nederlandse gebouwen the dowloaden uit OSM, en ik ben van plan om te proberen code te schrijven om de BAG extracten te parsen. Dan kan ik vervolgens heel erg makkelijk de BAG en OSM data vergelijken en hieruit fouten opsporen. Dingen zoals een niet overeenkomende start_date of constructie status bijvoorbeeld.

Het BAG gedeelte ziet er echter uit alsof het best wel wat tijd zou gaan kunnen kosten, en ik weet niet hoeveel tijd ik hier voor beschikbaar heb helaas.

3 Likes

Als het gaat om het markeren van gebouwen als rijksmonument - waar ik mee bezig ben geweest - dan wordt de correcte start_date relevant.

Nou weet ik natuurlijk niet wat de relevantie voor andere gebruikers of data-afnemers is.

Ken je nlextract?

Nee, had daar nog niet van gehoord. Ik zal er eens naar gaan kijken. Is dat makkelijker om mee te werken?

Ja en nee. Als vanuit de BAG plug-in de geometrie van een pand wordt aangepast, wordt ook het bouwjaar meegenomen. Maar niet systematisch door heel Nederland.

Een aantal jaar geleden heb ik een stukje van de Achterhoek systematisch aangepast aan de hand van een vergelijking tussen exports uit de BAG en OSM. Naar aanleiding van deze posts het er weer bijgepakt. In de Achterhoek zijn bijna 3000 panden waarvoor het bouwjaar niet gelijk is.

Naast de XML biedt het het Kadaster ook een GeoPackage aan.(BAG))
Dit is een kant en klaar geo-database-bestand. Daar is heel veel mee te doen, maar niet alles. Bouwjaren van aanwezige panden is typisch iets dat er in zit. Ingetrokken adressen is (als ik het me goed herinner) iets dat er niet in zit.

Het ding is dat we alle gebouwen hebben geïmporteerd in 2014. En we houden dat niet systematisch bij. Alles moet handmatig geüpdatete worden. Op dit moment zijn er gebieden in Nederland waar er geen adressen of gebouwen missen. Maar dat betekent niet dat de gebouwen die ooit geïmporteerd zijn nog kloppen.

Het is mogelijk om een heel gebied volledig te updaten: achavi - Augmented OSM Change Viewer  [attic]

Maar dat kan alleen als het gebied niet te veel gebouwen bevat (niet meer dan 10k). En dan nog zijn alle tags die op building nodes zitten handwerk. Zoals entrances building passages etc.

Als wij willen dat OSM en de BAG meer up to date zijn dan zullen we moeten gaan kijken om een deel van dit handwerk te automatiseren. Een aantal tasks die makkelijk geautomatiseerd zouden kunnen worden zijn onder andere:

  • Nieuw adres importeren
  • Revoked adres verwijderen
  • Start_date updaten
  • ID updaten
2 Likes

Redelijk gemakkelijk, afhankelijk van je kennis en ervaring. Voor jouw doel echter misschien een beetje overkill, omdat je alleen de panden nodig hebt en dan waarschijnlijk genoeg hebt aan het pand id en het bouwjaar. Dan is xslt misschien meer geschikt.
Ik heb als test met xslt een cvs bestand gemaakt met 2 kolommen (identificatie en bouwjaar). Daarmee dacht ik klaar te zijn, totdat ik me realiseerde dat de BAG ook historie bevat. Ik kreeg een cvs bestand met 21286110 regels, terwijl de BAG ‘maar’ zo’n 12 miljoen panden bevat.
Nog even terug naar de tekentafel om een aantal filters toe te voegen. Daarmee kwam ik uit op dit xslt script:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:sl-bag-extract="http://www.kadaster.nl/schemas/lvbag/extract-deelbestand-lvc/v20200601" xmlns:Objecten="www.kadaster.nl/schemas/lvbag/imbag/objecten/v20200601" xmlns:Objecten-ref="www.kadaster.nl/schemas/lvbag/imbag/objecten-ref/v20200601" xmlns:sl="http://www.kadaster.nl/schemas/standlevering-generiek/1.0" xmlns:Historie="www.kadaster.nl/schemas/lvbag/imbag/historie/v20200601">
  <xsl:output method="text" indent="no"/>

  <xsl:template match="/sl-bag-extract:bagStand">
<!--    <xsl:text>identificatie,bouwjaar&#10;</xsl:text>-->
      <xsl:apply-templates select="sl:standBestand/sl:stand/sl-bag-extract:bagObject/Objecten:Pand"/>
  </xsl:template>

  <xsl:template match="Objecten:Pand">
    <xsl:if test="not(Objecten:voorkomen/Historie:Voorkomen/Historie:eindGeldigheid) and not(Objecten:voorkomen/Historie:Voorkomen/Historie:BeschikbaarLV/Historie:tijdstipEindRegistratieLV) and not(Objecten:voorkomen/Historie:Voorkomen//Historie:BeschikbaarLV/Historie:tijdstipnietbaglv) and not(Objecten:voorkomen/Historie:Voorkomen/Historie:BeschikbaarLV/Historie:tijdstipinactiefLV)">
      <xsl:value-of select="Objecten:identificatie" />,<xsl:value-of select="Objecten:oorspronkelijkBouwjaar"/><xsl:text>&#10;</xsl:text>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

Het xslt script verwerkt een enkel ‘9999PND*.xml’ bestand. Er moet dus nog wat OS-specifieke scripting omheen om alle ruim 2000 xml bestanden uit ‘9999PND*.zip’ te verwerken.

Voor linux heb ik het onderstaande script gemaakt. Voor Windows powershell of Mac zal je het een beetje moeten aanpassen.

#unzip -o 9999PND08062023.zip
echo "identificatie, bouwjaar" > pand_bouwjaar.csv
for file in 9999PND*.xml; do
    xsltproc pand_bouwjaar_0_2.xslt "$file" >> pand_bouwjaar.csv
done
# rm 9999PND*.xml

Dit resulteert na 17 min op een huis-tuin-en-keuken laptop in een csv bestand met de identificatie en het bouwjaar van 11923157 actuele BAG panden. 262 MB (30 MB gezipt), dus een beetje groot om te mailen.

Hm… je hebt geautomatiseerd, en je hebt geautomatiseerd. Kan dit helemaal zonder handwerk? Bv een periodieke taak die uit de BAG leest, vergelijkt met OSM, nieuwe toevoegt, verwijderde weghaalt, en bij matches de start_date overneemt en de ID aanpast? (En daarvan een mooi logje produceert natuurlijk)?

Dat zou dan wel de eerste geautomatiseerde bron=> OSM update zijn die ik tot nu toe gezien heb… de meeste zijn een vrij moeizaam geheel van handmatig werk met hier en daar geautomatiseerde dingen. Veel tools, en zelf aan elkaar knopen zeg maar.

Mijn ervaring is inmiddels dat met de BAG plug-in een hele solide basis is om vanuit te werken. Daar zijn ook export bestanden bij om gericht missende panden op te voeren. Dan is er nog een check mogelijk met luchtfoto of in het terrein.

Alles wat je volledig automatisch wilt doen wordt al snel heel ingewikkeld vanwege de vele uitzonderingen, definitie verschillen en inpassen binnen bestaande geometrie.

Met automatisch bedoel ik dat als een adres of gebouw aangemaakt of veranderd dat dat dan binnen een minuut zonder omkijken van ons in OSM wordt gezet. En dan het liefst met één changeset per change/gebied. En niet op een vaste tijd over heel Nederland.

Ja in principe kan alles volledig geautomatiseerd worden. Alleen is er voor elke taak een kans dat dit niet kan. Per taak verschilt dat, bijvoorbeeld een nieuw adres importeren kan altijd. Maar een adres weghalen alleen als dat adres geen POI-data bevat.

Zo heeft elke taak een lijst van uitzonderingen en condities van het uitvoeren van de taak. Zo moet bij het aanpassen van de gebouw omtrek de ingangen weer gesnaped worden naar de dichtstbijzijnde building way.

Een nieuw gebouw kan niet geïmporteerd worden als een er significante overlap is met een gebouw wat handmatig getekend is. Etc.

Waar het om gaat is dat het merendeel van de updates volledig automatisch kunnen en dat we daardoor ons kunnen focussen op de niet te automatiseren delen.

Ook ligt het eraan hoe je tegen het importeren van bag staat. Vind je dat wij als mappers de fouten van het kadaster over kunnen nemen of moeten wij die fixen?

1 Like

Dat zijn precies de soort dingen waardoor het volautomatisch synchronizeren niet lukt. Om de bulk volleduig te kunnen automatiseren, moet je dus tevoren alle mogelijke uitzonderingen (die best wel vaak voorkomen) eruit filteren en apart behandelen. En dat voor verschillende “taken”. MIsschien kan het wel - maar wie gaat dat maken?

Bedankt voor deze snippets. Heb dit werkend kunnen krijgen en heeft alles voor mij een stuk makkelijker gemaakt. Heb nog wel een klein vraagje, als ik nu ook nog de status van de gebouwen wil hebben, hoe zou ik dit dan moeten toevoegen aan dit xslt script?

Na het verwerken van beide datasets (note: osm data van 23 mei, bag data van 08 mei) heb ik een aantal dingen geconstateerd:

in osm staan:

  • 10.779.634 gebouwen met de tag “bag:ref”.
  • 1.277.458 gebouwen zijn niet van hun leading zero’s gestript.
  • 46.791 gebouwen zonder start_date
  • 109 gebouwen met een verkeerd start_date formaat (bijvoorbeeld: “~1995”, “1885-1998”, “C20”)
  • 1.183.906 gebouwen minder dan in bag. (bag bevat ook gesloopte panden, maar dat kan nooit 1.2M zijn lijkt me)

en tot slot: In osm staan 252.143 gebouwen met een start_date dat niet overeen komt met bag (dit is inclusief de 46k missende en 109 incorrecte)

Ik heb hier 2 bestanden.
een json bestand (18.5MB) met alle bag id’s zoals deze in osm staan met de incorrecte en correcte start_date (dus: “3100000121797”: {“bag”: 1949, “osm”: 1959})
en een cvs bestand (5.5MB)met ook alle bag id’s zoals in osm maar alleen de correcte start_date zoals deze in bag staat.

1 Like

Mooi werk!
Op welk OS werk jij? Als dat Windows of Apple is kan je misschien je script delen met de gemeenschap.

Status toevoegen kan met een extra komma en xsl:value-of tag. Vanwege de spaties in de status is het verstandig om deze tussen dubbele quotes te zetten. Denk ook aan de kolom kop in het command-line script.

Hier de xlst met status toegevoegd:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:sl-bag-extract="http://www.kadaster.nl/schemas/lvbag/extract-deelbestand-lvc/v20200601" xmlns:Objecten="www.kadaster.nl/schemas/lvbag/imbag/objecten/v20200601" xmlns:Objecten-ref="www.kadaster.nl/schemas/lvbag/imbag/objecten-ref/v20200601" xmlns:sl="http://www.kadaster.nl/schemas/standlevering-generiek/1.0" xmlns:Historie="www.kadaster.nl/schemas/lvbag/imbag/historie/v20200601">
  <xsl:output method="text" indent="no"/>

  <xsl:template match="/sl-bag-extract:bagStand">
<!--    <xsl:text>identificatie,bouwjaar&#10;</xsl:text>-->
      <xsl:apply-templates select="sl:standBestand/sl:stand/sl-bag-extract:bagObject/Objecten:Pand"/>
  </xsl:template>

  <xsl:template match="Objecten:Pand">
    <xsl:if test="not(Objecten:voorkomen/Historie:Voorkomen/Historie:eindGeldigheid) and not(Objecten:voorkomen/Historie:Voorkomen/Historie:BeschikbaarLV/Historie:tijdstipEindRegistratieLV) and not(Objecten:voorkomen/Historie:Voorkomen//Historie:BeschikbaarLV/Historie:tijdstipnietbaglv) and not(Objecten:voorkomen/Historie:Voorkomen/Historie:BeschikbaarLV/Historie:tijdstipinactiefLV)">
      <xsl:value-of select="Objecten:identificatie" />,<xsl:value-of select="Objecten:oorspronkelijkBouwjaar"/>,"<xsl:value-of select="Objecten:status"/>"<xsl:text>&#10;</xsl:text>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

Ah top, dat kan ik dus aanpassen. Bedankt!

Ik werk grotendeels in Python, dus lekker niet OS gebonden. (de enige uitzondering momenteel is dat bash script van jou waarvoor ik WSL heb gebruikt)

Ik heb momenteel code om alle BAG gebouwen te downloaden en deze op te slaan in een boel json files met alle tags en ID beschikbaar. En ik heb nu ook code die deze osm json bestanden en het bag cvs bestand inlaad en de start_dates met elkaar vergelijkt en het resultaat naar een nieuw bestand schrijft.

De code die ik nu heb is momenteel erg ongeorganiseerd. Meer een willekeurig aantal functies die ik arbitrair aanroep om te doen wat ik wil dan iets wat makkelijk bruikbaar is voor anderen. Mijn doel is om de code nog iets uit te breiden, zodat het ook mogelijk is om andere analyses te doen en om de code gebruiksvriendelijker te maken. maar het is wel het plan om dit te delen met de community.

edit: oh en er is ook nog het probleem dat het best wel veel geheugen kost om 2 datasets van 10M objecten te laden.

1 Like