Merge branch 'master_14.3.1' into asm_14.3.1
Conflicts: cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java Former-commit-id: f22cc09d0a6fdc7a806726d5207f6b3507972b94
This commit is contained in:
commit
6f6daaa249
82 changed files with 4145 additions and 3289 deletions
|
@ -39,7 +39,10 @@ import com.raytheon.uf.viz.core.status.VizStatusInternal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements status handling by converting status messages into StatusMessages
|
* 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>
|
* <pre>
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
|
@ -47,6 +50,7 @@ import com.raytheon.uf.viz.core.status.VizStatusInternal;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Sep 09, 2008 1433 chammack Initial creation
|
* Sep 09, 2008 1433 chammack Initial creation
|
||||||
* Aug 26, 2013 2142 njensen Changed to use SLF4J
|
* Aug 26, 2013 2142 njensen Changed to use SLF4J
|
||||||
|
* Jul 02, 2014 3337 njensen Disabled logback packaging data
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -62,6 +66,34 @@ public class SystemStatusHandler extends AbstractStatusHandler {
|
||||||
|
|
||||||
private static final Marker FATAL = MarkerFactory.getMarker("FATAL");
|
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)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
<loadProperties>
|
<loadProperties>
|
||||||
<capabilities>
|
<capabilities>
|
||||||
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
||||||
<capability xsi:type="outlineCapability" lineStyle="SOLID" outlineOn="true" />
|
<capability xsi:type="pointCapability" pointStyle="NONE" />
|
||||||
|
<capability xsi:type="labelableCapability" labelField="id" />
|
||||||
|
<capability xsi:type="magnificationCapability" magnification="1.0" />
|
||||||
|
<capability xsi:type="densityCapability" density="1.0" />
|
||||||
</capabilities>
|
</capabilities>
|
||||||
<resourceType>PLAN_VIEW</resourceType>
|
<resourceType>PLAN_VIEW</resourceType>
|
||||||
</loadProperties>
|
</loadProperties>
|
||||||
|
@ -37,7 +40,23 @@
|
||||||
<capabilities>
|
<capabilities>
|
||||||
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
||||||
<capability xsi:type="labelableCapability" labelField="name" />
|
<capability xsi:type="labelableCapability" labelField="name" />
|
||||||
<capability xsi:type="outlineCapability" lineStyle="SOLID" outlineOn="true"
|
</capabilities>
|
||||||
|
<resourceType>PLAN_VIEW</resourceType>
|
||||||
|
</loadProperties>
|
||||||
|
<properties isSystemResource="false" isBlinking="false" isMapLayer="true" isHoverOn="false" isVisible="true">
|
||||||
|
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0" />
|
||||||
|
</properties>
|
||||||
|
<resourceData xsi:type="lpiResourceData">
|
||||||
|
<filename>cities.lpi</filename>
|
||||||
|
<mapName>Cities</mapName>
|
||||||
|
</resourceData>
|
||||||
|
</resource>
|
||||||
|
<mapName>Cities</mapName>
|
||||||
|
<resource>
|
||||||
|
<loadProperties>
|
||||||
|
<capabilities>
|
||||||
|
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
||||||
|
<capability xsi:type="labelableCapability" labelField="name" />
|
||||||
outlineWidth="1" />
|
outlineWidth="1" />
|
||||||
</capabilities>
|
</capabilities>
|
||||||
<resourceType>PLAN_VIEW</resourceType>
|
<resourceType>PLAN_VIEW</resourceType>
|
||||||
|
@ -51,27 +70,10 @@
|
||||||
<mapName>Cities</mapName>
|
<mapName>Cities</mapName>
|
||||||
</resourceData>
|
</resourceData>
|
||||||
</resource>
|
</resource>
|
||||||
<resource>
|
|
||||||
<loadProperties>
|
|
||||||
<capabilities>
|
|
||||||
<capability xsi:type="colorableCapability" colorAsString="#9b9b9b" />
|
|
||||||
<capability xsi:type="labelableCapability" labelField="name" />
|
|
||||||
<capability xsi:type="outlineCapability" lineStyle="SOLID" outlineOn="true" outlineWidth="1" />
|
|
||||||
</capabilities>
|
|
||||||
<resourceType>PLAN_VIEW</resourceType>
|
|
||||||
</loadProperties>
|
|
||||||
<properties isSystemResource="false" isBlinking="false" isMapLayer="true" isHoverOn="false" isVisible="true">
|
|
||||||
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0" />
|
|
||||||
</properties>
|
|
||||||
<resourceData xsi:type="lpiResourceData">
|
|
||||||
<filename>cities.lpi</filename>
|
|
||||||
<mapName>Cities</mapName>
|
|
||||||
</resourceData>
|
|
||||||
</resource>
|
|
||||||
<mapName>Cities</mapName>
|
|
||||||
</resourceData>
|
</resourceData>
|
||||||
</resource>
|
</resource>
|
||||||
</descriptor>
|
</descriptor>
|
||||||
</displays>
|
</displays>
|
||||||
</displayList>
|
</displayList>
|
||||||
</bundle>
|
</bundle>
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ import org.eclipse.ui.IWorkbenchWindow;
|
||||||
import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile;
|
import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile;
|
||||||
import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile.AutoUpdatingFileChangedListener;
|
import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile.AutoUpdatingFileChangedListener;
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
import com.raytheon.uf.common.localization.IPathManager;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||||
|
@ -41,6 +44,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay;
|
import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.maps.display.VizMapEditor;
|
||||||
import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale;
|
import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale;
|
||||||
import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId;
|
import com.raytheon.uf.viz.core.maps.scales.MapScales.PartId;
|
||||||
import com.raytheon.uf.viz.core.procedures.Bundle;
|
import com.raytheon.uf.viz.core.procedures.Bundle;
|
||||||
|
@ -61,7 +65,8 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml;
|
||||||
* Oct 08, 2013 mschenke Initial creation
|
* Oct 08, 2013 mschenke Initial creation
|
||||||
* Oct 22, 2013 2491 bsteffen Change from SerializationUtil to
|
* Oct 22, 2013 2491 bsteffen Change from SerializationUtil to
|
||||||
* ProcedureXmlManager
|
* ProcedureXmlManager
|
||||||
* Mar 24, 2014 2954 mpduff Check for missing map scale files and handle the situation.
|
* Mar 24, 2014 2954 mpduff Log when missing map scale files
|
||||||
|
* Jul 15, 2014 2954 njensen Added fallbacks when missing map scale files
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -79,6 +84,11 @@ public class MapScalesManager {
|
||||||
|
|
||||||
private static final String DEFAULT_SCALES_FILE = "scalesInfo.xml";
|
private static final String DEFAULT_SCALES_FILE = "scalesInfo.xml";
|
||||||
|
|
||||||
|
// TODO would be better to fall back to a worldwide display
|
||||||
|
private static final String LAST_RESORT_NAME = "Northern Hemisphere";
|
||||||
|
|
||||||
|
private static final String LAST_RESORT_FILENAME = "NHemisphere.xml";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager class for a single {@link MapScale}. Is able to create a Bundle
|
* Manager class for a single {@link MapScale}. Is able to create a Bundle
|
||||||
* for the scale. May provide functions for modifying/saving scales
|
* for the scale. May provide functions for modifying/saving scales
|
||||||
|
@ -94,7 +104,7 @@ public class MapScalesManager {
|
||||||
|
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
|
|
||||||
private final PartId[] partIds;
|
private PartId[] partIds;
|
||||||
|
|
||||||
private final AutoUpdatingLocalizationFile scaleFile;
|
private final AutoUpdatingLocalizationFile scaleFile;
|
||||||
|
|
||||||
|
@ -103,13 +113,15 @@ public class MapScalesManager {
|
||||||
private final boolean isCustom;
|
private final boolean isCustom;
|
||||||
|
|
||||||
private ManagedMapScale(String baseDir, MapScale scale)
|
private ManagedMapScale(String baseDir, MapScale scale)
|
||||||
throws SerializationException {
|
throws IllegalStateException, SerializationException {
|
||||||
this.isCustom = false;
|
this.isCustom = false;
|
||||||
|
this.partIds = scale.getPartIds();
|
||||||
|
this.displayName = scale.getDisplayName();
|
||||||
|
|
||||||
LocalizationFile file = PathManagerFactory.getPathManager()
|
LocalizationFile file = PathManagerFactory.getPathManager()
|
||||||
.getStaticLocalizationFile(
|
.getStaticLocalizationFile(
|
||||||
baseDir + IPathManager.SEPARATOR
|
baseDir + IPathManager.SEPARATOR
|
||||||
+ scale.getFileName());
|
+ scale.getFileName());
|
||||||
|
|
||||||
if (file == null || !file.exists()) {
|
if (file == null || !file.exists()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"scalesInfo.xml references missing file "
|
"scalesInfo.xml references missing file "
|
||||||
|
@ -117,9 +129,18 @@ public class MapScalesManager {
|
||||||
}
|
}
|
||||||
this.scaleFile = new AutoUpdatingLocalizationFile(file);
|
this.scaleFile = new AutoUpdatingLocalizationFile(file);
|
||||||
this.scaleFile.addListener(listener);
|
this.scaleFile.addListener(listener);
|
||||||
this.partIds = scale.getPartIds();
|
|
||||||
this.displayName = scale.getDisplayName();
|
|
||||||
loadBundleXml();
|
loadBundleXml();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO this is inefficient to unmarshal it eagerly for no purpose
|
||||||
|
* other than to validate, but it ensures that if the files exist
|
||||||
|
* but have bad XML, then the thrown exception from getScaleBundle()
|
||||||
|
* will cause the fallback code to be triggered, leading to no blank
|
||||||
|
* panes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// validate the XML is good
|
||||||
|
getScaleBundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManagedMapScale(String displayName, Bundle scaleBundle)
|
private ManagedMapScale(String displayName, Bundle scaleBundle)
|
||||||
|
@ -190,7 +211,9 @@ public class MapScalesManager {
|
||||||
@Override
|
@Override
|
||||||
public void fileChanged(AutoUpdatingLocalizationFile file) {
|
public void fileChanged(AutoUpdatingLocalizationFile file) {
|
||||||
try {
|
try {
|
||||||
loadMapScales();
|
MapScales scales = file.loadObject(getJAXBManager(),
|
||||||
|
MapScales.class);
|
||||||
|
loadMapScales(scales);
|
||||||
} catch (SerializationException e) {
|
} catch (SerializationException e) {
|
||||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||||
e);
|
e);
|
||||||
|
@ -198,7 +221,7 @@ public class MapScalesManager {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final AutoUpdatingLocalizationFile scalesFile;
|
private AutoUpdatingLocalizationFile scalesFile;
|
||||||
|
|
||||||
private final String scaleBundleDir;
|
private final String scaleBundleDir;
|
||||||
|
|
||||||
|
@ -223,36 +246,108 @@ public class MapScalesManager {
|
||||||
*/
|
*/
|
||||||
public MapScalesManager(String scalesDir, String scalesFile)
|
public MapScalesManager(String scalesDir, String scalesFile)
|
||||||
throws SerializationException {
|
throws SerializationException {
|
||||||
this(scalesDir, PathManagerFactory.getPathManager()
|
String filename = scalesDir + IPathManager.SEPARATOR + scalesFile;
|
||||||
|
LocalizationFile locFile = PathManagerFactory.getPathManager()
|
||||||
.getStaticLocalizationFile(
|
.getStaticLocalizationFile(
|
||||||
scalesDir + IPathManager.SEPARATOR + scalesFile));
|
filename);
|
||||||
|
MapScales scales = null;
|
||||||
|
try {
|
||||||
|
this.scalesFile = new AutoUpdatingLocalizationFile(locFile);
|
||||||
|
scales = this.scalesFile.loadObject(getJAXBManager(),
|
||||||
|
MapScales.class);
|
||||||
|
} catch (SerializationException e) {
|
||||||
|
/*
|
||||||
|
* failed to load scalesInfo file, try and fall back to BASE
|
||||||
|
*/
|
||||||
|
statusHandler.error("Error loading " + DEFAULT_SCALES_FILE
|
||||||
|
+ ". Attempting to revert to base version. ", e);
|
||||||
|
if (!locFile.getContext().getLocalizationLevel()
|
||||||
|
.equals(LocalizationLevel.BASE)) {
|
||||||
|
locFile = PathManagerFactory.getPathManager()
|
||||||
|
.getLocalizationFile(
|
||||||
|
new LocalizationContext(
|
||||||
|
LocalizationType.CAVE_STATIC,
|
||||||
|
LocalizationLevel.BASE), filename);
|
||||||
|
this.scalesFile = new AutoUpdatingLocalizationFile(locFile);
|
||||||
|
scales = this.scalesFile.loadObject(getJAXBManager(),
|
||||||
|
MapScales.class);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.scaleBundleDir = scalesDir;
|
||||||
|
this.scalesFile.addListener(listener);
|
||||||
|
loadMapScales(scales);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void loadMapScales(MapScales scales)
|
||||||
|
{
|
||||||
|
List<ManagedMapScale> storedScales = new ArrayList<ManagedMapScale>();
|
||||||
|
List<PartId> failedParts = new ArrayList<PartId>();
|
||||||
|
for (MapScale scale : scales.getScales()) {
|
||||||
|
try {
|
||||||
|
storedScales.add(new ManagedMapScale(scaleBundleDir, scale));
|
||||||
|
} catch (Exception e) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Error loading " + scale.getDisplayName()
|
||||||
|
+ " scale. ");
|
||||||
|
if (scale.getPartIds() != null && scale.getPartIds().length > 0) {
|
||||||
|
sb.append(scale.getDisplayName()
|
||||||
|
+ " pane will attempt to revert to working scale. ");
|
||||||
|
}
|
||||||
|
sb.append(scale.getDisplayName()
|
||||||
|
+ " will not appear in the menu. ");
|
||||||
|
statusHandler.error(sb.toString(), e);
|
||||||
|
if (scale.getPartIds() != null) {
|
||||||
|
for (PartId p : scale.getPartIds()) {
|
||||||
|
failedParts.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.storedScales = storedScales;
|
||||||
|
|
||||||
|
// storedScales must be set before handleMissingParts()
|
||||||
|
if (!failedParts.isEmpty()) {
|
||||||
|
handleMissingParts(failedParts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a MapScalesManager for the given scales file. File must be
|
* Handles the parts that referenced scales files that couldn't be found.
|
||||||
* deserializable into a {@link MapScales} object
|
|
||||||
*
|
*
|
||||||
* @param bundleDir
|
* @param missingParts
|
||||||
* directory bundle files are relative to
|
* the parts that were missing
|
||||||
* @param scalesFile
|
* @param goodScales
|
||||||
* @throws SerializationException
|
* the scales that successfully loaded
|
||||||
*/
|
*/
|
||||||
public MapScalesManager(String bundleDir, LocalizationFile scalesFile)
|
protected void handleMissingParts(List<PartId> missingParts) {
|
||||||
throws SerializationException {
|
/*
|
||||||
this.scaleBundleDir = bundleDir;
|
* if the missing part was a side view, fall back to the main pane
|
||||||
this.scalesFile = new AutoUpdatingLocalizationFile(scalesFile);
|
*/
|
||||||
this.scalesFile.addListener(listener);
|
ManagedMapScale mainPane = findEditorScale();
|
||||||
loadMapScales();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void loadMapScales() throws SerializationException {
|
if (mainPane == null) {
|
||||||
List<ManagedMapScale> storedScales = new ArrayList<ManagedMapScale>();
|
/*
|
||||||
MapScales scales = this.scalesFile.loadObject(getJAXBManager(),
|
* main pane is missing too, so fall back to a base scale that is
|
||||||
MapScales.class);
|
* guaranteed to be there
|
||||||
for (MapScale scale : scales.getScales()) {
|
*/
|
||||||
storedScales.add(new ManagedMapScale(scaleBundleDir, scale));
|
mainPane = getLastResortScale();
|
||||||
|
storedScales.add(mainPane);
|
||||||
}
|
}
|
||||||
this.storedScales = storedScales;
|
|
||||||
|
/*
|
||||||
|
* Set all the missing parts to the scale in the main pane
|
||||||
|
*/
|
||||||
|
List<PartId> combinedParts = new ArrayList<PartId>(
|
||||||
|
mainPane.partIds.length + missingParts.size());
|
||||||
|
for (PartId p : mainPane.getPartIds()) {
|
||||||
|
combinedParts.add(p);
|
||||||
|
}
|
||||||
|
for (PartId p : missingParts) {
|
||||||
|
combinedParts.add(p);
|
||||||
|
}
|
||||||
|
mainPane.partIds = combinedParts.toArray(new PartId[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -336,12 +431,12 @@ public class MapScalesManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link ManagedMapScale}s defined for the partId
|
* Gets the Bundle defined for the partId.
|
||||||
*
|
*
|
||||||
* @param partId
|
* @param partId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ManagedMapScale[] getScalesForPart(String partId) {
|
public Bundle getScaleBundleForPart(String partId) {
|
||||||
List<ManagedMapScale> scalesForPart = new ArrayList<ManagedMapScale>();
|
List<ManagedMapScale> scalesForPart = new ArrayList<ManagedMapScale>();
|
||||||
for (ManagedMapScale scale : storedScales) {
|
for (ManagedMapScale scale : storedScales) {
|
||||||
for (PartId part : scale.getPartIds()) {
|
for (PartId part : scale.getPartIds()) {
|
||||||
|
@ -351,7 +446,26 @@ public class MapScalesManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return scalesForPart.toArray(new ManagedMapScale[0]);
|
|
||||||
|
Bundle b = null;
|
||||||
|
for (ManagedMapScale scale : scalesForPart) {
|
||||||
|
try {
|
||||||
|
b = scale.getScaleBundle();
|
||||||
|
} catch (SerializationException e) {
|
||||||
|
statusHandler.error("Error deserializing bundle for scale: "
|
||||||
|
+ scale, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b != null) {
|
||||||
|
b.setView(partId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -408,4 +522,54 @@ public class MapScalesManager {
|
||||||
}
|
}
|
||||||
return jaxbManager;
|
return jaxbManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a base scale that should always be there and should always work.
|
||||||
|
* Used to prevent blank panes if scale overrides are misconfigured.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected ManagedMapScale getLastResortScale() {
|
||||||
|
ManagedMapScale scale = null;
|
||||||
|
PartId fallbackPartId = new PartId();
|
||||||
|
fallbackPartId.setId(VizMapEditor.EDITOR_ID);
|
||||||
|
fallbackPartId.setView(false);
|
||||||
|
MapScale fallback = new MapScale();
|
||||||
|
fallback.setPartIds(new PartId[] { fallbackPartId });
|
||||||
|
fallback.setDisplayName(LAST_RESORT_NAME);
|
||||||
|
fallback.setFileName(LAST_RESORT_FILENAME);
|
||||||
|
try {
|
||||||
|
scale = new ManagedMapScale(scaleBundleDir, fallback);
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler.fatal("Error loading the last resort scale "
|
||||||
|
+ LAST_RESORT_FILENAME, e);
|
||||||
|
// things will null pointer if this ever hits, but come on
|
||||||
|
}
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the editor pane (ie VizMapEditor.EDITOR_ID) associated with a list
|
||||||
|
* of scales
|
||||||
|
*
|
||||||
|
* @return the first scale tied to a VizMapEditor, or null if none are found
|
||||||
|
*/
|
||||||
|
public ManagedMapScale findEditorScale() {
|
||||||
|
ManagedMapScale editorScale = null;
|
||||||
|
for (ManagedMapScale scale : storedScales) {
|
||||||
|
PartId[] parts = scale.partIds;
|
||||||
|
if (parts != null) {
|
||||||
|
for (PartId p : parts) {
|
||||||
|
if (VizMapEditor.EDITOR_ID.equals(p.getId())) {
|
||||||
|
editorScale = scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editorScale != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return editorScale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import com.raytheon.uf.common.time.DataTimeComparator;
|
||||||
* cease a null pointer exception.
|
* cease a null pointer exception.
|
||||||
* May 5, 2014 DR 17201 D. Friedman Make same-radar time matching work more like A1.
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -657,7 +658,6 @@ public class TimeMatcher {
|
||||||
|
|
||||||
if (fspatial) {
|
if (fspatial) {
|
||||||
frameFcsts = dataFcsts;
|
frameFcsts = dataFcsts;
|
||||||
dtf = dt;
|
|
||||||
} else if (dtf > dt) {
|
} else if (dtf > dt) {
|
||||||
dt = dtf;
|
dt = dtf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.ui.PartInitException;
|
||||||
import org.eclipse.ui.PlatformUI;
|
import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.part.ViewPart;
|
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.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
@ -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.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.globals.VizGlobalsManager;
|
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;
|
||||||
import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale;
|
|
||||||
import com.raytheon.uf.viz.core.procedures.Bundle;
|
import com.raytheon.uf.viz.core.procedures.Bundle;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
import com.raytheon.uf.viz.core.rsc.IInputHandler;
|
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
|
* Mar 21, 2013 1638 mschenke Changed map scales not tied to d2d
|
||||||
* Aug 9, 2013 DR 16427 D. Friedman Swap additional input handlers.
|
* Aug 9, 2013 DR 16427 D. Friedman Swap additional input handlers.
|
||||||
* Oct 10, 2013 #2104 mschenke Switched to use MapScalesManager
|
* Oct 10, 2013 #2104 mschenke Switched to use MapScalesManager
|
||||||
*
|
* Jul 15, 2014 2954 njensen Updated init() for MapScalesManager change
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -141,18 +140,8 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
||||||
String myId = site.getId() + UiUtil.SECONDARY_ID_SEPARATOR
|
String myId = site.getId() + UiUtil.SECONDARY_ID_SEPARATOR
|
||||||
+ site.getSecondaryId();
|
+ site.getSecondaryId();
|
||||||
|
|
||||||
for (ManagedMapScale scale : MapScalesManager.getInstance()
|
bundleToLoad = MapScalesManager.getInstance().getScaleBundleForPart(
|
||||||
.getScalesForPart(myId)) {
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -284,6 +273,7 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
||||||
*
|
*
|
||||||
* @see com.raytheon.viz.core.IDisplayPaneContainer#getActiveDisplayPane()
|
* @see com.raytheon.viz.core.IDisplayPaneContainer#getActiveDisplayPane()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public IDisplayPane getActiveDisplayPane() {
|
public IDisplayPane getActiveDisplayPane() {
|
||||||
return paneManager.getActiveDisplayPane();
|
return paneManager.getActiveDisplayPane();
|
||||||
}
|
}
|
||||||
|
@ -774,15 +764,18 @@ public class SideView extends ViewPart implements IMultiPaneEditor,
|
||||||
ISelectedPanesChangedListener listener) {
|
ISelectedPanesChangedListener listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void registerMouseHandler(IInputHandler handler,
|
public void registerMouseHandler(IInputHandler handler,
|
||||||
InputPriority priority) {
|
InputPriority priority) {
|
||||||
paneManager.registerMouseHandler(handler, priority);
|
paneManager.registerMouseHandler(handler, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void registerMouseHandler(IInputHandler handler) {
|
public void registerMouseHandler(IInputHandler handler) {
|
||||||
paneManager.registerMouseHandler(handler);
|
paneManager.registerMouseHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void unregisterMouseHandler(IInputHandler handler) {
|
public void unregisterMouseHandler(IInputHandler handler) {
|
||||||
paneManager.unregisterMouseHandler(handler);
|
paneManager.unregisterMouseHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||||
* 21Mar2014 #2925 lvenable Fixed NPE error found during testing.
|
* 21Mar2014 #2925 lvenable Fixed NPE error found during testing.
|
||||||
* 09Apr2014 #3005 lvenable Added calls to mark the tabs as not current when the tabs are changed.
|
* 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.
|
* This will show the tab as updating in the header and data text controls.
|
||||||
|
* 07/23/2014 15645 zhao modified checkBasicSyntaxError()
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -2110,19 +2111,29 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
return editorComp;
|
return editorComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Check if there is an extra '=' sign in a TAF
|
||||||
*
|
*
|
||||||
* @param doLogMessage
|
* @param doLogMessage
|
||||||
* @return true if error found, otherwise false
|
* @return true if error found, otherwise false
|
||||||
*/
|
*/
|
||||||
private boolean checkBasicSyntaxError(boolean doLogMessage) {
|
private boolean checkBasicSyntaxError(boolean doLogMessage) {
|
||||||
|
|
||||||
|
boolean errorFound = false;
|
||||||
|
|
||||||
String in = editorTafTabComp.getTextEditorControl().getText();
|
String in = editorTafTabComp.getTextEditorControl().getText();
|
||||||
|
|
||||||
clearSyntaxErrorLevel();
|
clearSyntaxErrorLevel();
|
||||||
|
|
||||||
st = editorTafTabComp.getTextEditorControl();
|
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>();
|
final Map<StyleRange, String> syntaxMap = new HashMap<StyleRange, String>();
|
||||||
|
|
||||||
st.addMouseTrackListener(new MouseTrackAdapter() {
|
st.addMouseTrackListener(new MouseTrackAdapter() {
|
||||||
|
@ -2154,66 +2165,36 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
int tafIndex = in.indexOf("TAF");
|
String msg = "Syntax error: There is an extra '=' sign or 'TAF' is missing at beginning of TAF";
|
||||||
int equalSignIndex = in.indexOf("=");
|
String[] tafs = in.split("\n\n");
|
||||||
int lastEqualSignIndex = equalSignIndex;
|
int tafStartIndex = 0;
|
||||||
|
for ( String taf : tafs ) {
|
||||||
if (tafIndex < 0 && equalSignIndex < 0) { // empty TAF
|
int firstEqualSignIndex = taf.indexOf('=');
|
||||||
return false;
|
if ( firstEqualSignIndex == -1 ) {
|
||||||
}
|
tafStartIndex += taf.length() + 2;
|
||||||
|
continue;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
int secondEqualSignIndex = taf.indexOf('=', firstEqualSignIndex+1);
|
||||||
tafIndex = in.indexOf("TAF", tafIndex + 1);
|
if ( secondEqualSignIndex == -1 ) {
|
||||||
lastEqualSignIndex = equalSignIndex;
|
tafStartIndex += taf.length() + 2;
|
||||||
equalSignIndex = in.indexOf("=", equalSignIndex + 1);
|
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() {
|
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.Grid2DFloat;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.grid.Op;
|
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.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;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockMode;
|
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockMode;
|
||||||
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockStatus;
|
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.
|
* Apr 02, 2013 #1774 randerso Fixed a possible deadlock issue.
|
||||||
* Aug 27, 2013 #2302 randerso Fix simultaneous save issue
|
* Aug 27, 2013 #2302 randerso Fix simultaneous save issue
|
||||||
* Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys()
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -619,21 +622,19 @@ public abstract class Parm implements Comparable<Parm> {
|
||||||
return new TimeRange();
|
return new TimeRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMutable()) {
|
TimeRange tr = getInventorySpan();
|
||||||
return getInventorySpan();
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeRange tr = new TimeRange();
|
if (isMutable()) {
|
||||||
if (lockTable != null) {
|
LockTable lt = this.lockTable;
|
||||||
if (lockTable.getLocks().size() > 0) {
|
if (lt != null) {
|
||||||
tr = lockTable.getLocks().get(0).getTimeRange();
|
List<Lock> locks = lt.getLocks();
|
||||||
}
|
for (Lock lock : locks) {
|
||||||
for (int i = 1; i < lockTable.getLocks().size(); i++) {
|
tr = tr.combineWith(lock.getTimeRange());
|
||||||
tr = tr.combineWith(lockTable.getLocks().get(i).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.Status;
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
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;
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +42,7 @@ import com.raytheon.uf.common.time.TimeRange;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 27, 2013 #2302 randerso Initial creation
|
* Aug 27, 2013 #2302 randerso Initial creation
|
||||||
|
* Jun 30, 2014 #3332 randerso Added exception handling
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -48,6 +51,9 @@ import com.raytheon.uf.common.time.TimeRange;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ParmSaveJob extends Job {
|
public class ParmSaveJob extends Job {
|
||||||
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(ParmSaveJob.class);
|
||||||
|
|
||||||
public static class ParmSaveStatus {
|
public static class ParmSaveStatus {
|
||||||
boolean successful = false;
|
boolean successful = false;
|
||||||
|
|
||||||
|
@ -127,8 +133,13 @@ public class ParmSaveJob extends Job {
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
ParmSaveRequest req = null;
|
ParmSaveRequest req = null;
|
||||||
while ((req = this.saveQueue.poll()) != null) {
|
while ((req = this.saveQueue.poll()) != null) {
|
||||||
boolean successful = parm.saveParameterSubClass(req.times);
|
try {
|
||||||
req.status.setSuccessful(successful);
|
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;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,6 +260,7 @@ public class RadarBiasTableDialog extends Dialog {
|
||||||
applyBtn = new Button(applyBtnComp, SWT.PUSH);
|
applyBtn = new Button(applyBtnComp, SWT.PUSH);
|
||||||
applyBtn.setText("Apply");
|
applyBtn.setText("Apply");
|
||||||
applyBtn.setLayoutData(bd);
|
applyBtn.setLayoutData(bd);
|
||||||
|
applyBtn.setEnabled(false);
|
||||||
applyBtn.addSelectionListener(new SelectionAdapter() {
|
applyBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -274,7 +275,6 @@ public class RadarBiasTableDialog extends Dialog {
|
||||||
applyBiasUpdate(dt);
|
applyBiasUpdate(dt);
|
||||||
MPEDisplayManager mgr = MPEDisplayManager.getCurrent();
|
MPEDisplayManager mgr = MPEDisplayManager.getCurrent();
|
||||||
mgr.setSavedData(false);
|
mgr.setSavedData(false);
|
||||||
shell.dispose();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -560,7 +560,6 @@ public class RadarBiasTableDialog extends Dialog {
|
||||||
editedSPBiasValue[ai] = oldSPBiasValue[ai];
|
editedSPBiasValue[ai] = oldSPBiasValue[ai];
|
||||||
spBiasValueTextArray[ai].setText(String.format("%-1.2f", editedSPBiasValue[ai]));
|
spBiasValueTextArray[ai].setText(String.format("%-1.2f", editedSPBiasValue[ai]));
|
||||||
spBiasChangeMap.put(radIds[ai], ai);
|
spBiasChangeMap.put(radIds[ai], ai);
|
||||||
applyBtn.setEnabled(false);
|
|
||||||
spManEditButtonArray[ai].setText("NO");
|
spManEditButtonArray[ai].setText("NO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
* Sep 6, 2012 13365 rferrel Accumulate and Display fix.
|
* Sep 6, 2012 13365 rferrel Accumulate and Display fix.
|
||||||
* Sep 25, 2012 1196 lvenable Dialog refactor for AlarmDisplayWindow.Added DO_NOT_BLOCK.
|
* Sep 25, 2012 1196 lvenable Dialog refactor for AlarmDisplayWindow.Added DO_NOT_BLOCK.
|
||||||
* Nov 20, 2013 2488 randerso Changed to use DejaVu font
|
* Nov 20, 2013 2488 randerso Changed to use DejaVu font
|
||||||
|
* Jul 24, 2014 3423 randerso Added setLoading() to indicate waiting on product
|
||||||
|
* retrieval. Removed prods from constructor.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -100,19 +102,13 @@ public class AlarmDisplayWindow extends CaveSWTDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parentShell
|
* @param parentShell
|
||||||
* @param prodList
|
|
||||||
* @param accum_state
|
* @param accum_state
|
||||||
*/
|
*/
|
||||||
protected AlarmDisplayWindow(Shell parentShell,
|
protected AlarmDisplayWindow(Shell parentShell, ACCUMULATE_STATE accum_state) {
|
||||||
java.util.List<StdTextProduct> prodList,
|
|
||||||
ACCUMULATE_STATE accum_state) {
|
|
||||||
super(parentShell, SWT.RESIZE, CAVE.PERSPECTIVE_INDEPENDENT
|
super(parentShell, SWT.RESIZE, CAVE.PERSPECTIVE_INDEPENDENT
|
||||||
| CAVE.INDEPENDENT_SHELL | CAVE.DO_NOT_BLOCK);
|
| CAVE.INDEPENDENT_SHELL | CAVE.DO_NOT_BLOCK);
|
||||||
setText("Alarm Display Window");
|
setText("Alarm Display Window");
|
||||||
prods = prodList;
|
prods = new ArrayList<StdTextProduct>(0);
|
||||||
if (prods == null) {
|
|
||||||
prods = new ArrayList<StdTextProduct>();
|
|
||||||
}
|
|
||||||
this.accum_state = accum_state;
|
this.accum_state = accum_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,6 +261,11 @@ public class AlarmDisplayWindow extends CaveSWTDialog {
|
||||||
populateText();
|
populateText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLoading() {
|
||||||
|
actualText = text.getText();
|
||||||
|
text.setText("Loading...");
|
||||||
|
}
|
||||||
|
|
||||||
public void addText(String msg) {
|
public void addText(String msg) {
|
||||||
if (accumulate) {
|
if (accumulate) {
|
||||||
if (text.getText().isEmpty()) {
|
if (text.getText().isEmpty()) {
|
||||||
|
|
|
@ -24,7 +24,13 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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.SWT;
|
||||||
import org.eclipse.swt.events.ControlAdapter;
|
import org.eclipse.swt.events.ControlAdapter;
|
||||||
import org.eclipse.swt.events.ControlEvent;
|
import org.eclipse.swt.events.ControlEvent;
|
||||||
|
@ -52,7 +58,9 @@ import com.raytheon.uf.common.dataplugin.text.db.StdTextProduct;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.util.Pair;
|
||||||
import com.raytheon.uf.edex.services.textdbsrv.IQueryTransport;
|
import com.raytheon.uf.edex.services.textdbsrv.IQueryTransport;
|
||||||
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
import com.raytheon.viz.core.mode.CAVEMode;
|
import com.raytheon.viz.core.mode.CAVEMode;
|
||||||
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmDisplayWindow.ACCUMULATE_STATE;
|
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmDisplayWindow.ACCUMULATE_STATE;
|
||||||
import com.raytheon.viz.texteditor.alarmalert.util.AlarmAlertFunctions;
|
import com.raytheon.viz.texteditor.alarmalert.util.AlarmAlertFunctions;
|
||||||
|
@ -97,8 +105,10 @@ import com.raytheon.viz.ui.dialogs.ModeListener;
|
||||||
* Alarm Queue" GUI
|
* Alarm Queue" GUI
|
||||||
* Sep 6, 2012 13365 rferrel Accumulate and Display fix.
|
* Sep 6, 2012 13365 rferrel Accumulate and Display fix.
|
||||||
* Sep 25, 2012 1196 lvenable Dialog refactor for AlarmDisplayWindow.
|
* 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.
|
* are saved and set on the next open.
|
||||||
|
* Jul 24, 2014 3423 randerso Created eclipse job to get afos command
|
||||||
|
* execution off the UI thread
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -142,7 +152,7 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
* Location and dimensions of the dialog on the close.
|
* Location and dimensions of the dialog on the close.
|
||||||
*/
|
*/
|
||||||
private static Point closeLocation = null;
|
private static Point closeLocation = null;
|
||||||
|
|
||||||
private static Point closeDimensions = null;
|
private static Point closeDimensions = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,14 +161,65 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
private boolean canRedraw = true;
|
private boolean canRedraw = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum width,initial height and offset of the window
|
* Maximum width,initial height and offset of the window
|
||||||
*/
|
*/
|
||||||
private static final int SHELL_WIDTH = 350;
|
private static final int SHELL_WIDTH = 350;
|
||||||
|
|
||||||
private static final int INIT_HEIGHT = 200;
|
private static final int INIT_HEIGHT = 200;
|
||||||
|
|
||||||
private static final int INIT_OFFSET = 15;
|
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 parentShell
|
||||||
* @param style
|
* @param style
|
||||||
|
@ -261,12 +322,13 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
shellComp = new Composite(shell, SWT.NONE);
|
shellComp = new Composite(shell, SWT.NONE);
|
||||||
shellComp.setLayout(constructShellLayout());
|
shellComp.setLayout(constructShellLayout());
|
||||||
shellComp.setLayoutData(gd);
|
shellComp.setLayoutData(gd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DR15173 - Create a listener to save the location
|
* DR15173 - Create a listener to save the location and dimensions of
|
||||||
* and dimensions of closed window.
|
* closed window.
|
||||||
*/
|
*/
|
||||||
shell.addShellListener(new ShellAdapter() {
|
shell.addShellListener(new ShellAdapter() {
|
||||||
|
@Override
|
||||||
public void shellClosed(ShellEvent event) {
|
public void shellClosed(ShellEvent event) {
|
||||||
closeLocation = getShell().getLocation();
|
closeLocation = getShell().getLocation();
|
||||||
closeDimensions = getShell().getSize();
|
closeDimensions = getShell().getSize();
|
||||||
|
@ -289,11 +351,13 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
Display.getDefault().asyncExec(new Runnable() {
|
Display.getDefault().asyncExec(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
/*
|
/*
|
||||||
* DR15173 - Enforce that the window width does not exceed the SHELL_WIDTH.
|
* DR15173 - Enforce that the window width does not
|
||||||
*/
|
* exceed the SHELL_WIDTH.
|
||||||
shell.setBounds(location.x, location.y, SHELL_WIDTH, point.y);
|
*/
|
||||||
shell.setMinimumSize(SHELL_WIDTH, 0);
|
shell.setBounds(location.x, location.y, SHELL_WIDTH,
|
||||||
|
point.y);
|
||||||
|
shell.setMinimumSize(SHELL_WIDTH, 0);
|
||||||
canRedraw = true;
|
canRedraw = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -302,7 +366,7 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
|
|
||||||
// Initialize all of the controls and layouts
|
// Initialize all of the controls and layouts
|
||||||
initializeComponents();
|
initializeComponents();
|
||||||
|
|
||||||
// Set the shell location and dimensions.
|
// Set the shell location and dimensions.
|
||||||
setShellGeometry();
|
setShellGeometry();
|
||||||
}
|
}
|
||||||
|
@ -310,26 +374,25 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
/**
|
/**
|
||||||
* Sets the geometry for the Current Alarm Queue shell
|
* Sets the geometry for the Current Alarm Queue shell
|
||||||
*/
|
*/
|
||||||
private void setShellGeometry() {
|
private void setShellGeometry() {
|
||||||
Rectangle displayArea = shell.getDisplay().getClientArea();
|
Rectangle displayArea = shell.getDisplay().getClientArea();
|
||||||
int locationX = displayArea.x + INIT_OFFSET;
|
int locationX = displayArea.x + INIT_OFFSET;
|
||||||
int locationY = displayArea.y + INIT_OFFSET;
|
int locationY = displayArea.y + INIT_OFFSET;
|
||||||
int width = SHELL_WIDTH;
|
int width = SHELL_WIDTH;
|
||||||
int height = INIT_HEIGHT;
|
int height = INIT_HEIGHT;
|
||||||
if (CurrentAlarmQueue.closeLocation != null) {
|
if (CurrentAlarmQueue.closeLocation != null) {
|
||||||
locationX = CurrentAlarmQueue.closeLocation.x;
|
locationX = CurrentAlarmQueue.closeLocation.x;
|
||||||
locationY = CurrentAlarmQueue.closeLocation.y;
|
locationY = CurrentAlarmQueue.closeLocation.y;
|
||||||
}
|
}
|
||||||
if (CurrentAlarmQueue.closeDimensions != null) {
|
if (CurrentAlarmQueue.closeDimensions != null) {
|
||||||
height = CurrentAlarmQueue.closeDimensions.y;
|
height = CurrentAlarmQueue.closeDimensions.y;
|
||||||
}
|
}
|
||||||
shell.setMinimumSize(width, height);
|
shell.setMinimumSize(width, height);
|
||||||
shell.setLocation(locationX, locationY);
|
shell.setLocation(locationX, locationY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
|
||||||
* Initializes each component of the shell
|
* Initializes each component of the shell
|
||||||
*/
|
*/
|
||||||
private void initializeComponents() {
|
private void initializeComponents() {
|
||||||
|
@ -421,7 +484,7 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
* Display the selected product the current alarm queue list.
|
* Display the selected product the current alarm queue list.
|
||||||
*/
|
*/
|
||||||
private void displayList() {
|
private void displayList() {
|
||||||
String command = "";
|
String command = null;
|
||||||
Date refDate = null;
|
Date refDate = null;
|
||||||
if (list != null && list.getItemCount() > 0
|
if (list != null && list.getItemCount() > 0
|
||||||
&& list.getSelectionCount() > 0 && list.getSelection() != null) {
|
&& list.getSelectionCount() > 0 && list.getSelection() != null) {
|
||||||
|
@ -436,14 +499,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
|
// Display the Alarm Display Window
|
||||||
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
||||||
alarmDisplayDlg = new AlarmDisplayWindow(shell, prods,
|
alarmDisplayDlg = new AlarmDisplayWindow(shell,
|
||||||
ACCUMULATE_STATE.UNCHANGE);
|
ACCUMULATE_STATE.UNCHANGE);
|
||||||
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
||||||
|
|
||||||
|
@ -458,58 +516,52 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
|
|
||||||
alarmDisplayDlg.open();
|
alarmDisplayDlg.open();
|
||||||
} else {
|
} else {
|
||||||
alarmDisplayDlg.setProds(prods);
|
|
||||||
alarmDisplayDlg.setDialogFocus();
|
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.
|
* Display all the products in the alarm queue list and clear the list.
|
||||||
*/
|
*/
|
||||||
private void displayAll() {
|
private void displayAll() {
|
||||||
String[] command = null;
|
String[] command = new String[list.getItemCount()];
|
||||||
if (list != null) {
|
for (int i = 0; i < list.getItemCount(); i++) {
|
||||||
command = new String[list.getItemCount()];
|
command[i] = list.getItems()[i].split(" ")[0];
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
// Do a count of how many instances of each command are in
|
||||||
java.util.List<StdTextProduct> prods = new ArrayList<StdTextProduct>();
|
// the queue.
|
||||||
if (command.length > 0) {
|
Map<String, Integer> counter = new HashMap<String, Integer>();
|
||||||
for (int i = 0; i < command.length; i++) {
|
for (int i = 0; i < command.length; ++i) {
|
||||||
prods.addAll(produceTextProduct(command[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
|
// Display the Alarm Display Window
|
||||||
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
if (alarmDisplayDlg == null || alarmDisplayDlg.getShell().isDisposed()) {
|
||||||
alarmDisplayDlg = new AlarmDisplayWindow(shell, prods,
|
alarmDisplayDlg = new AlarmDisplayWindow(shell,
|
||||||
ACCUMULATE_STATE.TRUE);
|
ACCUMULATE_STATE.TRUE);
|
||||||
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
alarmDisplayDlg.setCloseCallback(new ICloseCallback() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -523,10 +575,12 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
});
|
});
|
||||||
alarmDisplayDlg.open();
|
alarmDisplayDlg.open();
|
||||||
} else {
|
} else {
|
||||||
alarmDisplayDlg.setProds(prods);
|
|
||||||
alarmDisplayDlg.setAccumulate(true);
|
alarmDisplayDlg.setAccumulate(true);
|
||||||
alarmDisplayDlg.setDialogFocus();
|
alarmDisplayDlg.setDialogFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alarmDisplayDlg.setLoading();
|
||||||
|
produceTextProductsJob.queue(null, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -578,12 +632,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.
|
* Get the product for the given AFOS command and reference time.
|
||||||
*
|
*
|
||||||
|
@ -591,11 +639,16 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
* @param refTime
|
* @param refTime
|
||||||
* @return prodList
|
* @return prodList
|
||||||
*/
|
*/
|
||||||
private java.util.List<StdTextProduct> produceTextProduct(String command,
|
private java.util.List<StdTextProduct> produceTextProducts(Long refTime,
|
||||||
Long refTime) {
|
String... commands) {
|
||||||
ICommand cmd = CommandFactory.getAfosCommand(command, refTime);
|
|
||||||
executeCommand(cmd);
|
java.util.List<StdTextProduct> prods = new ArrayList<StdTextProduct>();
|
||||||
return prodList;
|
for (String command : commands) {
|
||||||
|
ICommand cmd = CommandFactory.getAfosCommand(command, refTime);
|
||||||
|
executeCommand(cmd);
|
||||||
|
prods.addAll(prodList);
|
||||||
|
}
|
||||||
|
return prods;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -652,12 +705,19 @@ public class CurrentAlarmQueue extends CaveSWTDialog implements
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void currentAlarmChanged(CurrentAlarmEvent event) {
|
public void currentAlarmChanged(CurrentAlarmEvent event) {
|
||||||
AlarmAlertProduct aap = (AlarmAlertProduct) event.getSource();
|
final AlarmAlertProduct aap = (AlarmAlertProduct) event.getSource();
|
||||||
if (!shell.isDisposed() && shell != null) {
|
if (!shell.isDisposed() && shell != null) {
|
||||||
CAVEMode mode = CAVEMode.getMode();
|
CAVEMode mode = CAVEMode.getMode();
|
||||||
if ((CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
if ((CAVEMode.OPERATIONAL.equals(mode) || CAVEMode.TEST
|
||||||
.equals(mode)) && aap.getOperationalMode()) {
|
.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.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||||
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmAlertBell;
|
import com.raytheon.viz.texteditor.alarmalert.dialogs.AlarmAlertBell;
|
||||||
import com.raytheon.viz.texteditor.command.CommandFactory;
|
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.
|
* 03/19/2012 D. Friedman Fix determination of "Alarm" entries.
|
||||||
* 12/07/2012 15555 m.gamazaychikov Added methods and constants for
|
* 12/07/2012 15555 m.gamazaychikov Added methods and constants for
|
||||||
* the implementation of proximity alarm
|
* the implementation of proximity alarm
|
||||||
|
* 07/24/2014 3423 randerso Ensure ringBell is called on UI thread
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -211,14 +213,16 @@ public class AlarmAlertFunctions {
|
||||||
match = true;
|
match = true;
|
||||||
}
|
}
|
||||||
if (match) {
|
if (match) {
|
||||||
if (productFound == null)
|
if (productFound == null) {
|
||||||
productFound = p;
|
productFound = p;
|
||||||
|
}
|
||||||
if ("Alarm".equals(p.getAlarmType()) && p.isAlarm()) {
|
if ("Alarm".equals(p.getAlarmType()) && p.isAlarm()) {
|
||||||
alarm = true;
|
alarm = true;
|
||||||
productFound = p;
|
productFound = p;
|
||||||
}
|
}
|
||||||
if (alarm)
|
if (alarm) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +233,14 @@ public class AlarmAlertFunctions {
|
||||||
instance.getCurrentAlarms().add(prod);
|
instance.getCurrentAlarms().add(prod);
|
||||||
instance.fireNewCurrentAlarmEvent(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.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.viz.core.VizApp;
|
|
||||||
import com.raytheon.uf.viz.core.notification.INotificationObserver;
|
import com.raytheon.uf.viz.core.notification.INotificationObserver;
|
||||||
import com.raytheon.uf.viz.core.notification.NotificationMessage;
|
import com.raytheon.uf.viz.core.notification.NotificationMessage;
|
||||||
import com.raytheon.uf.viz.core.notification.jobs.NotificationManagerJob;
|
import com.raytheon.uf.viz.core.notification.jobs.NotificationManagerJob;
|
||||||
import com.raytheon.viz.core.mode.CAVEMode;
|
import com.raytheon.viz.core.mode.CAVEMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Add Description
|
* Alarm Alert Notification Observer
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -108,7 +108,8 @@ public class AlarmAlertNotificationObserver implements INotificationObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run != null) {
|
if (run != null) {
|
||||||
VizApp.runAsync(run);
|
Thread thread = new Thread(run);
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
|
|
|
@ -21,6 +21,7 @@ package com.raytheon.viz.warngen.gis;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -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;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
//import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||||
|
import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil.Direction;
|
||||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||||
import com.raytheon.viz.warngen.util.Abbreviation;
|
import com.raytheon.viz.warngen.util.Abbreviation;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
@ -79,6 +82,8 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
||||||
* Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
|
* Dec 4, 2013 2604 jsanchez Refactored GisUtil and PortionsUtil.
|
||||||
* Apr 29, 2014 3033 jsanchez Updated method to retrieve files in localization.
|
* Apr 29, 2014 3033 jsanchez Updated method to retrieve files in localization.
|
||||||
* May 16, 2014 DR 17365 D. Friedman Reduce precision of warning area to avoid topology errors.
|
* May 16, 2014 DR 17365 D. Friedman Reduce precision of warning area to avoid topology errors.
|
||||||
|
* Jun 30, 2014 DR 17447 Qinglu lin Updated findAffectedAreas().
|
||||||
|
* Jul 22, 23014 3419 jsanchez Cleaned up converFeAreaToPartList.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -94,6 +99,10 @@ public class Area {
|
||||||
*/
|
*/
|
||||||
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
public static final double DEFAULT_PORTION_TOLERANCE = 0.60;
|
||||||
|
|
||||||
|
private static final List<String> SPECIAL_CASE_FE_AREAS = Arrays
|
||||||
|
.asList(new String[] { "PA", "MI", "PD", "UP", "BB", "ER", "EU",
|
||||||
|
"SR", "NR", "WU", "DS" });
|
||||||
|
|
||||||
private PortionsUtil portionsUtil;
|
private PortionsUtil portionsUtil;
|
||||||
|
|
||||||
public Area(PortionsUtil portionsUtil) {
|
public Area(PortionsUtil portionsUtil) {
|
||||||
|
@ -181,6 +190,7 @@ public class Area {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> uniqueFips = new ArrayList<String>();
|
List<String> uniqueFips = new ArrayList<String>();
|
||||||
|
List<String> uniqueCountyname = new ArrayList<String>();
|
||||||
List<AffectedAreas> areas = new ArrayList<AffectedAreas>();
|
List<AffectedAreas> areas = new ArrayList<AffectedAreas>();
|
||||||
for (GeospatialData regionFeature : countyMap.values()) {
|
for (GeospatialData regionFeature : countyMap.values()) {
|
||||||
Geometry regionGeom = regionFeature.geometry;
|
Geometry regionGeom = regionFeature.geometry;
|
||||||
|
@ -260,8 +270,14 @@ public class Area {
|
||||||
|
|
||||||
area.points = pointList.toArray(new String[pointList.size()]);
|
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);
|
uniqueFips.add(area.fips);
|
||||||
|
if (countyName != null) {
|
||||||
|
uniqueCountyname.add(countyName);
|
||||||
|
}
|
||||||
areas.add(area);
|
areas.add(area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +313,8 @@ public class Area {
|
||||||
Map<String, Object> areasMap = new HashMap<String, Object>();
|
Map<String, Object> areasMap = new HashMap<String, Object>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Geometry precisionReducedArea = PolygonUtil.reducePrecision(warnArea);
|
Geometry precisionReducedArea = PolygonUtil
|
||||||
|
.reducePrecision(warnArea);
|
||||||
if (precisionReducedArea.isValid()) {
|
if (precisionReducedArea.isValid()) {
|
||||||
warnArea = precisionReducedArea;
|
warnArea = precisionReducedArea;
|
||||||
}
|
}
|
||||||
|
@ -335,66 +352,41 @@ public class Area {
|
||||||
|
|
||||||
public static List<String> converFeAreaToPartList(String feArea) {
|
public static List<String> converFeAreaToPartList(String feArea) {
|
||||||
final List<String> partList = new ArrayList<String>();
|
final List<String> partList = new ArrayList<String>();
|
||||||
if (feArea == null) {
|
if (feArea != null) {
|
||||||
// Marine warnings
|
feArea = feArea.toUpperCase();
|
||||||
partList.add("");
|
if (SPECIAL_CASE_FE_AREAS.contains(feArea)) {
|
||||||
} else {
|
partList.add(feArea);
|
||||||
if (feArea.equals("pa"))
|
} else {
|
||||||
partList.add("PA");
|
|
||||||
else if (feArea.equals("mi"))
|
|
||||||
partList.add("MI");
|
|
||||||
else if (feArea.equals("pd"))
|
|
||||||
partList.add("PD");
|
|
||||||
else if (feArea.equals("up"))
|
|
||||||
partList.add("UP");
|
|
||||||
else if (feArea.equals("bb"))
|
|
||||||
partList.add("BB");
|
|
||||||
else if (feArea.equals("er"))
|
|
||||||
partList.add("ER");
|
|
||||||
else if (feArea.equals("eu"))
|
|
||||||
partList.add("EU");
|
|
||||||
else if (feArea.equals("sr"))
|
|
||||||
partList.add("SR");
|
|
||||||
else if (feArea.equals("nr"))
|
|
||||||
partList.add("NR");
|
|
||||||
else if (feArea.equals("wu"))
|
|
||||||
partList.add("WU");
|
|
||||||
else if (feArea.equals("ds"))
|
|
||||||
partList.add("DS");
|
|
||||||
else if (feArea.equals("ne"))
|
|
||||||
partList.add("NE");
|
|
||||||
else if (feArea.equals("nw"))
|
|
||||||
partList.add("NW");
|
|
||||||
else if (feArea.equals("se"))
|
|
||||||
partList.add("SE");
|
|
||||||
else if (feArea.equals("sw"))
|
|
||||||
partList.add("SW");
|
|
||||||
else {
|
|
||||||
for (int i = 0; i < feArea.length(); i++) {
|
for (int i = 0; i < feArea.length(); i++) {
|
||||||
char c = feArea.charAt(i);
|
char c = feArea.charAt(i);
|
||||||
|
Direction direction = null;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
|
||||||
partList.add("CENTRAL");
|
case 'C':
|
||||||
|
direction = Direction.CENTRAL;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'W':
|
||||||
partList.add("WEST");
|
direction = Direction.WEST;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'N':
|
||||||
partList.add("NORTH");
|
direction = Direction.NORTH;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'E':
|
||||||
partList.add("EAST");
|
direction = Direction.EAST;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 'S':
|
||||||
partList.add("SOUTH");
|
direction = Direction.SOUTH;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (direction != null) {
|
||||||
|
partList.add(direction.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return partList;
|
return partList;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,9 @@ import com.vividsolutions.jts.precision.SimpleGeometryPrecisionReducer;
|
||||||
* 01/09/2014 DR 16974 D. Friedman Improve followup redraw-from-hatched-area polygons.
|
* 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.
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mschenke
|
* @author mschenke
|
||||||
|
@ -417,12 +420,15 @@ public class PolygonUtil {
|
||||||
p1--;
|
p1--;
|
||||||
|
|
||||||
if (p1 >= 0) {
|
if (p1 >= 0) {
|
||||||
|
Coordinate last = new Coordinate();
|
||||||
int n, best1, best2;
|
int n, best1, best2;
|
||||||
for (n = k = 0; k < npoints; k++) {
|
for (n = k = 0; k < npoints; k++) {
|
||||||
if (match[k] == nv)
|
if (match[k] == nv)
|
||||||
continue;
|
continue;
|
||||||
best1 = match[p1];
|
best1 = match[p1];
|
||||||
best2 = match[k];
|
best2 = match[k];
|
||||||
|
last.x = longest[p1].x;
|
||||||
|
last.y = longest[p1].y;
|
||||||
p1 = k;
|
p1 = k;
|
||||||
if (best1 < 0 && best2 < 0) {
|
if (best1 < 0 && best2 < 0) {
|
||||||
if (k == n)
|
if (k == n)
|
||||||
|
@ -460,16 +466,59 @@ public class PolygonUtil {
|
||||||
best1 += nv;
|
best1 += nv;
|
||||||
else if (dn - da < -len2)
|
else if (dn - da < -len2)
|
||||||
best2 += nv;
|
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++) {
|
for (best1++; best1 <= best2; best1++) {
|
||||||
fixed[n] = 1;
|
fixed[n] = 1;
|
||||||
longest[n++] = new Coordinate(vert[best1]);
|
longest[n++] = new Coordinate(vert[best1]);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
for (; best1 > best2; best1--) {
|
for (; best1 > best2; best1--) {
|
||||||
fixed[n] = 1;
|
fixed[n] = 1;
|
||||||
longest[n++] = new Coordinate(vert[best1]);
|
longest[n++] = new Coordinate(vert[best1]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fixed[n] = 1;
|
fixed[n] = 1;
|
||||||
|
@ -1670,11 +1719,11 @@ public class PolygonUtil {
|
||||||
}
|
}
|
||||||
return slope;
|
return slope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a polygon whose two diagonal coordinates are a and b.
|
* 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;
|
double maxX, minX, maxY, minY;
|
||||||
maxX = Math.max(a.x, b.x);
|
maxX = Math.max(a.x, b.x);
|
||||||
minX = Math.min(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[2] = new Coordinate(maxX, maxY);
|
||||||
coord[3] = new Coordinate(minX, maxY);
|
coord[3] = new Coordinate(minX, maxY);
|
||||||
coord[4] = new Coordinate(coord[0]);
|
coord[4] = new Coordinate(coord[0]);
|
||||||
GeometryFactory gf = new GeometryFactory();
|
|
||||||
LinearRing lr = gf.createLinearRing(coord);
|
LinearRing lr = gf.createLinearRing(coord);
|
||||||
return gf.createPolygon(lr, null);
|
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
|
/** Creates a copy of a Geometry with reduced precision to reduce the chance of topology errors when used
|
||||||
* in intersection operations.
|
* 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 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.
|
* 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.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -166,6 +168,12 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(WarngenDialog.class);
|
.getHandler(WarngenDialog.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This flag allows a hidden button to appear to help recreating warning
|
||||||
|
* polygons that had issues in the feed.
|
||||||
|
*/
|
||||||
|
private boolean debug = false;
|
||||||
|
|
||||||
private static final int BULLET_WIDTH = 390;
|
private static final int BULLET_WIDTH = 390;
|
||||||
|
|
||||||
private static final int BULLET_HEIGHT = 230;
|
private static final int BULLET_HEIGHT = 230;
|
||||||
|
@ -484,30 +492,39 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
* @param productType2
|
* @param productType2
|
||||||
*/
|
*/
|
||||||
private void createOtherProductsList(Group productType2) {
|
private void createOtherProductsList(Group productType2) {
|
||||||
other = new Button(productType, SWT.RADIO);
|
if (other == null) {
|
||||||
other.setText("Other:");
|
other = new Button(productType, SWT.RADIO);
|
||||||
other.setEnabled(true);
|
other.setText("Other:");
|
||||||
other.addSelectionListener(new SelectionAdapter() {
|
other.setEnabled(true);
|
||||||
|
other.addSelectionListener(new SelectionAdapter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent arg0) {
|
public void widgetSelected(SelectionEvent arg0) {
|
||||||
otherSelected();
|
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);
|
updateOtherProductList(otherProductListCbo);
|
||||||
otherProductListCbo.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent arg0) {
|
|
||||||
otherProductSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMainProductButtons(Group productType) {
|
private void createMainProductButtons(Group productType) {
|
||||||
|
@ -519,12 +536,13 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
mainProducts.add(str);
|
mainProducts.add(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
String defaultTemplate = warngenLayer.getDialogConfig()
|
String defaultTemplate = getDefaultTemplate();
|
||||||
.getDefaultTemplate();
|
|
||||||
if ((defaultTemplate == null) || defaultTemplate.equals("")) {
|
|
||||||
defaultTemplate = mainProducts.get(0).split("/")[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (mainProductBtns != null) {
|
||||||
|
for (Button button : mainProductBtns) {
|
||||||
|
button.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
mainProductBtns = new Button[mainProducts.size()];
|
mainProductBtns = new Button[mainProducts.size()];
|
||||||
|
|
||||||
if (mainProducts.size() > 0) {
|
if (mainProducts.size() > 0) {
|
||||||
|
@ -540,24 +558,29 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
mainProductBtns[0].addSelectionListener(new SelectionAdapter() {
|
mainProductBtns[0].addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
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);
|
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||||
gd.horizontalIndent = 30;
|
if (updateListCbo == null) {
|
||||||
updateListCbo = new Combo(productType, SWT.READ_ONLY | SWT.DROP_DOWN);
|
gd.horizontalIndent = 30;
|
||||||
updateListCbo.setLayoutData(gd);
|
updateListCbo = new Combo(productType, SWT.READ_ONLY
|
||||||
recreateUpdates();
|
| SWT.DROP_DOWN);
|
||||||
|
updateListCbo.setLayoutData(gd);
|
||||||
|
recreateUpdates();
|
||||||
|
|
||||||
updateListCbo.addSelectionListener(new SelectionAdapter() {
|
updateListCbo.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent arg0) {
|
public void widgetSelected(SelectionEvent arg0) {
|
||||||
updateListSelected();
|
updateListSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
} else if (mainProductBtns.length > 0) {
|
||||||
|
updateListCbo.moveBelow(mainProductBtns[0]);
|
||||||
|
}
|
||||||
|
|
||||||
for (int cnt = 1; cnt < mainProducts.size(); cnt++) {
|
for (int cnt = 1; cnt < mainProducts.size(); cnt++) {
|
||||||
final String[] tmp = mainProducts.get(cnt).split("/");
|
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);
|
Composite redrawFrom = new Composite(redrawBox, SWT.NONE);
|
||||||
redrawFrom.setLayout(new GridLayout(3, false));
|
int columns = debug ? 4 : 3;
|
||||||
|
redrawFrom.setLayout(new GridLayout(columns, false));
|
||||||
redrawFrom.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false,
|
redrawFrom.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false,
|
||||||
true));
|
true));
|
||||||
|
|
||||||
|
@ -651,9 +675,30 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
damBreakThreatArea.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
damBreakThreatAreaPressed();
|
DamInfoBullet damBullet = bulletListManager
|
||||||
|
.getSelectedDamInfoBullet();
|
||||||
|
if (damBullet != null) {
|
||||||
|
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
Button drawPolygonButton = new Button(redrawFrom, SWT.PUSH);
|
||||||
|
drawPolygonButton.setText("?");
|
||||||
|
drawPolygonButton.setEnabled(true);
|
||||||
|
drawPolygonButton.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
/*
|
||||||
|
* Copy/paste the LAT...LON line from the text product to
|
||||||
|
* quickly recreate the polygon.
|
||||||
|
*/
|
||||||
|
String latLon = "LAT...LON 4282 7174 4256 7129 4248 7159 4280 7198";
|
||||||
|
damBreakThreatAreaPressed(latLon, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createBackupTrackEditGroups(Composite mainComposite) {
|
private void createBackupTrackEditGroups(Composite mainComposite) {
|
||||||
|
@ -683,7 +728,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
backupGroup.setLayout(new GridLayout(2, false));
|
backupGroup.setLayout(new GridLayout(2, false));
|
||||||
|
|
||||||
Label label2 = new Label(backupGroup, SWT.BOLD);
|
Label label2 = new Label(backupGroup, SWT.BOLD);
|
||||||
label2.setText("Full:");
|
label2.setText("WFO:");
|
||||||
label2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
label2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
backupSiteCbo = new Combo(backupGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
|
backupSiteCbo = new Combo(backupGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
|
||||||
backupSiteCbo.addSelectionListener(new SelectionAdapter() {
|
backupSiteCbo.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@ -1195,7 +1240,11 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
setInstructions();
|
setInstructions();
|
||||||
} else if (bulletListManager.isDamNameSeletcted()
|
} else if (bulletListManager.isDamNameSeletcted()
|
||||||
&& bulletListManager.isDamCauseSelected()) {
|
&& bulletListManager.isDamCauseSelected()) {
|
||||||
damBreakThreatAreaPressed();
|
DamInfoBullet damBullet = bulletListManager
|
||||||
|
.getSelectedDamInfoBullet();
|
||||||
|
if (damBullet != null) {
|
||||||
|
damBreakThreatAreaPressed(damBullet.getCoords(), true);
|
||||||
|
}
|
||||||
if (damBreakInstruct != null) {
|
if (damBreakInstruct != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1323,9 +1372,28 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
} else {
|
} else {
|
||||||
new TemplateRunnerInitJob(backupSite).schedule();
|
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) {
|
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
|
* Responsible for drawing a pre-defined warning polygon (coords) on the
|
||||||
* the WarnGen layer. The method is called when a drainage basin is selected
|
* WarnGen layer.
|
||||||
* in the WarnGen Dialog Bullet List and the Dam Break Threat Area button is
|
|
||||||
* pressed. Dam info geometries are defined in the Database so a Spatial
|
|
||||||
* Query is performed to retrieve the data.
|
|
||||||
*
|
*
|
||||||
|
* @param coords
|
||||||
|
* pre-defined warning polygon coordinates in LAT...LON form.
|
||||||
|
* @param lockPolygon
|
||||||
|
* indicates if the polygon should be locked or not.
|
||||||
*/
|
*/
|
||||||
private void damBreakThreatAreaPressed() {
|
private void damBreakThreatAreaPressed(String coords, boolean lockPolygon) {
|
||||||
damBreakInstruct = "Either no dam selected, no dam info bullets in .xml file, or no\n"
|
damBreakInstruct = "Either no dam selected, no dam info bullets in .xml file, or no\n"
|
||||||
+ "dam break primary cause selected.";
|
+ "dam break primary cause selected.";
|
||||||
DamInfoBullet damBullet = bulletListManager.getSelectedDamInfoBullet();
|
|
||||||
if (damBullet != null) {
|
|
||||||
|
|
||||||
if ((damBullet.getCoords() == null)
|
if ((coords == null) || (coords.length() == 0)) {
|
||||||
|| (damBullet.getCoords().length() == 0)) {
|
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
||||||
damBreakInstruct = "LAT...LON can not be found in 'coords' parameter";
|
} else {
|
||||||
} else {
|
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
||||||
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
|
Pattern coordinatePtrn = Pattern
|
||||||
Pattern coordinatePtrn = Pattern
|
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
Pattern latLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
||||||
Pattern latLonPtrn = Pattern
|
|
||||||
.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
|
|
||||||
|
|
||||||
Matcher m = coordinatePtrn.matcher(damBullet.getCoords());
|
Matcher m = coordinatePtrn.matcher(coords);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
m = latLonPtrn.matcher(damBullet.getCoords());
|
m = latLonPtrn.matcher(coords);
|
||||||
while (m.find()) {
|
while (m.find()) {
|
||||||
coordinates.add(new Coordinate((-1 * Double
|
coordinates.add(new Coordinate((-1 * Double.parseDouble(m
|
||||||
.parseDouble(m.group(2))) / 100, Double
|
.group(2))) / 100,
|
||||||
.parseDouble(m.group(1)) / 100));
|
Double.parseDouble(m.group(1)) / 100));
|
||||||
}
|
|
||||||
|
|
||||||
if (coordinates.size() < 3) {
|
|
||||||
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
|
||||||
} else {
|
|
||||||
coordinates.add(coordinates.get(0));
|
|
||||||
PolygonUtil.truncate(coordinates, 2);
|
|
||||||
warngenLayer.createDamThreatArea(coordinates
|
|
||||||
.toArray(new Coordinate[coordinates.size()]));
|
|
||||||
setPolygonLocked(true);
|
|
||||||
warngenLayer.issueRefresh();
|
|
||||||
damBreakInstruct = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
|
||||||
+ "La/Lon for dam break threat area is not in pairs.";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (coordinates.size() < 3) {
|
||||||
|
damBreakInstruct = "Lat/Lon pair for dam break threat area is less than three";
|
||||||
|
} else {
|
||||||
|
coordinates.add(coordinates.get(0));
|
||||||
|
PolygonUtil.truncate(coordinates, 2);
|
||||||
|
warngenLayer.createDamThreatArea(coordinates
|
||||||
|
.toArray(new Coordinate[coordinates.size()]));
|
||||||
|
setPolygonLocked(lockPolygon);
|
||||||
|
warngenLayer.issueRefresh();
|
||||||
|
damBreakInstruct = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
damBreakInstruct = "The 'coords' parameter maybe be misformatted or the\n"
|
||||||
|
+ "La/Lon for dam break threat area is not in pairs.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (damBreakInstruct != null) {
|
if (damBreakInstruct != null) {
|
||||||
setInstructions();
|
setInstructions();
|
||||||
|
@ -1490,6 +1553,19 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by controls that can change the current template. Do not do
|
||||||
|
* anything if the request template is already selected. This 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
|
* 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
|
* 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) {
|
private void changeTemplate(String templateName) {
|
||||||
|
|
||||||
// DR 14515
|
|
||||||
if (templateName.equals(warngenLayer.getTemplateName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String lastAreaSource = warngenLayer.getConfiguration()
|
String lastAreaSource = warngenLayer.getConfiguration()
|
||||||
.getHatchedAreaSource().getAreaSource();
|
.getHatchedAreaSource().getAreaSource();
|
||||||
|
|
||||||
|
@ -1641,6 +1712,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
otherProducts = new HashMap<String, String>();
|
otherProducts = new HashMap<String, String>();
|
||||||
String[] otherProductsStr = warngenLayer.getDialogConfig()
|
String[] otherProductsStr = warngenLayer.getDialogConfig()
|
||||||
.getOtherWarngenProducts().split(",");
|
.getOtherWarngenProducts().split(",");
|
||||||
|
theList.removeAll();
|
||||||
for (String str : otherProductsStr) {
|
for (String str : otherProductsStr) {
|
||||||
String[] s = str.split("/");
|
String[] s = str.split("/");
|
||||||
otherProducts.put(s[0], s[1]);
|
otherProducts.put(s[0], s[1]);
|
||||||
|
@ -1791,7 +1863,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
templateName = otherProducts.get(otherProductListCbo
|
templateName = otherProducts.get(otherProductListCbo
|
||||||
.getItem(otherProductListCbo.getSelectionIndex()));
|
.getItem(otherProductListCbo.getSelectionIndex()));
|
||||||
}
|
}
|
||||||
changeTemplate(templateName);
|
uiChangeTemplate(templateName);
|
||||||
otherProductListCbo.pack(true);
|
otherProductListCbo.pack(true);
|
||||||
productType.layout();
|
productType.layout();
|
||||||
|
|
||||||
|
@ -2258,7 +2330,7 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
templateName = otherProducts.get(otherProductListCbo
|
templateName = otherProducts.get(otherProductListCbo
|
||||||
.getItem(otherProductListCbo.getSelectionIndex()));
|
.getItem(otherProductListCbo.getSelectionIndex()));
|
||||||
}
|
}
|
||||||
changeTemplate(templateName);
|
uiChangeTemplate(templateName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshDisplay() {
|
private void refreshDisplay() {
|
||||||
|
@ -2510,4 +2582,13 @@ public class WarngenDialog extends CaveSWTDialog implements
|
||||||
warngenLayer.issueRefresh();
|
warngenLayer.issueRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDefaultTemplate() {
|
||||||
|
String defaultTemplate = warngenLayer.getDialogConfig()
|
||||||
|
.getDefaultTemplate();
|
||||||
|
if ((defaultTemplate == null) || defaultTemplate.equals("")) {
|
||||||
|
defaultTemplate = mainProducts.get(0).split("/")[1];
|
||||||
|
}
|
||||||
|
return defaultTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,9 @@ import com.vividsolutions.jts.io.WKTReader;
|
||||||
* 04/28,2014 3033 jsanchez Properly handled back up configuration (*.xml) files. Set backupSite to null when backup site is not selected.
|
* 04/28,2014 3033 jsanchez Properly handled back up configuration (*.xml) files. Set backupSite to null when backup site is not selected.
|
||||||
* 05/16/2014 DR 17365 D. Friedman Check if moved vertex results in polygon valid in both lat/lon and local coordinates.
|
* 05/16/2014 DR 17365 D. Friedman Check if moved vertex results in polygon valid in both lat/lon and local coordinates.
|
||||||
* 06/23/2014 DR16322 m.gamazaychikov Fix Warngen unloading previously loaded maps.
|
* 06/23/2014 DR16322 m.gamazaychikov Fix Warngen unloading previously loaded maps.
|
||||||
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mschenke
|
* @author mschenke
|
||||||
|
@ -225,6 +228,9 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
|
|
||||||
String uniqueFip = null;
|
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 class GeospatialDataList {
|
||||||
|
|
||||||
private static final String LOCAL_GEOM = "localGeometry";
|
private static final String LOCAL_GEOM = "localGeometry";
|
||||||
|
@ -1107,6 +1113,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
DrawableString string = new DrawableString(text, textColor);
|
DrawableString string = new DrawableString(text, textColor);
|
||||||
string.magnification = magnification;
|
string.magnification = magnification;
|
||||||
string.setCoordinates(out[0], out[1]);
|
string.setCoordinates(out[0], out[1]);
|
||||||
|
string.horizontalAlignment = IGraphicsTarget.HorizontalAlignment.CENTER;
|
||||||
|
string.verticallAlignment = IGraphicsTarget.VerticalAlignment.MIDDLE;
|
||||||
strings.add(string);
|
strings.add(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,6 +1198,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
}// end synchronize
|
}// end synchronize
|
||||||
customMaps.loadCustomMaps(Arrays.asList(config.getMaps()));
|
customMaps.loadCustomMaps(Arrays.asList(config.getMaps()));
|
||||||
|
|
||||||
|
createAreaAndCentroidMaps();
|
||||||
|
|
||||||
this.configuration = config;
|
this.configuration = config;
|
||||||
System.out.println("Total time to init warngen config = "
|
System.out.println("Total time to init warngen config = "
|
||||||
+ (System.currentTimeMillis() - t0) + "ms");
|
+ (System.currentTimeMillis() - t0) + "ms");
|
||||||
|
@ -1392,6 +1402,49 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
} else {
|
} else {
|
||||||
backupSite = site;
|
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() {
|
public String getLocalizedSite() {
|
||||||
|
@ -3162,66 +3215,127 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
toKeep.toArray(new Geometry[0]));
|
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
|
* Populate the W strings with the included counties
|
||||||
*/
|
*/
|
||||||
private void populateStrings() {
|
private void populateStrings() {
|
||||||
state.strings.clear();
|
state.strings.clear();
|
||||||
|
Geometry warningArea = state.getWarningArea();
|
||||||
Set<String> prefixes = new HashSet<String>(Arrays.asList(GeometryUtil
|
Set<String> prefixes = new HashSet<String>(Arrays.asList(GeometryUtil
|
||||||
.getGID(state.getWarningArea())));
|
.getGID(warningArea)));
|
||||||
|
|
||||||
prefixes = removeDuplicateGid(prefixes);
|
prefixes = removeDuplicateGid(prefixes);
|
||||||
|
|
||||||
for (GeospatialData f : geoData.features) {
|
Set<Integer> indexes = new HashSet<Integer>();
|
||||||
Geometry geom = f.geometry;
|
String prefixM, prefixN;
|
||||||
Geometry geom2 = null;
|
double areaM, areaN, maxArea = -1.0;
|
||||||
Geometry warningAreaN = null;
|
int geomIndex = -1;
|
||||||
Coordinate populatePt = null;
|
int geomNum = warningArea.getNumGeometries();
|
||||||
Geometry populatePtGeom;
|
// Find an unique index for each county in warningArea. If there is more than one index
|
||||||
boolean contained = false, closeTo = false;
|
// for one county, find the one with max area.
|
||||||
double shift = 1.E-8, distance, minDistance = 10.0;
|
Geometry warningAreaM = null, warningAreaN = null;
|
||||||
int loop, maxLoop = 10;
|
for (int i = 0; i < geomNum; i++) {
|
||||||
Geometry warningArea = state.getWarningArea();
|
warningAreaM = warningArea.getGeometryN(i);
|
||||||
String prefix = GeometryUtil.getPrefix(geom.getUserData());
|
prefixM = GeometryUtil.getPrefix(warningAreaM.getUserData());
|
||||||
if (prefixes.contains(prefix)) {
|
if (!prefixes.contains(prefixM)) {
|
||||||
loop = 0;
|
continue;
|
||||||
warningAreaN = findLargestGeometry(GeometryUtil.intersection(geom, warningArea));
|
}
|
||||||
do {
|
areaM = warningAreaM.getArea();
|
||||||
if (!warningAreaN.isEmpty()) {
|
geomIndex = i;
|
||||||
populatePt = GisUtil.d2dCoordinate(warningAreaN.getCentroid()
|
while (i + 1 < geomNum) {
|
||||||
.getCoordinate());
|
warningAreaN = warningArea.getGeometryN(i + 1);
|
||||||
for (GeospatialData f2 : geoData.features) {
|
prefixN = GeometryUtil.getPrefix(warningAreaN.getUserData());
|
||||||
geom2 = f2.getGeometry();
|
if (prefixN.equals(prefixM)) {
|
||||||
if (!GeometryUtil.getPrefix(geom2.getUserData()).equals(prefix)) {
|
areaN = warningAreaN.getArea();
|
||||||
contained = false;
|
if (areaN > areaM) {
|
||||||
closeTo = false;
|
if (areaN > maxArea) {
|
||||||
populatePtGeom = PolygonUtil.createPolygonByPoints(populatePt,
|
maxArea = areaN;
|
||||||
new Coordinate(populatePt.x + shift, populatePt.y + shift));
|
geomIndex = i + 1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// use the existing populatePt
|
if (areaM > maxArea) {
|
||||||
break;
|
maxArea = areaM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loop += 1;
|
} else {
|
||||||
} while ((contained || closeTo) && loop <= maxLoop);
|
break;
|
||||||
state.strings.put(populatePt, "W");
|
}
|
||||||
|
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) {
|
public boolean featureProduct(Coordinate c) {
|
||||||
|
@ -3498,21 +3612,6 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
* A Geometry or a GeometryCollection.
|
* A Geometry or a GeometryCollection.
|
||||||
* @return Geometry
|
* @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.
|
* 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.
|
* The geometry of a county/zone.
|
||||||
* @return Geometry
|
* @return Geometry
|
||||||
* The geometey of largest quadrant among the four, which are the result of
|
* 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) {
|
private Geometry findLargestQuadrant(GeometryFactory gf, Geometry geom) {
|
||||||
Geometry envelope = hatchedArea.getEnvelope();
|
Geometry envelope = geom.getEnvelope();
|
||||||
Coordinate centroidCoord = GisUtil.d2dCoordinate(envelope.getCentroid()
|
Coordinate centroidCoord = GisUtil.d2dCoordinate(envelope.getCentroid()
|
||||||
.getCoordinate());
|
.getCoordinate());
|
||||||
Coordinate[] envCoords = envelope.getCoordinates();
|
Coordinate[] envCoords = envelope.getCoordinates();
|
||||||
|
@ -3536,19 +3635,22 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
double largestArea = -1.0, area = -1.0;
|
double largestArea = -1.0, area = -1.0;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
quadrants[i] = PolygonUtil.createPolygonByPoints(envCoords[i], centroidCoord);
|
quadrants[i] = PolygonUtil.createPolygonByPoints(gf, envCoords[i], centroidCoord);
|
||||||
intersections[i] = GeometryUtil.intersection(quadrants[i], hatchedArea);
|
try {
|
||||||
area = intersections[i].getArea();
|
intersections[i] = GeometryUtil.intersection(quadrants[i], geom);
|
||||||
if (area > largestArea) {
|
area = intersections[i].getArea();
|
||||||
largestArea = area;
|
if (area > largestArea) {
|
||||||
index = i;
|
largestArea = area;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (intersections[index].isValid())
|
if (null != intersections[index] && intersections[index].isValid())
|
||||||
return intersections[index];
|
return intersections[index];
|
||||||
else {
|
else {
|
||||||
// "intersections[" + index + "] is invalid"
|
return geom;
|
||||||
return hatchedArea;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3564,4 +3666,5 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
||||||
StormTrackState.trackType = "lineOfStorms";
|
StormTrackState.trackType = "lineOfStorms";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,42 +37,25 @@ import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.measure.converter.UnitConverter;
|
|
||||||
import javax.measure.unit.NonSI;
|
|
||||||
import javax.measure.unit.SI;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.apache.velocity.Template;
|
import org.apache.velocity.Template;
|
||||||
import org.apache.velocity.VelocityContext;
|
import org.apache.velocity.VelocityContext;
|
||||||
import org.apache.velocity.app.Velocity;
|
import org.apache.velocity.app.Velocity;
|
||||||
import org.apache.velocity.app.VelocityEngine;
|
import org.apache.velocity.app.VelocityEngine;
|
||||||
import org.apache.velocity.tools.generic.ListTool;
|
import org.apache.velocity.tools.generic.ListTool;
|
||||||
|
|
||||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
|
||||||
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
|
|
||||||
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
import com.raytheon.uf.common.dataplugin.warning.WarningConstants;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration.AreaType;
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData;
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.portions.GisUtil;
|
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.portions.PortionsUtil;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
|
||||||
import com.raytheon.uf.common.dataquery.requests.DbQueryRequest;
|
|
||||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
|
||||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
|
|
||||||
import com.raytheon.uf.common.dataquery.responses.DbQueryResponse;
|
|
||||||
import com.raytheon.uf.common.localization.IPathManager;
|
import com.raytheon.uf.common.localization.IPathManager;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||||
|
@ -84,11 +67,9 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
import com.raytheon.uf.common.time.SimulatedTime;
|
import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
|
||||||
import com.raytheon.uf.common.util.FileUtil;
|
import com.raytheon.uf.common.util.FileUtil;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
|
||||||
import com.raytheon.viz.awipstools.ToolsDataManager;
|
import com.raytheon.viz.awipstools.ToolsDataManager;
|
||||||
import com.raytheon.viz.awipstools.common.StormTrackData;
|
import com.raytheon.viz.awipstools.common.StormTrackData;
|
||||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||||
|
@ -99,6 +80,8 @@ import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
import com.raytheon.viz.warngen.gis.Area;
|
import com.raytheon.viz.warngen.gis.Area;
|
||||||
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
import com.raytheon.viz.warngen.gis.ClosestPointComparator;
|
||||||
import com.raytheon.viz.warngen.gis.PathCast;
|
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.gis.Wx;
|
||||||
import com.raytheon.viz.warngen.gui.BackupData;
|
import com.raytheon.viz.warngen.gui.BackupData;
|
||||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
import com.raytheon.viz.warngen.gui.FollowupData;
|
||||||
|
@ -111,9 +94,6 @@ import com.raytheon.viz.warngen.util.CurrentWarnings;
|
||||||
import com.raytheon.viz.warngen.util.FipsUtil;
|
import com.raytheon.viz.warngen.util.FipsUtil;
|
||||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||||
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
||||||
import com.raytheon.viz.warngen.util.WatchUtil;
|
|
||||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch;
|
|
||||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch.Portion;
|
|
||||||
import com.raytheon.viz.warnings.DateUtil;
|
import com.raytheon.viz.warnings.DateUtil;
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
@ -160,6 +140,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
||||||
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
|
* Mar 17, 2014 DR 16309 Qinglu Lin Updated getWatches(), processATEntries() and determineAffectedPortions(), and
|
||||||
* added determineAffectedMarinePortions().
|
* added determineAffectedMarinePortions().
|
||||||
* Apr 28, 2014 3033 jsanchez Set the site and backup site in Velocity Engine's properties
|
* Apr 28, 2014 3033 jsanchez Set the site and backup site in Velocity Engine's properties
|
||||||
|
* Jul 21, 2014 3419 jsanchez Refactored WatchUtil.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author njensen
|
* @author njensen
|
||||||
|
@ -172,16 +153,13 @@ public class TemplateRunner {
|
||||||
|
|
||||||
private static final String LOGIN_NAME_KEY = "LOGNAME";
|
private static final String LOGIN_NAME_KEY = "LOGNAME";
|
||||||
|
|
||||||
private static final UnitConverter milesToKilometer = NonSI.MILE
|
|
||||||
.getConverterTo(SI.KILOMETER);
|
|
||||||
|
|
||||||
private static final double KmToDegrees = 111.12;
|
|
||||||
|
|
||||||
private static final Pattern BBB_PATTERN = Pattern
|
private static final Pattern BBB_PATTERN = Pattern
|
||||||
.compile(".*\\sCC([A-Z])");
|
.compile(".*\\sCC([A-Z])");
|
||||||
|
|
||||||
private static Hashtable<String, DateFormat> dateFormat;
|
private static Hashtable<String, DateFormat> dateFormat;
|
||||||
|
|
||||||
|
private static WatchUtil watchUtil;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
dateFormat = new Hashtable<String, DateFormat>();
|
dateFormat = new Hashtable<String, DateFormat>();
|
||||||
dateFormat
|
dateFormat
|
||||||
|
@ -876,11 +854,14 @@ public class TemplateRunner {
|
||||||
// Store Watches
|
// Store Watches
|
||||||
try {
|
try {
|
||||||
t0 = System.currentTimeMillis();
|
t0 = System.currentTimeMillis();
|
||||||
WatchUtil watches = getWatches(warngenLayer, config, warnPolygon,
|
if (watchUtil == null) {
|
||||||
areas, fourLetterSiteId, simulatedTime);
|
watchUtil = new WatchUtil(warngenLayer);
|
||||||
|
}
|
||||||
|
List<Watch> watches = watchUtil.getWatches(config, warnPolygon,
|
||||||
|
simulatedTime);
|
||||||
System.out.println("getWatches time: "
|
System.out.println("getWatches time: "
|
||||||
+ (System.currentTimeMillis() - t0));
|
+ (System.currentTimeMillis() - t0));
|
||||||
if (watches != null) {
|
if (watches != null && watches.isEmpty() == false) {
|
||||||
context.put("watches", watches);
|
context.put("watches", watches);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -980,574 +961,4 @@ public class TemplateRunner {
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method populates a WatchUtil object with tornado and severe
|
|
||||||
* thunderstorm watches from the active table that are contained by the
|
|
||||||
* polygon. Furthermore, watches that have not yet expired (current time <
|
|
||||||
* end time) are only included.
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* WarnGen template configuration settings
|
|
||||||
* ([template_name_site.xml])
|
|
||||||
* @param polygon
|
|
||||||
* The Geometry surrounded by the warning polygon.
|
|
||||||
* @param simulatedTime
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private static WatchUtil getWatches(WarngenLayer warngenLayer,
|
|
||||||
WarngenConfiguration config, Geometry polygon,
|
|
||||||
AffectedAreas[] affectedAreas, String fourLetterSiteId,
|
|
||||||
Date simulatedTime) throws Exception {
|
|
||||||
Validate.isTrue(config.getHatchedAreaSource()
|
|
||||||
.getIncludedWatchAreaBuffer() >= 0,
|
|
||||||
"IncludedWatchAreaBuffer can not be negative");
|
|
||||||
|
|
||||||
WatchUtil rval = null;
|
|
||||||
String[] includedWatches = config.getIncludedWatches();
|
|
||||||
|
|
||||||
if ((includedWatches != null) && (includedWatches.length > 0)) {
|
|
||||||
String phensigList = null;
|
|
||||||
for (String includedWatch : includedWatches) {
|
|
||||||
if (includedWatch.equalsIgnoreCase("torWatches")) {
|
|
||||||
phensigList = phensigList == null ? "TO.A" : phensigList
|
|
||||||
+ ",TO.A";
|
|
||||||
} else if (includedWatch.equalsIgnoreCase("svrWatches")) {
|
|
||||||
phensigList = phensigList == null ? "SV.A" : phensigList
|
|
||||||
+ ",SV.A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phensigList != null) {
|
|
||||||
// Create start/endtime constraints
|
|
||||||
Date endConstraintTime = simulatedTime;
|
|
||||||
Calendar cal = Calendar.getInstance();
|
|
||||||
cal.setTime(simulatedTime);
|
|
||||||
cal.add(Calendar.MINUTE, 3);
|
|
||||||
Date startConstraintTime = cal.getTime();
|
|
||||||
|
|
||||||
// Get record type
|
|
||||||
Class<? extends ActiveTableRecord> recordType = CAVEMode
|
|
||||||
.getMode() == CAVEMode.OPERATIONAL ? OperationalActiveTableRecord.class
|
|
||||||
: PracticeActiveTableRecord.class;
|
|
||||||
|
|
||||||
DbQueryRequest request = new DbQueryRequest();
|
|
||||||
request.setEntityClass(recordType);
|
|
||||||
request.addConstraint("startTime", new RequestConstraint(
|
|
||||||
TimeUtil.formatDate(startConstraintTime),
|
|
||||||
ConstraintType.LESS_THAN_EQUALS));
|
|
||||||
request.addConstraint(
|
|
||||||
"endTime",
|
|
||||||
new RequestConstraint(TimeUtil
|
|
||||||
.formatDate(endConstraintTime),
|
|
||||||
ConstraintType.GREATER_THAN_EQUALS));
|
|
||||||
/*
|
|
||||||
* TODO: Currently limited to filtering out one of
|
|
||||||
* ("CAN","EXP"). Could use "Act" in addition to "act", but this
|
|
||||||
* should really be fixed the underlying system.
|
|
||||||
* request.addConstraint("act", new RequestConstraint("CAN",
|
|
||||||
* ConstraintType.NOT_EQUALS));
|
|
||||||
*/
|
|
||||||
request.addConstraint("act", new RequestConstraint("EXP",
|
|
||||||
ConstraintType.NOT_EQUALS));
|
|
||||||
request.addConstraint("phensig", new RequestConstraint(
|
|
||||||
phensigList, ConstraintType.IN));
|
|
||||||
|
|
||||||
// TODO: Talk to Jonathan about this... Do I even need officeid
|
|
||||||
// IN or is ugc zone good enough?
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get all UGCs in the CWA now so that the watches will be
|
|
||||||
* formatted with all portions of the affected state(s).
|
|
||||||
*
|
|
||||||
* Filtering for valid UGCs is performed in processATEntries
|
|
||||||
*/
|
|
||||||
RequestConstraint ugcConstraint = new RequestConstraint("",
|
|
||||||
ConstraintType.IN);
|
|
||||||
ugcConstraint.setConstraintValueList(warngenLayer
|
|
||||||
.getAllUgcs());
|
|
||||||
request.addConstraint("ugcZone", ugcConstraint);
|
|
||||||
|
|
||||||
// These are the only fields we need for processing watches
|
|
||||||
request.addFields(new String[] { "issueTime", "startTime",
|
|
||||||
"endTime", "ugcZone", "phensig", "vtecstr", "etn",
|
|
||||||
"act" });
|
|
||||||
|
|
||||||
DbQueryResponse response = (DbQueryResponse) ThriftClient
|
|
||||||
.sendRequest(request);
|
|
||||||
|
|
||||||
List<ActiveTableRecord> records = new ArrayList<ActiveTableRecord>(
|
|
||||||
response.getNumResults());
|
|
||||||
for (Map<String, Object> result : response.getResults()) {
|
|
||||||
/*
|
|
||||||
* TODO: Doing this here because only "EXP" is filtered out
|
|
||||||
* by the query. Remove "act" from the field list once this
|
|
||||||
* is fixed.
|
|
||||||
*/
|
|
||||||
if ("CAN".equals(result.get("act")))
|
|
||||||
continue;
|
|
||||||
ActiveTableRecord record = recordType.newInstance();
|
|
||||||
record.setIssueTime((Calendar) result.get("issueTime"));
|
|
||||||
record.setStartTime((Calendar) result.get("startTime"));
|
|
||||||
record.setEndTime((Calendar) result.get("endTime"));
|
|
||||||
record.setUgcZone((String) result.get("ugcZone"));
|
|
||||||
record.setPhensig((String) result.get("phensig"));
|
|
||||||
record.setVtecstr((String) result.get("vtecstr"));
|
|
||||||
record.setEtn((String) result.get("etn"));
|
|
||||||
records.add(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (records.size() > 0) {
|
|
||||||
Set<String> validUgcZones;
|
|
||||||
try {
|
|
||||||
long t0, t1;
|
|
||||||
t0 = System.currentTimeMillis();
|
|
||||||
Polygon watchArea = (Polygon) polygon
|
|
||||||
.buffer(milesToKilometer.convert(config
|
|
||||||
.getHatchedAreaSource()
|
|
||||||
.getIncludedWatchAreaBuffer())
|
|
||||||
/ KmToDegrees);
|
|
||||||
t1 = System.currentTimeMillis();
|
|
||||||
System.out.println("getWatches.polygonBuffer time: "
|
|
||||||
+ (t1 - t0));
|
|
||||||
validUgcZones = warngenLayer
|
|
||||||
.getUgcsForWatches(watchArea);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.ERROR,
|
|
||||||
"Error determining areas to search for watches.",
|
|
||||||
e);
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
rval = processATEntries(records, warngenLayer,
|
|
||||||
validUgcZones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WatchWork {
|
|
||||||
public WeatherAdvisoryWatch waw;
|
|
||||||
|
|
||||||
public boolean valid;
|
|
||||||
|
|
||||||
public ArrayList<String> ugcZone = new ArrayList<String>();
|
|
||||||
|
|
||||||
public WatchWork(WeatherAdvisoryWatch waw) {
|
|
||||||
this.waw = waw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the list of objects representing active watches that will be
|
|
||||||
* passed to the template context.
|
|
||||||
*
|
|
||||||
* @param activeTable
|
|
||||||
* List of entries for active watches
|
|
||||||
* @param warngenLayer
|
|
||||||
* @param validUgcZones
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static WatchUtil processATEntries(
|
|
||||||
List<ActiveTableRecord> activeTable, WarngenLayer warngenLayer,
|
|
||||||
Set<String> validUgcZones) {
|
|
||||||
WatchUtil rval = new WatchUtil();
|
|
||||||
TreeMap<WeatherAdvisoryWatch, WatchWork> map = new TreeMap<WeatherAdvisoryWatch, TemplateRunner.WatchWork>();
|
|
||||||
|
|
||||||
AreaSourceConfiguration asc = null;
|
|
||||||
for (AreaSourceConfiguration a : warngenLayer.getConfiguration()
|
|
||||||
.getAreaSources()) {
|
|
||||||
if (a.getType() == AreaType.HATCHING) {
|
|
||||||
asc = a;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (asc == null) {
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.ERROR,
|
|
||||||
"Cannot process watches: missing HATCHING area source configuration");
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
GeospatialData[] geoData = warngenLayer.getGeodataFeatures(
|
|
||||||
asc.getAreaSource(), warngenLayer.getLocalizedSite());
|
|
||||||
if ((geoData == null) || (geoData.length == 0)) {
|
|
||||||
statusHandler.handle(Priority.ERROR,
|
|
||||||
"Cannot process watches: cannot get geospatial data");
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each watch event, get the end time and list of active zones
|
|
||||||
for (ActiveTableRecord ar : activeTable) {
|
|
||||||
/*
|
|
||||||
* Currently reports all zones in the watch even if a given zone is
|
|
||||||
* not in the warning polygon. If the logic is changed to only show
|
|
||||||
* the portions of the watch near our warning polygon, filter on
|
|
||||||
* validUgcZones here.
|
|
||||||
*/
|
|
||||||
WeatherAdvisoryWatch waw = new WeatherAdvisoryWatch();
|
|
||||||
waw.setPhensig(ar.getPhensig());
|
|
||||||
try {
|
|
||||||
waw.setEventId(Integer.parseInt(ar.getEtn()));
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
statusHandler.handle(Priority.ERROR, String.format(
|
|
||||||
"Watch %s has null end time; not included.",
|
|
||||||
ar.getVtecstr()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
WatchWork work = map.get(waw);
|
|
||||||
if (work == null) {
|
|
||||||
waw.setEndTime(ar.getEndTime().getTime());
|
|
||||||
work = new WatchWork(waw);
|
|
||||||
map.put(waw, work);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validUgcZones.contains(ar.getUgcZone())) {
|
|
||||||
work.valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are no checks here to determine whether or not the given
|
|
||||||
* zone is in the CWA. That should have already been done the query
|
|
||||||
* performed in getWatches.
|
|
||||||
*
|
|
||||||
* There is also validation performed later in
|
|
||||||
* determineAffectedPortions.
|
|
||||||
*/
|
|
||||||
work.ugcZone.add(ar.getUgcZone());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (WatchWork work : map.values()) {
|
|
||||||
/*
|
|
||||||
* If none of the areas in the watch were neer our warning polygon,
|
|
||||||
* do not included it.
|
|
||||||
*/
|
|
||||||
if (!work.valid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean isMarineZone = warngenLayer.getConfiguration().getGeospatialConfig()
|
|
||||||
.getAreaSource().equalsIgnoreCase(WarngenLayer.MARINE);
|
|
||||||
if (!isMarineZone) {
|
|
||||||
if (determineAffectedPortions(work.ugcZone, asc, geoData, work.waw)) {
|
|
||||||
rval.addWaw(work.waw);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (determineAffectedMarinePortions(work.ugcZone, asc, geoData, work.waw)) {
|
|
||||||
rval.addWaw(work.waw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the list of counties in a watch, fill out the "portions" part of
|
|
||||||
* the given WeatherAdvisoryWatch. Also checks if the given counties are
|
|
||||||
* actually in the CWA.
|
|
||||||
*
|
|
||||||
* @param ugcs
|
|
||||||
* @param asc
|
|
||||||
* @param geoData
|
|
||||||
* @param waw
|
|
||||||
*/
|
|
||||||
private static boolean determineAffectedPortions(List<String> ugcs,
|
|
||||||
AreaSourceConfiguration asc, GeospatialData[] geoData,
|
|
||||||
WeatherAdvisoryWatch waw) {
|
|
||||||
|
|
||||||
// Maps state abbreviation to unique fe_area values
|
|
||||||
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
|
|
||||||
|
|
||||||
for (String ugc : ugcs) {
|
|
||||||
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "County");
|
|
||||||
Entry<String, String[]> e = null;
|
|
||||||
|
|
||||||
// Either zero or more than one sates/counties would be wrong
|
|
||||||
if ((parsed.size() != 1)
|
|
||||||
|| ((e = parsed.entrySet().iterator().next()).getValue().length != 1)) {
|
|
||||||
statusHandler.handle(Priority.ERROR,
|
|
||||||
"Invalid ugczone in active table entry: " + ugc);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String stateAbbrev = e.getKey();
|
|
||||||
String feArea = null;
|
|
||||||
try {
|
|
||||||
feArea = getFeArea(stateAbbrev, e.getValue()[0], asc, geoData);
|
|
||||||
} catch (RuntimeException exc) {
|
|
||||||
statusHandler.handle(Priority.ERROR,
|
|
||||||
"Error generating included watches.", exc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (feArea == NOT_IN_CWA) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> feAreas = map.get(stateAbbrev);
|
|
||||||
if (feAreas == null) {
|
|
||||||
feAreas = new HashSet<String>();
|
|
||||||
map.put(stateAbbrev, feAreas);
|
|
||||||
}
|
|
||||||
if (feArea != null) {
|
|
||||||
feAreas.add(feArea);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
|
|
||||||
for (Entry<String, Set<String>> e : map.entrySet()) {
|
|
||||||
Portion portion = new Portion();
|
|
||||||
try {
|
|
||||||
portion.parentRegion = getStateName(e.getKey(), asc, geoData)
|
|
||||||
.toUpperCase();
|
|
||||||
} catch (RuntimeException exc) {
|
|
||||||
statusHandler.handle(Priority.ERROR,
|
|
||||||
"Error generating included watches.", exc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
portion.partOfParentRegion = Area
|
|
||||||
.converFeAreaToPartList(mungeFeAreas(e.getValue()));
|
|
||||||
portions.add(portion);
|
|
||||||
}
|
|
||||||
waw.setPortions(portions);
|
|
||||||
// Set legacy values
|
|
||||||
if (portions.size() > 0) {
|
|
||||||
waw.setParentRegion(portions.get(0).parentRegion);
|
|
||||||
waw.setPartOfParentRegion(portions.get(0).partOfParentRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the list of marine zones in a watch, fill out the "portions" part of
|
|
||||||
* the given WeatherAdvisoryWatch. Also checks if the given marine zones are
|
|
||||||
* actually in the CWA.
|
|
||||||
*
|
|
||||||
* @param ugcs
|
|
||||||
* @param asc
|
|
||||||
* @param geoData
|
|
||||||
* @param waw
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private static boolean determineAffectedMarinePortions(List<String> ugcs,
|
|
||||||
AreaSourceConfiguration asc, GeospatialData[] geoData,
|
|
||||||
WeatherAdvisoryWatch waw) {
|
|
||||||
|
|
||||||
// Maps state abbreviation to unique fe_area values
|
|
||||||
HashMap<String, Set<String>> map = new HashMap<String, Set<String>>();
|
|
||||||
Set<String> marinezonenameSet = new HashSet<String>();
|
|
||||||
for (String ugc : ugcs) {
|
|
||||||
for (GeospatialData gd: geoData) {
|
|
||||||
|
|
||||||
if (gd.attributes.get("ID").equals(ugc)) {
|
|
||||||
marinezonenameSet.add((String)gd.attributes.get("NAME"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String marinezonename = "";
|
|
||||||
int size = marinezonenameSet.size();
|
|
||||||
Iterator<String> iter = marinezonenameSet.iterator();
|
|
||||||
int count = 0;
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
String s = iter.next();
|
|
||||||
marinezonename += s;
|
|
||||||
count += 1;
|
|
||||||
if (size > 1) {
|
|
||||||
if (size == 2 && count < 2) {
|
|
||||||
marinezonename += " and ";
|
|
||||||
} else {
|
|
||||||
if (count == size - 1) {
|
|
||||||
marinezonename += ", and ";
|
|
||||||
} else {
|
|
||||||
if (count < size - 1) {
|
|
||||||
marinezonename += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String ugc : ugcs) {
|
|
||||||
Map<String, String[]> parsed = FipsUtil.parseHeader(ugc, "Marine");
|
|
||||||
Entry<String, String[]> e = null;
|
|
||||||
|
|
||||||
// Either zero or more than one marine zone would be wrong
|
|
||||||
if ((parsed.size() != 1)
|
|
||||||
|| ((e = parsed.entrySet().iterator().next()).getValue().length != 1)) {
|
|
||||||
statusHandler.handle(Priority.ERROR,
|
|
||||||
"Invalid ugczone in active table entry: " + ugc);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String stateAbbrev = e.getKey();
|
|
||||||
Set<String> feAreas = map.get(stateAbbrev);
|
|
||||||
if (feAreas == null) {
|
|
||||||
feAreas = new HashSet<String>();
|
|
||||||
map.put(stateAbbrev, feAreas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Portion> portions = new ArrayList<Portion>(map.size());
|
|
||||||
Portion portion = new Portion();
|
|
||||||
portion.parentRegion = marinezonename;
|
|
||||||
portion.partOfParentRegion = new ArrayList<String>();
|
|
||||||
portion.partOfParentRegion.add("");
|
|
||||||
portions.add(portion);
|
|
||||||
waw.setPortions(portions);
|
|
||||||
// Set legacy values
|
|
||||||
if (portions.size() > 0) {
|
|
||||||
waw.setParentRegion(portions.get(0).parentRegion);
|
|
||||||
waw.setPartOfParentRegion(portions.get(0).partOfParentRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Based on AWIPS 1 SELSparagraphs.C SELSparagraphs::processWOU().
|
|
||||||
private static String mungeFeAreas(Set<String> feAreas) {
|
|
||||||
String abrev = "";
|
|
||||||
// If eight or more portions, don't qualify area of state
|
|
||||||
int m = feAreas.size();
|
|
||||||
if (m < 8) {
|
|
||||||
String partAbrev = "";
|
|
||||||
/*
|
|
||||||
* TODO: Unused variables should be removed if we are not going to
|
|
||||||
* improve this in A2.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
int nw, nc, ne, wc, cc, ec, sw, sc, se, pa;
|
|
||||||
int eee, www, nnn, sss, ee, ww, nn, ss;
|
|
||||||
|
|
||||||
// Identify individual sub areas of this state affected
|
|
||||||
nw = nc = ne = wc = cc = ec = sw = sc = se = pa = 0;
|
|
||||||
eee = www = nnn = sss = ee = ww = nn = ss = 0;
|
|
||||||
for (String part : feAreas) {
|
|
||||||
if ("pa".equals(part)) {
|
|
||||||
pa = 1;
|
|
||||||
continue;
|
|
||||||
} else if ("nn".equals(part)) {
|
|
||||||
nnn = nn = 1;
|
|
||||||
} else if ("ss".equals(part)) {
|
|
||||||
sss = ss = 1;
|
|
||||||
} else if ("ee".equals(part)) {
|
|
||||||
eee = ee = 1;
|
|
||||||
} else if ("ww".equals(part)) {
|
|
||||||
www = ww = 1;
|
|
||||||
} else if ("nw".equals(part)) {
|
|
||||||
nnn = www = nw = 1;
|
|
||||||
} else if ("nc".equals(part)) {
|
|
||||||
nnn = nc = 1;
|
|
||||||
} else if ("ne".equals(part)) {
|
|
||||||
nnn = eee = ne = 1;
|
|
||||||
} else if ("wc".equals(part)) {
|
|
||||||
www = wc = 1;
|
|
||||||
} else if ("cc".equals(part)) {
|
|
||||||
cc = 1;
|
|
||||||
continue;
|
|
||||||
} else if ("ec".equals(part)) {
|
|
||||||
eee = ec = 1;
|
|
||||||
} else if ("sw".equals(part)) {
|
|
||||||
sss = www = sw = 1;
|
|
||||||
} else if ("sc".equals(part)) {
|
|
||||||
sss = sc = 1;
|
|
||||||
} else if ("se".equals(part)) {
|
|
||||||
sss = eee = se = 1;
|
|
||||||
}
|
|
||||||
partAbrev = part;
|
|
||||||
}
|
|
||||||
// decide how to describe these subareas.
|
|
||||||
if ((ne > 0) && (nw > 0)) {
|
|
||||||
nn = 1;
|
|
||||||
}
|
|
||||||
if ((se > 0) && (sw > 0)) {
|
|
||||||
ss = 1;
|
|
||||||
}
|
|
||||||
if ((se > 0) && (ne > 0)) {
|
|
||||||
ee = 1;
|
|
||||||
}
|
|
||||||
if ((sw > 0) && (nw > 0)) {
|
|
||||||
ww = 1;
|
|
||||||
}
|
|
||||||
if ((nnn > 0) && (sss > 0) && (eee > 0) && (www > 0)) {
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
if (((nn > 0) && (ss > 0)) || ((ee > 0) && (ww > 0))) {
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
if (nnn + sss + eee + www == 3) {
|
|
||||||
if (www == 0) {
|
|
||||||
abrev = "e";
|
|
||||||
} else if (eee == 0) {
|
|
||||||
abrev = "w";
|
|
||||||
} else if (nnn == 0) {
|
|
||||||
abrev = "s";
|
|
||||||
} else if (sss == 0) {
|
|
||||||
abrev = "n";
|
|
||||||
}
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
if (((nnn == sss) && (eee == www)) || (cc == m)) {
|
|
||||||
abrev = "c";
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
if ((pa != 0) && (cc == 0)) {
|
|
||||||
abrev = "pa";
|
|
||||||
if (--m <= 0) {
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m == 1 + cc) {
|
|
||||||
abrev += partAbrev + " ";
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
if (nnn != sss) {
|
|
||||||
abrev += nnn != 0 ? "n" : "s";
|
|
||||||
}
|
|
||||||
if (eee != www) {
|
|
||||||
abrev += eee != 0 ? "e" : "w";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return abrev;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getStateName(String key, AreaSourceConfiguration asc,
|
|
||||||
GeospatialData[] geoData) {
|
|
||||||
for (GeospatialData g : geoData) {
|
|
||||||
if (key.equals(g.attributes.get("STATE"))) {
|
|
||||||
return (String) g.parent.attributes.get("NAME");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String NOT_IN_CWA = new String("NOT_IN_CWA");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the given UGC is in the CWA and if it is, returns the
|
|
||||||
* portion of the CWA.
|
|
||||||
*
|
|
||||||
* @param stateAbbrev
|
|
||||||
* @param ugc
|
|
||||||
* @param asc
|
|
||||||
* @param geoData
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String getFeArea(String stateAbbrev, String ugc,
|
|
||||||
AreaSourceConfiguration asc, GeospatialData[] geoData) {
|
|
||||||
for (GeospatialData g : geoData) {
|
|
||||||
if (stateAbbrev.equals(g.attributes.get("STATE"))
|
|
||||||
&& ((String) g.attributes.get(asc.getFipsField()))
|
|
||||||
.endsWith(ugc)) {
|
|
||||||
return (String) g.attributes.get(asc.getFeAreaField());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Is this the correct way to determine if the county is in the
|
|
||||||
// CWA?
|
|
||||||
return NOT_IN_CWA;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.viz.warngen.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This utility will provide an object to be sent into velocity templates which
|
|
||||||
* will allow the template to output current Warnings.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 1, 2009 bwoodle Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bwoodle
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class WatchUtil {
|
|
||||||
|
|
||||||
private Date latestTorTime;
|
|
||||||
|
|
||||||
private Date latestSvrTime;
|
|
||||||
|
|
||||||
private ArrayList<WeatherAdvisoryWatch> torWatches;
|
|
||||||
|
|
||||||
private ArrayList<WeatherAdvisoryWatch> svrWatches;
|
|
||||||
|
|
||||||
public WatchUtil() {
|
|
||||||
torWatches = new ArrayList<WeatherAdvisoryWatch>();
|
|
||||||
svrWatches = new ArrayList<WeatherAdvisoryWatch>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addWaw(WeatherAdvisoryWatch watch) {
|
|
||||||
if (watch.getPhensig().equalsIgnoreCase("SV.A")) {
|
|
||||||
svrWatches.add(watch);
|
|
||||||
if (latestSvrTime == null
|
|
||||||
|| watch.getEndTime().after(latestSvrTime)) {
|
|
||||||
latestSvrTime = watch.getEndTime();
|
|
||||||
}
|
|
||||||
} else if (watch.getPhensig().equalsIgnoreCase("TO.A")) {
|
|
||||||
torWatches.add(watch);
|
|
||||||
if (latestTorTime == null
|
|
||||||
|| watch.getEndTime().after(latestTorTime)) {
|
|
||||||
latestTorTime = watch.getEndTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<WeatherAdvisoryWatch> getTorWatches() {
|
|
||||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
|
||||||
for (WeatherAdvisoryWatch w : torWatches) {
|
|
||||||
w.setEndTime(latestTorTime);
|
|
||||||
rval.add(w);
|
|
||||||
}
|
|
||||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<WeatherAdvisoryWatch> getSvrWatches() {
|
|
||||||
Set<WeatherAdvisoryWatch> rval = new TreeSet<WeatherAdvisoryWatch>();
|
|
||||||
for (WeatherAdvisoryWatch w : svrWatches) {
|
|
||||||
w.setEndTime(latestSvrTime);
|
|
||||||
rval.add(w);
|
|
||||||
}
|
|
||||||
return new ArrayList<WeatherAdvisoryWatch>(rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLatestTorTime() {
|
|
||||||
return latestTorTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getLatestSvrTime() {
|
|
||||||
return latestSvrTime;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,155 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.viz.warngen.util;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Add Description
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Jul 1, 2009 bwoodle Initial creation
|
|
||||||
* Nov 9, 2012 DR 15430 D. Friedman Support proper watch inclusion language
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author bwoodle
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class WeatherAdvisoryWatch implements Comparable<WeatherAdvisoryWatch> {
|
|
||||||
|
|
||||||
public static class Portion {
|
|
||||||
public String parentRegion;
|
|
||||||
|
|
||||||
public List<String> partOfParentRegion;
|
|
||||||
|
|
||||||
public String getParentRegion() {
|
|
||||||
return parentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParentRegion(String parentRegion) {
|
|
||||||
this.parentRegion = parentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getPartOfParentRegion() {
|
|
||||||
return partOfParentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
|
||||||
this.partOfParentRegion = partOfParentRegion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: NOTE: There is no site field. We currently only process
|
|
||||||
* WCNs for the site and not WOUs from the SPC.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private String phensig;
|
|
||||||
|
|
||||||
private int eventId;
|
|
||||||
|
|
||||||
private Date endTime;
|
|
||||||
|
|
||||||
private List<Portion> portions;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private String parentRegion;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private List<String> partOfParentRegion;
|
|
||||||
|
|
||||||
public String getPhensig() {
|
|
||||||
return phensig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhensig(String phensig) {
|
|
||||||
this.phensig = phensig;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndTime(Date endTime) {
|
|
||||||
this.endTime = endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public String getParentRegion() {
|
|
||||||
return parentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void setParentRegion(String parentRegion) {
|
|
||||||
this.parentRegion = parentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public List<String> getPartOfParentRegion() {
|
|
||||||
return partOfParentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void setPartOfParentRegion(List<String> partOfParentRegion) {
|
|
||||||
this.partOfParentRegion = partOfParentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return obj instanceof WeatherAdvisoryWatch &&
|
|
||||||
this.compareTo((WeatherAdvisoryWatch) obj) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(WeatherAdvisoryWatch waw) {
|
|
||||||
if (this.phensig == null)
|
|
||||||
return waw.phensig == null ? 0 : -1;
|
|
||||||
else if (waw.phensig == null)
|
|
||||||
return 1;
|
|
||||||
else {
|
|
||||||
int c = this.phensig.compareTo(waw.phensig);
|
|
||||||
if (c == 0)
|
|
||||||
return this.eventId - waw.eventId;
|
|
||||||
else
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEventId() {
|
|
||||||
return eventId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEventId(int eventId) {
|
|
||||||
this.eventId = eventId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Portion> getPortions() {
|
|
||||||
return portions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPortions(List<Portion> portions) {
|
|
||||||
this.portions = portions;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -136,6 +136,19 @@
|
||||||
</doTry>
|
</doTry>
|
||||||
</route>
|
</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>
|
</camelContext>
|
||||||
|
|
||||||
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
||||||
|
|
|
@ -101,7 +101,7 @@ import com.raytheon.uf.edex.database.purge.PurgeLogger;
|
||||||
* D2DGridDatabase constructor
|
* D2DGridDatabase constructor
|
||||||
* 04/23/13 #1949 rjpeter Added inventory retrieval for a given time range.
|
* 04/23/13 #1949 rjpeter Added inventory retrieval for a given time range.
|
||||||
* 05/02/13 #1969 randerso Fixed possible null pointer in getParmList
|
* 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/03/13 #1974 randerso Fixed error logging to include stack trace
|
||||||
* 05/14/13 #2004 randerso Added methods to synch GridParmManager across JVMs
|
* 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.
|
* 05/30/13 #2044 randerso Refactored to better match A1 design. Removed D2DParmIDCache.
|
||||||
|
@ -119,7 +119,10 @@ import com.raytheon.uf.edex.database.purge.PurgeLogger;
|
||||||
* the same parm simultaneously.
|
* the same parm simultaneously.
|
||||||
* Added code to check the purge times when publishing and not publish
|
* Added code to check the purge times when publishing and not publish
|
||||||
* data that is eligible to be purged.
|
* data that is eligible to be purged.
|
||||||
*
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -172,7 +175,7 @@ public class GridParmManager {
|
||||||
this.lockMgr.setGridParmMgr(this);
|
this.lockMgr.setGridParmMgr(this);
|
||||||
|
|
||||||
initializeManager();
|
initializeManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose the GridParmManager
|
* Dispose the GridParmManager
|
||||||
|
@ -199,7 +202,7 @@ public class GridParmManager {
|
||||||
.debug("No matching GridDatabase for requested ParmID in createParm()");
|
.debug("No matching GridDatabase for requested ParmID in createParm()");
|
||||||
// TODO: should we return null?
|
// TODO: should we return null?
|
||||||
return new GridParm();
|
return new GridParm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -330,10 +333,10 @@ public class GridParmManager {
|
||||||
for (SaveGridRequest req : saveRequest) {
|
for (SaveGridRequest req : saveRequest) {
|
||||||
ServerResponse<?> ssr = null;
|
ServerResponse<?> ssr = null;
|
||||||
GridParm gp = null;
|
GridParm gp = null;
|
||||||
gp = gridParm(req.getParmId());
|
gp = gridParm(req.getParmId());
|
||||||
if (!gp.isValid()) {
|
if (!gp.isValid()) {
|
||||||
sr.addMessage("Unknown Parm: " + req.getParmId()
|
sr.addMessage("Unknown Parm: " + req.getParmId()
|
||||||
+ " in saveGridData()");
|
+ " in saveGridData()");
|
||||||
statusHandler.error("Unknown Parm: " + req.getParmId()
|
statusHandler.error("Unknown Parm: " + req.getParmId()
|
||||||
+ " in saveGridData()");
|
+ " in saveGridData()");
|
||||||
continue;
|
continue;
|
||||||
|
@ -455,27 +458,27 @@ public class GridParmManager {
|
||||||
// for the source data
|
// for the source data
|
||||||
ParmID sourceParmId = req.getParmId();
|
ParmID sourceParmId = req.getParmId();
|
||||||
GridParm sourceGP = gridParm(sourceParmId);
|
GridParm sourceGP = gridParm(sourceParmId);
|
||||||
if (!sourceGP.isValid()) {
|
if (!sourceGP.isValid()) {
|
||||||
ssr.addMessage("Unknown Source Parm: " + req.getParmId()
|
ssr.addMessage("Unknown Source Parm: " + req.getParmId()
|
||||||
+ " in commitGrid()");
|
+ " in commitGrid()");
|
||||||
srDetailed.addMessages(ssr);
|
srDetailed.addMessages(ssr);
|
||||||
failures.add(req);
|
failures.add(req);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for the destination data
|
// for the destination data
|
||||||
ParmID destParmId = new ParmID(req.getParmId().getParmName(),
|
ParmID destParmId = new ParmID(req.getParmId().getParmName(),
|
||||||
officialDBid, req.getParmId().getParmLevel());
|
officialDBid, req.getParmId().getParmLevel());
|
||||||
String destParmIdStr = destParmId.toString();
|
String destParmIdStr = destParmId.toString();
|
||||||
GridParm destGP = null;
|
GridParm destGP = null;
|
||||||
destGP = gridParm(destParmId);
|
destGP = gridParm(destParmId);
|
||||||
if (!destGP.isValid()) {
|
if (!destGP.isValid()) {
|
||||||
ssr.addMessage("Unknown Destination Parm: " + destGP
|
ssr.addMessage("Unknown Destination Parm: " + destGP
|
||||||
+ " in commitGrid()");
|
+ " in commitGrid()");
|
||||||
srDetailed.addMessages(ssr);
|
srDetailed.addMessages(ssr);
|
||||||
failures.add(req);
|
failures.add(req);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify that the source and destination are matched
|
// verify that the source and destination are matched
|
||||||
GridParmInfo sourceInfo, destInfo;
|
GridParmInfo sourceInfo, destInfo;
|
||||||
|
@ -519,17 +522,17 @@ public class GridParmManager {
|
||||||
publishTime.setStart(startTime);
|
publishTime.setStart(startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
inventoryTimer.start();
|
inventoryTimer.start();
|
||||||
ServerResponse<List<TimeRange>> invSr = sourceGP
|
ServerResponse<List<TimeRange>> invSr = sourceGP
|
||||||
.getGridInventory(publishTime);
|
.getGridInventory(publishTime);
|
||||||
List<TimeRange> overlapInventory = invSr.getPayload();
|
List<TimeRange> overlapInventory = invSr.getPayload();
|
||||||
ssr.addMessages(invSr);
|
ssr.addMessages(invSr);
|
||||||
if (!ssr.isOkay()) {
|
if (!ssr.isOkay()) {
|
||||||
ssr.addMessage("GetGridInventory for source for commitGrid() failure: "
|
ssr.addMessage("GetGridInventory for source for commitGrid() failure: "
|
||||||
+ ssr.message());
|
+ ssr.message());
|
||||||
srDetailed.addMessages(ssr);
|
srDetailed.addMessages(ssr);
|
||||||
failures.add(req);
|
failures.add(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// expand publish time to span overlapping inventory
|
// expand publish time to span overlapping inventory
|
||||||
if (!overlapInventory.isEmpty()) {
|
if (!overlapInventory.isEmpty()) {
|
||||||
|
@ -546,173 +549,173 @@ public class GridParmManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
invSr = destGP.getGridInventory(publishTime);
|
invSr = destGP.getGridInventory(publishTime);
|
||||||
inventoryTimer.stop();
|
inventoryTimer.stop();
|
||||||
List<TimeRange> destInventory = invSr.getPayload();
|
List<TimeRange> destInventory = invSr.getPayload();
|
||||||
ssr.addMessages(invSr);
|
ssr.addMessages(invSr);
|
||||||
if (!ssr.isOkay()) {
|
|
||||||
ssr.addMessage("GetGridInventory for destination for commitGrid() failure: "
|
|
||||||
+ ssr.message());
|
|
||||||
srDetailed.addMessages(ssr);
|
|
||||||
failures.add(req);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the source grid data
|
|
||||||
List<IGridSlice> sourceData = null;
|
|
||||||
List<TimeRange> badGridTR = new ArrayList<TimeRange>();
|
|
||||||
|
|
||||||
// System.out.println("overlapInventory initial size "
|
|
||||||
// + overlapInventory.size());
|
|
||||||
|
|
||||||
historyRetrieveTimer.start();
|
|
||||||
ServerResponse<Map<TimeRange, List<GridDataHistory>>> history = sourceGP
|
|
||||||
.getGridHistory(overlapInventory);
|
|
||||||
Map<TimeRange, List<GridDataHistory>> currentDestHistory = destGP
|
|
||||||
.getGridHistory(overlapInventory).getPayload();
|
|
||||||
historyRetrieveTimer.stop();
|
|
||||||
|
|
||||||
Map<TimeRange, List<GridDataHistory>> historyOnly = new HashMap<TimeRange, List<GridDataHistory>>();
|
|
||||||
for (TimeRange tr : history.getPayload().keySet()) {
|
|
||||||
// should only ever be one history for source grids
|
|
||||||
List<GridDataHistory> gdhList = history.getPayload()
|
|
||||||
.get(tr);
|
|
||||||
boolean doPublish = false;
|
|
||||||
for (GridDataHistory gdh : gdhList) {
|
|
||||||
// if update time is less than publish time, grid
|
|
||||||
// has not changed since last published,
|
|
||||||
// therefore only update history, do not publish
|
|
||||||
if ((gdh.getPublishTime() == null)
|
|
||||||
|| (gdh.getUpdateTime().getTime() > gdh
|
|
||||||
.getPublishTime().getTime())
|
|
||||||
// in service backup, times on srcHistory
|
|
||||||
// could appear as not needing a publish,
|
|
||||||
// even though dest data does not exist
|
|
||||||
|| (currentDestHistory.get(tr) == null)
|
|
||||||
|| (currentDestHistory.get(tr).size() == 0)) {
|
|
||||||
doPublish = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!doPublish) {
|
|
||||||
historyOnly.put(tr, gdhList);
|
|
||||||
overlapInventory.remove(tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
retrieveTimer.start();
|
|
||||||
ServerResponse<List<IGridSlice>> getSr = sourceGP.getGridData(
|
|
||||||
new GetGridRequest(req.getParmId(), overlapInventory),
|
|
||||||
badGridTR);
|
|
||||||
retrieveTimer.stop();
|
|
||||||
// System.out.println("Retrieved " + overlapInventory.size()
|
|
||||||
// + " grids");
|
|
||||||
sourceData = getSr.getPayload();
|
|
||||||
ssr.addMessages(getSr);
|
|
||||||
if (!ssr.isOkay()) {
|
|
||||||
ssr.addMessage("GetGridData for source for commitGrid() failure: "
|
|
||||||
+ ssr.message());
|
|
||||||
srDetailed.addMessages(ssr);
|
|
||||||
failures.add(req);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get list of official grids that overlap publish range and
|
|
||||||
// aren't contained in the publish range, these have to be
|
|
||||||
// included in the publish step. Then get the grids, shorten
|
|
||||||
// and insert into sourceData.
|
|
||||||
List<IGridSlice> officialData = new ArrayList<IGridSlice>();
|
|
||||||
List<TimeRange> officialTR = new ArrayList<TimeRange>();
|
|
||||||
for (int t = 0; t < destInventory.size(); t++) {
|
|
||||||
if (!publishTime.contains(destInventory.get(t))) {
|
|
||||||
officialTR.add(destInventory.get(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!officialTR.isEmpty()) {
|
|
||||||
retrieveTimer.start();
|
|
||||||
getSr = destGP.getGridData(new GetGridRequest(destParmId,
|
|
||||||
officialTR), badGridTR);
|
|
||||||
retrieveTimer.stop();
|
|
||||||
officialData = getSr.getPayload();
|
|
||||||
ssr.addMessages(getSr);
|
|
||||||
if (!ssr.isOkay()) {
|
if (!ssr.isOkay()) {
|
||||||
ssr.addMessage("GetGridData for official for commidtGrid() failure: "
|
ssr.addMessage("GetGridInventory for destination for commitGrid() failure: "
|
||||||
+ ssr.message());
|
+ ssr.message());
|
||||||
srDetailed.addMessages(ssr);
|
srDetailed.addMessages(ssr);
|
||||||
failures.add(req);
|
failures.add(req);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the grid into the "sourceGrid" list
|
// get the source grid data
|
||||||
for (int t = 0; t < officialTR.size(); t++) {
|
List<IGridSlice> sourceData = null;
|
||||||
// before
|
List<TimeRange> badGridTR = new ArrayList<TimeRange>();
|
||||||
try {
|
|
||||||
if (officialTR.get(t).getStart()
|
// System.out.println("overlapInventory initial size "
|
||||||
.before(publishTime.getStart())) {
|
// + overlapInventory.size());
|
||||||
|
|
||||||
|
historyRetrieveTimer.start();
|
||||||
|
ServerResponse<Map<TimeRange, List<GridDataHistory>>> history = sourceGP
|
||||||
|
.getGridHistory(overlapInventory);
|
||||||
|
Map<TimeRange, List<GridDataHistory>> currentDestHistory = destGP
|
||||||
|
.getGridHistory(overlapInventory).getPayload();
|
||||||
|
historyRetrieveTimer.stop();
|
||||||
|
|
||||||
|
Map<TimeRange, List<GridDataHistory>> historyOnly = new HashMap<TimeRange, List<GridDataHistory>>();
|
||||||
|
for (TimeRange tr : history.getPayload().keySet()) {
|
||||||
|
// should only ever be one history for source grids
|
||||||
|
List<GridDataHistory> gdhList = history.getPayload()
|
||||||
|
.get(tr);
|
||||||
|
boolean doPublish = false;
|
||||||
|
for (GridDataHistory gdh : gdhList) {
|
||||||
|
// if update time is less than publish time, grid
|
||||||
|
// has not changed since last published,
|
||||||
|
// therefore only update history, do not publish
|
||||||
|
if ((gdh.getPublishTime() == null)
|
||||||
|
|| (gdh.getUpdateTime().getTime() > gdh
|
||||||
|
.getPublishTime().getTime())
|
||||||
|
// in service backup, times on srcHistory
|
||||||
|
// could appear as not needing a publish,
|
||||||
|
// even though dest data does not exist
|
||||||
|
|| (currentDestHistory.get(tr) == null)
|
||||||
|
|| (currentDestHistory.get(tr).size() == 0)) {
|
||||||
|
doPublish = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!doPublish) {
|
||||||
|
historyOnly.put(tr, gdhList);
|
||||||
|
overlapInventory.remove(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieveTimer.start();
|
||||||
|
ServerResponse<List<IGridSlice>> getSr = sourceGP.getGridData(
|
||||||
|
new GetGridRequest(req.getParmId(), overlapInventory),
|
||||||
|
badGridTR);
|
||||||
|
retrieveTimer.stop();
|
||||||
|
// System.out.println("Retrieved " + overlapInventory.size()
|
||||||
|
// + " grids");
|
||||||
|
sourceData = getSr.getPayload();
|
||||||
|
ssr.addMessages(getSr);
|
||||||
|
if (!ssr.isOkay()) {
|
||||||
|
ssr.addMessage("GetGridData for source for commitGrid() failure: "
|
||||||
|
+ ssr.message());
|
||||||
|
srDetailed.addMessages(ssr);
|
||||||
|
failures.add(req);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get list of official grids that overlap publish range and
|
||||||
|
// aren't contained in the publish range, these have to be
|
||||||
|
// included in the publish step. Then get the grids, shorten
|
||||||
|
// and insert into sourceData.
|
||||||
|
List<IGridSlice> officialData = new ArrayList<IGridSlice>();
|
||||||
|
List<TimeRange> officialTR = new ArrayList<TimeRange>();
|
||||||
|
for (int t = 0; t < destInventory.size(); t++) {
|
||||||
|
if (!publishTime.contains(destInventory.get(t))) {
|
||||||
|
officialTR.add(destInventory.get(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!officialTR.isEmpty()) {
|
||||||
|
retrieveTimer.start();
|
||||||
|
getSr = destGP.getGridData(new GetGridRequest(destParmId,
|
||||||
|
officialTR), badGridTR);
|
||||||
|
retrieveTimer.stop();
|
||||||
|
officialData = getSr.getPayload();
|
||||||
|
ssr.addMessages(getSr);
|
||||||
|
if (!ssr.isOkay()) {
|
||||||
|
ssr.addMessage("GetGridData for official for commidtGrid() failure: "
|
||||||
|
+ ssr.message());
|
||||||
|
srDetailed.addMessages(ssr);
|
||||||
|
failures.add(req);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert the grid into the "sourceGrid" list
|
||||||
|
for (int t = 0; t < officialTR.size(); t++) {
|
||||||
|
// before
|
||||||
|
try {
|
||||||
|
if (officialTR.get(t).getStart()
|
||||||
|
.before(publishTime.getStart())) {
|
||||||
|
|
||||||
IGridSlice tempSlice = officialData.get(t)
|
IGridSlice tempSlice = officialData.get(t)
|
||||||
.clone();
|
.clone();
|
||||||
tempSlice.setValidTime(new TimeRange(officialTR
|
tempSlice.setValidTime(new TimeRange(officialTR
|
||||||
.get(t).getStart(), publishTime
|
.get(t).getStart(), publishTime
|
||||||
.getStart()));
|
.getStart()));
|
||||||
sourceData.add(0, tempSlice);
|
sourceData.add(0, tempSlice);
|
||||||
publishTime.setStart(officialTR.get(t)
|
publishTime.setStart(officialTR.get(t)
|
||||||
.getStart());
|
.getStart());
|
||||||
overlapInventory.add(tempSlice.getValidTime());
|
overlapInventory.add(tempSlice.getValidTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// after
|
// after
|
||||||
if (officialTR.get(t).getEnd()
|
if (officialTR.get(t).getEnd()
|
||||||
.after(publishTime.getEnd())) {
|
.after(publishTime.getEnd())) {
|
||||||
IGridSlice tempSlice = officialData.get(t)
|
IGridSlice tempSlice = officialData.get(t)
|
||||||
.clone();
|
.clone();
|
||||||
tempSlice.setValidTime(new TimeRange(
|
tempSlice.setValidTime(new TimeRange(
|
||||||
publishTime.getEnd(), officialTR.get(t)
|
publishTime.getEnd(), officialTR.get(t)
|
||||||
.getEnd()));
|
.getEnd()));
|
||||||
sourceData.add(tempSlice);
|
sourceData.add(tempSlice);
|
||||||
publishTime.setEnd(officialTR.get(t).getEnd());
|
publishTime.setEnd(officialTR.get(t).getEnd());
|
||||||
overlapInventory.add(tempSlice.getValidTime());
|
overlapInventory.add(tempSlice.getValidTime());
|
||||||
|
}
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
sr.addMessage("Error cloning GridSlice "
|
||||||
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
sr.addMessage("Error cloning GridSlice "
|
|
||||||
+ e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// save off the source grid history, to update the source
|
// save off the source grid history, to update the source
|
||||||
// database modify the source grid data for the dest ParmID and
|
// database modify the source grid data for the dest ParmID and
|
||||||
// GridDataHistory
|
// GridDataHistory
|
||||||
Map<TimeRange, List<GridDataHistory>> histories = new HashMap<TimeRange, List<GridDataHistory>>();
|
Map<TimeRange, List<GridDataHistory>> histories = new HashMap<TimeRange, List<GridDataHistory>>();
|
||||||
Date nowTime = new Date();
|
Date nowTime = new Date();
|
||||||
|
|
||||||
for (IGridSlice slice : sourceData) {
|
for (IGridSlice slice : sourceData) {
|
||||||
GridDataHistory[] sliceHist = slice.getHistory();
|
GridDataHistory[] sliceHist = slice.getHistory();
|
||||||
for (GridDataHistory hist : sliceHist) {
|
for (GridDataHistory hist : sliceHist) {
|
||||||
hist.setPublishTime((Date) nowTime.clone());
|
hist.setPublishTime((Date) nowTime.clone());
|
||||||
}
|
}
|
||||||
slice.getGridInfo().resetParmID(destParmId);
|
slice.getGridInfo().resetParmID(destParmId);
|
||||||
histories.put(slice.getValidTime(),
|
histories.put(slice.getValidTime(),
|
||||||
Arrays.asList(sliceHist));
|
Arrays.asList(sliceHist));
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the history for publish time for grids that are
|
// update the history for publish time for grids that are
|
||||||
// unchanged
|
// unchanged
|
||||||
for (TimeRange tr : historyOnly.keySet()) {
|
for (TimeRange tr : historyOnly.keySet()) {
|
||||||
List<GridDataHistory> histList = historyOnly.get(tr);
|
List<GridDataHistory> histList = historyOnly.get(tr);
|
||||||
for (GridDataHistory hist : histList) {
|
for (GridDataHistory hist : histList) {
|
||||||
hist.setPublishTime((Date) nowTime.clone());
|
hist.setPublishTime((Date) nowTime.clone());
|
||||||
|
}
|
||||||
|
histories.put(tr, histList);
|
||||||
}
|
}
|
||||||
histories.put(tr, histList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the publish times in the source database,
|
// update the publish times in the source database,
|
||||||
// update the notifications
|
// update the notifications
|
||||||
historyUpdateTimer.start();
|
historyUpdateTimer.start();
|
||||||
sr.addMessages(sourceGP.updatePublishTime(histories.values(),
|
sr.addMessages(sourceGP.updatePublishTime(histories.values(),
|
||||||
(Date) nowTime.clone()));
|
(Date) nowTime.clone()));
|
||||||
// System.out.println("Updated " + histories.size() +
|
// System.out.println("Updated " + histories.size() +
|
||||||
// " histories");
|
// " histories");
|
||||||
historyUpdateTimer.stop();
|
historyUpdateTimer.stop();
|
||||||
|
|
||||||
List<TimeRange> historyTimes = new ArrayList<TimeRange>(
|
List<TimeRange> historyTimes = new ArrayList<TimeRange>(
|
||||||
histories.keySet());
|
histories.keySet());
|
||||||
|
@ -723,56 +726,56 @@ public class GridParmManager {
|
||||||
// update the histories of destination database for ones
|
// update the histories of destination database for ones
|
||||||
// that are not going to be saved since there hasn't been a
|
// that are not going to be saved since there hasn't been a
|
||||||
// change
|
// change
|
||||||
List<TimeRange> historyOnlyList = new ArrayList<TimeRange>();
|
List<TimeRange> historyOnlyList = new ArrayList<TimeRange>();
|
||||||
historyOnlyList.addAll(historyOnly.keySet());
|
historyOnlyList.addAll(historyOnly.keySet());
|
||||||
|
|
||||||
historyRetrieveTimer.start();
|
historyRetrieveTimer.start();
|
||||||
Map<TimeRange, List<GridDataHistory>> destHistory = destGP
|
Map<TimeRange, List<GridDataHistory>> destHistory = destGP
|
||||||
.getGridHistory(historyOnlyList).getPayload();
|
.getGridHistory(historyOnlyList).getPayload();
|
||||||
historyRetrieveTimer.stop();
|
historyRetrieveTimer.stop();
|
||||||
for (TimeRange tr : destHistory.keySet()) {
|
for (TimeRange tr : destHistory.keySet()) {
|
||||||
List<GridDataHistory> srcHistList = histories.get(tr);
|
List<GridDataHistory> srcHistList = histories.get(tr);
|
||||||
List<GridDataHistory> destHistList = destHistory.get(tr);
|
List<GridDataHistory> destHistList = destHistory.get(tr);
|
||||||
for (int i = 0; i < srcHistList.size(); i++) {
|
for (int i = 0; i < srcHistList.size(); i++) {
|
||||||
destHistList.get(i).replaceValues(srcHistList.get(i));
|
destHistList.get(i).replaceValues(srcHistList.get(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// only need to update the publish time on the destination
|
// only need to update the publish time on the destination
|
||||||
// histories of grids that are not being saved (due to no
|
// histories of grids that are not being saved (due to no
|
||||||
// changes), because the saveGridSlices() call below will update
|
// changes), because the saveGridSlices() call below will update
|
||||||
// the publish time of the ones with changes
|
// the publish time of the ones with changes
|
||||||
historyUpdateTimer.start();
|
historyUpdateTimer.start();
|
||||||
destGP.updatePublishTime(destHistory.values(),
|
destGP.updatePublishTime(destHistory.values(),
|
||||||
(Date) nowTime.clone());
|
(Date) nowTime.clone());
|
||||||
historyUpdateTimer.stop();
|
historyUpdateTimer.stop();
|
||||||
|
|
||||||
// save data directly to the official database (bypassing
|
// save data directly to the official database (bypassing
|
||||||
// the checks in Parm intentionally)
|
// the checks in Parm intentionally)
|
||||||
storeTimer.start();
|
storeTimer.start();
|
||||||
ssr.addMessages(officialDBPtr.saveGridSlices(destParmId,
|
ssr.addMessages(officialDBPtr.saveGridSlices(destParmId,
|
||||||
publishTime, sourceData, requestorId, historyOnlyList));
|
publishTime, sourceData, requestorId, historyOnlyList));
|
||||||
storeTimer.stop();
|
storeTimer.stop();
|
||||||
|
|
||||||
// System.out.println("Published " + sourceData.size() +
|
// System.out.println("Published " + sourceData.size() +
|
||||||
// " slices");
|
// " slices");
|
||||||
if (!ssr.isOkay()) {
|
if (!ssr.isOkay()) {
|
||||||
ssr.addMessage("SaveGridData for official for commitGrid() failure: "
|
ssr.addMessage("SaveGridData for official for commitGrid() failure: "
|
||||||
+ ssr.message());
|
+ ssr.message());
|
||||||
srDetailed.addMessages(ssr);
|
srDetailed.addMessages(ssr);
|
||||||
failures.add(req);
|
failures.add(req);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make the notification
|
// make the notification
|
||||||
GridUpdateNotification not = new GridUpdateNotification(
|
GridUpdateNotification not = new GridUpdateNotification(
|
||||||
destParmId, publishTime, histories, requestorId, siteID);
|
destParmId, publishTime, histories, requestorId, siteID);
|
||||||
changes.add(not);
|
changes.add(not);
|
||||||
sr.getPayload().add(not);
|
sr.getPayload().add(not);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
ClusterLockUtils.unlock(ct, false);
|
ClusterLockUtils.unlock(ct, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perfLog.logDuration("Publish Grids: Acquiring cluster lock",
|
perfLog.logDuration("Publish Grids: Acquiring cluster lock",
|
||||||
|
@ -822,8 +825,8 @@ public class GridParmManager {
|
||||||
this.dbMap.keySet());
|
this.dbMap.keySet());
|
||||||
|
|
||||||
sr.setPayload(databases);
|
sr.setPayload(databases);
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a database if available
|
* Get a database if available
|
||||||
|
@ -832,6 +835,10 @@ public class GridParmManager {
|
||||||
* @return GridDatabase or null if not available
|
* @return GridDatabase or null if not available
|
||||||
*/
|
*/
|
||||||
public GridDatabase getDatabase(DatabaseID dbId) {
|
public GridDatabase getDatabase(DatabaseID dbId) {
|
||||||
|
return getDatabase(dbId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GridDatabase getDatabase(DatabaseID dbId, boolean notify) {
|
||||||
// look up the database in the map
|
// look up the database in the map
|
||||||
GridDatabase db = this.dbMap.get(dbId);
|
GridDatabase db = this.dbMap.get(dbId);
|
||||||
|
|
||||||
|
@ -846,12 +853,14 @@ public class GridParmManager {
|
||||||
ServerResponse<GridDatabase> status = createDB(dbId);
|
ServerResponse<GridDatabase> status = createDB(dbId);
|
||||||
if (status.isOkay()) {
|
if (status.isOkay()) {
|
||||||
db = status.getPayload();
|
db = status.getPayload();
|
||||||
createDbNotification(Arrays.asList(dbId), null);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
this.addDB(db);
|
this.addDB(db);
|
||||||
|
if (notify) {
|
||||||
|
createDbNotification(Arrays.asList(dbId), null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,8 +895,8 @@ public class GridParmManager {
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete database
|
* Delete database
|
||||||
|
@ -944,9 +953,9 @@ public class GridParmManager {
|
||||||
|
|
||||||
if (db == null) {
|
if (db == null) {
|
||||||
sr.addMessage("Database " + dbId
|
sr.addMessage("Database " + dbId
|
||||||
+ " does not exist for getParmList()");
|
+ " does not exist for getParmList()");
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sr = db.getParmList();
|
sr = db.getParmList();
|
||||||
return sr;
|
return sr;
|
||||||
|
@ -988,7 +997,7 @@ public class GridParmManager {
|
||||||
|
|
||||||
// determine desired number of versions
|
// determine desired number of versions
|
||||||
desiredVersions = this.config.desiredDbVersions(dbId);
|
desiredVersions = this.config.desiredDbVersions(dbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process the id and determine whether it should be purged
|
// process the id and determine whether it should be purged
|
||||||
count++;
|
count++;
|
||||||
|
@ -1012,9 +1021,9 @@ public class GridParmManager {
|
||||||
toRemove.removeAll(newInv);
|
toRemove.removeAll(newInv);
|
||||||
for (DatabaseID dbId : toRemove) {
|
for (DatabaseID dbId : toRemove) {
|
||||||
if (dbMap.remove(dbId) != null) {
|
if (dbMap.remove(dbId) != null) {
|
||||||
statusHandler
|
statusHandler
|
||||||
.info("Synching GridParmManager with database inventory, removing "
|
.info("Synching GridParmManager with database inventory, removing "
|
||||||
+ dbId);
|
+ dbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add any removals to the deletions list
|
// add any removals to the deletions list
|
||||||
|
@ -1073,14 +1082,14 @@ public class GridParmManager {
|
||||||
List<LockNotification> lockNotify = new ArrayList<LockNotification>();
|
List<LockNotification> lockNotify = new ArrayList<LockNotification>();
|
||||||
GridParm gp = createParm(parmId);
|
GridParm gp = createParm(parmId);
|
||||||
if (gp.isValid()) {
|
if (gp.isValid()) {
|
||||||
ServerResponse<Integer> sr1 = gp.timePurge(purgeTime,
|
ServerResponse<Integer> sr1 = gp.timePurge(purgeTime,
|
||||||
gridNotify, lockNotify);
|
gridNotify, lockNotify);
|
||||||
sr.addMessages(sr1);
|
sr.addMessages(sr1);
|
||||||
purgedCount += sr1.getPayload();
|
purgedCount += sr1.getPayload();
|
||||||
|
|
||||||
gridNotifications.addAll(gridNotify);
|
gridNotifications.addAll(gridNotify);
|
||||||
lockNotifications.addAll(lockNotify);
|
lockNotifications.addAll(lockNotify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PurgeLogger.logInfo("Purge " + purgedCount + " items from " + dbId,
|
PurgeLogger.logInfo("Purge " + purgedCount + " items from " + dbId,
|
||||||
|
@ -1119,7 +1128,7 @@ public class GridParmManager {
|
||||||
|
|
||||||
if (dbId.getRemovedDate() != null) {
|
if (dbId.getRemovedDate() != null) {
|
||||||
// mark database as not removed
|
// mark database as not removed
|
||||||
try {
|
try {
|
||||||
GFEDao gfeDao = new GFEDao();
|
GFEDao gfeDao = new GFEDao();
|
||||||
gfeDao.setDatabaseRemovedDate(dbId, null);
|
gfeDao.setDatabaseRemovedDate(dbId, null);
|
||||||
statusHandler.info("Database " + dbId + " restored");
|
statusHandler.info("Database " + dbId + " restored");
|
||||||
|
@ -1127,7 +1136,7 @@ public class GridParmManager {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
"Unable to mark database restored: " + dbId, e);
|
"Unable to mark database restored: " + dbId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add to list of databases
|
// add to list of databases
|
||||||
addDB(db);
|
addDB(db);
|
||||||
|
@ -1177,8 +1186,8 @@ public class GridParmManager {
|
||||||
if (manID.getFormat().equals(DataType.GRID)
|
if (manID.getFormat().equals(DataType.GRID)
|
||||||
&& !inventory.contains(manID)) {
|
&& !inventory.contains(manID)) {
|
||||||
inventory.add(manID);
|
inventory.add(manID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// create the databases (the list should now only contain GRID dbs)
|
// create the databases (the list should now only contain GRID dbs)
|
||||||
ServerResponse<GridDatabase> sr = new ServerResponse<GridDatabase>();
|
ServerResponse<GridDatabase> sr = new ServerResponse<GridDatabase>();
|
||||||
|
@ -1208,11 +1217,6 @@ public class GridParmManager {
|
||||||
ClusterTask ct = ClusterLockUtils.lookupLock(SMART_INIT_TASK_NAME,
|
ClusterTask ct = ClusterLockUtils.lookupLock(SMART_INIT_TASK_NAME,
|
||||||
SMART_INIT_TASK_DETAILS + siteID);
|
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
|
ct = ClusterLockUtils
|
||||||
.lock(SMART_INIT_TASK_NAME, SMART_INIT_TASK_DETAILS
|
.lock(SMART_INIT_TASK_NAME, SMART_INIT_TASK_DETAILS
|
||||||
+ siteID, SMART_INIT_TIMEOUT, false);
|
+ siteID, SMART_INIT_TIMEOUT, false);
|
||||||
|
@ -1285,7 +1289,7 @@ public class GridParmManager {
|
||||||
if (db == null) {
|
if (db == null) {
|
||||||
// New database
|
// New database
|
||||||
db = D2DGridDatabase.getDatabase(config, d2dModelName, refTime);
|
db = D2DGridDatabase.getDatabase(config, d2dModelName, refTime);
|
||||||
if (db == null) {
|
if (db == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,16 +1312,16 @@ public class GridParmManager {
|
||||||
queue.queue(siteID, config, dbId, validTime, false,
|
queue.queue(siteID, config, dbId, validTime, false,
|
||||||
SmartInitRecord.LIVE_SMART_INIT_PRIORITY);
|
SmartInitRecord.LIVE_SMART_INIT_PRIORITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send notifications;
|
// send notifications;
|
||||||
try {
|
try {
|
||||||
SendNotifications.send(guns);
|
SendNotifications.send(guns);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.error("Unable to send grib ingest notifications", e);
|
statusHandler.error("Unable to send grib ingest notifications", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param records
|
* @param records
|
||||||
|
@ -1339,9 +1343,9 @@ public class GridParmManager {
|
||||||
Date validTime = gun.getReplacementTimeRange().getStart();
|
Date validTime = gun.getReplacementTimeRange().getStart();
|
||||||
queue.queue(siteID, config, dbId, validTime, false,
|
queue.queue(siteID, config, dbId, validTime, false,
|
||||||
SmartInitRecord.LIVE_SMART_INIT_PRIORITY);
|
SmartInitRecord.LIVE_SMART_INIT_PRIORITY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SendNotifications.send(guns);
|
SendNotifications.send(guns);
|
||||||
|
@ -1349,7 +1353,7 @@ public class GridParmManager {
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
"Unable to send satellite ingest notifications", e);
|
"Unable to send satellite ingest notifications", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date purgeTime(DatabaseID id) {
|
private Date purgeTime(DatabaseID id) {
|
||||||
int numHours = this.config.gridPurgeAgeInHours(id);
|
int numHours = this.config.gridPurgeAgeInHours(id);
|
||||||
|
@ -1427,8 +1431,8 @@ public class GridParmManager {
|
||||||
for (ParmID pid : parmList) {
|
for (ParmID pid : parmList) {
|
||||||
out.add(new CommitGridRequest(pid, req.getTimeRange(),
|
out.add(new CommitGridRequest(pid, req.getTimeRange(),
|
||||||
req.isClientSendStatus()));
|
req.isClientSendStatus()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sr.addMessage("Could not find database for "
|
sr.addMessage("Could not find database for "
|
||||||
+ req.getDbId() + " in convertToParmReq()");
|
+ req.getDbId() + " in convertToParmReq()");
|
||||||
}
|
}
|
||||||
|
@ -1495,25 +1499,7 @@ public class GridParmManager {
|
||||||
|
|
||||||
ServerResponse<GridDatabase> sr = new ServerResponse<GridDatabase>();
|
ServerResponse<GridDatabase> sr = new ServerResponse<GridDatabase>();
|
||||||
for (DatabaseID dbId : invChanged.getAdditions()) {
|
for (DatabaseID dbId : invChanged.getAdditions()) {
|
||||||
// TODO: This is pretty much just a duplicate of what's in
|
this.getDatabase(dbId, false);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
if (!sr.isOkay()) {
|
if (!sr.isOkay()) {
|
||||||
statusHandler.error("Error updating GridParmManager: "
|
statusHandler.error("Error updating GridParmManager: "
|
||||||
|
@ -1544,7 +1530,7 @@ public class GridParmManager {
|
||||||
DatabaseID dbId = db.getDbId();
|
DatabaseID dbId = db.getDbId();
|
||||||
statusHandler.info("addDB called, adding " + dbId);
|
statusHandler.info("addDB called, adding " + dbId);
|
||||||
this.dbMap.put(dbId, db);
|
this.dbMap.put(dbId, db);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process D2D grid data purge notification
|
* Process D2D grid data purge notification
|
||||||
|
@ -1568,44 +1554,22 @@ public class GridParmManager {
|
||||||
newInventory.addAll(dbIds);
|
newInventory.addAll(dbIds);
|
||||||
} catch (DataAccessLayerException e) {
|
} catch (DataAccessLayerException e) {
|
||||||
statusHandler.error(e.getLocalizedMessage(), e);
|
statusHandler.error(e.getLocalizedMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
List<DatabaseID> deleted = new ArrayList<DatabaseID>(currentInventory);
|
||||||
deleted.removeAll(newInventory);
|
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();
|
Iterator<DatabaseID> iter = deleted.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
DatabaseID dbid = iter.next();
|
DatabaseID dbid = iter.next();
|
||||||
// remove satellite database and non-D2D databases from deletes
|
// don't delete non-D2D databases
|
||||||
if (!dbid.getDbType().equals("D2D") || dbid.equals(satDbid)) {
|
if (!dbid.getDbType().equals("D2D")) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
} else {
|
} else {
|
||||||
// remove the database
|
// remove the database
|
||||||
|
@ -1613,19 +1577,16 @@ public class GridParmManager {
|
||||||
statusHandler.info("d2dGridDataPurged removing database: "
|
statusHandler.info("d2dGridDataPurged removing database: "
|
||||||
+ dbid);
|
+ dbid);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if ((added.size() > 0) || (deleted.size() > 0)) {
|
|
||||||
// DBInvChangeNotification changed = new DBInvChangeNotification(
|
|
||||||
// added, deleted, siteID);
|
|
||||||
if (deleted.size() > 0) {
|
if (deleted.size() > 0) {
|
||||||
DBInvChangeNotification changed = new DBInvChangeNotification(null,
|
DBInvChangeNotification changed = new DBInvChangeNotification(null,
|
||||||
deleted, siteID);
|
deleted, siteID);
|
||||||
|
|
||||||
SendNotifications.send(changed);
|
SendNotifications.send(changed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process D2D satellite data purge notification
|
* Process D2D satellite data purge notification
|
||||||
|
|
|
@ -114,6 +114,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||||
* Added function to create a D2DGridDatabase object only if there is
|
* Added function to create a D2DGridDatabase object only if there is
|
||||||
* data in postgres for the desired model/reftime
|
* data in postgres for the desired model/reftime
|
||||||
* 04/17/2014 #2934 dgilling Change getGridParmInfo to use D2DParm's GridParmInfo.
|
* 04/17/2014 #2934 dgilling Change getGridParmInfo to use D2DParm's GridParmInfo.
|
||||||
|
* 06/24/2014 #3317 randerso Don't allow database to be created if it exceeds D2DDBVERSIONS and
|
||||||
|
* should be purged.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -176,8 +178,9 @@ public class D2DGridDatabase extends VGridDatabase {
|
||||||
String d2dModelName, Date refTime) {
|
String d2dModelName, Date refTime) {
|
||||||
try {
|
try {
|
||||||
GFED2DDao dao = new GFED2DDao();
|
GFED2DDao dao = new GFED2DDao();
|
||||||
// TODO create query for single refTime
|
int dbVersions = config.desiredDbVersions(getDbId(d2dModelName,
|
||||||
List<Date> result = dao.getModelRunTimes(d2dModelName, -1);
|
refTime, config));
|
||||||
|
List<Date> result = dao.getModelRunTimes(d2dModelName, dbVersions);
|
||||||
|
|
||||||
if (result.contains(refTime)) {
|
if (result.contains(refTime)) {
|
||||||
D2DGridDatabase db = new D2DGridDatabase(config, d2dModelName,
|
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
|
* May 7, 2008 njensen Initial creation
|
||||||
* Jun 13, 2013 #2044 randerso Refactored to use IFPServer
|
* Jun 13, 2013 #2044 randerso Refactored to use IFPServer
|
||||||
|
* Jul 28, 2014 RM 15655 ryu Negate raising exception for empty db in constructor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -88,7 +89,6 @@ public class IFPDB {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.keys = Collections.emptyList();
|
this.keys = Collections.emptyList();
|
||||||
throw new GfeException(sr.message());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ except:
|
||||||
import numpy
|
import numpy
|
||||||
import JUtil
|
import JUtil
|
||||||
|
|
||||||
|
from java.lang import System
|
||||||
from java.util import ArrayList
|
from java.util import ArrayList
|
||||||
from java.util import LinkedHashMap
|
from java.util import LinkedHashMap
|
||||||
from com.raytheon.uf.common.dataplugin.gfe.grid import Grid2DFloat
|
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.
|
# 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/03/2014 2737 randerso Allow iscMosaic to blankOtherPeriods even when no grids received
|
||||||
# 04/11/2014 17242 David Gillingham (code checked in by zhao)
|
# 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
|
BATCH_DELAY = 0.0
|
||||||
|
@ -727,6 +729,9 @@ class IscMosaic:
|
||||||
|
|
||||||
# process incoming grids
|
# process incoming grids
|
||||||
for i in xrange(len(inTimes)):
|
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.
|
# Put in a delay so we don't hammer the server so hard.
|
||||||
if self.__gridDelay > 0.0:
|
if self.__gridDelay > 0.0:
|
||||||
time.sleep(self.__gridDelay)
|
time.sleep(self.__gridDelay)
|
||||||
|
|
|
@ -2929,7 +2929,6 @@
|
||||||
<name>HPCGuide</name>
|
<name>HPCGuide</name>
|
||||||
<center>7</center>
|
<center>7</center>
|
||||||
<subcenter>5</subcenter>
|
<subcenter>5</subcenter>
|
||||||
<grid>197</grid>
|
|
||||||
<process>
|
<process>
|
||||||
<id>183</id>
|
<id>183</id>
|
||||||
</process>
|
</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.SHEFDate;
|
||||||
import com.raytheon.edex.plugin.shef.util.ShefParm;
|
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;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode.Duration;
|
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode.Duration;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.util.ParameterCode.Extremum;
|
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.
|
* 03/19/08 387 M. Duff Initial creation.
|
||||||
* 10/16/2008 1548 jelkins Integrated ParameterCode Types
|
* 10/16/2008 1548 jelkins Integrated ParameterCode Types
|
||||||
* 04/29/2014 3088 mpduff cleanup.
|
* 04/29/2014 3088 mpduff cleanup.
|
||||||
|
* 06/26/2014 3321 mpduff Added ingestfilter primary key getter.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
|
@ -805,14 +807,30 @@ public class ShefData implements ISerializableObject {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getPeTsE() {
|
public String getPeDTsE() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(this.getPhysicalElement().getCode());
|
sb.append(this.getPhysicalElement().getCode());
|
||||||
sb.append(this.getTypeSource().getCode());
|
sb.append(this.getTypeSource().getCode());
|
||||||
sb.append(this.getExtremum().getCode());
|
sb.append(this.getExtremum().getCode());
|
||||||
|
sb.append(this.getDurationCodeVariable());
|
||||||
return sb.toString();
|
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
|
* @param element
|
||||||
|
@ -885,5 +903,4 @@ public class ShefData implements ISerializableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* 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.
|
* 06/02/2008 1166 M. Duff Added checks for null data objects.
|
||||||
* 22Jul2008 1277 MW Fegan Use CoreDao in checkIngest().
|
* 22Jul2008 1277 MW Fegan Use CoreDao in checkIngest().
|
||||||
* 10/16/2008 1548 jelkins Integrated ParameterCode Types and misc fixes
|
* 10/16/2008 1548 jelkins Integrated ParameterCode Types and misc fixes
|
||||||
|
@ -123,6 +123,9 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
* Updated with more performance fixes.
|
* Updated with more performance fixes.
|
||||||
* 05/28/2014 3222 mpduff Fix posting time to be processed time so db doesn't show all post times the same
|
* 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/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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mduff
|
* @author mduff
|
||||||
|
@ -228,7 +231,7 @@ public class PostShef {
|
||||||
private Map<String, ShefAdjustFactor> adjustmentMap = new HashMap<String, ShefAdjustFactor>();
|
private Map<String, ShefAdjustFactor> adjustmentMap = new HashMap<String, ShefAdjustFactor>();
|
||||||
|
|
||||||
/** Map of location identifier to IngestSwitch */
|
/** 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
|
// AppsDefaults tokens
|
||||||
private String undefStation;
|
private String undefStation;
|
||||||
|
@ -274,9 +277,6 @@ public class PostShef {
|
||||||
/** Basis time TimeStamp */
|
/** Basis time TimeStamp */
|
||||||
private java.sql.Timestamp basisTimeAnsi = new Timestamp(basisBeginTime);
|
private java.sql.Timestamp basisTimeAnsi = new Timestamp(basisBeginTime);
|
||||||
|
|
||||||
/** River status update flag. update if true */
|
|
||||||
private boolean riverStatusUpdateFlag = true;
|
|
||||||
|
|
||||||
/** river status update query value */
|
/** river status update query value */
|
||||||
private boolean riverStatusUpdateValueFlag;
|
private boolean riverStatusUpdateValueFlag;
|
||||||
|
|
||||||
|
@ -295,39 +295,12 @@ public class PostShef {
|
||||||
/** Forecast query results */
|
/** Forecast query results */
|
||||||
private Object[] queryForecastResults;
|
private Object[] queryForecastResults;
|
||||||
|
|
||||||
/** Location range data found flag */
|
/** Cache of data limits and loc data limits */
|
||||||
private boolean locRangeFound = false;
|
private Map<String, ShefRangeData> dataRangeMap = new HashMap<String, ShefRangeData>();
|
||||||
|
|
||||||
/** Default range data found flag */
|
|
||||||
private boolean defRangeFound = false;
|
|
||||||
|
|
||||||
/** Valid date range flag */
|
/** Valid date range flag */
|
||||||
private boolean validDateRange = false;
|
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
|
* @param date
|
||||||
|
@ -529,7 +502,7 @@ public class PostShef {
|
||||||
if (dataLog) {
|
if (dataLog) {
|
||||||
log.info(LOG_SEP);
|
log.info(LOG_SEP);
|
||||||
log.info("Posting process started for LID [" + locId
|
log.info("Posting process started for LID [" + locId
|
||||||
+ "] PEDTSEP [" + data.getPeTsE() + "] value ["
|
+ "] PEDTSEP [" + data.getPeDTsE() + "] value ["
|
||||||
+ dataValue + "]");
|
+ dataValue + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,7 +623,7 @@ public class PostShef {
|
||||||
if (Location.LOC_LOCATION.equals(postLocData)
|
if (Location.LOC_LOCATION.equals(postLocData)
|
||||||
|| (Location.LOC_GEOAREA.equals(postLocData))) {
|
|| (Location.LOC_GEOAREA.equals(postLocData))) {
|
||||||
if (!DataType.CONTINGENCY.equals(dataType)) {
|
if (!DataType.CONTINGENCY.equals(dataType)) {
|
||||||
ingestSwitch = checkIngest(locId, data, ingestSwitch);
|
ingestSwitch = checkIngest(locId, data);
|
||||||
}
|
}
|
||||||
if (ShefConstants.IngestSwitch.POST_PE_OFF
|
if (ShefConstants.IngestSwitch.POST_PE_OFF
|
||||||
.equals(ingestSwitch)) {
|
.equals(ingestSwitch)) {
|
||||||
|
@ -1107,23 +1080,12 @@ public class PostShef {
|
||||||
// Reset .E cache vars
|
// Reset .E cache vars
|
||||||
tsList.clear();
|
tsList.clear();
|
||||||
useLatest = MISSING;
|
useLatest = MISSING;
|
||||||
riverStatusUpdateFlag = true;
|
|
||||||
qualityCheckFlag = true;
|
qualityCheckFlag = true;
|
||||||
useTs = null;
|
useTs = null;
|
||||||
basisTimeValues = null;
|
basisTimeValues = null;
|
||||||
previousQueryForecast = null;
|
previousQueryForecast = null;
|
||||||
locRangeFound = false;
|
dataRangeMap.clear();
|
||||||
defRangeFound = false;
|
|
||||||
validDateRange = false;
|
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1448,15 +1410,7 @@ public class PostShef {
|
||||||
if ((shefList != null) && (shefList.size() > 0)) {
|
if ((shefList != null) && (shefList.size() > 0)) {
|
||||||
ShefData maxShefDataValue = findMaxFcst(shefList);
|
ShefData maxShefDataValue = findMaxFcst(shefList);
|
||||||
|
|
||||||
if (shefRecord.getShefType() == ShefType.E) {
|
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
||||||
if (riverStatusUpdateFlag) {
|
|
||||||
riverStatusUpdateFlag = false;
|
|
||||||
|
|
||||||
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
riverStatusUpdateValueFlag = updateRiverStatus(lid, pe, ts);
|
|
||||||
}
|
|
||||||
postTables.postRiverStatus(shefRecord, maxShefDataValue,
|
postTables.postRiverStatus(shefRecord, maxShefDataValue,
|
||||||
riverStatusUpdateValueFlag);
|
riverStatusUpdateValueFlag);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2125,8 +2079,7 @@ public class PostShef {
|
||||||
* ingest switch setting
|
* ingest switch setting
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private IngestSwitch checkIngest(String locId, ShefData data,
|
private IngestSwitch checkIngest(String locId, ShefData data) {
|
||||||
ShefConstants.IngestSwitch ingestSwitch) {
|
|
||||||
StringBuilder errorMsg = new StringBuilder();
|
StringBuilder errorMsg = new StringBuilder();
|
||||||
boolean matchFound = false;
|
boolean matchFound = false;
|
||||||
int hNum = 0;
|
int hNum = 0;
|
||||||
|
@ -2152,13 +2105,16 @@ public class PostShef {
|
||||||
String telem = null;
|
String telem = null;
|
||||||
String sql = null;
|
String sql = null;
|
||||||
Object[] oa = 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 {
|
try {
|
||||||
if (!ingestSwitchMap.containsKey(key)) {
|
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 = '"
|
sql = "select lid, pe, dur, ts, extremum, ts_rank, ingest, ofs_input, stg2_input from IngestFilter where lid = '"
|
||||||
+ locId + "'";
|
+ locId + "'";
|
||||||
errorMsg.setLength(0);
|
|
||||||
errorMsg.append("Error requesting IngestFilter data: " + sql);
|
errorMsg.append("Error requesting IngestFilter data: " + sql);
|
||||||
oa = dao.executeSQLQuery(sql);
|
oa = dao.executeSQLQuery(sql);
|
||||||
if (oa.length > 0) {
|
if (oa.length > 0) {
|
||||||
|
@ -2443,7 +2399,7 @@ public class PostShef {
|
||||||
if (!matchFound) {
|
if (!matchFound) {
|
||||||
log.warn(locId + " - " + data.getPhysicalElement() + "("
|
log.warn(locId + " - " + data.getPhysicalElement() + "("
|
||||||
+ data.getDuration() + ")" + data.getTypeSource()
|
+ data.getDuration() + ")" + data.getTypeSource()
|
||||||
+ data.getExtremum() + " ingest " + "filter not defined");
|
+ data.getExtremum() + " ingest filter not defined");
|
||||||
stats.incrementWarningMessages();
|
stats.incrementWarningMessages();
|
||||||
ingestSwitch = ShefConstants.IngestSwitch.POST_PE_OFF;
|
ingestSwitch = ShefConstants.IngestSwitch.POST_PE_OFF;
|
||||||
}
|
}
|
||||||
|
@ -2646,24 +2602,12 @@ public class PostShef {
|
||||||
return ShefConstants.QC_MANUAL_FAILED;
|
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 locLimitSql = new StringBuilder();
|
||||||
StringBuilder defLimitSql = new StringBuilder();
|
StringBuilder defLimitSql = new StringBuilder();
|
||||||
|
String key = lid + data.getPhysicalElement().getCode()
|
||||||
|
+ data.getDurationValue();
|
||||||
try {
|
try {
|
||||||
if (executeQuery) {
|
if (!dataRangeMap.containsKey(key)) {
|
||||||
String sqlStart = "select monthdaystart, monthdayend, gross_range_min, gross_range_max, reason_range_min, "
|
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, "
|
+ "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, "
|
+ "alarm_roc_limit, alert_lower_limit, alarm_lower_limit, alert_diff_limit, "
|
||||||
|
@ -2679,6 +2623,7 @@ public class PostShef {
|
||||||
Object[] oa = dao.executeSQLQuery(locLimitSql.toString());
|
Object[] oa = dao.executeSQLQuery(locLimitSql.toString());
|
||||||
|
|
||||||
if (oa.length == 0) {
|
if (oa.length == 0) {
|
||||||
|
dataRangeMap.put(key, null);
|
||||||
// default range
|
// default range
|
||||||
defLimitSql = new StringBuilder(sqlStart);
|
defLimitSql = new StringBuilder(sqlStart);
|
||||||
defLimitSql.append("datalimits where pe = '")
|
defLimitSql.append("datalimits where pe = '")
|
||||||
|
@ -2687,7 +2632,13 @@ public class PostShef {
|
||||||
.append(data.getDurationValue());
|
.append(data.getDurationValue());
|
||||||
|
|
||||||
oa = dao.executeSQLQuery(defLimitSql.toString());
|
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++) {
|
for (int i = 0; i < oa.length; i++) {
|
||||||
Object[] oa2 = (Object[]) oa[i];
|
Object[] oa2 = (Object[]) oa[i];
|
||||||
|
|
||||||
|
@ -2704,49 +2655,65 @@ public class PostShef {
|
||||||
* if a range is found, then check the value and set the
|
* if a range is found, then check the value and set the
|
||||||
* flag
|
* flag
|
||||||
*/
|
*/
|
||||||
grossRangeMin = ShefUtil.getDouble(oa2[2], missing);
|
ShefRangeData rangeData = new ShefRangeData();
|
||||||
grossRangeMax = ShefUtil.getDouble(oa2[3], missing);
|
rangeData.setGrossRangeMin(ShefUtil.getDouble(oa2[2],
|
||||||
reasonRangeMin = ShefUtil.getDouble(oa2[4], missing);
|
missing));
|
||||||
reasonRangeMax = ShefUtil.getDouble(oa2[5], missing);
|
rangeData.setGrossRangeMax(ShefUtil.getDouble(oa2[3],
|
||||||
alertUpperLimit = ShefUtil.getDouble(oa2[7], missing);
|
missing));
|
||||||
alertLowerLimit = ShefUtil.getDouble(oa2[11], missing);
|
rangeData.setReasonRangeMin(ShefUtil.getDouble(oa2[4],
|
||||||
alarmLowerLimit = ShefUtil.getDouble(oa2[12], missing);
|
missing));
|
||||||
alarmUpperLimit = ShefUtil.getDouble(oa2[9], missing);
|
rangeData.setReasonRangeMax(ShefUtil.getDouble(oa2[5],
|
||||||
defRangeFound = true;
|
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;
|
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 a range is found, then check the value and set the flag
|
||||||
*/
|
*/
|
||||||
if (((grossRangeMin != missing) && (dValue < grossRangeMin))
|
if (((rangeData.getGrossRangeMin() != missing) && (dValue < rangeData
|
||||||
|| ((grossRangeMax != missing) && (dValue > grossRangeMax))) {
|
.getGrossRangeMin()))
|
||||||
|
|| ((rangeData.getGrossRangeMax() != missing) && (dValue > rangeData
|
||||||
|
.getGrossRangeMax()))) {
|
||||||
qualityCode = ShefQC.setQcCode(
|
qualityCode = ShefQC.setQcCode(
|
||||||
(int) ShefConstants.QC_GROSSRANGE_FAILED,
|
(int) ShefConstants.QC_GROSSRANGE_FAILED,
|
||||||
qualityCode);
|
qualityCode);
|
||||||
|
|
||||||
if (dataLog) {
|
if (dataLog) {
|
||||||
log.info(lid + " failed gross range check: " + dValue
|
log.info(lid + " failed gross range check: " + dValue
|
||||||
+ " out of range " + grossRangeMin + " - "
|
+ " out of range "
|
||||||
+ grossRangeMax);
|
+ rangeData.getGrossRangeMin() + " - "
|
||||||
|
+ rangeData.getGrossRangeMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* don't do anything if it fails the gross range check
|
* don't do anything if it fails the gross range check
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
if (((reasonRangeMin != missing) && (dValue < reasonRangeMin))
|
if (((rangeData.getReasonRangeMin() != missing) && (dValue < rangeData
|
||||||
|| ((reasonRangeMax != missing) && (dValue > reasonRangeMax))) {
|
.getReasonRangeMin()))
|
||||||
|
|| ((rangeData.getReasonRangeMax() != missing) && (dValue > rangeData
|
||||||
|
.getReasonRangeMax()))) {
|
||||||
qualityCode = ShefQC.setQcCode(
|
qualityCode = ShefQC.setQcCode(
|
||||||
(int) ShefConstants.QC_REASONRANGE_FAILED,
|
(int) ShefConstants.QC_REASONRANGE_FAILED,
|
||||||
qualityCode);
|
qualityCode);
|
||||||
if (dataLog) {
|
if (dataLog) {
|
||||||
log.info(lid + " failed reasonable range check: "
|
log.info(lid + " failed reasonable range check: "
|
||||||
+ dValue + " out of range "
|
+ dValue + " out of range "
|
||||||
+ reasonRangeMin + " - " + reasonRangeMax);
|
+ rangeData.getReasonRangeMin() + " - "
|
||||||
|
+ rangeData.getReasonRangeMax());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2756,17 +2723,17 @@ public class PostShef {
|
||||||
* table.
|
* table.
|
||||||
*/
|
*/
|
||||||
if (shefAlertAlarm) {
|
if (shefAlertAlarm) {
|
||||||
if ((alarmUpperLimit != missing)
|
if ((rangeData.getAlarmUpperLimit() != missing)
|
||||||
&& (dValue >= alarmUpperLimit)) {
|
&& (dValue >= rangeData.getAlarmUpperLimit())) {
|
||||||
alertAlarm = ShefConstants.ALARM_UPPER_DETECTED;
|
alertAlarm = ShefConstants.ALARM_UPPER_DETECTED;
|
||||||
} else if ((alertUpperLimit != missing)
|
} else if ((rangeData.getAlertUpperLimit() != missing)
|
||||||
&& (dValue >= alertUpperLimit)) {
|
&& (dValue >= rangeData.getAlertUpperLimit())) {
|
||||||
alertAlarm = ShefConstants.ALERT_UPPER_DETECTED;
|
alertAlarm = ShefConstants.ALERT_UPPER_DETECTED;
|
||||||
} else if ((alarmLowerLimit != missing)
|
} else if ((rangeData.getAlarmLowerLimit() != missing)
|
||||||
&& (dValue <= alarmLowerLimit)) {
|
&& (dValue <= rangeData.getAlarmLowerLimit())) {
|
||||||
alertAlarm = ShefConstants.ALARM_LOWER_DETECTED;
|
alertAlarm = ShefConstants.ALARM_LOWER_DETECTED;
|
||||||
} else if ((alertLowerLimit != missing)
|
} else if ((rangeData.getAlertLowerLimit() != missing)
|
||||||
&& (dValue <= alertLowerLimit)) {
|
&& (dValue <= rangeData.getAlertLowerLimit())) {
|
||||||
alertAlarm = ShefConstants.ALERT_LOWER_DETECTED;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,8 +23,8 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import com.raytheon.edex.utility.ProtectedFiles;
|
import com.raytheon.edex.utility.ProtectedFiles;
|
||||||
import com.raytheon.uf.common.auth.exception.AuthorizationException;
|
import com.raytheon.uf.common.auth.exception.AuthorizationException;
|
||||||
|
@ -54,6 +54,7 @@ import com.raytheon.uf.edex.core.EDEXUtil;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 11, 2010 mschenke Initial creation
|
* Aug 11, 2010 mschenke Initial creation
|
||||||
|
* Jul 14, 2014 3372 njensen fileMap is ConcurrentHashMap for thread safety
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -75,7 +76,7 @@ public class LocalizationStreamHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<StreamPair, File> fileMap = new HashMap<StreamPair, File>();
|
private Map<StreamPair, File> fileMap = new ConcurrentHashMap<StreamPair, File>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<parameter>zAGL</parameter>
|
<parameter>zAGL</parameter>
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<contourStyle>
|
<contourStyle>
|
||||||
<displayUnits>dam</displayUnits>
|
<displayUnits>ft</displayUnits>
|
||||||
<contourLabeling labelSpacing="4" labelFormat="#">
|
<contourLabeling labelSpacing="4" labelFormat="#">
|
||||||
<increment>50</increment>
|
<increment>50</increment>
|
||||||
</contourLabeling>
|
</contourLabeling>
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
<parameter>Topo</parameter>
|
<parameter>Topo</parameter>
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<displayUnits>km</displayUnits>
|
<displayUnits>ft</displayUnits>
|
||||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
</styleRule>
|
</styleRule>
|
||||||
|
|
|
@ -43,6 +43,7 @@ import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
||||||
* --/--/---- Initial creation
|
* --/--/---- Initial creation
|
||||||
* 10/22/2013 2361 njensen Use JAXBManager for XML
|
* 10/22/2013 2361 njensen Use JAXBManager for XML
|
||||||
* Apr 28, 2014 3033 jsanchez Refactored file retrieval.
|
* Apr 28, 2014 3033 jsanchez Refactored file retrieval.
|
||||||
|
* Jul 02, 2014 DR 17450 D. Friedman Support using list of templates from backup site.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
|
@ -91,6 +92,18 @@ public class DialogConfiguration {
|
||||||
return (DialogConfiguration) jaxb.unmarshalFromXml(xml);
|
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() {
|
public String getWarngenOfficeShort() {
|
||||||
return warngenOfficeShort;
|
return warngenOfficeShort;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,18 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Apr 28, 2014 3033 jsanchez Searches the backup site directory before the localized site directory.
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class WarnFileUtil {
|
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
|
* Returns the appropriate file in localization. If a backupSiteID is not
|
||||||
* null and a corresponding file does exist in the backup site directory,
|
* null and a corresponding file does exist in the backup site directory,
|
||||||
|
@ -49,7 +55,7 @@ public class WarnFileUtil {
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
*/
|
*/
|
||||||
public static LocalizationFile findFileInLocalizationIncludingBackupSite(String filename,
|
public static LocalizationFile findFileInLocalizationIncludingBackupSite(String filename,
|
||||||
String issuingSiteID, String backupSiteID)
|
String issuingSiteID, String backupSiteID, boolean allowUser)
|
||||||
throws FileNotFoundException {
|
throws FileNotFoundException {
|
||||||
|
|
||||||
IPathManager pm = PathManagerFactory.getPathManager();
|
IPathManager pm = PathManagerFactory.getPathManager();
|
||||||
|
@ -71,6 +77,9 @@ public class WarnFileUtil {
|
||||||
LocalizationContext[] searchContext = pm
|
LocalizationContext[] searchContext = pm
|
||||||
.getLocalSearchHierarchy(LocalizationType.COMMON_STATIC);
|
.getLocalSearchHierarchy(LocalizationType.COMMON_STATIC);
|
||||||
for (LocalizationContext ctx : searchContext) {
|
for (LocalizationContext ctx : searchContext) {
|
||||||
|
if (!allowUser && ctx.getLocalizationLevel() == LocalizationLevel.USER)
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((ctx.getLocalizationLevel() == LocalizationLevel.SITE || ctx
|
if ((ctx.getLocalizationLevel() == LocalizationLevel.SITE || ctx
|
||||||
.getLocalizationLevel() == LocalizationLevel.CONFIGURED)
|
.getLocalizationLevel() == LocalizationLevel.CONFIGURED)
|
||||||
&& issuingSiteID != null) {
|
&& issuingSiteID != null) {
|
||||||
|
@ -90,6 +99,18 @@ public class WarnFileUtil {
|
||||||
return fileToUse;
|
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
|
* Locates the appropriate file in the localization hierarchy including the
|
||||||
* backupSite directory (if provided) and converts the content of the file
|
* backupSite directory (if provided) and converts the content of the file
|
||||||
|
@ -105,10 +126,20 @@ public class WarnFileUtil {
|
||||||
public static String convertFileContentsToString(String filename,
|
public static String convertFileContentsToString(String filename,
|
||||||
String localizedSite, String backupSite)
|
String localizedSite, String backupSite)
|
||||||
throws FileNotFoundException, IOException {
|
throws FileNotFoundException, IOException {
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
BufferedReader input = null;
|
|
||||||
File file = findFileInLocalizationIncludingBackupSite(filename, localizedSite, backupSite)
|
File file = findFileInLocalizationIncludingBackupSite(filename, localizedSite, backupSite)
|
||||||
.getFile();
|
.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 {
|
try {
|
||||||
input = new BufferedReader(new FileReader(file));
|
input = new BufferedReader(new FileReader(file));
|
||||||
|
|
||||||
|
|
|
@ -189,33 +189,35 @@ ${drainage.name}##
|
||||||
########END MACRO
|
########END MACRO
|
||||||
|
|
||||||
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
#macro(inserttorwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||||
#set($torWatches = ${watches.getTorWatches()})
|
#set($tornadoWatches = [])
|
||||||
#set($torWatchAlso = "")
|
#foreach(${watch} in ${watches})
|
||||||
#set($torWatchFirst = 1)
|
#if(${watch.getPhenSig()} == 'TO.A')
|
||||||
#foreach(${watch} in ${torWatches})
|
#set($success = $tornadoWatches.add($watch))
|
||||||
#if($torWatchFirst)
|
#set($endTime = ${watch.endTime})
|
||||||
#set($torWatchFirst = 0)
|
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||||
#else
|
#set($latestEndTime = ${endTime})
|
||||||
##
|
|
||||||
#end
|
#end
|
||||||
A TORNADO WATCH ${torWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
|
#if(!${list.isEmpty($tornadoWatches)})
|
||||||
|
|
||||||
|
A TORNADO WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||||
|
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||||
#if(${secondtimezone})
|
#if(${secondtimezone})
|
||||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||||
#end
|
#end
|
||||||
FOR ##
|
FOR ##
|
||||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
#set($numPortions = ${list.size(${tornadoWatches})})
|
||||||
#set($count = 0)
|
#set($count = 0)
|
||||||
#foreach(${portion} in ${watch.getPortions()})
|
#foreach(${watch} in ${tornadoWatches})
|
||||||
#set($count = $count + 1)
|
#set($count = $count + 1)
|
||||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||||
#if($count == $numPortions - 1)
|
#if($count == $numPortions - 1)
|
||||||
AND ##
|
AND ##
|
||||||
#elseif($count < $numPortions)
|
#elseif($count < $numPortions)
|
||||||
...##
|
...##
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#set($torWatchAlso = "ALSO ")
|
|
||||||
. ##
|
. ##
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -223,33 +225,35 @@ ${dateUtil.period(${watches.getLatestTorTime()},${timeFormat.plain}, 15, ${local
|
||||||
########END MACRO
|
########END MACRO
|
||||||
|
|
||||||
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
#macro(insertsvrwatches $watches $list $secondtimezone $dateUtil $timeFormat)
|
||||||
#set($svrWatches = ${watches.getSvrWatches()})
|
#set($severeWatches = [])
|
||||||
#set($svrWatchAlso = "")
|
#foreach(${watch} in ${watches})
|
||||||
#set($svrWatchFirst = 1)
|
#if(${watch.getPhenSig()} == 'SV.A')
|
||||||
#foreach(${watch} in ${svrWatches})
|
#set($success = $severeWatches.add($watch))
|
||||||
#if($svrWatchFirst)
|
#set($endTime = ${watch.endTime})
|
||||||
#set($svrWatchFirst = 0)
|
#if(!$latestEndTime || ${endTime.after($latestEndTime)})
|
||||||
#else
|
#set($latestEndTime = ${endTime})
|
||||||
##
|
|
||||||
#end
|
#end
|
||||||
A SEVERE THUNDERSTORM WATCH ${svrWatchAlso}REMAINS IN EFFECT UNTIL ${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
${dateUtil.period(${watches.getLatestSvrTime()},${timeFormat.plain}, 15, ${localtimezone})}##
|
#end
|
||||||
|
#if(!${list.isEmpty($severeWatches)})
|
||||||
|
|
||||||
|
A SEVERE THUNDERSTORM WATCH REMAINS IN EFFECT UNTIL ${dateUtil.format(${latestEndTime}, ${timeFormat.plain}, 15, ${localtimezone})}##
|
||||||
|
${dateUtil.period(${latestEndTime},${timeFormat.plain}, 15, ${localtimezone})}##
|
||||||
#if(${secondtimezone})
|
#if(${secondtimezone})
|
||||||
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
/${dateUtil.format(${watch.getEndTime()}, ${timeFormat.plain}, 15, ${secondtimezone})}/##
|
||||||
#end
|
#end
|
||||||
FOR ##
|
FOR ##
|
||||||
#set($numPortions = ${list.size(${watch.getPortions()})})
|
#set($numPortions = ${list.size(${severeWatches})})
|
||||||
#set($count = 0)
|
#set($count = 0)
|
||||||
#foreach(${portion} in ${watch.getPortions()})
|
#foreach(${watch} in ${severeWatches})
|
||||||
#set($count = $count + 1)
|
#set($count = $count + 1)
|
||||||
#areaFormat(${portion.partOfParentRegion} true false true)${portion.parentRegion}##
|
#areaFormat(${watch.partOfState} true false true)${watch.state}##
|
||||||
#if($count == $numPortions - 1)
|
#if($count == $numPortions - 1)
|
||||||
AND ##
|
AND ##
|
||||||
#elseif($count < $numPortions)
|
#elseif($count < $numPortions)
|
||||||
...##
|
...##
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#set($svrWatchAlso = "ALSO ")
|
|
||||||
. ##
|
. ##
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -368,18 +372,6 @@ SOUTH##
|
||||||
#if(${list.contains($directionSet, "WEST")})
|
#if(${list.contains($directionSet, "WEST")})
|
||||||
#set($output = "${output}WEST")
|
#set($output = "${output}WEST")
|
||||||
#end
|
#end
|
||||||
#if(${list.contains($directionSet, "NE")})
|
|
||||||
#set($output = "${output}NORTHEAST")
|
|
||||||
#end
|
|
||||||
#if(${list.contains($directionSet, "NW")})
|
|
||||||
#set($output = "${output}NORTHWEST")
|
|
||||||
#end
|
|
||||||
#if(${list.contains($directionSet, "SE")})
|
|
||||||
#set($output = "${output}SOUTHEAST")
|
|
||||||
#end
|
|
||||||
#if(${list.contains($directionSet, "SW")})
|
|
||||||
#set($output = "${output}SOUTHWEST")
|
|
||||||
#end
|
|
||||||
#if(${useCentral} && ${list.contains($directionSet, "CENTRAL")})
|
#if(${useCentral} && ${list.contains($directionSet, "CENTRAL")})
|
||||||
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
#if(${list.contains($directionSet, "NORTH")} || ${list.contains($directionSet, "SOUTH")} || ${list.contains($directionSet, "EAST")} || ${list.contains($directionSet, "WEST")})
|
||||||
#set($output = "${output} ")
|
#set($output = "${output} ")
|
||||||
|
|
|
@ -119,11 +119,11 @@ FOR THE FOLLOWING THREATS...
|
||||||
## If sites do not want watches in their AWW product comment out the
|
## If sites do not want watches in their AWW product comment out the
|
||||||
## section below
|
## section below
|
||||||
#######################################################################
|
#######################################################################
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -48,11 +48,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -59,11 +59,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<enableDamBreakThreat>true</enableDamBreakThreat>
|
<enableDamBreakThreat>true</enableDamBreakThreat>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>.
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>.
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
|
@ -191,10 +191,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -69,10 +69,10 @@ THIS IS A TEST MESSAGE. ##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -238,10 +238,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -346,10 +346,10 @@ THIS IS A TEST MESSAGE.##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -468,10 +468,10 @@ THE SAFEST PLACE TO BE DURING A MAJOR LANDFALLING HURRICANE IS IN A REINFORCED I
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -512,10 +512,10 @@ THIS IS A TEST MESSAGE.##
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -57,11 +57,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- durations: the list of possible durations of the svs -->
|
||||||
|
|
|
@ -52,7 +52,7 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
|
@ -67,11 +67,11 @@ Must be paired with proper vm code (also commented out in flashFloodWarning.vm)!
|
||||||
<!-- <trackEnabled>true</trackEnabled> -->
|
<!-- <trackEnabled>true</trackEnabled> -->
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -624,12 +624,12 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
#* NO NEED TO INCLUDE SVR T-STM WATCHES IN A SVR WARNING!!!!
|
#* NO NEED TO INCLUDE SVR T-STM WATCHES IN A SVR WARNING!!!!
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#
|
#
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -54,10 +54,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -290,10 +290,10 @@ ${expcanPhrase} ${addthreat}
|
||||||
###########################################
|
###########################################
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -1180,7 +1180,7 @@ TORRENTIAL RAINFALL IS OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FLOODIN
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -72,8 +72,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
</phensigs>
|
</phensigs>
|
||||||
|
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<enableRestart>false</enableRestart>
|
<enableRestart>false</enableRestart>
|
||||||
|
|
|
@ -470,10 +470,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -397,10 +397,10 @@ ${canwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -571,10 +571,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -679,10 +679,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -880,10 +880,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#elseif(${CORCAN} == "true")
|
#elseif(${CORCAN} == "true")
|
||||||
|
@ -952,10 +952,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -1142,10 +1142,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -1219,10 +1219,10 @@ ${expwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -52,11 +52,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- durations: the list of possible durations of the svs -->
|
||||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations -->
|
<!-- durations: the list of possible durations -->
|
||||||
|
|
|
@ -51,11 +51,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations -->
|
<!-- durations: the list of possible durations -->
|
||||||
|
|
|
@ -471,7 +471,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -58,10 +58,10 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -262,10 +262,10 @@ ${expcanPhrase} ${addthreat}
|
||||||
###########################################
|
###########################################
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
###if(${list.contains(${includedWatches}, "torWatches")})
|
###if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
###inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
###end
|
###end
|
||||||
###if(${list.contains(${includedWatches}, "svrWatches")})
|
###if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
###insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
###end
|
###end
|
||||||
#if(${list.contains(${bullets}, "svrboxactive")})
|
#if(${list.contains(${bullets}, "svrboxactive")})
|
||||||
|
@ -924,7 +924,7 @@ TORRENTIAL RAINFALL IS ALSO OCCURRING WITH THIS STORM...AND MAY LEAD TO FLASH FL
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${phenomena}=="SV")
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${phenomena}=="SV")
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -69,8 +69,8 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
</phensigs>
|
</phensigs>
|
||||||
|
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<enableRestart>false</enableRestart>
|
<enableRestart>false</enableRestart>
|
||||||
|
|
|
@ -230,11 +230,11 @@ LOCATIONS CAN EXPECT !** EXPECTED SNOW **! INCHES OF SNOW.
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")} && ${list.contains(${bullets}, "includeTorWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")} && ${list.contains(${bullets}, "includeTorWatches")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")} && ${list.contains(${bullets}, "includeSvrWatches")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -309,10 +309,10 @@ IF ON OR NEAR !**Name Of Lake**!...GET OUT OF THE WATER AND MOVE INDOORS OR INSI
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
####################################
|
####################################
|
||||||
|
|
|
@ -50,11 +50,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -431,10 +431,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
|
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
|
|
@ -54,11 +54,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -365,10 +365,10 @@ ${canwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -538,10 +538,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -646,10 +646,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${productClass}=="T")
|
#if(${productClass}=="T")
|
||||||
|
@ -845,10 +845,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#elseif(${CORCAN} == "true")
|
#elseif(${CORCAN} == "true")
|
||||||
|
@ -917,10 +917,10 @@ THE ${eventType} !** WEAKENED / MOVED OUT OF THE WARNED AREA **! AND NO LONGER $
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -1104,10 +1104,10 @@ REPORT SEVERE WEATHER TO THE COAST GUARD OR NEAREST LAW ENFORCEMENT AGENCY. THEY
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@ -1182,10 +1182,10 @@ ${expwarning}
|
||||||
#############
|
#############
|
||||||
## WATCHES ##
|
## WATCHES ##
|
||||||
#############
|
#############
|
||||||
#if(${list.contains(${includedWatches}, "torWatches")})
|
#if(${list.contains(${includedWatches}, "TO.A")})
|
||||||
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#inserttorwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#if(${list.contains(${includedWatches}, "svrWatches")})
|
#if(${list.contains(${includedWatches}, "SV.A")})
|
||||||
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
#insertsvrwatches(${watches}, ${list}, ${secondtimezone}, ${dateUtil}, ${timeFormat})
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -56,11 +56,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the svs -->
|
<!-- durations: the list of possible durations of the svs -->
|
||||||
|
|
|
@ -49,11 +49,11 @@ turned on unless the corresponding .vm file is turned on in a given template's .
|
||||||
<autoLockText>true</autoLockText>
|
<autoLockText>true</autoLockText>
|
||||||
|
|
||||||
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
<!-- Included watches: If a tornado watch or severe thunderstorm watch is to be
|
||||||
included with the warning product include torWatches and/or svrWatches,
|
included with the warning product include TO.A and/or SV.A,
|
||||||
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
respectively. Please refer to 'includedWatchAreaBuffer' in <areaConfig/>. -->
|
||||||
<includedWatches>
|
<includedWatches>
|
||||||
<includedWatch>torWatches</includedWatch>
|
<includedWatch>TO.A</includedWatch>
|
||||||
<includedWatch>svrWatches</includedWatch>
|
<includedWatch>SV.A</includedWatch>
|
||||||
</includedWatches>
|
</includedWatches>
|
||||||
|
|
||||||
<!-- durations: the list of possible durations of the warning -->
|
<!-- durations: the list of possible durations of the warning -->
|
||||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: Activetablesrv Plug-in
|
Bundle-Name: Activetablesrv Plug-in
|
||||||
Bundle-SymbolicName: com.raytheon.uf.edex.activetable
|
Bundle-SymbolicName: com.raytheon.uf.edex.activetable
|
||||||
Bundle-Version: 1.12.1174.qualifier
|
Bundle-Version: 1.13.0.qualifier
|
||||||
Bundle-Vendor: RAYTHEON
|
Bundle-Vendor: RAYTHEON
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Import-Package: com.raytheon.uf.common.activetable,
|
Import-Package: com.raytheon.uf.common.activetable,
|
||||||
|
@ -26,6 +26,7 @@ Require-Bundle: com.raytheon.uf.common.localization;bundle-version="1.11.1",
|
||||||
com.raytheon.uf.edex.site;bundle-version="1.0.0",
|
com.raytheon.uf.edex.site;bundle-version="1.0.0",
|
||||||
com.google.guava;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.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"
|
||||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
||||||
Export-Package: com.raytheon.uf.edex.activetable
|
Export-Package: com.raytheon.uf.edex.activetable
|
||||||
|
|
|
@ -24,14 +24,15 @@ import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import jep.JepException;
|
import jep.JepException;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.raytheon.edex.site.SiteUtil;
|
||||||
import com.raytheon.edex.util.Util;
|
import com.raytheon.edex.util.Util;
|
||||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
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.PyUtil;
|
||||||
import com.raytheon.uf.common.python.PythonScript;
|
import com.raytheon.uf.common.python.PythonScript;
|
||||||
import com.raytheon.uf.common.site.SiteMap;
|
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.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.PerformanceStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.util.CollectionUtil;
|
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.common.util.FileUtil;
|
||||||
import com.raytheon.uf.edex.core.EDEXUtil;
|
import com.raytheon.uf.edex.core.EDEXUtil;
|
||||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||||
|
@ -83,6 +88,9 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||||
* Mar 06, 2014 2883 randerso Pass siteId into python code
|
* Mar 06, 2014 2883 randerso Pass siteId into python code
|
||||||
* Apr 10, 2014 3004 dgilling Remove ActiveTableMode parameter from
|
* Apr 10, 2014 3004 dgilling Remove ActiveTableMode parameter from
|
||||||
* clearPracticeTable().
|
* clearPracticeTable().
|
||||||
|
* Jun 17, 2014 3296 randerso Cached PythonScript. Moved active table
|
||||||
|
* backup and purging to a separate thread.
|
||||||
|
* Added performance logging
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -97,9 +105,44 @@ public class ActiveTable {
|
||||||
private static final Logger changeLog = Logger
|
private static final Logger changeLog = Logger
|
||||||
.getLogger("ActiveTableChange");
|
.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(
|
private static CoreDao practiceDao = new CoreDao(
|
||||||
DaoConfig.forClass(PracticeActiveTableRecord.class));
|
DaoConfig.forClass(PracticeActiveTableRecord.class));
|
||||||
|
@ -107,25 +150,9 @@ public class ActiveTable {
|
||||||
private static CoreDao operationalDao = new CoreDao(
|
private static CoreDao operationalDao = new CoreDao(
|
||||||
DaoConfig.forClass(OperationalActiveTableRecord.class));
|
DaoConfig.forClass(OperationalActiveTableRecord.class));
|
||||||
|
|
||||||
private PythonScript python;
|
/**
|
||||||
|
* Default constructor
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActiveTable() {
|
public ActiveTable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +181,10 @@ public class ActiveTable {
|
||||||
* the active table mode (PRACTICE or OPERATIONAL)
|
* the active table mode (PRACTICE or OPERATIONAL)
|
||||||
* @param phensigList
|
* @param phensigList
|
||||||
* phensigs to include. If null, all phensigs will be included.
|
* 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
|
* @param requestValidTimes
|
||||||
* true if only valid times are to be returned
|
* true if only valid times are to be returned
|
||||||
* @return the active table corresponding to the input parameters
|
* @return the active table corresponding to the input parameters
|
||||||
|
@ -173,6 +204,10 @@ public class ActiveTable {
|
||||||
* the active table mode (PRACTICE or OPERATIONAL)
|
* the active table mode (PRACTICE or OPERATIONAL)
|
||||||
* @param phensigList
|
* @param phensigList
|
||||||
* phensigs to include. If null, all phensigs will be included.
|
* 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
|
* @param requestValidTimes
|
||||||
* true if only valid times are to be returned
|
* true if only valid times are to be returned
|
||||||
* @param wfos
|
* @param wfos
|
||||||
|
@ -186,32 +221,18 @@ public class ActiveTable {
|
||||||
String[] wfos) {
|
String[] wfos) {
|
||||||
|
|
||||||
if (wfos == null || !Arrays.asList(wfos).contains("all")) {
|
if (wfos == null || !Arrays.asList(wfos).contains("all")) {
|
||||||
SiteMap siteMap = SiteMap.getInstance();
|
|
||||||
|
|
||||||
if (wfos == null || wfos.length == 0) {
|
if (wfos == null || wfos.length == 0) {
|
||||||
// default to WFOs from VTECPartners
|
// default to WFOs from VTECPartners
|
||||||
|
|
||||||
// Use the 3-char site or VTEC_DECODER_SITES will be empty
|
Set<String> wfoSet = getDecoderSites(siteId);
|
||||||
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);
|
|
||||||
String spcSite = (String) vtecPartners
|
|
||||||
.getattr("VTEC_SPC_SITE");
|
|
||||||
wfoSet.add(spcSite);
|
|
||||||
String tpcSite = (String) vtecPartners
|
|
||||||
.getattr("VTEC_TPC_SITE");
|
|
||||||
wfoSet.add(tpcSite);
|
|
||||||
}
|
|
||||||
wfoSet.add(siteId);
|
wfoSet.add(siteId);
|
||||||
wfos = wfoSet.toArray(new String[0]);
|
wfos = wfoSet.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have an array of 3- or 4-char WFOs to filter against.
|
// We have an array of 3- or 4-char WFOs to filter against.
|
||||||
// We need a String "KMFL,KTBW,..." for the query.
|
// We need a String "KMFL,KTBW,..." for the query.
|
||||||
|
SiteMap siteMap = SiteMap.getInstance();
|
||||||
StringBuilder wfosb = new StringBuilder();
|
StringBuilder wfosb = new StringBuilder();
|
||||||
String sep = "";
|
String sep = "";
|
||||||
for (String wfo : wfos) {
|
for (String wfo : wfos) {
|
||||||
|
@ -228,6 +249,26 @@ public class ActiveTable {
|
||||||
false);
|
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
|
* Updates the active table with the new warnings
|
||||||
*
|
*
|
||||||
|
@ -244,11 +285,38 @@ public class ActiveTable {
|
||||||
mode = ActiveTableMode.OPERATIONAL;
|
mode = ActiveTableMode.OPERATIONAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MergeResult result = filterTable(siteId,
|
IPerformanceStatusHandler perfStat = PerformanceStatus
|
||||||
getActiveTable(siteId, mode), newRecords, mode, offsetSecs);
|
.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);
|
updateTable(siteId, result, mode);
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateTable", timer.getElapsedTime());
|
||||||
if (result.changeList.size() > 0) {
|
if (result.changeList.size() > 0) {
|
||||||
sendNotification(mode, result.changeList, "VTECDecoder");
|
sendNotification(mode, result.changeList, "VTECDecoder");
|
||||||
}
|
}
|
||||||
|
@ -281,26 +349,17 @@ public class ActiveTable {
|
||||||
args.put("offsetSecs", offsetSecs);
|
args.put("offsetSecs", offsetSecs);
|
||||||
MergeResult result = null;
|
MergeResult result = null;
|
||||||
try {
|
try {
|
||||||
|
PythonScript python = threadLocalPythonScript.get();
|
||||||
try {
|
try {
|
||||||
python = new PythonScript(filePath, includePath,
|
result = (MergeResult) python.execute("mergeFromJava", args);
|
||||||
ActiveTable.class.getClassLoader());
|
|
||||||
try {
|
|
||||||
result = (MergeResult) python
|
|
||||||
.execute("mergeFromJava", args);
|
|
||||||
} catch (JepException e) {
|
} catch (JepException e) {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
"Error updating active table", e);
|
"Error updating active table", e);
|
||||||
}
|
}
|
||||||
} catch (JepException e) {
|
} catch (Exception e) {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
"Error initializing active table python", e);
|
"Error initializing active table python", e);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
if (python != null) {
|
|
||||||
python.dispose();
|
|
||||||
python = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -415,15 +474,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) {
|
public Exception merge(List<ActiveTableRecord> newRecords) {
|
||||||
return merge(newRecords, 0.0f);
|
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) {
|
public Exception merge(List<ActiveTableRecord> newRecords, float timeOffset) {
|
||||||
Exception exc = null;
|
Exception exc = null;
|
||||||
try {
|
try {
|
||||||
if (newRecords != null) {
|
if (newRecords != null) {
|
||||||
String siteId = newRecords.get(0).getOfficeid();
|
String siteId = SiteUtil.getSite();
|
||||||
|
siteId = SiteMap.getInstance().getSite4LetterId(siteId);
|
||||||
updateActiveTable(siteId, newRecords, timeOffset);
|
updateActiveTable(siteId, newRecords, timeOffset);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -528,10 +604,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)
|
public static void clearPracticeTable(String requestedSiteId)
|
||||||
throws DataAccessLayerException {
|
throws DataAccessLayerException {
|
||||||
CoreDao dao = practiceDao;
|
CoreDao dao = practiceDao;
|
||||||
|
@ -544,6 +623,13 @@ public class ActiveTable {
|
||||||
dao.executeNativeSql(sql);
|
dao.executeNativeSql(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump product text to temp file
|
||||||
|
*
|
||||||
|
* @param productText
|
||||||
|
* product text
|
||||||
|
* @return the temp file
|
||||||
|
*/
|
||||||
public static File dumpProductToTempFile(String productText) {
|
public static File dumpProductToTempFile(String productText) {
|
||||||
File file = Util.createTempFile(productText.getBytes(), "vtec");
|
File file = Util.createTempFile(productText.getBytes(), "vtec");
|
||||||
file.deleteOnExit();
|
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;
|
package com.raytheon.uf.edex.activetable;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.raytheon.edex.esb.Headers;
|
import com.raytheon.edex.esb.Headers;
|
||||||
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
import com.raytheon.uf.common.activetable.ActiveTableMode;
|
||||||
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
import com.raytheon.uf.common.activetable.ActiveTableRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
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;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
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
|
* 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
|
* Mar 17, 2009 njensen Initial creation
|
||||||
* Jul 14, 2009 #2950 njensen Multiple site support
|
* Jul 14, 2009 #2950 njensen Multiple site support
|
||||||
* Dec 21, 2009 #4055 njensen No site filtering
|
* Dec 21, 2009 #4055 njensen No site filtering
|
||||||
|
* Jun 17, 2014 3296 randerso Added performance logging
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -54,16 +56,30 @@ public class ActiveTableSrv {
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
.getHandler(ActiveTableSrv.class);
|
.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) {
|
public void vtecArrived(List<AbstractWarningRecord> records) {
|
||||||
|
ITimer timer = TimeUtil.getTimer();
|
||||||
|
timer.start();
|
||||||
try {
|
try {
|
||||||
long threadId = Thread.currentThread().getId();
|
ActiveTable activeTable = threadLocalActiveTable.get();
|
||||||
ActiveTable activeTable = activeTableMap.get(threadId);
|
|
||||||
if (activeTable == null) {
|
|
||||||
activeTable = new ActiveTable();
|
|
||||||
activeTableMap.put(threadId, activeTable);
|
|
||||||
}
|
|
||||||
if (records != null && records.size() > 0) {
|
if (records != null && records.size() > 0) {
|
||||||
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
||||||
records, ActiveTableMode.OPERATIONAL));
|
records, ActiveTableMode.OPERATIONAL));
|
||||||
|
@ -72,8 +88,18 @@ public class ActiveTableSrv {
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
"Error merging active table", t);
|
"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,
|
public void practiceVtecArrived(List<AbstractWarningRecord> records,
|
||||||
Headers headers) {
|
Headers headers) {
|
||||||
Integer offsetSeconds = null;
|
Integer offsetSeconds = null;
|
||||||
|
@ -84,12 +110,7 @@ public class ActiveTableSrv {
|
||||||
offsetSeconds = Integer.valueOf(0);
|
offsetSeconds = Integer.valueOf(0);
|
||||||
}
|
}
|
||||||
if (records != null && records.size() > 0) {
|
if (records != null && records.size() > 0) {
|
||||||
long threadId = Thread.currentThread().getId();
|
ActiveTable activeTable = threadLocalActiveTable.get();
|
||||||
ActiveTable activeTable = activeTableMap.get(threadId);
|
|
||||||
if (activeTable == null) {
|
|
||||||
activeTable = new ActiveTable();
|
|
||||||
activeTableMap.put(threadId, activeTable);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
activeTable.merge(ActiveTableRecord.transformFromWarnings(
|
||||||
records, ActiveTableMode.PRACTICE), offsetSeconds
|
records, ActiveTableMode.PRACTICE), offsetSeconds
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
# 06/11/13 #2083 randerso Log active table changes, save backups
|
# 06/11/13 #2083 randerso Log active table changes, save backups
|
||||||
# 03/06/14 #2883 randerso Pass siteId into mergeFromJava
|
# 03/06/14 #2883 randerso Pass siteId into mergeFromJava
|
||||||
# 03/25/14 #2884 randerso Added xxxid to VTECChange
|
# 03/25/14 #2884 randerso Added xxxid to VTECChange
|
||||||
|
# 06/17/13 #3296 randerso Moved active table backup and purging
|
||||||
|
# to a separate thread in java.
|
||||||
|
# Added performance logging
|
||||||
#
|
#
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
@ -40,6 +43,10 @@ from com.raytheon.uf.common.localization import PathManagerFactory
|
||||||
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as LocalizationType
|
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationType as LocalizationType
|
||||||
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationLevel as LocalizationLevel
|
from com.raytheon.uf.common.localization import LocalizationContext_LocalizationLevel as LocalizationLevel
|
||||||
|
|
||||||
|
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):
|
class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
|
|
||||||
def __init__(self, activeTableMode):
|
def __init__(self, activeTableMode):
|
||||||
|
@ -60,6 +67,8 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
changedFlag = False
|
changedFlag = False
|
||||||
|
|
||||||
#delete "obsolete" records from the old table.
|
#delete "obsolete" records from the old table.
|
||||||
|
timer = TimeUtil.getTimer()
|
||||||
|
timer.start()
|
||||||
vts = VTECTableSqueeze.VTECTableSqueeze(self._time+offsetSecs)
|
vts = VTECTableSqueeze.VTECTableSqueeze(self._time+offsetSecs)
|
||||||
activeTable, tossRecords = vts.squeeze(activeTable)
|
activeTable, tossRecords = vts.squeeze(activeTable)
|
||||||
for r in tossRecords:
|
for r in tossRecords:
|
||||||
|
@ -67,9 +76,13 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
del vts
|
del vts
|
||||||
if len(tossRecords):
|
if len(tossRecords):
|
||||||
changedFlag = True
|
changedFlag = True
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable squeeze", timer.getElapsedTime());
|
||||||
|
|
||||||
#expand out any 000 UGC codes, such as FLC000, to indicate all
|
#expand out any 000 UGC codes, such as FLC000, to indicate all
|
||||||
#zones.
|
#zones.
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
newRecExpanded = []
|
newRecExpanded = []
|
||||||
compare1 = ['phen', 'sig', 'officeid', 'etn', 'pil']
|
compare1 = ['phen', 'sig', 'officeid', 'etn', 'pil']
|
||||||
for newR in newRecords:
|
for newR in newRecords:
|
||||||
|
@ -85,11 +98,15 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
else:
|
else:
|
||||||
newRecExpanded.append(newR)
|
newRecExpanded.append(newR)
|
||||||
newRecords = newRecExpanded
|
newRecords = newRecExpanded
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable expand", timer.getElapsedTime());
|
||||||
|
|
||||||
# match new records with old records, with issue time is different
|
# match new records with old records, with issue time is different
|
||||||
# years and event times overlap. Want to reassign ongoing events
|
# years and event times overlap. Want to reassign ongoing events
|
||||||
# from last year's issueTime to be 12/31/2359z, rather than the
|
# from last year's issueTime to be 12/31/2359z, rather than the
|
||||||
# real issuetime (which is this year's).
|
# real issuetime (which is this year's).
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
compare = ['phen', 'sig', 'officeid', 'pil', 'etn']
|
compare = ['phen', 'sig', 'officeid', 'pil', 'etn']
|
||||||
for newR in newRecords:
|
for newR in newRecords:
|
||||||
cyear = time.gmtime(newR['issueTime'])[0] #current year issuance time
|
cyear = time.gmtime(newR['issueTime'])[0] #current year issuance time
|
||||||
|
@ -106,9 +123,13 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
"\nNewRec: ", self.printEntry(newR),
|
"\nNewRec: ", self.printEntry(newR),
|
||||||
"OldRec: ", self.printEntry(oldR))
|
"OldRec: ", self.printEntry(oldR))
|
||||||
newR['issueTime'] = lastYearIssueTime
|
newR['issueTime'] = lastYearIssueTime
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable match", timer.getElapsedTime());
|
||||||
|
|
||||||
|
|
||||||
# split records out by issuance year for processing
|
# split records out by issuance year for processing
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
newRecDict = {} #key is issuance year
|
newRecDict = {} #key is issuance year
|
||||||
oldRecDict = {}
|
oldRecDict = {}
|
||||||
years = []
|
years = []
|
||||||
|
@ -126,8 +147,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
oldRecDict[issueYear] = records
|
oldRecDict[issueYear] = records
|
||||||
if issueYear not in years:
|
if issueYear not in years:
|
||||||
years.append(issueYear)
|
years.append(issueYear)
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable split", timer.getElapsedTime());
|
||||||
|
|
||||||
# process each year
|
# process each year
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
compare = ['id', 'phen', 'sig', 'officeid', 'pil']
|
compare = ['id', 'phen', 'sig', 'officeid', 'pil']
|
||||||
|
|
||||||
for year in years:
|
for year in years:
|
||||||
|
@ -166,8 +191,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
oldR['state'] = "Replaced"
|
oldR['state'] = "Replaced"
|
||||||
changedFlag = True
|
changedFlag = True
|
||||||
updatedTable.append(oldR)
|
updatedTable.append(oldR)
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable process", timer.getElapsedTime());
|
||||||
|
|
||||||
#always add in the new records (except for ROU)
|
#always add in the new records (except for ROU)
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
compare = ['id', 'phen', 'sig', 'officeid', 'pil', 'etn']
|
compare = ['id', 'phen', 'sig', 'officeid', 'pil', 'etn']
|
||||||
for year in newRecDict.keys():
|
for year in newRecDict.keys():
|
||||||
newRecords = newRecDict[year]
|
newRecords = newRecDict[year]
|
||||||
|
@ -199,8 +228,12 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
rec = (newR['officeid'], newR['pil'], newR['phensig'], newR['xxxid'])
|
rec = (newR['officeid'], newR['pil'], newR['phensig'], newR['xxxid'])
|
||||||
if rec not in changes:
|
if rec not in changes:
|
||||||
changes.append(rec)
|
changes.append(rec)
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable add", timer.getElapsedTime());
|
||||||
|
|
||||||
#filter out any captured text and overviewText if not in the categories
|
#filter out any captured text and overviewText if not in the categories
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
cats = self._getTextCaptureCategories()
|
cats = self._getTextCaptureCategories()
|
||||||
if cats is not None:
|
if cats is not None:
|
||||||
for rec in updatedTable:
|
for rec in updatedTable:
|
||||||
|
@ -210,6 +243,8 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
if rec.has_key('overviewText'):
|
if rec.has_key('overviewText'):
|
||||||
del rec['overviewText']
|
del rec['overviewText']
|
||||||
|
|
||||||
|
timer.stop();
|
||||||
|
perfStat.logDuration("updateActiveTable filter", timer.getElapsedTime());
|
||||||
return updatedTable, tossRecords, changes, changedFlag
|
return updatedTable, tossRecords, changes, changedFlag
|
||||||
|
|
||||||
# time overlaps, if tr1 overlaps tr2 (adjacent is not an overlap)
|
# time overlaps, if tr1 overlaps tr2 (adjacent is not an overlap)
|
||||||
|
@ -250,35 +285,35 @@ class ActiveTable(VTECTableUtil.VTECTableUtil):
|
||||||
return outTable, purgedRecords, changes, changedFlag
|
return outTable, purgedRecords, changes, changedFlag
|
||||||
|
|
||||||
def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
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 = []
|
pyActive = []
|
||||||
szActive = activeTable.size()
|
szActive = activeTable.size()
|
||||||
for i in range(szActive):
|
for i in range(szActive):
|
||||||
pyActive.append(ActiveTableRecord.ActiveTableRecord(activeTable.get(i)))
|
pyActive.append(ActiveTableRecord.ActiveTableRecord(activeTable.get(i)))
|
||||||
|
|
||||||
decoderSites = VTECPartners.VTEC_DECODER_SITES
|
|
||||||
decoderSites.append(VTECPartners.get4ID(siteId))
|
|
||||||
decoderSites.append(VTECPartners.VTEC_SPC_SITE)
|
|
||||||
decoderSites.append(VTECPartners.VTEC_TPC_SITE)
|
|
||||||
|
|
||||||
backup = False
|
|
||||||
pyNew = []
|
pyNew = []
|
||||||
szNew = newRecords.size()
|
szNew = newRecords.size()
|
||||||
for i in range(szNew):
|
for i in range(szNew):
|
||||||
rec = ActiveTableRecord.ActiveTableRecord(newRecords.get(i))
|
rec = ActiveTableRecord.ActiveTableRecord(newRecords.get(i))
|
||||||
if rec['officeid'] in decoderSites:
|
|
||||||
backup = True
|
|
||||||
pyNew.append(rec)
|
pyNew.append(rec)
|
||||||
|
|
||||||
active = ActiveTable(mode)
|
active = ActiveTable(mode)
|
||||||
|
|
||||||
if backup:
|
logger.info("Updating " + mode + " Active Table: new records\n" +
|
||||||
oldActiveTable = active._convertTableToPurePython(pyActive, siteId)
|
active.printActiveTable(pyNew, combine=1))
|
||||||
active.saveOldActiveTable(oldActiveTable)
|
|
||||||
pTime = getattr(VTECPartners, "VTEC_BACKUP_TABLE_PURGE_TIME",168)
|
timer.stop()
|
||||||
active.purgeOldSavedTables(pTime)
|
perfStat.logDuration("mergeFromJava preprocess", timer.getElapsedTime());
|
||||||
|
|
||||||
updatedTable, purgeRecords, changes, changedFlag = active.activeTableMerge(pyActive, pyNew, offsetSecs)
|
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" +
|
logger.info("Updated " + mode + " Active Table: purged\n" +
|
||||||
active.printActiveTable(purgeRecords, combine=1))
|
active.printActiveTable(purgeRecords, combine=1))
|
||||||
|
|
||||||
|
@ -298,15 +333,15 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
||||||
logger.info("Updated " + mode + " Active Table: decoded\n" +
|
logger.info("Updated " + mode + " Active Table: decoded\n" +
|
||||||
active.printActiveTable(decoded, combine=1))
|
active.printActiveTable(decoded, combine=1))
|
||||||
|
|
||||||
updatedList = ArrayList()
|
updatedList = ArrayList(len(updatedTable))
|
||||||
for x in updatedTable:
|
for x in updatedTable:
|
||||||
updatedList.add(x.javaRecord())
|
updatedList.add(x.javaRecord())
|
||||||
|
|
||||||
purgedList = ArrayList()
|
purgedList = ArrayList(len(purgeRecords))
|
||||||
for x in purgeRecords:
|
for x in purgeRecords:
|
||||||
purgedList.add(x.javaRecord())
|
purgedList.add(x.javaRecord())
|
||||||
|
|
||||||
changeList = ArrayList()
|
changeList = ArrayList(len(changes))
|
||||||
if (changedFlag):
|
if (changedFlag):
|
||||||
from com.raytheon.uf.common.activetable import VTECChange
|
from com.raytheon.uf.common.activetable import VTECChange
|
||||||
for c in changes:
|
for c in changes:
|
||||||
|
@ -314,4 +349,6 @@ def mergeFromJava(siteId, activeTable, newRecords, logger, mode, offsetSecs=0):
|
||||||
|
|
||||||
from com.raytheon.uf.common.activetable import MergeResult
|
from com.raytheon.uf.common.activetable import MergeResult
|
||||||
result = MergeResult(updatedList, purgedList, changeList)
|
result = MergeResult(updatedList, purgedList, changeList)
|
||||||
|
timer.stop()
|
||||||
|
perfStat.logDuration("mergeFromJava postprocess", timer.getElapsedTime());
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -1,24 +1,38 @@
|
||||||
##
|
##
|
||||||
# This software was developed and / or modified by Raytheon Company,
|
# This software was developed and / or modified by Raytheon Company,
|
||||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
#
|
#
|
||||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
# This software product contains export-restricted data whose
|
# This software product contains export-restricted data whose
|
||||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
# to non-U.S. persons whether in the United States or abroad requires
|
# to non-U.S. persons whether in the United States or abroad requires
|
||||||
# an export license or other authorization.
|
# an export license or other authorization.
|
||||||
#
|
#
|
||||||
# Contractor Name: Raytheon Company
|
# Contractor Name: Raytheon Company
|
||||||
# Contractor Address: 6825 Pine Street, Suite 340
|
# Contractor Address: 6825 Pine Street, Suite 340
|
||||||
# Mail Stop B8
|
# Mail Stop B8
|
||||||
# Omaha, NE 68106
|
# Omaha, NE 68106
|
||||||
# 402.291.0100
|
# 402.291.0100
|
||||||
#
|
#
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# 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
|
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
|
# This class takes a VTEC active table and eliminates unnecessary
|
||||||
# records. Records purged consist of old SPC watches, old Tropical
|
# records. Records purged consist of old SPC watches, old Tropical
|
||||||
# events, last year's records, and extraneous records not needed for
|
# events, last year's records, and extraneous records not needed for
|
||||||
|
@ -27,7 +41,7 @@ import os, sys, time, copy, LogStream
|
||||||
class VTECTableSqueeze:
|
class VTECTableSqueeze:
|
||||||
|
|
||||||
#constructor
|
#constructor
|
||||||
def __init__(self, currentTime, debug=True):
|
def __init__(self, currentTime, debug=False):
|
||||||
self.__ctime = currentTime
|
self.__ctime = currentTime
|
||||||
self.__thisYear = time.gmtime(self.__ctime)[0]
|
self.__thisYear = time.gmtime(self.__ctime)[0]
|
||||||
self.__debug = debug
|
self.__debug = debug
|
||||||
|
@ -41,7 +55,11 @@ class VTECTableSqueeze:
|
||||||
LogStream.logDebug(self.__printActiveTable(table))
|
LogStream.logDebug(self.__printActiveTable(table))
|
||||||
|
|
||||||
# modify old UFN events (in case fcstrs didn't CAN them)
|
# modify old UFN events (in case fcstrs didn't CAN them)
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
table, modTable = self.__modifyOldUFNEvents(table)
|
table, modTable = self.__modifyOldUFNEvents(table)
|
||||||
|
timer.stop()
|
||||||
|
perfStat.logDuration("updateActiveTable squeeze __modifyOldUFNEvents", timer.getElapsedTime());
|
||||||
if self.__debug:
|
if self.__debug:
|
||||||
LogStream.logDebug("************** MOD UFN TABLE *********************")
|
LogStream.logDebug("************** MOD UFN TABLE *********************")
|
||||||
for old, new in modTable:
|
for old, new in modTable:
|
||||||
|
@ -50,8 +68,12 @@ class VTECTableSqueeze:
|
||||||
LogStream.logDebug(" -----------")
|
LogStream.logDebug(" -----------")
|
||||||
|
|
||||||
# remove the national center and short fused events
|
# remove the national center and short fused events
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
shortWFO, shortNC, purgeT = \
|
shortWFO, shortNC, purgeT = \
|
||||||
self.__removeOldNationalAndShortFusedEvents(table)
|
self.__removeOldNationalAndShortFusedEvents(table)
|
||||||
|
timer.stop()
|
||||||
|
perfStat.logDuration("updateActiveTable squeeze __removeOldNationalAndShortFusedEvents", timer.getElapsedTime());
|
||||||
if self.__debug:
|
if self.__debug:
|
||||||
LogStream.logDebug("************** SHORT WFO TABLE *********************")
|
LogStream.logDebug("************** SHORT WFO TABLE *********************")
|
||||||
LogStream.logDebug(self.__printActiveTable(shortWFO))
|
LogStream.logDebug(self.__printActiveTable(shortWFO))
|
||||||
|
@ -61,10 +83,18 @@ class VTECTableSqueeze:
|
||||||
LogStream.logDebug(self.__printActiveTable(purgeT))
|
LogStream.logDebug(self.__printActiveTable(purgeT))
|
||||||
|
|
||||||
# separate out the shortWFO into dictionary structure
|
# separate out the shortWFO into dictionary structure
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
dict = self.__separateTable(shortWFO)
|
dict = self.__separateTable(shortWFO)
|
||||||
|
timer.stop()
|
||||||
|
perfStat.logDuration("updateActiveTable squeeze __separateTable", timer.getElapsedTime());
|
||||||
|
|
||||||
# purge old entries with LowerETNs that aren't in effect
|
# purge old entries with LowerETNs that aren't in effect
|
||||||
|
timer.reset()
|
||||||
|
timer.start()
|
||||||
shorterT, purgeT2 = self.__purgeOldEntriesWithLowerETNs(dict)
|
shorterT, purgeT2 = self.__purgeOldEntriesWithLowerETNs(dict)
|
||||||
|
timer.stop()
|
||||||
|
perfStat.logDuration("updateActiveTable squeeze __purgeOldEntriesWithLowerETNs", timer.getElapsedTime());
|
||||||
if self.__debug:
|
if self.__debug:
|
||||||
LogStream.logDebug("************** TRIMMED WFO TABLE ******************")
|
LogStream.logDebug("************** TRIMMED WFO TABLE ******************")
|
||||||
LogStream.logDebug(self.__printActiveTable(shorterT))
|
LogStream.logDebug(self.__printActiveTable(shorterT))
|
||||||
|
@ -72,12 +102,10 @@ class VTECTableSqueeze:
|
||||||
LogStream.logDebug(self.__printActiveTable(purgeT2))
|
LogStream.logDebug(self.__printActiveTable(purgeT2))
|
||||||
|
|
||||||
#add in any shortNC entries to final table
|
#add in any shortNC entries to final table
|
||||||
for r in shortNC:
|
shorterT.extend(shortNC)
|
||||||
shorterT.append(r)
|
|
||||||
|
|
||||||
#add in the purged entries from before
|
#add in the purged entries from before
|
||||||
for r in purgeT2:
|
purgeT.extend(purgeT2)
|
||||||
purgeT.append(r)
|
|
||||||
|
|
||||||
if self.__debug:
|
if self.__debug:
|
||||||
LogStream.logDebug("************** FINAL TABLE ********************")
|
LogStream.logDebug("************** FINAL TABLE ********************")
|
||||||
|
|
|
@ -17,7 +17,14 @@
|
||||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
# further licensing information.
|
# 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 copy
|
||||||
import cPickle
|
import cPickle
|
||||||
|
@ -384,3 +391,14 @@ class VTECTableUtil:
|
||||||
|
|
||||||
return JUtil.javaObjToPyVal(javaDictFormat)
|
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
|
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||||
* @generated
|
* @generated
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
* 07/29/13 2215 bkowal Regenerated for thrift 0.9.0
|
||||||
|
* 07/22/14 15649 lshi Rollback to thrift 0.8.0
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -43,14 +44,13 @@
|
||||||
*/
|
*/
|
||||||
#include "Notification_types.h"
|
#include "Notification_types.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::ascii_fingerprint = "ACE4F644F0FDD289DDC4EE5B83BC13C0";
|
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};
|
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 com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::read(::apache::thrift::protocol::TProtocol* iprot) {
|
||||||
|
|
||||||
uint32_t xfer = 0;
|
uint32_t xfer = 0;
|
||||||
std::string fname;
|
std::string fname;
|
||||||
::apache::thrift::protocol::TType ftype;
|
::apache::thrift::protocol::TType ftype;
|
||||||
|
@ -75,14 +75,14 @@ uint32_t com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::r
|
||||||
this->dataURIs.clear();
|
this->dataURIs.clear();
|
||||||
uint32_t _size0;
|
uint32_t _size0;
|
||||||
::apache::thrift::protocol::TType _etype3;
|
::apache::thrift::protocol::TType _etype3;
|
||||||
xfer += iprot->readListBegin(_etype3, _size0);
|
iprot->readListBegin(_etype3, _size0);
|
||||||
this->dataURIs.resize(_size0);
|
this->dataURIs.resize(_size0);
|
||||||
uint32_t _i4;
|
uint32_t _i4;
|
||||||
for (_i4 = 0; _i4 < _size0; ++_i4)
|
for (_i4 = 0; _i4 < _size0; ++_i4)
|
||||||
{
|
{
|
||||||
xfer += iprot->readString(this->dataURIs[_i4]);
|
xfer += iprot->readString(this->dataURIs[_i4]);
|
||||||
}
|
}
|
||||||
xfer += iprot->readListEnd();
|
iprot->readListEnd();
|
||||||
}
|
}
|
||||||
this->__isset.dataURIs = true;
|
this->__isset.dataURIs = true;
|
||||||
} else {
|
} 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 com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
||||||
uint32_t xfer = 0;
|
uint32_t xfer = 0;
|
||||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage");
|
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataplugin_message_DataURINotificationMessage");
|
||||||
|
|
||||||
xfer += oprot->writeFieldBegin("dataURIs", ::apache::thrift::protocol::T_LIST, 1);
|
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()));
|
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->writeListEnd();
|
||||||
}
|
}
|
||||||
xfer += oprot->writeFieldEnd();
|
xfer += oprot->writeFieldEnd();
|
||||||
|
|
||||||
xfer += oprot->writeFieldStop();
|
xfer += oprot->writeFieldStop();
|
||||||
xfer += oprot->writeStructEnd();
|
xfer += oprot->writeStructEnd();
|
||||||
return xfer;
|
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
|
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
* 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>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -34,13 +28,21 @@
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bkowal
|
* @author gzhou
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autogenerated by Thrift
|
||||||
|
*
|
||||||
|
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||||
|
*/
|
||||||
#include "PointDataServer_constants.h"
|
#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
|
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
* 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>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -34,240 +28,222 @@
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bkowal
|
* @author gzhou
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PointDataServer_types.h"
|
#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";
|
xfer += iprot->readStructBegin(fname);
|
||||||
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) {
|
using ::apache::thrift::protocol::TProtocolException;
|
||||||
|
|
||||||
uint32_t xfer = 0;
|
xfer += iprot->readFieldBegin(fname, ftype, fid);
|
||||||
std::string fname;
|
if (ftype == ::apache::thrift::protocol::T_STRING) {
|
||||||
::apache::thrift::protocol::TType ftype;
|
xfer += iprot->readString(operand);
|
||||||
int16_t fid;
|
this->__isset.operand = true;
|
||||||
|
} else
|
||||||
|
xfer += iprot->skip(ftype);
|
||||||
|
xfer += iprot->readFieldEnd();
|
||||||
|
|
||||||
xfer += iprot->readStructBegin(fname);
|
xfer += iprot->readStructEnd();
|
||||||
|
|
||||||
using ::apache::thrift::protocol::TProtocolException;
|
return xfer;
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::write(::apache::thrift::protocol::TProtocol* oprot) const {
|
uint32_t com_raytheon_uf_common_dataquery_requests_ConstraintType::write(
|
||||||
uint32_t xfer = 0;
|
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataquery_requests_ConstraintType");
|
uint32_t xfer = 0;
|
||||||
|
xfer
|
||||||
xfer += oprot->writeFieldBegin("operand", ::apache::thrift::protocol::T_STRING, 1);
|
+= oprot->writeStructBegin(
|
||||||
xfer += oprot->writeString(this->operand);
|
"com_raytheon_uf_common_dataquery_requests_RequestConstraint$ConstraintType");
|
||||||
xfer += oprot->writeFieldEnd();
|
xfer += oprot->writeFieldBegin("__enumValue__",
|
||||||
|
::apache::thrift::protocol::T_STRING, 1);
|
||||||
xfer += oprot->writeFieldStop();
|
xfer += oprot->writeString(this->operand);
|
||||||
xfer += oprot->writeStructEnd();
|
xfer += oprot->writeFieldEnd();
|
||||||
return xfer;
|
xfer += oprot->writeStructEnd();
|
||||||
|
return xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(com_raytheon_uf_common_dataquery_requests_ConstraintType &a, com_raytheon_uf_common_dataquery_requests_ConstraintType &b) {
|
const char
|
||||||
using ::std::swap;
|
* com_raytheon_uf_common_dataquery_requests_RequestConstraint::ascii_fingerprint =
|
||||||
swap(a.operand, b.operand);
|
"BDAF55DAA660FA1ADBE30760752211A8";
|
||||||
swap(a.__isset, b.__isset);
|
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";
|
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::write(
|
||||||
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};
|
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||||
|
uint32_t xfer = 0;
|
||||||
uint32_t com_raytheon_uf_common_dataquery_requests_RequestConstraint::read(::apache::thrift::protocol::TProtocol* iprot) {
|
xfer += oprot->writeStructBegin(
|
||||||
|
"com_raytheon_uf_common_dataquery_requests_RequestConstraint");
|
||||||
uint32_t xfer = 0;
|
xfer += oprot->writeFieldBegin("constraintType",
|
||||||
std::string fname;
|
::apache::thrift::protocol::T_STRUCT, 1);
|
||||||
::apache::thrift::protocol::TType ftype;
|
xfer += this->constraintType.write(oprot);
|
||||||
int16_t fid;
|
xfer += oprot->writeFieldEnd();
|
||||||
|
xfer += oprot->writeFieldBegin("constraintValue",
|
||||||
xfer += iprot->readStructBegin(fname);
|
::apache::thrift::protocol::T_STRING, 2);
|
||||||
|
xfer += oprot->writeString(this->constraintValue);
|
||||||
using ::apache::thrift::protocol::TProtocolException;
|
xfer += oprot->writeFieldEnd();
|
||||||
|
xfer += oprot->writeFieldStop();
|
||||||
|
xfer += oprot->writeStructEnd();
|
||||||
while (true)
|
return xfer;
|
||||||
{
|
|
||||||
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 {
|
const char
|
||||||
uint32_t xfer = 0;
|
* com_raytheon_uf_common_pointdata_PointDataServerRequest::ascii_fingerprint =
|
||||||
xfer += oprot->writeStructBegin("com_raytheon_uf_common_dataquery_requests_RequestConstraint");
|
"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);
|
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::read(
|
||||||
xfer += this->constraintType.write(oprot);
|
::apache::thrift::protocol::TProtocol* iprot) {
|
||||||
xfer += oprot->writeFieldEnd();
|
|
||||||
|
|
||||||
xfer += oprot->writeFieldBegin("constraintValue", ::apache::thrift::protocol::T_STRING, 2);
|
uint32_t xfer = 0;
|
||||||
xfer += oprot->writeString(this->constraintValue);
|
std::string fname;
|
||||||
xfer += oprot->writeFieldEnd();
|
::apache::thrift::protocol::TType ftype;
|
||||||
|
int16_t fid;
|
||||||
|
|
||||||
xfer += oprot->writeFieldStop();
|
xfer += iprot->readStructBegin(fname);
|
||||||
xfer += oprot->writeStructEnd();
|
|
||||||
return xfer;
|
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) {
|
uint32_t com_raytheon_uf_common_pointdata_PointDataServerRequest::write(
|
||||||
using ::std::swap;
|
::apache::thrift::protocol::TProtocol* oprot) const {
|
||||||
swap(a.constraintType, b.constraintType);
|
uint32_t xfer = 0;
|
||||||
swap(a.constraintValue, b.constraintValue);
|
xfer += oprot->writeStructBegin(
|
||||||
swap(a.__isset, b.__isset);
|
"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
|
* COPYRIGHT (c), 2009, RAYTHEON COMPANY
|
||||||
* ALL RIGHTS RESERVED, An Unpublished Work
|
* 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>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -34,13 +28,21 @@
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* 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>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bkowal
|
* @author brockwoo
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autogenerated by Thrift
|
||||||
|
*
|
||||||
|
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
||||||
|
*/
|
||||||
#include "PointData_constants.h"
|
#include "PointData_constants.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue