From d0f939b91e9adb31622e848e3596b7c7341ffb7d Mon Sep 17 00:00:00 2001 From: Ivor Bosloper Date: Mon, 26 Oct 2026 14:31:35 +0100 Subject: [PATCH] DE-BB: leave out landscape elements, and map the zero-padded codes to HCAT Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + fiboa_cli/datasets/de_bb.py | 6 +++++- tests/test_convert.py | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b39ed7d..b03f205b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - CH: Removed the national `ch` converter, whose single licence could not cover the cantons' differing terms; the canton converters replace it, and a Swiss file is `fiboa merge` of their outputs. ### Fixed +- DE-BB: Landscape elements (hedges, tree rows, copses, wetlands) are left out, and codes under 100, such as the eco-scheme areas, now map to HCAT; they come zero-padded in the source. - Added HCAT spelling fixes via `csv_supplements` for DE-BB, DE-NDS and EC-SI. - EC-FR, EC-NL-CROP: HCAT mappings for iris, Jerusalem artichoke and parsley now match the taxonomy. - EuroCrops converters whose source already carries HCAT (such as EC-FR and EC-SI) now apply their supplements too. diff --git a/fiboa_cli/datasets/de_bb.py b/fiboa_cli/datasets/de_bb.py index ae404d40..67210c4f 100644 --- a/fiboa_cli/datasets/de_bb.py +++ b/fiboa_cli/datasets/de_bb.py @@ -37,4 +37,8 @@ class Converter(AdminConverterMixin, AddHCATMixin, FiboaBaseConverter): "code": "crop:code", } # NBF: areas in a field block the cadastre marks as not usable for agriculture (pylons, ditches, woods); no crop code - column_filters = {"tf_typ": lambda col: col != "NBF"} + # LE: landscape elements (hedges, tree rows, copses, wetlands), which are no fields; their + # codes 001-013 also name non-crop uses, so only the type tells them apart + column_filters = {"tf_typ": lambda col: ~col.isin(["NBF", "LE"])} + # codes under 100 come zero-padded (088), the code lists write them without (88) + column_migrations = {"code": lambda col: col.str.replace(r"^0+(?=\d)", "", regex=True)} diff --git a/tests/test_convert.py b/tests/test_convert.py index 86f5f2b3..c7eaa3bf 100644 --- a/tests/test_convert.py +++ b/tests/test_convert.py @@ -363,8 +363,13 @@ def _input_files(converter, *names): "ec_be_vlg": ("1", "2"), # small woody features and other areas that are no field "de_thuenen": ("3001", "3004"), + # landscape elements (tf_typ LE); in the fixture these codes name nothing else + "de_bb": ("1", "3", "4", "11", "13", "001", "003", "004", "011", "013"), } +# Converters whose fixture maps every row to HCAT +fully_mapped = {"de_bb"} + # The smallest field (m²) a converter keeps, where the fixture holds a smaller sliver minimum_area = { "br_conab": 100, @@ -444,6 +449,10 @@ def load_mapping(csv_file=None, url=None): dropped = [c for c in filtered_codes.get(converter, ()) if c in set(df["crop:code"])] assert not dropped, f"{converter} kept rows it should filter out: crop:code {dropped}" + if converter in fully_mapped: + unmapped = sorted(set(df.loc[df["hcat:code"].isna(), "crop:code"])) + assert not unmapped, f"{converter}: crop:code {unmapped} has no HCAT code" + if "metrics:area" in df.columns and converter not in ("de_bb", "ec_de_bb"): # Check for accidental hectare conversion; fields should be more than 10 square meters assert (df["metrics:area"] > 10).all()