"""
This module contains the structures related to areas of interest.
"""
from dataclasses import dataclass
from typing import NamedTuple, Optional, Tuple, Union
from pyproj.utils import is_null
[docs]@dataclass(frozen=True)
class AreaOfInterest:
"""
.. versionadded:: 2.3.0
This is the area of interest for:
- Transformations
- Querying for CRS data.
"""
#: The west bound in degrees of the area of interest.
west_lon_degree: float
#: The south bound in degrees of the area of interest.
south_lat_degree: float
#: The east bound in degrees of the area of interest.
east_lon_degree: float
#: The north bound in degrees of the area of interest.
north_lat_degree: float
def __post_init__(self):
if (
is_null(self.west_lon_degree)
or is_null(self.south_lat_degree)
or is_null(self.east_lon_degree)
or is_null(self.north_lat_degree)
):
raise ValueError("NaN or None values are not allowed.")
[docs]class AreaOfUse(NamedTuple):
"""
.. versionadded:: 2.0.0
Area of Use for CRS, CoordinateOperation, or a Transformer.
"""
#: West bound of area of use.
west: float
#: South bound of area of use.
south: float
#: East bound of area of use.
east: float
#: North bound of area of use.
north: float
#: Name of area of use.
name: Optional[str] = None
@property
def bounds(self) -> Tuple[float, float, float, float]:
"""
The bounds of the area of use.
Returns
-------
Tuple[float, float, float, float]
west, south, east, and north bounds.
"""
return self.west, self.south, self.east, self.north
def __str__(self) -> str:
return f"- name: {self.name}\n" f"- bounds: {self.bounds}"
[docs]@dataclass
class BBox:
"""
Bounding box to check if data intersects/contains other
bounding boxes.
.. versionadded:: 3.0.0
"""
#: West bound of bounding box.
west: float
#: South bound of bounding box.
south: float
#: East bound of bounding box.
east: float
#: North bound of bounding box.
north: float
def __post_init__(self):
if (
is_null(self.west)
or is_null(self.south)
or is_null(self.east)
or is_null(self.north)
):
raise ValueError("NaN or None values are not allowed.")
[docs] def intersects(self, other: Union["BBox", AreaOfUse]) -> bool:
"""
Parameters
----------
other: BBox
The other BBox to use to check.
Returns
-------
bool:
True if this BBox intersects the other bbox.
"""
return (
self.west < other.east
and other.west < self.east
and self.south < other.north
and other.south < self.north
)
[docs] def contains(self, other: Union["BBox", AreaOfUse]) -> bool:
"""
Parameters
----------
other: Union["BBox", AreaOfUse]
The other BBox to use to check.
Returns
-------
bool:
True if this BBox contains the other bbox.
"""
return (
other.west >= self.west
and other.east <= self.east
and other.south >= self.south
and other.north <= self.north
)