Compare commits

...

2 commits

2 changed files with 58 additions and 14 deletions

View file

@ -140,4 +140,37 @@ create table xmet_sounding_sample (
create index xmet_sounding_sample_sounding_id_idx on xmet_sounding_sample (sounding_id); create index xmet_sounding_sample_sounding_id_idx on xmet_sounding_sample (sounding_id);
create table xmet_spc_outlook (
id INTEGER PRIMARY KEY NOT NULL,
timestamp_issued TIMESTAMP NOT NULL,
timestamp_start TIMESTAMP NOT NULL,
timestamp_end TIMESTAMP NOT NULL,
day INTEGER NOT NULL,
text_raw TEXT NOT NULL,
body TEXT NOT NULL
);
create table xmet_spc_outlook_probability_area (
id INTEGER PRIMARY KEY NOT NULL,
outlook_id INTEGER NOT NULL,
hazard TEXT NOT NULL,
probability INTEGER NOT NULL,
FOREIGN KEY (outlook_id) REFERENCES xmet_spc_outlook (id)
);
select AddGeometryColumn('xmet_spc_outlook_probability_area', 'poly', 4326, 'POLYGON'),
CreateSpatialIndex('xmet_spc_outlook_probability_area', 'poly');
create table xmet_spc_outlook_category_area (
id INTEGER PRIMARY KEY NOT NULL,
outlook_id INTEGER NOT NULL,
category TEXT NOT NULL,
FOREIGN KEY (outlook_id) REFERENCES xmet_spc_outlook (id)
);
select AddGeometryColumn('xmet_spc_outlook_category_area', 'poly', 4326, 'POLYGON'),
CreateSpatialIndex('xmet_spc_outlook_category_area', 'poly');
commit; commit;

View file

@ -48,7 +48,7 @@ RE_HAZARD = re.compile(r'''
RE_POINTS_START = re.compile(r''' RE_POINTS_START = re.compile(r'''
^(?P<category>[A-Z0-9\.]+) ^(?P<category>[A-Z0-9\.]+)
(?P<rest>\s+\d{8}){1,6} (?P<rest>(?:\s+\d{8}){1,6})
''', re.X) ''', re.X)
RE_POINTS = re.compile(r'^(?:\s+\d{8}){1,6}$') RE_POINTS = re.compile(r'^(?:\s+\d{8}){1,6}$')
@ -68,8 +68,18 @@ def parse_coord(coord: str) -> tuple[float, float]:
0.01 * int(coord[0:4]) 0.01 * int(coord[0:4])
) )
def parse_poly(points: list[str]) -> shapely.Polygon: def each_poly(parts: list[str]):
return shapely.Polygon([parse_coord(p) for p in points]) points = list()
for part in parts:
if part == '99999999':
yield shapely.Polygon(points)
points = list()
else:
points.append(parse_coord(part))
if len(points) > 0:
yield shapely.Polygon(points)
class SPCOutlookArea(DatabaseTable): class SPCOutlookArea(DatabaseTable):
__slots__ = ('id', 'outlook_id', 'poly') __slots__ = ('id', 'outlook_id', 'poly')
@ -276,19 +286,20 @@ class SPCOutlookParser():
self.state = SPCOutlookParserState.AREA_THREAT self.state = SPCOutlookParserState.AREA_THREAT
def handle_area(self): def handle_area(self):
if self.area_type == 'PROBABILISTIC': for poly in each_poly(self.points):
area = SPCOutlookProbabilityArea() if self.area_type == 'PROBABILISTIC':
area.hazard = self.hazard area = SPCOutlookProbabilityArea()
area.probability = self.category area.hazard = self.hazard
area.poly = parse_poly(self.points) area.probability = self.category
area.poly = poly
self.outlook.probabilities.append(area) self.outlook.probabilities.append(area)
elif self.area_type == 'CATEGORICAL': elif self.area_type == 'CATEGORICAL':
area = SPCOutlookCategoryArea() area = SPCOutlookCategoryArea()
area.category = self.category area.category = self.category
area.poly = parse_poly(self.points) area.poly = poly
self.outlook.categories.append(area) self.outlook.categories.append(area)
self.category = None self.category = None
self.points = list() self.points = list()