Compare commits
3 commits
bcf0fa2f97
...
5e615b5d59
Author | SHA1 | Date | |
---|---|---|---|
5e615b5d59 | |||
37c5b1f77a | |||
2d8fc92099 |
4 changed files with 62 additions and 7 deletions
51
bin/xmet-sounding-graph
Executable file
51
bin/xmet-sounding-graph
Executable file
|
@ -0,0 +1,51 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import cairo
|
||||||
|
import shapely
|
||||||
|
|
||||||
|
from xmet.db import Database
|
||||||
|
from xmet.sounding import Sounding
|
||||||
|
from xmet.skew_t import SkewTGraph, SkewTLegend
|
||||||
|
|
||||||
|
IMAGE_WIDTH = 800
|
||||||
|
IMAGE_HEIGHT = 800
|
||||||
|
|
||||||
|
GRAPH_WIDTH = 800 - 128
|
||||||
|
GRAPH_HEIGHT = 800 - 128
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description = 'Graph most recent valid sounding for location'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument('db', help='XMET SQLite3 database')
|
||||||
|
parser.add_argument('lat', help='Latitude')
|
||||||
|
parser.add_argument('lon', help='Longitude')
|
||||||
|
parser.add_argument('timestamp', help='Timestamp in YYYY-MM-DD HH:MM:SS (UTC)')
|
||||||
|
parser.add_argument('output', help='Output SVG file')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
db = Database.connect(args.db)
|
||||||
|
|
||||||
|
location = shapely.Point(float(args.lon), float(args.lat))
|
||||||
|
sounding = Sounding.valid_by_location(db, location, args.timestamp)
|
||||||
|
|
||||||
|
print(f"Graphing {sounding.station} sounding at {sounding.timestamp_observed}")
|
||||||
|
|
||||||
|
skew_t = SkewTGraph(GRAPH_WIDTH, GRAPH_HEIGHT)
|
||||||
|
|
||||||
|
with cairo.SVGSurface(args.output, IMAGE_WIDTH, IMAGE_HEIGHT) as surface:
|
||||||
|
cr = cairo.Context(surface)
|
||||||
|
|
||||||
|
cr.set_source_rgb(1, 1, 1)
|
||||||
|
cr.rectangle(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT)
|
||||||
|
cr.fill()
|
||||||
|
|
||||||
|
skew_t.draw(cr, 64, 64, sounding.samples)
|
||||||
|
|
||||||
|
cr.set_source_rgb(0, 0, 0)
|
||||||
|
cr.rectangle(64, 64, GRAPH_WIDTH, GRAPH_HEIGHT)
|
||||||
|
cr.stroke()
|
||||||
|
|
||||||
|
SkewTLegend.draw_for_graph(cr, skew_t, 64, 64)
|
|
@ -114,9 +114,10 @@ class IGRAReader():
|
||||||
sounding.station = match['id']
|
sounding.station = match['id']
|
||||||
|
|
||||||
date = datetime.datetime(
|
date = datetime.datetime(
|
||||||
year = int(match['year']),
|
year = int(match['year']),
|
||||||
month = int(match['month']),
|
month = int(match['month']),
|
||||||
day = int(match['day'])
|
day = int(match['day']),
|
||||||
|
tzinfo = datetime.UTC
|
||||||
)
|
)
|
||||||
|
|
||||||
timestamp = date.astimezone(datetime.UTC)
|
timestamp = date.astimezone(datetime.UTC)
|
||||||
|
|
|
@ -112,6 +112,9 @@ class SkewTGraph():
|
||||||
first = True
|
first = True
|
||||||
|
|
||||||
for sample in samples:
|
for sample in samples:
|
||||||
|
if sample.pressure < 0 or sample.pressure is None:
|
||||||
|
continue
|
||||||
|
|
||||||
if sample.pressure < PRESSURE_MIN:
|
if sample.pressure < PRESSURE_MIN:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -131,9 +131,9 @@ class Sounding(DatabaseTable):
|
||||||
xmet_sounding
|
xmet_sounding
|
||||||
where
|
where
|
||||||
station = :station
|
station = :station
|
||||||
and timestamp_released <= :timestamp
|
and timestamp_observed <= :timestamp
|
||||||
order by
|
order by
|
||||||
timestamp_released desc
|
timestamp_observed desc
|
||||||
limit 1
|
limit 1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -167,10 +167,10 @@ class Sounding(DatabaseTable):
|
||||||
from
|
from
|
||||||
xmet_sounding
|
xmet_sounding
|
||||||
where
|
where
|
||||||
timestamp_released <= :timestamp
|
timestamp_observed <= :timestamp
|
||||||
order by
|
order by
|
||||||
distance asc,
|
distance asc,
|
||||||
timestamp_released desc
|
timestamp_observed desc
|
||||||
limit 1
|
limit 1
|
||||||
""".format(crs=COORD_SYSTEM)
|
""".format(crs=COORD_SYSTEM)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue