Broaden official source portfolio
This commit is contained in:
@@ -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)
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 orthofoto’s',
|
||||
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>
|
||||
|
||||
@@ -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 risico’s 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 orthofoto’s',
|
||||
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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user