import warnings import numpy as np from shapely.geometry import Polygon from .classify import CLASSES from .vectors import mask_polygons MIN_AREA = 12.0 RECT_COVERAGE = 0.85 def regularize(poly: Polygon) -> Polygon | None: """Rechteck, wenn das Polygon sein gedrehtes Hüllrechteck gut ausfüllt; sonst vereinfacht.""" poly = poly.buffer(0) if poly.geom_type != "Polygon" or poly.area < MIN_AREA: return None with warnings.catch_warnings(): # Shapelys oriented_envelope (minimum_rotated_rectangle) wertet einen Winkelterm # aus, der für bereits achsenparallele/rechtwinklige Polygone exakt 0/0 wird - # GEOS meldet das als RuntimeWarning, obwohl das zurückgegebene Rechteck korrekt # bleibt (geprüft: Fläche stimmt, kein NaN). Nur diese eine Property-Abfrage ist # eingeschränkt, damit ein echter Warnhinweis an anderer Stelle sichtbar bliebe. warnings.filterwarnings("ignore", message=r".*oriented_envelope.*", category=RuntimeWarning) rect = poly.minimum_rotated_rectangle if rect.area > 0 and poly.area / rect.area >= RECT_COVERAGE: return rect return poly.simplify(0.5) def building_polygons(labels: np.ndarray) -> list[tuple[Polygon, bool]]: out = [] for name, speculative in (("gebaeude", False), ("spekulativ", True)): mask = labels == CLASSES[name] for poly in mask_polygons(mask, min_area=MIN_AREA, simplify=0.5): reg = regularize(poly) if reg is not None: out.append((reg, speculative)) return out