some more type hinting magic
This commit is contained in:
parent
ff00daca9d
commit
e1a1ae8bc4
2 changed files with 18 additions and 9 deletions
|
@ -29,7 +29,7 @@ def hybrid_union(geoms):
|
||||||
return HybridGeometry(geom=unary_union(tuple(geom.geom for geom in geoms)),
|
return HybridGeometry(geom=unary_union(tuple(geom.geom for geom in geoms)),
|
||||||
faces=tuple(chain(*(geom.faces for geom in geoms))),
|
faces=tuple(chain(*(geom.faces for geom in geoms))),
|
||||||
add_faces=add_faces,
|
add_faces=add_faces,
|
||||||
crop_ids=reduce(operator.or_, (other.crop_ids for other in geoms), set()))
|
crop_ids=reduce(operator.or_, (other.crop_ids for other in geoms), frozenset()))
|
||||||
|
|
||||||
|
|
||||||
THybridGeometry = TypeVar("THybridGeometry", bound="HybridGeometry")
|
THybridGeometry = TypeVar("THybridGeometry", bound="HybridGeometry")
|
||||||
|
@ -51,7 +51,7 @@ class HybridGeometry:
|
||||||
add_faces: dict = field(default_factory=dict) # todo: specify type more precisely
|
add_faces: dict = field(default_factory=dict) # todo: specify type more precisely
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, geom, face_centers) -> THybridGeometry:
|
def create(cls, geom, face_centers: np.ndarray[tuple[int, Literal[2]], np.uint32]) -> THybridGeometry:
|
||||||
"""
|
"""
|
||||||
Create from existing facets and just select the ones that lie inside this polygon.
|
Create from existing facets and just select the ones that lie inside this polygon.
|
||||||
"""
|
"""
|
||||||
|
@ -61,7 +61,10 @@ class HybridGeometry:
|
||||||
set(np.argwhere(shapely_to_mpl(subgeom).contains_points(face_centers)).flatten())
|
set(np.argwhere(shapely_to_mpl(subgeom).contains_points(face_centers)).flatten())
|
||||||
for subgeom in assert_multipolygon(geom)
|
for subgeom in assert_multipolygon(geom)
|
||||||
)
|
)
|
||||||
return HybridGeometry(geom, tuple(f for f in faces if f)) # todo: wtf? that is the wrong typing
|
|
||||||
|
faces = tuple(reduce(operator.or_, faces, set()))
|
||||||
|
return HybridGeometry(geom, faces) # old code had wrong typing
|
||||||
|
# return HybridGeometry(geom, tuple(f for f in faces if f)) # old code had wrong typing
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_full(cls, geom: BaseGeometry,
|
def create_full(cls, geom: BaseGeometry,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from dataclasses import InitVar, dataclass, field
|
from dataclasses import InitVar, dataclass, field
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from matplotlib.path import Path
|
from matplotlib.path import Path
|
||||||
|
@ -11,11 +12,15 @@ from c3nav.mapdata.utils.geometry import assert_multipolygon
|
||||||
|
|
||||||
class MplPathProxy(ABC):
|
class MplPathProxy(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def intersects_path(self, path):
|
def intersects_path(self, path: Path) -> bool:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def contains_point(self, point):
|
def contains_point(self, point: tuple[int, int]) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def contains_points(self, points: np.ndarray[tuple[int, Literal[2]], np.uint32]) -> bool:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,11 +28,11 @@ class MplPathProxy(ABC):
|
||||||
class MplPolygonPath(MplPathProxy):
|
class MplPolygonPath(MplPathProxy):
|
||||||
polygon: InitVar[Polygon]
|
polygon: InitVar[Polygon]
|
||||||
exterior: Path = field(init=False)
|
exterior: Path = field(init=False)
|
||||||
interiors: list[Path] = field(init=False)
|
interiors: tuple[Path, ...] = field(init=False)
|
||||||
|
|
||||||
def __post_init__(self, polygon):
|
def __post_init__(self, polygon):
|
||||||
self.exterior = linearring_to_mpl_path(polygon.exterior)
|
self.exterior = linearring_to_mpl_path(polygon.exterior)
|
||||||
self.interiors = [linearring_to_mpl_path(interior) for interior in polygon.interiors]
|
self.interiors = tuple(linearring_to_mpl_path(interior) for interior in polygon.interiors)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exteriors(self):
|
def exteriors(self):
|
||||||
|
@ -52,6 +57,7 @@ class MplPolygonPath(MplPathProxy):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def contains_points(self, points):
|
def contains_points(self, points):
|
||||||
|
# noinspection PyTypeChecker
|
||||||
result = self.exterior.contains_points(points)
|
result = self.exterior.contains_points(points)
|
||||||
for interior in self.interiors:
|
for interior in self.interiors:
|
||||||
if not result.any():
|
if not result.any():
|
||||||
|
@ -72,11 +78,11 @@ class MplPolygonPath(MplPathProxy):
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class MplMultipolygonPath(MplPathProxy):
|
class MplMultipolygonPath(MplPathProxy):
|
||||||
polygons: list[MplPolygonPath] = field(init=False)
|
polygons: tuple[MplPolygonPath, ...] = field(init=False)
|
||||||
polygons_: InitVar[Polygon | MultiPolygon | GeometryCollection]
|
polygons_: InitVar[Polygon | MultiPolygon | GeometryCollection]
|
||||||
|
|
||||||
def __post_init__(self, polygons_):
|
def __post_init__(self, polygons_):
|
||||||
self.polygons = [MplPolygonPath(polygon) for polygon in assert_multipolygon(polygons_)]
|
self.polygons = tuple(MplPolygonPath(polygon) for polygon in assert_multipolygon(polygons_))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exteriors(self):
|
def exteriors(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue