From 79649f2693e8e92d229290d789e74fea0aa20ada Mon Sep 17 00:00:00 2001 From: dieuska Date: Mon, 17 Jun 2024 12:26:38 +0200 Subject: [PATCH] fix for od_strategy_snap_all_side to exclude non-logical parts fix for od_strategy_snap_all_side to exclude non-logical parts --- brdr/aligner.py | 31 +++++++++++++++++++++++++++++++ examples/example_eo.py | 21 +++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 examples/example_eo.py diff --git a/brdr/aligner.py b/brdr/aligner.py index 5004d98..14e1f41 100644 --- a/brdr/aligner.py +++ b/brdr/aligner.py @@ -1017,6 +1017,14 @@ def _calculate_geom_by_intersection_and_reference( self.buffer_distance(), ), ) + #TODO BEGIN: experimental fix - check if it is ok in all cases? + #when calculating for OD, we create a 'virtual parcel'. When calculating this virtual parcel, it is buffered to take outer boundaries into account. + #This results in a side-effect that there are extra non-logical parts included in the result. The function below tries to exclude these non-logica parts. + # see eo_id 206363 with relevant distance=0.2m and SNAP_ALL_SIDE + if is_openbaar_domein: + #geom = buffer_neg_pos(geom, self.buffer_distance()) + geom = self.get_relevant_polygons_from_geom (geom) + #TODO END elif ( not geom_relevant_intersection.is_empty and geom_relevant_difference.is_empty @@ -1047,6 +1055,29 @@ def _calculate_geom_by_intersection_and_reference( geom = geom_relevant_intersection # (=empty geometry) return geom, geom_relevant_intersection, geom_relevant_difference + + def get_relevant_polygons_from_geom(self, geom): + """ + Get only the relevant parts (polygon) from a geometry. + Points, Lines and Polygons smaller than relevant distance are excluded from the result + """ + if geom.is_empty or geom is None: + # If the input geometry is empty or None, do nothing. + return geom + else: + geom = make_valid(unary_union(geom)) + # Create a GeometryCollection from the input geometry. + geometry_collection = GeometryCollection(geom) + array=[] + for g in geometry_collection.geoms: + # Ensure each sub-geometry is valid. + g = make_valid(g) + if str(g.geom_type) in ["Polygon", "MultiPolygon"]: + relevant_geom = buffer_neg(g,self.buffer_distance()) + if relevant_geom != None and not relevant_geom.is_empty: + array.append(g) + return make_valid(unary_union(array)) + @staticmethod def _add_geom_to_dict(dictionary, geom, id_theme): dictionary[id_theme] = geom diff --git a/examples/example_eo.py b/examples/example_eo.py new file mode 100644 index 0000000..542a0b0 --- /dev/null +++ b/examples/example_eo.py @@ -0,0 +1,21 @@ +from brdr.aligner import Aligner +from brdr.utils import get_oe_dict_by_ids +from examples import show_map + +if __name__ == "__main__": + # EXAMPLE to test the algorithm for erfgoedobject with relevant distance 0.2m and od_strategy SNAP_ALL_SIDE + + # Initiate brdr + aligner = Aligner() + # Load thematic data & reference data + dict_theme = get_oe_dict_by_ids([206363], oetype='erfgoedobjecten') + aligner.load_thematic_data_dict(dict_theme) + aligner.load_reference_data_grb_actual(grb_type="adp", partition=1000) + + #RESULTS + rel_dist = 0.2 + dict_results_by_distance = {} + #put resulting tuple in a dictionary + dict_results_by_distance[rel_dist] = aligner.process_dict_thematic(rel_dist,2) + aligner.export_results("output/") + show_map(dict_results_by_distance, aligner.dict_thematic, aligner.dict_reference) \ No newline at end of file