|
1 | 1 | """AreaOfInterest class.""" |
2 | 2 |
|
3 | | -from dataclasses import dataclass |
4 | 3 | from datetime import datetime |
| 4 | +from typing import Annotated |
5 | 5 |
|
| 6 | +from pydantic import BaseModel, Field, model_validator |
| 7 | +from typing_extensions import Self |
6 | 8 |
|
7 | | -@dataclass |
8 | | -class SpatialRange: |
9 | | - """Defines the geographic boundaries for an area of interest.""" |
| 9 | +Longitude = Annotated[float, Field(..., ge=-180, le=180)] |
| 10 | +Latitude = Annotated[float, Field(..., ge=-90, le=90)] |
| 11 | +Depth = float # TODO: insert a minimum depth here? e.g., `Annotated[float, Field(..., ge=0)]` |
10 | 12 |
|
11 | | - minimum_longitude: float |
12 | | - maximum_longitude: float |
13 | | - minimum_latitude: float |
14 | | - maximum_latitude: float |
15 | | - minimum_depth: float |
16 | | - maximum_depth: float |
17 | 13 |
|
| 14 | +class SpatialRange(BaseModel): |
| 15 | + """Defines the geographic boundaries for an area of interest.""" |
18 | 16 |
|
19 | | -@dataclass |
20 | | -class TimeRange: |
| 17 | + minimum_longitude: Longitude |
| 18 | + maximum_longitude: Longitude |
| 19 | + minimum_latitude: Latitude |
| 20 | + maximum_latitude: Latitude |
| 21 | + minimum_depth: Depth |
| 22 | + maximum_depth: Depth |
| 23 | + |
| 24 | + @model_validator(mode="after") |
| 25 | + def _check_spatial_domain(self) -> Self: |
| 26 | + if not self.minimum_longitude < self.maximum_longitude: |
| 27 | + raise ValueError("minimum_longitude must be less than maximum_longitude") |
| 28 | + if not self.minimum_latitude < self.maximum_latitude: |
| 29 | + raise ValueError("minimum_latitude must be less than maximum_latitude") |
| 30 | + if not self.minimum_depth < self.maximum_depth: |
| 31 | + raise ValueError("minimum_depth must be less than maximum_depth") |
| 32 | + return self |
| 33 | + |
| 34 | + |
| 35 | +class TimeRange(BaseModel): |
21 | 36 | """Defines the temporal boundaries for an area of interest.""" |
22 | 37 |
|
23 | 38 | start_time: datetime |
24 | 39 | end_time: datetime |
25 | 40 |
|
| 41 | + @model_validator(mode="after") |
| 42 | + def _check_time_range(self) -> Self: |
| 43 | + if not self.start_time < self.end_time: |
| 44 | + raise ValueError("start_time must be before end_time") |
| 45 | + return self |
| 46 | + |
26 | 47 |
|
27 | | -@dataclass |
28 | | -class AreaOfInterest: |
| 48 | +class AreaOfInterest(BaseModel): |
29 | 49 | """An area of interest with spatial and temporal boundaries.""" |
30 | 50 |
|
31 | 51 | spatial_range: SpatialRange |
|
0 commit comments