Broaden official source portfolio
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-16 02:04:31 +02:00
parent 8628582caa
commit fdf3881592
10 changed files with 970 additions and 197 deletions
+18
View File
@@ -7,6 +7,24 @@
# Changelog
## Sprint 212 Platform-wide official source portfolio (2026-07-16)
- Rebalanced the source strategy across six user-facing domains: space and
buildings, nature and agriculture, soil and relief, mobility and
accessibility, population and services, and climate and living environment.
- Added a central frontend source portfolio with official catalogue links,
measurable outcomes, priorities and dataset matchers. A source is labelled
operational only when a matching ready Dataset really exists.
- Simplified the Sources inventory to six compact domain cards. Theme/time
detail, active-source limitations and the complete candidate list now use
progressive disclosure instead of competing for attention.
- Expanded the Datavindplaats roadmap beyond hydrology with land use, space
occupation, soil, population, services, accessibility, business parks,
mobility hubs, cycle highways, heat and air quality.
- Recommended a governed allowlisted Mercator thematic-raster registry as the
next implementation wave so one safe acquisition path unlocks several
platform domains without arbitrary provider URLs or schema changes.
## Sprint 211 Regional VMM flood-hazard provisioning support (2026-07-16)
- Added `provision_regional_flood_hazards.py`, an explicit operator for the
@@ -0,0 +1,70 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
def test_source_portfolio_covers_the_complete_platform() -> None:
portfolio = (ROOT / "frontend/src/lib/sourcePortfolio.ts").read_text(encoding="utf-8")
for domain in ("space", "nature", "soil", "mobility", "people", "climate"):
assert f"key: '{domain}'" in portfolio
for source in (
"Landgebruik Vlaanderen",
"Digitale bodemkaart",
"Bedrijventerreinen OSLO",
"Knooppuntwaarde per hectare",
"Statistische sectoren",
"Inwonersdichtheid per hectare",
"Totaal voorzieningenniveau",
"Hitte-eilanden in steden",
"Luchtkwaliteit",
"Vlaamse Hydrografische Atlas",
):
assert source in portfolio
assert portfolio.count("domain: 'climate'") < portfolio.count("domain:") / 2
assert "OFFICIAL_SOURCE_PORTFOLIO" in portfolio
assert "dataset.status === 'ready'" in portfolio
def test_source_inventory_is_compact_honest_and_domain_driven() -> None:
catalog = (ROOT / "frontend/src/components/datasets/SourceCatalogPanel.tsx").read_text(encoding="utf-8")
styles = (ROOT / "frontend/src/styles/app.css").read_text(encoding="utf-8")
assert "Welke vragen kan GeoIntel beantwoorden?" in catalog
assert "Zes domeinen vormen samen het platform" in catalog
assert "operationalSources(ready)" in catalog
assert "Dekking per kaartthema en tijdreeks" in catalog
assert "Actieve broncollecties en hun beperkingen" in catalog
assert "Officiële bronnen die hierna kunnen worden ingeladen" in catalog
assert "Meetbaar als:" in catalog
assert "source-domain-grid" in styles
assert "source-opportunity-domain" in styles
def test_roadmap_prioritizes_cross_domain_profile_before_more_water_layers() -> None:
roadmap = (ROOT / "docs/DATAVINDPLAATS_SOURCE_ROADMAP.md").read_text(encoding="utf-8")
assert "Water is one analysis domain" in roadmap
assert "Wave 1 - Cross-domain area profile" in roadmap
assert "space occupation 2025" in roadmap
assert "population density 2019" in roadmap
assert "node value 2022" in roadmap
assert "total service level 2022" in roadmap
assert "digital soil map" in roadmap
assert "VHA/runoff as hydrological context" in roadmap
assert "Governed Flemish Thematic Raster Registry - Wave 1" in roadmap
def test_portfolio_pass_does_not_add_provider_fetch_or_persistence_code() -> None:
changed_scope = {
"frontend/src/lib/sourcePortfolio.ts",
"frontend/src/components/datasets/SourceCatalogPanel.tsx",
"frontend/src/styles/app.css",
"docs/DATAVINDPLAATS_SOURCE_ROADMAP.md",
}
assert not any(path.startswith("backend/app/") for path in changed_scope)
assert not any("migration" in path for path in changed_scope)
+36
View File
@@ -8989,3 +8989,39 @@ Follow-up validation:
- Added `docs/DATAVINDPLAATS_SOURCE_ROADMAP.md` with recommended public
Vlaanderen Datavindplaats follow-up sources for hydrology, soil, planning
and accessibility.
## Sprint 212 - Platform-wide official source portfolio (2026-07-16)
Implemented:
- Audited the official public-source roadmap across the complete GeoIntel
product instead of continuing with a water-first backlog.
- Added one central frontend portfolio covering space/buildings,
nature/agriculture, soil/relief, mobility/accessibility,
population/services and climate/living environment.
- Each source records official ownership/coverage, the metrics it can honestly
support, an implementation priority and a real catalogue URL. Runtime status
is derived only from matching ready Datasets.
- Reworked the Sources inventory into six compact domain summaries. Detailed
theme/timeline state, active source limitations and candidate-source cards
remain accessible through progressive disclosure.
- Rewrote the Datavindplaats roadmap around a cross-domain area profile. The
next recommended implementation is a fixed allowlist of Mercator thematic
rasters plus the digital soil map, not another isolated water connector.
Boundaries:
- No backend provider, live fetch, API contract, database model or migration
changed in this pass.
- Audited sources remain visibly non-operational until a governed import and
metric-validation pass has completed. No source data or historical trend was
fabricated.
Validation:
- Frontend typecheck passes after the source-portfolio extraction and Sources
workspace refactor.
- Focused source-portfolio tests and the complete readiness gate are recorded
in the delivery handoff for this sprint.
Next:
- Implement the governed Flemish thematic-raster registry Wave 1 for space
occupation, open space, population density, node value and total service
level, followed by the digital soil map vector operator.
+147 -96
View File
@@ -1,130 +1,181 @@
# Datavindplaats Source Roadmap
This roadmap lists public Vlaamse Datavindplaats sources that are strong
additions for GeoIntel after the current Mol/Kempen foundation. Every source
must still receive a governed operator contract, source evidence retention,
CRS/unit validation and selection metrics before being shown as loaded data.
This roadmap was rebalanced on 2026-07-16 after a platform-wide review of
public Vlaamse Datavindplaats sources. Water is one analysis domain, not the
organizing principle of GeoIntel. The target product remains simple:
## P1 - Hydrology And Water Risk
1. select an area on the map;
2. choose a subject;
3. read source-correct measurements;
4. compare persisted observations when a valid time series exists;
5. inspect provenance and export evidence.
### Vlaamse Hydrografische Atlas - Waterlopen
Every source below is either already operational or has an official public
catalog/service record. A catalog entry is not the same as an implemented
provider. GeoIntel may label a source operational only after governed import,
CRS/unit validation, persisted provenance and selection-metric tests pass.
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/vlaamse-hydrografische-atlas-waterlopen-toestand-03-02-2026
- Service: https://www.vlaanderen.be/datavindplaats/catalogus/ogc-api-features-vlaamse-hydrografische-atlas-waterlopen
- Type: vector watercourse axes.
- Value: replace mixed GRB water context with authoritative watercourse
network metrics: length by category, navigable/non-navigable classes,
manager, basin/zone context and proximity to selected area.
- Caveat: line network is not water surface, discharge, depth or volume.
## Current Operational Foundation
### Afstromingskaart - meervoudige stroomlijnen
- Space and buildings: GRB building/road context, Buildings and Addresses
Register for Mol, official land-use snapshots and orthophotos.
- Nature and agriculture: regional BWK/Natura 2000 state 2025 and definitive
agricultural parcel editions.
- Soil and relief: bounded DHMV DTM/DSM acquisition with height, relief and
slope metrics.
- Climate and environment: VMM flood-hazard scenarios and station-bound
Waterinfo series.
- Historical context: official 1778, 1873 and 1969 mapped land-use classes and
modern land-use editions where persisted.
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/afstromingskaart-meervoudige-stroomlijnen
- Type: 5 m GeoTIFF, EPSG:31370.
- Value: runoff-risk and drainage-context layer for drawn rectangles and
parcels; useful beside DHMV and VMM flood scenarios.
- Caveat: modelled potential flow pattern, not observed water movement.
This is a strong base, but population/services, soil classes and modeled
accessibility are still genuine coverage gaps.
### Overstromingsgevoelige gebieden pluviaal/fluviaal
## Domain A - Space, Buildings And Economy
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/overstromingsgevoelige-gebieden-pluviaal
- Type: watertoets/informatieplicht map layer.
- Value: policy/legal flood-sensitivity overlay complementary to the current
VMM modelled water-depth scenario rasters.
- Caveat: do not merge with VMM depth rasters into one metric; it answers a
different policy question.
### Highest-value additions
## P2 - Soil, Infiltration And Erosion
- [Landgebruik Vlaanderen 2022](https://www.vlaanderen.be/datavindplaats/catalogus/landgebruik-vlaanderen-toestand-2022)
- 10 m GeoTIFF in EPSG:31370 with WMS/WCS distribution.
- Measure hectares and share by actual land-use class; do not present it as
legal zoning.
- [Ruimtebeslag Vlaanderen 2025](https://www.vlaanderen.be/datavindplaats/catalogus/ruimtebeslag-vlaanderen-toestand-2025)
- 10 m settlement/space-occupation raster.
- Measure occupied hectares and share beside open space and land use.
- [Open ruimte Vlaanderen 2022](https://www.vlaanderen.be/datavindplaats/catalogus/open-ruimte-vlaanderen-toestand-2022)
- 10 m derived open-space product.
- Keep its method separate from raw land-use classes.
- [Kernen, linten en verspreide bebouwing 2022](https://www.vlaanderen.be/datavindplaats/catalogus/kernen-linten-verspreide-bebouwing-in-vlaanderen-kernen-toestand-2022)
- Morphological vector typology, not a legal planning boundary.
- [WFS Bedrijventerreinen](https://www.vlaanderen.be/datavindplaats/catalogus/wfs-bedrijventerreinen)
- Production WFS for economic areas.
- Measure total/occupied area and retain VLAIO/Digitaal Vlaanderen source
status and edition.
### Digitale bodemkaart van het Vlaams Gewest: bodemtypes
## Domain B - Nature And Agriculture
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/digitale-bodemkaart-van-het-vlaams-gewest-bodemtypes
- Type: vector polygons, EPSG:31370.
- Value: soil texture/drainage/profile metrics by selected rectangle, strong
context for forest, agriculture, runoff and suitability analysis.
- Caveat: based on historical field data from 1949-1971; current drainage can
differ.
- [BWK / Natura 2000 state 2025](https://www.vlaanderen.be/datavindplaats/catalogus/biologische-waarderingskaart-en-natura-2000-habitatkaart-toestand-2025)
is operational regionally. It remains a current state, not an invented annual
nature series.
- [Open geodata agricultural parcels](https://www.vlaanderen.be/datavindplaats/catalogus/open-geodata-landbouwgebruikspercelen)
is operational as annual declared-use area. Parcel identities remain
intentionally unstable between editions.
- Open-space and land-use rasters complement these object layers. Metrics must
not add overlapping classification surfaces as if they were disjoint.
### Potentiele bodemerosiekaart per perceel
## Domain C - Soil And Relief
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/potentiele-bodemerosiekaart-per-perceel-2023
- Type: parcel-level erosion sensitivity.
- Value: erosion risk by selected area, especially useful with agricultural
parcels, slope/DHMV and runoff.
- Caveat: potential erosion modelling; not observed erosion damage.
- [Digital soil map: soil types](https://www.vlaanderen.be/datavindplaats/catalogus/digitale-bodemkaart-van-het-vlaams-gewest-bodemtypes)
- Vector soil polygons in EPSG:31370.
- Measure hectares by soil type, texture and drainage class.
- Historical field mapping from 1949-1971 is baseline evidence, not a claim
about current parcel drainage.
- [Potential soil erosion per parcel 2023](https://www.vlaanderen.be/datavindplaats/catalogus/potentiele-bodemerosiekaart-per-perceel-2023)
- Modelled potential erosion, not observed damage.
- Combine with agricultural use and DHMV slope only while keeping each
source and method explicit.
- [Physical system map](https://www.vlaanderen.be/datavindplaats/catalogus/fysische-systeemkaart)
- Coarse interpretive landscape zones for context, not parcel evidence.
### Fysische systeemkaart
## Domain D - Mobility And Accessibility
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/fysische-systeemkaart
- Type: generalized physical-system zones.
- Value: quick landscape-system interpretation: soil, relief, hydrological
setting, infiltration/kwel sensitivity.
- Caveat: coarser interpretive layer, not parcel-scale evidence.
- Current GRB roads provide map and length context where persisted.
- [Knooppuntwaarde per hectare 2022](https://www.vlaanderen.be/datavindplaats/catalogus/knooppuntwaarde-per-ha-toestand-2022)
- 1 ha modeled public-transport accessibility score.
- [Hoppinpunten and mobility hubs](https://www.vlaanderen.be/DataCatalogRecord/c262d7d0-d90d-4695-a8c6-6427ef4abb38)
- Planned and realized multimodal points; expose status and proximity.
- [Fietssnelwegen WFS](https://www.vlaanderen.be/datavindplaats/catalogus/fietssnelwegen-wfs)
- Region-wide network with realization, quality, lighting and route context.
## P3 - Spatial Planning And Built Environment
Accessibility scores are not live timetable reliability. Network length and
proximity are separate measurements from modeled accessibility.
### Ruimtebeslag - Vlaanderen - toestand 2025
## Domain E - Population And Services
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/ruimtebeslag-vlaanderen-toestand-2025
- Type: 10 m GeoTIFF, EPSG:31370.
- Value: built-up/settlement pressure metrics and evolution, complementary to
land-use and GRB building footprints.
- Caveat: settlement-area concept, not individual building footprint.
- [Statistical sectors, state 2024](https://www.vlaanderen.be/datavindplaats/catalogus/statistische-sectoren-van-belgie-toestand-01-01-2024)
- Spatial aggregation key for population and socio-economic indicators.
- [Population density per hectare 2019](https://www.vlaanderen.be/datavindplaats/catalogus/inwonersdichtheid-per-ha-vlaanderen-toestand-2019)
- 1 ha density surface corrected against Statbel sectors.
- Report observation year and estimation method; never expose address-level
population.
- [Total service level 2022](https://www.vlaanderen.be/datavindplaats/catalogus/totaal-voorzieningenniveau-toestand-2022)
- 1 ha modeled proximity score for daily services.
- [Synthesis node value and service level 2022](https://www.vlaanderen.be/datavindplaats/catalogus/synthese-knooppuntwaarde-en-voorzieningenniveau-toestand-2022)
- End-user classification after the two component scores are available.
- [Municipality indicators](https://www.vlaanderen.be/datavindplaats/catalogus/gemeente-in-cijfers)
- Context for municipal comparison; not a replacement for area-level map
measurements.
### Open ruimte - Vlaanderen - toestand 2022
## Domain F - Climate And Living Environment
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/open-ruimte-vlaanderen-toestand-2022
- Type: 10 m GeoTIFF, EPSG:31370.
- Value: open-space share per selection and regional fragmentation analysis.
- Caveat: derived from land-use/space-occupation/core logic; keep method
separate from raw land-use classes.
- VMM flood-hazard rasters and Waterinfo station series are already governed.
- [Urban heat islands](https://www.vlaanderen.be/datavindplaats/catalogus/hitte-eilanden-in-steden)
- Hittestress evidence with explicit year/method limitations.
- [PM2.5 concentration](https://www.vlaanderen.be/datavindplaats/catalogus/concentratie-fijn-stof-pm25-in-de-omgevingslucht)
and [GES air-quality map 2017](https://www.vlaanderen.be/datavindplaats/catalogus/ges-kaart-luchtkwaliteit-toestand-2017)
- Keep measured station trends separate from modeled area maps.
- [VHA watercourses OGC API](https://www.vlaanderen.be/datavindplaats/catalogus/ogc-api-features-vlaamse-hydrografische-atlas-waterlopen)
and [runoff map](https://www.vlaanderen.be/datavindplaats/catalogus/afstromingskaart-meervoudige-stroomlijnen)
remain useful, but they follow the broader cross-domain foundation.
Watercourse lines are not surfaces, discharge, depth or volume.
### Kernen, linten, verspreide bebouwing - toestand 2022
## Implementation Waves
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/kernen-linten-verspreide-bebouwing-in-vlaanderen-kernen-toestand-2022
- Type: vector typology.
- Value: readable urban morphology: core/lint/dispersed-building context for
Mol and Kempen.
- Caveat: algorithmic morphology; not a legal planning boundary.
### Wave 1 - Cross-domain area profile
### Verstedelijkt, randstedelijk en landelijk Vlaanderen - toestand 2022
Implement one governed Mercator thematic-raster registry instead of separate
ad-hoc provider code. Its fixed allowlist should first cover:
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/verstedelijkt-randstedelijk-en-landelijk-vlaanderen-indeling-op-basis-van-statistische-sectoren-toestand-2022
- Type: statistical-sector typology.
- Value: high-level area profile and comparison between municipalities.
- Caveat: analysis framework, not direct zoning policy.
1. space occupation 2025;
2. open space 2022;
3. population density 2019;
4. node value 2022;
5. total service level 2022.
## P4 - Accessibility And Services
The existing Dataset, DatasetVersion, Job and raster-selection architecture is
sufficient. Each product needs a fixed coverage id, native unit/classes,
observation date, resolution, legend, permitted aggregations and caveat. No
arbitrary WCS URL or layer name may enter the API.
### Knooppuntwaarde per ha - toestand 2022
In parallel, add the digital soil map through the existing canonical vector
DatasetService/VectorFeatureService path. This immediately gives every drawn
rectangle a balanced profile across space, soil, people, services and
accessibility.
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/knooppuntwaarde-per-ha-toestand-2022
- Type: 1 ha raster/grid score.
- Value: public-transport accessibility score for selected areas.
- Caveat: modelled accessibility score, not live timetable reliability.
### Wave 2 - Economic and mobility objects
### Totaal voorzieningenniveau - toestand 2022
Add governed vector operators for business parks, Hoppinpoints and cycle
highways. Persist provider output only through DatasetService and
VectorFeatureService. Selection metrics should be area for business parks,
counts/proximity for Hoppinpoints and length/status for cycle highways.
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/totaal-voorzieningenniveau-toestand-2022
- Type: 1 ha raster/grid score.
- Value: services proximity score for living-quality and spatial-development
analysis.
- Caveat: score is method-dependent and should be shown with source method.
### Wave 3 - Living environment
### Synthese knooppuntwaarde en voorzieningenniveau - toestand 2022
Add heat and air-quality sources only after their spatial scale and temporal
comparability are explicit. Then add VHA/runoff as hydrological context. Do not
derive missing volume, exposure or health outcomes.
- Catalogus: https://www.vlaanderen.be/datavindplaats/catalogus/synthese-knooppuntwaarde-en-voorzieningenniveau-toestand-2022
- Type: synthesized spatial-opportunity classification.
- Value: simple end-user layer for "where is development/accessibility strong?"
- Caveat: derived classification; keep underlying component scores available.
### Wave 4 - Historical completeness
## Recommended Implementation Order
Search for comparable earlier editions of every accepted product. A valid
series requires compatible classes and methods, explicit observation dates
and persisted versions. When methods differ, show side-by-side evidence rather
than a fabricated trend.
1. VHA waterlopen plus afstromingskaart: highest immediate GIS value and
directly improves water/runoff analysis without pretending to know volume.
2. Bodemkaart plus potential erosion: unlocks soil, drainage, infiltration and
agriculture/nature interpretation.
3. Ruimtebeslag/open ruimte/kernen-linten: makes map selection much more
understandable for end users and supports evolution narratives.
4. Knooppuntwaarde/voorzieningenniveau/synthese: adds planning-quality context
after the physical/environmental layers are stable.
## Recommended Next Sprint
Build **Governed Flemish Thematic Raster Registry - Wave 1**. It is the best
next platform step because one bounded, allowlisted acquisition architecture
unlocks spatial planning, open space, population, accessibility and services
without changing the database schema or creating one-off provider paths.
Acceptance requires:
- product registry and honest capability metadata;
- bounded WCS acquisition through the existing Job/Dataset flow;
- exact Area/rectangle selection with product-specific metrics;
- MapLibre image overlay and simple legend;
- source date, unit, method and caveat in every result;
- no startup/browser fetch and no fabricated historical observations;
- focused GIS, API, persistence and frontend tests;
- one Mol live smoke before regional provisioning.
+21
View File
@@ -495,3 +495,24 @@ ordinary Dataset upload API with `source_name=inbo_bwk_natura2000`,
The state remains a single 2025 map edition, not an annual time series. BWK
valuation, Natura 2000 shares, regional biotopes and uncertain habitat remain
separate fields and metrics. PHAB-derived hectares remain explicitly estimated.
## Platform-wide audited source portfolio
The complete follow-up portfolio is maintained in
`docs/DATAVINDPLAATS_SOURCE_ROADMAP.md` and represented in the frontend by
`frontend/src/lib/sourcePortfolio.ts`. It covers six equal product domains:
space/buildings, nature/agriculture, soil/relief, mobility/accessibility,
population/services and climate/living environment.
An official catalogue record means only that a candidate source has been
audited. It does not make the source operational. The Sources workspace may
report `operational` only when a matching Dataset has `status=ready`. Future
provider output continues to use DatasetService and, for vectors,
VectorFeatureService. Arbitrary service URLs, browser-side fetches and startup
downloads remain forbidden.
The recommended next connector is a fixed allowlist of public Mercator
thematic rasters for space occupation, open space, population density, node
value and service level. The digital soil map should follow the existing
canonical vector persistence path. Watercourse/runoff additions remain in the
roadmap but no longer precede these cross-domain gaps.
+10
View File
@@ -648,3 +648,13 @@ This file now starts with the current implementation status. Older preparation/b
- [x] Reject challenger activation because Postel-bos produced two detections while the active model remained at zero.
- [x] Update the recommended UI profile with the current active model's coverage-aligned evidence.
- [ ] Collect new training-only hard negatives matching the two Postel-bos errors before another challenger attempt.
# Sprint 212 - Platform-wide official source portfolio
- [x] Rebalance official source planning across six platform domains.
- [x] Distinguish operational ready Datasets from audited but unimplemented sources.
- [x] Reduce Sources workspace noise through domain summaries and progressive disclosure.
- [x] Add official space, soil, mobility, population, service, climate and economy candidates.
- [x] Replace the water-first recommendation with a cross-domain implementation wave.
- [ ] Implement the governed Flemish thematic-raster registry for space occupation, open space, population density, node value and service level.
- [ ] Add the digital soil map through DatasetService and VectorFeatureService.
+14
View File
@@ -547,3 +547,17 @@ regional Dataset remains available and the backend clips metrics and map output
to the selected municipality or drawn rectangle. The Sources workspace reports
overlapping BWK area snapshots as separate coverages and does not sum their
feature counts as if they were disjoint observations.
## Platform-wide source portfolio
The Sources inventory is organized around six end-user questions rather than
provider technology: space/buildings, nature/agriculture, soil/relief,
mobility/accessibility, population/services and climate/living environment.
The central definitions live in `src/lib/sourcePortfolio.ts`.
The domain cards count only matching `ready` Datasets as operational. Audited
official sources that have not passed acquisition, persistence and metric
validation remain inside the collapsed follow-up list with an explicit
priority and examples of the measurements they should eventually support.
Theme/time-series detail and active-source limitations are also collapsed by
default so the Data workspace stays readable.
@@ -1,5 +1,12 @@
import type { DatasetCreateResponse } from '../../types'
import { getDatasetSourceDisplayName } from '../../lib/datasetDisplay'
import {
OFFICIAL_SOURCE_PORTFOLIO,
SOURCE_DOMAINS,
operationalSources,
sourcesForDomain,
type SourcePriority,
} from '../../lib/sourcePortfolio'
interface SourceCatalogPanelProps {
datasets: DatasetCreateResponse[]
@@ -18,65 +25,6 @@ const THEME_LABELS: Record<string, string> = {
parcels: 'Percelen',
}
const AVAILABLE_SOURCES = [
{
key: 'historical_orthophoto',
name: 'Historische orthofotos',
owner: 'Digitaal Vlaanderen',
coverage: '1971, 1979-1990, 2000-2025',
value: 'Visuele evolutie via begrensde officiële luchtbeelden',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/orthofotomozaiek-kleinschalig-zomeropnamen',
},
{
key: 'bwk',
name: 'Biologische Waarderingskaart / Natura 2000',
owner: 'INBO',
coverage: 'Toestand 2025',
value: 'Natuurwaarde, biotopen en habitattypen',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/biologische-waarderingskaart-en-natura-2000-habitatkaart-toestand-2025',
},
{
key: 'agriculture',
name: 'Landbouwgebruikspercelen',
owner: 'Agentschap Landbouw en Zeevisserij',
coverage: 'Jaarlijkse bestanden',
value: 'Landbouwoppervlakte, teelten en perceelevolutie',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/open-geodata-landbouwgebruikspercelen',
},
{
key: 'buildings_register',
name: 'Gebouwen- en adressenregister',
owner: 'Digitaal Vlaanderen',
coverage: 'Continu geactualiseerd',
value: 'Gebouwstatus, levensloop en adressen als aanvulling op GRB',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/gebouwen-en-adressenregister',
},
{
key: 'elevation',
name: 'Digitaal Hoogtemodel Vlaanderen II',
owner: 'Digitaal Vlaanderen',
coverage: 'LiDAR-opname 2013-2015, DTM/DSM 1 m en 5 m',
value: 'Hoogte, reliëf en helling; afstroming is afgeleid, geen waterdiepte',
url: 'https://www.vlaanderen.be/digitaal-vlaanderen/onze-diensten-en-platformen/earth-observation-data-science-eodas/het-digitaal-hoogtemodel/digitaal-hoogtemodel-vlaanderen-ii',
},
{
key: 'waterinfo',
name: 'Waterinfo en VMM-metingen',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Meetpunten en tijdreeksen voor waterstand, debiet en neerslag',
value: 'Hydrologische toestand; geen gebiedsdekkend watervolume zonder bodemprofiel',
url: 'https://waterinfo.vlaanderen.be/',
},
{
key: 'flood_hazard',
name: 'Overstromingsgevaarkaarten waterdiepte',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Fluviaal/pluviaal, T10/T100/T1000, huidig klimaat en projectie 2050',
value: 'Gemodelleerd overstroomd oppervlak en maximale waterdiepte per vast scenario; geen bathymetrie',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/publieke-inspire-coverage-service-van-ogrk',
},
]
function datasetTheme(dataset: DatasetCreateResponse): string | null {
const configured = String(dataset.source_metadata?.['theme'] ?? dataset.reference_layer_name ?? '').toLowerCase()
if (configured === 'built' || configured === 'building') return 'buildings'
@@ -85,6 +33,12 @@ function datasetTheme(dataset: DatasetCreateResponse): string | null {
return null
}
function priorityLabel(priority: SourcePriority): string {
if (priority === 'next') return 'Eerstvolgend'
if (priority === 'planned') return 'Daarna'
return 'Later'
}
function timelineSummary(
temporalCount: number,
temporalSeriesCount: number,
@@ -132,15 +86,23 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
)[0]
const agricultureYears = agricultureDatasets
.flatMap((dataset) => dataset.observed_at ? [new Date(dataset.observed_at).getUTCFullYear()] : [])
const pendingSources = AVAILABLE_SOURCES.filter((source) => {
if (source.key === 'waterinfo') return waterinfoDatasets.length === 0
if (source.key === 'historical_orthophoto') return historicalOrthophotos.length === 0
const availableSources = operationalSources(ready)
const availableSourceKeys = new Set(availableSources.map((source) => source.key))
const pendingSources = OFFICIAL_SOURCE_PORTFOLIO.filter((source) => {
if (source.key === 'bwk') return bwkDatasets.length === 0
if (source.key === 'agriculture') return agricultureDatasets.length === 0
if (source.key === 'buildings_register') return buildingsRegisterDatasets.length === 0
if (source.key === 'elevation') return dhmvDatasets.length === 0
if (source.key === 'flood_hazard') return floodHazardDatasets.length === 0
return true
return !availableSourceKeys.has(source.key)
})
const domains = SOURCE_DOMAINS.map((domain) => {
const sources = sourcesForDomain(domain.key)
const loaded = sources.filter((source) => availableSourceKeys.has(source.key))
const next = sources.filter((source) => source.priority === 'next' && !availableSourceKeys.has(source.key))
return {
...domain,
sourceCount: sources.length,
loadedCount: loaded.length,
nextCount: next.length,
loadedNames: loaded.map((source) => source.name),
}
})
const themes = Object.keys(THEME_LABELS).map((theme) => {
const matches = ready.filter((dataset) => datasetTheme(dataset) === theme)
@@ -174,33 +136,58 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
<div className="panel-title-row">
<div>
<span className="section-kicker">Broninventaris</span>
<h2>Wat is werkelijk beschikbaar?</h2>
<p className="muted">Ingeladen bronnen staan direct klaar voor de kaart. Andere officiële bronnen worden pas gebruikt na een gecontroleerde import.</p>
<h2>Welke vragen kan GeoIntel beantwoorden?</h2>
<p className="muted">Zes domeinen vormen samen het platform. Alleen werkelijk ingeladen bronnen krijgen de status operationeel; de rest blijft een transparante aansluitplanning.</p>
</div>
<span className="status-badge status-badge-ready">{ready.length} datasets klaar</span>
<span className="status-badge status-badge-ready">{availableSources.length} officiële bronnen operationeel</span>
</div>
<div className="source-catalog-grid">
{themes.map((theme) => (
<article className="source-catalog-card" key={theme.theme}>
<div className="source-domain-grid" aria-label="Platformbrede brondomeinen">
{domains.map((domain) => (
<article className="source-domain-card" key={domain.key}>
<div>
<strong>{theme.label}</strong>
<span>{theme.source ?? 'Nog niet ingeladen'}</span>
<strong>{domain.label}</strong>
<span>{domain.loadedCount} van {domain.sourceCount} bronnen operationeel</span>
</div>
<b>{theme.datasetCount > 0 ? 'Beschikbaar' : 'Ontbreekt'}</b>
<p>{timelineSummary(
theme.temporalCount,
theme.temporalSeriesCount,
theme.otherMethodCount,
theme.firstYear,
theme.lastYear,
)}</p>
<b className={domain.loadedCount > 0 ? 'source-status-operational' : 'source-status-planned'}>
{domain.loadedCount > 0 ? 'Operationeel' : 'Aansluiting nodig'}
</b>
<p>{domain.question}</p>
<small>
{domain.loadedNames.length > 0
? domain.loadedNames.slice(0, 2).join(' · ')
: `${domain.nextCount} geverifieerde bron${domain.nextCount === 1 ? '' : 'nen'} eerstvolgend`}
</small>
</article>
))}
</div>
<details className="source-theme-coverage">
<summary>Dekking per kaartthema en tijdreeks</summary>
<div className="source-catalog-grid">
{themes.map((theme) => (
<article className="source-catalog-card" key={theme.theme}>
<div>
<strong>{theme.label}</strong>
<span>{theme.source ?? 'Nog niet ingeladen'}</span>
</div>
<b>{theme.datasetCount > 0 ? 'Beschikbaar' : 'Ontbreekt'}</b>
<p>{timelineSummary(
theme.temporalCount,
theme.temporalSeriesCount,
theme.otherMethodCount,
theme.firstYear,
theme.lastYear,
)}</p>
</article>
))}
</div>
</details>
{waterinfoDatasets.length > 0 || historicalOrthophotos.length > 0 || bwkDatasets.length > 0 || agricultureDatasets.length > 0 || buildingsRegisterDatasets.length > 0 || dhmvDatasets.length > 0 || floodHazardDatasets.length > 0 ? (
<div className="source-catalog-loaded" aria-label="Aanvullende ingeladen bronnen">
<details className="source-loaded-disclosure">
<summary>Actieve broncollecties en hun beperkingen</summary>
<div className="source-catalog-loaded" aria-label="Aanvullende ingeladen bronnen">
{waterinfoDatasets.length > 0 ? (
<article>
<strong>Waterinfo meetreeksen</strong>
@@ -257,22 +244,39 @@ export function SourceCatalogPanel({ datasets }: SourceCatalogPanelProps): JSX.E
<p>Gemodelleerde maximumdiepte per kansscenario. Geen actuele waterstand, bathymetrie of permanent watervolume.</p>
</article>
) : null}
</div>
</div>
</details>
) : null}
<details className="source-opportunity-list">
<summary>Officiële bronnen die hierna kunnen worden ingeladen</summary>
<div>
{pendingSources.map((source) => (
<article key={source.name}>
<div>
<strong>{source.name}</strong>
<span>{source.owner} · {source.coverage}</span>
</div>
<p>{source.value}</p>
<a href={source.url} target="_blank" rel="noreferrer">Bekijk officiële bron</a>
</article>
))}
<div className="source-opportunity-domains">
{SOURCE_DOMAINS.map((domain) => {
const sources = pendingSources.filter((source) => source.domain === domain.key)
if (sources.length === 0) return null
return (
<section className="source-opportunity-domain" key={domain.key}>
<header>
<strong>{domain.label}</strong>
<span>{sources.length} gecontroleerde kandidaatbron{sources.length === 1 ? '' : 'nen'}</span>
</header>
<div>
{sources.map((source) => (
<article key={source.name}>
<div>
<strong>{source.name}</strong>
<span>{source.owner} · {source.coverage}</span>
</div>
<span className={`source-priority source-priority-${source.priority}`}>{priorityLabel(source.priority)}</span>
<p>{source.value}</p>
<small>Meetbaar als: {source.metricExamples}</small>
<a href={source.url} target="_blank" rel="noreferrer">Bekijk officiële bron</a>
</article>
))}
</div>
</section>
)
})}
</div>
</details>
</section>
+398
View File
@@ -0,0 +1,398 @@
import type { DatasetCreateResponse } from '../types'
export type SourceDomainKey =
| 'space'
| 'nature'
| 'soil'
| 'mobility'
| 'people'
| 'climate'
export type SourcePriority = 'next' | 'planned' | 'later'
export interface SourceDomainDefinition {
key: SourceDomainKey
label: string
question: string
}
export interface OfficialSourceDefinition {
key: string
domain: SourceDomainKey
name: string
owner: string
coverage: string
value: string
metricExamples: string
priority: SourcePriority
url: string
matches: (dataset: DatasetCreateResponse) => boolean
}
const sourceNameIs = (dataset: DatasetCreateResponse, sourceName: string): boolean =>
dataset.source_name === sourceName
const referenceLayerIs = (dataset: DatasetCreateResponse, layerName: string): boolean =>
String(dataset.reference_layer_name ?? dataset.source_metadata?.['theme'] ?? '').toLowerCase() === layerName
export const SOURCE_DOMAINS: SourceDomainDefinition[] = [
{
key: 'space',
label: 'Ruimte en bebouwing',
question: 'Wat staat en gebeurt hier, en hoe verandert het ruimtegebruik?',
},
{
key: 'nature',
label: 'Natuur en landbouw',
question: 'Hoeveel bos, natuurwaarde en landbouwgebruik ligt in de selectie?',
},
{
key: 'soil',
label: 'Bodem en reliëf',
question: 'Welke bodem, hoogte, helling en erosiegevoeligheid komen voor?',
},
{
key: 'mobility',
label: 'Mobiliteit en bereikbaarheid',
question: 'Welke netwerken en knooppunten maken het gebied bereikbaar?',
},
{
key: 'people',
label: 'Bevolking en voorzieningen',
question: 'Hoeveel mensen wonen er en hoe bereikbaar zijn dagelijkse diensten?',
},
{
key: 'climate',
label: 'Klimaat en leefomgeving',
question: 'Welke risicos en omgevingsdruk spelen rond hitte, lucht en water?',
},
]
export const OFFICIAL_SOURCE_PORTFOLIO: OfficialSourceDefinition[] = [
{
key: 'grb_buildings',
domain: 'space',
name: 'GRB-gebouwen',
owner: 'Digitaal Vlaanderen',
coverage: 'Actuele gebouwcontouren',
value: 'Objectniveau voor bebouwing, kaartselectie en AI-validatie.',
metricExamples: 'aantal gebouwen, bebouwde oppervlakte, dichtheid',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/grbgis',
matches: (dataset) => sourceNameIs(dataset, 'grb') && referenceLayerIs(dataset, 'buildings'),
},
{
key: 'building_register',
domain: 'space',
name: 'Gebouwen- en Adressenregister',
owner: 'Digitaal Vlaanderen',
coverage: 'Continu geactualiseerd',
value: 'Gebouwstatus en geaggregeerde eenheden als aanvulling op GRB.',
metricExamples: 'gerealiseerde gebouwen, gebouweenheden, statusverdeling',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/gebouwen-en-adressenregister',
matches: (dataset) => sourceNameIs(dataset, 'digitaal_vlaanderen_buildings_addresses_register'),
},
{
key: 'land_use',
domain: 'space',
name: 'Landgebruik Vlaanderen',
owner: 'Departement Omgeving',
coverage: '10 m raster, meerdere officiële toestanden',
value: 'Werkelijk gebruik voor wonen, industrie, landbouw en natuur.',
metricExamples: 'hectare per landgebruiksklasse, aandeel van selectie, evolutie',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/landgebruik-vlaanderen-toestand-2022',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_land_use') || sourceNameIs(dataset, 'historical_landuse'),
},
{
key: 'orthophoto',
domain: 'space',
name: 'Actuele en historische orthofotos',
owner: 'Digitaal Vlaanderen',
coverage: '1971, 1979-1990 en jaarlijkse reeksen 2000-2025',
value: 'Beeldbewijs voor actuele toestand en visuele evolutie.',
metricExamples: 'beeldjaargang en begrensde AI- of visuele analyse',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/orthofotomozaiek-kleinschalig-zomeropnamen',
matches: (dataset) => sourceNameIs(dataset, 'digitaal_vlaanderen_orthophoto'),
},
{
key: 'space_occupation',
domain: 'space',
name: 'Ruimtebeslag Vlaanderen 2025',
owner: 'Departement Omgeving',
coverage: '10 m raster, toestand 2025',
value: 'Gebiedsdruk en ingenomen ruimte naast het fijnere GRB-objectbeeld.',
metricExamples: 'hectare ruimtebeslag, aandeel, vergelijking met open ruimte',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/ruimtebeslag-vlaanderen-toestand-2025',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_space_occupation'),
},
{
key: 'settlement_typology',
domain: 'space',
name: 'Kernen, linten en verspreide bebouwing',
owner: 'Departement Omgeving',
coverage: 'Toestand 2022',
value: 'Begrijpelijke morfologie voor kern, lint en verspreide bebouwing.',
metricExamples: 'oppervlakte en aandeel per morfologisch type',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/kernen-linten-verspreide-bebouwing-in-vlaanderen-kernen-toestand-2022',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_settlement_typology'),
},
{
key: 'business_parks',
domain: 'space',
name: 'Bedrijventerreinen OSLO',
owner: 'VLAIO / Digitaal Vlaanderen',
coverage: 'Productieservice, toestand 2026',
value: 'Economische ruimte, bezetting en bedrijventerreincontext.',
metricExamples: 'hectare bedrijventerrein, bezette/onbezette oppervlakte',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/wfs-bedrijventerreinen',
matches: (dataset) => sourceNameIs(dataset, 'vlaio_business_parks'),
},
{
key: 'bwk',
domain: 'nature',
name: 'BWK / Natura 2000',
owner: 'INBO',
coverage: 'Toestand 2025',
value: 'Biologische waardering, biotopen en habitattypen.',
metricExamples: 'hectare natuurwaarde, habitat en regionaal belangrijk biotoop',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/biologische-waarderingskaart-en-natura-2000-habitatkaart-toestand-2025',
matches: (dataset) => sourceNameIs(dataset, 'inbo_bwk_natura2000'),
},
{
key: 'agriculture',
domain: 'nature',
name: 'Landbouwgebruikspercelen',
owner: 'Agentschap Landbouw en Zeevisserij',
coverage: 'Jaarlijkse definitieve bestanden',
value: 'Landbouwoppervlakte en teeltevolutie zonder perceellijnage te verzinnen.',
metricExamples: 'hectare landbouw en hoofdteeltgroep per jaar',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/open-geodata-landbouwgebruikspercelen',
matches: (dataset) => sourceNameIs(dataset, 'agentschap_landbouw_zeevisserij_agricultural_parcels'),
},
{
key: 'open_space',
domain: 'nature',
name: 'Open ruimte Vlaanderen',
owner: 'Departement Omgeving',
coverage: '10 m raster, toestand 2022',
value: 'Openruimte-aandeel en versnippering naast ruimtebeslag en landgebruik.',
metricExamples: 'hectare open ruimte, aandeel en fragmentatie',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/open-ruimte-vlaanderen-toestand-2022',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_open_space'),
},
{
key: 'dhmv',
domain: 'soil',
name: 'Digitaal Hoogtemodel Vlaanderen II',
owner: 'Digitaal Vlaanderen',
coverage: 'DTM/DSM, opname 2013-2015',
value: 'Hoogte, reliëf en helling als gemeten terreinbasis.',
metricExamples: 'hoogte m TAW, reliëf en helling in graden',
priority: 'next',
url: 'https://www.vlaanderen.be/digitaal-vlaanderen/onze-diensten-en-platformen/earth-observation-data-science-eodas/het-digitaal-hoogtemodel/digitaal-hoogtemodel-vlaanderen-ii',
matches: (dataset) => sourceNameIs(dataset, 'digitaal_vlaanderen_dhmv'),
},
{
key: 'soil_map',
domain: 'soil',
name: 'Digitale bodemkaart',
owner: 'Databank Ondergrond Vlaanderen',
coverage: 'Vlaams Gewest, historische kartering',
value: 'Bodemtype, textuur en drainage voor landbouw en geschiktheid.',
metricExamples: 'hectare per bodemtype, drainage- en textuurverdeling',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/digitale-bodemkaart-van-het-vlaams-gewest-bodemtypes',
matches: (dataset) => sourceNameIs(dataset, 'dov_soil_map'),
},
{
key: 'erosion',
domain: 'soil',
name: 'Potentiële bodemerosie per perceel',
owner: 'Departement Omgeving',
coverage: 'Perceelmodel, editie 2023',
value: 'Potentiële erosiedruk gecombineerd met landbouw en reliëf.',
metricExamples: 'hectare per erosieklasse en aandeel risicogebied',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/potentiele-bodemerosiekaart-per-perceel-2023',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_erosion'),
},
{
key: 'grb_roads',
domain: 'mobility',
name: 'GRB-wegen en transport',
owner: 'Digitaal Vlaanderen',
coverage: 'Actuele wegcontext',
value: 'Wegennet en transportcontext in de kaartselectie.',
metricExamples: 'kilometer weg, dichtheid en afstand tot netwerk',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/grbgis',
matches: (dataset) => sourceNameIs(dataset, 'grb') && referenceLayerIs(dataset, 'roads'),
},
{
key: 'node_value',
domain: 'mobility',
name: 'Knooppuntwaarde per hectare',
owner: 'Departement Omgeving',
coverage: '1 ha raster, toestand 2022',
value: 'Modelmatige bereikbaarheid via collectief vervoer.',
metricExamples: 'gemiddelde score en aandeel per bereikbaarheidsklasse',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/knooppuntwaarde-per-ha-toestand-2022',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_node_value'),
},
{
key: 'hoppin',
domain: 'mobility',
name: 'Hoppinpunten en mobiliteitsknooppunten',
owner: 'Departement Mobiliteit en Openbare Werken',
coverage: 'Geplande en gerealiseerde punten',
value: 'Multimodale overstappunten en voorzieningen in de buurt.',
metricExamples: 'aantal punten, status en afstand tot selectie',
priority: 'planned',
url: 'https://www.vlaanderen.be/DataCatalogRecord/c262d7d0-d90d-4695-a8c6-6427ef4abb38',
matches: (dataset) => sourceNameIs(dataset, 'mow_hoppin'),
},
{
key: 'cycle_highways',
domain: 'mobility',
name: 'Fietssnelwegen',
owner: 'Vereniging van de Vlaamse Provincies',
coverage: 'Vlaams netwerk, productieservice',
value: 'Gerealiseerde en geplande functionele fietsverbindingen.',
metricExamples: 'kilometer route, realisatiestatus en kwaliteit',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/fietssnelwegen-wfs',
matches: (dataset) => sourceNameIs(dataset, 'vvp_cycle_highways'),
},
{
key: 'statistical_sectors',
domain: 'people',
name: 'Statistische sectoren',
owner: 'Statbel / Digitaal Vlaanderen',
coverage: 'Gebiedsindeling, toestand 2024/2025',
value: 'Betrouwbare ruimtelijke sleutel voor socio-economische indicatoren.',
metricExamples: 'sectorprofielen en gewogen indicatoren per selectie',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/statistische-sectoren-van-belgie-toestand-01-01-2024',
matches: (dataset) => sourceNameIs(dataset, 'statbel') && referenceLayerIs(dataset, 'statistical_sectors'),
},
{
key: 'population_density',
domain: 'people',
name: 'Inwonersdichtheid per hectare',
owner: 'Departement Omgeving / Statbel',
coverage: '1 ha raster, toestand 2019',
value: 'Gebiedsdekkende bevolkingsdichtheid zonder adressen te tonen.',
metricExamples: 'geschat aantal inwoners en inwoners per hectare',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/inwonersdichtheid-per-ha-vlaanderen-toestand-2019',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_population_density'),
},
{
key: 'service_level',
domain: 'people',
name: 'Totaal voorzieningenniveau',
owner: 'Departement Omgeving',
coverage: '1 ha raster, toestand 2022',
value: 'Nabijheid van dagelijkse voorzieningen in één brongetrouwe score.',
metricExamples: 'gemiddelde score en aandeel per voorzieningsklasse',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/totaal-voorzieningenniveau-toestand-2022',
matches: (dataset) => sourceNameIs(dataset, 'department_omgeving_service_level'),
},
{
key: 'municipality_indicators',
domain: 'people',
name: 'Gemeente in cijfers',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Gemeentelijke klimaat- en leefomgevingsindicatoren',
value: 'Contextcijfers voor Mol en vergelijking met andere gemeenten.',
metricExamples: 'hittegolfdagen, temperatuur en luchtkwaliteitsindex',
priority: 'later',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/gemeente-in-cijfers',
matches: (dataset) => sourceNameIs(dataset, 'vmm_municipality_indicators'),
},
{
key: 'flood_hazard',
domain: 'climate',
name: 'VMM-overstromingsgevaar',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Fluviaal/pluviaal, T10/T100/T1000, huidig en 2050',
value: 'Gemodelleerde lokale maximumdiepte per kansscenario.',
metricExamples: 'hectare positieve diepte, gemiddelde/P90/maximale diepte',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/publieke-inspire-coverage-service-van-ogrk',
matches: (dataset) => sourceNameIs(dataset, 'vmm_flood_hazard'),
},
{
key: 'waterinfo',
domain: 'climate',
name: 'Waterinfo meetreeksen',
owner: 'Waterinfo Vlaanderen',
coverage: 'Stationgebonden jaarmetingen',
value: 'Hydrologische waarnemingen als puntreeksen, niet als gebiedsvolume.',
metricExamples: 'waterstand, debiet en neerslag per station en periode',
priority: 'planned',
url: 'https://waterinfo.vlaanderen.be/',
matches: (dataset) => sourceNameIs(dataset, 'waterinfo'),
},
{
key: 'heat_stress',
domain: 'climate',
name: 'Hitte-eilanden in steden',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Jaarbeelden 2019-2022',
value: 'Ruimtelijke blootstelling aan hittestress voor leefomgevingsanalyse.',
metricExamples: 'hittegolfgraaddagen en aandeel blootgesteld gebied',
priority: 'next',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/hitte-eilanden-in-steden',
matches: (dataset) => sourceNameIs(dataset, 'vmm_heat_stress'),
},
{
key: 'air_quality',
domain: 'climate',
name: 'Luchtkwaliteit',
owner: 'Vlaamse Milieumaatschappij / Departement Omgeving',
coverage: 'Meetreeksen en geselecteerde gebiedskaarten',
value: 'PM2,5 en andere luchtindicatoren met expliciete schaal en jaargang.',
metricExamples: 'concentratie, normoverschrijding en trend per brongebied',
priority: 'planned',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/concentratie-fijn-stof-pm25-in-de-omgevingslucht',
matches: (dataset) => sourceNameIs(dataset, 'vmm_air_quality'),
},
{
key: 'vha',
domain: 'climate',
name: 'Vlaamse Hydrografische Atlas',
owner: 'Vlaamse Milieumaatschappij',
coverage: 'Actuele gecategoriseerde waterlopen',
value: 'Autoritatief waterlopennetwerk voor lengte, categorie en beheerder.',
metricExamples: 'kilometer waterloop per categorie en afstand tot netwerk',
priority: 'later',
url: 'https://www.vlaanderen.be/datavindplaats/catalogus/ogc-api-features-vlaamse-hydrografische-atlas-waterlopen',
matches: (dataset) => sourceNameIs(dataset, 'vmm_vha'),
},
]
export function operationalSources(
datasets: DatasetCreateResponse[],
domain?: SourceDomainKey,
): OfficialSourceDefinition[] {
const ready = datasets.filter((dataset) => dataset.status === 'ready')
return OFFICIAL_SOURCE_PORTFOLIO.filter(
(source) => (!domain || source.domain === domain) && ready.some(source.matches),
)
}
export function sourcesForDomain(domain: SourceDomainKey): OfficialSourceDefinition[] {
return OFFICIAL_SOURCE_PORTFOLIO.filter((source) => source.domain === domain)
}
+156 -5
View File
@@ -6669,13 +6669,91 @@ section {
grid-column: 1 / -1;
}
.source-catalog-grid {
.source-domain-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 0.65rem;
margin-top: 1rem;
}
.source-domain-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 0.42rem 0.7rem;
min-width: 0;
border: 1px solid #d9e4df;
border-left: 3px solid #75968a;
border-radius: 6px;
padding: 0.82rem;
background: #fbfcfc;
}
.source-domain-card > div {
display: grid;
min-width: 0;
gap: 0.14rem;
}
.source-domain-card span,
.source-domain-card p,
.source-domain-card small {
margin: 0;
color: #62716c;
font-size: 0.73rem;
line-height: 1.42;
}
.source-domain-card b {
align-self: start;
font-size: 0.68rem;
}
.source-domain-card p,
.source-domain-card small {
grid-column: 1 / -1;
}
.source-domain-card small {
border-top: 1px solid #e6ece9;
padding-top: 0.4rem;
}
.source-status-operational {
color: #286646;
}
.source-status-planned {
color: #8a5a16;
}
.source-theme-coverage,
.source-loaded-disclosure,
.source-catalog-grid {
min-width: 0;
}
.source-theme-coverage,
.source-loaded-disclosure {
margin-top: 0.8rem;
border-top: 1px solid #dfe7e4;
padding-top: 0.7rem;
}
.source-theme-coverage > summary,
.source-loaded-disclosure > summary {
cursor: pointer;
color: #34433e;
font-size: 0.82rem;
font-weight: 750;
}
.source-catalog-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 0.65rem;
margin-top: 0.7rem;
}
.source-catalog-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
@@ -6715,7 +6793,7 @@ section {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.6rem;
margin-top: 0.75rem;
margin-top: 0.7rem;
}
.source-catalog-loaded article {
@@ -6747,12 +6825,47 @@ section {
.source-opportunity-list > div {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: minmax(0, 1fr);
gap: 0.6rem;
margin-top: 0.7rem;
}
.source-opportunity-domain {
display: grid;
gap: 0.55rem;
border: 0;
border-top: 1px solid #e2e8e6;
border-radius: 0;
padding: 0.7rem 0 0;
background: transparent;
box-shadow: none;
}
.source-opportunity-domain:first-child {
border-top: 0;
padding-top: 0;
}
.source-opportunity-domain > header {
display: flex;
gap: 0.7rem;
align-items: baseline;
justify-content: space-between;
}
.source-opportunity-domain > header span {
color: #66746f;
font-size: 0.7rem;
}
.source-opportunity-domain > div {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.55rem;
}
.source-opportunity-list article {
position: relative;
display: grid;
gap: 0.35rem;
padding: 0.75rem;
@@ -6772,20 +6885,58 @@ section {
font-weight: 700;
}
.source-opportunity-list article > small {
margin: 0;
color: #52635d;
font-size: 0.7rem;
line-height: 1.4;
}
.source-priority {
position: absolute;
top: 0.7rem;
right: 0.7rem;
border-left: 2px solid #718096;
padding-left: 0.38rem;
font-size: 0.65rem !important;
font-weight: 800;
}
.source-opportunity-list article > div {
padding-right: 5.5rem;
}
.source-priority-next {
border-left-color: #287051;
color: #286646 !important;
}
.source-priority-planned {
border-left-color: #a66a18;
color: #8a5a16 !important;
}
@media (max-width: 980px) {
.source-domain-grid,
.source-catalog-grid,
.source-catalog-loaded,
.source-opportunity-list > div {
.source-opportunity-domain > div {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.source-domain-grid,
.source-catalog-grid,
.source-catalog-loaded,
.source-opportunity-list > div {
.source-opportunity-domain > div {
grid-template-columns: 1fr;
}
.source-opportunity-domain > header {
display: grid;
gap: 0.15rem;
}
}
.workspace-grid-assistant {