Merge "ASM #335 - Watch wording not being inserted for SMW and SMW followup" into asm_14.2.2

Former-commit-id: d6e2b7f741 [formerly c735051e00] [formerly d6e2b7f741 [formerly c735051e00] [formerly 867f00b438 [formerly 669d66d3b8279833df4a361c961c113e653a542d]]]
Former-commit-id: 867f00b438
Former-commit-id: ed07060240 [formerly c54631024a]
Former-commit-id: d34b5c1a2c
This commit is contained in:
Juliya Dynina 2014-03-18 08:13:51 -05:00 committed by Gerrit Code Review
commit de68dcfeb4
5 changed files with 173 additions and 39 deletions

View file

@ -202,6 +202,10 @@ import com.vividsolutions.jts.io.WKTReader;
* populateStrings() and paintText().
* 02/07/2014 DR16090 m.gamazaychikov Added GeomMetaDataUpdateNotificationObserver class to get notification
* when geometry file get updated to re-read them in.
* 03/17/2014 DR16309 Qinglu Lin Updated getWarningAreaFromPolygon(); changed searchCountyGeospatialDataAccessor) to
* searchGeospatialDataAccessor() and updated it; changed getCountyGeospatialDataAcessor()
* to getGeospatialDataAcessor(); changed getAllCountyUgcs() to getAllUgcs(); changed
* getUgcsForWatches() to getUgcsForCountyWatches().
* </pre>
*
* @author mschenke
@ -1409,8 +1413,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
*/
public Geometry getWarningAreaFromPolygon(Polygon polygon,
AbstractWarningRecord record) {
Map<String, String[]> countyMap = FipsUtil.parseCountyHeader(record
.getCountyheader());
Map<String, String[]> countyMap = FipsUtil.parseHeader(record
.getCountyheader(), "County");
try {
return getArea(polygon, countyMap);
} catch (Exception e) {
@ -1423,35 +1427,53 @@ public class WarngenLayer extends AbstractStormTrackResource {
* Returns a set of UGCs for each area in the CWA that intersects the given
* polygon.
*/
public Set<String> getUgcsForCountyWatches(Polygon polygon)
public Set<String> getUgcsForWatches(Polygon polygon)
throws Exception {
GeospatialDataAccessor gda = getCountyGeospatialDataAcessor();
GeospatialDataAccessor gda = getGeospatialDataAcessor();
boolean isMarineZone = configuration.getGeospatialConfig()
.getAreaSource().equalsIgnoreCase(MARINE);
if (!isMarineZone) {
Set<String> ugcs = new HashSet<String>();
for (String fips : gda.getAllFipsInArea(gda.buildArea(polygon))) {
ugcs.add(FipsUtil.getUgcFromFips(fips));
}
return ugcs;
} else {
Set<String> ids = new HashSet<String>();
Geometry g = gda.buildArea(polygon);
ids = getAllFipsInArea(g);
return ids;
}
}
public Set<String> getAllUgcs() throws Exception {
GeospatialDataAccessor gda;
Set<String> ugcs = new HashSet<String>();
for (String fips : gda.getAllFipsInArea(gda.buildArea(polygon))) {
ugcs.add(FipsUtil.getUgcFromFips(fips));
gda = getGeospatialDataAcessor();
boolean isMarineZone = configuration.getGeospatialConfig()
.getAreaSource().equalsIgnoreCase(MARINE);
if (!isMarineZone) {
for (GeospatialData r : gda.geoData.features) {
ugcs.add(FipsUtil.getUgcFromFips(gda.getFips(r)));
}
} else {
for (GeospatialData r : gda.geoData.features) {
ugcs.add(getFips(r));
}
}
return ugcs;
}
public Set<String> getAllCountyUgcs() throws Exception {
GeospatialDataAccessor gda = getCountyGeospatialDataAcessor();
Set<String> ugcs = new HashSet<String>();
for (GeospatialData r : gda.geoData.features) {
ugcs.add(FipsUtil.getUgcFromFips(gda.getFips(r)));
}
return ugcs;
}
private GeospatialDataAccessor getCountyGeospatialDataAcessor()
private GeospatialDataAccessor getGeospatialDataAcessor()
throws Exception {
GeospatialDataList gdl = searchCountyGeospatialDataAccessor();
GeospatialDataList gdl = searchGeospatialDataAccessor();
if (gdl == null) {
// Cause county geospatial data to be loaded
// TODO: Should not be referencing tornadoWarning.
WarngenConfiguration torConfig = WarngenConfiguration.loadConfig(
"tornadoWarning", getLocalizedSite());
loadGeodataForConfiguration(torConfig);
gdl = searchCountyGeospatialDataAccessor();
gdl = searchGeospatialDataAccessor();
}
// TODO: There should be some way to get the "county" configuration by
@ -1463,13 +1485,21 @@ public class WarngenLayer extends AbstractStormTrackResource {
return new GeospatialDataAccessor(gdl, areaConfig);
}
private GeospatialDataList searchCountyGeospatialDataAccessor() {
private GeospatialDataList searchGeospatialDataAccessor() {
synchronized (siteMap) {
for (Map.Entry<String, GeospatialDataList> entry : siteMap
.entrySet()) {
String[] keyParts = entry.getKey().split("\\.");
boolean isMarineZone = configuration.getGeospatialConfig()
.getAreaSource().equalsIgnoreCase(MARINE);
String mapdataTable = null;
if (!isMarineZone) {
mapdataTable = "county";
} else {
mapdataTable = "marinezones";
}
if (keyParts.length == 2
&& "county".equalsIgnoreCase(keyParts[0])
&& mapdataTable.equalsIgnoreCase(keyParts[0])
&& getLocalizedSite().equals(keyParts[1])) {
return entry.getValue();
}

View file

@ -156,6 +156,8 @@ import com.vividsolutions.jts.io.WKTReader;
* May 30, 2013 DR 16237 D. Friedman Fix watch query.
* Jun 18, 2013 2118 njensen Only calculate pathcast if it's actually used
* Aug 19, 2013 2177 jsanchez Passed PortionsUtil to Area class.
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
* added determineAffectedMarinePortions().
* </pre>
*
* @author njensen
@ -1057,7 +1059,7 @@ public class TemplateRunner {
RequestConstraint ugcConstraint = new RequestConstraint("",
ConstraintType.IN);
ugcConstraint.setConstraintValueList(warngenLayer
.getAllCountyUgcs());
.getAllUgcs());
request.addConstraint("ugcZone", ugcConstraint);
// These are the only fields we need for processing watches
@ -1103,7 +1105,7 @@ public class TemplateRunner {
System.out.println("getWatches.polygonBuffer time: "
+ (t1 - t0));
validUgcZones = warngenLayer
.getUgcsForCountyWatches(watchArea);
.getUgcsForWatches(watchArea);
} catch (RuntimeException e) {
statusHandler
.handle(Priority.ERROR,
@ -1220,8 +1222,16 @@ public class TemplateRunner {
if (!work.valid) {
continue;
}
if (determineAffectedPortions(work.ugcZone, asc, geoData, work.waw)) {
rval.addWaw(work.waw);
boolean isMarineZone = warngenLayer.getConfiguration().getGeospatialConfig()
.getAreaSource().equalsIgnoreCase(WarngenLayer.MARINE);
if (!isMarineZone) {
if (determineAffectedPortions(work.ugcZone, asc, geoData, work.waw)) {
rval.addWaw(work.waw);
}
} else {
if (determineAffectedMarinePortions(work.ugcZone, asc, geoData, work.waw)) {
rval.addWaw(work.waw);
}
}
}
@ -1246,7 +1256,7 @@ public class TemplateRunner {
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
for (String ugc : ugcs) {
Map<String, String[]> parsed = FipsUtil.parseCountyHeader(ugc);
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "County");
Entry<String, String[]> e = null;
// Either zero or more than one sates/counties would be wrong
@ -1305,6 +1315,91 @@ public class TemplateRunner {
return true;
}
/**
* Given the list of marine zones in a watch, fill out the "portions" part of
* the given WeatherAdvisoryWatch. Also checks if the given marine zones are
* actually in the CWA.
*
* @param ugcs
* @param asc
* @param geoData
* @param waw
*/
@SuppressWarnings("deprecation")
private static boolean determineAffectedMarinePortions(List<String> ugcs,
AreaSourceConfiguration asc, GeospatialData[] geoData,
WeatherAdvisoryWatch waw) {
// Maps state abbreviation to unique fe_area values
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
Set<String> marinezonenameSet = new HashSet<String>();
for (String ugc : ugcs) {
for (GeospatialData gd: geoData) {
if (gd.attributes.get("ID").equals(ugc)) {
marinezonenameSet.add((String)gd.attributes.get("NAME"));
}
}
}
String marinezonename = "";
int size = marinezonenameSet.size();
Iterator<String> iter = marinezonenameSet.iterator();
int count = 0;
while (iter.hasNext()) {
String s = iter.next();
marinezonename += s;
count += 1;
if (size > 1) {
if (size == 2 && count < 2) {
marinezonename += " and ";
} else {
if (count == size - 1) {
marinezonename += ", and ";
} else {
if (count < size - 1) {
marinezonename += ", ";
}
}
}
}
}
for (String ugc : ugcs) {
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "Marine");
Entry<String, String[]> e = null;
// Either zero or more than one marine zone would be wrong
if ((parsed.size() != 1)
|| ((e = parsed.entrySet().iterator().next()).getValue().length != 1)) {
statusHandler.handle(Priority.ERROR,
"Invalid ugczone in active table entry: " + ugc);
continue;
}
String stateAbbrev = e.getKey();
Set<String> feAreas = map.get(stateAbbrev);
if (feAreas == null) {
feAreas = new HashSet<String>();
map.put(stateAbbrev, feAreas);
}
}
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
Portion portion = new Portion();
portion.parentRegion = marinezonename;
portion.partOfParentRegion = new ArrayList<String>();
portion.partOfParentRegion.add("");
portions.add(portion);
waw.setPortions(portions);
// Set legacy values
if (portions.size() > 0) {
waw.setParentRegion(portions.get(0).parentRegion);
waw.setPartOfParentRegion(portions.get(0).partOfParentRegion);
}
return true;
}
// Based on AWIPS 1 SELSparagraphs.C SELSparagraphs::processWOU().
private static String mungeFeAreas(Set<String> feAreas) {
String abrev = "";

View file

@ -50,6 +50,7 @@ import com.raytheon.viz.warnings.DateUtil;
* Apr 25, 2013 1877 jsanchez Sorted the UGC line for cancellations.
* May 10, 2013 1951 rjpeter Updated ugcZones references
* May 31, 2013 DR 16237 D. Friedman Added getUgcFromFips.
* Mar 17, 2014 DR 16309 Qinglu Lin Changed parseCountyHeader() to parseHeader() and updated it..
* </pre>
*
* @author bwoodle
@ -101,7 +102,7 @@ public class FipsUtil {
*/
public static String getUgcLine(AffectedAreas[] areas, Date endtime,
int interval) {
// TODO: If changed, change parseCountyHeader as well to reverse
// TODO: If changed, change parseHeader as well to reverse
StringBuffer rval = new StringBuffer();
ArrayList<String> countiesOrZones = new ArrayList<String>();
DateUtil du = new DateUtil();
@ -177,16 +178,16 @@ public class FipsUtil {
return rval.toString();
}
public static Map<String, String[]> parseCountyHeader(String countyHeader) {
public static Map<String, String[]> parseHeader(String header, String countyOrMarine) {
Map<String, String[]> stateToIdMap = new HashMap<String, String[]>();
// Remove new lines:
String[] lines = countyHeader.split("[\n]");
countyHeader = "";
String[] lines = header.split("[\n]");
header = "";
for (String line : lines) {
countyHeader += line;
header += line;
}
String[] ranges = countyHeader.split("[-]");
String[] ranges = header.split("[-]");
List<String> curList = null;
String curState = null;
for (String range : ranges) {
@ -197,7 +198,11 @@ public class FipsUtil {
stateToIdMap.put(curState,
curList.toArray(new String[curList.size()]));
}
curState = range.substring(0, 2);
if (!countyOrMarine.equals("Marine")) {
curState = range.substring(0, 2);
} else {
curState = "";
}
curList = new ArrayList<String>();
range = range.substring(3);
}

View file

@ -10,6 +10,7 @@
##### like the ~ and % characters in A1.
##### Evan Bookbinder 05-05-2013 handleClosesPoints and 3rd bullet changes (OVER & now)
##### Evan Bookbinder 09-20-2013 Fixed rural area otherPoints in pathcast section, added rural phrase
##### Qinglu Lin 03-17-2014 DR 16309. Updated inserttorwatches and insertsvrwatches.
####################################################################################################
#*
Mile Marker Test Code
@ -201,12 +202,12 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
#if(${secondtimezone})
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
#end
FOR ##
FOR##
#set($numPortions = ${list.size(${watch.getPortions()})})
#set($count = 0)
#foreach(${portion} in ${watch.getPortions()})
#set($count = $count + 1)
#areaFormat(${portion.partOfParentRegion} true false false) ${portion.parentRegion}##
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
#if($count == $numPortions - 1)
AND ##
#elseif($count < $numPortions)
@ -214,7 +215,7 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
#end
#end
#set($torWatchAlso = "ALSO ")
.##
. ##
#end
#end
@ -235,12 +236,12 @@ ${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${local
#if(${secondtimezone})
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
#end
FOR ##
FOR##
#set($numPortions = ${list.size(${watch.getPortions()})})
#set($count = 0)
#foreach(${portion} in ${watch.getPortions()})
#set($count = $count + 1)
#areaFormat(${portion.partOfParentRegion} true false) ${portion.parentRegion}##
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
#if($count == $numPortions - 1)
AND ##
#elseif($count < $numPortions)
@ -248,7 +249,7 @@ ${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${local
#end
#end
#set($svrWatchAlso = "ALSO ")
.##
. ##
#end
#end

View file

@ -372,6 +372,7 @@ ${canwarning}
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
#end
#end
##
#######################################################################
## MWS CON PRODUCT
@ -544,6 +545,7 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
#end
#end
##
## #####################################################################
## MWS CAN/CON PRODUCT
@ -921,6 +923,7 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
#if(${list.contains(${includedWatches}, "svrWatches")})
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
#end
#if(${productClass}=="T")
THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE.
@ -929,7 +932,6 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE.
#tml(${TMLtime}, ${timeFormat}, ${movementDirection}, ${movementInKnots}, ${eventLocation})
$$
${ugcline}
@ -1109,6 +1111,7 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
#end
#end
##
## #####################################################################
## MWS EXP PRODUCT