From df6740bc74191f205fd1583b616c3cd6a6821260 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Sat, 14 Dec 2024 18:51:11 +0100 Subject: [PATCH] Dataclasses instead of namedtuples --- mikeio/spatial/_FM_geometry.py | 12 ++++++++++-- mikeio/spatial/_FM_utils.py | 14 ++++++++------ mikeio/spatial/_geometry.py | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/mikeio/spatial/_FM_geometry.py b/mikeio/spatial/_FM_geometry.py index 564228cab..961b5697d 100644 --- a/mikeio/spatial/_FM_geometry.py +++ b/mikeio/spatial/_FM_geometry.py @@ -1,5 +1,5 @@ from __future__ import annotations -from collections import namedtuple +from dataclasses import dataclass from functools import cached_property from pathlib import Path from typing import ( @@ -12,6 +12,7 @@ import numpy as np +from numpy.typing import NDArray from mikecore.DfsuFile import DfsuFileType from mikecore.eum import eumQuantity from mikecore.MeshBuilder import MeshBuilder @@ -38,6 +39,14 @@ from matplotlib.axes import Axes +@dataclass +class Polyline: + n_nodes: int + nodes: NDArray + xy: NDArray + area: float + + class _GeometryFMPlotter: """Plot GeometryFM. @@ -914,7 +923,6 @@ def _get_boundary_polylines(self) -> BoundaryPolylines: poly_lines_int = [] poly_lines_ext = [] - Polyline = namedtuple("Polyline", ["n_nodes", "nodes", "xy", "area"]) for polyline in polylines: xy = self.node_coordinates[polyline, :2] diff --git a/mikeio/spatial/_FM_utils.py b/mikeio/spatial/_FM_utils.py index d6388f8f2..431e47fc3 100644 --- a/mikeio/spatial/_FM_utils.py +++ b/mikeio/spatial/_FM_utils.py @@ -1,4 +1,4 @@ -from __future__ import annotations +from dataclasses import dataclass from typing import Any, Literal, Sequence from matplotlib.axes import Axes from matplotlib.cm import ScalarMappable @@ -8,7 +8,6 @@ from matplotlib.tri import Triangulation import numpy as np from scipy.sparse import csr_matrix -from collections import namedtuple from ._utils import _relative_cumulative_distance @@ -16,10 +15,13 @@ MESH_COL = "0.95" MESH_COL_DARK = "0.6" -BoundaryPolylines = namedtuple( - "BoundaryPolylines", - ["n_exteriors", "exteriors", "n_interiors", "interiors"], -) + +@dataclass +class BoundaryPolylines: + n_exteriors: int + exteriors: list + n_interiors: int + interiors: list def _plot_map( diff --git a/mikeio/spatial/_geometry.py b/mikeio/spatial/_geometry.py index 77af91e2f..417f22f34 100644 --- a/mikeio/spatial/_geometry.py +++ b/mikeio/spatial/_geometry.py @@ -1,11 +1,39 @@ from abc import ABC, abstractmethod -from collections import namedtuple +from dataclasses import dataclass from typing import Any from mikecore.Projections import MapProjection -BoundingBox = namedtuple("BoundingBox", ["left", "bottom", "right", "top"]) + +@dataclass +class BoundingBox: + """Bounding box for spatial data.""" + + left: float + bottom: float + right: float + top: float + + def overlaps(self, other: "BoundingBox") -> bool: + """Check if two bounding boxes overlap.""" + return not ( + self.left > other.right + or self.bottom > other.top + or self.right < other.left + or self.top < other.bottom + ) + + def __post_init__(self) -> None: + if self.left > self.right: + raise ValueError( + f"Invalid x axis, left: {self.left} must be smaller than right: {self.right}" + ) + + if self.bottom > self.top: + raise ValueError( + f"Invalid y axis, bottom: {self.bottom} must be smaller than top: {self.top}" + ) class _Geometry(ABC):