From de7e428b7c40bb42e56ce10a0ae6e6932127ace7 Mon Sep 17 00:00:00 2001 From: Erik van Velzen Date: Tue, 17 Dec 2024 15:34:09 +0100 Subject: [PATCH] WIP more buurten support --- .../services/wijkenbuurten/buurten.test.ts | 53 +++++++++++++++ .../src/services/wijkenbuurten/buurten.ts | 65 ++++++++++++++----- 2 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 frontend/src/services/wijkenbuurten/buurten.test.ts diff --git a/frontend/src/services/wijkenbuurten/buurten.test.ts b/frontend/src/services/wijkenbuurten/buurten.test.ts new file mode 100644 index 00000000..6d1d9b99 --- /dev/null +++ b/frontend/src/services/wijkenbuurten/buurten.test.ts @@ -0,0 +1,53 @@ +import {fetchBuurtenByCodes} from "./buurten" + +const hoekscheWaardBuurtcodes = [ + "BU19639997", + "BU19630950", + "BU19630699", + "BU19630400", + "BU19630005", + "BU19630000", + "BU19630099", + "BU19630300", + "BU19630800", + "BU19630700", + "BU19630050", + "BU19631200", + "BU19631300", + "BU19630200", + "BU19630999", + "BU19631299", + "BU19630500", + "BU19630001", + "BU19631199", + "BU19630007", + "BU19630002", + "BU19630900", + "BU19630199", + "BU19630006", + "BU19631099", + "BU19630150", + "BU19630399", + "BU19631399", + "BU19630499", + "BU19630600", + "BU19630299", + "BU19630750", + "BU19631000", + "BU19630799", + "BU19630599", + "BU19630051", + "BU19630650", + "BU19630003", + "BU19630100", + "BU19630004", + "BU19631100", + "BU19630899", +] + +describe(fetchBuurtenByCodes.name, () => { + test("Many buurtcodes which split request", async () => { + const buurten = await fetchBuurtenByCodes(hoekscheWaardBuurtcodes) + expect(buurten.features.length).toBe(hoekscheWaardBuurtcodes.length) + }) +}) diff --git a/frontend/src/services/wijkenbuurten/buurten.ts b/frontend/src/services/wijkenbuurten/buurten.ts index a6abf23d..a26d3041 100644 --- a/frontend/src/services/wijkenbuurten/buurten.ts +++ b/frontend/src/services/wijkenbuurten/buurten.ts @@ -4,6 +4,7 @@ import {LatLng} from 'leaflet' import center from '@turf/center' import {geoJsonPositionToLeaflet} from '../geometry' import {featureCollection} from "@turf/helpers" +import {chunk} from "lodash" export type BuurtFeatureCollection = FeatureCollection export type Buurt = Feature @@ -114,7 +115,7 @@ export function getBuurtCenter(buurt: Buurt): LatLng { } export async function fetchBuurt(gemeente: string, buurt: string): Promise { - const buurten = await fetchBuurten(` + const buurten = await fetchBuurtenGet(` @@ -146,7 +147,7 @@ export async function fetchBuurtenByCodes(buurtCodes: readonly string[]): Promis } if (buurtCodes.length == 1) { - return await fetchBuurten(` + return await fetchBuurtenPost(` buurtcode @@ -156,21 +157,32 @@ export async function fetchBuurtenByCodes(buurtCodes: readonly string[]): Promis `) } - return await fetchBuurten(` - - - ${buurtCodes.map(code => ` - - buurtcode - ${code} - - `)} - - - `) + // There is a limit to the number of filter clauses on the server + const buurtCodeChunks = chunk(buurtCodes, 10) + + const requests = buurtCodeChunks.map(buurtCodeChunk => + fetchBuurtenPost(` + + + ${buurtCodes.map(code => ` + + buurtcode + ${code} + + `).join("").replaceAll(/ +/g, " ").replaceAll("\n", "")} + + + `, + )) + + const featureCollections = await Promise.all(requests) + + return featureCollection(featureCollections.flatMap(fc => fc.features)) } -export async function fetchBuurten(xmlFilter: string): Promise { +const baseUrl = "https://service.pdok.nl/cbs/wijkenbuurten/2023/wfs/v1_0" + +async function fetchBuurtenGet(xmlFilter: string): Promise { const params = new URLSearchParams({ request: 'GetFeature', typeName: 'buurten', @@ -181,7 +193,7 @@ export async function fetchBuurten(xmlFilter: string): Promise { + const response = await fetch(baseUrl, { + method: "POST", + body: ` + + + ${xmlFilter} + + + `, + }) + + if (response.status != 200) { + throw Error("Failure getting buurt geometry") + } + + return await response.json() +} + +