#! /usr/bin/env python3 import argparse import cairo from xmet.spc import SPCOutlookParser, SPCOutlook, SPCOutlookMap ASSETS = { 'light': { 'map': 'doc/conus.svg', 'logo': 'doc/logo-paths.svg' }, 'dark': { 'map': 'doc/conus-dark.svg', 'logo': 'doc/logo-paths-dark.svg' } } def render_categorical(conus: SPCOutlookMap, outlook: SPCOutlook, args): assets = ASSETS['dark'] if args.dark else ASSETS['light'] with cairo.SVGSurface(args.categorical, conus.width, conus.height) as surface: cr = cairo.Context(surface) conus.draw_base_map_from_file(cr, assets['map']) conus.draw_categories(cr, outlook) conus.draw_logo(cr, assets['logo']) if args.dark: cr.set_source_rgb(1, 1, 1) conus.draw_annotation(cr, f"Day {outlook.day} Categorical Severe Weather Outlook") def render_probabilistic(conus: SPCOutlookMap, outlook: SPCOutlook, hazard: str, path: str, args): assets = ASSETS['dark'] if args.dark else ASSETS['light'] with cairo.SVGSurface(path, conus.width, conus.height) as surface: cr = cairo.Context(surface) conus.draw_base_map_from_file(cr, assets['map']) conus.draw_probabilities(cr, outlook, hazard.upper()) conus.draw_logo(cr, assets['logo']) if args.dark: cr.set_source_rgb(1, 1, 1) conus.draw_annotation(cr, f"Day {outlook.day} Probabilistic {hazard.lower().capitalize()} Risk") argparser = argparse.ArgumentParser(description='Render graphical SPC outlooks from text file') argparser.add_argument('--dark', action='store_true', help='Output dark mode graphics') argparser.add_argument('--categorical', type=str, help='Output categorical risk graphic file') argparser.add_argument('--tornado', type=str, help='Output probabilistic hail risk graphic file') argparser.add_argument('--hail', type=str, help='Output probabilistic hail risk graphic file') argparser.add_argument('--wind', type=str, help='Output probabilistic wind risk graphic file') argparser.add_argument('outlook', type=str, help='SPC text product file') args = argparser.parse_args() parser = SPCOutlookParser() conus = SPCOutlookMap() with open(args.outlook, 'r') as fh: outlook = parser.parse(fh.read()) if args.categorical is not None: render_categorical(conus, outlook, args) if args.tornado is not None: render_probabilistic(conus, outlook, 'tornado', args.tornado, args) if args.hail is not None: render_probabilistic(conus, outlook, 'hail', args.hail, args) if args.wind is not None: render_probabilistic(conus, outlook, 'wind', args.wind, args)