From 57c743b005697f37ee2d9a154170fa9f722a1a1a Mon Sep 17 00:00:00 2001 From: kempersc Date: Sun, 7 Dec 2025 19:48:07 +0100 Subject: [PATCH] refactor(frontend): fetch NL municipalities from PostGIS API instead of static file Replace static netherlands_municipalities_simplified.geojson with dynamic PostGIS API call to /boundaries/countries/NL/admin2/geojson. Transform API response properties to expected format: - API: {code, name, name_local, admin1_code, admin1_name} - Expected: {code, naam, provincieCode, provincieNaam} This ensures NL boundary data comes from the authoritative PostGIS database rather than a static file that could become outdated. --- frontend/src/hooks/useWerkgebiedMapLibre.ts | 53 +++++++++++++++++---- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/frontend/src/hooks/useWerkgebiedMapLibre.ts b/frontend/src/hooks/useWerkgebiedMapLibre.ts index 29a31ac28c..9166154599 100644 --- a/frontend/src/hooks/useWerkgebiedMapLibre.ts +++ b/frontend/src/hooks/useWerkgebiedMapLibre.ts @@ -4,7 +4,7 @@ * Custom hook for managing werkgebied (service area) polygon display on MapLibre GL maps. * * Loads: - * - Municipality GeoJSON boundaries from netherlands_municipalities_simplified.geojson + * - Municipality GeoJSON boundaries from PostGIS API (NL admin2 boundaries) * - Archive-to-municipalities mapping from archive_werkgebied_mapping.json * - Historical HALC boundaries from netherlands_historical_adm2_1500.geojson * - Historical archive mapping from historical_archive_halc_mapping.json @@ -71,12 +71,14 @@ interface HistoricalArchiveMapping { }>; } -// URLs for data files -const MUNICIPALITIES_URL = '/data/netherlands_municipalities_simplified.geojson'; +// URLs for data files (static files only - municipalities now fetched from API) const WERKGEBIED_MAPPING_URL = '/data/archive_werkgebied_mapping.json'; const HISTORICAL_HALC_URL = '/data/netherlands_historical_adm2_1500.geojson'; const HISTORICAL_MAPPING_URL = '/data/historical_archive_halc_mapping.json'; +// PostGIS Boundaries API URL +const BOUNDARIES_API_URL = import.meta.env.VITE_POSTGRES_API_URL || '/api/postgres'; + // Layer and source IDs const WERKGEBIED_SOURCE_ID = 'werkgebied-source'; const WERKGEBIED_FILL_LAYER_ID = 'werkgebied-fill'; @@ -139,22 +141,57 @@ export function useWerkgebiedMapLibre(map: maplibregl.Map | null): WerkgebiedHoo setError(null); try { - // Load all files in parallel + // Load static files and API data in parallel + // Note: Municipalities now fetched from PostGIS API instead of static file const [municipalitiesRes, mappingRes, halcRes, historicalMappingRes] = await Promise.all([ - fetch(MUNICIPALITIES_URL), + fetch(`${BOUNDARIES_API_URL}/boundaries/countries/NL/admin2/geojson?simplify=0.001`), fetch(WERKGEBIED_MAPPING_URL), fetch(HISTORICAL_HALC_URL), fetch(HISTORICAL_MAPPING_URL), ]); if (!municipalitiesRes.ok) { - throw new Error(`Failed to load municipalities: ${municipalitiesRes.statusText}`); + throw new Error(`Failed to load municipalities from API: ${municipalitiesRes.statusText}`); } if (!mappingRes.ok) { throw new Error(`Failed to load werkgebied mapping: ${mappingRes.statusText}`); } - municipalitiesRef.current = await municipalitiesRes.json(); + // Parse API response and transform to expected format + const apiGeoJSON = await municipalitiesRes.json(); + + // Transform API properties to expected format: + // API: {id, code, name, name_local, admin1_code, area_km2, source} + // Expected: {code, naam, provincieCode?, provincieNaam?} + const transformedFeatures = apiGeoJSON.features.map((feature: { + type: 'Feature'; + properties: { + id?: number; + code: string; + name: string; + name_local?: string; + admin1_code?: string; + admin1_name?: string; + area_km2?: number; + source?: string; + }; + geometry: GeoJSON.Geometry; + }) => ({ + type: 'Feature', + properties: { + code: feature.properties.code, + naam: feature.properties.name_local || feature.properties.name, + provincieCode: feature.properties.admin1_code, + provincieNaam: feature.properties.admin1_name, + }, + geometry: feature.geometry, + })); + + municipalitiesRef.current = { + type: 'FeatureCollection', + features: transformedFeatures, + }; + mappingRef.current = await mappingRes.json(); // HALC data is optional - don't fail if not available @@ -174,7 +211,7 @@ export function useWerkgebiedMapLibre(map: maplibregl.Map | null): WerkgebiedHoo dataLoadedRef.current = true; - console.log(`[useWerkgebiedMapLibre] Loaded ${municipalitiesRef.current?.features.length} municipalities`); + console.log(`[useWerkgebiedMapLibre] Loaded ${municipalitiesRef.current?.features.length} municipalities from PostGIS API`); console.log(`[useWerkgebiedMapLibre] Loaded ${mappingRef.current?.statistics.total_archives} archives`); } catch (err) { console.error('[useWerkgebiedMapLibre] Error loading data:', err);