From fb251c0cf4dad4910119b4629c831fe3a57987da Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Tue, 30 Jun 2026 16:12:59 +0200 Subject: [PATCH 1/6] CI: fix testdata: broken NRW Hausumringe dataset URL Replace huge 859.7 MB file `hu_EPSG4647_Shape.zip` (which no longer exists in openNRW) with 70 MB `gru_vereinf_05314000_Bonn_EPSG25832_GeoPackage.zip` file from --- download_urls.py | 4 ++-- testsuite/data/test_aoi_NW.geojson | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/download_urls.py b/download_urls.py index 673aad6..1baed77 100644 --- a/download_urls.py +++ b/download_urls.py @@ -34,7 +34,7 @@ "MV": None, "NI": None, "NW": "https://www.opengeodata.nrw.de/produkte/geobasis" - "/lk/akt/hu_shp/hu_EPSG4647_Shape.zip", + "/lk/akt/gru_vereinfacht_gpkg/gru_vereinf_05314000_Bonn_EPSG25832_GeoPackage.zip", "RP": None, "SL": None, "SN": "https://geocloud.landesvermessung.sachsen.de/index.php/s" @@ -54,7 +54,7 @@ "HE": "gebaeude-he.shp", "MV": None, "NI": None, - "NW": "hu_shp.shp", + "NW": "gru_vereinf_05314000_Bonn_EPSG25832_GeoPackage.gpkg", "RP": None, "SL": None, "SN": "hu_sn_gebaeude_20240118.shp", diff --git a/testsuite/data/test_aoi_NW.geojson b/testsuite/data/test_aoi_NW.geojson index ac84219..0fbdedb 100644 --- a/testsuite/data/test_aoi_NW.geojson +++ b/testsuite/data/test_aoi_NW.geojson @@ -1 +1 @@ -{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[6.955032348632812,50.94544969875718],[6.933231353759766,50.935714552368594],[6.957607269287109,50.92998067919713],[6.961212158203125,50.937445394034576],[6.955032348632812,50.94544969875718]]]}}]} +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[7.120,50.740],[7.120,50.730],[7.145,50.730],[7.145,50.740],[7.120,50.740]]]}}]} From 9aee36eb70a624e1317f766efc629fc4660ea880 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Tue, 30 Jun 2026 16:36:39 +0200 Subject: [PATCH 2/6] fix layer name --- download_urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download_urls.py b/download_urls.py index 1baed77..0297393 100644 --- a/download_urls.py +++ b/download_urls.py @@ -54,7 +54,7 @@ "HE": "gebaeude-he.shp", "MV": None, "NI": None, - "NW": "gru_vereinf_05314000_Bonn_EPSG25832_GeoPackage.gpkg", + "NW": "202601_gru_vereinf_05314000_Bonn_EPSG25832.gpkg", "RP": None, "SL": None, "SN": "hu_sn_gebaeude_20240118.shp", From 8a5dc78d2221317c9ef9c37fe56398eff86c1dcc Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Tue, 30 Jun 2026 17:10:18 +0200 Subject: [PATCH 3/6] fix test sets region --- testsuite/data/test_aoi_NW.geojson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/data/test_aoi_NW.geojson b/testsuite/data/test_aoi_NW.geojson index 0fbdedb..c6cfa9b 100644 --- a/testsuite/data/test_aoi_NW.geojson +++ b/testsuite/data/test_aoi_NW.geojson @@ -1 +1 @@ -{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[7.120,50.740],[7.120,50.730],[7.145,50.730],[7.145,50.740],[7.120,50.740]]]}}]} +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[7.090,50.750],[7.090,50.710],[7.155,50.710],[7.155,50.750],[7.090,50.750]]]}}]} From 78e3dc73dbf647bbcc810ca250669e8ec1290b74 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Mon, 20 Jul 2026 20:12:16 +0200 Subject: [PATCH 4/6] add BUILDINGS_LAYERS dict for NW GPKG layer selection --- download_urls.py | 4 ++++ v.alkis.buildings.import.py | 31 +++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/download_urls.py b/download_urls.py index 0297393..6aeb268 100644 --- a/download_urls.py +++ b/download_urls.py @@ -63,6 +63,10 @@ "TH": "gebaeude-th.shp", } +BUILDINGS_LAYERS = { + "NW": "GebauedeBauwerk", +} + BB_districts = { "BAR": "Barnim", "BRB": "Brandenburg an der Havel", diff --git a/v.alkis.buildings.import.py b/v.alkis.buildings.import.py index 74e518a..eaa8f69 100644 --- a/v.alkis.buildings.import.py +++ b/v.alkis.buildings.import.py @@ -117,6 +117,7 @@ from download_urls import ( URLS, BUILDINGS_FILENAMES, + BUILDINGS_LAYERS, BB_districts, download_dict, ) @@ -332,7 +333,7 @@ def download_alkis_buildings(fs, url): def import_single_alkis_source( - alkis_source, aoi_map, load_region, output_alkis, f_state + alkis_source, aoi_map, load_region, output_alkis, f_state, layer=None ): """Importing single ALKIS source""" alkis_source_fixed = alkis_source @@ -362,23 +363,23 @@ def import_single_alkis_source( if f_state == "Thüringen": snap = 0.1 + vimport_opts = dict( + input=alkis_source_fixed, + snap=snap, + quiet=True, + ) + if layer: + vimport_opts["layer"] = layer + if aoi_map: # set region to aoi_map grass.run_command("g.region", vector=aoi_map, quiet=True) - # if grass.find_file( - # name=OUTPUT_ALKIS_TEMP, element="vector" - # )["file"] != "": - # import pdb; pdb.set_trace() - # OUTPUT_ALKIS_TEMP += "_2" - # rm_vectors.append(OUTPUT_ALKIS_TEMP) grass.run_command( "v.import", - input=alkis_source_fixed, output=OUTPUT_ALKIS_TEMP, - snap=snap, extent="region", - quiet=True, overwrite=True, + **vimport_opts, ) grass.run_command( "v.clip", @@ -391,19 +392,15 @@ def import_single_alkis_source( elif load_region: grass.run_command( "v.import", - input=alkis_source_fixed, output=output_alkis, - snap=snap, extent="region", - quiet=True, + **vimport_opts, ) else: grass.run_command( "v.import", - input=alkis_source_fixed, output=output_alkis, - snap=snap, - quiet=True, + **vimport_opts, ) @@ -701,6 +698,7 @@ def main(): # import to GRASS DB grass.message(_(f"Importing ALKIS buildings data ({fs})...")) + layer_name = BUILDINGS_LAYERS.get(fs) if isinstance(alkis_source, str): import_single_alkis_source( alkis_source, @@ -708,6 +706,7 @@ def main(): load_region, output_alkis_fs, federal_state, + layer=layer_name, ) else: import_shapefiles(alkis_source, output_alkis_fs, aoi_map) From 66407a69681e79aeb8faae52fe74255dee4dc911 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Mon, 20 Jul 2026 20:39:41 +0200 Subject: [PATCH 5/6] fix region setup: pad on all sides instead of narrow east strip --- testsuite/v_alkis_buildings_import_base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testsuite/v_alkis_buildings_import_base.py b/testsuite/v_alkis_buildings_import_base.py index d10c6ef..36d256f 100644 --- a/testsuite/v_alkis_buildings_import_base.py +++ b/testsuite/v_alkis_buildings_import_base.py @@ -103,10 +103,12 @@ def setUpClass(cls): # set region grass.run_command("g.region", vector=cls.aoi_map, flags="a") if cls.east == "" and cls.west == "": - grass.run_command("g.region", n="n+200", s="n-100", w="e-100") + grass.run_command( + "g.region", n="n+200", s="s-100", w="w-100", e="e+100" + ) else: grass.run_command( - "g.region", n="n+200", s="n-100", w=cls.west, e=cls.east + "g.region", n="n+200", s="s-100", w=cls.west, e=cls.east ) def option_aoi_map(self): From b16f1bb2bdd553c2495f7c388362679f4fa1c4ef Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Mon, 20 Jul 2026 20:50:11 +0200 Subject: [PATCH 6/6] fix flag test: use area overlap check instead of strict 25m boundary The old check required building footprints to cover the entire region within 25m on all sides. This is unrealistic for discrete building features in large regions. Changed to match the documented intent: data should overlap with at least 50% of the region. --- testsuite/v_alkis_buildings_import_base.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/testsuite/v_alkis_buildings_import_base.py b/testsuite/v_alkis_buildings_import_base.py index 36d256f..1e6c54f 100644 --- a/testsuite/v_alkis_buildings_import_base.py +++ b/testsuite/v_alkis_buildings_import_base.py @@ -163,20 +163,26 @@ def flag(self): self.assertTrue( "AGS" in atr[1], "Module failed, because of missins key 'AGS'" ) - # check extend of output (data should overlap with 50 percent of the - # region) + # check that output extent overlaps with at least 50% of the region out_data_reg = grass.parse_command( "v.info", map=self.test_output, flags="g" ) g_reg = grass.region() + overlap_e = min(float(out_data_reg["east"]), g_reg["e"]) + overlap_w = max(float(out_data_reg["west"]), g_reg["w"]) + overlap_n = min(float(out_data_reg["north"]), g_reg["n"]) + overlap_s = max(float(out_data_reg["south"]), g_reg["s"]) + if overlap_e > overlap_w and overlap_n > overlap_s: + overlap_area = (overlap_e - overlap_w) * (overlap_n - overlap_s) + region_area = (g_reg["e"] - g_reg["w"]) * (g_reg["n"] - g_reg["s"]) + overlap_pct = overlap_area / region_area * 100 + else: + overlap_pct = 0 self.assertTrue( - ( - abs(float(out_data_reg["north"]) - g_reg["n"]) < 25 - and abs(float(out_data_reg["south"]) - g_reg["s"]) < 25 - and abs(float(out_data_reg["east"]) - g_reg["e"]) < 25 - and abs(float(out_data_reg["west"]) - g_reg["w"]) < 25 + overlap_pct > 50, + "Output data overlaps only {:.0f}% of the region".format( + overlap_pct ), - "Output data extend is wrong.", ) print(f"Running test for {self.fs} region flag done.")