diff --git a/lib/xmet/spc.py b/lib/xmet/spc.py index 576a898..b3bad88 100644 --- a/lib/xmet/spc.py +++ b/lib/xmet/spc.py @@ -3,9 +3,9 @@ import enum import shapely import datetime -from typing import Self - -from xmet.afos import MONTHS, TIMEZONES +from xmet.db import DatabaseTable +from xmet.coord import COORD_SYSTEM +from xmet.afos import MONTHS, TIMEZONES RE_HEADER = re.compile(r''' ^DAY @@ -71,26 +71,54 @@ def parse_coord(coord: str) -> tuple[float, float]: def parse_poly(points: list[str]) -> shapely.Polygon: return shapely.Polygon([parse_coord(p) for p in points]) -class SPCOutlookArea(): +class SPCOutlookArea(DatabaseTable): __slots__ = ('id', 'outlook_id', 'poly') + __columns_read__ = { + 'poly': 'ST_AsText(poly) as poly' + } + + __values_read__ = { + 'poly': shapely.from_wkt + } + + __columns_write__ = { + 'poly': 'ST_GeomFromText(:poly, {crs})'.format(crs=COORD_SYSTEM) + } + + __values_write__ = { + 'poly': lambda v: {'poly': shapely.to_wkt(v)} + } + + def __init__(self): + super().__init__() + self.id = None + self.outlook_id = None + self.poly = None + class SPCOutlookProbabilityArea(SPCOutlookArea): __slots__ = ( 'hazard', 'probability', ) + __table__ = 'xmet_spc_outlook_probability_area' + __key__ = 'id' + + __columns__ = ( + 'id', 'outlook_id', 'hazard', 'probability', 'poly' + ) + class SPCOutlookCategoryArea(SPCOutlookArea): __slots__ = ( 'category' ) -class SPCOutlookParserState(enum.Enum): - HEADER = 1 - OFFICE = enum.auto() - ISSUANCE = enum.auto() - VALIDITY = enum.auto() - AREA_THREAT = enum.auto() - BODY = enum.auto() + __table__ = 'xmet_spc_outlook_category_area' + __key__ = 'id' + + __columns__ = ( + 'id', 'outlook_id', 'category', 'poly' + ) class SPCOutlook(): __slots__ = ( @@ -98,8 +126,16 @@ class SPCOutlook(): 'text_raw', 'body', 'poly', 'probabilities', 'categories' ) + __table__ = 'xmet_spc_outlook' + __key__ = 'id' + + __columns__ = ( + 'id', 'timestamp_issued', 'timestamp_start', 'timestamp_end', + 'day', 'text_raw', 'body' + ) + def __init__(self): - self.id = None + self.id = None self.timestamp_issued = None self.timestamp_start = None self.timestamp_end = None @@ -111,6 +147,14 @@ class SPCOutlook(): self.probabilities = list() self.categories = list() +class SPCOutlookParserState(enum.Enum): + HEADER = 1 + OFFICE = enum.auto() + ISSUANCE = enum.auto() + VALIDITY = enum.auto() + AREA_THREAT = enum.auto() + BODY = enum.auto() + class SPCOutlookParser(): outlook: SPCOutlook state: SPCOutlookParserState @@ -246,7 +290,6 @@ class SPCOutlookParser(): self.outlook.categories.append(area) - self.hazard = None self.category = None self.points = list() @@ -312,6 +355,8 @@ class SPCOutlookParser(): def parse(self, text: str) -> SPCOutlook: self.reset() + self.outlook.text_raw = text + for line in text.split('\n'): if line is None: break