De PDOK JSON-aanleverstandaard is het voorkeursformaat voor aanleveringen van datasets aan PDOK.
De belangrijkste concepten van deze standaard zijn als volgt:
-
Basis van alles is een feature: een object uit de dataset, gecombineerd met velden die het proces aansturen.
-
De objectvelden in het feature, waaronder de geometrie, worden attributen genoemd. In de ideale situatie hebben features precies één geometrie en platte attributen. Nul of meerdere geometrieën en complexe attributen worden ondersteund, maar leiden zoals verderop beschreven mogelijk tot ander gedrag.
-
Een collection is een verzameling features van hetzelfde objecttype (bijv. pand). Over het algemeen zullen features van één collection dezelfde attribuutnamen hebben, maar hier zitten vooralsnog geen beperkingen op.
-
Van features wordt historie bijgehouden: ze kunnen niet alleen worden toegevoegd, maar ook gewijzigd, beëindigd of verwijderd.
Important
|
collection-namen en attribuutnamen zijn hoofdlettergevoelig, maar gebruik van twee collection-namen die zich enkel in hoofdlettergebruik onderscheiden, is momenteel nog niet mogelijk. |
Aanlevering
De aanlevering geschiedt in één bestand:
{
"_meta": {
// Header met metadata. Voor toekomstig gebruik, momenteel niet gevuld.
},
"dataset": "dataset-identifier",
"features" : [ feature objects ]
}
Important
|
De volgorde is hier belangrijk! features moet het laatste attribuut zijn.
|
Features
Features hebben een aantal verplichte velden, die herkenbaar zijn aan de voorloop-underscore (_):
_action
|
string: |
_collection
|
string |
_id
|
string, uniek in collection |
_validity
|
date-time-string, mutatietijdstip: yyyy-MM-ddTHH:mm:ss.SSSZ (enkel bij |
_current_validity
|
date-time-string, validity van vorige mutatie: yyyy-MM-ddTHH:mm:ss.SSSZ (enkel bij
|
Daarnaast zijn er vrije velden (attributen).
Acties en historieopbouw
Zoals hierboven al vermeld, ondersteunt het aanleverformaat niet alleen het eenmalig aanmaken van features, maar ook het wijzigen, beëindigen en verwijderen ervan. Hierbij wordt historie opgebouwd, die voor gebruikers te raadplegen is via downloadservices. Elke mutatie (uitgevoerde actie op een feature) is voorzien van een mutatietijdstip (validity). Zo ontstaat per feature een tijdlijn, waarbij elke periode tussen twee mutatietijdstippen overeenkomt met één versie van het feature.
Na het initiële opvoeren van een feature wordt ter controle steeds het tijdstip van de voorafgaande mutatie meegestuurd (current validity). Zo kan gevalideerd worden dat er geen mutaties op het feature zijn gemist.
Voor het muteren van features zijn de volgende acties gedefinieerd:
-
new
voegt de eerste versie van een feature toe. Er wordt gevalideerd dat er geen eerdere versie van dit feature bestaat. -
change
wijzigt een feature. Hierbij kan gekozen worden of er wel of geen historie opgebouwd dient te worden. Wordt een validity meegegeven die later is dan de current validity, dan wordt de momenteel actuele versie bewaard als historie en een nieuwe versie aan de tijdlijn toegevoegd. Dit kan gebruikt worden als er een vanaf een bepaalde ingangsdatum een nieuwe werkelijkheid is. De validity wordt gebruikt als overgangsdatum tussen de twee versies. Wordt een validity meegegeven die gelijk is aan de current validity, dan wordt de momenteel actuele versie overschreven zonder dat deze in de historie bewaard blijft. Dit kan gebruikt worden als er een technische correctie op het feature dient plaats te vinden, terwijl de werkelijkheid ongewijzigd is. -
close
beëindigt een feature. Dit houdt in dat de momenteel actuele versie bewaard wordt als historie, zonder dat er een nieuwe versie voor in de plaats komt. Dit kan gebruikt worden als het object in de werkelijkheid met een bepaalde ingangsdatum komt te vervallen. -
delete
verwijdert een feature volledig, inclusief alle historie. Dit kan gebruikt worden als er in de aanleveringen een fout gemaakt is die niet op een andere manier hersteld kan worden. Hierna kan hetzelfde feature indien gewenst opnieuw worden aangeboden middels eennew
.
Een voorbeeld om de acties te illustreren:
[{
"_action": "new",
"_collection": "historie-voorbeeld",
"_id": "feature1",
"_validity": "[t1]"
"value": "foo"
},
{
"_action": "change",
"_collection": "historie-voorbeeld",
"_id": "feature1",
"_current_validity": "[t1]",
"_validity": "[t2]"
"value": "bar"
},
{
"_action": "change",
"_collection": "historie-voorbeeld",
"_id": "feature1",
"_current_validity": "[t2]",
"_validity": "[t2]"
"value": "baz"
},
{
"_action": "change",
"_collection": "historie-voorbeeld",
"_id": "feature1",
"_current_validity": "[t2]",
"_validity": "[t3]"
"value": "spam"
},
{
"_action": "close",
"_collection": "historie-voorbeeld",
"_id": "feature1",
"_current_validity": "[t3]",
"_validity": "[t4]"
}]
Dit resulteert in de volgende tijdlijn:
t1 t2 t3 t4 -------|---------------|---------------|----------------|--------> X value=foo value=baz value=spam X
Hierbij staat X voor: er is in deze periode geen versie van dit feature.
Tot slot kan het feature verwijderd worden met:
{
"_action": "delete",
"_id": "feature1",
"_collection": "historie-voorbeeld",
"_current_validity": "[t4]"
}
Attributen
De attributen (vrije velden) van een feature mogen simple types (string, numeriek, boolean) zijn, complex types (arrays of subobjecten), voorgedefinieerde functies of geometrieobjecten (in een van de ondersteunde formaten, zie verderop). Het type wordt bepaald op basis van het eerste voorkomen van een attribuut.
Complex types
Complex types kunnen bijvoorbeeld gebruikt worden als een feature subobjecten bevat. Een typisch voorbeeld is een pand dat een vlakgeometrie heeft, maar daarnaast één of meer nummeraanduidingen met eigen attributen en een puntgeometrie.
Bij het gebruik van complex types dient er rekening mee gehouden te worden dat deze voor de viewservices afgesplitst
worden als aparte lagen. In het bovengenoemde voorbeeld zou een laag pand
en een laag
pand$nummeraanduiding
ontstaan. Om deze reden zijn complex types in sommige delen van de
verwerkingspijplijn duurder dan simple types en dienen ze dus alleen gebruikt te worden als ze daadwerkelijk een
toegevoegde waarde hebben t.o.v. platte attributen.
Functies
Een functie kan gebruikt worden als een attribuut omgezet dient te worden naar een ander type dan string, numeriek of boolean. Het zijn dus in feite voorgedefinieerde types. Functies worden als volgt aangeroepen:
["~#functienaam", [param1, param2, ...]]
Op dit moment zijn de volgende functies beschikbaar:
~#moment
|
date-time-string (yyyy-MM-ddTHH:mm:ss.SSSZ) → |
~#date
|
date-string (yyyy-MM-dd) → |
~#int
|
|
~#boolean
|
|
~#double
|
|
~#geometry
|
geometrieobject (zie verderop) |
De functies ~#int
, ~#boolean
en ~#double
zijn er als alternatief voor de
automatische detectie van het attribuuttype. Ze komen vooral van pas als voor een bepaald attribuut lege
(null
) waardes kunnen voorkomen, omdat het type dan niet automatisch bepaald kan worden. In het laatste
geval kiest de automatische detectie voor string als er geen functie gebruikt wordt.
Voorbeeld:
{
"getalEen": 15, // Integer
"getalTwee": null, // String
"getalDrie": ["~#int", null] // Integer
}
Geometrieën
Voor geometrieën worden de formaten GML en WKT ondersteund. Mogelijk wordt in de toekomst ondersteuning voor GeoJSON toegevoegd.
Dat het bij een attribuut om een geometrie gaat, kan op twee manieren aangegeven worden. Heet het attribuut
_geometry
, dan wordt dit automatisch als geometrie geïnterpreteerd. Heet het attribuut anders, dan dient
bovengenoemde functie ~#geometry
gebruikt te worden.
Voorbeelden:
"_geometry":{
"type": "gml",
"gml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"urn:ogc:def:crs:EPSG::28992\">
<gml:pos srsDimension=\"2\">154676.328 464046.743</gml:pos>
</gml:Point>"
},
"andereGeometrie": ["~#geometry", [{
"type": "wkt",
"wkt": "LINESTRING (154676.328 464046.743, 154676.578 464046.743, 154674.285 464048.372)",
"srid": 28992
}]]
Het veld srid
is optioneel. Als het wordt weggelaten, wordt 28992 (Amersfoort / RD New) gebruikt.
Feature zonder geometrie
Een feature zonder geometrie wordt ook verwerkt. De data kan dan echter niet gevisualiseerd worden. Wel is deze zichtbaar in eventuele downloadservices. Voor de rest is een feature zonder geometrie hetzelfde als een feature met geometrie.