Skip to content

Commit

Permalink
WIP more buurten support
Browse files Browse the repository at this point in the history
  • Loading branch information
Erikvv committed Jan 21, 2025
1 parent c47b12c commit a7883a9
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 16 deletions.
53 changes: 53 additions & 0 deletions frontend/src/services/wijkenbuurten/buurten.test.ts
Original file line number Diff line number Diff line change
@@ -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)
})
})
65 changes: 49 additions & 16 deletions frontend/src/services/wijkenbuurten/buurten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<MultiPolygon, BuurtProperties>
export type Buurt = Feature<MultiPolygon, BuurtProperties>
Expand Down Expand Up @@ -114,7 +115,7 @@ export function getBuurtCenter(buurt: Buurt): LatLng {
}

export async function fetchBuurt(gemeente: string, buurt: string): Promise<Buurt> {
const buurten = await fetchBuurten(`
const buurten = await fetchBuurtenGet(`
<Filter>
<AND>
<PropertyIsEqualTo>
Expand Down Expand Up @@ -146,7 +147,7 @@ export async function fetchBuurtenByCodes(buurtCodes: readonly string[]): Promis
}

if (buurtCodes.length == 1) {
return await fetchBuurten(`
return await fetchBuurtenPost(`
<Filter>
<PropertyIsEqualTo>
<PropertyName>buurtcode</PropertyName>
Expand All @@ -156,21 +157,32 @@ export async function fetchBuurtenByCodes(buurtCodes: readonly string[]): Promis
`)
}

return await fetchBuurten(`
<Filter>
<Or>
${buurtCodes.map(code => `
<PropertyIsEqualTo>
<PropertyName>buurtcode</PropertyName>
<Literal>${code}</Literal>
</PropertyIsEqualTo>
`)}
</Or>
</Filter>
`)
// There is a limit to the number of filter clauses on the server
const buurtCodeChunks = chunk(buurtCodes, 10)

const requests = buurtCodeChunks.map(buurtCodeChunk =>
fetchBuurtenPost(`
<Filter>
<Or>
${buurtCodes.map(code => `
<PropertyIsEqualTo>
<PropertyName>buurtcode</PropertyName>
<Literal>${code}</Literal>
</PropertyIsEqualTo>
`).join("").replaceAll(/ +/g, " ").replaceAll("\n", "")}
</Or>
</Filter>
`,
))

const featureCollections = await Promise.all(requests)

return featureCollection(featureCollections.flatMap(fc => fc.features))
}

export async function fetchBuurten(xmlFilter: string): Promise<BuurtFeatureCollection> {
const baseUrl = "https://service.pdok.nl/cbs/wijkenbuurten/2023/wfs/v1_0"

async function fetchBuurtenGet(xmlFilter: string): Promise<BuurtFeatureCollection> {
const params = new URLSearchParams({
request: 'GetFeature',
typeName: 'buurten',
Expand All @@ -181,11 +193,32 @@ export async function fetchBuurten(xmlFilter: string): Promise<BuurtFeatureColle
filter: xmlFilter,
})

const url = 'https://service.pdok.nl/cbs/wijkenbuurten/2023/wfs/v1_0?' + params.toString()
const url = baseUrl + "?" + params.toString()
const response = await fetch(url)
if (response.status != 200) {
throw Error('Failure getting buurt geometry')
}

return await response.json()
}

async function fetchBuurtenPost(xmlFilter: string): Promise<BuurtFeatureCollection> {
const response = await fetch(baseUrl, {
method: "POST",
body: `
<GetFeature service="WFS" version="2.0.0" outputFormat="json" xmlns="http://www.opengis.net/wfs/2.0">
<Query typeName="buurten" srsName="EPSG:4326">
${xmlFilter}
</Query>
</GetFeature>
`,
})

if (response.status != 200) {
throw Error("Failure getting buurt geometry")
}

return await response.json()
}


0 comments on commit a7883a9

Please sign in to comment.