BAG WFS request geeft maar 1000 objecten maximaal terug

Ook al geef ik een hogere count aan in het request, het maximum aantal objecten dat ik terug krijg is 1000.
Dat is vrij beperkt. Kan dat maximum omhoog?
Het lijkt te gelden voor alle PDOK WFS’en, in ieder geval ook voor de Kadaster WFS.

Deze beperking van 1000 features (per request) is bepaald om een hogere performance te halen.

In de capabilities van de betreffende service staat het limiet beschreven.
https://geodata.nationaalgeoregister.nl/bag/wfs?request=getCapabilities&service=WFS

Dit limiet van 1000 geldt niet voor alle PDOK WFSsen. Het kan per service/dataset verschillen, dus controleer de capabilities van de betreffende service voor meer informatie.

Het is bijvoorbeeld wel mogelijk om minder dan 1000 features per request op te halen:
https://geodata.nationaalgeoregister.nl/bag/wfs?request=getFeature&version=2.0.0&typeNames=bag:verblijfsobject&count=10

Mocht je dan meer dan 1000 features willen ophalen kan je gebruik maken van het zogenaamde pagineren (startindex parameter).

Voorbeeld met pagineren per 10 features (dit kan dus ook per 1000):
Eerste 10 features:

https://geodata.nationaalgeoregister.nl/bag/wfs?request=getFeature&version=2.0.0&typeNames=bag:verblijfsobject&count=10&startindex=0

Volgende 10 features:

https://geodata.nationaalgeoregister.nl/bag/wfs?request=getFeature&version=2.0.0&typeNames=bag:verblijfsobject&count=10&startindex=10

De meeste GIS-clients doen dit overigens automatisch, als ze de capabilities honereren.

2 likes

Ik heb WFS paginering nog niet eerder gebruikt.
Ik ben eigenlijk wel benieuwd of dat dan in alle gevallen goed gaat want de server moet toch op een of andere manier onthouden wat de eerste 1000 records zijn geweest van de vorige zoekopdracht. Ik weet dan in Oracle de volgorde van rijen per zoekopdracht weer anders kan zijn.

In jouw voorbeeld moet startindex toch 11 zijn? Of begint ie bij 0?

Zoals je kan zien in het voorbeeld begint hij bij 0.

In welke gevallen zou je verwachten dat het eventueel mis gaat? De WFS leest in dit geval uit een PostGIS database. De features in de database hebben een uniek id en deze volgorde staat vast. In de WFS service staat geconfigureerd over welk uniek id hij moet wandelen om deze paginering te kunnen doen. Dit geeft dus bij elk request dezelfde volgorde aan resultaten terug. In het geval dat dit niet mogelijk is, of niet goed geconfigureerd is in een WFS service zal hiervan een foutmelding gegeven worden. Meestal lijkt de tekst dan op dit:

<ows:Exception exceptionCode="NoApplicableCode">
     <ows:ExceptionText>java.lang.RuntimeException: java.lang.RuntimeException: java.io.IOException
            java.lang.RuntimeException: java.io.IOException
            java.io.IOExceptionCannot do natural order without a primary key, please add it or specify a manual sort over existing attributes
     </ows:ExceptionText>
</ows:Exception>
1 like

Ok, duidelijk.
Paginering zal negatieve impact hebben op de overall performance aan de WFS-server-kant, lijkt me, omdat dezelfde query steeds opnieuw uitgevoerd moet worden met steeds meer records waarbij alleen de laatste 1000 worden geretourneerd.

Vreemde aanname :slight_smile:. Zeker aangezien ik eerst het volgende benoemde:

Je mag van mij aannemen dat we verschillende benchmarks hebben gedaan voordat we uiteindelijk het besluit hebben genomen om deze specifieke WFS service een limit van 1000 features per verzoek terug te laten geven. Nog hogere aantallen features per verzoek maken deze specifieke service vele malen trager.

Je kan je voorstellen dat als je een paar miljoen features in een database hebt zitten voor een specifieke dataset en die in een keer terug laat komen langer duurt, dan in kleinere blokjes. Zeker wanneer je meer dan 1 gebruiker hebt die gebruik maakt van deze service. Het is namelijk veel sneller om een klein blokje data op te halen, te verpakken en te verzenden over de lijn, dan een hele grote bak data.

Ik begrijp niet zo goed waarom er steeds dezelfde query zou worden uitgevoerd worden? Nutteloze data queryen in een database lijkt me geen goed idee en zou zeker de perfomance schaden. Zou een zeer pijnlijke implementatie zijn van een dergelijke functionaliteit.

Gelukkig werkt het niet zo.

Hoe ziet volgens jou de onderliggende query in SQL eruit om de tweede set van 1000 records op te halen, b.v. alle percelen die binnen een rechthoek vallen?
Je weet toch niet van tevoren welke id’s er in die tweede set zitten?

Beste @rli, helaas is mijn tijd te kostbaar om de gehele technische werking van de BAG WFS uit te leggen.

Mocht je jezelf verder in willen verdiepen:

De ID’s weet je wel wanneer je de bounding box query (opnieuw) uitvoert en de ID’s sorteert. Dan werkt het naar verwachting op dezelfde manier als wanneer je de hele dataset bevraagt. Dus ongeveer: select * from myfeatures where st_overlaps(boundingbox, geometry) order by id limit offset ;

Wat WFS en grote aantallen betreft: ik denk zelf dat de performance op een gegeven moment wel merkbaar slechter wordt. Want sorteren kost ook tijd. Bij de eerste X pagina’s hoeft de backend server niet alle records te sorteren, i.i.g. niet wanneer er een index op het sorteerveld (bijv ID-veld) zit, maar dit gaat wel gebeuren naarmate je steeds verder komt.

Toen ik nog bij PDOK werkzaam was, heb ik dit o.a. gemerkt met Locatieserver. Hierbij wordt wel gebruikt van een andere technologie (Apache Solr) dan bij de geo-sevices (Postgres en in beperkte mate Geopackage). Als je een startindex van 2 miljoen opgeeft en 100 records opvraagt, doet Solr er een stuk langer over dan wanneer de startindex 0 of zelfs 100.000 is.

Maar voor zowel WFS als voor Locatieserver zou je bij zulke aantallen in mijn optiek deze services niet moeten gebruiken, maar zelf de hele dataset downloaden en hierop je bewerkingen / analyses uitvoeren. Locatieserver is daar in ieder geval niet voor bedoeld, want als je “alles” zoekt, waar ben je dan specifiek naar op zoek? Voor WFS zie ik eerder wel een use case om grotere gebieden te downloaden, maar hiervoor heeft PDOK aparte downloadservices. Ergens zit een omslagpunt dat het efficienter is om een downloadservice dan een zoekservice te gebruiken.

Q.E.D.
Je moet eerst de hele set ophalen en dan sorteren op ID en vervolgens haal je je page uit die hele set die al opgehaald is. Misschien dat je voor de sortering alleen eerst de ID’s ophaalt en bij de page alle attributen maar zoveel zal dat niet uitmaken bij een database want die heeft dan toch al het complete record in het geheugen.
Paging heeft dus grote performance consequenties voor grote aantallen.
Er zijn steeds meer klanten die eisen dat alle via services moet verlopen. Hetgeen betekent dat je niets download naar een lokale database. En als diezelfde klanten ook eisen dat ook grote aantallen geselecteerd moeten worden via die services met een grote buffer (bv alle verblijfsobjecten in een wijk/buurt) dan betekent dit gewoon lang wachten. Dit gaat met een REST API i.p.v. WFS ook niet anders zijn.