diff --git a/lib/nexrad/coord.py b/lib/nexrad/coord.py index 66cddb5..85f1a76 100644 --- a/lib/nexrad/coord.py +++ b/lib/nexrad/coord.py @@ -1,3 +1,5 @@ +import shapely + COORD_SYSTEM = 4326 class Coord(): @@ -9,3 +11,12 @@ class Coord(): def __str__(self): return '%f, %f' % (self.lon, self.lat) + + @staticmethod + def from_wkt(wkt: str): + try: + point = shapely.from_wkt(wkt) + + return Coord(point.x, point.y) + except: + return None diff --git a/lib/nexrad/db.py b/lib/nexrad/db.py index c4c8aaa..c7f8e60 100644 --- a/lib/nexrad/db.py +++ b/lib/nexrad/db.py @@ -15,7 +15,7 @@ class DatabaseTable(): def __reset__(self): object.__setattr__(self, '__dirty__', False) - object.__setattr__(self, '__dirty_columns__', {k: 0 for k in self.columns}) + object.__setattr__(self, '__dirty_columns__', {k: 0 for k in self.__columns__}) def __setattr__(self, k, v): object.__setattr__(self, k, v) @@ -59,12 +59,18 @@ class DatabaseTableCursor(): return fn(row) obj = self.table() + cr = getattr(self.table, '__columns_read__', None) for name in self.table.__columns__: try: - setattr(obj, name, getattr(row, name)) + v = row[name] + + if cr is not None and name in cr: + setattr(obj, name, cr[name](v)) + else: + setattr(obj, name, v) except IndexError: - setattr(obj, name, None) + pass obj.__reset__() diff --git a/lib/nexrad/radar.py b/lib/nexrad/radar.py index da1c2e5..24408f9 100644 --- a/lib/nexrad/radar.py +++ b/lib/nexrad/radar.py @@ -57,6 +57,10 @@ class Radar(DatabaseTable): 'coord': 'ST_AsText(coord) as coord' } + __columns_read__ = { + 'coord': Coord.from_wkt + } + __columns_write__ = { 'coord': 'MakePoint(:coord_lon, :coord_lat, {crs})'.format(crs=COORD_SYSTEM) } diff --git a/lib/nexrad/storm.py b/lib/nexrad/storm.py index ff047d7..f70942f 100644 --- a/lib/nexrad/storm.py +++ b/lib/nexrad/storm.py @@ -2,7 +2,6 @@ import re import gzip import csv import datetime -import shapely from nexrad.db import DatabaseTable from nexrad.coord import Coord, COORD_SYSTEM @@ -102,6 +101,13 @@ class StormReport(DatabaseTable): 'coord_end': 'ST_AsText(coord_end) as coord_end' } + __columns_read__ = { + 'timestamp_start': datetime.datetime.fromisoformat, + 'timestamp_end': datetime.datetime.fromisoformat, + 'coord_start': Coord.from_wkt, + 'coord_end': Coord.from_wkt + } + __columns_write__ = { 'coord_start': 'MakePoint(:coord_start_lon, :coord_start_lat, {crs})'.format(crs=COORD_SYSTEM), 'coord_end': 'MakePoint(:coord_end_lon, :coord_end_lat, {crs})'.format(crs=COORD_SYSTEM) @@ -125,35 +131,6 @@ class StormReport(DatabaseTable): coord_start: Coord coord_end: Coord - @staticmethod - def __from_row__(row): - report = StormReport() - - report.id = row['id'] - report.timestamp_start = datetime.datetime.fromisoformat(row['timestamp_start']) - report.timestamp_end = datetime.datetime.fromisoformat(row['timestamp_end']) - report.episode_id = row['episode_id'] - report.state = row['state'] - report.event_type = row['event_type'] - report.wfo = row['wfo'] - report.locale_start = row['locale_start'] - report.locale_end = row['locale_end'] - report.tornado_f_rating = row['tornado_f_rating'] - - try: - c = shapely.from_wkt(row['coord_start']) - report.coord_start = Coord(c.x, c.y) - except: - report.coord_start = None - - try: - c = shapely.from_wkt(row['coord_end']) - report.coord_end = Coord(c.x, c.y) - except: - report.coord_end = None - - return report - @staticmethod def from_csv_row(row: dict): report = StormReport()