Compare commits

..

No commits in common. "bbd07b7f3a942a7424b5a18a8a440bd83c9eb1a6" and "902ae26b80cd53d7a2dfe6081f5ca7a62bdc3f17" have entirely different histories.

4 changed files with 43 additions and 205 deletions

View file

@ -4,11 +4,7 @@ import argparse
import cairo
from xmet.db import Database
from xmet.spc import SPCOutlookParser, \
SPCOutlook, \
SPCOutlookMap, \
SPCOutlookType
from xmet.spc import SPCOutlookParser, SPCOutlook, SPCOutlookMap
ASSETS = {
'light': {
@ -36,7 +32,6 @@ def render_categorical(conus: SPCOutlookMap,
conus.draw_categories(cr, outlook)
conus.draw_cities(cr, db)
conus.draw_logo(cr, assets['logo'])
conus.draw_legend(cr, SPCOutlookType.CATEGORICAL)
if args.dark:
cr.set_source_rgb(1, 1, 1)
@ -59,7 +54,6 @@ def render_probabilistic(conus: SPCOutlookMap,
conus.draw_probabilities(cr, outlook, hazard.upper())
conus.draw_cities(cr, db)
conus.draw_logo(cr, assets['logo'])
conus.draw_legend(cr, SPCOutlookType.PROBABILISTIC)
if args.dark:
cr.set_source_rgb(1, 1, 1)

View file

@ -1,29 +0,0 @@
import math
import cairo
def draw_rounded_rect(cr: cairo.Context,
x: float,
y: float,
width: float,
height: float,
radius: float):
rect_width = width - 2 * radius
rect_height = height - 2 * radius
# Upper right
cr.arc(x + radius + rect_width, y + radius, radius,
-math.pi / 2, 0)
# Lower right
cr.arc(x + radius + rect_width, y + radius + rect_height, radius,
0, math.pi / 2)
# Lower left
cr.arc(x + radius, y + radius + rect_height, radius,
math.pi / 2, math.pi)
# Upper right
cr.arc(x + radius, y + radius, radius,
math.pi, math.pi * 1.5)
cr.line_to(x + radius + rect_width, y)

View file

@ -88,9 +88,9 @@ class EquirectMap():
elif city.population >= 500000:
radius = 3
elif city.population >= 100000:
radius = 2.5
radius = 2
else:
radius = 1.3
radius = 1
extents = cr.text_extents(city.name)

View file

@ -9,7 +9,6 @@ from xmet.coord import COORD_SYSTEM
from xmet.city import City
from xmet.map import EquirectMap, MAP_SCREEN_DIMENSIONS, MAP_BOUNDS
from xmet.afos import MONTHS, TIMEZONES
from xmet.draw import draw_rounded_rect
from pyiem.nws.products._outlook_util import (
condition_segment,
@ -65,58 +64,57 @@ RE_POINTS_START = re.compile(r'''
RE_POINTS = re.compile(r'^(?:\s+\d{8}){1,6}$')
CITIES = {
'WA': ('Seattle', 'Spokane'),
'OR': ('Portland', 'Eugene', 'Medford'),
'CA': (
'Redding', 'Sacramento', 'San Francisco', 'Fresno', 'Santa Barbara',
'Los Angeles', 'San Diego'
),
'ID': ('Boise', 'Pocatello'),
'NV': ('Elko', 'Reno', 'Las Vegas'),
'UT': ('Salt Lake City', 'Cedar City'),
'AZ': ('Flagstaff', 'Phoenix', 'Tucson'),
'MT': ('Great Falls', 'Missoula', 'Butte', 'Billings'),
'WY': ('Sheridan', 'Jackson', 'Casper', 'Cheyenne'),
'CO': ('Denver', 'Grand Junction', 'Pueblo', 'Durango'),
'NM': ('Santa Fe', 'Albuquerque', 'Las Cruces'),
'ND': ('Minot', 'Bismarck', 'Fargo', 'Grand Forks'),
'SD': ('Aberdeen', 'Pierre', 'Rapid City', 'Sioux Falls'),
'NE': ('Omaha', 'Lincoln', 'McCook', 'Norfolk'),
'KS': ('Wichita', 'Colby', 'Liberal', 'Garden City'),
'OK': ('Woodward', 'Tulsa', 'Oklahoma City', 'Norman', 'Altus'),
'TX': (
'Amarillo', 'Wichita Falls', 'Lubbock', 'Dallas', 'Abilene',
'Midland', 'Waco', 'Austin', 'San Antonio', 'Houston',
'Corpus Christi', 'Brownsville'
),
'AL': ('Tuscaloosa', 'Mobile'),
'AR': ('Little Rock', 'Bentonville'),
'AZ': ('Flagstaff', 'Phoenix', 'Tucson'),
'CO': ('Denver', 'Grand Junction', 'Pueblo', 'Durango'),
'CT': ('Hartford',),
'DC': ('Washington',),
'FL': ('Tallahassee', 'Jacksonville', 'Orlando', 'Tampa', 'Miami'),
'GA': ('Atlanta', 'Columbus'),
'IA': ('Des Moines',),
'ID': ('Boise', 'Pocatello'),
'IL': ('Chicago', 'Peoria', 'Springfield'),
'IN': ('Fort Wayne', 'Indianapolis'),
'KS': ('Wichita', 'Colby', 'Liberal', 'Garden City'),
'KY': ('Louisville', 'Paducah', 'Bowling Green'),
'LA': ('Shreveport', 'New Orleans', 'Alexandria',),
'MA': ('Boston',),
'MD': ('Baltimore',),
'ME': ('Portland',),
'MI': ('Marquette', 'Detroit'),
'MN': ('Minneapolis', 'Duluth'),
'AR': ('Little Rock', 'Bentonville'),
'MO': ('Jefferson City', 'Kansas City'),
'MS': ('Jackson',),
'MT': ('Great Falls', 'Missoula', 'Butte', 'Billings'),
'NC': ('Charlotte', 'Raleigh', 'Wilmington'),
'ND': ('Minot', 'Bismarck', 'Fargo', 'Grand Forks'),
'NE': ('Omaha', 'Lincoln', 'McCook', 'Norfolk'),
'NM': ('Santa Fe', 'Albuquerque', 'Las Cruces'),
'NV': ('Elko', 'Reno', 'Las Vegas'),
'NY': ('Rochester', 'Buffalo', 'New York'),
'OH': ('Columbus', 'Cincinnati'),
'OK': ('Woodward', 'Tulsa', 'Oklahoma City', 'Norman', 'Altus'),
'OR': ('Portland', 'Eugene', 'Medford'),
'PA': ('Philadelphia', 'Pittsburgh', 'Scranton'),
'SC': ('Columbia', 'Charleston'),
'SD': ('Aberdeen', 'Pierre', 'Rapid City', 'Sioux Falls'),
'TN': ('Nashville', 'Jackson', 'Memphis'),
'UT': ('Salt Lake City', 'Cedar City'),
'VA': ('Roanoke', 'Richmond'),
'VT': ('Burlington',),
'WA': ('Seattle', 'Spokane'),
'IA': ('Des Moines',),
'MN': ('Minneapolis', 'Duluth'),
'MI': ('Marquette', 'Detroit'),
'WI': ('Green Bay', 'Milwaukee'),
'IL': ('Chicago', 'Peoria', 'Springfield'),
'KY': ('Louisville', 'Paducah', 'Bowling Green'),
'TN': ('Nashville', 'Jackson', 'Memphis'),
'MS': ('Jackson',),
'AL': ('Tuscaloosa', 'Mobile'),
'GA': ('Atlanta', 'Columbus'),
'FL': ('Tallahassee', 'Jacksonville', 'Orlando', 'Tampa', 'Miami'),
'SC': ('Columbia', 'Charleston'),
'NC': ('Charlotte', 'Raleigh', 'Wilmington'),
'VA': ('Roanoke', 'Richmond'),
'WV': ('Charleston',),
'WY': ('Sheridan', 'Jackson', 'Casper', 'Cheyenne'),
'DC': ('Washington',),
'MD': ('Baltimore',),
'OH': ('Columbus', 'Cincinnati'),
'IN': ('Fort Wayne', 'Indianapolis'),
'PA': ('Philadelphia', 'Pittsburgh', 'Scranton'),
'NY': ('Rochester', 'Buffalo', 'New York'),
'VT': ('Burlington',),
'ME': ('Portland',),
'MA': ('Boston',)
}
class SPCOutlookParserException(Exception):
@ -544,114 +542,13 @@ class SPCOutlookParser():
return self.outlook
class SPCOutlookType(enum.Enum):
CATEGORICAL = 1
PROBABILISTIC = 2
class SPCOutlookLegend():
MARGIN = 16
RADIUS = 16
COLOR_WIDTH = 32
COLOR_HEIGHT = 32
FONT_FACE = 'Muli'
FONT_SIZE = 16
def __init__(self, colors: dict[str, tuple[float, float, float]]):
self.colors = colors
self.text_width = 0.0
self.width = None
self.height = None
def find_size(self, cr: cairo.Context) -> tuple[float, float]:
cr.save()
count = 0
cr.select_font_face(self.FONT_FACE,
cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(self.FONT_SIZE)
for key in self.colors:
if key is None:
continue
extents = cr.text_extents(str(key))
if self.text_width < extents.width:
self.text_width = extents.width
count += 1
self.width = 3 * self.MARGIN + self.COLOR_WIDTH + self.text_width
self.height = self.MARGIN + count * (self.COLOR_HEIGHT + self.MARGIN)
cr.restore()
return self.width, self.height
def draw_item(self, cr: cairo.Context, key: str, x: float, y: float):
cr.save()
cr.set_source_rgb(*self.colors[key])
cr.rectangle(x, y, self.COLOR_WIDTH, self.COLOR_HEIGHT)
cr.fill()
cr.set_source_rgb(0, 0, 0)
cr.rectangle(x, y, self.COLOR_WIDTH, self.COLOR_HEIGHT)
cr.stroke()
text = str(key)
extents = cr.text_extents(text)
cr.move_to(x + self.COLOR_WIDTH + self.MARGIN,
y + self.COLOR_WIDTH / 2 + extents.height / 2)
cr.show_text(text)
cr.restore()
def draw(self, cr: cairo.Context, x: float, y: float):
cr.save()
cr.select_font_face(self.FONT_FACE,
cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(self.FONT_SIZE)
cr.set_source_rgba(0.2, 0.2, 0.2, 0.5)
draw_rounded_rect(cr, x, y, self.width, self.height, self.RADIUS)
cr.fill()
i = 0
for key in self.colors:
if key is None:
continue
item_y = y + self.MARGIN + i * (self.COLOR_HEIGHT + self.MARGIN)
self.draw_item(cr, key, x + self.MARGIN, item_y)
i += 1
cr.restore()
class SPCOutlookMap(EquirectMap):
TEXT_FONT = 'Muli'
LOGO_RATIO = 75.0 / 275.0
LOGO_WIDTH = 360
LOGO_HEIGHT = LOGO_RATIO * LOGO_WIDTH
MARGIN = 16
LOGO_MARGIN = 16
__category_colors__ = {
'TSTM': (212/255.0, 240/255.0, 213/255.0),
@ -684,36 +581,12 @@ class SPCOutlookMap(EquirectMap):
cr.line_to(4, 4)
cr.stroke()
def draw_legend(self,
cr: cairo.Context,
kind: SPCOutlookType):
if kind is SPCOutlookType.CATEGORICAL:
colors = self.__category_colors__
elif kind is SPCOutlookType.PROBABILISTIC:
colors = dict()
for key in self.__probability_colors__:
if key is None:
continue
text = "%d%%" % int(key * 100)
colors[text] = self.__probability_colors__[key]
legend = SPCOutlookLegend(colors)
size = legend.find_size(cr)
x = self.width - 3 * self.MARGIN - size[0]
y = self.height - 6 * self.MARGIN - size[1]
legend.draw(cr, x, y)
def draw_logo(self, cr: cairo.Context, path: str):
cr.save()
width = self.LOGO_WIDTH
height = width * self.LOGO_RATIO
margin = self.MARGIN
margin = self.LOGO_MARGIN
x = margin
y = self.height - height - margin