Merge branch 'omaha_14.3.1' into omaha_14.4.1
Conflicts: cave/com.raytheon.uf.viz.core.maps/localization/bundles/maps/Cities.xml cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/scales/MapScalesManager.java cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmDisplayWindow.java cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/CurrentAlarmQueue.java cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/GridParmManager.java edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/util/GribModelLookup.java edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/LocalizationStreamHandler.java edexOsgi/com.raytheon.uf.edex.activetable/META-INF/MANIFEST.MF edexOsgi/com.raytheon.uf.edex.activetable/src/com/raytheon/uf/edex/activetable/ActiveTable.java edexOsgi/com.raytheon.uf.edex.activetable/utility/common_static/base/vtec/ActiveTable.py Former-commit-id:bf9a0fa5de
[formerly f7d474895366eb23ae5eef242a4568f911435aa3] Former-commit-id:0fb743ec44
This commit is contained in:
commit
a92dc418c6
80 changed files with 3675 additions and 2981 deletions
|
@ -39,7 +39,10 @@ import com.raytheon.uf.viz.core.status.VizStatusInternal;
|
|||
|
||||
/**
|
||||
* Implements status handling by converting status messages into StatusMessages
|
||||
* and sending them to alertviz
|
||||
* and sending them to alertviz.
|
||||
*
|
||||
* Also logs to a file so the error can be traced to the specific process id and
|
||||
* as a safety net in case alertviz cannot be reached.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
|
@ -47,6 +50,7 @@ import com.raytheon.uf.viz.core.status.VizStatusInternal;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 09, 2008 1433 chammack Initial creation
|
||||
* Aug 26, 2013 2142 njensen Changed to use SLF4J
|
||||
* Jul 02, 2014 3337 njensen Disabled logback packaging data
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -62,6 +66,34 @@ public class SystemStatusHandler extends AbstractStatusHandler {
|
|||
|
||||
private static final Marker FATAL = MarkerFactory.getMarker("FATAL");
|
||||
|
||||
static {
|
||||
/*
|
||||
* Disables the packaging data feature of logback (ie how the
|
||||
* stacktraces list the jar the class is in). Due to the viz dependency
|
||||
* tree, in some scenarios the determination of the packaging data can
|
||||
* spend an inordinate amount of time in the OSGi classloader trying to
|
||||
* find classes. If the viz dependency tree is cleaned up (ie
|
||||
* modularized, unnecessary imports removed, register buddies reduced)
|
||||
* then this may be able to be re-enabled without a performance hit.
|
||||
*
|
||||
* Unfortunately there is no way to do this other than casting to a
|
||||
* logback Logger, see http://jira.qos.ch/browse/LOGBACK-730 and
|
||||
* http://jira.qos.ch/browse/LOGBACK-899
|
||||
*/
|
||||
try {
|
||||
((ch.qos.logback.classic.Logger) logger).getLoggerContext()
|
||||
.setPackagingDataEnabled(false);
|
||||
} catch (Throwable t) {
|
||||
/*
|
||||
* given that this static block is for initializing the logger
|
||||
* correctly, if that went wrong let's not even try to "log" it,
|
||||
* just use stderr
|
||||
*/
|
||||
System.err.println("Error disabling logback packaging data");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -53,6 +53,7 @@ import com.raytheon.uf.common.time.DataTimeComparator;
|
|||
* cease a null pointer exception.
|
||||
* May 5, 2014 DR 17201 D. Friedman Make same-radar time matching work more like A1.
|
||||
* Aug 08, 2013 2245 bsteffen Make all DataTime comparisons consistent.
|
||||
* Jul 18, 2014 ASM #15049 D. Friedman Fix LAPS problem introduced by DR 17201
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -657,7 +658,6 @@ public class TimeMatcher {
|
|||
|
||||
if (fspatial) {
|
||||
frameFcsts = dataFcsts;
|
||||
dtf = dt;
|
||||
} else if (dtf > dt) {
|
||||
dt = dtf;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.ui.PartInitException;
|
|||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.part.ViewPart;
|
||||
|
||||
import com.raytheon.uf.common.serialization.SerializationException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
@ -52,7 +51,6 @@ import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.globals.VizGlobalsManager;
|
||||
import com.raytheon.uf.viz.core.maps.scales.MapScalesManager;
|
||||
import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale;
|
||||
import com.raytheon.uf.viz.core.procedures.Bundle;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.IInputHandler;
|
||||
|
@ -96,7 +94,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d
|
||||
* Aug 9, 2013 DR 16427 D. Friedman Swap additional input handlers.
|
||||
* Oct 10, 2013 #2104 mschenke Switched to use MapScalesManager
|
||||
*
|
||||
* Jul 15, 2014 2954 njensen Updated init() for MapScalesManager change
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -141,18 +140,8 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
|||
String myId = site.getId() + UiUtil.SECONDARY_ID_SEPARATOR
|
||||
+ site.getSecondaryId();
|
||||
|
||||
for (ManagedMapScale scale : MapScalesManager.getInstance()
|
||||
.getScalesForPart(myId)) {
|
||||
try {
|
||||
Bundle b = scale.getScaleBundle();
|
||||
b.setView(myId);
|
||||
bundleToLoad = b;
|
||||
} catch (SerializationException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error deserializing bundle for scale: " + scale, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
bundleToLoad = MapScalesManager.getInstance().getScaleBundleForPart(
|
||||
myId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -284,6 +273,7 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
|||
*
|
||||
* @see com.raytheon.viz.core.IDisplayPaneContainer#getActiveDisplayPane()
|
||||
*/
|
||||
@Override
|
||||
public IDisplayPane getActiveDisplayPane() {
|
||||
return paneManager.getActiveDisplayPane();
|
||||
}
|
||||
|
@ -774,15 +764,18 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
|||
ISelectedPanesChangedListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMouseHandler(IInputHandler handler,
|
||||
InputPriority priority) {
|
||||
paneManager.registerMouseHandler(handler, priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMouseHandler(IInputHandler handler) {
|
||||
paneManager.registerMouseHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterMouseHandler(IInputHandler handler) {
|
||||
paneManager.unregisterMouseHandler(handler);
|
||||
}
|
||||
|
|
|
@ -237,6 +237,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
|||
* 09Apr2014 #3005 lvenable Added calls to mark the tabs as not current when the tabs are changed.
|
||||
* This will show the tab as updating in the header and data text controls.
|
||||
* 06May2014 3091 rferrel Use OUP authorization to bring up send dialog.
|
||||
* 07/23/2014 15645 zhao modified checkBasicSyntaxError()
|
||||
* May 15, 2014 3002 bgonzale Moved common taf code to com.raytheon.uf.common.dataplugin.taf.
|
||||
*
|
||||
* </pre>
|
||||
|
@ -2114,19 +2115,29 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
|||
return editorComp;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check if there is an extra '=' sign in a TAF
|
||||
*
|
||||
* @param doLogMessage
|
||||
* @return true if error found, otherwise false
|
||||
*/
|
||||
private boolean checkBasicSyntaxError(boolean doLogMessage) {
|
||||
|
||||
boolean errorFound = false;
|
||||
|
||||
String in = editorTafTabComp.getTextEditorControl().getText();
|
||||
|
||||
clearSyntaxErrorLevel();
|
||||
|
||||
st = editorTafTabComp.getTextEditorControl();
|
||||
|
||||
in = in.toUpperCase().replaceAll("TAF", "\n\nTAF").trim();
|
||||
while ( in.contains("\n\n\n") ) {
|
||||
in = in.replace("\n\n\n", "\n\n");
|
||||
}
|
||||
|
||||
st.setText(in);
|
||||
|
||||
final Map<StyleRange, String> syntaxMap = new HashMap<StyleRange, String>();
|
||||
|
||||
st.addMouseTrackListener(new MouseTrackAdapter() {
|
||||
|
@ -2158,66 +2169,36 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
|||
}
|
||||
});
|
||||
|
||||
int tafIndex = in.indexOf("TAF");
|
||||
int equalSignIndex = in.indexOf("=");
|
||||
int lastEqualSignIndex = equalSignIndex;
|
||||
|
||||
if (tafIndex < 0 && equalSignIndex < 0) { // empty TAF
|
||||
return false;
|
||||
}
|
||||
|
||||
while (tafIndex > -1 || equalSignIndex > -1) {
|
||||
|
||||
if (tafIndex == -1 || tafIndex > equalSignIndex) {
|
||||
|
||||
int lineIndexOfFirstEqualSign = st
|
||||
.getLineAtOffset(lastEqualSignIndex);
|
||||
int lineIndexOfSecondEqualSign = st
|
||||
.getLineAtOffset(equalSignIndex);
|
||||
if (lineIndexOfFirstEqualSign == lineIndexOfSecondEqualSign) {
|
||||
StyleRange sr = new StyleRange(lastEqualSignIndex, 1, null,
|
||||
qcColors[3]);
|
||||
String msg = "Syntax error: there is an extra '=' sign in this line";
|
||||
syntaxMap.put(sr, msg);
|
||||
st.setStyleRange(null);
|
||||
st.setStyleRange(sr);
|
||||
if (doLogMessage) {
|
||||
msgStatComp.setMessageText(msg, qcColors[3].getRGB());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int startIndex = lastEqualSignIndex;
|
||||
|
||||
while (!in.substring(startIndex, startIndex + 1).matches(
|
||||
"[A-Z]")
|
||||
&& !in.substring(startIndex, startIndex + 1).matches(
|
||||
"[0-9]")) {
|
||||
startIndex++;
|
||||
}
|
||||
int length = 6;
|
||||
if ((equalSignIndex - startIndex) < 6) {
|
||||
length = equalSignIndex - startIndex;
|
||||
}
|
||||
StyleRange sr = new StyleRange(startIndex, length, null,
|
||||
qcColors[3]);
|
||||
String msg = "Syntax error: There is an extra '=' sign before this point, or 'TAF' is missing at beginning of TAF";
|
||||
syntaxMap.put(sr, msg);
|
||||
st.setStyleRange(null);
|
||||
st.setStyleRange(sr);
|
||||
if (doLogMessage) {
|
||||
msgStatComp.setMessageText(msg, qcColors[3].getRGB());
|
||||
}
|
||||
|
||||
return true;
|
||||
String msg = "Syntax error: There is an extra '=' sign or 'TAF' is missing at beginning of TAF";
|
||||
String[] tafs = in.split("\n\n");
|
||||
int tafStartIndex = 0;
|
||||
for ( String taf : tafs ) {
|
||||
int firstEqualSignIndex = taf.indexOf('=');
|
||||
if ( firstEqualSignIndex == -1 ) {
|
||||
tafStartIndex += taf.length() + 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
tafIndex = in.indexOf("TAF", tafIndex + 1);
|
||||
lastEqualSignIndex = equalSignIndex;
|
||||
equalSignIndex = in.indexOf("=", equalSignIndex + 1);
|
||||
int secondEqualSignIndex = taf.indexOf('=', firstEqualSignIndex+1);
|
||||
if ( secondEqualSignIndex == -1 ) {
|
||||
tafStartIndex += taf.length() + 2;
|
||||
continue;
|
||||
}
|
||||
while ( secondEqualSignIndex > -1 ) {
|
||||
int secondEqualSignIndexInEditorText = tafStartIndex + secondEqualSignIndex;
|
||||
StyleRange sr = new StyleRange(secondEqualSignIndexInEditorText, 1, null, qcColors[3]);
|
||||
syntaxMap.put(sr, msg);
|
||||
st.setStyleRange(sr);
|
||||
secondEqualSignIndex = taf.indexOf('=', secondEqualSignIndex+1);
|
||||
}
|
||||
errorFound = true;
|
||||
tafStartIndex += taf.length() + 2;
|
||||
}
|
||||
|
||||
return false;
|
||||
if ( doLogMessage ) {
|
||||
msgStatComp.setMessageText(msg, qcColors[3].getRGB());
|
||||
}
|
||||
|
||||
return errorFound;
|
||||
}
|
||||
|
||||
private void syntaxCheck() {
|
||||
|
|
|
@ -54,6 +54,7 @@ import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DByte;
|
|||
import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DFloat;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.grid.Op;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.Lock;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockMode;
|
||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockStatus;
|
||||
|
@ -185,6 +186,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Apr 02, 2013 #1774 randerso Fixed a possible deadlock issue.
|
||||
* Aug 27, 2013 #2302 randerso Fix simultaneous save issue
|
||||
* Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
||||
* Jun 30, 2014 #3332 randerso Kept local reference to lock table to avoid
|
||||
* race conditions with asynchronous updates
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -619,21 +622,19 @@ public abstract class Parm implements Comparable<Parm> {
|
|||
return new TimeRange();
|
||||
}
|
||||
|
||||
if (!isMutable()) {
|
||||
return getInventorySpan();
|
||||
}
|
||||
TimeRange tr = getInventorySpan();
|
||||
|
||||
TimeRange tr = new TimeRange();
|
||||
if (lockTable != null) {
|
||||
if (lockTable.getLocks().size() > 0) {
|
||||
tr = lockTable.getLocks().get(0).getTimeRange();
|
||||
}
|
||||
for (int i = 1; i < lockTable.getLocks().size(); i++) {
|
||||
tr = tr.combineWith(lockTable.getLocks().get(i).getTimeRange());
|
||||
if (isMutable()) {
|
||||
LockTable lt = this.lockTable;
|
||||
if (lt != null) {
|
||||
List<Lock> locks = lt.getLocks();
|
||||
for (Lock lock : locks) {
|
||||
tr = tr.combineWith(lock.getTimeRange());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tr.combineWith(getInventorySpan());
|
||||
return tr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.eclipse.core.runtime.IStatus;
|
|||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,7 @@ import com.raytheon.uf.common.time.TimeRange;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 27, 2013 #2302 randerso Initial creation
|
||||
* Jun 30, 2014 #3332 randerso Added exception handling
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -48,6 +51,9 @@ import com.raytheon.uf.common.time.TimeRange;
|
|||
*/
|
||||
|
||||
public class ParmSaveJob extends Job {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ParmSaveJob.class);
|
||||
|
||||
public static class ParmSaveStatus {
|
||||
boolean successful = false;
|
||||
|
||||
|
@ -127,8 +133,13 @@ public class ParmSaveJob extends Job {
|
|||
protected IStatus run(IProgressMonitor monitor) {
|
||||
ParmSaveRequest req = null;
|
||||
while ((req = this.saveQueue.poll()) != null) {
|
||||
boolean successful = parm.saveParameterSubClass(req.times);
|
||||
req.status.setSuccessful(successful);
|
||||
try {
|
||||
boolean successful = parm.saveParameterSubClass(req.times);
|
||||
req.status.setSuccessful(successful);
|
||||
} catch (Exception e) {
|
||||
statusHandler.error("Error saving grids for " + this.parm, e);
|
||||
req.status.setSuccessful(false);
|
||||
}
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
|
|
@ -260,6 +260,7 @@ public class RadarBiasTableDialog extends Dialog {
|
|||
applyBtn = new Button(applyBtnComp, SWT.PUSH);
|
||||
applyBtn.setText("Apply");
|
||||
applyBtn.setLayoutData(bd);
|
||||
applyBtn.setEnabled(false);
|
||||
applyBtn.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
/*
|
||||
|
@ -274,7 +275,6 @@ public class RadarBiasTableDialog extends Dialog {
|
|||
applyBiasUpdate(dt);
|
||||
MPEDisplayManager mgr = MPEDisplayManager.getCurrent();
|
||||
mgr.setSavedData(false);
|
||||
shell.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -560,7 +560,6 @@ public class RadarBiasTableDialog extends Dialog {
|
|||
editedSPBiasValue[ai] = oldSPBiasValue[ai];
|
||||
spBiasValueTextArray[ai].setText(String.format("%-1.2f", editedSPBiasValue[ai]));
|
||||
spBiasChangeMap.put(radIds[ai], ai);
|
||||
applyBtn.setEnabled(false);
|
||||
spManEditButtonArray[ai].setText("NO");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* Sep 25, 2012 1196 lvenable Dialog refactor for AlarmDisplayWindow.Added DO_NOT_BLOCK.
|
||||
* Nov 20, 2013 2488 randerso Changed to use DejaVu font
|
||||
* Jun 23, 2014 #3161 lvenable Added SWT dialog trim to the dialogs for thin client.
|
||||
* Jul 24, 2014 3423 randerso Added setLoading() to indicate waiting on product
|
||||
* retrieval. Removed prods from constructor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -101,20 +103,14 @@ public class AlarmDisplayWindow extends CaveSWTDialog {
|
|||
|
||||
/**
|
||||
* @param parentShell
|
||||
* @param prodList
|
||||
* @param accum_state
|
||||
*/
|
||||
protected AlarmDisplayWindow(Shell parentShell,
|
||||
java.util.List<StdTextProduct> prodList,
|
||||
ACCUMULATE_STATE accum_state) {
|
||||
protected AlarmDisplayWindow(Shell parentShell, ACCUMULATE_STATE accum_state) {
|
||||
super(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE,
|
||||
CAVE.PERSPECTIVE_INDEPENDENT | CAVE.INDEPENDENT_SHELL
|
||||
| CAVE.DO_NOT_BLOCK);
|
||||
setText("Alarm Display Window");
|
||||
prods = prodList;
|
||||
if (prods == null) {
|
||||
prods = new ArrayList<StdTextProduct>();
|
||||
}
|
||||
prods = new ArrayList<StdTextProduct>(0);
|
||||
this.accum_state = accum_state;
|
||||
}
|
||||
|
||||
|
@ -267,6 +263,11 @@ public class AlarmDisplayWindow extends CaveSWTDialog {
|
|||
populateText();
|
||||
}
|
||||
|
||||
public void setLoading() {
|
||||
actualText = text.getText();
|
||||
text.setText("Loading...");
|
||||
}
|
||||
|
||||
public void addText(String msg) {
|
||||
if (accumulate) {
|
||||
if (text.getText().isEmpty()) {
|
||||
|
|
|
@ -24,7 +24,13 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ControlAdapter;
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
|
@ -53,6 +59,8 @@ import com.raytheon.uf.common.dataplugin.text.dbsrv.IQueryTransport;
|
|||
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.util.Pair;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmDisplayWindow.ACCUMULATE_STATE;
|
||||
import com.raytheon.viz.texteditor.alarmalert.util.AlarmAlertFunctions;
|
||||
|
@ -97,9 +105,11 @@ import com.raytheon.viz.ui.dialogs.ModeListener;
|
|||
* Alarm Queue" GUI
|
||||
* Sep 6, 2012 13365 rferrel Accumulate and Display fix.
|
||||
* Sep 25, 2012 1196 lvenable Dialog refactor for AlarmDisplayWindow.
|
||||
* Mar 05,2013 15173 mgamazaychikov The dimensions and location of closed window
|
||||
* Mar 05, 2013 15173 mgamazaychikov The dimensions and location of closed window
|
||||
* are saved and set on the next open.
|
||||
* Jun 23, 2014 #3161 lvenable Added SWT dialog trim to the dialogs for thin client.
|
||||
* Jul 24, 2014 3423 randerso Created eclipse job to get afos command
|
||||
* execution off the UI thread
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -160,6 +170,57 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
|
||||
private static final int INIT_OFFSET = 15;
|
||||
|
||||
/**
|
||||
* Job to retrieve text products off the UI thread
|
||||
*/
|
||||
private class ProduceTextProductsJob extends Job {
|
||||
private Queue<Pair<Long, String[]>> queue = new ConcurrentLinkedQueue<Pair<Long, String[]>>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ProduceTextProductsJob() {
|
||||
super("ProduceTextProductsJob");
|
||||
setSystem(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a text product retrieval job
|
||||
*
|
||||
* @param refTime
|
||||
* @param commands
|
||||
*/
|
||||
public void queue(Long refTime, String... commands) {
|
||||
queue.add(new Pair<Long, String[]>(refTime, commands));
|
||||
this.schedule();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
while (queue.size() > 0) {
|
||||
Pair<Long, String[]> pair = queue.poll();
|
||||
if (pair != null) {
|
||||
final java.util.List<StdTextProduct> prods = produceTextProducts(
|
||||
pair.getFirst(), pair.getSecond());
|
||||
|
||||
VizApp.runSync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (alarmDisplayDlg != null
|
||||
&& !alarmDisplayDlg.isDisposed()) {
|
||||
alarmDisplayDlg.setProds(prods);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
private ProduceTextProductsJob produceTextProductsJob = new ProduceTextProductsJob();
|
||||
|
||||
/**
|
||||
* @param parentShell
|
||||
* @param style
|
||||
|
@ -268,6 +329,7 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
* closed window.
|
||||
*/
|
||||
shell.addShellListener(new ShellAdapter() {
|
||||
@Override
|
||||
public void shellClosed(ShellEvent event) {
|
||||
closeLocation = getShell().getLocation();
|
||||
closeDimensions = getShell().getSize();
|
||||
|
@ -423,7 +485,7 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
* Display the selected product the current alarm queue list.
|
||||
*/
|
||||
private void displayList() {
|
||||
String command = "";
|
||||
String command = null;
|
||||
Date refDate = null;
|
||||
if (list != null && list.getItemCount() > 0
|
||||
&& list.getSelectionCount() > 0 && list.getSelection() != null) {
|
||||
|
@ -438,14 +500,9 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
}
|
||||
}
|
||||
|
||||
java.util.List<StdTextProduct> prods = null;
|
||||
if (command != "" && refDate != null) {
|
||||
prods = produceTextProduct(command, refDate.getTime());
|
||||
}
|
||||
|
||||
// Display the Alarm Display Window
|
||||
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
||||
alarmDisplayDlg = new AlarmDisplayWindow(shell, prods,
|
||||
alarmDisplayDlg = new AlarmDisplayWindow(shell,
|
||||
ACCUMULATE_STATE.UNCHANGE);
|
||||
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
||||
|
||||
|
@ -460,58 +517,52 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
|
||||
alarmDisplayDlg.open();
|
||||
} else {
|
||||
alarmDisplayDlg.setProds(prods);
|
||||
alarmDisplayDlg.setDialogFocus();
|
||||
}
|
||||
|
||||
if (command != null && refDate != null) {
|
||||
alarmDisplayDlg.setLoading();
|
||||
produceTextProductsJob.queue(refDate.getTime(), command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display all the products in the alarm queue list and clear the list.
|
||||
*/
|
||||
private void displayAll() {
|
||||
String[] command = null;
|
||||
if (list != null) {
|
||||
command = new String[list.getItemCount()];
|
||||
for (int i = 0; i < list.getItemCount(); i++) {
|
||||
command[i] = list.getItems()[i].split(" ")[0];
|
||||
}
|
||||
// Do a count of how many instances of each command are in
|
||||
// the queue.
|
||||
Map<String, Integer> counter = new HashMap<String, Integer>();
|
||||
for (int i = 0; i < command.length; ++i) {
|
||||
if (counter.get(command[i]) == null) {
|
||||
counter.put(command[i], 0);
|
||||
} else {
|
||||
counter.put(command[i], (counter.get(command[i]) + 1));
|
||||
}
|
||||
}
|
||||
// For each command, see how far back it needs to go to
|
||||
// account for multiple instances, and construct the
|
||||
// appropriate AFOS command.
|
||||
for (int j = 0; j < command.length; ++j) {
|
||||
Integer count = counter.get(command[j]);
|
||||
if (count > 0) {
|
||||
String newCom = "-" + count.toString() + ":" + command[j];
|
||||
counter.put(command[j], (count - 1));
|
||||
command[j] = newCom;
|
||||
}
|
||||
}
|
||||
AlarmAlertLists.getInstance().getCurrentAlarms().clear();
|
||||
listDates.clear();
|
||||
list.removeAll();
|
||||
AlarmAlertFunctions.getAlarmalertbell().close();
|
||||
String[] command = new String[list.getItemCount()];
|
||||
for (int i = 0; i < list.getItemCount(); i++) {
|
||||
command[i] = list.getItems()[i].split(" ")[0];
|
||||
}
|
||||
|
||||
java.util.List<StdTextProduct> prods = new ArrayList<StdTextProduct>();
|
||||
if (command.length > 0) {
|
||||
for (int i = 0; i < command.length; i++) {
|
||||
prods.addAll(produceTextProduct(command[i]));
|
||||
// Do a count of how many instances of each command are in
|
||||
// the queue.
|
||||
Map<String, Integer> counter = new HashMap<String, Integer>();
|
||||
for (int i = 0; i < command.length; ++i) {
|
||||
if (counter.get(command[i]) == null) {
|
||||
counter.put(command[i], 0);
|
||||
} else {
|
||||
counter.put(command[i], (counter.get(command[i]) + 1));
|
||||
}
|
||||
}
|
||||
// For each command, see how far back it needs to go to
|
||||
// account for multiple instances, and construct the
|
||||
// appropriate AFOS command.
|
||||
for (int j = 0; j < command.length; ++j) {
|
||||
Integer count = counter.get(command[j]);
|
||||
if (count > 0) {
|
||||
String newCom = "-" + count.toString() + ":" + command[j];
|
||||
counter.put(command[j], (count - 1));
|
||||
command[j] = newCom;
|
||||
}
|
||||
}
|
||||
AlarmAlertLists.getInstance().getCurrentAlarms().clear();
|
||||
listDates.clear();
|
||||
list.removeAll();
|
||||
AlarmAlertFunctions.getAlarmalertbell().close();
|
||||
|
||||
// Display the Alarm Display Window
|
||||
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
||||
alarmDisplayDlg = new AlarmDisplayWindow(shell, prods,
|
||||
alarmDisplayDlg = new AlarmDisplayWindow(shell,
|
||||
ACCUMULATE_STATE.TRUE);
|
||||
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
||||
@Override
|
||||
|
@ -525,10 +576,12 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
});
|
||||
alarmDisplayDlg.open();
|
||||
} else {
|
||||
alarmDisplayDlg.setProds(prods);
|
||||
alarmDisplayDlg.setAccumulate(true);
|
||||
alarmDisplayDlg.setDialogFocus();
|
||||
}
|
||||
|
||||
alarmDisplayDlg.setLoading();
|
||||
produceTextProductsJob.queue(null, command);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -580,12 +633,6 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
}
|
||||
}
|
||||
|
||||
public java.util.List<StdTextProduct> produceTextProduct(String command) {
|
||||
ICommand cmd = CommandFactory.getAfosCommand(command);
|
||||
executeCommand(cmd);
|
||||
return prodList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product for the given AFOS command and reference time.
|
||||
*
|
||||
|
@ -593,11 +640,16 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
* @param refTime
|
||||
* @return prodList
|
||||
*/
|
||||
private java.util.List<StdTextProduct> produceTextProduct(String command,
|
||||
Long refTime) {
|
||||
ICommand cmd = CommandFactory.getAfosCommand(command, refTime);
|
||||
executeCommand(cmd);
|
||||
return prodList;
|
||||
private java.util.List<StdTextProduct> produceTextProducts(Long refTime,
|
||||
String... commands) {
|
||||
|
||||
java.util.List<StdTextProduct> prods = new ArrayList<StdTextProduct>();
|
||||
for (String command : commands) {
|
||||
ICommand cmd = CommandFactory.getAfosCommand(command, refTime);
|
||||
executeCommand(cmd);
|
||||
prods.addAll(prodList);
|
||||
}
|
||||
return prods;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -654,12 +706,19 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
|||
*/
|
||||
@Override
|
||||
public void currentAlarmChanged(CurrentAlarmEvent event) {
|
||||
AlarmAlertProduct aap = (AlarmAlertProduct) event.getSource();
|
||||
final AlarmAlertProduct aap = (AlarmAlertProduct) event.getSource();
|
||||
if (!shell.isDisposed() && shell != null) {
|
||||
CAVEMode mode = CAVEMode.getMode();
|
||||
if ((CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
||||
.equals(mode)) && aap.getOperationalMode()) {
|
||||
addToQueue(aap.getProductId(), aap.getDateReceived());
|
||||
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
addToQueue(aap.getProductId(), aap.getDateReceived());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import com.raytheon.uf.common.localization.exception.LocalizationOpFailedExcepti
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmAlertBell;
|
||||
import com.raytheon.viz.texteditor.command.CommandFactory;
|
||||
|
@ -79,6 +80,7 @@ import com.vividsolutions.jts.geom.GeometryFactory;
|
|||
* 03/19/2012 D. Friedman Fix determination of "Alarm" entries.
|
||||
* 12/07/2012 15555 m.gamazaychikov Added methods and constants for
|
||||
* the implementation of proximity alarm
|
||||
* 07/24/2014 3423 randerso Ensure ringBell is called on UI thread
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -211,14 +213,16 @@ public class AlarmAlertFunctions {
|
|||
match = true;
|
||||
}
|
||||
if (match) {
|
||||
if (productFound == null)
|
||||
if (productFound == null) {
|
||||
productFound = p;
|
||||
}
|
||||
if ("Alarm".equals(p.getAlarmType()) && p.isAlarm()) {
|
||||
alarm = true;
|
||||
productFound = p;
|
||||
}
|
||||
if (alarm)
|
||||
if (alarm) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +233,14 @@ public class AlarmAlertFunctions {
|
|||
instance.getCurrentAlarms().add(prod);
|
||||
instance.fireNewCurrentAlarmEvent(prod);
|
||||
|
||||
ringBell(alarm);
|
||||
final boolean sound = alarm;
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ringBell(sound);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,22 +23,22 @@ import com.raytheon.uf.common.dataplugin.text.alarms.AlarmAlertProduct;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.notification.INotificationObserver;
|
||||
import com.raytheon.uf.viz.core.notification.NotificationMessage;
|
||||
import com.raytheon.uf.viz.core.notification.jobs.NotificationManagerJob;
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
* Alarm Alert Notification Observer
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 13, 2009 mnash Initial creation
|
||||
* Oct 13, 2009 mnash Initial creation
|
||||
* Jun 07, 2010 5851 cjeanbap Properly stop alarm/alert observer listener.
|
||||
* Jul 24, 2014 3423 randerso Get afos command execution off the UI thread
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -108,7 +108,8 @@ public class AlarmAlertNotificationObserver implements INotificationObserver {
|
|||
}
|
||||
|
||||
if (run != null) {
|
||||
VizApp.runAsync(run);
|
||||
Thread thread = new Thread(run);
|
||||
thread.start();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
|
|
|
@ -21,6 +21,7 @@ package com.raytheon.viz.warngen.gis;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -47,6 +48,8 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
|
|||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
//import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
@ -79,6 +82,8 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
|||
* Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
|
||||
* Apr 29, 2014 3033 jsanchez Updated method to retrieve files in localization.
|
||||
* May 16, 2014 DR 17365 D. Friedman Reduce precision of warning area to avoid topology errors.
|
||||
* Jun 30, 2014 DR 17447 Qinglu lin Updated findAffectedAreas().
|
||||
* Jul 22, 23014 3419 jsanchez Cleaned up converFeAreaToPartList.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -94,6 +99,10 @@ public class Area {
|
|||
*/
|
||||
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
||||
|
||||
private static final List<String> SPECIAL_CASE_FE_AREAS = Arrays
|
||||
.asList(new String[] { "PA", "MI", "PD", "UP", "BB", "ER", "EU",
|
||||
"SR", "NR", "WU", "DS" });
|
||||
|
||||
private PortionsUtil portionsUtil;
|
||||
|
||||
public Area(PortionsUtil portionsUtil) {
|
||||
|
@ -181,6 +190,7 @@ public class Area {
|
|||
}
|
||||
|
||||
List<String> uniqueFips = new ArrayList<String>();
|
||||
List<String> uniqueCountyname = new ArrayList<String>();
|
||||
List<AffectedAreas> areas = new ArrayList<AffectedAreas>();
|
||||
for (GeospatialData regionFeature : countyMap.values()) {
|
||||
Geometry regionGeom = regionFeature.geometry;
|
||||
|
@ -260,8 +270,14 @@ public class Area {
|
|||
|
||||
area.points = pointList.toArray(new String[pointList.size()]);
|
||||
}
|
||||
if (uniqueFips.contains(area.fips) == false) {
|
||||
String countyName = (String) regionFeature.attributes
|
||||
.get("COUNTYNAME");
|
||||
if (uniqueFips.contains(area.fips) == false
|
||||
|| !uniqueCountyname.contains(countyName)) {
|
||||
uniqueFips.add(area.fips);
|
||||
if (countyName != null) {
|
||||
uniqueCountyname.add(countyName);
|
||||
}
|
||||
areas.add(area);
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +313,8 @@ public class Area {
|
|||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||
|
||||
try {
|
||||
Geometry precisionReducedArea = PolygonUtil.reducePrecision(warnArea);
|
||||
Geometry precisionReducedArea = PolygonUtil
|
||||
.reducePrecision(warnArea);
|
||||
if (precisionReducedArea.isValid()) {
|
||||
warnArea = precisionReducedArea;
|
||||
}
|
||||
|
@ -335,66 +352,41 @@ public class Area {
|
|||
|
||||
public static List<String> converFeAreaToPartList(String feArea) {
|
||||
final List<String> partList = new ArrayList<String>();
|
||||
if (feArea == null) {
|
||||
// Marine warnings
|
||||
partList.add("");
|
||||
} else {
|
||||
if (feArea.equals("pa"))
|
||||
partList.add("PA");
|
||||
else if (feArea.equals("mi"))
|
||||
partList.add("MI");
|
||||
else if (feArea.equals("pd"))
|
||||
partList.add("PD");
|
||||
else if (feArea.equals("up"))
|
||||
partList.add("UP");
|
||||
else if (feArea.equals("bb"))
|
||||
partList.add("BB");
|
||||
else if (feArea.equals("er"))
|
||||
partList.add("ER");
|
||||
else if (feArea.equals("eu"))
|
||||
partList.add("EU");
|
||||
else if (feArea.equals("sr"))
|
||||
partList.add("SR");
|
||||
else if (feArea.equals("nr"))
|
||||
partList.add("NR");
|
||||
else if (feArea.equals("wu"))
|
||||
partList.add("WU");
|
||||
else if (feArea.equals("ds"))
|
||||
partList.add("DS");
|
||||
else if (feArea.equals("ne"))
|
||||
partList.add("NE");
|
||||
else if (feArea.equals("nw"))
|
||||
partList.add("NW");
|
||||
else if (feArea.equals("se"))
|
||||
partList.add("SE");
|
||||
else if (feArea.equals("sw"))
|
||||
partList.add("SW");
|
||||
else {
|
||||
if (feArea != null) {
|
||||
feArea = feArea.toUpperCase();
|
||||
if (SPECIAL_CASE_FE_AREAS.contains(feArea)) {
|
||||
partList.add(feArea);
|
||||
} else {
|
||||
for (int i = 0; i < feArea.length(); i++) {
|
||||
char c = feArea.charAt(i);
|
||||
Direction direction = null;
|
||||
switch (c) {
|
||||
case 'c':
|
||||
partList.add("CENTRAL");
|
||||
|
||||
case 'C':
|
||||
direction = Direction.CENTRAL;
|
||||
break;
|
||||
case 'w':
|
||||
partList.add("WEST");
|
||||
case 'W':
|
||||
direction = Direction.WEST;
|
||||
break;
|
||||
case 'n':
|
||||
partList.add("NORTH");
|
||||
case 'N':
|
||||
direction = Direction.NORTH;
|
||||
break;
|
||||
case 'e':
|
||||
partList.add("EAST");
|
||||
case 'E':
|
||||
direction = Direction.EAST;
|
||||
break;
|
||||
case 's':
|
||||
partList.add("SOUTH");
|
||||
case 'S':
|
||||
direction = Direction.SOUTH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (direction != null) {
|
||||
partList.add(direction.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return partList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,6 +86,9 @@ import com.vividsolutions.jts.precision.SimpleGeometryPrecisionReducer;
|
|||
* 01/09/2014 DR 16974 D. Friedman Improve followup redraw-from-hatched-area polygons.
|
||||
* 04/15/2014 DR 17247 D. Friedman Prevent some invalid coordinates in adjustVertex.
|
||||
* 05/16/2014 DR 17365 D. Friedman Prevent some Coordinate reuse. Add reducePrecision.
|
||||
* 06/27/2014 DR 17443 D. Friedman Fix some odd cases in which parts of a polygon not covering a
|
||||
* hatched area would be retained after redrawing.
|
||||
* 07/22/2014 DR 17475 Qinglu Lin Updated createPolygonByPoints() and created second createPolygonByPoints().
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -417,12 +420,15 @@ public class PolygonUtil {
|
|||
p1--;
|
||||
|
||||
if (p1 >= 0) {
|
||||
Coordinate last = new Coordinate();
|
||||
int n, best1, best2;
|
||||
for (n = k = 0; k < npoints; k++) {
|
||||
if (match[k] == nv)
|
||||
continue;
|
||||
best1 = match[p1];
|
||||
best2 = match[k];
|
||||
last.x = longest[p1].x;
|
||||
last.y = longest[p1].y;
|
||||
p1 = k;
|
||||
if (best1 < 0 && best2 < 0) {
|
||||
if (k == n)
|
||||
|
@ -460,16 +466,59 @@ public class PolygonUtil {
|
|||
best1 += nv;
|
||||
else if (dn - da < -len2)
|
||||
best2 += nv;
|
||||
if (best1 < best2)
|
||||
|
||||
/*
|
||||
* We have apparently jumped from side best1 to side
|
||||
* best2. Should we add all of the original
|
||||
* vert[best1] -> vert[best2] vertices? If this is
|
||||
* significantly longer then the distance from the
|
||||
* last contour point to this one, it is probably
|
||||
* the wrong thing to do.
|
||||
*
|
||||
* The factor of 3 assumes that all points along the
|
||||
* contour we ware redrawing are fairly close so
|
||||
* that three times the length from any one point to
|
||||
* another is not very long.
|
||||
*/
|
||||
double maxPatchLen = last.distance(longest[k]) * 3;
|
||||
double patchLen = 0;
|
||||
|
||||
int va = Math.min(best1, best2);
|
||||
int vb = Math.max(best1, best2);
|
||||
if (va < nv) {
|
||||
patchLen = totlen[Math.min(nv, vb)] - totlen[va];
|
||||
if (vb >= nv)
|
||||
patchLen += totlen[vb % nv];
|
||||
} else {
|
||||
patchLen = totlen[vb % nv] - totlen[va % nv];
|
||||
}
|
||||
|
||||
if (patchLen >= maxPatchLen) {
|
||||
/*
|
||||
* Adding all of the other vertices would be
|
||||
* going of the rails, so just add a vertex for
|
||||
* the last point (since it may be far from
|
||||
* vert[best1] and the current point. Only add
|
||||
* one point if adding two would cause the
|
||||
* output in longest to overtake the input.
|
||||
*/
|
||||
if (n + 1 < k) {
|
||||
fixed[n] = 1;
|
||||
longest[n++] = new Coordinate(last);
|
||||
}
|
||||
fixed[n] = 1;
|
||||
longest[n++] = longest[k];
|
||||
} else if (best1 < best2) {
|
||||
for (best1++; best1 <= best2; best1++) {
|
||||
fixed[n] = 1;
|
||||
longest[n++] = new Coordinate(vert[best1]);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
for (; best1 > best2; best1--) {
|
||||
fixed[n] = 1;
|
||||
longest[n++] = new Coordinate(vert[best1]);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fixed[n] = 1;
|
||||
|
@ -1670,11 +1719,11 @@ public class PolygonUtil {
|
|||
}
|
||||
return slope;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a polygon whose two diagonal coordinates are a and b.
|
||||
**/
|
||||
static public Geometry createPolygonByPoints(Coordinate a, Coordinate b) {
|
||||
static public Geometry createPolygonByPoints(GeometryFactory gf, Coordinate a, Coordinate b) {
|
||||
double maxX, minX, maxY, minY;
|
||||
maxX = Math.max(a.x, b.x);
|
||||
minX = Math.min(a.x, b.x);
|
||||
|
@ -1686,10 +1735,14 @@ public class PolygonUtil {
|
|||
coord[2] = new Coordinate(maxX, maxY);
|
||||
coord[3] = new Coordinate(minX, maxY);
|
||||
coord[4] = new Coordinate(coord[0]);
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
LinearRing lr = gf.createLinearRing(coord);
|
||||
return gf.createPolygon(lr, null);
|
||||
}
|
||||
}
|
||||
|
||||
static public Geometry createPolygonByPoints(GeometryFactory gf, Coordinate a, double shift) {
|
||||
Coordinate b = new Coordinate(a.x + shift, a.y + shift);
|
||||
return createPolygonByPoints(gf, a, b);
|
||||
}
|
||||
|
||||
/** Creates a copy of a Geometry with reduced precision to reduce the chance of topology errors when used
|
||||
* in intersection operations.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -156,6 +156,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* Apr 24, 2014 DR 16356 Qinglu Lin Updated selectOneStorm() and selectLineOfStorms().
|
||||
* Apr 28, 2014 3033 jsanchez Re-initialized the Velocity Engine when switching back up sites.
|
||||
* May 09, 2014 DR16694 m.gamazaychikov Fixed disabled duration menu after creating text for a COR SVS.
|
||||
* Jul 01, 2014 DR 17450 D. Friedman Use list of templates from backup site.
|
||||
* Jul 21, 2014 3419 jsanchez Created a hidden button to make recreating polygons easier.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -166,6 +168,12 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(WarngenDialog.class);
|
||||
|
||||
/*
|
||||
* This flag allows a hidden button to appear to help recreating warning
|
||||
* polygons that had issues in the feed.
|
||||
*/
|
||||
private boolean debug = false;
|
||||
|
||||
private static final int BULLET_WIDTH = 390;
|
||||
|
||||
private static final int BULLET_HEIGHT = 230;
|
||||
|
@ -484,30 +492,39 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
* @param productType2
|
||||
*/
|
||||
private void createOtherProductsList(Group productType2) {
|
||||
other = new Button(productType, SWT.RADIO);
|
||||
other.setText("Other:");
|
||||
other.setEnabled(true);
|
||||
other.addSelectionListener(new SelectionAdapter() {
|
||||
if (other == null) {
|
||||
other = new Button(productType, SWT.RADIO);
|
||||
other.setText("Other:");
|
||||
other.setEnabled(true);
|
||||
other.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
otherSelected();
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
otherSelected();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
otherProductListCbo = new Combo(productType, SWT.READ_ONLY
|
||||
| SWT.DROP_DOWN);
|
||||
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
otherProductListCbo.setLayoutData(gd);
|
||||
otherProductListCbo.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
otherProductSelected();
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
other.setSelection(false);
|
||||
if (mainProductBtns.length > 0 && mainProductBtns.length > 0) {
|
||||
other.moveBelow(mainProductBtns[mainProductBtns.length - 1]);
|
||||
}
|
||||
otherProductListCbo.moveBelow(other);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
otherProductListCbo = new Combo(productType, SWT.READ_ONLY
|
||||
| SWT.DROP_DOWN);
|
||||
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
otherProductListCbo.setLayoutData(gd);
|
||||
updateOtherProductList(otherProductListCbo);
|
||||
otherProductListCbo.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
otherProductSelected();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void createMainProductButtons(Group productType) {
|
||||
|
@ -519,12 +536,13 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
mainProducts.add(str);
|
||||
}
|
||||
|
||||
String defaultTemplate = warngenLayer.getDialogConfig()
|
||||
.getDefaultTemplate();
|
||||
if ((defaultTemplate == null) || defaultTemplate.equals("")) {
|
||||
defaultTemplate = mainProducts.get(0).split("/")[1];
|
||||
}
|
||||
String defaultTemplate = getDefaultTemplate();
|
||||
|
||||
if (mainProductBtns != null) {
|
||||
for (Button button : mainProductBtns) {
|
||||
button.dispose();
|
||||
}
|
||||
}
|
||||
mainProductBtns = new Button[mainProducts.size()];
|
||||
|
||||
if (mainProducts.size() > 0) {
|
||||
|
@ -540,24 +558,29 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
mainProductBtns[0].addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
changeTemplate(mainProducts.get(0).split("/")[1]);
|
||||
uiChangeTemplate(mainProducts.get(0).split("/")[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
gd.horizontalIndent = 30;
|
||||
updateListCbo = new Combo(productType, SWT.READ_ONLY | SWT.DROP_DOWN);
|
||||
updateListCbo.setLayoutData(gd);
|
||||
recreateUpdates();
|
||||
if (updateListCbo == null) {
|
||||
gd.horizontalIndent = 30;
|
||||
updateListCbo = new Combo(productType, SWT.READ_ONLY
|
||||
| SWT.DROP_DOWN);
|
||||
updateListCbo.setLayoutData(gd);
|
||||
recreateUpdates();
|
||||
|
||||
updateListCbo.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
updateListSelected();
|
||||
}
|
||||
updateListCbo.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent arg0) {
|
||||
updateListSelected();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
} else if (mainProductBtns.length > 0) {
|
||||
updateListCbo.moveBelow(mainProductBtns[0]);
|
||||
}
|
||||
|
||||
for (int cnt = 1; cnt < mainProducts.size(); cnt++) {
|
||||
final String[] tmp = mainProducts.get(cnt).split("/");
|
||||
|
@ -586,7 +609,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
}
|
||||
}
|
||||
|
||||
changeTemplate(templateName);
|
||||
uiChangeTemplate(templateName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -616,7 +639,8 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
});
|
||||
|
||||
Composite redrawFrom = new Composite(redrawBox, SWT.NONE);
|
||||
redrawFrom.setLayout(new GridLayout(3, false));
|
||||
int columns = debug ? 4 : 3;
|
||||
redrawFrom.setLayout(new GridLayout(columns, false));
|
||||
redrawFrom.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false,
|
||||
true));
|
||||
|
||||
|
@ -651,9 +675,30 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
damBreakThreatAreaPressed();
|
||||
DamInfoBullet damBullet = bulletListManager
|
||||
.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (debug) {
|
||||
Button drawPolygonButton = new Button(redrawFrom, SWT.PUSH);
|
||||
drawPolygonButton.setText("?");
|
||||
drawPolygonButton.setEnabled(true);
|
||||
drawPolygonButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
/*
|
||||
* Copy/paste the LAT...LON line from the text product to
|
||||
* quickly recreate the polygon.
|
||||
*/
|
||||
String latLon = "LAT...LON 4282 7174 4256 7129 4248 7159 4280 7198";
|
||||
damBreakThreatAreaPressed(latLon, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void createBackupTrackEditGroups(Composite mainComposite) {
|
||||
|
@ -683,7 +728,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
backupGroup.setLayout(new GridLayout(2, false));
|
||||
|
||||
Label label2 = new Label(backupGroup, SWT.BOLD);
|
||||
label2.setText("Full:");
|
||||
label2.setText("WFO:");
|
||||
label2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
backupSiteCbo = new Combo(backupGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
|
||||
backupSiteCbo.addSelectionListener(new SelectionAdapter() {
|
||||
|
@ -1195,7 +1240,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
setInstructions();
|
||||
} else if (bulletListManager.isDamNameSeletcted()
|
||||
&& bulletListManager.isDamCauseSelected()) {
|
||||
damBreakThreatAreaPressed();
|
||||
DamInfoBullet damBullet = bulletListManager
|
||||
.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||
}
|
||||
if (damBreakInstruct != null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1323,9 +1372,28 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
} else {
|
||||
new TemplateRunnerInitJob(backupSite).schedule();
|
||||
}
|
||||
// Refresh template
|
||||
changeTemplate(warngenLayer.getTemplateName());
|
||||
resetPressed();
|
||||
|
||||
/*
|
||||
* When the product selection buttons are recreated below, the
|
||||
* button for the default template will be selected and mainProducts
|
||||
* will have been recreated. Then getDefaultTemplate() can be used
|
||||
* here to change the state.
|
||||
*/
|
||||
createMainProductButtons(productType);
|
||||
createOtherProductsList(productType);
|
||||
|
||||
// Don't let errors prevent the new controls from being displayed!
|
||||
try {
|
||||
changeTemplate(getDefaultTemplate());
|
||||
resetPressed();
|
||||
} catch (Exception e) {
|
||||
statusHandler
|
||||
.error("Error occurred while switching to the default template.",
|
||||
e);
|
||||
}
|
||||
|
||||
productType.layout(true, true);
|
||||
getShell().pack(true);
|
||||
}
|
||||
|
||||
if (backupSiteCbo.getSelectionIndex() == 0) {
|
||||
|
@ -1413,55 +1481,50 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for drawing a pre-defined drainage basin on
|
||||
* the WarnGen layer. The method is called when a drainage basin is selected
|
||||
* in the WarnGen Dialog Bullet List and the Dam Break Threat Area button is
|
||||
* pressed. Dam info geometries are defined in the Database so a Spatial
|
||||
* Query is performed to retrieve the data.
|
||||
* Responsible for drawing a pre-defined warning polygon (coords) on the
|
||||
* WarnGen layer.
|
||||
*
|
||||
* @param coords
|
||||
* pre-defined warning polygon coordinates in LAT...LON form.
|
||||
* @param lockPolygon
|
||||
* indicates if the polygon should be locked or not.
|
||||
*/
|
||||
private void damBreakThreatAreaPressed() {
|
||||
private void damBreakThreatAreaPressed(String coords, boolean lockPolygon) {
|
||||
damBreakInstruct = "Either no dam selected, no dam info bullets in .xml file, or no\n"
|
||||
+ "dam break primary cause selected.";
|
||||
DamInfoBullet damBullet = bulletListManager.getSelectedDamInfoBullet();
|
||||
if (damBullet != null) {
|
||||
|
||||
if ((damBullet.getCoords() == null)
|
||||
|| (damBullet.getCoords().length() == 0)) {
|
||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||
} else {
|
||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||
Pattern coordinatePtrn = Pattern
|
||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||
Pattern latLonPtrn = Pattern
|
||||
.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||
if ((coords == null) || (coords.length() == 0)) {
|
||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||
} else {
|
||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||
Pattern coordinatePtrn = Pattern
|
||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||
Pattern latLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||
|
||||
Matcher m = coordinatePtrn.matcher(damBullet.getCoords());
|
||||
if (m.find()) {
|
||||
m = latLonPtrn.matcher(damBullet.getCoords());
|
||||
while (m.find()) {
|
||||
coordinates.add(new Coordinate((-1 * Double
|
||||
.parseDouble(m.group(2))) / 100, Double
|
||||
.parseDouble(m.group(1)) / 100));
|
||||
}
|
||||
|
||||
if (coordinates.size() < 3) {
|
||||
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
||||
} else {
|
||||
coordinates.add(coordinates.get(0));
|
||||
PolygonUtil.truncate(coordinates, 2);
|
||||
warngenLayer.createDamThreatArea(coordinates
|
||||
.toArray(new Coordinate[coordinates.size()]));
|
||||
setPolygonLocked(true);
|
||||
warngenLayer.issueRefresh();
|
||||
damBreakInstruct = null;
|
||||
}
|
||||
} else {
|
||||
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
||||
+ "La/Lon for dam break threat area is not in pairs.";
|
||||
Matcher m = coordinatePtrn.matcher(coords);
|
||||
if (m.find()) {
|
||||
m = latLonPtrn.matcher(coords);
|
||||
while (m.find()) {
|
||||
coordinates.add(new Coordinate((-1 * Double.parseDouble(m
|
||||
.group(2))) / 100,
|
||||
Double.parseDouble(m.group(1)) / 100));
|
||||
}
|
||||
}
|
||||
|
||||
if (coordinates.size() < 3) {
|
||||
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
||||
} else {
|
||||
coordinates.add(coordinates.get(0));
|
||||
PolygonUtil.truncate(coordinates, 2);
|
||||
warngenLayer.createDamThreatArea(coordinates
|
||||
.toArray(new Coordinate[coordinates.size()]));
|
||||
setPolygonLocked(lockPolygon);
|
||||
warngenLayer.issueRefresh();
|
||||
damBreakInstruct = null;
|
||||
}
|
||||
} else {
|
||||
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
||||
+ "La/Lon for dam break threat area is not in pairs.";
|
||||
}
|
||||
}
|
||||
if (damBreakInstruct != null) {
|
||||
setInstructions();
|
||||
|
@ -1490,6 +1553,19 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by controls that can change the current template. Do not do
|
||||
* anything if the request template is already selected. This check is
|
||||
* necessary to prevent certain state being reset if a followup has been
|
||||
* selected as this is not handled by changeTemplate() (DR 14515.)
|
||||
*/
|
||||
private void uiChangeTemplate(String templateName) {
|
||||
if (templateName.equals(warngenLayer.getTemplateName())) {
|
||||
return;
|
||||
}
|
||||
changeTemplate(templateName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the Warngen Layer and Warngen Dialog based on a new
|
||||
* template selection. This method should also be called when the CWA is
|
||||
|
@ -1502,11 +1578,6 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
*/
|
||||
private void changeTemplate(String templateName) {
|
||||
|
||||
// DR 14515
|
||||
if (templateName.equals(warngenLayer.getTemplateName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
String lastAreaSource = warngenLayer.getConfiguration()
|
||||
.getHatchedAreaSource().getAreaSource();
|
||||
|
||||
|
@ -1641,6 +1712,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
otherProducts = new HashMap<String, String>();
|
||||
String[] otherProductsStr = warngenLayer.getDialogConfig()
|
||||
.getOtherWarngenProducts().split(",");
|
||||
theList.removeAll();
|
||||
for (String str : otherProductsStr) {
|
||||
String[] s = str.split("/");
|
||||
otherProducts.put(s[0], s[1]);
|
||||
|
@ -1791,7 +1863,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
templateName = otherProducts.get(otherProductListCbo
|
||||
.getItem(otherProductListCbo.getSelectionIndex()));
|
||||
}
|
||||
changeTemplate(templateName);
|
||||
uiChangeTemplate(templateName);
|
||||
otherProductListCbo.pack(true);
|
||||
productType.layout();
|
||||
|
||||
|
@ -2258,7 +2330,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
templateName = otherProducts.get(otherProductListCbo
|
||||
.getItem(otherProductListCbo.getSelectionIndex()));
|
||||
}
|
||||
changeTemplate(templateName);
|
||||
uiChangeTemplate(templateName);
|
||||
}
|
||||
|
||||
private void refreshDisplay() {
|
||||
|
@ -2510,4 +2582,13 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
warngenLayer.issueRefresh();
|
||||
}
|
||||
|
||||
private String getDefaultTemplate() {
|
||||
String defaultTemplate = warngenLayer.getDialogConfig()
|
||||
.getDefaultTemplate();
|
||||
if ((defaultTemplate == null) || defaultTemplate.equals("")) {
|
||||
defaultTemplate = mainProducts.get(0).split("/")[1];
|
||||
}
|
||||
return defaultTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -215,6 +215,9 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* 05/16/2014 DR 17365 D. Friedman Check if moved vertex results in polygon valid in both lat/lon and local coordinates.
|
||||
* 07/24/2014 3429 mapeters Updated deprecated drawLine() calls.
|
||||
* 08/01/2014 3471 mapeters Updated deprecated createShadedShape() calls.
|
||||
* 07/01/2014 DR 17450 D. Friedman Use list of templates from backup site.
|
||||
* 07/28/2014 DR 17475 Qinglu Lin Updated populateStrings() and findLargestQuadrant(), removed findLargestGeometry(),
|
||||
* added createAreaAndCentroidMaps() and movePopulatePt(), updated paintText() to center W.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -227,6 +230,9 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
String uniqueFip = null;
|
||||
|
||||
Map<String, Double> geomArea = new HashMap<String, Double>();
|
||||
Map<String, Point> geomCentroid = new HashMap<String, Point>();
|
||||
|
||||
private static class GeospatialDataList {
|
||||
|
||||
private static final String LOCAL_GEOM = "localGeometry";
|
||||
|
@ -1107,6 +1113,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
DrawableString string = new DrawableString(text, textColor);
|
||||
string.magnification = magnification;
|
||||
string.setCoordinates(out[0], out[1]);
|
||||
string.horizontalAlignment = IGraphicsTarget.HorizontalAlignment.CENTER;
|
||||
string.verticallAlignment = IGraphicsTarget.VerticalAlignment.MIDDLE;
|
||||
strings.add(string);
|
||||
}
|
||||
}
|
||||
|
@ -1190,6 +1198,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}// end synchronize
|
||||
customMaps.loadCustomMaps(Arrays.asList(config.getMaps()));
|
||||
|
||||
createAreaAndCentroidMaps();
|
||||
|
||||
this.configuration = config;
|
||||
System.out.println("Total time to init warngen config = "
|
||||
+ (System.currentTimeMillis() - t0) + "ms");
|
||||
|
@ -1392,6 +1402,49 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
} else {
|
||||
backupSite = site;
|
||||
}
|
||||
|
||||
DialogConfiguration dc = null;
|
||||
if (backupSite != null) {
|
||||
boolean haveBackupConfig = DialogConfiguration.isSiteDialogConfigExtant(backupSite);
|
||||
if (haveBackupConfig) {
|
||||
try {
|
||||
dc = DialogConfiguration.loadDialogConfigNoUser(backupSite);
|
||||
} catch (Exception e) {
|
||||
statusHandler.error(String.format(
|
||||
"Unable to load WarnGen configuration for site %s. Falling back to local configuration.",
|
||||
getLocalizedSite()), e);
|
||||
}
|
||||
} else {
|
||||
statusHandler.warn(String.format(
|
||||
"WarnGen configuration for site %s does not exist. Falling back to local configuration.",
|
||||
backupSite));
|
||||
}
|
||||
if (dc == null) {
|
||||
try {
|
||||
dc = DialogConfiguration.loadDialogConfigNoUser(LocalizationManager
|
||||
.getInstance().getCurrentSite());
|
||||
} catch (Exception e) {
|
||||
dc = new DialogConfiguration();
|
||||
statusHandler.error(String.format(
|
||||
"Unable to load WarnGen configuration for site %s.",
|
||||
getLocalizedSite()), e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
dc = DialogConfiguration.loadDialogConfig(LocalizationManager
|
||||
.getInstance().getCurrentSite());
|
||||
} catch (Exception e) {
|
||||
dc = new DialogConfiguration();
|
||||
statusHandler.error(
|
||||
"Unable to load local WarnGen configuration.", e);
|
||||
}
|
||||
}
|
||||
if (dc != null && dialogConfig != null) {
|
||||
dialogConfig.setDefaultTemplate(dc.getDefaultTemplate());
|
||||
dialogConfig.setMainWarngenProducts(dc.getMainWarngenProducts());
|
||||
dialogConfig.setOtherWarngenProducts(dc.getOtherWarngenProducts());
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocalizedSite() {
|
||||
|
@ -3162,66 +3215,127 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
toKeep.toArray(new Geometry[0]));
|
||||
}
|
||||
|
||||
private void createAreaAndCentroidMaps() {
|
||||
String gid;
|
||||
geomArea.clear();
|
||||
geomCentroid.clear();
|
||||
for (GeospatialData f : geoData.features) {
|
||||
Geometry geom = f.getGeometry();
|
||||
gid = ((CountyUserData)geom.getUserData()).gid;
|
||||
geomArea.put(gid, geom.getArea());
|
||||
geomCentroid.put(gid, geom.getCentroid());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the W strings with the included counties
|
||||
*/
|
||||
private void populateStrings() {
|
||||
state.strings.clear();
|
||||
Geometry warningArea = state.getWarningArea();
|
||||
Set<String> prefixes = new HashSet<String>(Arrays.asList(GeometryUtil
|
||||
.getGID(state.getWarningArea())));
|
||||
.getGID(warningArea)));
|
||||
|
||||
prefixes = removeDuplicateGid(prefixes);
|
||||
|
||||
for (GeospatialData f : geoData.features) {
|
||||
Geometry geom = f.geometry;
|
||||
Geometry geom2 = null;
|
||||
Geometry warningAreaN = null;
|
||||
Coordinate populatePt = null;
|
||||
Geometry populatePtGeom;
|
||||
boolean contained = false, closeTo = false;
|
||||
double shift = 1.E-8, distance, minDistance = 10.0;
|
||||
int loop, maxLoop = 10;
|
||||
Geometry warningArea = state.getWarningArea();
|
||||
String prefix = GeometryUtil.getPrefix(geom.getUserData());
|
||||
if (prefixes.contains(prefix)) {
|
||||
loop = 0;
|
||||
warningAreaN = findLargestGeometry(GeometryUtil.intersection(geom, warningArea));
|
||||
do {
|
||||
if (!warningAreaN.isEmpty()) {
|
||||
populatePt = GisUtil.d2dCoordinate(warningAreaN.getCentroid()
|
||||
.getCoordinate());
|
||||
for (GeospatialData f2 : geoData.features) {
|
||||
geom2 = f2.getGeometry();
|
||||
if (!GeometryUtil.getPrefix(geom2.getUserData()).equals(prefix)) {
|
||||
contained = false;
|
||||
closeTo = false;
|
||||
populatePtGeom = PolygonUtil.createPolygonByPoints(populatePt,
|
||||
new Coordinate(populatePt.x + shift, populatePt.y + shift));
|
||||
if (GeometryUtil.contains(geom2, populatePtGeom)) {
|
||||
// populatePt is in another county/zone.
|
||||
warningAreaN = findLargestQuadrant(warningAreaN, geom);
|
||||
contained = true;
|
||||
break;
|
||||
} else {
|
||||
distance = populatePtGeom.distance(geom2);
|
||||
if (distance < minDistance) {
|
||||
// populatePt is very close to the boundary of another county/zone.
|
||||
warningAreaN = findLargestQuadrant(warningAreaN, geom);
|
||||
closeTo = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<Integer> indexes = new HashSet<Integer>();
|
||||
String prefixM, prefixN;
|
||||
double areaM, areaN, maxArea = -1.0;
|
||||
int geomIndex = -1;
|
||||
int geomNum = warningArea.getNumGeometries();
|
||||
// Find an unique index for each county in warningArea. If there is more than one index
|
||||
// for one county, find the one with max area.
|
||||
Geometry warningAreaM = null, warningAreaN = null;
|
||||
for (int i = 0; i < geomNum; i++) {
|
||||
warningAreaM = warningArea.getGeometryN(i);
|
||||
prefixM = GeometryUtil.getPrefix(warningAreaM.getUserData());
|
||||
if (!prefixes.contains(prefixM)) {
|
||||
continue;
|
||||
}
|
||||
areaM = warningAreaM.getArea();
|
||||
geomIndex = i;
|
||||
while (i + 1 < geomNum) {
|
||||
warningAreaN = warningArea.getGeometryN(i + 1);
|
||||
prefixN = GeometryUtil.getPrefix(warningAreaN.getUserData());
|
||||
if (prefixN.equals(prefixM)) {
|
||||
areaN = warningAreaN.getArea();
|
||||
if (areaN > areaM) {
|
||||
if (areaN > maxArea) {
|
||||
maxArea = areaN;
|
||||
geomIndex = i + 1;
|
||||
}
|
||||
} else {
|
||||
// use the existing populatePt
|
||||
break;
|
||||
if (areaM > maxArea) {
|
||||
maxArea = areaM;
|
||||
}
|
||||
}
|
||||
loop += 1;
|
||||
} while ((contained || closeTo) && loop <= maxLoop);
|
||||
state.strings.put(populatePt, "W");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
indexes.add(geomIndex);
|
||||
}
|
||||
|
||||
Map<String, Coordinate> populatePtMap = new HashMap<String, Coordinate>();
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
Geometry geomN = null, populatePtGeom = null;
|
||||
Coordinate populatePt = new Coordinate();
|
||||
Point centroid = null;
|
||||
int loop, maxLoop = 10;
|
||||
double threshold = 0.1, weight = 0.5, shift = 1.E-8, minArea = 1.0E-2, area;
|
||||
Iterator<Integer> iter = indexes.iterator();
|
||||
while (iter.hasNext()) {
|
||||
warningAreaM = warningArea.getGeometryN(iter.next().intValue());
|
||||
prefixM = GeometryUtil.getPrefix(warningAreaM.getUserData());
|
||||
area = warningAreaM.getArea();
|
||||
if (area < minArea || area / geomArea.get(prefixM) < threshold) {
|
||||
// Hatched area inside a county is small, move W toward to default centroid
|
||||
centroid = movePopulatePt(gf, warningAreaM, geomCentroid.get(prefixM), weight);
|
||||
populatePt = new Coordinate(centroid.getX(), centroid.getY());
|
||||
populatePtGeom = PolygonUtil.createPolygonByPoints(gf, populatePt, shift);
|
||||
} else {
|
||||
// Use the controid of the hatched area in a county
|
||||
centroid = warningAreaM.getCentroid();
|
||||
populatePt = new Coordinate(centroid.getX(), centroid.getY());
|
||||
populatePtGeom = PolygonUtil.createPolygonByPoints(gf, populatePt, shift);
|
||||
}
|
||||
for (GeospatialData gd : geoData.features) {
|
||||
geomN = gd.getGeometry();
|
||||
CountyUserData cud = (CountyUserData)geomN.getUserData();
|
||||
prefixN = cud.gid;
|
||||
if (prefixN.length() > 0 && prefixM.length() > 0 &&
|
||||
!prefixN.equals(prefixM)) {
|
||||
if (GeometryUtil.contains(geomN, populatePtGeom)) {
|
||||
// W is inside a county. Use default centroid of a county (not that of its hatched area)
|
||||
centroid = geomCentroid.get(prefixM);
|
||||
populatePt = new Coordinate(centroid.getX(), centroid.getY());
|
||||
populatePtGeom = PolygonUtil.createPolygonByPoints(gf, populatePt, shift);
|
||||
}
|
||||
loop = 1;
|
||||
while (GeometryUtil.contains(geomN, populatePtGeom) && loop < maxLoop) {
|
||||
// W is still inside a county, move W to the largest quadrant
|
||||
warningAreaM = findLargestQuadrant(gf, warningAreaM);
|
||||
centroid = warningAreaM.getCentroid();
|
||||
populatePt = new Coordinate(centroid.getX(), centroid.getY());
|
||||
populatePtGeom = PolygonUtil.createPolygonByPoints(gf, populatePt, shift);
|
||||
loop += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
populatePtMap.put(prefixM, populatePt);
|
||||
}
|
||||
for (String key: populatePtMap.keySet()) {
|
||||
state.strings.put(populatePtMap.get(key), "W");
|
||||
}
|
||||
}
|
||||
|
||||
private Point movePopulatePt(GeometryFactory gf, Geometry geom, Point point, double weight) {
|
||||
Point centroid = geom.getCentroid();
|
||||
Coordinate coord = new Coordinate();
|
||||
coord.x = centroid.getX() * weight + point.getX() * (1.0 - weight);
|
||||
coord.y = centroid.getY() * weight + point.getY() * (1.0 - weight);
|
||||
return gf.createPoint(new Coordinate(coord.x, coord.y));
|
||||
}
|
||||
|
||||
public boolean featureProduct(Coordinate c) {
|
||||
|
@ -3498,21 +3612,6 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
* A Geometry or a GeometryCollection.
|
||||
* @return Geometry
|
||||
*/
|
||||
private Geometry findLargestGeometry(Geometry g) {
|
||||
int size = g.getNumGeometries();
|
||||
if (size == 1)
|
||||
return g;
|
||||
double area, maxArea = -1.0;
|
||||
int index = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
area = g.getGeometryN(i).getArea();
|
||||
if (area > maxArea) {
|
||||
maxArea = area;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return g.getGeometryN(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the hatched area into four quadrants, and return the largest one.
|
||||
|
@ -3523,10 +3622,10 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
* The geometry of a county/zone.
|
||||
* @return Geometry
|
||||
* The geometey of largest quadrant among the four, which are the result of
|
||||
* splitting of hatchedArea.
|
||||
* splitting of a county's hatched area.
|
||||
*/
|
||||
private Geometry findLargestQuadrant(Geometry hatchedArea, Geometry geom) {
|
||||
Geometry envelope = hatchedArea.getEnvelope();
|
||||
private Geometry findLargestQuadrant(GeometryFactory gf, Geometry geom) {
|
||||
Geometry envelope = geom.getEnvelope();
|
||||
Coordinate centroidCoord = GisUtil.d2dCoordinate(envelope.getCentroid()
|
||||
.getCoordinate());
|
||||
Coordinate[] envCoords = envelope.getCoordinates();
|
||||
|
@ -3536,19 +3635,22 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
double largestArea = -1.0, area = -1.0;
|
||||
int index = -1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
quadrants[i] = PolygonUtil.createPolygonByPoints(envCoords[i], centroidCoord);
|
||||
intersections[i] = GeometryUtil.intersection(quadrants[i], hatchedArea);
|
||||
area = intersections[i].getArea();
|
||||
if (area > largestArea) {
|
||||
largestArea = area;
|
||||
index = i;
|
||||
quadrants[i] = PolygonUtil.createPolygonByPoints(gf, envCoords[i], centroidCoord);
|
||||
try {
|
||||
intersections[i] = GeometryUtil.intersection(quadrants[i], geom);
|
||||
area = intersections[i].getArea();
|
||||
if (area > largestArea) {
|
||||
largestArea = area;
|
||||
index = i;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if (intersections[index].isValid())
|
||||
if (null != intersections[index] && intersections[index].isValid())
|
||||
return intersections[index];
|
||||
else {
|
||||
// "intersections[" + index + "] is invalid"
|
||||
return hatchedArea;
|
||||
return geom;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3564,4 +3666,5 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
StormTrackState.trackType = "lineOfStorms";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,42 +37,25 @@ import java.util.Hashtable;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.tools.generic.ListTool;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.AreaType;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
|
||||
import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
|
||||
import com.raytheon.uf.common.dataplugin.warning.portions.PortionsUtil;
|
||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
|
@ -84,11 +67,9 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.SimulatedTime;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.awipstools.ToolsDataManager;
|
||||
import com.raytheon.viz.awipstools.common.StormTrackData;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||
|
@ -99,6 +80,8 @@ import com.raytheon.viz.warngen.gis.AffectedAreas;
|
|||
import com.raytheon.viz.warngen.gis.Area;
|
||||
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
||||
import com.raytheon.viz.warngen.gis.PathCast;
|
||||
import com.raytheon.viz.warngen.gis.Watch;
|
||||
import com.raytheon.viz.warngen.gis.WatchUtil;
|
||||
import com.raytheon.viz.warngen.gis.Wx;
|
||||
import com.raytheon.viz.warngen.gui.BackupData;
|
||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
||||
|
@ -111,9 +94,6 @@ import com.raytheon.viz.warngen.util.CurrentWarnings;
|
|||
import com.raytheon.viz.warngen.util.FipsUtil;
|
||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
||||
import com.raytheon.viz.warngen.util.WatchUtil;
|
||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch;
|
||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch.Portion;
|
||||
import com.raytheon.viz.warnings.DateUtil;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
|
@ -160,6 +140,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
|
||||
* added determineAffectedMarinePortions().
|
||||
* Apr 28, 2014 3033 jsanchez Set the site and backup site in Velocity Engine's properties
|
||||
* Jul 21, 2014 3419 jsanchez Refactored WatchUtil.
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -172,16 +153,13 @@ public class TemplateRunner {
|
|||
|
||||
private static final String LOGIN_NAME_KEY = "LOGNAME";
|
||||
|
||||
private static final UnitConverter milesToKilometer = NonSI.MILE
|
||||
.getConverterTo(SI.KILOMETER);
|
||||
|
||||
private static final double KmToDegrees = 111.12;
|
||||
|
||||
private static final Pattern BBB_PATTERN = Pattern
|
||||
.compile(".*\\sCC([A-Z])");
|
||||
|
||||
private static Hashtable<String, DateFormat> dateFormat;
|
||||
|
||||
private static WatchUtil watchUtil;
|
||||
|
||||
static {
|
||||
dateFormat = new Hashtable<String, DateFormat>();
|
||||
dateFormat
|
||||
|
@ -876,11 +854,14 @@ public class TemplateRunner {
|
|||
// Store Watches
|
||||
try {
|
||||
t0 = System.currentTimeMillis();
|
||||
WatchUtil watches = getWatches(warngenLayer, config, warnPolygon,
|
||||
areas, fourLetterSiteId, simulatedTime);
|
||||
if (watchUtil == null) {
|
||||
watchUtil = new WatchUtil(warngenLayer);
|
||||
}
|
||||
List<Watch> watches = watchUtil.getWatches(config, warnPolygon,
|
||||
simulatedTime);
|
||||
System.out.println("getWatches time: "
|
||||
+ (System.currentTimeMillis() - t0));
|
||||
if (watches != null) {
|
||||
if (watches != null && watches.isEmpty() == false) {
|
||||
context.put("watches", watches);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -980,574 +961,4 @@ public class TemplateRunner {
|
|||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method populates a WatchUtil object with tornado and severe
|
||||
* thunderstorm watches from the active table that are contained by the
|
||||
* polygon. Furthermore, watches that have not yet expired (current time <
|
||||
* end time) are only included.
|
||||
*
|
||||
* @param config
|
||||
* WarnGen template configuration settings
|
||||
* ([template_name_site.xml])
|
||||
* @param polygon
|
||||
* The Geometry surrounded by the warning polygon.
|
||||
* @param simulatedTime
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static WatchUtil getWatches(WarngenLayer warngenLayer,
|
||||
WarngenConfiguration config, Geometry polygon,
|
||||
AffectedAreas[] affectedAreas, String fourLetterSiteId,
|
||||
Date simulatedTime) throws Exception {
|
||||
Validate.isTrue(config.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer() >= 0,
|
||||
"IncludedWatchAreaBuffer can not be negative");
|
||||
|
||||
WatchUtil rval = null;
|
||||
String[] includedWatches = config.getIncludedWatches();
|
||||
|
||||
if ((includedWatches != null) && (includedWatches.length > 0)) {
|
||||
String phensigList = null;
|
||||
for (String includedWatch : includedWatches) {
|
||||
if (includedWatch.equalsIgnoreCase("torWatches")) {
|
||||
phensigList = phensigList == null ? "TO.A" : phensigList
|
||||
+ ",TO.A";
|
||||
} else if (includedWatch.equalsIgnoreCase("svrWatches")) {
|
||||
phensigList = phensigList == null ? "SV.A" : phensigList
|
||||
+ ",SV.A";
|
||||
}
|
||||
}
|
||||
|
||||
if (phensigList != null) {
|
||||
// Create start/endtime constraints
|
||||
Date endConstraintTime = simulatedTime;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(simulatedTime);
|
||||
cal.add(Calendar.MINUTE, 3);
|
||||
Date startConstraintTime = cal.getTime();
|
||||
|
||||
// Get record type
|
||||
Class<? extends ActiveTableRecord> recordType = CAVEMode
|
||||
.getMode() == CAVEMode.OPERATIONAL ? OperationalActiveTableRecord.class
|
||||
: PracticeActiveTableRecord.class;
|
||||
|
||||
DbQueryRequest request = new DbQueryRequest();
|
||||
request.setEntityClass(recordType);
|
||||
request.addConstraint("startTime", new RequestConstraint(
|
||||
TimeUtil.formatDate(startConstraintTime),
|
||||
ConstraintType.LESS_THAN_EQUALS));
|
||||
request.addConstraint(
|
||||
"endTime",
|
||||
new RequestConstraint(TimeUtil
|
||||
.formatDate(endConstraintTime),
|
||||
ConstraintType.GREATER_THAN_EQUALS));
|
||||
/*
|
||||
* TODO: Currently limited to filtering out one of
|
||||
* ("CAN","EXP"). Could use "Act" in addition to "act", but this
|
||||
* should really be fixed the underlying system.
|
||||
* request.addConstraint("act", new RequestConstraint("CAN",
|
||||
* ConstraintType.NOT_EQUALS));
|
||||
*/
|
||||
request.addConstraint("act", new RequestConstraint("EXP",
|
||||
ConstraintType.NOT_EQUALS));
|
||||
request.addConstraint("phensig", new RequestConstraint(
|
||||
phensigList, ConstraintType.IN));
|
||||
|
||||
// TODO: Talk to Jonathan about this... Do I even need officeid
|
||||
// IN or is ugc zone good enough?
|
||||
|
||||
/*
|
||||
* Get all UGCs in the CWA now so that the watches will be
|
||||
* formatted with all portions of the affected state(s).
|
||||
*
|
||||
* Filtering for valid UGCs is performed in processATEntries
|
||||
*/
|
||||
RequestConstraint ugcConstraint = new RequestConstraint("",
|
||||
ConstraintType.IN);
|
||||
ugcConstraint.setConstraintValueList(warngenLayer
|
||||
.getAllUgcs());
|
||||
request.addConstraint("ugcZone", ugcConstraint);
|
||||
|
||||
// These are the only fields we need for processing watches
|
||||
request.addFields(new String[] { "issueTime", "startTime",
|
||||
"endTime", "ugcZone", "phensig", "vtecstr", "etn",
|
||||
"act" });
|
||||
|
||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
||||
.sendRequest(request);
|
||||
|
||||
List<ActiveTableRecord> records = new ArrayList<ActiveTableRecord>(
|
||||
response.getNumResults());
|
||||
for (Map<String, Object> result : response.getResults()) {
|
||||
/*
|
||||
* TODO: Doing this here because only "EXP" is filtered out
|
||||
* by the query. Remove "act" from the field list once this
|
||||
* is fixed.
|
||||
*/
|
||||
if ("CAN".equals(result.get("act")))
|
||||
continue;
|
||||
ActiveTableRecord record = recordType.newInstance();
|
||||
record.setIssueTime((Calendar) result.get("issueTime"));
|
||||
record.setStartTime((Calendar) result.get("startTime"));
|
||||
record.setEndTime((Calendar) result.get("endTime"));
|
||||
record.setUgcZone((String) result.get("ugcZone"));
|
||||
record.setPhensig((String) result.get("phensig"));
|
||||
record.setVtecstr((String) result.get("vtecstr"));
|
||||
record.setEtn((String) result.get("etn"));
|
||||
records.add(record);
|
||||
}
|
||||
|
||||
if (records.size() > 0) {
|
||||
Set<String> validUgcZones;
|
||||
try {
|
||||
long t0, t1;
|
||||
t0 = System.currentTimeMillis();
|
||||
Polygon watchArea = (Polygon) polygon
|
||||
.buffer(milesToKilometer.convert(config
|
||||
.getHatchedAreaSource()
|
||||
.getIncludedWatchAreaBuffer())
|
||||
/ KmToDegrees);
|
||||
t1 = System.currentTimeMillis();
|
||||
System.out.println("getWatches.polygonBuffer time: "
|
||||
+ (t1 - t0));
|
||||
validUgcZones = warngenLayer
|
||||
.getUgcsForWatches(watchArea);
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Error determining areas to search for watches.",
|
||||
e);
|
||||
return rval;
|
||||
}
|
||||
|
||||
rval = processATEntries(records, warngenLayer,
|
||||
validUgcZones);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
private static class WatchWork {
|
||||
public WeatherAdvisoryWatch waw;
|
||||
|
||||
public boolean valid;
|
||||
|
||||
public ArrayList<String> ugcZone = new ArrayList<String>();
|
||||
|
||||
public WatchWork(WeatherAdvisoryWatch waw) {
|
||||
this.waw = waw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the list of objects representing active watches that will be
|
||||
* passed to the template context.
|
||||
*
|
||||
* @param activeTable
|
||||
* List of entries for active watches
|
||||
* @param warngenLayer
|
||||
* @param validUgcZones
|
||||
* @return
|
||||
*/
|
||||
private static WatchUtil processATEntries(
|
||||
List<ActiveTableRecord> activeTable, WarngenLayer warngenLayer,
|
||||
Set<String> validUgcZones) {
|
||||
WatchUtil rval = new WatchUtil();
|
||||
TreeMap<WeatherAdvisoryWatch, WatchWork> map = new TreeMap<WeatherAdvisoryWatch, TemplateRunner.WatchWork>();
|
||||
|
||||
AreaSourceConfiguration asc = null;
|
||||
for (AreaSourceConfiguration a : warngenLayer.getConfiguration()
|
||||
.getAreaSources()) {
|
||||
if (a.getType() == AreaType.HATCHING) {
|
||||
asc = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (asc == null) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Cannot process watches: missing HATCHING area source configuration");
|
||||
return rval;
|
||||
}
|
||||
GeospatialData[] geoData = warngenLayer.getGeodataFeatures(
|
||||
asc.getAreaSource(), warngenLayer.getLocalizedSite());
|
||||
if ((geoData == null) || (geoData.length == 0)) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Cannot process watches: cannot get geospatial data");
|
||||
return rval;
|
||||
}
|
||||
|
||||
// For each watch event, get the end time and list of active zones
|
||||
for (ActiveTableRecord ar : activeTable) {
|
||||
/*
|
||||
* Currently reports all zones in the watch even if a given zone is
|
||||
* not in the warning polygon. If the logic is changed to only show
|
||||
* the portions of the watch near our warning polygon, filter on
|
||||
* validUgcZones here.
|
||||
*/
|
||||
WeatherAdvisoryWatch waw = new WeatherAdvisoryWatch();
|
||||
waw.setPhensig(ar.getPhensig());
|
||||
try {
|
||||
waw.setEventId(Integer.parseInt(ar.getEtn()));
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler.handle(Priority.ERROR, String.format(
|
||||
"Watch %s has null end time; not included.",
|
||||
ar.getVtecstr()));
|
||||
continue;
|
||||
}
|
||||
|
||||
WatchWork work = map.get(waw);
|
||||
if (work == null) {
|
||||
waw.setEndTime(ar.getEndTime().getTime());
|
||||
work = new WatchWork(waw);
|
||||
map.put(waw, work);
|
||||
}
|
||||
|
||||
if (validUgcZones.contains(ar.getUgcZone())) {
|
||||
work.valid = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are no checks here to determine whether or not the given
|
||||
* zone is in the CWA. That should have already been done the query
|
||||
* performed in getWatches.
|
||||
*
|
||||
* There is also validation performed later in
|
||||
* determineAffectedPortions.
|
||||
*/
|
||||
work.ugcZone.add(ar.getUgcZone());
|
||||
}
|
||||
|
||||
for (WatchWork work : map.values()) {
|
||||
/*
|
||||
* If none of the areas in the watch were neer our warning polygon,
|
||||
* do not included it.
|
||||
*/
|
||||
if (!work.valid) {
|
||||
continue;
|
||||
}
|
||||
boolean isMarineZone = warngenLayer.getConfiguration().getGeospatialConfig()
|
||||
.getAreaSource().equalsIgnoreCase(WarngenLayer.MARINE);
|
||||
if (!isMarineZone) {
|
||||
if (determineAffectedPortions(work.ugcZone, asc, geoData, work.waw)) {
|
||||
rval.addWaw(work.waw);
|
||||
}
|
||||
} else {
|
||||
if (determineAffectedMarinePortions(work.ugcZone, asc, geoData, work.waw)) {
|
||||
rval.addWaw(work.waw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the list of counties in a watch, fill out the "portions" part of
|
||||
* the given WeatherAdvisoryWatch. Also checks if the given counties are
|
||||
* actually in the CWA.
|
||||
*
|
||||
* @param ugcs
|
||||
* @param asc
|
||||
* @param geoData
|
||||
* @param waw
|
||||
*/
|
||||
private static boolean determineAffectedPortions(List<String> ugcs,
|
||||
AreaSourceConfiguration asc, GeospatialData[] geoData,
|
||||
WeatherAdvisoryWatch waw) {
|
||||
|
||||
// Maps state abbreviation to unique fe_area values
|
||||
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
|
||||
|
||||
for (String ugc : ugcs) {
|
||||
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "County");
|
||||
Entry<String, String[]> e = null;
|
||||
|
||||
// Either zero or more than one sates/counties would be wrong
|
||||
if ((parsed.size() != 1)
|
||||
|| ((e = parsed.entrySet().iterator().next()).getValue().length != 1)) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Invalid ugczone in active table entry: " + ugc);
|
||||
continue;
|
||||
}
|
||||
|
||||
String stateAbbrev = e.getKey();
|
||||
String feArea = null;
|
||||
try {
|
||||
feArea = getFeArea(stateAbbrev, e.getValue()[0], asc, geoData);
|
||||
} catch (RuntimeException exc) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error generating included watches.", exc);
|
||||
return false;
|
||||
}
|
||||
if (feArea == NOT_IN_CWA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> feAreas = map.get(stateAbbrev);
|
||||
if (feAreas == null) {
|
||||
feAreas = new HashSet<String>();
|
||||
map.put(stateAbbrev, feAreas);
|
||||
}
|
||||
if (feArea != null) {
|
||||
feAreas.add(feArea);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
|
||||
for (Entry<String, Set<String>> e : map.entrySet()) {
|
||||
Portion portion = new Portion();
|
||||
try {
|
||||
portion.parentRegion = getStateName(e.getKey(), asc, geoData)
|
||||
.toUpperCase();
|
||||
} catch (RuntimeException exc) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error generating included watches.", exc);
|
||||
return false;
|
||||
}
|
||||
portion.partOfParentRegion = Area
|
||||
.converFeAreaToPartList(mungeFeAreas(e.getValue()));
|
||||
portions.add(portion);
|
||||
}
|
||||
waw.setPortions(portions);
|
||||
// Set legacy values
|
||||
if (portions.size() > 0) {
|
||||
waw.setParentRegion(portions.get(0).parentRegion);
|
||||
waw.setPartOfParentRegion(portions.get(0).partOfParentRegion);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the list of marine zones in a watch, fill out the "portions" part of
|
||||
* the given WeatherAdvisoryWatch. Also checks if the given marine zones are
|
||||
* actually in the CWA.
|
||||
*
|
||||
* @param ugcs
|
||||
* @param asc
|
||||
* @param geoData
|
||||
* @param waw
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private static boolean determineAffectedMarinePortions(List<String> ugcs,
|
||||
AreaSourceConfiguration asc, GeospatialData[] geoData,
|
||||
WeatherAdvisoryWatch waw) {
|
||||
|
||||
// Maps state abbreviation to unique fe_area values
|
||||
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
|
||||
Set<String> marinezonenameSet = new HashSet<String>();
|
||||
for (String ugc : ugcs) {
|
||||
for (GeospatialData gd: geoData) {
|
||||
|
||||
if (gd.attributes.get("ID").equals(ugc)) {
|
||||
marinezonenameSet.add((String)gd.attributes.get("NAME"));
|
||||
}
|
||||
}
|
||||
}
|
||||
String marinezonename = "";
|
||||
int size = marinezonenameSet.size();
|
||||
Iterator<String> iter = marinezonenameSet.iterator();
|
||||
int count = 0;
|
||||
while (iter.hasNext()) {
|
||||
String s = iter.next();
|
||||
marinezonename += s;
|
||||
count += 1;
|
||||
if (size > 1) {
|
||||
if (size == 2 && count < 2) {
|
||||
marinezonename += " and ";
|
||||
} else {
|
||||
if (count == size - 1) {
|
||||
marinezonename += ", and ";
|
||||
} else {
|
||||
if (count < size - 1) {
|
||||
marinezonename += ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String ugc : ugcs) {
|
||||
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "Marine");
|
||||
Entry<String, String[]> e = null;
|
||||
|
||||
// Either zero or more than one marine zone would be wrong
|
||||
if ((parsed.size() != 1)
|
||||
|| ((e = parsed.entrySet().iterator().next()).getValue().length != 1)) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Invalid ugczone in active table entry: " + ugc);
|
||||
continue;
|
||||
}
|
||||
|
||||
String stateAbbrev = e.getKey();
|
||||
Set<String> feAreas = map.get(stateAbbrev);
|
||||
if (feAreas == null) {
|
||||
feAreas = new HashSet<String>();
|
||||
map.put(stateAbbrev, feAreas);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
|
||||
Portion portion = new Portion();
|
||||
portion.parentRegion = marinezonename;
|
||||
portion.partOfParentRegion = new ArrayList<String>();
|
||||
portion.partOfParentRegion.add("");
|
||||
portions.add(portion);
|
||||
waw.setPortions(portions);
|
||||
// Set legacy values
|
||||
if (portions.size() > 0) {
|
||||
waw.setParentRegion(portions.get(0).parentRegion);
|
||||
waw.setPartOfParentRegion(portions.get(0).partOfParentRegion);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Based on AWIPS 1 SELSparagraphs.C SELSparagraphs::processWOU().
|
||||
private static String mungeFeAreas(Set<String> feAreas) {
|
||||
String abrev = "";
|
||||
// If eight or more portions, don't qualify area of state
|
||||
int m = feAreas.size();
|
||||
if (m < 8) {
|
||||
String partAbrev = "";
|
||||
/*
|
||||
* TODO: Unused variables should be removed if we are not going to
|
||||
* improve this in A2.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
int nw, nc, ne, wc, cc, ec, sw, sc, se, pa;
|
||||
int eee, www, nnn, sss, ee, ww, nn, ss;
|
||||
|
||||
// Identify individual sub areas of this state affected
|
||||
nw = nc = ne = wc = cc = ec = sw = sc = se = pa = 0;
|
||||
eee = www = nnn = sss = ee = ww = nn = ss = 0;
|
||||
for (String part : feAreas) {
|
||||
if ("pa".equals(part)) {
|
||||
pa = 1;
|
||||
continue;
|
||||
} else if ("nn".equals(part)) {
|
||||
nnn = nn = 1;
|
||||
} else if ("ss".equals(part)) {
|
||||
sss = ss = 1;
|
||||
} else if ("ee".equals(part)) {
|
||||
eee = ee = 1;
|
||||
} else if ("ww".equals(part)) {
|
||||
www = ww = 1;
|
||||
} else if ("nw".equals(part)) {
|
||||
nnn = www = nw = 1;
|
||||
} else if ("nc".equals(part)) {
|
||||
nnn = nc = 1;
|
||||
} else if ("ne".equals(part)) {
|
||||
nnn = eee = ne = 1;
|
||||
} else if ("wc".equals(part)) {
|
||||
www = wc = 1;
|
||||
} else if ("cc".equals(part)) {
|
||||
cc = 1;
|
||||
continue;
|
||||
} else if ("ec".equals(part)) {
|
||||
eee = ec = 1;
|
||||
} else if ("sw".equals(part)) {
|
||||
sss = www = sw = 1;
|
||||
} else if ("sc".equals(part)) {
|
||||
sss = sc = 1;
|
||||
} else if ("se".equals(part)) {
|
||||
sss = eee = se = 1;
|
||||
}
|
||||
partAbrev = part;
|
||||
}
|
||||
// decide how to describe these subareas.
|
||||
if ((ne > 0) && (nw > 0)) {
|
||||
nn = 1;
|
||||
}
|
||||
if ((se > 0) && (sw > 0)) {
|
||||
ss = 1;
|
||||
}
|
||||
if ((se > 0) && (ne > 0)) {
|
||||
ee = 1;
|
||||
}
|
||||
if ((sw > 0) && (nw > 0)) {
|
||||
ww = 1;
|
||||
}
|
||||
if ((nnn > 0) && (sss > 0) && (eee > 0) && (www > 0)) {
|
||||
return abrev;
|
||||
}
|
||||
if (((nn > 0) && (ss > 0)) || ((ee > 0) && (ww > 0))) {
|
||||
return abrev;
|
||||
}
|
||||
if (nnn + sss + eee + www == 3) {
|
||||
if (www == 0) {
|
||||
abrev = "e";
|
||||
} else if (eee == 0) {
|
||||
abrev = "w";
|
||||
} else if (nnn == 0) {
|
||||
abrev = "s";
|
||||
} else if (sss == 0) {
|
||||
abrev = "n";
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
if (((nnn == sss) && (eee == www)) || (cc == m)) {
|
||||
abrev = "c";
|
||||
return abrev;
|
||||
}
|
||||
if ((pa != 0) && (cc == 0)) {
|
||||
abrev = "pa";
|
||||
if (--m <= 0) {
|
||||
return abrev;
|
||||
}
|
||||
}
|
||||
if (m == 1 + cc) {
|
||||
abrev += partAbrev + " ";
|
||||
return abrev;
|
||||
}
|
||||
if (nnn != sss) {
|
||||
abrev += nnn != 0 ? "n" : "s";
|
||||
}
|
||||
if (eee != www) {
|
||||
abrev += eee != 0 ? "e" : "w";
|
||||
}
|
||||
}
|
||||
return abrev;
|
||||
}
|
||||
|
||||
private static String getStateName(String key, AreaSourceConfiguration asc,
|
||||
GeospatialData[] geoData) {
|
||||
for (GeospatialData g : geoData) {
|
||||
if (key.equals(g.attributes.get("STATE"))) {
|
||||
return (String) g.parent.attributes.get("NAME");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String NOT_IN_CWA = new String("NOT_IN_CWA");
|
||||
|
||||
/**
|
||||
* Determines if the given UGC is in the CWA and if it is, returns the
|
||||
* portion of the CWA.
|
||||
*
|
||||
* @param stateAbbrev
|
||||
* @param ugc
|
||||
* @param asc
|
||||
* @param geoData
|
||||
* @return
|
||||
*/
|
||||
private static String getFeArea(String stateAbbrev, String ugc,
|
||||
AreaSourceConfiguration asc, GeospatialData[] geoData) {
|
||||
for (GeospatialData g : geoData) {
|
||||
if (stateAbbrev.equals(g.attributes.get("STATE"))
|
||||
&& ((String) g.attributes.get(asc.getFipsField()))
|
||||
.endsWith(ugc)) {
|
||||
return (String) g.attributes.get(asc.getFeAreaField());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Is this the correct way to determine if the county is in the
|
||||
// CWA?
|
||||
return NOT_IN_CWA;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* This utility will provide an object to be sent into velocity templates which
|
||||
* will allow the template to output current Warnings.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 1, 2009 bwoodle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bwoodle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WatchUtil {
|
||||
|
||||
private Date latestTorTime;
|
||||
|
||||
private Date latestSvrTime;
|
||||
|
||||
private ArrayList<WeatherAdvisoryWatch> torWatches;
|
||||
|
||||
private ArrayList<WeatherAdvisoryWatch> svrWatches;
|
||||
|
||||
public WatchUtil() {
|
||||
torWatches = new ArrayList<WeatherAdvisoryWatch>();
|
||||
svrWatches = new ArrayList<WeatherAdvisoryWatch>();
|
||||
}
|
||||
|
||||
public void addWaw(WeatherAdvisoryWatch watch) {
|
||||
if (watch.getPhensig().equalsIgnoreCase("SV.A")) {
|
||||
svrWatches.add(watch);
|
||||
if (latestSvrTime == null
|
||||
|| watch.getEndTime().after(latestSvrTime)) {
|
||||
latestSvrTime = watch.getEndTime();
|
||||
}
|
||||
} else if (watch.getPhensig().equalsIgnoreCase("TO.A")) {
|
||||
torWatches.add(watch);
|
||||
if (latestTorTime == null
|
||||
|| watch.getEndTime().after(latestTorTime)) {
|
||||
latestTorTime = watch.getEndTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<WeatherAdvisoryWatch> getTorWatches() {
|
||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
||||
for (WeatherAdvisoryWatch w : torWatches) {
|
||||
w.setEndTime(latestTorTime);
|
||||
rval.add(w);
|
||||
}
|
||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
||||
}
|
||||
|
||||
public ArrayList<WeatherAdvisoryWatch> getSvrWatches() {
|
||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
||||
for (WeatherAdvisoryWatch w : svrWatches) {
|
||||
w.setEndTime(latestSvrTime);
|
||||
rval.add(w);
|
||||
}
|
||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
||||
}
|
||||
|
||||
public Date getLatestTorTime() {
|
||||
return latestTorTime;
|
||||
}
|
||||
|
||||
public Date getLatestSvrTime() {
|
||||
return latestSvrTime;
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.warngen.util;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO Add Description
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 1, 2009 bwoodle Initial creation
|
||||
* Nov 9, 2012 DR 15430 D. Friedman Support proper watch inclusion language
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bwoodle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class WeatherAdvisoryWatch implements Comparable<WeatherAdvisoryWatch> {
|
||||
|
||||
public static class Portion {
|
||||
public String parentRegion;
|
||||
|
||||
public List<String> partOfParentRegion;
|
||||
|
||||
public String getParentRegion() {
|
||||
return parentRegion;
|
||||
}
|
||||
|
||||
public void setParentRegion(String parentRegion) {
|
||||
this.parentRegion = parentRegion;
|
||||
}
|
||||
|
||||
public List<String> getPartOfParentRegion() {
|
||||
return partOfParentRegion;
|
||||
}
|
||||
|
||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
||||
this.partOfParentRegion = partOfParentRegion;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: NOTE: There is no site field. We currently only process
|
||||
* WCNs for the site and not WOUs from the SPC.
|
||||
*/
|
||||
|
||||
private String phensig;
|
||||
|
||||
private int eventId;
|
||||
|
||||
private Date endTime;
|
||||
|
||||
private List<Portion> portions;
|
||||
|
||||
@Deprecated
|
||||
private String parentRegion;
|
||||
|
||||
@Deprecated
|
||||
private List<String> partOfParentRegion;
|
||||
|
||||
public String getPhensig() {
|
||||
return phensig;
|
||||
}
|
||||
|
||||
public void setPhensig(String phensig) {
|
||||
this.phensig = phensig;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getParentRegion() {
|
||||
return parentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setParentRegion(String parentRegion) {
|
||||
this.parentRegion = parentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<String> getPartOfParentRegion() {
|
||||
return partOfParentRegion;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
||||
this.partOfParentRegion = partOfParentRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WeatherAdvisoryWatch &&
|
||||
this.compareTo((WeatherAdvisoryWatch) obj) == 0;
|
||||
}
|
||||
|
||||
public int compareTo(WeatherAdvisoryWatch waw) {
|
||||
if (this.phensig == null)
|
||||
return waw.phensig == null ? 0 : -1;
|
||||
else if (waw.phensig == null)
|
||||
return 1;
|
||||
else {
|
||||
int c = this.phensig.compareTo(waw.phensig);
|
||||
if (c == 0)
|
||||
return this.eventId - waw.eventId;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
public int getEventId() {
|
||||
return eventId;
|
||||
}
|
||||
|
||||
public void setEventId(int eventId) {
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
public List<Portion> getPortions() {
|
||||
return portions;
|
||||
}
|
||||
|
||||
public void setPortions(List<Portion> portions) {
|
||||
this.portions = portions;
|
||||
}
|
||||
}
|
|
@ -143,6 +143,19 @@
|
|||
</doTry>
|
||||
</route>
|
||||
|
||||
<!-- Convert the topic into a queue so only one consumer gets each message and we still have competing consumers. -->
|
||||
<route id="gfePurgeNotificationQueueRoute">
|
||||
<from uri="jms-generic:topic:pluginPurged"/>
|
||||
<doTry>
|
||||
<to uri="jms-generic:queue:gfePurgeNotification"/>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to
|
||||
uri="log:ifpServer?level=ERROR"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
</camelContext>
|
||||
|
||||
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
||||
|
|
|
@ -101,7 +101,7 @@ import com.raytheon.uf.edex.database.purge.PurgeLogger;
|
|||
* D2DGridDatabase constructor
|
||||
* 04/23/13 #1949 rjpeter Added inventory retrieval for a given time range.
|
||||
* 05/02/13 #1969 randerso Fixed possible null pointer in getParmList
|
||||
* Removed inventory from DBInvChangedNotification
|
||||
* Removed inventory from DBInvChangeNotification
|
||||
* 05/03/13 #1974 randerso Fixed error logging to include stack trace
|
||||
* 05/14/13 #2004 randerso Added methods to synch GridParmManager across JVMs
|
||||
* 05/30/13 #2044 randerso Refactored to better match A1 design. Removed D2DParmIDCache.
|
||||
|
@ -122,7 +122,10 @@ import com.raytheon.uf.edex.database.purge.PurgeLogger;
|
|||
* 05/22/14 #3071 randerso Expand publish time to time constraint quantum after truncating it
|
||||
* to the purge time
|
||||
* 06/12/14 #3244 randerso Improved error handling
|
||||
*
|
||||
* 06/24/2014 #3317 randerso Send DBInvChangeNotification when database is created, unless it's
|
||||
* created in response to another DBInvChangeNotification so IFPServers stay in synch.
|
||||
* Cleaned up commented code.
|
||||
* 07/21/2014 #3415 randerso Fixed d2dGridDataPurged to not purge NetCDF databases.
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -840,6 +843,10 @@ public class GridParmManager {
|
|||
* @return GridDatabase or null if not available
|
||||
*/
|
||||
public GridDatabase getDatabase(DatabaseID dbId) {
|
||||
return getDatabase(dbId, true);
|
||||
}
|
||||
|
||||
private GridDatabase getDatabase(DatabaseID dbId, boolean notify) {
|
||||
// look up the database in the map
|
||||
GridDatabase db = this.dbMap.get(dbId);
|
||||
|
||||
|
@ -854,12 +861,14 @@ public class GridParmManager {
|
|||
ServerResponse<GridDatabase> status = createDB(dbId);
|
||||
if (status.isOkay()) {
|
||||
db = status.getPayload();
|
||||
createDbNotification(Arrays.asList(dbId), null);
|
||||
}
|
||||
}
|
||||
|
||||
if (db != null) {
|
||||
this.addDB(db);
|
||||
if (notify) {
|
||||
createDbNotification(Arrays.asList(dbId), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1220,11 +1229,6 @@ public class GridParmManager {
|
|||
ClusterTask ct = ClusterLockUtils.lookupLock(SMART_INIT_TASK_NAME,
|
||||
SMART_INIT_TASK_DETAILS + siteID);
|
||||
|
||||
// TODO: reconsider this as changes to localConfig may change what
|
||||
// smartInits should be run
|
||||
// TODO: re-enable check
|
||||
// if ((ct.getLastExecution() + SMART_INIT_TIMEOUT) < System
|
||||
// .currentTimeMillis()) {
|
||||
ct = ClusterLockUtils
|
||||
.lock(SMART_INIT_TASK_NAME, SMART_INIT_TASK_DETAILS
|
||||
+ siteID, SMART_INIT_TIMEOUT, false);
|
||||
|
@ -1507,25 +1511,7 @@ public class GridParmManager {
|
|||
|
||||
ServerResponse<GridDatabase> sr = new ServerResponse<GridDatabase>();
|
||||
for (DatabaseID dbId : invChanged.getAdditions()) {
|
||||
// TODO: This is pretty much just a duplicate of what's in
|
||||
// getDatabase.
|
||||
// Verify this works and then remove this commented code
|
||||
|
||||
// if (dbId.getDbType().equals("D2D")) {
|
||||
// String d2dModelName = config.d2dModelNameMapping(dbId
|
||||
// .getModelName());
|
||||
// D2DGridDatabase db = D2DGridDatabase.getDatabase(config,
|
||||
// d2dModelName, dbId.getModelDate());
|
||||
// if (db != null) {
|
||||
// this.addDB(db);
|
||||
// }
|
||||
// statusHandler
|
||||
// .info("handleGfeNotification new D2D database: "
|
||||
// + dbId);
|
||||
// } else {
|
||||
// sr = this.createDB(dbId);
|
||||
// }
|
||||
this.getDatabase(dbId);
|
||||
this.getDatabase(dbId, false);
|
||||
}
|
||||
if (!sr.isOkay()) {
|
||||
statusHandler.error("Error updating GridParmManager: "
|
||||
|
@ -1584,40 +1570,18 @@ public class GridParmManager {
|
|||
}
|
||||
}
|
||||
|
||||
DatabaseID satDbid = D2DSatDatabase.getDbId(siteID);
|
||||
|
||||
// TODO why are we processing adds in a purge method. We should get adds
|
||||
// via other means
|
||||
// Verify and remove the commented code
|
||||
// List<DatabaseID> added = new ArrayList<DatabaseID>(newInventory);
|
||||
// added.removeAll(currentInventory);
|
||||
// Iterator<DatabaseID> iter = added.iterator();
|
||||
// while (iter.hasNext()) {
|
||||
// DatabaseID dbid = iter.next();
|
||||
// // remove satellite database and non-D2D databases from adds
|
||||
// if (!dbid.getDbType().equals("D2D") || dbid.equals(satDbid)) {
|
||||
// iter.remove();
|
||||
// } else {
|
||||
// // add the new database
|
||||
// try {
|
||||
// D2DGridDatabase db = new D2DGridDatabase(config, dbid);
|
||||
// addDB(db);
|
||||
// statusHandler.info("d2dGridDataPurged new D2D database: "
|
||||
// + dbid);
|
||||
// } catch (Exception e) {
|
||||
// statusHandler.handle(Priority.PROBLEM,
|
||||
// e.getLocalizedMessage(), e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
List<DatabaseID> deleted = new ArrayList<DatabaseID>(currentInventory);
|
||||
deleted.removeAll(newInventory);
|
||||
|
||||
// don't delete NetCDF and satellite databases.
|
||||
deleted.removeAll(NetCDFDatabaseManager.getDatabaseIds(siteID));
|
||||
deleted.remove(D2DSatDatabase.getDbId(siteID));
|
||||
|
||||
Iterator<DatabaseID> iter = deleted.iterator();
|
||||
while (iter.hasNext()) {
|
||||
DatabaseID dbid = iter.next();
|
||||
// remove satellite database and non-D2D databases from deletes
|
||||
if (!dbid.getDbType().equals("D2D") || dbid.equals(satDbid)) {
|
||||
// don't delete non-D2D databases
|
||||
if (!dbid.getDbType().equals("D2D")) {
|
||||
iter.remove();
|
||||
} else {
|
||||
// remove the database
|
||||
|
@ -1628,9 +1592,6 @@ public class GridParmManager {
|
|||
}
|
||||
}
|
||||
|
||||
// if ((added.size() > 0) || (deleted.size() > 0)) {
|
||||
// DBInvChangeNotification changed = new DBInvChangeNotification(
|
||||
// added, deleted, siteID);
|
||||
if (deleted.size() > 0) {
|
||||
DBInvChangeNotification changed = new DBInvChangeNotification(null,
|
||||
deleted, siteID);
|
||||
|
|
|
@ -115,6 +115,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException;
|
|||
* data in postgres for the desired model/reftime
|
||||
* 04/17/2014 #2934 dgilling Change getGridParmInfo to use D2DParm's GridParmInfo.
|
||||
* 05/22/2014 #3071 randerso Improved error logging
|
||||
* 06/24/2014 #3317 randerso Don't allow database to be created if it exceeds D2DDBVERSIONS and
|
||||
* should be purged.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -177,8 +179,9 @@ public class D2DGridDatabase extends VGridDatabase {
|
|||
String d2dModelName, Date refTime) {
|
||||
try {
|
||||
GFED2DDao dao = new GFED2DDao();
|
||||
// TODO create query for single refTime
|
||||
List<Date> result = dao.getModelRunTimes(d2dModelName, -1);
|
||||
int dbVersions = config.desiredDbVersions(getDbId(d2dModelName,
|
||||
refTime, config));
|
||||
List<Date> result = dao.getModelRunTimes(d2dModelName, dbVersions);
|
||||
|
||||
if (result.contains(refTime)) {
|
||||
D2DGridDatabase db = new D2DGridDatabase(config, d2dModelName,
|
||||
|
|
|
@ -41,6 +41,7 @@ import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* May 7, 2008 njensen Initial creation
|
||||
* Jun 13, 2013 #2044 randerso Refactored to use IFPServer
|
||||
* Jul 28, 2014 RM 15655 ryu Negate raising exception for empty db in constructor
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -88,7 +89,6 @@ public class IFPDB {
|
|||
}
|
||||
} else {
|
||||
this.keys = Collections.emptyList();
|
||||
throw new GfeException(sr.message());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ except:
|
|||
import numpy
|
||||
import JUtil
|
||||
|
||||
from java.lang import System
|
||||
from java.util import ArrayList
|
||||
from java.util import LinkedHashMap
|
||||
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DFloat
|
||||
|
@ -88,6 +89,7 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
|
|||
# 02/04/14 17042 ryu Check in changes for randerso.
|
||||
# 04/03/2014 2737 randerso Allow iscMosaic to blankOtherPeriods even when no grids received
|
||||
# 04/11/2014 17242 David Gillingham (code checked in by zhao)
|
||||
# 07/22/2014 17484 randerso Update cluster lock time to prevent time out
|
||||
#
|
||||
|
||||
BATCH_DELAY = 0.0
|
||||
|
@ -727,6 +729,9 @@ class IscMosaic:
|
|||
|
||||
# process incoming grids
|
||||
for i in xrange(len(inTimes)):
|
||||
# update cluster lock time to avoid time out
|
||||
ClusterLockUtils.updateLockTime("ISC Write Lock", parmName ,System.currentTimeMillis())
|
||||
|
||||
# Put in a delay so we don't hammer the server so hard.
|
||||
if self.__gridDelay > 0.0:
|
||||
time.sleep(self.__gridDelay)
|
||||
|
|
|
@ -57,6 +57,7 @@ import com.raytheon.uf.common.util.mapping.MultipleMappingException;
|
|||
* Oct 14, 2013 2473 bsteffen Remove lookup of deprecated grib files.
|
||||
* Apr 25, 2014 2874 bsteffen Add processType
|
||||
* Jul 02, 2014 3230 rferrel Recursively get model files in initModelList.
|
||||
* Jul 30, 2014 3455 bsteffen Allow model matching with no grid defined.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
|
@ -149,6 +150,9 @@ public class GribModelLookup {
|
|||
return model;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String key = toKey(center, subcenter, null, process, processType);
|
||||
return models.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -2849,7 +2849,6 @@
|
|||
<name>HPCGuide</name>
|
||||
<center>7</center>
|
||||
<subcenter>5</subcenter>
|
||||
<grid>197</grid>
|
||||
<process>
|
||||
<id>183</id>
|
||||
</process>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<subGridDef>
|
||||
<modelNames>HPCGuide</modelNames>
|
||||
<referenceGrid>197</referenceGrid>
|
||||
<nx>1000</nx>
|
||||
<ny>689</ny>
|
||||
<!--
|
||||
<centerLatitude>46.0</centerLatitude>
|
||||
<centerLongitude>-95.5</centerLongitude>
|
||||
-->
|
||||
</subGridDef>
|
|
@ -25,6 +25,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import com.raytheon.edex.plugin.shef.util.SHEFDate;
|
||||
import com.raytheon.edex.plugin.shef.util.ShefParm;
|
||||
import com.raytheon.uf.common.dataplugin.shef.tables.IngestfilterId;
|
||||
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode;
|
||||
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode.Duration;
|
||||
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode.Extremum;
|
||||
|
@ -47,6 +48,7 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
|
|||
* 03/19/08 387 M. Duff Initial creation.
|
||||
* 10/16/2008 1548 jelkins Integrated ParameterCode Types
|
||||
* 04/29/2014 3088 mpduff cleanup.
|
||||
* 06/26/2014 3321 mpduff Added ingestfilter primary key getter.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
|
@ -805,14 +807,30 @@ public class ShefData implements ISerializableObject {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPeTsE() {
|
||||
public String getPeDTsE() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.getPhysicalElement().getCode());
|
||||
sb.append(this.getTypeSource().getCode());
|
||||
sb.append(this.getExtremum().getCode());
|
||||
sb.append(this.getDurationCodeVariable());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ingest filter table primary key value for this data object.
|
||||
*
|
||||
* @return The primary key object
|
||||
*/
|
||||
public IngestfilterId getIngestFilterKey() {
|
||||
IngestfilterId id = new IngestfilterId();
|
||||
id.setLid(this.getLocationId());
|
||||
id.setDur(this.getDurationValue());
|
||||
id.setExtremum(this.getExtremum().getCode());
|
||||
id.setPe(this.getPhysicalElement().getCode());
|
||||
id.setTs(this.getTypeSource().getCode());
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param element
|
||||
|
@ -885,5 +903,4 @@ public class ShefData implements ISerializableObject {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
|||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 04/21/2008 387 M. Duff Initial Version.
|
||||
* 04/21/2008 387 M. Duff Initial Version.
|
||||
* 06/02/2008 1166 M. Duff Added checks for null data objects.
|
||||
* 22Jul2008 1277 MW Fegan Use CoreDao in checkIngest().
|
||||
* 10/16/2008 1548 jelkins Integrated ParameterCode Types and misc fixes
|
||||
|
@ -125,6 +125,9 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
|||
* May 14, 2014 2536 bclement removed TimeTools usage
|
||||
* 05/28/2014 3222 mpduff Fix posting time to be processed time so db doesn't show all post times the same
|
||||
* 06/02/2014 mpduff Fix for caching of range checks.
|
||||
* 06/26/2014 3321 mpduff Fix ingestSwitchMap checks
|
||||
* 07/10/2014 3370 mpduff Fix update/insert issue for riverstatus
|
||||
* 07/14/2014 mpduff Fix data range checks
|
||||
* </pre>
|
||||
*
|
||||
* @author mduff
|
||||
|
@ -230,7 +233,7 @@ public class PostShef {
|
|||
private Map<String, ShefAdjustFactor> adjustmentMap = new HashMap<String, ShefAdjustFactor>();
|
||||
|
||||
/** Map of location identifier to IngestSwitch */
|
||||
private Map<String, IngestSwitch> ingestSwitchMap = new HashMap<String, IngestSwitch>();
|
||||
private Map<IngestfilterId, IngestSwitch> ingestSwitchMap = new HashMap<IngestfilterId, IngestSwitch>();
|
||||
|
||||
// AppsDefaults tokens
|
||||
private String undefStation;
|
||||
|
@ -276,9 +279,6 @@ public class PostShef {
|
|||
/** Basis time TimeStamp */
|
||||
private java.sql.Timestamp basisTimeAnsi = new Timestamp(basisBeginTime);
|
||||
|
||||
/** River status update flag. update if true */
|
||||
private boolean riverStatusUpdateFlag = true;
|
||||
|
||||
/** river status update query value */
|
||||
private boolean riverStatusUpdateValueFlag;
|
||||
|
||||
|
@ -297,39 +297,12 @@ public class PostShef {
|
|||
/** Forecast query results */
|
||||
private Object[] queryForecastResults;
|
||||
|
||||
/** Location range data found flag */
|
||||
private boolean locRangeFound = false;
|
||||
|
||||
/** Default range data found flag */
|
||||
private boolean defRangeFound = false;
|
||||
/** Cache of data limits and loc data limits */
|
||||
private Map<String, ShefRangeData> dataRangeMap = new HashMap<String, ShefRangeData>();
|
||||
|
||||
/** Valid date range flag */
|
||||
private boolean validDateRange = false;
|
||||
|
||||
/** Gross range minimum value */
|
||||
private double grossRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Gross range maximum value */
|
||||
private double grossRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Reasonable range minimum value */
|
||||
private double reasonRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Reasonable range maximum value */
|
||||
private double reasonRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Alert upper limit value */
|
||||
private double alertUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Alarm upper limit value */
|
||||
private double alarmUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Alert lower limit value */
|
||||
private double alertLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/** Alarm lower limit value */
|
||||
private double alarmLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param date
|
||||
|
@ -531,7 +504,7 @@ public class PostShef {
|
|||
if (dataLog) {
|
||||
log.info(LOG_SEP);
|
||||
log.info("Posting process started for LID [" + locId
|
||||
+ "] PEDTSEP [" + data.getPeTsE() + "] value ["
|
||||
+ "] PEDTSEP [" + data.getPeDTsE() + "] value ["
|
||||
+ dataValue + "]");
|
||||
}
|
||||
|
||||
|
@ -652,7 +625,7 @@ public class PostShef {
|
|||
if (Location.LOC_LOCATION.equals(postLocData)
|
||||
|| (Location.LOC_GEOAREA.equals(postLocData))) {
|
||||
if (!DataType.CONTINGENCY.equals(dataType)) {
|
||||
ingestSwitch = checkIngest(locId, data, ingestSwitch);
|
||||
ingestSwitch = checkIngest(locId, data);
|
||||
}
|
||||
if (ShefConstants.IngestSwitch.POST_PE_OFF
|
||||
.equals(ingestSwitch)) {
|
||||
|
@ -1109,23 +1082,12 @@ public class PostShef {
|
|||
// Reset .E cache vars
|
||||
tsList.clear();
|
||||
useLatest = MISSING;
|
||||
riverStatusUpdateFlag = true;
|
||||
qualityCheckFlag = true;
|
||||
useTs = null;
|
||||
basisTimeValues = null;
|
||||
previousQueryForecast = null;
|
||||
locRangeFound = false;
|
||||
defRangeFound = false;
|
||||
dataRangeMap.clear();
|
||||
validDateRange = false;
|
||||
grossRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
grossRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
reasonRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
reasonRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
alertUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
alarmUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
alertLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
alarmLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1450,15 +1412,7 @@ public class PostShef {
|
|||
if ((shefList != null) && (shefList.size() > 0)) {
|
||||
ShefData maxShefDataValue = findMaxFcst(shefList);
|
||||
|
||||
if (shefRecord.getShefType() == ShefType.E) {
|
||||
if (riverStatusUpdateFlag) {
|
||||
riverStatusUpdateFlag = false;
|
||||
|
||||
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
||||
}
|
||||
} else {
|
||||
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
||||
}
|
||||
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
||||
postTables.postRiverStatus(shefRecord, maxShefDataValue,
|
||||
riverStatusUpdateValueFlag);
|
||||
} else {
|
||||
|
@ -2127,8 +2081,7 @@ public class PostShef {
|
|||
* ingest switch setting
|
||||
* @return
|
||||
*/
|
||||
private IngestSwitch checkIngest(String locId, ShefData data,
|
||||
ShefConstants.IngestSwitch ingestSwitch) {
|
||||
private IngestSwitch checkIngest(String locId, ShefData data) {
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
boolean matchFound = false;
|
||||
int hNum = 0;
|
||||
|
@ -2154,13 +2107,16 @@ public class PostShef {
|
|||
String telem = null;
|
||||
String sql = null;
|
||||
Object[] oa = null;
|
||||
String key = locId + data.getPeTsE();
|
||||
|
||||
IngestfilterId key = data.getIngestFilterKey();// .getPeDTsE();
|
||||
|
||||
// Default to off
|
||||
ShefConstants.IngestSwitch ingestSwitch = IngestSwitch.POST_PE_OFF;
|
||||
|
||||
try {
|
||||
if (!ingestSwitchMap.containsKey(key)) {
|
||||
errorMsg.append("Error getting connection to IHFS Database");
|
||||
sql = "select lid, pe, dur, ts, extremum, ts_rank, ingest, ofs_input, stg2_input from IngestFilter where lid = '"
|
||||
+ locId + "'";
|
||||
errorMsg.setLength(0);
|
||||
errorMsg.append("Error requesting IngestFilter data: " + sql);
|
||||
oa = dao.executeSQLQuery(sql);
|
||||
if (oa.length > 0) {
|
||||
|
@ -2445,7 +2401,7 @@ public class PostShef {
|
|||
if (!matchFound) {
|
||||
log.warn(locId + " - " + data.getPhysicalElement() + "("
|
||||
+ data.getDuration() + ")" + data.getTypeSource()
|
||||
+ data.getExtremum() + " ingest " + "filter not defined");
|
||||
+ data.getExtremum() + " ingest filter not defined");
|
||||
stats.incrementWarningMessages();
|
||||
ingestSwitch = ShefConstants.IngestSwitch.POST_PE_OFF;
|
||||
}
|
||||
|
@ -2648,24 +2604,12 @@ public class PostShef {
|
|||
return ShefConstants.QC_MANUAL_FAILED;
|
||||
}
|
||||
|
||||
boolean executeQuery = true;
|
||||
if (!qualityCheckFlag) {
|
||||
// If qualityCheckFlag is false the the query has already been
|
||||
// executed
|
||||
executeQuery = false;
|
||||
}
|
||||
|
||||
if (shefRecord.getShefType() == ShefType.E) {
|
||||
// if qualityCheckFlag is true then don't need to query
|
||||
if (qualityCheckFlag) {
|
||||
qualityCheckFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder locLimitSql = new StringBuilder();
|
||||
StringBuilder defLimitSql = new StringBuilder();
|
||||
String key = lid + data.getPhysicalElement().getCode()
|
||||
+ data.getDurationValue();
|
||||
try {
|
||||
if (executeQuery) {
|
||||
if (!dataRangeMap.containsKey(key)) {
|
||||
String sqlStart = "select monthdaystart, monthdayend, gross_range_min, gross_range_max, reason_range_min, "
|
||||
+ "reason_range_max, roc_max, alert_upper_limit, alert_roc_limit, alarm_upper_limit, "
|
||||
+ "alarm_roc_limit, alert_lower_limit, alarm_lower_limit, alert_diff_limit, "
|
||||
|
@ -2681,6 +2625,7 @@ public class PostShef {
|
|||
Object[] oa = dao.executeSQLQuery(locLimitSql.toString());
|
||||
|
||||
if (oa.length == 0) {
|
||||
dataRangeMap.put(key, null);
|
||||
// default range
|
||||
defLimitSql = new StringBuilder(sqlStart);
|
||||
defLimitSql.append("datalimits where pe = '")
|
||||
|
@ -2689,7 +2634,13 @@ public class PostShef {
|
|||
.append(data.getDurationValue());
|
||||
|
||||
oa = dao.executeSQLQuery(defLimitSql.toString());
|
||||
key = data.getPhysicalElement().getCode()
|
||||
+ data.getDurationValue();
|
||||
if (oa.length == 0) {
|
||||
dataRangeMap.put(key, null);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < oa.length; i++) {
|
||||
Object[] oa2 = (Object[]) oa[i];
|
||||
|
||||
|
@ -2706,49 +2657,65 @@ public class PostShef {
|
|||
* if a range is found, then check the value and set the
|
||||
* flag
|
||||
*/
|
||||
grossRangeMin = ShefUtil.getDouble(oa2[2], missing);
|
||||
grossRangeMax = ShefUtil.getDouble(oa2[3], missing);
|
||||
reasonRangeMin = ShefUtil.getDouble(oa2[4], missing);
|
||||
reasonRangeMax = ShefUtil.getDouble(oa2[5], missing);
|
||||
alertUpperLimit = ShefUtil.getDouble(oa2[7], missing);
|
||||
alertLowerLimit = ShefUtil.getDouble(oa2[11], missing);
|
||||
alarmLowerLimit = ShefUtil.getDouble(oa2[12], missing);
|
||||
alarmUpperLimit = ShefUtil.getDouble(oa2[9], missing);
|
||||
defRangeFound = true;
|
||||
ShefRangeData rangeData = new ShefRangeData();
|
||||
rangeData.setGrossRangeMin(ShefUtil.getDouble(oa2[2],
|
||||
missing));
|
||||
rangeData.setGrossRangeMax(ShefUtil.getDouble(oa2[3],
|
||||
missing));
|
||||
rangeData.setReasonRangeMin(ShefUtil.getDouble(oa2[4],
|
||||
missing));
|
||||
rangeData.setReasonRangeMax(ShefUtil.getDouble(oa2[5],
|
||||
missing));
|
||||
rangeData.setAlarmLowerLimit(ShefUtil.getDouble(
|
||||
oa2[12], missing));
|
||||
rangeData.setAlarmUpperLimit(ShefUtil.getDouble(oa2[9],
|
||||
missing));
|
||||
rangeData.setAlertLowerLimit(ShefUtil.getDouble(
|
||||
oa2[11], missing));
|
||||
rangeData.setAlertUpperLimit(ShefUtil.getDouble(oa2[7],
|
||||
missing));
|
||||
this.dataRangeMap.put(key, rangeData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locRangeFound || defRangeFound) {
|
||||
ShefRangeData rangeData = dataRangeMap.get(key);
|
||||
if (rangeData != null) {
|
||||
/*
|
||||
* if a range is found, then check the value and set the flag
|
||||
*/
|
||||
if (((grossRangeMin != missing) && (dValue < grossRangeMin))
|
||||
|| ((grossRangeMax != missing) && (dValue > grossRangeMax))) {
|
||||
if (((rangeData.getGrossRangeMin() != missing) && (dValue < rangeData
|
||||
.getGrossRangeMin()))
|
||||
|| ((rangeData.getGrossRangeMax() != missing) && (dValue > rangeData
|
||||
.getGrossRangeMax()))) {
|
||||
qualityCode = ShefQC.setQcCode(
|
||||
(int) ShefConstants.QC_GROSSRANGE_FAILED,
|
||||
qualityCode);
|
||||
|
||||
if (dataLog) {
|
||||
log.info(lid + " failed gross range check: " + dValue
|
||||
+ " out of range " + grossRangeMin + " - "
|
||||
+ grossRangeMax);
|
||||
+ " out of range "
|
||||
+ rangeData.getGrossRangeMin() + " - "
|
||||
+ rangeData.getGrossRangeMax());
|
||||
}
|
||||
|
||||
/*
|
||||
* don't do anything if it fails the gross range check
|
||||
*/
|
||||
} else {
|
||||
if (((reasonRangeMin != missing) && (dValue < reasonRangeMin))
|
||||
|| ((reasonRangeMax != missing) && (dValue > reasonRangeMax))) {
|
||||
if (((rangeData.getReasonRangeMin() != missing) && (dValue < rangeData
|
||||
.getReasonRangeMin()))
|
||||
|| ((rangeData.getReasonRangeMax() != missing) && (dValue > rangeData
|
||||
.getReasonRangeMax()))) {
|
||||
qualityCode = ShefQC.setQcCode(
|
||||
(int) ShefConstants.QC_REASONRANGE_FAILED,
|
||||
qualityCode);
|
||||
if (dataLog) {
|
||||
log.info(lid + " failed reasonable range check: "
|
||||
+ dValue + " out of range "
|
||||
+ reasonRangeMin + " - " + reasonRangeMax);
|
||||
+ rangeData.getReasonRangeMin() + " - "
|
||||
+ rangeData.getReasonRangeMax());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2758,17 +2725,17 @@ public class PostShef {
|
|||
* table.
|
||||
*/
|
||||
if (shefAlertAlarm) {
|
||||
if ((alarmUpperLimit != missing)
|
||||
&& (dValue >= alarmUpperLimit)) {
|
||||
if ((rangeData.getAlarmUpperLimit() != missing)
|
||||
&& (dValue >= rangeData.getAlarmUpperLimit())) {
|
||||
alertAlarm = ShefConstants.ALARM_UPPER_DETECTED;
|
||||
} else if ((alertUpperLimit != missing)
|
||||
&& (dValue >= alertUpperLimit)) {
|
||||
} else if ((rangeData.getAlertUpperLimit() != missing)
|
||||
&& (dValue >= rangeData.getAlertUpperLimit())) {
|
||||
alertAlarm = ShefConstants.ALERT_UPPER_DETECTED;
|
||||
} else if ((alarmLowerLimit != missing)
|
||||
&& (dValue <= alarmLowerLimit)) {
|
||||
} else if ((rangeData.getAlarmLowerLimit() != missing)
|
||||
&& (dValue <= rangeData.getAlarmLowerLimit())) {
|
||||
alertAlarm = ShefConstants.ALARM_LOWER_DETECTED;
|
||||
} else if ((alertLowerLimit != missing)
|
||||
&& (dValue <= alertLowerLimit)) {
|
||||
} else if ((rangeData.getAlertLowerLimit() != missing)
|
||||
&& (dValue <= rangeData.getAlertLowerLimit())) {
|
||||
alertAlarm = ShefConstants.ALERT_LOWER_DETECTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* 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.edex.plugin.shef.database;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.shef.util.ShefConstants;
|
||||
|
||||
/**
|
||||
* Data object for holding SHEF range limits
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 14, 2014 mpduff Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mpduff
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ShefRangeData {
|
||||
|
||||
private double grossRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double grossRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double reasonRangeMin = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double reasonRangeMax = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double alertUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double alarmUpperLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double alertLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
private double alarmLowerLimit = ShefConstants.SHEF_MISSING_INT;
|
||||
|
||||
/**
|
||||
* @return the grossRangeMin
|
||||
*/
|
||||
public double getGrossRangeMin() {
|
||||
return grossRangeMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grossRangeMin
|
||||
* the grossRangeMin to set
|
||||
*/
|
||||
public void setGrossRangeMin(double grossRangeMin) {
|
||||
this.grossRangeMin = grossRangeMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the grossRangeMax
|
||||
*/
|
||||
public double getGrossRangeMax() {
|
||||
return grossRangeMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grossRangeMax
|
||||
* the grossRangeMax to set
|
||||
*/
|
||||
public void setGrossRangeMax(double grossRangeMax) {
|
||||
this.grossRangeMax = grossRangeMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reasonRangeMin
|
||||
*/
|
||||
public double getReasonRangeMin() {
|
||||
return reasonRangeMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reasonRangeMin
|
||||
* the reasonRangeMin to set
|
||||
*/
|
||||
public void setReasonRangeMin(double reasonRangeMin) {
|
||||
this.reasonRangeMin = reasonRangeMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reasonRangeMax
|
||||
*/
|
||||
public double getReasonRangeMax() {
|
||||
return reasonRangeMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reasonRangeMax
|
||||
* the reasonRangeMax to set
|
||||
*/
|
||||
public void setReasonRangeMax(double reasonRangeMax) {
|
||||
this.reasonRangeMax = reasonRangeMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alertUpperLimit
|
||||
*/
|
||||
public double getAlertUpperLimit() {
|
||||
return alertUpperLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alertUpperLimit
|
||||
* the alertUpperLimit to set
|
||||
*/
|
||||
public void setAlertUpperLimit(double alertUpperLimit) {
|
||||
this.alertUpperLimit = alertUpperLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alarmUpperLimit
|
||||
*/
|
||||
public double getAlarmUpperLimit() {
|
||||
return alarmUpperLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alarmUpperLimit
|
||||
* the alarmUpperLimit to set
|
||||
*/
|
||||
public void setAlarmUpperLimit(double alarmUpperLimit) {
|
||||
this.alarmUpperLimit = alarmUpperLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alertLowerLimit
|
||||
*/
|
||||
public double getAlertLowerLimit() {
|
||||
return alertLowerLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alertLowerLimit
|
||||
* the alertLowerLimit to set
|
||||
*/
|
||||
public void setAlertLowerLimit(double alertLowerLimit) {
|
||||
this.alertLowerLimit = alertLowerLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alarmLowerLimit
|
||||
*/
|
||||
public double getAlarmLowerLimit() {
|
||||
return alarmLowerLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alarmLowerLimit
|
||||
* the alarmLowerLimit to set
|
||||
*/
|
||||
public void setAlarmLowerLimit(double alarmLowerLimit) {
|
||||
this.alarmLowerLimit = alarmLowerLimit;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,7 +47,7 @@
|
|||
<parameter>zAGL</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits>dam</displayUnits>
|
||||
<displayUnits>ft</displayUnits>
|
||||
<contourLabeling labelSpacing="4" labelFormat="#">
|
||||
<increment>50</increment>
|
||||
</contourLabeling>
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
<parameter>Topo</parameter>
|
||||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>km</displayUnits>
|
||||
<displayUnits>ft</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
</imageStyle>
|
||||
</styleRule>
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
|||
* --/--/---- Initial creation
|
||||
* 10/22/2013 2361 njensen Use JAXBManager for XML
|
||||
* Apr 28, 2014 3033 jsanchez Refactored file retrieval.
|
||||
* Jul 02, 2014 DR 17450 D. Friedman Support using list of templates from backup site.
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
|
@ -91,6 +92,18 @@ public class DialogConfiguration {
|
|||
return (DialogConfiguration) jaxb.unmarshalFromXml(xml);
|
||||
}
|
||||
|
||||
public static DialogConfiguration loadDialogConfigNoUser(String site)
|
||||
throws FileNotFoundException, IOException, JAXBException {
|
||||
String xml = WarnFileUtil.convertFileContentsToStringNoUser(
|
||||
CONFIG_FILE, site);
|
||||
return (DialogConfiguration) jaxb.unmarshalFromXml(xml);
|
||||
}
|
||||
|
||||
public static boolean isSiteDialogConfigExtant(String backupSite) {
|
||||
return WarnFileUtil.isLocalizationFileExtantAtSiteLevel(CONFIG_FILE,
|
||||
backupSite);
|
||||
}
|
||||
|
||||
public String getWarngenOfficeShort() {
|
||||
return warngenOfficeShort;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,18 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 28, 2014 3033 jsanchez Searches the backup site directory before the localized site directory.
|
||||
* Jul 02, 2014 DR 17450 D. Friedman Support using list of templates from backup site.
|
||||
* </pre>
|
||||
*
|
||||
* @author jsanchez
|
||||
* @version 1.0
|
||||
*/
|
||||
public class WarnFileUtil {
|
||||
public static LocalizationFile findFileInLocalizationIncludingBackupSite(String filename,
|
||||
String issuingSiteID, String backupSiteID) throws FileNotFoundException {
|
||||
return findFileInLocalizationIncludingBackupSite(filename, issuingSiteID, backupSiteID, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate file in localization. If a backupSiteID is not
|
||||
* null and a corresponding file does exist in the backup site directory,
|
||||
|
@ -49,7 +55,7 @@ public class WarnFileUtil {
|
|||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static LocalizationFile findFileInLocalizationIncludingBackupSite(String filename,
|
||||
String issuingSiteID, String backupSiteID)
|
||||
String issuingSiteID, String backupSiteID, boolean allowUser)
|
||||
throws FileNotFoundException {
|
||||
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
|
@ -71,6 +77,9 @@ public class WarnFileUtil {
|
|||
LocalizationContext[] searchContext = pm
|
||||
.getLocalSearchHierarchy(LocalizationType.COMMON_STATIC);
|
||||
for (LocalizationContext ctx : searchContext) {
|
||||
if (!allowUser && ctx.getLocalizationLevel() == LocalizationLevel.USER)
|
||||
continue;
|
||||
|
||||
if ((ctx.getLocalizationLevel() == LocalizationLevel.SITE || ctx
|
||||
.getLocalizationLevel() == LocalizationLevel.CONFIGURED)
|
||||
&& issuingSiteID != null) {
|
||||
|
@ -90,6 +99,18 @@ public class WarnFileUtil {
|
|||
return fileToUse;
|
||||
}
|
||||
|
||||
public static boolean isLocalizationFileExtantAtSiteLevel(String filename, String siteID) {
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
String fileToRetrieve = WarningConstants.WARNGEN_DIR
|
||||
+ IPathManager.SEPARATOR + filename;
|
||||
LocalizationContext backupSiteCtx = pm.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE);
|
||||
backupSiteCtx.setContextName(siteID);
|
||||
LocalizationFile backupFile = pm.getLocalizationFile(backupSiteCtx,
|
||||
fileToRetrieve);
|
||||
return backupFile != null && backupFile.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the appropriate file in the localization hierarchy including the
|
||||
* backupSite directory (if provided) and converts the content of the file
|
||||
|
@ -105,10 +126,20 @@ public class WarnFileUtil {
|
|||
public static String convertFileContentsToString(String filename,
|
||||
String localizedSite, String backupSite)
|
||||
throws FileNotFoundException, IOException {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
BufferedReader input = null;
|
||||
File file = findFileInLocalizationIncludingBackupSite(filename, localizedSite, backupSite)
|
||||
.getFile();
|
||||
return convertFileContentsToString(file);
|
||||
}
|
||||
|
||||
public static String convertFileContentsToStringNoUser(String filename,
|
||||
String site) throws FileNotFoundException {
|
||||
File file = findFileInLocalizationIncludingBackupSite(filename, site, null, false).getFile();
|
||||
return convertFileContentsToString(file);
|
||||
}
|
||||
|
||||
private static String convertFileContentsToString(File file) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
input = new BufferedReader(new FileReader(file));
|
||||
|
||||
|
|
|
@ -189,33 +189,35 @@ ${drainage.name}##
|
|||
########END MACRO
|
||||
|
||||
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||
#set($torWatches = ${watches.getTorWatches()})
|
||||
#set($torWatchAlso = "")
|
||||
#set($torWatchFirst = 1)
|
||||
#foreach(${watch} in ${torWatches})
|
||||
#if($torWatchFirst)
|
||||
#set($torWatchFirst = 0)
|
||||
#else
|
||||
##
|
||||
#set($tornadoWatches = [])
|
||||
#foreach(${watch} in ${watches})
|
||||
#if(${watch.getPhenSig()} == 'TO.A')
|
||||
#set($success = $tornadoWatches.add($watch))
|
||||
#set($endTime = ${watch.endTime})
|
||||
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||
#set($latestEndTime = ${endTime})
|
||||
#end
|
||||
A TORNADO WATCH ${torWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#end
|
||||
#end
|
||||
#if(!${list.isEmpty($tornadoWatches)})
|
||||
|
||||
A TORNADO WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#if(${secondtimezone})
|
||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||
#end
|
||||
FOR ##
|
||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
||||
#set($numPortions = ${list.size(${tornadoWatches})})
|
||||
#set($count = 0)
|
||||
#foreach(${portion} in ${watch.getPortions()})
|
||||
#foreach(${watch} in ${tornadoWatches})
|
||||
#set($count = $count + 1)
|
||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
||||
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||
#if($count == $numPortions - 1)
|
||||
AND ##
|
||||
#elseif($count < $numPortions)
|
||||
...##
|
||||
#end
|
||||
#end
|
||||
#set($torWatchAlso = "ALSO ")
|
||||
. ##
|
||||
#end
|
||||
|
||||
|
@ -223,33 +225,35 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
|
|||
########END MACRO
|
||||
|
||||
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||
#set($svrWatches = ${watches.getSvrWatches()})
|
||||
#set($svrWatchAlso = "")
|
||||
#set($svrWatchFirst = 1)
|
||||
#foreach(${watch} in ${svrWatches})
|
||||
#if($svrWatchFirst)
|
||||
#set($svrWatchFirst = 0)
|
||||
#else
|
||||
##
|
||||
#set($severeWatches = [])
|
||||
#foreach(${watch} in ${watches})
|
||||
#if(${watch.getPhenSig()} == 'SV.A')
|
||||
#set($success = $severeWatches.add($watch))
|
||||
#set($endTime = ${watch.endTime})
|
||||
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||
#set($latestEndTime = ${endTime})
|
||||
#end
|
||||
A SEVERE THUNDERSTORM WATCH ${svrWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#end
|
||||
#end
|
||||
#if(!${list.isEmpty($severeWatches)})
|
||||
|
||||
A SEVERE THUNDERSTORM WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||
#if(${secondtimezone})
|
||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||
#end
|
||||
FOR ##
|
||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
||||
#set($numPortions = ${list.size(${severeWatches})})
|
||||
#set($count = 0)
|
||||
#foreach(${portion} in ${watch.getPortions()})
|
||||
#foreach(${watch} in ${severeWatches})
|
||||
#set($count = $count + 1)
|
||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
||||
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||
#if($count == $numPortions - 1)
|
||||
AND ##
|
||||
#elseif($count < $numPortions)
|
||||
...##
|
||||
#end
|
||||
#end
|
||||
#set($svrWatchAlso = "ALSO ")
|
||||
. ##
|
||||
#end
|
||||
|
||||
|
@ -368,18 +372,6 @@ SOUTH##
|
|||
#if(${list.contains($directionSet, "WEST")})
|
||||
#set($output = "${output}WEST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "NE")})
|
||||
#set($output = "${output}NORTHEAST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "NW")})
|
||||
#set($output = "${output}NORTHWEST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "SE")})
|
||||
#set($output = "${output}SOUTHEAST")
|
||||
#end
|
||||
#if(${list.contains($directionSet, "SW")})
|
||||
#set($output = "${output}SOUTHWEST")
|
||||
#end
|
||||
#if(${useCentral} && ${list.contains($directionSet, "CENTRAL")})
|
||||
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
||||
#set($output = "${output} ")
|
||||
|
|
|
@ -119,11 +119,11 @@ FOR THE FOLLOWING THREATS...
|
|||
## If sites do not want watches in their AWW product comment out the
|
||||
## section below
|
||||
#######################################################################
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -48,11 +48,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -59,11 +59,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<enableDamBreakThreat>true</enableDamBreakThreat>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>.
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
-->
|
||||
|
||||
|
|
|
@ -191,10 +191,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -69,10 +69,10 @@ THIS IS A TEST MESSAGE. ##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -238,10 +238,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -346,10 +346,10 @@ THIS IS A TEST MESSAGE.##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -468,10 +468,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -512,10 +512,10 @@ THIS IS A TEST MESSAGE.##
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -57,11 +57,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -52,7 +52,7 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
</includedWatches>
|
||||
|
|
|
@ -67,11 +67,11 @@ Must be paired with proper vm code (also commented out in flashFloodWarning.vm)!
|
|||
<!-- <trackEnabled>true</trackEnabled> -->
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -624,12 +624,12 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#* NO NEED TO INCLUDE SVR T-STM WATCHES IN A SVR WARNING!!!!
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#
|
||||
#end
|
||||
|
|
|
@ -54,10 +54,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -290,10 +290,10 @@ ${expcanPhrase} ${addthreat}
|
|||
###########################################
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
@ -1180,7 +1180,7 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -72,8 +72,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
</phensigs>
|
||||
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<enableRestart>false</enableRestart>
|
||||
|
|
|
@ -470,10 +470,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -397,10 +397,10 @@ ${canwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -571,10 +571,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -679,10 +679,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -880,10 +880,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#elseif(${CORCAN} == "true")
|
||||
|
@ -952,10 +952,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -1142,10 +1142,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -1219,10 +1219,10 @@ ${expwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations -->
|
||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations -->
|
||||
|
|
|
@ -471,7 +471,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -58,10 +58,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -262,10 +262,10 @@ ${expcanPhrase} ${addthreat}
|
|||
###########################################
|
||||
## WATCHES ##
|
||||
#############
|
||||
###if(${list.contains(${includedWatches}, "torWatches")})
|
||||
###if(${list.contains(${includedWatches}, "TO.A")})
|
||||
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
###end
|
||||
###if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
###if(${list.contains(${includedWatches}, "SV.A")})
|
||||
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
###end
|
||||
#if(${list.contains(${bullets}, "svrboxactive")})
|
||||
|
@ -924,7 +924,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -69,8 +69,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
</phensigs>
|
||||
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<enableRestart>false</enableRestart>
|
||||
|
|
|
@ -230,11 +230,11 @@ LOCATIONS CAN EXPECT !** EXPECTED SNOW **! INCHES OF SNOW.
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
|
||||
#end
|
||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -309,10 +309,10 @@ IF ON OR NEAR !**Name Of Lake**!...GET OUT OF THE WATER AND MOVE INDOORS OR INSI
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
####################################
|
||||
|
|
|
@ -50,11 +50,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -431,10 +431,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
## WATCHES ##
|
||||
#############
|
||||
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -365,10 +365,10 @@ ${canwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -538,10 +538,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -646,10 +646,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${productClass}=="T")
|
||||
|
@ -845,10 +845,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#elseif(${CORCAN} == "true")
|
||||
|
@ -917,10 +917,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
|
||||
|
@ -1104,10 +1104,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
@ -1182,10 +1182,10 @@ ${expwarning}
|
|||
#############
|
||||
## WATCHES ##
|
||||
#############
|
||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
||||
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
||||
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -56,11 +56,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the svs -->
|
||||
|
|
|
@ -49,11 +49,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
|||
<autoLockText>true</autoLockText>
|
||||
|
||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||
included with the warning product include torWatches and/or svrWatches,
|
||||
included with the warning product include TO.A and/or SV.A,
|
||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||
<includedWatches>
|
||||
<includedWatch>torWatches</includedWatch>
|
||||
<includedWatch>svrWatches</includedWatch>
|
||||
<includedWatch>TO.A</includedWatch>
|
||||
<includedWatch>SV.A</includedWatch>
|
||||
</includedWatches>
|
||||
|
||||
<!-- durations: the list of possible durations of the warning -->
|
||||
|
|
|
@ -26,5 +26,6 @@ Require-Bundle: com.raytheon.uf.common.localization;bundle-version="1.11.1",
|
|||
com.raytheon.uf.edex.site;bundle-version="1.0.0",
|
||||
com.google.guava;bundle-version="1.0.0",
|
||||
com.raytheon.uf.edex.auth;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.serialization.comm
|
||||
com.raytheon.uf.common.serialization.comm,
|
||||
org.apache.commons.io;bundle-version="2.4.0"
|
||||
Export-Package: com.raytheon.uf.edex.activetable
|
||||
|
|
|
@ -24,14 +24,15 @@ import java.util.Arrays;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import jep.JepException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.raytheon.edex.site.SiteUtil;
|
||||
import com.raytheon.edex.util.Util;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
|
@ -49,10 +50,14 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
|
|||
import com.raytheon.uf.common.python.PyUtil;
|
||||
import com.raytheon.uf.common.python.PythonScript;
|
||||
import com.raytheon.uf.common.site.SiteMap;
|
||||
import com.raytheon.uf.common.status.IPerformanceStatusHandler;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.PerformanceStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.util.CollectionUtil;
|
||||
import com.raytheon.uf.common.time.util.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
import com.raytheon.uf.edex.core.EDEXUtil;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
|
@ -85,6 +90,9 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
|||
* clearPracticeTable().
|
||||
* May 15, 2014 3157 dgilling Add support for multiple TPC and SPC
|
||||
* issuing sites.
|
||||
* Jun 17, 2014 3296 randerso Cached PythonScript. Moved active table
|
||||
* backup and purging to a separate thread.
|
||||
* Added performance logging
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -99,9 +107,44 @@ public class ActiveTable {
|
|||
private static final Logger changeLog = Logger
|
||||
.getLogger("ActiveTableChange");
|
||||
|
||||
private static String filePath;
|
||||
private static ThreadLocal<PythonScript> threadLocalPythonScript = new ThreadLocal<PythonScript>() {
|
||||
|
||||
private static String includePath;
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.ThreadLocal#initialValue()
|
||||
*/
|
||||
@Override
|
||||
protected PythonScript initialValue() {
|
||||
try {
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext commonCx = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
String filePath = pathMgr.getFile(commonCx,
|
||||
"vtec" + File.separator + "ActiveTable.py").getPath();
|
||||
String siteId = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE)
|
||||
.getContextName();
|
||||
String includePath = PyUtil.buildJepIncludePath(
|
||||
ActiveTablePyIncludeUtil.getCommonPythonIncludePath(),
|
||||
ActiveTablePyIncludeUtil.getVtecIncludePath(siteId),
|
||||
ActiveTablePyIncludeUtil
|
||||
.getGfeConfigIncludePath(siteId));
|
||||
|
||||
PythonScript python = new PythonScript(filePath, includePath,
|
||||
ActiveTable.class.getClassLoader());
|
||||
timer.stop();
|
||||
PerformanceStatus.getHandler("ActiveTable").logDuration(
|
||||
"create PythonScript", timer.getElapsedTime());
|
||||
return python;
|
||||
} catch (JepException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private static CoreDao practiceDao = new CoreDao(
|
||||
DaoConfig.forClass(PracticeActiveTableRecord.class));
|
||||
|
@ -109,25 +152,9 @@ public class ActiveTable {
|
|||
private static CoreDao operationalDao = new CoreDao(
|
||||
DaoConfig.forClass(OperationalActiveTableRecord.class));
|
||||
|
||||
private PythonScript python;
|
||||
|
||||
static {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext commonCx = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
filePath = pathMgr.getFile(commonCx,
|
||||
"vtec" + File.separator + "ActiveTable.py").getPath();
|
||||
String siteId = pathMgr.getContext(LocalizationType.COMMON_STATIC,
|
||||
LocalizationLevel.SITE).getContextName();
|
||||
String pythonPath = ActiveTablePyIncludeUtil
|
||||
.getCommonPythonIncludePath();
|
||||
String vtecPath = ActiveTablePyIncludeUtil.getVtecIncludePath(siteId);
|
||||
String configPath = ActiveTablePyIncludeUtil
|
||||
.getGfeConfigIncludePath(siteId);
|
||||
includePath = PyUtil.buildJepIncludePath(pythonPath, vtecPath,
|
||||
configPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public ActiveTable() {
|
||||
}
|
||||
|
||||
|
@ -156,6 +183,10 @@ public class ActiveTable {
|
|||
* the active table mode (PRACTICE or OPERATIONAL)
|
||||
* @param phensigList
|
||||
* phensigs to include. If null, all phensigs will be included.
|
||||
* @param act
|
||||
* the VTEC action. If null all actions will be included
|
||||
* @param etn
|
||||
* the ETN. If null all ETNs will be included
|
||||
* @param requestValidTimes
|
||||
* true if only valid times are to be returned
|
||||
* @return the active table corresponding to the input parameters
|
||||
|
@ -175,6 +206,10 @@ public class ActiveTable {
|
|||
* the active table mode (PRACTICE or OPERATIONAL)
|
||||
* @param phensigList
|
||||
* phensigs to include. If null, all phensigs will be included.
|
||||
* @param act
|
||||
* the VTEC action. If null all actions will be included
|
||||
* @param etn
|
||||
* the ETN. If null all ETNs will be included
|
||||
* @param requestValidTimes
|
||||
* true if only valid times are to be returned
|
||||
* @param wfos
|
||||
|
@ -188,28 +223,18 @@ public class ActiveTable {
|
|||
String[] wfos) {
|
||||
|
||||
if (wfos == null || !Arrays.asList(wfos).contains("all")) {
|
||||
SiteMap siteMap = SiteMap.getInstance();
|
||||
|
||||
if (wfos == null || wfos.length == 0) {
|
||||
// default to WFOs from VTECPartners
|
||||
|
||||
// Use the 3-char site or VTEC_DECODER_SITES will be empty
|
||||
Set<String> site3s = siteMap.getSite3LetterIds(siteId);
|
||||
Set<String> wfoSet = new TreeSet<String>();
|
||||
for (String site3 : site3s) {
|
||||
VTECPartners vtecPartners = VTECPartners.getInstance(site3);
|
||||
List<String> wfoList = (List<String>) vtecPartners
|
||||
.getattr("VTEC_DECODER_SITES");
|
||||
wfoSet.addAll(wfoList);
|
||||
wfoSet.addAll(vtecPartners.getSpcSites());
|
||||
wfoSet.addAll(vtecPartners.getTpcSites());
|
||||
}
|
||||
Set<String> wfoSet = getDecoderSites(siteId);
|
||||
wfoSet.add(siteId);
|
||||
wfos = wfoSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
// We have an array of 3- or 4-char WFOs to filter against.
|
||||
// We need a String "KMFL,KTBW,..." for the query.
|
||||
SiteMap siteMap = SiteMap.getInstance();
|
||||
StringBuilder wfosb = new StringBuilder();
|
||||
String sep = "";
|
||||
for (String wfo : wfos) {
|
||||
|
@ -226,6 +251,26 @@ public class ActiveTable {
|
|||
false);
|
||||
}
|
||||
|
||||
private static Set<String> getDecoderSites(String siteId) {
|
||||
SiteMap siteMap = SiteMap.getInstance();
|
||||
|
||||
// Use the 3-char site or VTEC_DECODER_SITES will be empty
|
||||
Set<String> site3s = siteMap.getSite3LetterIds(siteId);
|
||||
Set<String> wfoSet = new HashSet<String>();
|
||||
for (String site3 : site3s) {
|
||||
VTECPartners vtecPartners = VTECPartners.getInstance(site3);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> wfoList = (List<String>) vtecPartners
|
||||
.getattr("VTEC_DECODER_SITES");
|
||||
wfoSet.addAll(wfoList);
|
||||
String spcSite = (String) vtecPartners.getattr("VTEC_SPC_SITE");
|
||||
wfoSet.add(spcSite);
|
||||
String tpcSite = (String) vtecPartners.getattr("VTEC_TPC_SITE");
|
||||
wfoSet.add(tpcSite);
|
||||
}
|
||||
return wfoSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the active table with the new warnings
|
||||
*
|
||||
|
@ -242,11 +287,38 @@ public class ActiveTable {
|
|||
mode = ActiveTableMode.OPERATIONAL;
|
||||
}
|
||||
|
||||
MergeResult result = filterTable(siteId,
|
||||
getActiveTable(siteId, mode), newRecords, mode, offsetSecs);
|
||||
IPerformanceStatusHandler perfStat = PerformanceStatus
|
||||
.getHandler("ActiveTable");
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
List<ActiveTableRecord> activeTable = getActiveTable(siteId, mode);
|
||||
timer.stop();
|
||||
perfStat.logDuration("getActiveTable", timer.getElapsedTime());
|
||||
|
||||
// get decoder sites to see if we need to backup active table
|
||||
Set<String> decoderSites = getDecoderSites(siteId);
|
||||
|
||||
// if any new record is from one of the decoder sites
|
||||
// we need to queue a backup
|
||||
for (ActiveTableRecord rec : newRecords) {
|
||||
if (decoderSites.contains(rec.getOfficeid())) {
|
||||
ActiveTableBackup.queue(mode, activeTable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timer.reset();
|
||||
timer.start();
|
||||
MergeResult result = filterTable(siteId, activeTable, newRecords,
|
||||
mode, offsetSecs);
|
||||
timer.stop();
|
||||
perfStat.logDuration("filterTable", timer.getElapsedTime());
|
||||
|
||||
timer.reset();
|
||||
timer.start();
|
||||
updateTable(siteId, result, mode);
|
||||
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateTable", timer.getElapsedTime());
|
||||
if (result.changeList.size() > 0) {
|
||||
sendNotification(mode, result.changeList, "VTECDecoder");
|
||||
}
|
||||
|
@ -279,26 +351,17 @@ public class ActiveTable {
|
|||
args.put("offsetSecs", offsetSecs);
|
||||
MergeResult result = null;
|
||||
try {
|
||||
PythonScript python = threadLocalPythonScript.get();
|
||||
try {
|
||||
python = new PythonScript(filePath, includePath,
|
||||
ActiveTable.class.getClassLoader());
|
||||
try {
|
||||
result = (MergeResult) python
|
||||
.execute("mergeFromJava", args);
|
||||
result = (MergeResult) python.execute("mergeFromJava", args);
|
||||
} catch (JepException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error updating active table", e);
|
||||
}
|
||||
} catch (JepException e) {
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error initializing active table python", e);
|
||||
}
|
||||
} finally {
|
||||
if (python != null) {
|
||||
python.dispose();
|
||||
python = null;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -413,15 +476,32 @@ public class ActiveTable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new records into the active table
|
||||
*
|
||||
* @param newRecords
|
||||
* records to be merged
|
||||
* @return Exception if any occurs during merge
|
||||
*/
|
||||
public Exception merge(List<ActiveTableRecord> newRecords) {
|
||||
return merge(newRecords, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new records into the active table
|
||||
*
|
||||
* @param newRecords
|
||||
* records to be merged
|
||||
* @param timeOffset
|
||||
* time offset for practice mode in displaced real time mode
|
||||
* @return Exception if any occurs during merge
|
||||
*/
|
||||
public Exception merge(List<ActiveTableRecord> newRecords, float timeOffset) {
|
||||
Exception exc = null;
|
||||
try {
|
||||
if (newRecords != null) {
|
||||
String siteId = newRecords.get(0).getOfficeid();
|
||||
String siteId = SiteUtil.getSite();
|
||||
siteId = SiteMap.getInstance().getSite4LetterId(siteId);
|
||||
updateActiveTable(siteId, newRecords, timeOffset);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
@ -526,10 +606,13 @@ public class ActiveTable {
|
|||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
python.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the practice active table for the requested site
|
||||
*
|
||||
* @param requestedSiteId
|
||||
* site ID
|
||||
* @throws DataAccessLayerException
|
||||
*/
|
||||
public static void clearPracticeTable(String requestedSiteId)
|
||||
throws DataAccessLayerException {
|
||||
CoreDao dao = practiceDao;
|
||||
|
@ -542,6 +625,13 @@ public class ActiveTable {
|
|||
dao.executeNativeSql(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump product text to temp file
|
||||
*
|
||||
* @param productText
|
||||
* product text
|
||||
* @return the temp file
|
||||
*/
|
||||
public static File dumpProductToTempFile(String productText) {
|
||||
File file = Util.createTempFile(productText.getBytes(), "vtec");
|
||||
file.deleteOnExit();
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* 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.uf.edex.activetable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import jep.JepException;
|
||||
|
||||
import org.apache.commons.io.filefilter.WildcardFileFilter;
|
||||
|
||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.activetable.VTECPartners;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.python.PyUtil;
|
||||
import com.raytheon.uf.common.python.PythonScript;
|
||||
import com.raytheon.uf.common.status.IPerformanceStatusHandler;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.PerformanceStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.util.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
|
||||
/**
|
||||
* Perform Active Table Backup
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 17, 2014 #3296 randerso Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author randerso
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ActiveTableBackup {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ActiveTableBackup.class);
|
||||
|
||||
private static class BackupRequest {
|
||||
ActiveTableMode activeTableMode;
|
||||
|
||||
List<ActiveTableRecord> activeTable;
|
||||
|
||||
BackupRequest(ActiveTableMode activeTableMode,
|
||||
List<ActiveTableRecord> activeTable) {
|
||||
this.activeTableMode = activeTableMode;
|
||||
this.activeTable = activeTable;
|
||||
}
|
||||
}
|
||||
|
||||
private static int QUEUE_LIMIT = 10;
|
||||
|
||||
private static BlockingQueue<BackupRequest> queue = new LinkedBlockingQueue<BackupRequest>(
|
||||
QUEUE_LIMIT);
|
||||
|
||||
private static ThreadLocal<PythonScript> threadLocalPythonScript = new ThreadLocal<PythonScript>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.ThreadLocal#initialValue()
|
||||
*/
|
||||
@Override
|
||||
protected PythonScript initialValue() {
|
||||
try {
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext commonCx = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.BASE);
|
||||
String filePath = pathMgr.getFile(commonCx,
|
||||
"vtec" + File.separator + "VTECTableUtil.py").getPath();
|
||||
String siteId = pathMgr.getContext(
|
||||
LocalizationType.COMMON_STATIC, LocalizationLevel.SITE)
|
||||
.getContextName();
|
||||
String includePath = PyUtil.buildJepIncludePath(
|
||||
ActiveTablePyIncludeUtil.getCommonPythonIncludePath(),
|
||||
ActiveTablePyIncludeUtil.getVtecIncludePath(siteId));
|
||||
|
||||
PythonScript python = new PythonScript(filePath, includePath,
|
||||
ActiveTableBackup.class.getClassLoader());
|
||||
return python;
|
||||
} catch (JepException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private static Runnable target = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
IPerformanceStatusHandler perfStat = PerformanceStatus
|
||||
.getHandler("ActiveTable");
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
long lastPurge = 0;
|
||||
while (true) {
|
||||
try {
|
||||
BackupRequest request = queue.take();
|
||||
timer.reset();
|
||||
timer.start();
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationContext ctx = pathMgr.getContext(
|
||||
LocalizationType.EDEX_STATIC,
|
||||
LocalizationLevel.SITE);
|
||||
String siteId = ctx.getContextName();
|
||||
File backupDir = pathMgr.getFile(ctx,
|
||||
FileUtil.join("vtec", "backup")).getAbsoluteFile();
|
||||
|
||||
try {
|
||||
PythonScript python = threadLocalPythonScript.get();
|
||||
HashMap<String, Object> args = new HashMap<String, Object>(
|
||||
4, 1.0f);
|
||||
args.put("activeTable", request.activeTable);
|
||||
args.put("activeTableMode",
|
||||
request.activeTableMode.toString());
|
||||
args.put("filePath", backupDir.getParent());
|
||||
args.put("siteId", siteId);
|
||||
try {
|
||||
python.execute("backupActiveTable", args);
|
||||
} catch (JepException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error backing up active table", e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error initializing active table python", e);
|
||||
}
|
||||
timer.stop();
|
||||
perfStat.logDuration("backup activeTable",
|
||||
timer.getElapsedTime());
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
// don't run purge more than once a day
|
||||
if ((now - lastPurge) > TimeUtil.MILLIS_PER_DAY) {
|
||||
timer.reset();
|
||||
timer.start();
|
||||
lastPurge = now;
|
||||
// get purge age in hours
|
||||
long purgeAge = ((Number) VTECPartners.getInstance(
|
||||
siteId).getattr("VTEC_BACKUP_TABLE_PURGE_TIME",
|
||||
168 * 4)).longValue();
|
||||
|
||||
// compute purge time
|
||||
long purgeTime = now
|
||||
- (purgeAge * TimeUtil.MILLIS_PER_HOUR);
|
||||
|
||||
// file filter for backup files for the requested mode
|
||||
FilenameFilter filter = new WildcardFileFilter("*"
|
||||
+ request.activeTableMode.toString() + "*.gz");
|
||||
|
||||
// purge any backup file older than purge time;
|
||||
for (File file : backupDir.listFiles(filter)) {
|
||||
if (file.lastModified() < purgeTime) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
timer.stop();
|
||||
perfStat.logDuration("purge activeTable backups",
|
||||
timer.getElapsedTime());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private static Thread backupJob = new Thread(target, "activeTableBackup");
|
||||
|
||||
/**
|
||||
* Queue an active table backup request
|
||||
*
|
||||
* @param activeTableMode
|
||||
* @param activeTable
|
||||
*/
|
||||
public static void queue(ActiveTableMode activeTableMode,
|
||||
List<ActiveTableRecord> activeTable) {
|
||||
BackupRequest req = new BackupRequest(activeTableMode, activeTable);
|
||||
try {
|
||||
queue.add(req);
|
||||
} catch (IllegalStateException e) {
|
||||
// discard a backup request due to queue full
|
||||
BackupRequest discard = queue.poll();
|
||||
queue.add(req);
|
||||
if (discard != null) {
|
||||
statusHandler
|
||||
.warn("ActiveTable backup request discarded, queue full");
|
||||
}
|
||||
}
|
||||
if (!backupJob.isAlive()) {
|
||||
backupJob.start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,17 +19,18 @@
|
|||
**/
|
||||
package com.raytheon.uf.edex.activetable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.edex.esb.Headers;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.PerformanceStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.util.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
|
||||
/**
|
||||
* Service for the VTEC active table. Determines if the VTEC product corresponds
|
||||
|
@ -43,6 +44,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
* Mar 17, 2009 njensen Initial creation
|
||||
* Jul 14, 2009 #2950 njensen Multiple site support
|
||||
* Dec 21, 2009 #4055 njensen No site filtering
|
||||
* Jun 17, 2014 3296 randerso Added performance logging
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -54,16 +56,30 @@ public class ActiveTableSrv {
|
|||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ActiveTableSrv.class);
|
||||
|
||||
private static Map<Long, ActiveTable> activeTableMap = new HashMap<Long, ActiveTable>();
|
||||
private static ThreadLocal<ActiveTable> threadLocalActiveTable = new ThreadLocal<ActiveTable>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.ThreadLocal#initialValue()
|
||||
*/
|
||||
@Override
|
||||
protected ActiveTable initialValue() {
|
||||
return new ActiveTable();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge VTEC info from new warning records into the active table
|
||||
*
|
||||
* @param records
|
||||
*/
|
||||
public void vtecArrived(List<AbstractWarningRecord> records) {
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
try {
|
||||
long threadId = Thread.currentThread().getId();
|
||||
ActiveTable activeTable = activeTableMap.get(threadId);
|
||||
if (activeTable == null) {
|
||||
activeTable = new ActiveTable();
|
||||
activeTableMap.put(threadId, activeTable);
|
||||
}
|
||||
ActiveTable activeTable = threadLocalActiveTable.get();
|
||||
if (records != null && records.size() > 0) {
|
||||
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
||||
records, ActiveTableMode.OPERATIONAL));
|
||||
|
@ -72,8 +88,18 @@ public class ActiveTableSrv {
|
|||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error merging active table", t);
|
||||
}
|
||||
timer.stop();
|
||||
PerformanceStatus.getHandler("ActiveTable").logDuration(
|
||||
"Total time to process " + records.size() + " records",
|
||||
timer.getElapsedTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge new warning records into the practice active table
|
||||
*
|
||||
* @param records
|
||||
* @param headers
|
||||
*/
|
||||
public void practiceVtecArrived(List<AbstractWarningRecord> records,
|
||||
Headers headers) {
|
||||
Integer offsetSeconds = null;
|
||||
|
@ -84,12 +110,7 @@ public class ActiveTableSrv {
|
|||
offsetSeconds = Integer.valueOf(0);
|
||||
}
|
||||
if (records != null && records.size() > 0) {
|
||||
long threadId = Thread.currentThread().getId();
|
||||
ActiveTable activeTable = activeTableMap.get(threadId);
|
||||
if (activeTable == null) {
|
||||
activeTable = new ActiveTable();
|
||||
activeTableMap.put(threadId, activeTable);
|
||||
}
|
||||
ActiveTable activeTable = threadLocalActiveTable.get();
|
||||
try {
|
||||
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
||||
records, ActiveTableMode.PRACTICE), offsetSeconds
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
##
|
||||
# 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
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
##
|
||||
|
@ -29,6 +29,9 @@
|
|||
# 03/06/14 #2883 randerso Pass siteId into mergeFromJava
|
||||
# 03/25/14 #2884 randerso Added xxxid to VTECChange
|
||||
# 05/15/14 #3157 dgilling Support multiple TPC and SPC sites.
|
||||
# 06/17/13 #3296 randerso Moved active table backup and purging
|
||||
# to a separate thread in java.
|
||||
# Added performance logging
|
||||
#
|
||||
|
||||
import time
|
||||
|
@ -43,6 +46,10 @@ from com.raytheon.uf.common.localization import LocalizationContext_Localization
|
|||
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationLevel as LocalizationLevel
|
||||
from com.raytheon.uf.common.activetable import VTECPartners as JavaVTECPartners
|
||||
|
||||
from com.raytheon.uf.common.time.util import TimeUtil
|
||||
from com.raytheon.uf.common.status import PerformanceStatus
|
||||
perfStat = PerformanceStatus.getHandler("ActiveTable")
|
||||
|
||||
class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||
|
||||
def __init__(self, activeTableMode):
|
||||
|
@ -63,6 +70,8 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
changedFlag = False
|
||||
|
||||
#delete "obsolete" records from the old table.
|
||||
timer = TimeUtil.getTimer()
|
||||
timer.start()
|
||||
vts = VTECTableSqueeze.VTECTableSqueeze(self._time+offsetSecs)
|
||||
activeTable, tossRecords = vts.squeeze(activeTable)
|
||||
for r in tossRecords:
|
||||
|
@ -70,9 +79,13 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
del vts
|
||||
if len(tossRecords):
|
||||
changedFlag = True
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable squeeze", timer.getElapsedTime());
|
||||
|
||||
#expand out any 000 UGC codes, such as FLC000, to indicate all
|
||||
#zones.
|
||||
timer.reset()
|
||||
timer.start()
|
||||
newRecExpanded = []
|
||||
compare1 = ['phen', 'sig', 'officeid', 'etn', 'pil']
|
||||
for newR in newRecords:
|
||||
|
@ -88,11 +101,15 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
else:
|
||||
newRecExpanded.append(newR)
|
||||
newRecords = newRecExpanded
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable expand", timer.getElapsedTime());
|
||||
|
||||
# match new records with old records, with issue time is different
|
||||
# years and event times overlap. Want to reassign ongoing events
|
||||
# from last year's issueTime to be 12/31/2359z, rather than the
|
||||
# real issuetime (which is this year's).
|
||||
timer.reset()
|
||||
timer.start()
|
||||
compare = ['phen', 'sig', 'officeid', 'pil', 'etn']
|
||||
for newR in newRecords:
|
||||
cyear = time.gmtime(newR['issueTime'])[0] #current year issuance time
|
||||
|
@ -109,9 +126,13 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
"\nNewRec: ", self.printEntry(newR),
|
||||
"OldRec: ", self.printEntry(oldR))
|
||||
newR['issueTime'] = lastYearIssueTime
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable match", timer.getElapsedTime());
|
||||
|
||||
|
||||
# split records out by issuance year for processing
|
||||
timer.reset()
|
||||
timer.start()
|
||||
newRecDict = {} #key is issuance year
|
||||
oldRecDict = {}
|
||||
years = []
|
||||
|
@ -129,8 +150,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
oldRecDict[issueYear] = records
|
||||
if issueYear not in years:
|
||||
years.append(issueYear)
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable split", timer.getElapsedTime());
|
||||
|
||||
# process each year
|
||||
timer.reset()
|
||||
timer.start()
|
||||
compare = ['id', 'phen', 'sig', 'officeid', 'pil']
|
||||
|
||||
for year in years:
|
||||
|
@ -169,8 +194,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
oldR['state'] = "Replaced"
|
||||
changedFlag = True
|
||||
updatedTable.append(oldR)
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable process", timer.getElapsedTime());
|
||||
|
||||
#always add in the new records (except for ROU)
|
||||
timer.reset()
|
||||
timer.start()
|
||||
compare = ['id', 'phen', 'sig', 'officeid', 'pil', 'etn']
|
||||
for year in newRecDict.keys():
|
||||
newRecords = newRecDict[year]
|
||||
|
@ -202,8 +231,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
rec = (newR['officeid'], newR['pil'], newR['phensig'], newR['xxxid'])
|
||||
if rec not in changes:
|
||||
changes.append(rec)
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable add", timer.getElapsedTime());
|
||||
|
||||
#filter out any captured text and overviewText if not in the categories
|
||||
timer.reset()
|
||||
timer.start()
|
||||
cats = self._getTextCaptureCategories()
|
||||
if cats is not None:
|
||||
for rec in updatedTable:
|
||||
|
@ -213,6 +246,8 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
if rec.has_key('overviewText'):
|
||||
del rec['overviewText']
|
||||
|
||||
timer.stop();
|
||||
perfStat.logDuration("updateActiveTable filter", timer.getElapsedTime());
|
||||
return updatedTable, tossRecords, changes, changedFlag
|
||||
|
||||
# time overlaps, if tr1 overlaps tr2 (adjacent is not an overlap)
|
||||
|
@ -253,37 +288,35 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
|||
return outTable, purgedRecords, changes, changedFlag
|
||||
|
||||
def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
||||
perfStat.log("mergeFromJava called for site: %s, activeTable: %d , newRecords: %d" %
|
||||
(siteId, activeTable.size(), newRecords.size()))
|
||||
timer = TimeUtil.getTimer()
|
||||
timer.start()
|
||||
pyActive = []
|
||||
szActive = activeTable.size()
|
||||
for i in range(szActive):
|
||||
pyActive.append(ActiveTableRecord.ActiveTableRecord(activeTable.get(i)))
|
||||
|
||||
decoderSites = VTECPartners.VTEC_DECODER_SITES
|
||||
decoderSites.append(VTECPartners.get4ID(siteId))
|
||||
spcSites = JUtil.javaObjToPyVal(JavaVTECPartners.getInstance(siteId).getSpcSites())
|
||||
decoderSites.extend(spcSites)
|
||||
tpcSites = JUtil.javaObjToPyVal(JavaVTECPartners.getInstance(siteId).getTpcSites())
|
||||
decoderSites.extend(tpcSites)
|
||||
|
||||
backup = False
|
||||
pyNew = []
|
||||
szNew = newRecords.size()
|
||||
for i in range(szNew):
|
||||
rec = ActiveTableRecord.ActiveTableRecord(newRecords.get(i))
|
||||
if rec['officeid'] in decoderSites:
|
||||
backup = True
|
||||
pyNew.append(rec)
|
||||
|
||||
active = ActiveTable(mode)
|
||||
|
||||
if backup:
|
||||
oldActiveTable = active._convertTableToPurePython(pyActive, siteId)
|
||||
active.saveOldActiveTable(oldActiveTable)
|
||||
pTime = getattr(VTECPartners, "VTEC_BACKUP_TABLE_PURGE_TIME",168)
|
||||
active.purgeOldSavedTables(pTime)
|
||||
logger.info("Updating " + mode + " Active Table: new records\n" +
|
||||
active.printActiveTable(pyNew, combine=1))
|
||||
|
||||
timer.stop()
|
||||
perfStat.logDuration("mergeFromJava preprocess", timer.getElapsedTime());
|
||||
|
||||
updatedTable, purgeRecords, changes, changedFlag = active.activeTableMerge(pyActive, pyNew, offsetSecs)
|
||||
perfStat.log("mergeFromJava activeTableMerge returned updateTable: %d, purgeRecords: %d, changes: %d" %
|
||||
(len(updatedTable), len(purgeRecords), len(changes)))
|
||||
|
||||
timer.reset()
|
||||
timer.start()
|
||||
logger.info("Updated " + mode + " Active Table: purged\n" +
|
||||
active.printActiveTable(purgeRecords, combine=1))
|
||||
|
||||
|
@ -303,15 +336,15 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
|||
logger.info("Updated " + mode + " Active Table: decoded\n" +
|
||||
active.printActiveTable(decoded, combine=1))
|
||||
|
||||
updatedList = ArrayList()
|
||||
updatedList = ArrayList(len(updatedTable))
|
||||
for x in updatedTable:
|
||||
updatedList.add(x.javaRecord())
|
||||
|
||||
purgedList = ArrayList()
|
||||
purgedList = ArrayList(len(purgeRecords))
|
||||
for x in purgeRecords:
|
||||
purgedList.add(x.javaRecord())
|
||||
|
||||
changeList = ArrayList()
|
||||
changeList = ArrayList(len(changes))
|
||||
if (changedFlag):
|
||||
from com.raytheon.uf.common.activetable import VTECChange
|
||||
for c in changes:
|
||||
|
@ -319,4 +352,6 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
|||
|
||||
from com.raytheon.uf.common.activetable import MergeResult
|
||||
result = MergeResult(updatedList, purgedList, changeList)
|
||||
timer.stop()
|
||||
perfStat.logDuration("mergeFromJava postprocess", timer.getElapsedTime());
|
||||
return result
|
||||
|
|
|
@ -1,24 +1,38 @@
|
|||
##
|
||||
# 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
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
##
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 06/17/13 #3296 randerso Default debug to False to avoid logging overhead
|
||||
# Added performance logging
|
||||
#
|
||||
|
||||
import os, sys, time, copy, LogStream
|
||||
|
||||
from com.raytheon.uf.common.time.util import TimeUtil
|
||||
from com.raytheon.uf.common.status import PerformanceStatus
|
||||
perfStat = PerformanceStatus.getHandler("ActiveTable")
|
||||
timer = TimeUtil.getTimer()
|
||||
|
||||
# This class takes a VTEC active table and eliminates unnecessary
|
||||
# records. Records purged consist of old SPC watches, old Tropical
|
||||
# events, last year's records, and extraneous records not needed for
|
||||
|
@ -27,7 +41,7 @@ import os, sys, time, copy, LogStream
|
|||
class VTECTableSqueeze:
|
||||
|
||||
#constructor
|
||||
def __init__(self, currentTime, debug=True):
|
||||
def __init__(self, currentTime, debug=False):
|
||||
self.__ctime = currentTime
|
||||
self.__thisYear = time.gmtime(self.__ctime)[0]
|
||||
self.__debug = debug
|
||||
|
@ -41,7 +55,11 @@ class VTECTableSqueeze:
|
|||
LogStream.logDebug(self.__printActiveTable(table))
|
||||
|
||||
# modify old UFN events (in case fcstrs didn't CAN them)
|
||||
timer.reset()
|
||||
timer.start()
|
||||
table, modTable = self.__modifyOldUFNEvents(table)
|
||||
timer.stop()
|
||||
perfStat.logDuration("updateActiveTable squeeze __modifyOldUFNEvents", timer.getElapsedTime());
|
||||
if self.__debug:
|
||||
LogStream.logDebug("************** MOD UFN TABLE *********************")
|
||||
for old, new in modTable:
|
||||
|
@ -50,8 +68,12 @@ class VTECTableSqueeze:
|
|||
LogStream.logDebug(" -----------")
|
||||
|
||||
# remove the national center and short fused events
|
||||
timer.reset()
|
||||
timer.start()
|
||||
shortWFO, shortNC, purgeT = \
|
||||
self.__removeOldNationalAndShortFusedEvents(table)
|
||||
timer.stop()
|
||||
perfStat.logDuration("updateActiveTable squeeze __removeOldNationalAndShortFusedEvents", timer.getElapsedTime());
|
||||
if self.__debug:
|
||||
LogStream.logDebug("************** SHORT WFO TABLE *********************")
|
||||
LogStream.logDebug(self.__printActiveTable(shortWFO))
|
||||
|
@ -61,10 +83,18 @@ class VTECTableSqueeze:
|
|||
LogStream.logDebug(self.__printActiveTable(purgeT))
|
||||
|
||||
# separate out the shortWFO into dictionary structure
|
||||
timer.reset()
|
||||
timer.start()
|
||||
dict = self.__separateTable(shortWFO)
|
||||
timer.stop()
|
||||
perfStat.logDuration("updateActiveTable squeeze __separateTable", timer.getElapsedTime());
|
||||
|
||||
# purge old entries with LowerETNs that aren't in effect
|
||||
timer.reset()
|
||||
timer.start()
|
||||
shorterT, purgeT2 = self.__purgeOldEntriesWithLowerETNs(dict)
|
||||
timer.stop()
|
||||
perfStat.logDuration("updateActiveTable squeeze __purgeOldEntriesWithLowerETNs", timer.getElapsedTime());
|
||||
if self.__debug:
|
||||
LogStream.logDebug("************** TRIMMED WFO TABLE ******************")
|
||||
LogStream.logDebug(self.__printActiveTable(shorterT))
|
||||
|
@ -72,12 +102,10 @@ class VTECTableSqueeze:
|
|||
LogStream.logDebug(self.__printActiveTable(purgeT2))
|
||||
|
||||
#add in any shortNC entries to final table
|
||||
for r in shortNC:
|
||||
shorterT.append(r)
|
||||
shorterT.extend(shortNC)
|
||||
|
||||
#add in the purged entries from before
|
||||
for r in purgeT2:
|
||||
purgeT.append(r)
|
||||
purgeT.extend(purgeT2)
|
||||
|
||||
if self.__debug:
|
||||
LogStream.logDebug("************** FINAL TABLE ********************")
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
# further licensing information.
|
||||
##
|
||||
# Utility classes for the VTEC active table
|
||||
# Utility classes for the VTEC util table
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 06/17/13 #3296 randerso Moved active table backup and purging
|
||||
# to a separate thread in java.
|
||||
|
||||
import copy
|
||||
import cPickle
|
||||
|
@ -384,3 +391,14 @@ class VTECTableUtil:
|
|||
|
||||
return JUtil.javaObjToPyVal(javaDictFormat)
|
||||
|
||||
def backupActiveTable(activeTable, activeTableMode, filePath, siteId):
|
||||
import ActiveTableRecord
|
||||
pyActive = []
|
||||
szActive = activeTable.size()
|
||||
for i in range(szActive):
|
||||
pyActive.append(ActiveTableRecord.ActiveTableRecord(activeTable.get(i)))
|
||||
|
||||
# create a dummy name to simplify the file access code in VTECTableUtil
|
||||
util = VTECTableUtil(os.path.join(filePath, activeTableMode + ".tbl"))
|
||||
oldActiveTable = util._convertTableToPurePython(pyActive, siteId)
|
||||
util.saveOldActiveTable(oldActiveTable)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Autogenerated by Thrift Compiler (0.9.0)
|
||||
* Autogenerated by Thrift Compiler (0.8.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
* @generated
|
||||
|
@ -35,6 +35,7 @@
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 07/22/14 15649 lshi Rollback to thrift 0.8.0
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -43,14 +44,13 @@
|
|||
*/
|
||||
#include "Notification_types.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
const char* com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::ascii_fingerprint = "ACE4F644F0FDD289DDC4EE5B83BC13C0";
|
||||
const uint8_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::binary_fingerprint[16] = {0xAC,0xE4,0xF6,0x44,0xF0,0xFD,0xD2,0x89,0xDD,0xC4,0xEE,0x5B,0x83,0xBC,0x13,0xC0};
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::read(::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
|
@ -75,14 +75,14 @@ uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::r
|
|||
this->dataURIs.clear();
|
||||
uint32_t _size0;
|
||||
::apache::thrift::protocol::TType _etype3;
|
||||
xfer += iprot->readListBegin(_etype3, _size0);
|
||||
iprot->readListBegin(_etype3, _size0);
|
||||
this->dataURIs.resize(_size0);
|
||||
uint32_t _i4;
|
||||
for (_i4 = 0; _i4 < _size0; ++_i4)
|
||||
{
|
||||
xfer += iprot->readString(this->dataURIs[_i4]);
|
||||
}
|
||||
xfer += iprot->readListEnd();
|
||||
iprot->readListEnd();
|
||||
}
|
||||
this->__isset.dataURIs = true;
|
||||
} else {
|
||||
|
@ -104,7 +104,6 @@ uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::r
|
|||
uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage");
|
||||
|
||||
xfer += oprot->writeFieldBegin("dataURIs", ::apache::thrift::protocol::T_LIST, 1);
|
||||
{
|
||||
xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->dataURIs.size()));
|
||||
|
@ -116,16 +115,9 @@ uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::w
|
|||
xfer += oprot->writeListEnd();
|
||||
}
|
||||
xfer += oprot->writeFieldEnd();
|
||||
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
void swap(com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage &a, com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage &b) {
|
||||
using ::std::swap;
|
||||
swap(a.dataURIs, b.dataURIs);
|
||||
swap(a.__isset, b.__isset);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
/**
|
||||
* Autogenerated by Thrift Compiler (0.9.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
* @generated
|
||||
*/
|
||||
|
||||
/*****************************************************************************************
|
||||
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
||||
|
@ -26,7 +19,8 @@
|
|||
******************************************************************************************/
|
||||
|
||||
/*
|
||||
* Extended thrift protocol to handle messages from edex.
|
||||
* Support for point data request capability to retrieve point data and metadata
|
||||
* from EDEX Thrift service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -34,13 +28,21 @@
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 08/08/11 9696 gzhou Initial Creation
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 07/22/14 15649 lshi Rollback to Initial Creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
* @author gzhou
|
||||
* @version 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Autogenerated by Thrift
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
#include "PointDataServer_constants.h"
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
/**
|
||||
* Autogenerated by Thrift Compiler (0.9.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
* @generated
|
||||
*/
|
||||
|
||||
/*****************************************************************************************
|
||||
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
||||
|
@ -26,7 +19,8 @@
|
|||
******************************************************************************************/
|
||||
|
||||
/*
|
||||
* Extended thrift protocol to handle messages from edex.
|
||||
* Support for point data request capability to retrieve point data and metadata
|
||||
* from EDEX Thrift service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -34,240 +28,222 @@
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 08/08/11 9696 gzhou Initial Creation
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 07/22/14 15649 lshi Rollback to Initial Creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
* @author gzhou
|
||||
* @version 1
|
||||
*/
|
||||
|
||||
#include "PointDataServer_types.h"
|
||||
|
||||
#include <algorithm>
|
||||
const char
|
||||
* com_raytheon_uf_common_dataquery_requests_ConstraintType::ascii_fingerprint =
|
||||
"EFB929595D312AC8F305D5A794CFEDA1";
|
||||
const uint8_t
|
||||
com_raytheon_uf_common_dataquery_requests_ConstraintType::binary_fingerprint[16] =
|
||||
{ 0xEF, 0xB9, 0x29, 0x59, 0x5D, 0x31, 0x2A, 0xC8, 0xF3, 0x05,
|
||||
0xD5, 0xA7, 0x94, 0xCF, 0xED, 0xA1 };
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::read(
|
||||
::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
const char* com_raytheon_uf_common_dataquery_requests_ConstraintType::ascii_fingerprint = "EFB929595D312AC8F305D5A794CFEDA1";
|
||||
const uint8_t com_raytheon_uf_common_dataquery_requests_ConstraintType::binary_fingerprint[16] = {0xEF,0xB9,0x29,0x59,0x5D,0x31,0x2A,0xC8,0xF3,0x05,0xD5,0xA7,0x94,0xCF,0xED,0xA1};
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::read(::apache::thrift::protocol::TProtocol* iprot) {
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STRING) {
|
||||
xfer += iprot->readString(operand);
|
||||
this->__isset.operand = true;
|
||||
} else
|
||||
xfer += iprot->skip(ftype);
|
||||
xfer += iprot->readFieldEnd();
|
||||
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid)
|
||||
{
|
||||
case 1:
|
||||
if (ftype == ::apache::thrift::protocol::T_STRING) {
|
||||
xfer += iprot->readString(this->operand);
|
||||
this->__isset.operand = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
return xfer;
|
||||
return xfer;
|
||||
}
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataquery_requests_ConstraintType");
|
||||
|
||||
xfer += oprot->writeFieldBegin("operand", ::apache::thrift::protocol::T_STRING, 1);
|
||||
xfer += oprot->writeString(this->operand);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::write(
|
||||
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer
|
||||
+= oprot->writeStructBegin(
|
||||
"com_raytheon_uf_common_dataquery_requests_RequestConstraint$ConstraintType");
|
||||
xfer += oprot->writeFieldBegin("__enumValue__",
|
||||
::apache::thrift::protocol::T_STRING, 1);
|
||||
xfer += oprot->writeString(this->operand);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
void swap(com_raytheon_uf_common_dataquery_requests_ConstraintType &a, com_raytheon_uf_common_dataquery_requests_ConstraintType &b) {
|
||||
using ::std::swap;
|
||||
swap(a.operand, b.operand);
|
||||
swap(a.__isset, b.__isset);
|
||||
const char
|
||||
* com_raytheon_uf_common_dataquery_requests_RequestConstraint::ascii_fingerprint =
|
||||
"BDAF55DAA660FA1ADBE30760752211A8";
|
||||
const uint8_t
|
||||
com_raytheon_uf_common_dataquery_requests_RequestConstraint::binary_fingerprint[16] =
|
||||
{ 0xBD, 0xAF, 0x55, 0xDA, 0xA6, 0x60, 0xFA, 0x1A, 0xDB, 0xE3,
|
||||
0x07, 0x60, 0x75, 0x22, 0x11, 0xA8 };
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::read(
|
||||
::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
while (true) {
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid) {
|
||||
case 1:
|
||||
if (ftype == ::apache::thrift::protocol::T_STRUCT) {
|
||||
xfer += this->constraintType.read(iprot);
|
||||
this->__isset.constraintType = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (ftype == ::apache::thrift::protocol::T_STRING) {
|
||||
xfer += iprot->readString(this->constraintValue);
|
||||
this->__isset.constraintValue = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
return xfer;
|
||||
}
|
||||
|
||||
const char* com_raytheon_uf_common_dataquery_requests_RequestConstraint::ascii_fingerprint = "BDAF55DAA660FA1ADBE30760752211A8";
|
||||
const uint8_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::binary_fingerprint[16] = {0xBD,0xAF,0x55,0xDA,0xA6,0x60,0xFA,0x1A,0xDB,0xE3,0x07,0x60,0x75,0x22,0x11,0xA8};
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::read(::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid)
|
||||
{
|
||||
case 1:
|
||||
if (ftype == ::apache::thrift::protocol::T_STRUCT) {
|
||||
xfer += this->constraintType.read(iprot);
|
||||
this->__isset.constraintType = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (ftype == ::apache::thrift::protocol::T_STRING) {
|
||||
xfer += iprot->readString(this->constraintValue);
|
||||
this->__isset.constraintValue = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
return xfer;
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::write(
|
||||
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin(
|
||||
"com_raytheon_uf_common_dataquery_requests_RequestConstraint");
|
||||
xfer += oprot->writeFieldBegin("constraintType",
|
||||
::apache::thrift::protocol::T_STRUCT, 1);
|
||||
xfer += this->constraintType.write(oprot);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeFieldBegin("constraintValue",
|
||||
::apache::thrift::protocol::T_STRING, 2);
|
||||
xfer += oprot->writeString(this->constraintValue);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataquery_requests_RequestConstraint");
|
||||
const char
|
||||
* com_raytheon_uf_common_pointdata_PointDataServerRequest::ascii_fingerprint =
|
||||
"C9F1CC9CD1A896EE01B7C5215E2BE99F";
|
||||
const uint8_t
|
||||
com_raytheon_uf_common_pointdata_PointDataServerRequest::binary_fingerprint[16] =
|
||||
{ 0xC9, 0xF1, 0xCC, 0x9C, 0xD1, 0xA8, 0x96, 0xEE, 0x01, 0xB7,
|
||||
0xC5, 0x21, 0x5E, 0x2B, 0xE9, 0x9F };
|
||||
|
||||
xfer += oprot->writeFieldBegin("constraintType", ::apache::thrift::protocol::T_STRUCT, 1);
|
||||
xfer += this->constraintType.write(oprot);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::read(
|
||||
::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
xfer += oprot->writeFieldBegin("constraintValue", ::apache::thrift::protocol::T_STRING, 2);
|
||||
xfer += oprot->writeString(this->constraintValue);
|
||||
xfer += oprot->writeFieldEnd();
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
while (true) {
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid) {
|
||||
case 1:
|
||||
if (ftype == ::apache::thrift::protocol::T_MAP) {
|
||||
{
|
||||
this->rcMap.clear();
|
||||
uint32_t _size0;
|
||||
::apache::thrift::protocol::TType _ktype1;
|
||||
::apache::thrift::protocol::TType _vtype2;
|
||||
iprot->readMapBegin(_ktype1, _vtype2, _size0);
|
||||
uint32_t _i4;
|
||||
for (_i4 = 0; _i4 < _size0; ++_i4) {
|
||||
std::string _key5;
|
||||
xfer += iprot->readString(_key5);
|
||||
com_raytheon_uf_common_dataquery_requests_RequestConstraint
|
||||
& _val6 = this->rcMap[_key5];
|
||||
xfer += _val6.read(iprot);
|
||||
}
|
||||
iprot->readMapEnd();
|
||||
}
|
||||
this->__isset.rcMap = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
return xfer;
|
||||
}
|
||||
|
||||
void swap(com_raytheon_uf_common_dataquery_requests_RequestConstraint &a, com_raytheon_uf_common_dataquery_requests_RequestConstraint &b) {
|
||||
using ::std::swap;
|
||||
swap(a.constraintType, b.constraintType);
|
||||
swap(a.constraintValue, b.constraintValue);
|
||||
swap(a.__isset, b.__isset);
|
||||
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::write(
|
||||
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin(
|
||||
"com_raytheon_uf_common_pointdata_PointDataServerRequest");
|
||||
xfer += oprot->writeFieldBegin("rcMap", ::apache::thrift::protocol::T_MAP,
|
||||
1);
|
||||
{
|
||||
xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING,
|
||||
::apache::thrift::protocol::T_STRUCT, this->rcMap.size());
|
||||
std::map<std::string,
|
||||
com_raytheon_uf_common_dataquery_requests_RequestConstraint>::const_iterator
|
||||
_iter7;
|
||||
for (_iter7 = this->rcMap.begin(); _iter7 != this->rcMap.end(); ++_iter7) {
|
||||
xfer += oprot->writeStructBegin("11");
|
||||
xfer += oprot->writeString(_iter7->first);
|
||||
xfer += oprot->writeStructEnd();
|
||||
xfer += _iter7->second.write(oprot);
|
||||
}
|
||||
xfer += oprot->writeMapEnd();
|
||||
}
|
||||
xfer += oprot->writeFieldEnd();
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
const char* com_raytheon_uf_common_pointdata_PointDataServerRequest::ascii_fingerprint = "C9F1CC9CD1A896EE01B7C5215E2BE99F";
|
||||
const uint8_t com_raytheon_uf_common_pointdata_PointDataServerRequest::binary_fingerprint[16] = {0xC9,0xF1,0xCC,0x9C,0xD1,0xA8,0x96,0xEE,0x01,0xB7,0xC5,0x21,0x5E,0x2B,0xE9,0x9F};
|
||||
|
||||
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::read(::apache::thrift::protocol::TProtocol* iprot) {
|
||||
|
||||
uint32_t xfer = 0;
|
||||
std::string fname;
|
||||
::apache::thrift::protocol::TType ftype;
|
||||
int16_t fid;
|
||||
|
||||
xfer += iprot->readStructBegin(fname);
|
||||
|
||||
using ::apache::thrift::protocol::TProtocolException;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||
if (ftype == ::apache::thrift::protocol::T_STOP) {
|
||||
break;
|
||||
}
|
||||
switch (fid)
|
||||
{
|
||||
case 1:
|
||||
if (ftype == ::apache::thrift::protocol::T_MAP) {
|
||||
{
|
||||
this->rcMap.clear();
|
||||
uint32_t _size0;
|
||||
::apache::thrift::protocol::TType _ktype1;
|
||||
::apache::thrift::protocol::TType _vtype2;
|
||||
xfer += iprot->readMapBegin(_ktype1, _vtype2, _size0);
|
||||
uint32_t _i4;
|
||||
for (_i4 = 0; _i4 < _size0; ++_i4)
|
||||
{
|
||||
std::string _key5;
|
||||
xfer += iprot->readString(_key5);
|
||||
com_raytheon_uf_common_dataquery_requests_RequestConstraint& _val6 = this->rcMap[_key5];
|
||||
xfer += _val6.read(iprot);
|
||||
}
|
||||
xfer += iprot->readMapEnd();
|
||||
}
|
||||
this->__isset.rcMap = true;
|
||||
} else {
|
||||
xfer += iprot->skip(ftype);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfer += iprot->skip(ftype);
|
||||
break;
|
||||
}
|
||||
xfer += iprot->readFieldEnd();
|
||||
}
|
||||
|
||||
xfer += iprot->readStructEnd();
|
||||
|
||||
return xfer;
|
||||
}
|
||||
|
||||
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
||||
uint32_t xfer = 0;
|
||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_pointdata_PointDataServerRequest");
|
||||
|
||||
xfer += oprot->writeFieldBegin("rcMap", ::apache::thrift::protocol::T_MAP, 1);
|
||||
{
|
||||
xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->rcMap.size()));
|
||||
std::map<std::string, com_raytheon_uf_common_dataquery_requests_RequestConstraint> ::const_iterator _iter7;
|
||||
for (_iter7 = this->rcMap.begin(); _iter7 != this->rcMap.end(); ++_iter7)
|
||||
{
|
||||
xfer += oprot->writeString(_iter7->first);
|
||||
xfer += _iter7->second.write(oprot);
|
||||
}
|
||||
xfer += oprot->writeMapEnd();
|
||||
}
|
||||
xfer += oprot->writeFieldEnd();
|
||||
|
||||
xfer += oprot->writeFieldStop();
|
||||
xfer += oprot->writeStructEnd();
|
||||
return xfer;
|
||||
}
|
||||
|
||||
void swap(com_raytheon_uf_common_pointdata_PointDataServerRequest &a, com_raytheon_uf_common_pointdata_PointDataServerRequest &b) {
|
||||
using ::std::swap;
|
||||
swap(a.rcMap, b.rcMap);
|
||||
swap(a.__isset, b.__isset);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
/**
|
||||
* Autogenerated by Thrift Compiler (0.9.0)
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
* @generated
|
||||
*/
|
||||
|
||||
/*****************************************************************************************
|
||||
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
||||
|
@ -26,7 +19,8 @@
|
|||
******************************************************************************************/
|
||||
|
||||
/*
|
||||
* Extended thrift protocol to handle messages from edex.
|
||||
* Support for point data request capability to retrieve point data
|
||||
* from EDEX Thrift service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -34,13 +28,21 @@
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 01/18/10 3747 brockwoo Initial Creation
|
||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||
* 07/22/14 15649 lshi Rollback to Initial Creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
* @author brockwoo
|
||||
* @version 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Autogenerated by Thrift
|
||||
*
|
||||
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||
*/
|
||||
#include "PointData_constants.h"
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue