Skip to content

Commit 4edbb7a

Browse files
authored
Merge pull request #1210 from akrherz/cwa_groupdict
🐛 Account for CNCL as CWA cancellation string
2 parents 5b5f8a2 + df24e2b commit 4edbb7a

4 files changed

Lines changed: 28 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ All notable changes to this library are documented in this file.
2424

2525
### Bug Fixes
2626

27+
- Account for `CNCL` as a cancellation string in `CWA` products.
2728
- Add preflight check of MOS database write for known column storage.
2829
- Improve enforcement of str types into autoplot context parsing.
2930
- Support `with_sqlalchemy_conn` to decorate a generator.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
136
2+
FAUS26 KZSE 290320
3+
ZSE6 CWA 290320
4+
ZSE CWA 602 VALID UNTIL 290335
5+
CNCL ZSE CWSU 601. REFER TO CONVECTIVE SIGMET 19W FOR FURTHER
6+
INFORMATION. ZSE CWSU DS290320Z.
7+
=

src/pyiem/nws/products/cwa.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
"""Center Weather Advisories (CWA)"""
22

3-
# Stdlib imports
43
import math
54
import re
65
from typing import Tuple
76

8-
# Third Party
97
from shapely.geometry import LineString, Point, Polygon
108

11-
# Local stuff
129
from pyiem.models.cwa import CWAModel
1310
from pyiem.nws.product import TextProduct
1411
from pyiem.nws.ugc import str2time
@@ -35,7 +32,7 @@
3532
)
3633
NM_WIDE = re.compile(r"(\s|\.)(?P<width>\d+)\s?NM WIDE")
3734
DIAMETER = re.compile(r"DIAM (?P<diameter>\d+)\s?NM")
38-
CANCEL_LINE = re.compile("(CANCEL|ERROR)")
35+
CANCEL_LINE = re.compile("(CANCEL|ERROR|CNCL)")
3936

4037

4138
dirs = {
@@ -158,6 +155,7 @@ def parse_polygon(prod: TextProduct, line: str) -> Tuple[Polygon, str]:
158155
m = NM_WIDE.search(prod.unixtext)
159156
if not pts:
160157
return None, narrative
158+
poly = None
161159
if len(pts) >= 2 and m is not None:
162160
res = m.groupdict()
163161
# approx
@@ -170,13 +168,14 @@ def parse_polygon(prod: TextProduct, line: str) -> Tuple[Polygon, str]:
170168

171169
elif len(pts) == 1:
172170
# We have a point
173-
res = DIAMETER.search(prod.unixtext).groupdict()
174-
# approx
175-
diameter_deg = float(res["diameter"]) * KM_NM / 111.0
176-
poly = Point(*pts[0]).buffer(diameter_deg / 2)
171+
if m := DIAMETER.search(prod.unixtext):
172+
res = m.groupdict()
173+
# approx
174+
diameter_deg = float(res["diameter"]) * KM_NM / 111.0
175+
poly = Point(*pts[0]).buffer(diameter_deg / 2)
177176
else:
178177
poly = Polygon(pts)
179-
if not poly.is_valid:
178+
if poly and not poly.is_valid:
180179
poly = poly.buffer(0)
181180
msg = "\n".join(workdone)
182181
if any(

tests/nws/products/test_cwa.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"""CWA"""
22

3-
# third party
43
import pytest
54
from shapely.geometry import Polygon
65

7-
# this
86
from pyiem.nws.products.cwa import parser
97
from pyiem.util import get_test_file, utc
108

@@ -34,6 +32,18 @@
3432
}
3533

3634

35+
def test_260529_handle_groupdict():
36+
"""Test that we don't get any warnings for this and it is handled."""
37+
utcnow = utc(2026, 5, 29, 0)
38+
prod = parser(
39+
get_test_file("CWA/CWAZSE_groupdict.txt"),
40+
utcnow=utcnow,
41+
nwsli_provider=LOCS,
42+
)
43+
assert prod.data is None
44+
assert not prod.warnings
45+
46+
3747
def test_250417_none_groupdict():
3848
"""Test that we at least get a nice warning about this."""
3949
utcnow = utc(2025, 4, 17, 2, 8)

0 commit comments

Comments
 (0)