Issue #3419 Refactored watches to use the county table.
Change-Id: Ide7e07813203213511640d5ee515e73b278089c1 Former-commit-id:997485dd22
[formerly86a8ca4a30
] [formerly997485dd22
[formerly86a8ca4a30
] [formerlyb991838494
[formerly 135d7ffa84af58d7b3c9575e654fa1298b76b2e2]]] Former-commit-id:b991838494
Former-commit-id:f7bc9a8023
[formerly025c29acc0
] Former-commit-id:56cbd23141
This commit is contained in:
parent
3b5fc91579
commit
e4268f814e
40 changed files with 994 additions and 1105 deletions
|
@ -21,6 +21,7 @@ package com.raytheon.viz.warngen.gis;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -45,6 +46,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
|
|||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
@ -77,6 +79,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
|||
* Apr 29, 2014 3033 jsanchez Updated method to retrieve files in localization.
|
||||
* May 16, 2014 DR 17365 D. Friedman Reduce precision of warning area to avoid topology errors.
|
||||
* Jun 30, 2014 DR 17447 Qinglu lin Updated findAffectedAreas().
|
||||
* Jul 22, 23014 3419 jsanchez Cleaned up converFeAreaToPartList.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -92,6 +95,10 @@ public class Area {
|
|||
*/
|
||||
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
||||
|
||||
private static final List<String> SPECIAL_CASE_FE_AREAS = Arrays
|
||||
.asList(new String[] { "PA", "MI", "PD", "UP", "BB", "ER", "EU",
|
||||
"SR", "NR", "WU", "DS" });
|
||||
|
||||
private PortionsUtil portionsUtil;
|
||||
|
||||
public Area(PortionsUtil portionsUtil) {
|
||||
|
@ -259,8 +266,10 @@ public class Area {
|
|||
|
||||
area.points = pointList.toArray(new String[pointList.size()]);
|
||||
}
|
||||
String countyName = (String)regionFeature.attributes.get("COUNTYNAME");
|
||||
if (uniqueFips.contains(area.fips) == false || !uniqueCountyname.contains(countyName)) {
|
||||
String countyName = (String) regionFeature.attributes
|
||||
.get("COUNTYNAME");
|
||||
if (uniqueFips.contains(area.fips) == false
|
||||
|| !uniqueCountyname.contains(countyName)) {
|
||||
uniqueFips.add(area.fips);
|
||||
if (countyName != null) {
|
||||
uniqueCountyname.add(countyName);
|
||||
|
@ -300,7 +309,8 @@ public class Area {
|
|||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||
|
||||
try {
|
||||
Geometry precisionReducedArea = PolygonUtil.reducePrecision(warnArea);
|
||||
Geometry precisionReducedArea = PolygonUtil
|
||||
.reducePrecision(warnArea);
|
||||
if (precisionReducedArea.isValid()) {
|
||||
warnArea = precisionReducedArea;
|
||||
}
|
||||
|
@ -338,66 +348,41 @@ public class Area {
|
|||
|
||||
public static List<String> converFeAreaToPartList(String feArea) {
|
||||
final List<String> partList = new ArrayList<String>();
|
||||
if (feArea == null) {
|
||||
// Marine warnings
|
||||
partList.add("");
|
||||
} else {
|
||||
if (feArea.equals("pa"))
|
||||
partList.add("PA");
|
||||
else if (feArea.equals("mi"))
|
||||
partList.add("MI");
|
||||
else if (feArea.equals("pd"))
|
||||
partList.add("PD");
|
||||
else if (feArea.equals("up"))
|
||||
partList.add("UP");
|
||||
else if (feArea.equals("bb"))
|
||||
partList.add("BB");
|
||||
else if (feArea.equals("er"))
|
||||
partList.add("ER");
|
||||
else if (feArea.equals("eu"))
|
||||
partList.add("EU");
|
||||
else if (feArea.equals("sr"))
|
||||
partList.add("SR");
|
||||
else if (feArea.equals("nr"))
|
||||
partList.add("NR");
|
||||
else if (feArea.equals("wu"))
|
||||
partList.add("WU");
|
||||
else if (feArea.equals("ds"))
|
||||
partList.add("DS");
|
||||
else if (feArea.equals("ne"))
|
||||
partList.add("NE");
|
||||
else if (feArea.equals("nw"))
|
||||
partList.add("NW");
|
||||
else if (feArea.equals("se"))
|
||||
partList.add("SE");
|
||||
else if (feArea.equals("sw"))
|
||||
partList.add("SW");
|
||||
else {
|
||||
if (feArea != null) {
|
||||
feArea = feArea.toUpperCase();
|
||||
if (SPECIAL_CASE_FE_AREAS.contains(feArea)) {
|
||||
partList.add(feArea);
|
||||
} else {
|
||||
for (int i = 0; i < feArea.length(); i++) {
|
||||
char c = feArea.charAt(i);
|
||||
Direction direction = null;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
partList.add("CENTRAL");
|
||||
|
||||
case 'C':
|
||||
direction = Direction.CENTRAL;
|
||||
break;
|
||||
case 'w':
|
||||
partList.add("WEST");
|
||||
case 'W':
|
||||
direction = Direction.WEST;
|
||||
break;
|
||||
case 'n':
|
||||
partList.add("NORTH");
|
||||
case 'N':
|
||||
direction = Direction.NORTH;
|
||||
break;
|
||||
case 'e':
|
||||
partList.add("EAST");
|
||||
case 'E':
|
||||
direction = Direction.EAST;
|
||||
break;
|
||||
case 's':
|
||||
partList.add("SOUTH");
|
||||
case 'S':
|
||||
direction = Direction.SOUTH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (direction != null) {
|
||||
partList.add(direction.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return partList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.gis;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple POJO for a watch. The phenSig, action, etn, start time, and end time
|
||||
* make each watch unique similar to the VTEC.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 16, 2014 3419 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Watch {
|
||||
|
||||
private String phenSig;
|
||||
|
||||
private String action;
|
||||
|
||||
private String etn;
|
||||
|
||||
private Date startTime;
|
||||
|
||||
private Date endTime;
|
||||
|
||||
private List<String> areas;
|
||||
|
||||
private String state;
|
||||
|
||||
private List<String> partOfState;
|
||||
|
||||
public Watch(String state, String action, String phenSig, String etn,
|
||||
Date startTime, Date endTime) {
|
||||
this.state = state;
|
||||
this.action = action;
|
||||
this.phenSig = phenSig;
|
||||
this.etn = etn;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public String getPhenSig() {
|
||||
return phenSig;
|
||||
}
|
||||
|
||||
public void setPhenSig(String phenSig) {
|
||||
this.phenSig = phenSig;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Date startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public List<String> getAreas() {
|
||||
return areas;
|
||||
}
|
||||
|
||||
public void setAreas(List<String> areas) {
|
||||
this.areas = areas;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public List<String> getPartOfState() {
|
||||
return partOfState;
|
||||
}
|
||||
|
||||
public void setPartOfState(List<String> partOfState) {
|
||||
this.partOfState = partOfState;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getEtn() {
|
||||
return etn;
|
||||
}
|
||||
|
||||
public void setEtn(String etn) {
|
||||
this.etn = etn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((action == null) ? 0 : action.hashCode());
|
||||
result = prime * result + ((endTime == null) ? 0 : endTime.hashCode());
|
||||
result = prime * result + ((etn == null) ? 0 : etn.hashCode());
|
||||
result = prime * result + ((phenSig == null) ? 0 : phenSig.hashCode());
|
||||
result = prime * result
|
||||
+ ((startTime == null) ? 0 : startTime.hashCode());
|
||||
result = prime * result + ((state == null) ? 0 : state.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Watch other = (Watch) obj;
|
||||
if (action == null) {
|
||||
if (other.action != null)
|
||||
return false;
|
||||
} else if (!action.equals(other.action))
|
||||
return false;
|
||||
if (endTime == null) {
|
||||
if (other.endTime != null)
|
||||
return false;
|
||||
} else if (!endTime.equals(other.endTime))
|
||||
return false;
|
||||
if (etn == null) {
|
||||
if (other.etn != null)
|
||||
return false;
|
||||
} else if (!etn.equals(other.etn))
|
||||
return false;
|
||||
if (phenSig == null) {
|
||||
if (other.phenSig != null)
|
||||
return false;
|
||||
} else if (!phenSig.equals(other.phenSig))
|
||||
return false;
|
||||
if (startTime == null) {
|
||||
if (other.startTime != null)
|
||||
return false;
|
||||
} else if (!startTime.equals(other.startTime))
|
||||
return false;
|
||||
if (state == null) {
|
||||
if (other.state != null)
|
||||
return false;
|
||||
} else if (!state.equals(other.state))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,536 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.gis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Determines the valid watches related to the warning.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 17, 2014 3419 jsanchez Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WatchUtil {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(WatchUtil.class);
|
||||
|
||||
private static final UnitConverter milesToKilometer = NonSI.MILE
|
||||
.getConverterTo(SI.KILOMETER);
|
||||
|
||||
private static final double KmToDegrees = 111.12;
|
||||
|
||||
private static final String ISSUE_TIME_FIELD = "issueTime";
|
||||
|
||||
private static final String START_TIME_FIELD = "startTime";
|
||||
|
||||
private static final String END_TIME_FIELD = "endTime";
|
||||
|
||||
private static final String UGC_ZONE_FIELD = "ugcZone";
|
||||
|
||||
private static final String PHEN_SIG_FIELD = "phensig";
|
||||
|
||||
private static final String ETN = "etn";
|
||||
|
||||
private static final String ACTION = "act";
|
||||
|
||||
private static final String COUNTY_FIPS_FIELD = "FIPS";
|
||||
|
||||
private static final String COUNTY_FE_AREA_FIELD = "FE_AREA";
|
||||
|
||||
private static final String STATE_FIELD = "STATE";
|
||||
|
||||
private static final String COUNTY_TABLE = "County";
|
||||
|
||||
private static final String PARENT_NAME_FIELD = "NAME";
|
||||
|
||||
private static final String[] REQUEST_FIELDS = new String[] {
|
||||
ISSUE_TIME_FIELD, START_TIME_FIELD, END_TIME_FIELD, UGC_ZONE_FIELD,
|
||||
PHEN_SIG_FIELD, END_TIME_FIELD, ACTION, ETN };
|
||||
|
||||
private GeospatialData[] countyGeoData;
|
||||
|
||||
private WarngenLayer warngenLayer;
|
||||
|
||||
public WatchUtil(WarngenLayer warngenLayer) throws InstantiationException {
|
||||
countyGeoData = warngenLayer.getGeodataFeatures(COUNTY_TABLE,
|
||||
warngenLayer.getLocalizedSite());
|
||||
if ((countyGeoData == null) || (countyGeoData.length == 0)) {
|
||||
throw new InstantiationException("Cannot get geospatial data for "
|
||||
+ COUNTY_TABLE + "-based watches");
|
||||
}
|
||||
this.warngenLayer = warngenLayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves valid watches based on the constraints in the config, the
|
||||
* warning polygon, and the current simulated time.
|
||||
*
|
||||
* @param config
|
||||
* @param warningPolygon
|
||||
* @param simulatedTime
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<Watch> getWatches(WarngenConfiguration config,
|
||||
Geometry warningPolygon, Date simulatedTime) throws Exception {
|
||||
List<Watch> watches = null;
|
||||
AreaSourceConfiguration hatchedAreaSourceConfig = config
|
||||
.getHatchedAreaSource();
|
||||
// Validation check
|
||||
Validate.notNull(hatchedAreaSourceConfig,
|
||||
"Cannot process watches: missing HATCHING area source configuration");
|
||||
|
||||
double watchAreaBuffer = hatchedAreaSourceConfig
|
||||
.getIncludedWatchAreaBuffer();
|
||||
// Validation check
|
||||
Validate.isTrue(watchAreaBuffer >= 0,
|
||||
"'includedWatchAreaBuffer' can not be negative in .xml file");
|
||||
|
||||
String[] includedWatches = config.getIncludedWatches();
|
||||
|
||||
if ((includedWatches != null) && (includedWatches.length > 0)) {
|
||||
StringBuilder phenSigConstraint = new StringBuilder();
|
||||
Iterator<String> iterator = Arrays.asList(includedWatches)
|
||||
.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
phenSigConstraint.append(iterator.next());
|
||||
if (iterator.hasNext()) {
|
||||
phenSigConstraint.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
// Determine entity class
|
||||
Class<? extends ActiveTableRecord> entityClass = OperationalActiveTableRecord.class;
|
||||
if (CAVEMode.getMode() != CAVEMode.OPERATIONAL) {
|
||||
entityClass = PracticeActiveTableRecord.class;
|
||||
}
|
||||
|
||||
DbQueryRequest request = buildRequest(simulatedTime,
|
||||
phenSigConstraint.toString(), warngenLayer.getAllUgcs(),
|
||||
entityClass);
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(request);
|
||||
|
||||
List<ActiveTableRecord> records = convertReponse(entityClass,
|
||||
response);
|
||||
|
||||
if (records.isEmpty() == false) {
|
||||
try {
|
||||
long t0 = System.currentTimeMillis();
|
||||
Polygon watchArea = (Polygon) warningPolygon
|
||||
.buffer(milesToKilometer.convert(watchAreaBuffer)
|
||||
/ KmToDegrees);
|
||||
System.out.println("create watch area buffer time: "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
Set<String> validUgcZones = warngenLayer
|
||||
.getUgcsForWatches(watchArea);
|
||||
watches = processRecords(records, validUgcZones);
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Error determining areas to search for watches.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return watches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a DBQueryRequest object.
|
||||
*
|
||||
* @param simulatedTime
|
||||
* @param phenSig
|
||||
* @param ugcs
|
||||
* @param entityClass
|
||||
* @return
|
||||
*/
|
||||
private static DbQueryRequest buildRequest(Date simulatedTime,
|
||||
String phenSig, Set<String> ugcs,
|
||||
Class<? extends ActiveTableRecord> entityClass) {
|
||||
// Create start constraint
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(simulatedTime);
|
||||
cal.add(Calendar.MINUTE, 3);
|
||||
Date startConstraintTime = cal.getTime();
|
||||
|
||||
DbQueryRequest request = new DbQueryRequest();
|
||||
request.setEntityClass(entityClass);
|
||||
request.addConstraint(START_TIME_FIELD,
|
||||
new RequestConstraint(TimeUtil.formatDate(startConstraintTime),
|
||||
ConstraintType.LESS_THAN_EQUALS));
|
||||
request.addConstraint(END_TIME_FIELD,
|
||||
new RequestConstraint(TimeUtil.formatDate(simulatedTime),
|
||||
ConstraintType.GREATER_THAN_EQUALS));
|
||||
request.addConstraint("phensig",
|
||||
new RequestConstraint(phenSig.toString(), ConstraintType.IN));
|
||||
|
||||
/*
|
||||
* Get all UGCs in the CWA now so that the watches will be formatted
|
||||
* with all portions of the affected state(s).
|
||||
*
|
||||
* Filtering for valid UGCs is performed in processATEntries
|
||||
*/
|
||||
RequestConstraint ugcConstraint = new RequestConstraint("",
|
||||
ConstraintType.IN);
|
||||
ugcConstraint.setConstraintValueList(ugcs);
|
||||
request.addConstraint("ugcZone", ugcConstraint);
|
||||
|
||||
// These are the only fields we need for processing watches
|
||||
request.addFields(REQUEST_FIELDS);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the results of DbQueryResponse into a list of
|
||||
* ActiveTableRecords.
|
||||
*
|
||||
* @param entityClass
|
||||
* @param response
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
* @throws InstantiationException
|
||||
*/
|
||||
private static final List<ActiveTableRecord> convertReponse(
|
||||
Class<? extends ActiveTableRecord> entityClass,
|
||||
DbQueryResponse response) throws IllegalAccessException,
|
||||
InstantiationException {
|
||||
List<ActiveTableRecord> records = new ArrayList<ActiveTableRecord>(
|
||||
response.getNumResults());
|
||||
for (Map<String, Object> result : response.getResults()) {
|
||||
WarningAction action = WarningAction.valueOf(String.valueOf(result
|
||||
.get(ACTION)));
|
||||
/*
|
||||
* TODO: Currently limited to filtering out one of ("CAN","EXP").
|
||||
* Could use "Act" in addition to "act", but this should really be
|
||||
* fixed the underlying system. request.addConstraint("act", new
|
||||
* RequestConstraint("CAN", ConstraintType.NOT_EQUALS));
|
||||
*/
|
||||
if (action != WarningAction.CAN || action != WarningAction.EXP) {
|
||||
ActiveTableRecord record = entityClass.newInstance();
|
||||
record.setIssueTime((Calendar) result.get(ISSUE_TIME_FIELD));
|
||||
record.setStartTime((Calendar) result.get(START_TIME_FIELD));
|
||||
record.setEndTime((Calendar) result.get(END_TIME_FIELD));
|
||||
record.setEndTime((Calendar) result.get(END_TIME_FIELD));
|
||||
record.setUgcZone(String.valueOf(result.get(UGC_ZONE_FIELD)));
|
||||
record.setPhensig(String.valueOf(result.get(PHEN_SIG_FIELD)));
|
||||
record.setEtn(String.valueOf(result.get(ETN)));
|
||||
record.setAct(String.valueOf(result.get(ACTION)));
|
||||
records.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the activeTableRecords into Watch objects that share phenSig,
|
||||
* action, ETN, start time, and end time. It also determines the part of
|
||||
* state the watch covers.
|
||||
*
|
||||
* @param activeTableRecords
|
||||
* @param validUgcZones
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<Watch> processRecords(
|
||||
List<ActiveTableRecord> activeTableRecords,
|
||||
Set<String> validUgcZones) {
|
||||
List<Watch> watches = new ArrayList<Watch>();
|
||||
|
||||
/*
|
||||
* Assumption 1: TO.A and SV.A UGC line will always be in county format
|
||||
* from WOU.
|
||||
*/
|
||||
/*
|
||||
* Assumption 2: At least 1 warning for the issuing site supports county
|
||||
* based warnings. This will allow the county geo features to be cached.
|
||||
*/
|
||||
|
||||
Map<Watch, List<String>> map = new HashMap<Watch, List<String>>();
|
||||
// For each watch event, get the end time and list of active zones
|
||||
for (ActiveTableRecord ar : activeTableRecords) {
|
||||
/*
|
||||
* Currently reports all zones in the watch even if a given zone is
|
||||
* not in the warning polygon. If the logic is changed to only show
|
||||
* the portions of the watch near our warning polygon, filter on
|
||||
* validUgcZones here.
|
||||
*/
|
||||
String ugcZone = ar.getUgcZone();
|
||||
String state = getStateName(ugcZone.substring(0, 2));
|
||||
String action = ar.getAct();
|
||||
String phenSig = ar.getPhensig();
|
||||
String etn = ar.getEtn();
|
||||
Date startTime = ar.getStartTime().getTime();
|
||||
Date endTime = ar.getEndTime().getTime();
|
||||
|
||||
if (validUgcZones.contains(ugcZone)) {
|
||||
Watch watch = new Watch(state, action, phenSig, etn, startTime,
|
||||
endTime);
|
||||
List<String> areas = map.get(watch);
|
||||
if (areas == null) {
|
||||
areas = new ArrayList<String>();
|
||||
}
|
||||
areas.add(ugcZone);
|
||||
map.put(watch, areas);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the areas for the watch
|
||||
for (Entry<Watch, List<String>> entry : map.entrySet()) {
|
||||
Watch watch = entry.getKey();
|
||||
watch.setAreas(entry.getValue());
|
||||
List<String> partOfState = new ArrayList<String>(
|
||||
determineAffectedPortions(watch.getAreas()));
|
||||
watch.setPartOfState(partOfState);
|
||||
watches.add(watch);
|
||||
}
|
||||
|
||||
// Sorts the watches based on state name.
|
||||
Collections.sort(watches, new Comparator<Watch>() {
|
||||
|
||||
@Override
|
||||
public int compare(Watch watch1, Watch watch2) {
|
||||
return watch1.getState().compareTo(watch2.getState());
|
||||
}
|
||||
});
|
||||
|
||||
return watches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the directional set of a state.
|
||||
*
|
||||
* @param ugcs
|
||||
* @return
|
||||
*/
|
||||
private Set<String> determineAffectedPortions(List<String> ugcs) {
|
||||
Set<String> feAreas = new HashSet<String>();
|
||||
for (String ugc : ugcs) {
|
||||
// Want the first 2 letters
|
||||
String stateAbbrev = ugc.substring(0, 2);
|
||||
// Want the last 3 digits
|
||||
String fips = ugc.substring(ugc.length() - 3);
|
||||
String feArea = getFeArea(stateAbbrev, fips);
|
||||
// Checks to see if feArea in CWA
|
||||
if (feArea != null) {
|
||||
feAreas.add(feArea);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> affectedPortions = new HashSet(
|
||||
Area.converFeAreaToPartList(mungeFeAreas(feAreas)));
|
||||
return affectedPortions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full state name from the state abbreviation.
|
||||
*
|
||||
* @param stateAbrev
|
||||
* @return
|
||||
*/
|
||||
private String getStateName(String stateAbrev) {
|
||||
for (GeospatialData g : countyGeoData) {
|
||||
if (stateAbrev.equals(g.attributes.get(STATE_FIELD))) {
|
||||
return (String) g.parent.attributes.get(PARENT_NAME_FIELD);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the feArea field in the county table (i.e. n, s, e, w).
|
||||
*
|
||||
* @param stateAbbrev
|
||||
* @param ugc
|
||||
* @return
|
||||
*/
|
||||
private String getFeArea(String stateAbbrev, String ugc) {
|
||||
for (GeospatialData g : countyGeoData) {
|
||||
if (stateAbbrev.equals(g.attributes.get(STATE_FIELD))
|
||||
&& ((String) g.attributes.get(COUNTY_FIPS_FIELD))
|
||||
.endsWith(ugc)) {
|
||||
return (String) g.attributes.get(COUNTY_FE_AREA_FIELD);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Based on AWIPS 1 SELSparagraphs.C SELSparagraphs::processWOU().
|
||||
private String mungeFeAreas(Set<String> feAreas) {
|
||||
String abrev = "";
|
||||
// If eight or more portions, don't qualify area of state
|
||||
int m = feAreas.size();
|
||||
if (m < 8) {
|
||||
String partAbrev = "";
|
||||
/*
|
||||
* TODO: Unused variables should be removed if we are not going to
|
||||
* improve this in A2.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
int nw, nc, ne, wc, cc, ec, sw, sc, se, pa;
|
||||
int eee, www, nnn, sss, ee, ww, nn, ss;
|
||||
|
||||
// Identify individual sub areas of this state affected
|
||||
nw = nc = ne = wc = cc = ec = sw = sc = se = pa = 0;
|
||||
eee = www = nnn = sss = ee = ww = nn = ss = 0;
|
||||
for (String part : feAreas) {
|
||||
if ("pa".equals(part)) {
|
||||
pa = 1;
|
||||
continue;
|
||||
} else if ("nn".equals(part)) {
|
||||
nnn = nn = 1;
|
||||
} else if ("ss".equals(part)) {
|
||||
sss = ss = 1;
|
||||
} else if ("ee".equals(part)) {
|
||||
eee = ee = 1;
|
||||
} else if ("ww".equals(part)) {
|
||||
www = ww = 1;
|
||||
} else if ("nw".equals(part)) {
|
||||
nnn = www = nw = 1;
|
||||
} else if ("nc".equals(part)) {
|
||||
nnn = nc = 1;
|
||||
} else if ("ne".equals(part)) {
|
||||
nnn = eee = ne = 1;
|
||||
} else if ("wc".equals(part)) {
|
||||
www = wc = 1;
|
||||
} else if ("cc".equals(part)) {
|
||||
cc = 1;
|
||||
continue;
|
||||
} else if ("ec".equals(part)) {
|
||||
eee = ec = 1;
|
||||
} else if ("sw".equals(part)) {
|
||||
sss = www = sw = 1;
|
||||
} else if ("sc".equals(part)) {
|
||||
sss = sc = 1;
|
||||
} else if ("se".equals(part)) {
|
||||
sss = eee = se = 1;
|
||||
}
|
||||
partAbrev = part;
|
||||
}
|
||||
// decide how to describe these subareas.
|
||||
if ((ne > 0) && (nw > 0)) {
|
||||
nn = 1;
|
||||
}
|
||||
if ((se > 0) && (sw > 0)) {
|
||||
ss = 1;
|
||||
}
|
||||
if ((se > 0) && (ne > 0)) {
|
||||
ee = 1;
|
||||
}
|
||||
if ((sw > 0) && (nw > 0)) {
|
||||
ww = 1;
|
||||
}
|
||||
if ((nnn > 0) && (sss > 0) && (eee > 0) && (www > 0)) {
|
||||
return abrev;
|
||||
}
|
||||
if (((nn > 0) && (ss > 0)) || ((ee > 0) && (ww > 0))) {
|
||||
return abrev;
|
||||
}
|
||||
if (nnn + sss + eee + www == 3) {
|
||||
if (www == 0) {
|
||||
abrev = "e";
|
||||
} else if (eee == 0) {
|
||||
abrev = "w";
|
||||
} else if (nnn == 0) {
|
||||
abrev = "s";
|
||||
} else if (sss == 0) {
|
||||
abrev = "n";
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
if (((nnn == sss) && (eee == www)) || (cc == m)) {
|
||||
abrev = "c";
|
||||
return abrev;
|
||||
}
|
||||
if ((pa != 0) && (cc == 0)) {
|
||||
abrev = "pa";
|
||||
if (--m <= 0) {
|
||||
return abrev;
|
||||
}
|
||||
}
|
||||
if (m == 1 + cc) {
|
||||
abrev += partAbrev + " ";
|
||||
return abrev;
|
||||
}
|
||||
if (nnn != sss) {
|
||||
abrev += nnn != 0 ? "n" : "s";
|
||||
}
|
||||
if (eee != www) {
|
||||
abrev += eee != 0 ? "e" : "w";
|
||||
}
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
|
||||
}
|
|
@ -155,6 +155,7 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* Oct 29, 2013 DR 16734 D. Friedman If redraw-from-hatched-area fails, don't allow the polygon the be used.
|
||||
* Apr 28, 2014 3033 jsanchez Re-initialized the Velocity Engine when switching back up sites.
|
||||
* Jul 01, 2014 DR 17450 D. Friedman Use list of templates from backup site.
|
||||
* Jul 21, 2014 3419 jsanchez Created a hidden button to make recreating polygons easier.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -165,6 +166,12 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(WarngenDialog.class);
|
||||
|
||||
/*
|
||||
* This flag allows a hidden button to appear to help recreating warning
|
||||
* polygons that had issues in the feed.
|
||||
*/
|
||||
private boolean debug = false;
|
||||
|
||||
private static final int BULLET_WIDTH = 390;
|
||||
|
||||
private static final int BULLET_HEIGHT = 230;
|
||||
|
@ -557,7 +564,8 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
if (updateListCbo == null) {
|
||||
gd.horizontalIndent = 30;
|
||||
updateListCbo = new Combo(productType, SWT.READ_ONLY | SWT.DROP_DOWN);
|
||||
updateListCbo = new Combo(productType, SWT.READ_ONLY
|
||||
| SWT.DROP_DOWN);
|
||||
updateListCbo.setLayoutData(gd);
|
||||
recreateUpdates();
|
||||
|
||||
|
@ -629,7 +637,8 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
});
|
||||
|
||||
Composite redrawFrom = new Composite(redrawBox, SWT.NONE);
|
||||
redrawFrom.setLayout(new GridLayout(3, false));
|
||||
int columns = debug ? 4 : 3;
|
||||
redrawFrom.setLayout(new GridLayout(columns, false));
|
||||
redrawFrom.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false,
|
||||
true));
|
||||
|
||||
|
@ -664,9 +673,30 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
damBreakThreatAreaPressed();
|
||||
DamInfoBullet damBullet = bulletListManager
|
||||
.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (debug) {
|
||||
Button drawPolygonButton = new Button(redrawFrom, SWT.PUSH);
|
||||
drawPolygonButton.setText("?");
|
||||
drawPolygonButton.setEnabled(true);
|
||||
drawPolygonButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
/*
|
||||
* Copy/paste the LAT...LON line from the text product to
|
||||
* quickly recreate the polygon.
|
||||
*/
|
||||
String latLon = "LAT...LON 4282 7174 4256 7129 4248 7159 4280 7198";
|
||||
damBreakThreatAreaPressed(latLon, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void createBackupTrackEditGroups(Composite mainComposite) {
|
||||
|
@ -1208,7 +1238,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
setInstructions();
|
||||
} else if (bulletListManager.isDamNameSeletcted()
|
||||
&& bulletListManager.isDamCauseSelected()) {
|
||||
damBreakThreatAreaPressed();
|
||||
DamInfoBullet damBullet = bulletListManager
|
||||
.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||
}
|
||||
if (damBreakInstruct != null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1345,7 +1379,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
createMainProductButtons(productType);
|
||||
createOtherProductsList(productType);
|
||||
|
||||
// Don't let errors prevent the new controls from being displayed!
|
||||
// Don't let errors prevent the new controls from being displayed!
|
||||
try {
|
||||
changeTemplate(getDefaultTemplate());
|
||||
resetPressed();
|
||||
|
@ -1440,55 +1474,50 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for drawing a pre-defined drainage basin on
|
||||
* the WarnGen layer. The method is called when a drainage basin is selected
|
||||
* in the WarnGen Dialog Bullet List and the Dam Break Threat Area button is
|
||||
* pressed. Dam info geometries are defined in the Database so a Spatial
|
||||
* Query is performed to retrieve the data.
|
||||
* Responsible for drawing a pre-defined warning polygon (coords) on the
|
||||
* WarnGen layer.
|
||||
*
|
||||
* @param coords
|
||||
* pre-defined warning polygon coordinates in LAT...LON form.
|
||||
* @param lockPolygon
|
||||
* indicates if the polygon should be locked or not.
|
||||
*/
|
||||
private void damBreakThreatAreaPressed() {
|
||||
private void damBreakThreatAreaPressed(String coords, boolean lockPolygon) {
|
||||
damBreakInstruct = "Either no dam selected, no dam info bullets in .xml file, or no\n"
|
||||
+ "dam break primary cause selected.";
|
||||
DamInfoBullet damBullet = bulletListManager.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
|
||||
if ((damBullet.getCoords() == null)
|
||||
|| (damBullet.getCoords().length() == 0)) {
|
||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||
} else {
|
||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||
Pattern coordinatePtrn = Pattern
|
||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||
Pattern latLonPtrn = Pattern
|
||||
.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||
if ((coords == null) || (coords.length() == 0)) {
|
||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||
} else {
|
||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||
Pattern coordinatePtrn = Pattern
|
||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||
Pattern latLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||
|
||||
Matcher m = coordinatePtrn.matcher(damBullet.getCoords());
|
||||
if (m.find()) {
|
||||
m = latLonPtrn.matcher(damBullet.getCoords());
|
||||
while (m.find()) {
|
||||
coordinates.add(new Coordinate((-1 * Double
|
||||
.parseDouble(m.group(2))) / 100, Double
|
||||
.parseDouble(m.group(1)) / 100));
|
||||
}
|
||||
|
||||
if (coordinates.size() < 3) {
|
||||
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
||||
} else {
|
||||
coordinates.add(coordinates.get(0));
|
||||
PolygonUtil.truncate(coordinates, 2);
|
||||
warngenLayer.createDamThreatArea(coordinates
|
||||
.toArray(new Coordinate[coordinates.size()]));
|
||||
setPolygonLocked(true);
|
||||
warngenLayer.issueRefresh();
|
||||
damBreakInstruct = null;
|
||||
}
|
||||
} else {
|
||||
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
||||
+ "La/Lon for dam break threat area is not in pairs.";
|
||||
Matcher m = coordinatePtrn.matcher(coords);
|
||||
if (m.find()) {
|
||||
m = latLonPtrn.matcher(coords);
|
||||
while (m.find()) {
|
||||
coordinates.add(new Coordinate((-1 * Double.parseDouble(m
|
||||
.group(2))) / 100,
|
||||
Double.parseDouble(m.group(1)) / 100));
|
||||
}
|
||||
}
|
||||
|
||||
if (coordinates.size() < 3) {
|
||||
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
||||
} else {
|
||||
coordinates.add(coordinates.get(0));
|
||||
PolygonUtil.truncate(coordinates, 2);
|
||||
warngenLayer.createDamThreatArea(coordinates
|
||||
.toArray(new Coordinate[coordinates.size()]));
|
||||
setPolygonLocked(lockPolygon);
|
||||
warngenLayer.issueRefresh();
|
||||
damBreakInstruct = null;
|
||||
}
|
||||
} else {
|
||||
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
||||
+ "La/Lon for dam break threat area is not in pairs.";
|
||||
}
|
||||
}
|
||||
if (damBreakInstruct != null) {
|
||||
setInstructions();
|
||||
|
@ -1517,11 +1546,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
return result;
|
||||
}
|
||||
|
||||
/** Called by controls that can change the current template. Do not
|
||||
* do anything if the request template is already selected. This
|
||||
* check is necessary to prevent certain state being reset if
|
||||
* a followup has been selected as this is not handled by
|
||||
* changeTemplate() (DR 14515.)
|
||||
/**
|
||||
* Called by controls that can change the current template. Do not do
|
||||
* anything if the request template is already selected. This check is
|
||||
* necessary to prevent certain state being reset if a followup has been
|
||||
* selected as this is not handled by changeTemplate() (DR 14515.)
|
||||
*/
|
||||
private void uiChangeTemplate(String templateName) {
|
||||
if (templateName.equals(warngenLayer.getTemplateName())) {
|
||||
|
|
|
@ -37,40 +37,23 @@ import java.util.Hashtable;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.tools.generic.ListTool;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.AreaType;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
|
||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
|
@ -82,11 +65,9 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.SimulatedTime;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.awipstools.ToolsDataManager;
|
||||
import com.raytheon.viz.awipstools.common.StormTrackData;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||
|
@ -99,6 +80,8 @@ import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
|||
import com.raytheon.viz.warngen.gis.GisUtil;
|
||||
import com.raytheon.viz.warngen.gis.PathCast;
|
||||
import com.raytheon.viz.warngen.gis.PortionsUtil;
|
||||
import com.raytheon.viz.warngen.gis.Watch;
|
||||
import com.raytheon.viz.warngen.gis.WatchUtil;
|
||||
import com.raytheon.viz.warngen.gis.Wx;
|
||||
import com.raytheon.viz.warngen.gui.BackupData;
|
||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
||||
|
@ -111,9 +94,6 @@ import com.raytheon.viz.warngen.util.CurrentWarnings;
|
|||
import com.raytheon.viz.warngen.util.FipsUtil;
|
||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
||||
import com.raytheon.viz.warngen.util.WatchUtil;
|
||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch;
|
||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch.Portion;
|
||||
import com.raytheon.viz.warnings.DateUtil;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
@ -159,6 +139,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* Apr 28, 2014 3033 jsanchez Set the site and backup site in Velocity Engine's properties
|
||||
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
|
||||
* added determineAffectedMarinePortions().
|
||||
* Jul 21, 2014 3419 jsanchez Refactored WatchUtil.
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -171,16 +152,13 @@ public class TemplateRunner {
|
|||
|
||||
private static final String LOGIN_NAME_KEY = "LOGNAME";
|
||||
|
||||
private static final UnitConverter milesToKilometer = NonSI.MILE
|
||||
.getConverterTo(SI.KILOMETER);
|
||||
|
||||
private static final double KmToDegrees = 111.12;
|
||||
|
||||
private static final Pattern BBB_PATTERN = Pattern
|
||||
.compile(".*\\sCC([A-Z])");
|
||||
|
||||
private static Hashtable<String, DateFormat> dateFormat;
|
||||
|
||||
private static WatchUtil watchUtil;
|
||||
|
||||
static {
|
||||
dateFormat = new Hashtable<String, DateFormat>();
|
||||
dateFormat
|
||||
|
@ -873,11 +851,14 @@ public class TemplateRunner {
|
|||
// Store Watches
|
||||
try {
|
||||
t0 = System.currentTimeMillis();
|
||||
WatchUtil watches = getWatches(warngenLayer, config, warnPolygon,
|
||||
areas, fourLetterSiteId, simulatedTime);
|
||||
if (watchUtil == null) {
|
||||
watchUtil = new WatchUtil(warngenLayer);
|
||||
}
|
||||
List<Watch> watches = watchUtil.getWatches(config, warnPolygon,
|
||||
simulatedTime);
|
||||
System.out.println("getWatches time: "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
if (watches != null) {
|
||||
if (watches != null && watches.isEmpty() == false) {
|
||||
context.put("watches", watches);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -977,574 +958,4 @@ public class TemplateRunner {
|
|||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method populates a WatchUtil object with tornado and severe
|
||||
* thunderstorm watches from the active table that are contained by the
|
||||
* polygon. Furthermore, watches that have not yet expired (current time <
|
||||
* end time) are only included.
|
||||
*
|
||||
* @param config
|
||||
* WarnGen template configuration settings
|
||||
* ([template_name_site.xml])
|
||||
* @param polygon
|
||||
* The Geometry surrounded by the warning polygon.
|
||||
* @param simulatedTime
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static WatchUtil getWatches(WarngenLayer warngenLayer,
|
||||
WarngenConfiguration config, Geometry polygon,
|
||||
AffectedAreas[] affectedAreas, String fourLetterSiteId,
|
||||
Date simulatedTime) throws Exception {
|
||||
Validate.isTrue(config.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer() >= 0,
|
||||
"IncludedWatchAreaBuffer can not be negative");
|
||||
|
||||
WatchUtil rval = null;
|
||||
String[] includedWatches = config.getIncludedWatches();
|
||||
|
||||
if ((includedWatches != null) && (includedWatches.length > 0)) {
|
||||
String phensigList = null;
|
||||
for (String includedWatch : includedWatches) {
|
||||
if (includedWatch.equalsIgnoreCase("torWatches")) {
|
||||
phensigList = phensigList == null ? "TO.A" : phensigList
|
||||
+ ",TO.A";
|
||||
} else if (includedWatch.equalsIgnoreCase("svrWatches")) {
|
||||
phensigList = phensigList == null ? "SV.A" : phensigList
|
||||
+ ",SV.A";
|
||||
}
|
||||
}
|
||||
|
||||
if (phensigList != null) {
|
||||
// Create start/endtime constraints
|
||||
Date endConstraintTime = simulatedTime;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(simulatedTime);
|
||||
cal.add(Calendar.MINUTE, 3);
|
||||
Date startConstraintTime = cal.getTime();
|
||||
|
||||
// Get record type
|
||||
Class<? extends ActiveTableRecord> recordType = CAVEMode
|
||||
.getMode() == CAVEMode.OPERATIONAL ? OperationalActiveTableRecord.class
|
||||
: PracticeActiveTableRecord.class;
|
||||
|
||||
DbQueryRequest request = new DbQueryRequest();
|
||||
request.setEntityClass(recordType);
|
||||
request.addConstraint("startTime", new RequestConstraint(
|
||||
TimeUtil.formatDate(startConstraintTime),
|
||||
ConstraintType.LESS_THAN_EQUALS));
|
||||
request.addConstraint(
|
||||
"endTime",
|
||||
new RequestConstraint(TimeUtil
|
||||
.formatDate(endConstraintTime),
|
||||
ConstraintType.GREATER_THAN_EQUALS));
|
||||
/*
|
||||
* TODO: Currently limited to filtering out one of
|
||||
* ("CAN","EXP"). Could use "Act" in addition to "act", but this
|
||||
* should really be fixed the underlying system.
|
||||
* request.addConstraint("act", new RequestConstraint("CAN",
|
||||
* ConstraintType.NOT_EQUALS));
|
||||
*/
|
||||
request.addConstraint("act", new RequestConstraint("EXP",
|
||||
ConstraintType.NOT_EQUALS));
|
||||
request.addConstraint("phensig", new RequestConstraint(
|
||||
phensigList, ConstraintType.IN));
|
||||
|
||||
// TODO: Talk to Jonathan about this... Do I even need officeid
|
||||
// IN or is ugc zone good enough?
|
||||
|
||||
/*
|
||||
* Get all UGCs in the CWA now so that the watches will be
|
||||
* formatted with all portions of the affected state(s).
|
||||
*
|
||||
* Filtering for valid UGCs is performed in processATEntries
|
||||
*/
|
||||
RequestConstraint ugcConstraint = new RequestConstraint("",
|
||||
ConstraintType.IN);
|
||||
ugcConstraint.setConstraintValueList(warngenLayer
|
||||
.getAllUgcs());
|
||||
request.addConstraint("ugcZone", ugcConstraint);
|
||||
|
||||
// These are the only fields we need for processing watches
|
||||
request.addFields(new String[] { "issueTime", "startTime",
|
||||
"endTime", "ugcZone", "phensig", "vtecstr", "etn",
|
||||
"act" });
|
||||
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(request);
|
||||
|
||||
List<ActiveTableRecord> records = new ArrayList<ActiveTableRecord>(
|
||||
response.getNumResults());
|
||||
for (Map<String, Object> result : response.getResults()) {
|
||||
/*
|
||||
* TODO: Doing this here because only "EXP" is filtered out
|
||||
* by the query. Remove "act" from the field list once this
|
||||
* is fixed.
|
||||
*/
|
||||
if ("CAN".equals(result.get("act")))
|
||||
continue;
|
||||
ActiveTableRecord record = recordType.newInstance();
|
||||
record.setIssueTime((Calendar) result.get("issueTime"));
|
||||
record.setStartTime((Calendar) result.get("startTime"));
|
||||
record.setEndTime((Calendar) result.get("endTime"));
|
||||
record.setUgcZone((String) result.get("ugcZone"));
|
||||
record.setPhensig((String) result.get("phensig"));
|
||||
record.setVtecstr((String) result.get("vtecstr"));
|
||||
record.setEtn((String) result.get("etn"));
|
||||
records.add(record);
|
||||
}
|
||||
|
||||
if (records.size() > 0) {
|
||||
Set<String> validUgcZones;
|
||||
try {
|
||||
long t0, t1;
|
||||
t0 = System.currentTimeMillis();
|
||||
Polygon watchArea = (Polygon) polygon
|
||||
.buffer(milesToKilometer.convert(config
|
||||
.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer())
|
||||
/ KmToDegrees);
|
||||
t1 = System.currentTimeMillis();
|
||||
System.out.println("getWatches.polygonBuffer time: "
|
||||
+ (t1 - t0));
|
||||
validUgcZones = warngenLayer
|
||||
.getUgcsForWatches(watchArea);
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Error determining areas to search for watches.",
|
||||
e);
|
||||
return rval;
|
||||
}
|
||||
|
||||
rval = processATEntries(records, warngenLayer,
|
||||
validUgcZones);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
private static class WatchWork {
|
||||
public WeatherAdvisoryWatch waw;
|
||||
|
||||
public boolean valid;
|
||||
|
||||
public ArrayList<String> ugcZone = new ArrayList<String>();
|
||||
|
||||
public WatchWork(WeatherAdvisoryWatch waw) {
|
||||
this.waw = waw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the list of objects representing active watches that will be
|
||||
* passed to the template context.
|
||||
*
|
||||
* @param activeTable
|
||||
* List of entries for active watches
|
||||
* @param warngenLayer
|
||||
* @param validUgcZones
|
||||
* @return
|
||||
*/
|
||||
private static WatchUtil processATEntries(
|
||||
List<ActiveTableRecord> activeTable, WarngenLayer warngenLayer,
|
||||
Set<String> validUgcZones) {
|
||||
WatchUtil rval = new WatchUtil();
|
||||
TreeMap<WeatherAdvisoryWatch, WatchWork> map = new TreeMap<WeatherAdvisoryWatch, TemplateRunner.WatchWork>();
|
||||
|
||||
AreaSourceConfiguration asc = null;
|
||||
for (AreaSourceConfiguration a : warngenLayer.getConfiguration()
|
||||
.getAreaSources()) {
|
||||
if (a.getType() == AreaType.HATCHING) {
|
||||
asc = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (asc == null) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Cannot process watches: missing HATCHING area source configuration");
|
||||
return rval;
|
||||
}
|
||||
GeospatialData[] geoData = warngenLayer.getGeodataFeatures(
|
||||
asc.getAreaSource(), warngenLayer.getLocalizedSite());
|
||||
if ((geoData == null) || (geoData.length == 0)) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Cannot process watches: cannot get geospatial data");
|
||||
return rval;
|
||||
}
|
||||
|
||||
// For each watch event, get the end time and list of active zones
|
||||
for (ActiveTableRecord ar : activeTable) {
|
||||
/*
|
||||
* Currently reports all zones in the watch even if a given zone is
|
||||
* not in the warning polygon. If the logic is changed to only show
|
||||
* the portions of the watch near our warning polygon, filter on
|
||||
* validUgcZones here.
|
||||
*/
|
||||
WeatherAdvisoryWatch waw = new WeatherAdvisoryWatch();
|
||||
waw.setPhensig(ar.getPhensig());
|
||||
try {
|
||||
waw.setEventId(Integer.parseInt(ar.getEtn()));
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler.handle(Priority.ERROR, String.format(
|
||||
"Watch %s has null end time; not included.",
|
||||
ar.getVtecstr()));
|
||||
continue;
|
||||
}
|
||||
|
||||
WatchWork work = map.get(waw);
|
||||
if (work == null) {
|
||||
waw.setEndTime(ar.getEndTime().getTime());
|
||||
work = new WatchWork(waw);
|
||||
map.put(waw, work);
|
||||
}
|
||||
|
||||
if (validUgcZones.contains(ar.getUgcZone())) {
|
||||
work.valid = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are no checks here to determine whether or not the given
|
||||
* zone is in the CWA. That should have already been done the query
|
||||
* performed in getWatches.
|
||||
*
|
||||
* There is also validation performed later in
|
||||
* determineAffectedPortions.
|
||||
*/
|
||||
work.ugcZone.add(ar.getUgcZone());
|
||||
}
|
||||
|
||||
for (WatchWork work : map.values()) {
|
||||
/*
|
||||
* If none of the areas in the watch were neer our warning polygon,
|
||||
* do not included it.
|
||||
*/
|
||||
if (!work.valid) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the list of counties in a watch, fill out the "portions" part of
|
||||
* the given WeatherAdvisoryWatch. Also checks if the given counties are
|
||||
* actually in the CWA.
|
||||
*
|
||||
* @param ugcs
|
||||
* @param asc
|
||||
* @param geoData
|
||||
* @param waw
|
||||
*/
|
||||
private static boolean determineAffectedPortions(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>>();
|
||||
|
||||
for (String ugc : ugcs) {
|
||||
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "County");
|
||||
Entry<String, String[]> e = null;
|
||||
|
||||
// Either zero or more than one sates/counties 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();
|
||||
String feArea = null;
|
||||
try {
|
||||
feArea = getFeArea(stateAbbrev, e.getValue()[0], asc, geoData);
|
||||
} catch (RuntimeException exc) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error generating included watches.", exc);
|
||||
return false;
|
||||
}
|
||||
if (feArea == NOT_IN_CWA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> feAreas = map.get(stateAbbrev);
|
||||
if (feAreas == null) {
|
||||
feAreas = new HashSet<String>();
|
||||
map.put(stateAbbrev, feAreas);
|
||||
}
|
||||
if (feArea != null) {
|
||||
feAreas.add(feArea);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
|
||||
for (Entry<String, Set<String>> e : map.entrySet()) {
|
||||
Portion portion = new Portion();
|
||||
try {
|
||||
portion.parentRegion = getStateName(e.getKey(), asc, geoData)
|
||||
.toUpperCase();
|
||||
} catch (RuntimeException exc) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error generating included watches.", exc);
|
||||
return false;
|
||||
}
|
||||
portion.partOfParentRegion = Area
|
||||
.converFeAreaToPartList(mungeFeAreas(e.getValue()));
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = "";
|
||||
// If eight or more portions, don't qualify area of state
|
||||
int m = feAreas.size();
|
||||
if (m < 8) {
|
||||
String partAbrev = "";
|
||||
/*
|
||||
* TODO: Unused variables should be removed if we are not going to
|
||||
* improve this in A2.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
int nw, nc, ne, wc, cc, ec, sw, sc, se, pa;
|
||||
int eee, www, nnn, sss, ee, ww, nn, ss;
|
||||
|
||||
// Identify individual sub areas of this state affected
|
||||
nw = nc = ne = wc = cc = ec = sw = sc = se = pa = 0;
|
||||
eee = www = nnn = sss = ee = ww = nn = ss = 0;
|
||||
for (String part : feAreas) {
|
||||
if ("pa".equals(part)) {
|
||||
pa = 1;
|
||||
continue;
|
||||
} else if ("nn".equals(part)) {
|
||||
nnn = nn = 1;
|
||||
} else if ("ss".equals(part)) {
|
||||
sss = ss = 1;
|
||||
} else if ("ee".equals(part)) {
|
||||
eee = ee = 1;
|
||||
} else if ("ww".equals(part)) {
|
||||
www = ww = 1;
|
||||
} else if ("nw".equals(part)) {
|
||||
nnn = www = nw = 1;
|
||||
} else if ("nc".equals(part)) {
|
||||
nnn = nc = 1;
|
||||
} else if ("ne".equals(part)) {
|
||||
nnn = eee = ne = 1;
|
||||
} else if ("wc".equals(part)) {
|
||||
www = wc = 1;
|
||||
} else if ("cc".equals(part)) {
|
||||
cc = 1;
|
||||
continue;
|
||||
} else if ("ec".equals(part)) {
|
||||
eee = ec = 1;
|
||||
} else if ("sw".equals(part)) {
|
||||
sss = www = sw = 1;
|
||||
} else if ("sc".equals(part)) {
|
||||
sss = sc = 1;
|
||||
} else if ("se".equals(part)) {
|
||||
sss = eee = se = 1;
|
||||
}
|
||||
partAbrev = part;
|
||||
}
|
||||
// decide how to describe these subareas.
|
||||
if ((ne > 0) && (nw > 0)) {
|
||||
nn = 1;
|
||||
}
|
||||
if ((se > 0) && (sw > 0)) {
|
||||
ss = 1;
|
||||
}
|
||||
if ((se > 0) && (ne > 0)) {
|
||||
ee = 1;
|
||||
}
|
||||
if ((sw > 0) && (nw > 0)) {
|
||||
ww = 1;
|
||||
}
|
||||
if ((nnn > 0) && (sss > 0) && (eee > 0) && (www > 0)) {
|
||||
return abrev;
|
||||
}
|
||||
if (((nn > 0) && (ss > 0)) || ((ee > 0) && (ww > 0))) {
|
||||
return abrev;
|
||||
}
|
||||
if (nnn + sss + eee + www == 3) {
|
||||
if (www == 0) {
|
||||
abrev = "e";
|
||||
} else if (eee == 0) {
|
||||
abrev = "w";
|
||||
} else if (nnn == 0) {
|
||||
abrev = "s";
|
||||
} else if (sss == 0) {
|
||||
abrev = "n";
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
if (((nnn == sss) && (eee == www)) || (cc == m)) {
|
||||
abrev = "c";
|
||||
return abrev;
|
||||
}
|
||||
if ((pa != 0) && (cc == 0)) {
|
||||
abrev = "pa";
|
||||
if (--m <= 0) {
|
||||
return abrev;
|
||||
}
|
||||
}
|
||||
if (m == 1 + cc) {
|
||||
abrev += partAbrev + " ";
|
||||
return abrev;
|
||||
}
|
||||
if (nnn != sss) {
|
||||
abrev += nnn != 0 ? "n" : "s";
|
||||
}
|
||||
if (eee != www) {
|
||||
abrev += eee != 0 ? "e" : "w";
|
||||
}
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
|
||||
private static String getStateName(String key, AreaSourceConfiguration asc,
|
||||
GeospatialData[] geoData) {
|
||||
for (GeospatialData g : geoData) {
|
||||
if (key.equals(g.attributes.get("STATE"))) {
|
||||
return (String) g.parent.attributes.get("NAME");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String NOT_IN_CWA = new String("NOT_IN_CWA");
|
||||
|
||||
/**
|
||||
* Determines if the given UGC is in the CWA and if it is, returns the
|
||||
* portion of the CWA.
|
||||
*
|
||||
* @param stateAbbrev
|
||||
* @param ugc
|
||||
* @param asc
|
||||
* @param geoData
|
||||
* @return
|
||||
*/
|
||||
private static String getFeArea(String stateAbbrev, String ugc,
|
||||
AreaSourceConfiguration asc, GeospatialData[] geoData) {
|
||||
for (GeospatialData g : geoData) {
|
||||
if (stateAbbrev.equals(g.attributes.get("STATE"))
|
||||
&& ((String) g.attributes.get(asc.getFipsField()))
|
||||
.endsWith(ugc)) {
|
||||
return (String) g.attributes.get(asc.getFeAreaField());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Is this the correct way to determine if the county is in the
|
||||
// CWA?
|
||||
return NOT_IN_CWA;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* This utility will provide an object to be sent into velocity templates which
|
||||
* will allow the template to output current Warnings.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 1, 2009 bwoodle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bwoodle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WatchUtil {
|
||||
|
||||
private Date latestTorTime;
|
||||
|
||||
private Date latestSvrTime;
|
||||
|
||||
private ArrayList<WeatherAdvisoryWatch> torWatches;
|
||||
|
||||
private ArrayList<WeatherAdvisoryWatch> svrWatches;
|
||||
|
||||
public WatchUtil() {
|
||||
torWatches = new ArrayList<WeatherAdvisoryWatch>();
|
||||
svrWatches = new ArrayList<WeatherAdvisoryWatch>();
|
||||
}
|
||||
|
||||
public void addWaw(WeatherAdvisoryWatch watch) {
|
||||
if (watch.getPhensig().equalsIgnoreCase("SV.A")) {
|
||||
svrWatches.add(watch);
|
||||
if (latestSvrTime == null
|
||||
|| watch.getEndTime().after(latestSvrTime)) {
|
||||
latestSvrTime = watch.getEndTime();
|
||||
}
|
||||
} else if (watch.getPhensig().equalsIgnoreCase("TO.A")) {
|
||||
torWatches.add(watch);
|
||||
if (latestTorTime == null
|
||||
|| watch.getEndTime().after(latestTorTime)) {
|
||||
latestTorTime = watch.getEndTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<WeatherAdvisoryWatch> getTorWatches() {
|
||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
||||
for (WeatherAdvisoryWatch w : torWatches) {
|
||||
w.setEndTime(latestTorTime);
|
||||
rval.add(w);
|
||||
}
|
||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
||||
}
|
||||
|
||||
public ArrayList<WeatherAdvisoryWatch> getSvrWatches() {
|
||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
||||
for (WeatherAdvisoryWatch w : svrWatches) {
|
||||
w.setEndTime(latestSvrTime);
|
||||
rval.add(w);
|
||||
}
|
||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
||||
}
|
||||
|
||||
public Date getLatestTorTime() {
|
||||
return latestTorTime;
|
||||
}
|
||||
|
||||
public Date getLatestSvrTime() {
|
||||
return latestSvrTime;
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.util;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 1, 2009 bwoodle Initial creation
|
||||
* Nov 9, 2012 DR 15430 D. Friedman Support proper watch inclusion language
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bwoodle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WeatherAdvisoryWatch implements Comparable<WeatherAdvisoryWatch> {
|
||||
|
||||
public static class Portion {
|
||||
public String parentRegion;
|
||||
|
||||
public List<String> partOfParentRegion;
|
||||
|
||||
public String getParentRegion() {
|
||||
return parentRegion;
|
||||
}
|
||||
|
||||
public void setParentRegion(String parentRegion) {
|
||||
this.parentRegion = parentRegion;
|
||||
}
|
||||
|
||||
public List<String> getPartOfParentRegion() {
|
||||
return partOfParentRegion;
|
||||
}
|
||||
|
||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
||||
this.partOfParentRegion = partOfParentRegion;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: NOTE: There is no site field. We currently only process
|
||||
* WCNs for the site and not WOUs from the SPC.
|
||||
*/
|
||||
|
||||
private String phensig;
|
||||
|
||||
private int eventId;
|
||||
|
||||
private Date endTime;
|
||||
|
||||
private List<Portion> portions;
|
||||
|
||||
@Deprecated
|
||||
private String parentRegion;
|
||||
|
||||
@Deprecated
|
||||
private List<String> partOfParentRegion;
|
||||
|
||||
public String getPhensig() {
|
||||
return phensig;
|
||||
}
|
||||
|
||||
public void setPhensig(String phensig) {
|
||||
this.phensig = phensig;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getParentRegion() {
|
||||
return parentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setParentRegion(String parentRegion) {
|
||||
this.parentRegion = parentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<String> getPartOfParentRegion() {
|
||||
return partOfParentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
||||
this.partOfParentRegion = partOfParentRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WeatherAdvisoryWatch &&
|
||||
this.compareTo((WeatherAdvisoryWatch) obj) == 0;
|
||||
}
|
||||
|
||||
public int compareTo(WeatherAdvisoryWatch waw) {
|
||||
if (this.phensig == null)
|
||||
return waw.phensig == null ? 0 : -1;
|
||||
else if (waw.phensig == null)
|
||||
return 1;
|
||||
else {
|
||||
int c = this.phensig.compareTo(waw.phensig);
|
||||
if (c == 0)
|
||||
return this.eventId - waw.eventId;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
public int getEventId() {
|
||||
return eventId;
|
||||
}
|
||||
|
||||
public void setEventId(int eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
public List<Portion> getPortions() {
|
||||
return portions;
|
||||
}
|
||||
|
||||
public void setPortions(List<Portion> portions) {
|
||||
this.portions = portions;
|
||||
}
|
||||
}
|
|
@ -189,33 +189,35 @@ ${drainage.name}##
|
|||
########END MACRO
|
||||
|
||||
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||
#set($torWatches = ${watches.getTorWatches()})
|
||||
#set($torWatchAlso = "")
|
||||
#set($torWatchFirst = 1)
|
||||
#foreach(${watch} in ${torWatches})
|
||||
#if($torWatchFirst)
|
||||
#set($torWatchFirst = 0)
|
||||
#else
|
||||
##
|
||||
#set($tornadoWatches = [])
|
||||
#foreach(${watch} in ${watches})
|
||||
#if(${watch.getPhenSig()} == 'TO.A')
|
||||
#set($success = $tornadoWatches.add($watch))
|
||||
#set($endTime = ${watch.endTime})
|
||||
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||
#set($latestEndTime = ${endTime})
|
||||
#end
|
||||
A TORNADO WATCH ${torWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#end
|
||||
#end
|
||||
#if(!${list.isEmpty($tornadoWatches)})
|
||||
|
||||
A TORNADO WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#if(${secondtimezone})
|
||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||
#end
|
||||
FOR ##
|
||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
||||
#set($numPortions = ${list.size(${tornadoWatches})})
|
||||
#set($count = 0)
|
||||
#foreach(${portion} in ${watch.getPortions()})
|
||||
#foreach(${watch} in ${tornadoWatches})
|
||||
#set($count = $count + 1)
|
||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
||||
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||
#if($count == $numPortions - 1)
|
||||
AND ##
|
||||
#elseif($count < $numPortions)
|
||||
...##
|
||||
#end
|
||||
#end
|
||||
#set($torWatchAlso = "ALSO ")
|
||||
. ##
|
||||
#end
|
||||
|
||||
|
@ -223,33 +225,35 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
|
|||
########END MACRO
|
||||
|
||||
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||
#set($svrWatches = ${watches.getSvrWatches()})
|
||||
#set($svrWatchAlso = "")
|
||||
#set($svrWatchFirst = 1)
|
||||
#foreach(${watch} in ${svrWatches})
|
||||
#if($svrWatchFirst)
|
||||
#set($svrWatchFirst = 0)
|
||||
#else
|
||||
##
|
||||
#set($severeWatches = [])
|
||||
#foreach(${watch} in ${watches})
|
||||
#if(${watch.getPhenSig()} == 'SV.A')
|
||||
#set($success = $severeWatches.add($watch))
|
||||
#set($endTime = ${watch.endTime})
|
||||
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||
#set($latestEndTime = ${endTime})
|
||||
#end
|
||||
A SEVERE THUNDERSTORM WATCH ${svrWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#end
|
||||
#end
|
||||
#if(!${list.isEmpty($severeWatches)})
|
||||
|
||||
A SEVERE THUNDERSTORM WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#if(${secondtimezone})
|
||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||
#end
|
||||
FOR ##
|
||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
||||
#set($numPortions = ${list.size(${severeWatches})})
|
||||
#set($count = 0)
|
||||
#foreach(${portion} in ${watch.getPortions()})
|
||||
#foreach(${watch} in ${severeWatches})
|
||||
#set($count = $count + 1)
|
||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
||||
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||
#if($count == $numPortions - 1)
|
||||
AND ##
|
||||
#elseif($count < $numPortions)
|
||||
...##
|
||||
#end
|
||||
#end
|
||||
#set($svrWatchAlso = "ALSO ")
|
||||
. ##
|
||||
#end
|
||||
|
||||
|
@ -368,18 +372,6 @@ SOUTH##
|
|||
#if(${list.contains($directionSet, "WEST")})
|
||||
#set($output = "${output}WEST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "NE")})
|
||||
#set($output = "${output}NORTHEAST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "NW")})
|
||||
#set($output = "${output}NORTHWEST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "SE")})
|
||||
#set($output = "${output}SOUTHEAST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "SW")})
|
||||
#set($output = "${output}SOUTHWEST")
|
||||
#end
|
||||
#if(${useCentral} && ${list.contains($directionSet, "CENTRAL")})
|
||||
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
||||
#set($output = "${output} ")
|
||||
|
|
|
@ -119,11 +119,11 @@ FOR THE FOLLOWING THREATS...
|
|||
## If sites do not want watches in their AWW product comment out the
|
||||
## section below
|
||||
#######################################################################
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -48,11 +48,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -59,11 +59,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<enableDamBreakThreat>true</enableDamBreakThreat>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>.
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
-->
|
||||
|
||||
|
|
|
@ -191,10 +191,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -69,10 +69,10 @@ THIS IS A TEST MESSAGE. ##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -238,10 +238,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -346,10 +346,10 @@ THIS IS A TEST MESSAGE.##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -468,10 +468,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -512,10 +512,10 @@ THIS IS A TEST MESSAGE.##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -57,11 +57,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -52,7 +52,7 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
</includedWatches>
|
||||
|
|
|
@ -67,11 +67,11 @@ Must be paired with proper vm code (also commented out in flashFloodWarning.vm)!
|
|||
<!-- <trackEnabled>true</trackEnabled> -->
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -624,12 +624,12 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#* NO NEED TO INCLUDE SVR T-STM WATCHES IN A SVR WARNING!!!!
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#
|
||||
#end
|
||||
|
|
|
@ -54,10 +54,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -290,10 +290,10 @@ ${expcanPhrase} ${addthreat}
|
|||
###########################################
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
@ -1180,7 +1180,7 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -72,8 +72,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
</phensigs>
|
||||
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<enableRestart>false</enableRestart>
|
||||
|
|
|
@ -470,10 +470,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -397,10 +397,10 @@ ${canwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -571,10 +571,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -679,10 +679,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -880,10 +880,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#elseif(${CORCAN} == "true")
|
||||
|
@ -952,10 +952,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -1142,10 +1142,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -1219,10 +1219,10 @@ ${expwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations -->
|
||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations -->
|
||||
|
|
|
@ -471,7 +471,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -58,10 +58,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -262,10 +262,10 @@ ${expcanPhrase} ${addthreat}
|
|||
###########################################
|
||||
## WATCHES ##
|
||||
#############
|
||||
###if(${list.contains(${includedWatches}, "torWatches")})
|
||||
###if(${list.contains(${includedWatches}, "TO.A")})
|
||||
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
###end
|
||||
###if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
###if(${list.contains(${includedWatches}, "SV.A")})
|
||||
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
###end
|
||||
#if(${list.contains(${bullets}, "svrboxactive")})
|
||||
|
@ -924,7 +924,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -69,8 +69,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
</phensigs>
|
||||
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<enableRestart>false</enableRestart>
|
||||
|
|
|
@ -230,11 +230,11 @@ LOCATIONS CAN EXPECT !** EXPECTED SNOW **! INCHES OF SNOW.
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -309,10 +309,10 @@ IF ON OR NEAR !**Name Of Lake**!...GET OUT OF THE WATER AND MOVE INDOORS OR INSI
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
####################################
|
||||
|
|
|
@ -50,11 +50,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -431,10 +431,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -365,10 +365,10 @@ ${canwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -538,10 +538,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -646,10 +646,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -845,10 +845,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#elseif(${CORCAN} == "true")
|
||||
|
@ -917,10 +917,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
@ -1104,10 +1104,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -1182,10 +1182,10 @@ ${expwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -56,11 +56,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -49,11 +49,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
Loading…
Add table
Reference in a new issue