Initial (faulty) commit of VTEC polygon implementation
This commit is contained in:
parent
71d0d49ca7
commit
cc3e058d2e
3 changed files with 120 additions and 0 deletions
|
@ -43,4 +43,28 @@ select
|
||||||
AddGeometryColumn('nexrad_storm_event', 'coord_end', 4326, 'POINT', 'XY', 0),
|
AddGeometryColumn('nexrad_storm_event', 'coord_end', 4326, 'POINT', 'XY', 0),
|
||||||
CreateSpatialIndex('nexrad_storm_event', 'coord_end');
|
CreateSpatialIndex('nexrad_storm_event', 'coord_end');
|
||||||
|
|
||||||
|
create table nexrad_vtec_event (
|
||||||
|
id INTEGER PRIMARY KEY NOT NULL,
|
||||||
|
timestamp_issued TIMESTAMP NOT NULL,
|
||||||
|
timestamp_expired TIMESTAMP NOT NULL,
|
||||||
|
timestamp_init_iss TIMESTAMP NOT NULL,
|
||||||
|
timestamp_init_exp TIMESTAMP NOT NULL,
|
||||||
|
timestamp_updated TIMESTAMP NOT NULL,
|
||||||
|
timestamp_poly_start TIMESTAMP NOT NULL,
|
||||||
|
timestamp_poly_end TIMESTAMP NOT NULL,
|
||||||
|
event_id INTEGER,
|
||||||
|
status TEXT NOT NULL,
|
||||||
|
wfo TEXT NOT NULL,
|
||||||
|
sig TEXT NOT NULL,
|
||||||
|
phenom TEXT NOT NULL,
|
||||||
|
hail_size FLOAT,
|
||||||
|
wind_speed FLOAT,
|
||||||
|
tornado_tag TEXT,
|
||||||
|
damage_tag TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
select
|
||||||
|
AddGeometryColumn('nexrad_vtec_event', 'poly', 4326, 'POLYGON'),
|
||||||
|
CreateSpatialIndex('nexrad_vtec_event', 'poly');
|
||||||
|
|
||||||
commit;
|
commit;
|
||||||
|
|
95
lib/nexrad/vtec.py
Normal file
95
lib/nexrad/vtec.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
import enum
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import shapely
|
||||||
|
import shapefile
|
||||||
|
|
||||||
|
from nexrad.db import DatabaseTable
|
||||||
|
|
||||||
|
def parse_timestamp(timestamp: str):
|
||||||
|
return datetime.datetime.strptime(timestamp, '%Y%m%d%H%M%S').astimezone(datetime.UTC)
|
||||||
|
|
||||||
|
def shape_to_geojson(shape: shapefile.Shape):
|
||||||
|
ret = json.dumps({
|
||||||
|
'type': 'Polygon',
|
||||||
|
'coordinates': shape.points
|
||||||
|
})
|
||||||
|
|
||||||
|
print(f"Got a kitty: {ret}")
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class VTECType(enum.StrEnum):
|
||||||
|
OPERATIONAL = 'O'
|
||||||
|
TEST = 'T'
|
||||||
|
EXPERIMENTAL = 'E'
|
||||||
|
EXPERIMENTAL_VTEC = 'X'
|
||||||
|
|
||||||
|
class VTEC(DatabaseTable):
|
||||||
|
__table__ = 'nexrad_vtec_event'
|
||||||
|
__key__ = 'id'
|
||||||
|
|
||||||
|
__columns__ = (
|
||||||
|
'id', 'timestamp_issued', 'timestamp_expired',
|
||||||
|
'timestamp_init_iss', 'timestamp_init_exp',
|
||||||
|
'timestamp_updated', 'timestamp_poly_start',
|
||||||
|
'timestamp_poly_end', 'event_id', 'wfo', 'sig', 'phenom',
|
||||||
|
'status', 'hail_size', 'tornado_tag', 'damage_tag', 'poly'
|
||||||
|
)
|
||||||
|
|
||||||
|
__columns_read__ = {
|
||||||
|
'poly': 'ST_AsText(poly) as poly'
|
||||||
|
}
|
||||||
|
|
||||||
|
__values_write__ = {
|
||||||
|
'poly': shapely.from_wkt
|
||||||
|
}
|
||||||
|
|
||||||
|
__columns_write__ = {
|
||||||
|
'poly': 'GeomFromGeoJSON(:poly)'
|
||||||
|
}
|
||||||
|
|
||||||
|
__values_write__ = {
|
||||||
|
'poly': lambda v: {'poly': shape_to_geojson(v)}
|
||||||
|
}
|
||||||
|
|
||||||
|
id: int
|
||||||
|
poly: shapefile.Shape
|
||||||
|
event_id: int
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_shapefile_record(record, shape):
|
||||||
|
vtec = VTEC()
|
||||||
|
vtec.id = None
|
||||||
|
vtec.timestamp_issued = parse_timestamp(record['ISSUED'])
|
||||||
|
vtec.timestamp_expired = parse_timestamp(record['EXPIRED'])
|
||||||
|
vtec.timestamp_init_iss = parse_timestamp(record['INIT_ISS'])
|
||||||
|
vtec.timestamp_init_exp = parse_timestamp(record['INIT_EXP'])
|
||||||
|
vtec.timestamp_updated = parse_timestamp(record['UPDATED'])
|
||||||
|
vtec.timestamp_poly_start = parse_timestamp(record['POLY_BEG'])
|
||||||
|
vtec.timestamp_poly_end = parse_timestamp(record['POLY_END'])
|
||||||
|
vtec.event_id = int(record['ETN']) if (record['ETN'] is not None and record['ETN'] != '') else None
|
||||||
|
vtec.hail_size = float(record['HAILTAG']) if record['HAILTAG'] is not None else None
|
||||||
|
vtec.wind_speed = float(record['WINDTAG']) if record['WINDTAG'] is not None else None
|
||||||
|
|
||||||
|
vtec.status = record['STATUS']
|
||||||
|
vtec.wfo = record['WFO']
|
||||||
|
vtec.phenom = record['PHENOM']
|
||||||
|
vtec.sig = record['SIG']
|
||||||
|
vtec.tornado_tag = record['TORNTAG']
|
||||||
|
vtec.damage_tag = record['DAMAGTAG']
|
||||||
|
vtec.poly = shape
|
||||||
|
|
||||||
|
return vtec
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def each_from_shapefile(path: str):
|
||||||
|
sf = shapefile.Reader(path)
|
||||||
|
|
||||||
|
for i in range(0, sf.numRecords):
|
||||||
|
record = sf.record(i)
|
||||||
|
|
||||||
|
if record['GTYPE'] != 'P':
|
||||||
|
continue
|
||||||
|
|
||||||
|
yield VTEC.from_shapefile_record(record, sf.shape(i))
|
|
@ -1,2 +1,3 @@
|
||||||
boto3>=1.36
|
boto3>=1.36
|
||||||
shapely>=2.0
|
shapely>=2.0
|
||||||
|
pyshp>=2.3.0
|
||||||
|
|
Loading…
Add table
Reference in a new issue