diff --git a/koswat/calculations/reinforcement_layers_wrapper.py b/koswat/calculations/reinforcement_layers_wrapper.py index 8b675af0..abc06cec 100644 --- a/koswat/calculations/reinforcement_layers_wrapper.py +++ b/koswat/calculations/reinforcement_layers_wrapper.py @@ -1,8 +1,8 @@ from __future__ import annotations -from typing import List, Protocol, runtime_checkable +from typing import Protocol, runtime_checkable -from shapely.geometry import LineString, Polygon +from shapely.geometry import LineString, Polygon, MultiPolygon from koswat.core.geometries.calc_library import get_polygon_coordinates from koswat.dike.layers import KoswatLayerProtocol @@ -14,18 +14,18 @@ @runtime_checkable class ReinforcementLayerProtocol(KoswatLayerProtocol, Protocol): - new_layer_geometry: Polygon + new_layer_geometry: Polygon | MultiPolygon new_layer_surface: LineString old_layer_geometry: Polygon -class ReinforcementCoatingLayer(KoswatLayerProtocol): +class ReinforcementCoatingLayer(ReinforcementLayerProtocol): material_type: KoswatMaterialType outer_geometry: Polygon material_geometry: Polygon upper_points: LineString old_layer_geometry: Polygon - new_layer_geometry: Polygon + new_layer_geometry: Polygon | MultiPolygon new_layer_surface: LineString removal_layer_geometry: Polygon @@ -84,7 +84,7 @@ class ReinforcementBaseLayer(ReinforcementLayerProtocol): outer_geometry: Polygon material_geometry: Polygon upper_points: LineString - new_layer_geometry: Polygon + new_layer_geometry: Polygon | MultiPolygon new_layer_surface: LineString old_layer_geometry: Polygon @@ -115,7 +115,7 @@ def from_koswat_base_layer( class ReinforcementLayersWrapper(KoswatLayersWrapperProtocol): base_layer: ReinforcementBaseLayer - coating_layers: List[ReinforcementCoatingLayer] + coating_layers: list[ReinforcementCoatingLayer] def __init__(self) -> None: self.base_layer = None @@ -143,7 +143,7 @@ def get_layer(self, material_type: KoswatMaterialType) -> ReinforcementCoatingLa return _found_layer @property - def layers(self) -> List[ReinforcementLayerProtocol]: + def layers(self) -> list[ReinforcementLayerProtocol]: """ All the stored layers being the `KoswatBaseLayer` the latest one in the collection. diff --git a/koswat/core/geometries/calc_library.py b/koswat/core/geometries/calc_library.py index 0ec39b38..705f9781 100644 --- a/koswat/core/geometries/calc_library.py +++ b/koswat/core/geometries/calc_library.py @@ -1,5 +1,4 @@ import logging -from typing import List, Union from shapely import affinity, geometry, ops @@ -36,13 +35,13 @@ def order_geometry_points(dike_polygon: geometry.Polygon) -> geometry.Polygon: def as_unified_geometry( - source_geom: Union[geometry.Polygon, geometry.MultiPolygon] + source_geom: geometry.Polygon | geometry.MultiPolygon, ) -> geometry.Polygon: """ Ensures the calculated geometry is returned as a single polygon. Args: - source_geom (Union[geometry.Polygon, geometry.MultiPolygon]): Calculated source geometry. + source_geom (geometry.Polygon | geometry.MultiPolygon): Calculated source geometry. Returns: geometry.Polygon: Unified resulting geometry with its points ordered (first one is the most-left x coordinate). @@ -84,13 +83,13 @@ def get_relative_core_layer( def get_polygon_coordinates( - pol_geometry: Union[geometry.Polygon, geometry.MultiPolygon] + pol_geometry: geometry.Polygon | geometry.MultiPolygon, ) -> geometry.LineString: """ Given a single or multi geometry returns the coordinates composing its outer layout. Args: - pol_geometry (Union[geometry.Polygon, geometry.MultiPolygon]): Source geometry. + pol_geometry (geometry.Polygon | geometry.MultiPolygon): Source geometry. Raises: NotImplementedError: When the provided geometry is not yet supported. @@ -100,7 +99,7 @@ def get_polygon_coordinates( """ if isinstance(pol_geometry, geometry.Polygon): return geometry.LineString(pol_geometry.exterior.coords) - raise NotImplementedError(f"Geometry type {geometry.geom_type} not supported.") + raise NotImplementedError(f"Geometry type {pol_geometry.geom_type} not supported.") def get_groundlevel_surface(pol_geometry: geometry.Polygon) -> geometry.LineString: @@ -144,9 +143,9 @@ def _last_point_intersects() -> bool: def get_normalized_polygon_difference( left_geom: geometry.Polygon, right_geom: geometry.Polygon -) -> geometry.Polygon: +) -> geometry.Polygon | geometry.MultiPolygon: """ - Given two polygons calculates the difference between them and removes any residual polygon due to minor precission errors. + Given two polygons calculates the difference between them and removes any residual polygon due to minor precision errors. Args: left_geom (geometry.Polygon): Base polygon from where to substract. @@ -156,6 +155,8 @@ def get_normalized_polygon_difference( geometry.Polygon: Resulting normalized substraction polygon. """ _result_geom = order_geometry_points(left_geom.difference(right_geom)) + if isinstance(_result_geom, geometry.MultiPolygon): + return geometry.MultiPolygon(map(_get_normalized_polygon, _result_geom.geoms)) return _get_normalized_polygon(_result_geom) @@ -179,7 +180,7 @@ def _get_single_polygon_surface_points( def get_polygon_surface_points( - base_geometry: Union[geometry.Polygon, geometry.MultiPolygon] + base_geometry: geometry.Polygon | geometry.MultiPolygon, ) -> geometry.LineString: """ Gets all the points composing the upper surface of a 'dike' geometry. @@ -200,7 +201,7 @@ def get_polygon_surface_points( return base_geometry -def profile_points_to_polygon(points_list: List[geometry.Point]) -> geometry.Polygon: +def profile_points_to_polygon(points_list: list[geometry.Point]) -> geometry.Polygon: """ Transforms a list of points into a valid 'dike' polygon. When there is a difference in height between left and right side then we correct it in the x = 0 coordinate. diff --git a/poetry.lock b/poetry.lock index 90087d2e..c445fb8f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -347,6 +347,21 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "execnet" +version = "2.0.2" +description = "execnet: rapid multi-Python deployment" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, + {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, +] + +[package.extras] +testing = ["hatch", "pre-commit", "pytest", "tox"] + [[package]] name = "fonttools" version = "4.39.4" @@ -1247,6 +1262,27 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "pytest-xdist" +version = "3.3.1" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-xdist-3.3.1.tar.gz", hash = "sha256:d5ee0520eb1b7bcca50a60a518ab7a7707992812c578198f8b44fdfac78e8c93"}, + {file = "pytest_xdist-3.3.1-py3-none-any.whl", hash = "sha256:ff9daa7793569e6a68544850fd3927cd257cc03a7ef76c95e86915355e82b5f2"}, +] + +[package.dependencies] +execnet = ">=1.1" +pytest = ">=6.2.0" + +[package.extras] +psutil = ["psutil (>=3.0)"] +setproctitle = ["setproctitle"] +testing = ["filelock"] + [[package]] name = "python-dateutil" version = "2.8.2" @@ -1728,4 +1764,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.9, <3.11" -content-hash = "fd848f26a550f0ebc0231c9511351b1894ea9359aca68dc998bea95b8ec29433" +content-hash = "ec717581abe1b84563eb3deb8ec7480d15a7b5ea76ca9f6a275072a90f4c373e" diff --git a/pyproject.toml b/pyproject.toml index e8b05cec..1e8a9a10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ pytest-cov = "^3.0.0" coverage = "^6.4.4" teamcity-messages = "^1.32" opencv-python = "^4.8.1.78" +pytest-xdist = "^3.3.1" [tool.poetry.group.dev.dependencies] black = "^22.8.0"