Hoi @rboeters,
Het betreft de z-order curve (Z-order curve - Wikipedia), het grid is met die logica uitgezet. De BBOX betreft: -100000,200000, 412000,712000 (RD). Het is dus een grid van 512000x512000 meter verdeeld in tegels van 2000x2000 meter, op het laagste niveau.
https://downloads.pdok.nl/service/extract.zip?extractname=bgt&extractset=citygml&excludedtypes=plaatsbepalingspunt&history=true&tiles={"layers"%3A[{"aggregateLevel"%3A1%2C"codes"%3A[4094]}]}
De url heeft de query parameter âtilesâ welke een encoded stukje json consumeert.
Bijvoorbeeld (decoded): {âlayersâ:[{âaggregateLevelâ:0,âcodesâ:[16378]}]}
Dit request vraagt dus op het laagste niveau (0) de tegel met de code 16378 op. De parameter codes is een array, je kan dus meerdere tegels op 1 zoomniveau opvragen door bijvoorbeeld mee te geven:
{âlayersâ:[{âaggregateLevelâ:0,âcodesâ:[16376, 16377, 16378, 16379]}]}
Maar in het bovenste geval vormen de viertegel op aggregateLevel 1 (een niveau hoger) samen een nieuwe tegel namelijk tegel: 4094. Dus het volgende request levert hetzelfde resultaat op:
{âlayersâ:[{âaggregateLevelâ:1,âcodesâ:[4094]}]}
Want:
16376/4 â floor(4094) = 4094
16377/4 â floor(4094,25) = 4094
16378/4 â floor(4094,5) = 4094
16379/4 â floor(4094,75) = 4094
Met behulp van deze logica kan je ânavigerenâ tussen verschillende niveaus, door te âdelenâ of te âvermenigvuldigenâ met 4.
Om trouwens antwoord te geven op je vraag: om van een RD-coord naar een tile number te gaan, dat doen wij door middel van âbit shiftingâ. DEPRECATED_featured-shared/ZOrder.java at master · PDOK/DEPRECATED_featured-shared · GitHub
In Postgresql zou je het volgende kunnen doen trouwens (als dat makkelijker is), dit zou je eenvoudig in een functie kunnen schroeven (ff een disclaimer: code is een voorbeeld en geen âofficieleâ impementatie, enz, enzâŠ)
DO $$
DECLARE
morton_id INTEGER := 0;
x_masked_i INTEGER;
y_masked_i INTEGER;
i INTEGER := 0;
x_coord NUMERIC(10,1) := 42459;
y_coord NUMERIC(10,1) := 383029;
x NUMERIC(10,1);
y NUMERIC(10,1);
BEGIN
x := ((x_coord - -100000)/2000);
IF ((x % 1) != 0) THEN
x := FLOOR(x);
END IF;
y := ((y_coord - 200000)/2000);
IF ((y % 1) != 0) THEN
y := FLOOR(y);
END IF;
WHILE (i < 32) LOOP
x_masked_i = (x::INTEGER & (1 << i));
y_masked_i = (y::INTEGER & (1 << i));
morton_id := morton_id | (x_masked_i << i);
morton_id := morton_id | (y_masked_i << (i + 1));
i := i + 1;
END LOOP;
RAISE INFO 'morton_id: %', morton_id;
END
$$;