Issue #3419 Refactored watches to use the county table.
Change-Id: Ide7e07813203213511640d5ee515e73b278089c1 Former-commit-id:b991838494
[formerly 135d7ffa84af58d7b3c9575e654fa1298b76b2e2] Former-commit-id:86a8ca4a30
This commit is contained in:
parent
7b0b043c67
commit
997485dd22
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.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
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;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
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.gui.WarngenLayer;
|
||||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
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.
|
* 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.
|
* 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().
|
* Jun 30, 2014 DR 17447 Qinglu lin Updated findAffectedAreas().
|
||||||
|
* Jul 22, 23014 3419 jsanchez Cleaned up converFeAreaToPartList.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -92,6 +95,10 @@ public class Area {
|
||||||
*/
|
*/
|
||||||
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
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;
|
private PortionsUtil portionsUtil;
|
||||||
|
|
||||||
public Area(PortionsUtil portionsUtil) {
|
public Area(PortionsUtil portionsUtil) {
|
||||||
|
@ -259,8 +266,10 @@ public class Area {
|
||||||
|
|
||||||
area.points = pointList.toArray(new String[pointList.size()]);
|
area.points = pointList.toArray(new String[pointList.size()]);
|
||||||
}
|
}
|
||||||
String countyName = (String)regionFeature.attributes.get("COUNTYNAME");
|
String countyName = (String) regionFeature.attributes
|
||||||
if (uniqueFips.contains(area.fips) == false || !uniqueCountyname.contains(countyName)) {
|
.get("COUNTYNAME");
|
||||||
|
if (uniqueFips.contains(area.fips) == false
|
||||||
|
|| !uniqueCountyname.contains(countyName)) {
|
||||||
uniqueFips.add(area.fips);
|
uniqueFips.add(area.fips);
|
||||||
if (countyName != null) {
|
if (countyName != null) {
|
||||||
uniqueCountyname.add(countyName);
|
uniqueCountyname.add(countyName);
|
||||||
|
@ -300,7 +309,8 @@ public class Area {
|
||||||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Geometry precisionReducedArea = PolygonUtil.reducePrecision(warnArea);
|
Geometry precisionReducedArea = PolygonUtil
|
||||||
|
.reducePrecision(warnArea);
|
||||||
if (precisionReducedArea.isValid()) {
|
if (precisionReducedArea.isValid()) {
|
||||||
warnArea = precisionReducedArea;
|
warnArea = precisionReducedArea;
|
||||||
}
|
}
|
||||||
|
@ -338,66 +348,41 @@ public class Area {
|
||||||
|
|
||||||
public static List<String> converFeAreaToPartList(String feArea) {
|
public static List<String> converFeAreaToPartList(String feArea) {
|
||||||
final List<String> partList = new ArrayList<String>();
|
final List<String> partList = new ArrayList<String>();
|
||||||
if (feArea == null) {
|
if (feArea != null) {
|
||||||
// Marine warnings
|
feArea = feArea.toUpperCase();
|
||||||
partList.add("");
|
if (SPECIAL_CASE_FE_AREAS.contains(feArea)) {
|
||||||
} else {
|
partList.add(feArea);
|
||||||
if (feArea.equals("pa"))
|
} else {
|
||||||
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 {
|
|
||||||
for (int i = 0; i < feArea.length(); i++) {
|
for (int i = 0; i < feArea.length(); i++) {
|
||||||
char c = feArea.charAt(i);
|
char c = feArea.charAt(i);
|
||||||
|
Direction direction = null;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
|
||||||
partList.add("CENTRAL");
|
case 'C':
|
||||||
|
direction = Direction.CENTRAL;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'W':
|
||||||
partList.add("WEST");
|
direction = Direction.WEST;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'N':
|
||||||
partList.add("NORTH");
|
direction = Direction.NORTH;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'E':
|
||||||
partList.add("EAST");
|
direction = Direction.EAST;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 'S':
|
||||||
partList.add("SOUTH");
|
direction = Direction.SOUTH;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (direction != null) {
|
||||||
|
partList.add(direction.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return partList;
|
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.
|
* 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.
|
* 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 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -165,6 +166,12 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(WarngenDialog.class);
|
.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_WIDTH = 390;
|
||||||
|
|
||||||
private static final int BULLET_HEIGHT = 230;
|
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);
|
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||||
if (updateListCbo == null) {
|
if (updateListCbo == null) {
|
||||||
gd.horizontalIndent = 30;
|
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);
|
updateListCbo.setLayoutData(gd);
|
||||||
recreateUpdates();
|
recreateUpdates();
|
||||||
|
|
||||||
|
@ -629,7 +637,8 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
});
|
});
|
||||||
|
|
||||||
Composite redrawFrom = new Composite(redrawBox, SWT.NONE);
|
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,
|
redrawFrom.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false,
|
||||||
true));
|
true));
|
||||||
|
|
||||||
|
@ -664,9 +673,30 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
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) {
|
private void createBackupTrackEditGroups(Composite mainComposite) {
|
||||||
|
@ -1208,7 +1238,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
setInstructions();
|
setInstructions();
|
||||||
} else if (bulletListManager.isDamNameSeletcted()
|
} else if (bulletListManager.isDamNameSeletcted()
|
||||||
&& bulletListManager.isDamCauseSelected()) {
|
&& bulletListManager.isDamCauseSelected()) {
|
||||||
damBreakThreatAreaPressed();
|
DamInfoBullet damBullet = bulletListManager
|
||||||
|
.getSelectedDamInfoBullet();
|
||||||
|
if (damBullet != null) {
|
||||||
|
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||||
|
}
|
||||||
if (damBreakInstruct != null) {
|
if (damBreakInstruct != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1345,7 +1379,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
createMainProductButtons(productType);
|
createMainProductButtons(productType);
|
||||||
createOtherProductsList(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 {
|
try {
|
||||||
changeTemplate(getDefaultTemplate());
|
changeTemplate(getDefaultTemplate());
|
||||||
resetPressed();
|
resetPressed();
|
||||||
|
@ -1440,55 +1474,50 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is responsible for drawing a pre-defined drainage basin on
|
* Responsible for drawing a pre-defined warning polygon (coords) on the
|
||||||
* the WarnGen layer. The method is called when a drainage basin is selected
|
* WarnGen layer.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
|
* @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"
|
damBreakInstruct = "Either no dam selected, no dam info bullets in .xml file, or no\n"
|
||||||
+ "dam break primary cause selected.";
|
+ "dam break primary cause selected.";
|
||||||
DamInfoBullet damBullet = bulletListManager.getSelectedDamInfoBullet();
|
|
||||||
if (damBullet != null) {
|
|
||||||
|
|
||||||
if ((damBullet.getCoords() == null)
|
if ((coords == null) || (coords.length() == 0)) {
|
||||||
|| (damBullet.getCoords().length() == 0)) {
|
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
} else {
|
||||||
} else {
|
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
Pattern coordinatePtrn = Pattern
|
||||||
Pattern coordinatePtrn = Pattern
|
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
Pattern latLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||||
Pattern latLonPtrn = Pattern
|
|
||||||
.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
|
||||||
|
|
||||||
Matcher m = coordinatePtrn.matcher(damBullet.getCoords());
|
Matcher m = coordinatePtrn.matcher(coords);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
m = latLonPtrn.matcher(damBullet.getCoords());
|
m = latLonPtrn.matcher(coords);
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
coordinates.add(new Coordinate((-1 * Double
|
coordinates.add(new Coordinate((-1 * Double.parseDouble(m
|
||||||
.parseDouble(m.group(2))) / 100, Double
|
.group(2))) / 100,
|
||||||
.parseDouble(m.group(1)) / 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.";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
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) {
|
if (damBreakInstruct != null) {
|
||||||
setInstructions();
|
setInstructions();
|
||||||
|
@ -1517,11 +1546,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called by controls that can change the current template. Do not
|
/**
|
||||||
* do anything if the request template is already selected. This
|
* Called by controls that can change the current template. Do not do
|
||||||
* check is necessary to prevent certain state being reset if
|
* anything if the request template is already selected. This check is
|
||||||
* a followup has been selected as this is not handled by
|
* necessary to prevent certain state being reset if a followup has been
|
||||||
* changeTemplate() (DR 14515.)
|
* selected as this is not handled by changeTemplate() (DR 14515.)
|
||||||
*/
|
*/
|
||||||
private void uiChangeTemplate(String templateName) {
|
private void uiChangeTemplate(String templateName) {
|
||||||
if (templateName.equals(warngenLayer.getTemplateName())) {
|
if (templateName.equals(warngenLayer.getTemplateName())) {
|
||||||
|
|
|
@ -37,40 +37,23 @@ import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.Template;
|
||||||
import org.apache.velocity.VelocityContext;
|
import org.apache.velocity.VelocityContext;
|
||||||
import org.apache.velocity.app.Velocity;
|
import org.apache.velocity.app.Velocity;
|
||||||
import org.apache.velocity.app.VelocityEngine;
|
import org.apache.velocity.app.VelocityEngine;
|
||||||
import org.apache.velocity.tools.generic.ListTool;
|
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.AbstractWarningRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
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.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.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.IPathManager;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
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.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
import com.raytheon.uf.common.time.SimulatedTime;
|
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.common.util.FileUtil;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
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.ToolsDataManager;
|
||||||
import com.raytheon.viz.awipstools.common.StormTrackData;
|
import com.raytheon.viz.awipstools.common.StormTrackData;
|
||||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
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.GisUtil;
|
||||||
import com.raytheon.viz.warngen.gis.PathCast;
|
import com.raytheon.viz.warngen.gis.PathCast;
|
||||||
import com.raytheon.viz.warngen.gis.PortionsUtil;
|
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.gis.Wx;
|
||||||
import com.raytheon.viz.warngen.gui.BackupData;
|
import com.raytheon.viz.warngen.gui.BackupData;
|
||||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
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.FipsUtil;
|
||||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||||
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
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.raytheon.viz.warnings.DateUtil;
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
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
|
* 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
|
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
|
||||||
* added determineAffectedMarinePortions().
|
* added determineAffectedMarinePortions().
|
||||||
|
* Jul 21, 2014 3419 jsanchez Refactored WatchUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author njensen
|
* @author njensen
|
||||||
|
@ -171,16 +152,13 @@ public class TemplateRunner {
|
||||||
|
|
||||||
private static final String LOGIN_NAME_KEY = "LOGNAME";
|
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
|
private static final Pattern BBB_PATTERN = Pattern
|
||||||
.compile(".*\\sCC([A-Z])");
|
.compile(".*\\sCC([A-Z])");
|
||||||
|
|
||||||
private static Hashtable<String, DateFormat> dateFormat;
|
private static Hashtable<String, DateFormat> dateFormat;
|
||||||
|
|
||||||
|
private static WatchUtil watchUtil;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
dateFormat = new Hashtable<String, DateFormat>();
|
dateFormat = new Hashtable<String, DateFormat>();
|
||||||
dateFormat
|
dateFormat
|
||||||
|
@ -873,11 +851,14 @@ public class TemplateRunner {
|
||||||
// Store Watches
|
// Store Watches
|
||||||
try {
|
try {
|
||||||
t0 = System.currentTimeMillis();
|
t0 = System.currentTimeMillis();
|
||||||
WatchUtil watches = getWatches(warngenLayer, config, warnPolygon,
|
if (watchUtil == null) {
|
||||||
areas, fourLetterSiteId, simulatedTime);
|
watchUtil = new WatchUtil(warngenLayer);
|
||||||
|
}
|
||||||
|
List<Watch> watches = watchUtil.getWatches(config, warnPolygon,
|
||||||
|
simulatedTime);
|
||||||
System.out.println("getWatches time: "
|
System.out.println("getWatches time: "
|
||||||
+ (System.currentTimeMillis() - t0));
|
+ (System.currentTimeMillis() - t0));
|
||||||
if (watches != null) {
|
if (watches != null && watches.isEmpty() == false) {
|
||||||
context.put("watches", watches);
|
context.put("watches", watches);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -977,574 +958,4 @@ public class TemplateRunner {
|
||||||
return rval;
|
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
|
########END MACRO
|
||||||
|
|
||||||
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||||
#set($torWatches = ${watches.getTorWatches()})
|
#set($tornadoWatches = [])
|
||||||
#set($torWatchAlso = "")
|
#foreach(${watch} in ${watches})
|
||||||
#set($torWatchFirst = 1)
|
#if(${watch.getPhenSig()} == 'TO.A')
|
||||||
#foreach(${watch} in ${torWatches})
|
#set($success = $tornadoWatches.add($watch))
|
||||||
#if($torWatchFirst)
|
#set($endTime = ${watch.endTime})
|
||||||
#set($torWatchFirst = 0)
|
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||||
#else
|
#set($latestEndTime = ${endTime})
|
||||||
##
|
|
||||||
#end
|
#end
|
||||||
A TORNADO WATCH ${torWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
#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})
|
#if(${secondtimezone})
|
||||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||||
#end
|
#end
|
||||||
FOR ##
|
FOR ##
|
||||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
#set($numPortions = ${list.size(${tornadoWatches})})
|
||||||
#set($count = 0)
|
#set($count = 0)
|
||||||
#foreach(${portion} in ${watch.getPortions()})
|
#foreach(${watch} in ${tornadoWatches})
|
||||||
#set($count = $count + 1)
|
#set($count = $count + 1)
|
||||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||||
#if($count == $numPortions - 1)
|
#if($count == $numPortions - 1)
|
||||||
AND ##
|
AND ##
|
||||||
#elseif($count < $numPortions)
|
#elseif($count < $numPortions)
|
||||||
...##
|
...##
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#set($torWatchAlso = "ALSO ")
|
|
||||||
. ##
|
. ##
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -223,33 +225,35 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
|
||||||
########END MACRO
|
########END MACRO
|
||||||
|
|
||||||
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||||
#set($svrWatches = ${watches.getSvrWatches()})
|
#set($severeWatches = [])
|
||||||
#set($svrWatchAlso = "")
|
#foreach(${watch} in ${watches})
|
||||||
#set($svrWatchFirst = 1)
|
#if(${watch.getPhenSig()} == 'SV.A')
|
||||||
#foreach(${watch} in ${svrWatches})
|
#set($success = $severeWatches.add($watch))
|
||||||
#if($svrWatchFirst)
|
#set($endTime = ${watch.endTime})
|
||||||
#set($svrWatchFirst = 0)
|
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||||
#else
|
#set($latestEndTime = ${endTime})
|
||||||
##
|
|
||||||
#end
|
#end
|
||||||
A SEVERE THUNDERSTORM WATCH ${svrWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
#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})
|
#if(${secondtimezone})
|
||||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||||
#end
|
#end
|
||||||
FOR ##
|
FOR ##
|
||||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
#set($numPortions = ${list.size(${severeWatches})})
|
||||||
#set($count = 0)
|
#set($count = 0)
|
||||||
#foreach(${portion} in ${watch.getPortions()})
|
#foreach(${watch} in ${severeWatches})
|
||||||
#set($count = $count + 1)
|
#set($count = $count + 1)
|
||||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||||
#if($count == $numPortions - 1)
|
#if($count == $numPortions - 1)
|
||||||
AND ##
|
AND ##
|
||||||
#elseif($count < $numPortions)
|
#elseif($count < $numPortions)
|
||||||
...##
|
...##
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#set($svrWatchAlso = "ALSO ")
|
|
||||||
. ##
|
. ##
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -368,18 +372,6 @@ SOUTH##
|
||||||
#if(${list.contains($directionSet, "WEST")})
|
#if(${list.contains($directionSet, "WEST")})
|
||||||
#set($output = "${output}WEST")
|
#set($output = "${output}WEST")
|
||||||
#end
|
#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(${useCentral} && ${list.contains($directionSet, "CENTRAL")})
|
||||||
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
||||||
#set($output = "${output} ")
|
#set($output = "${output} ")
|
||||||
|
|
|
@ -119,11 +119,11 @@ FOR THE FOLLOWING THREATS...
|
||||||
## If sites do not want watches in their AWW product comment out the
|
## If sites do not want watches in their AWW product comment out the
|
||||||
## section below
|
## 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})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#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})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -48,11 +48,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- 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>
|
<enableDamBreakThreat>true</enableDamBreakThreat>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>.
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>.
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
|
@ -191,10 +191,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -69,10 +69,10 @@ THIS IS A TEST MESSAGE. ##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -238,10 +238,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -346,10 +346,10 @@ THIS IS A TEST MESSAGE.##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -468,10 +468,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -512,10 +512,10 @@ THIS IS A TEST MESSAGE.##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -57,11 +57,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- 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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
|
@ -67,11 +67,11 @@ Must be paired with proper vm code (also commented out in flashFloodWarning.vm)!
|
||||||
<!-- <trackEnabled>true</trackEnabled> -->
|
<!-- <trackEnabled>true</trackEnabled> -->
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- 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 ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
#* NO NEED TO INCLUDE SVR T-STM WATCHES IN A SVR WARNING!!!!
|
#* 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})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#
|
#
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -54,10 +54,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -290,10 +290,10 @@ ${expcanPhrase} ${addthreat}
|
||||||
###########################################
|
###########################################
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -1180,7 +1180,7 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -72,8 +72,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
</phensigs>
|
</phensigs>
|
||||||
|
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<enableRestart>false</enableRestart>
|
<enableRestart>false</enableRestart>
|
||||||
|
|
|
@ -470,10 +470,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -397,10 +397,10 @@ ${canwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -571,10 +571,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -679,10 +679,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -880,10 +880,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#elseif(${CORCAN} == "true")
|
#elseif(${CORCAN} == "true")
|
||||||
|
@ -952,10 +952,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -1142,10 +1142,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -1219,10 +1219,10 @@ ${expwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- 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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations -->
|
<!-- 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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations -->
|
<!-- 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 ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -58,10 +58,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -262,10 +262,10 @@ ${expcanPhrase} ${addthreat}
|
||||||
###########################################
|
###########################################
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
###if(${list.contains(${includedWatches}, "torWatches")})
|
###if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
###end
|
###end
|
||||||
###if(${list.contains(${includedWatches}, "svrWatches")})
|
###if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
###end
|
###end
|
||||||
#if(${list.contains(${bullets}, "svrboxactive")})
|
#if(${list.contains(${bullets}, "svrboxactive")})
|
||||||
|
@ -924,7 +924,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -69,8 +69,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
</phensigs>
|
</phensigs>
|
||||||
|
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<enableRestart>false</enableRestart>
|
<enableRestart>false</enableRestart>
|
||||||
|
|
|
@ -230,11 +230,11 @@ LOCATIONS CAN EXPECT !** EXPECTED SNOW **! INCHES OF SNOW.
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## 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})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#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})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- 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 ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
####################################
|
####################################
|
||||||
|
|
|
@ -50,11 +50,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- 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 ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -365,10 +365,10 @@ ${canwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -538,10 +538,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -646,10 +646,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -845,10 +845,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#elseif(${CORCAN} == "true")
|
#elseif(${CORCAN} == "true")
|
||||||
|
@ -917,10 +917,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -1104,10 +1104,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -1182,10 +1182,10 @@ ${expwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -56,11 +56,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- 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>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- 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/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
Loading…
Add table
Reference in a new issue