Merge branch 'unidata_16.2.2' of github.com:Unidata/awips2 into unidata_16.2.2

This commit is contained in:
mjames-upc 2016-09-23 13:09:04 -06:00
commit 17d8af1f2a
76 changed files with 876 additions and 5326 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="subMenu" menuText="Precipitation"
<contribute xsi:type="subMenu" menuText="HPC Precip Products"
id="ncepHydro.hpc.precipitation">
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="Instantaneous Precip" id="instantaneousPrecip">
@ -154,7 +154,7 @@
</contribute>
<contribute xsi:type="subMenu" menuText="Temps &amp;&amp; Weather"
<contribute xsi:type="subMenu" menuText="HPC Temps/Weather Products"
id="ncepHydro.hpc.tempsAndWeather">
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="1-5 Day Max Temp Anomaly" id="fiveDayMaxTempAnomaly">

View file

@ -21,6 +21,8 @@
<menuContributionFile>
<include installTo="menu:ncepHydro?before=SPC"
fileName="menus/ncepHydro/baseNCEP.xml"/>
<include installTo="menu:ncepHydro?before=HPC"
fileName="menus/ncepHydro/hpc/baseHPC.xml"/>
<include installTo="menu:ncepHydro?before=TPC"
fileName="menus/ncepHydro/tpc/baseTPC.xml"/>
<include installTo="menu:ncepHydro?before=NCO"
@ -29,6 +31,6 @@
fileName="menus/ncepHydro/cpc/baseCPC.xml"/>
<include installTo="menu:ncepHydro?before=AWC"
fileName="menus/ncepHydro/awc/baseAWC.xml"/>
<include installTo="menu:ncepHydro?after=STQ"
<include installTo="menu:ncepHydro?before=STQ"
fileName="menus/ncepHydro/stq/baseSTQ.xml"/>
</menuContributionFile>

View file

@ -35,27 +35,27 @@
</visibleWhen>
<separator
name="SPC"
visible="false">
visible="true">
</separator>
<separator
name="TPC"
visible="false">
visible="true">
</separator>
<separator
name="NCO"
visible="false">
visible="true">
</separator>
<separator
name="HPC"
visible="false">
visible="true">
</separator>
<separator
name="OPC"
visible="false">
visible="true">
</separator>
<separator
name="CPC"
visible="false">
visible="true">
</separator>
<separator
name="AWC"
@ -65,25 +65,13 @@
name="HYDRO"
visible="true">
</separator>
<separator name="QPE" visible="false"/>
<separator name="QPF" visible="false"/>
<separator name="HydroMenuEnd" visible="false"/>
<separator name="QPE" visible="true"/>
<separator name="QPF" visible="true"/>
<separator
name="xyx"
name="STQ"
visible="true">
</separator>
<command id="STQ"
commandId="com.raytheon.viz.ui.actions.titleAction"
label="------ STQ ------">
</command>
<separator
name="xxx"
visible="true">
</separator>
<command
commandId="com.raytheon.viz.ui.actions.titleAction"
label="------ Local Analyses/Statistical Guidance ------">
</command>
<separator name="HydroMenuEnd" visible="true"/>
</menu>
</menuContribution>
</extension>

View file

@ -31,12 +31,6 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.viz.radarapps.fsi"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.raytheon.uf.viz.radarapps.requests"
download-size="0"

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.radarapps.fsi</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>

View file

@ -1,20 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: FSI Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.radarapps.fsi;singleton:=true
Bundle-Version: 1.14.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.radarapps.fsi.Activator
Bundle-Vendor: Raytheon
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
com.raytheon.uf.viz.core;bundle-version="1.11.17",
com.raytheon.viz.ui;bundle-version="1.11.17",
org.geotools;bundle-version="2.5.8",
com.raytheon.viz.core;bundle-version="1.11.17",
com.raytheon.uf.common.message;bundle-version="1.11.17",
com.raytheon.viz.radar;bundle-version="1.11.17",
com.raytheon.viz.awipstools;bundle-version="1.11.17",
com.raytheon.uf.common.dataplugin.radar;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: com.raytheon.uf.viz.radarapps.fsi.jar

View file

@ -1,6 +0,0 @@
output.com.raytheon.uf.viz.radarapps.fsi.jar = bin/
bin.includes = META-INF/,\
plugin.xml,\
localization/,\
com.raytheon.uf.viz.radarapps.fsi.jar
source.com.raytheon.uf.viz.radarapps.fsi.jar = src/

View file

@ -1,84 +0,0 @@
#!/bin/sh
##
# 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.
##
# startWG.sh - start script for WDSSII wg process (FSI mode)
#
# Based on AWIPS 1 startWG.sh by Greg Stumpf
#
# This version combines the linear buffer operations and launching of wg
# into a single script.
while test "$#" -gt 0; do
case "$1" in
-l) lb=$2 ; shift ;;
-m)
msg=$2;
msg_set=1;
shift
;;
-r) log=$2 ; shift ;;
-h)
echo "usage: startWG.sh [-l <linear buffer>] [-m <control message>] [-r <log>]"
exit 0
;;
*)
echo "error: invalid option $1"
exit 1
;;
esac
shift
done
# Set FSI environment if needed
if test -z "$FXA_HOME"; then export FXA_HOME=/awips/fxa ; fi
if test -z "$WDSS2"; then export WDSS2=${FXA_HOME}/fsi ; fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${WDSS2}/lib
if test -z "$W2_CONFIG_LOCATION"; then export W2_CONFIG_LOCATION=${WDSS2}/w2config ; fi
if test -z "$W2_EXTENSION_LIBS"; then export W2_EXTENSION_LIBS=w2nexrad ; fi
if test -z "$RMTPORT"; then export RMTPORT=50000 ; fi
export PATH=${WDSS2}:${WDSS2}/bin:${PATH}
if test -z "$lb"; then
lb=$HOME/caveData/.metadata/.plugins/com.raytheon.uf.viz.radarapps.fsi/FSIcontrol.lb
echo "Linear buffer not specified with --lb=<path>. Using $lb" >&2
fi
if test ! -f "$lb"; then
$WDSS2/bin/lb_create -n 500 "$lb" || exit 1
fi
if test -n "$msg_set"; then
echo "$msg" | $WDSS2/bin/lb_cat -w "$lb" || exit 1
fi
umask g+rwx
match=`ps -ef | grep $WDSS2/bin/wg | grep -v grep | grep -o wg`
if [ ! ${match} ]
then
# wg is not running, starting wg
if test -n "$log"; then
$WDSS2/bin/wg -x $W2_CONFIG_LOCATION/misc/fsi-n.xul -l="file:///$lb?protocol=xmllb" --control="file:///$lb?protocol=xmllb" -p=1.0 >"$log" 2>&1 </dev/null &
else
$WDSS2/bin/wg -x $W2_CONFIG_LOCATION/misc/fsi-n.xul -l="file:///$lb?protocol=xmllb" --control="file:///$lb?protocol=xmllb" -p=1.0 &
fi
fi
#wg wg is running, not starting wg
exit 0

View file

@ -1,25 +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.
-->
<menuContributionFile>
<include installTo="menu:tools?after=tools.Fs"
fileName="menus/tools/fsi-tools-menu.xml">
</include>
</menuContributionFile>

View file

@ -1,27 +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.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="command"
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI"
menuText="4-D Storm Investigator (FSI)" />
</menuTemplate>

View file

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.ui.commands">
<command
id="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI"
name="4-D Storm Investigator (FSI)">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.raytheon.uf.viz.radarapps.fsi.FSILauncherCommandHandler"
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI">
</handler>
</extension>
<extension
point="com.raytheon.uf.viz.core.resource">
<resource
class="com.raytheon.uf.viz.radarapps.fsi.FSILauncherLayer"
name="FSILauncherResource"
renderingOrderId="ANNOTATION">
</resource>
</extension>
</plugin>

View file

@ -1,69 +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.uf.viz.radarapps.fsi;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.raytheon.uf.viz.radarapps.fsi";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}

View file

@ -1,74 +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.uf.viz.radarapps.fsi;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.ui.EditorUtil;
public class FSILauncherCommandHandler extends AbstractHandler {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(FSILauncherCommandHandler.class);
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
if (container != null) {
FSILauncherLayer layer = findLayer(container);
if (layer == null) {
IDescriptor desc = container.getActiveDisplayPane()
.getDescriptor();
FSILauncherResourceData rd = new FSILauncherResourceData();
try {
LoadProperties loadProps = new LoadProperties();
layer = rd.construct(loadProps, desc);
desc.getResourceList().add(layer);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
e.getMessage(), e);
return null;
}
}
}
return null;
}
private FSILauncherLayer findLayer(IDisplayPaneContainer container) {
List<FSILauncherLayer> layers = container.getActiveDisplayPane()
.getDescriptor().getResourceList()
.getResourcesByTypeAsType(FSILauncherLayer.class);
for (FSILauncherLayer layer : layers) {
return layer;
}
return null;
}
}

View file

@ -1,662 +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.uf.viz.radarapps.fsi;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.common.dataplugin.HDF5Util;
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
import com.raytheon.uf.common.dataplugin.radar.util.RadarDataRetriever;
import com.raytheon.uf.common.dataplugin.radar.util.TerminalRadarUtils;
import com.raytheon.uf.common.dataquery.db.OrderField.ResultOrder;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.message.Message;
import com.raytheon.uf.common.message.response.AbstractResponseMessage;
import com.raytheon.uf.common.message.response.ResponseMessageError;
import com.raytheon.uf.common.message.response.ResponseMessageGeneric;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.catalog.DbQuery;
import com.raytheon.uf.viz.core.comm.Connector;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.exception.VizServerSideException;
import com.raytheon.uf.viz.core.map.MapDescriptor;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.viz.awipstools.ToolsDataManager;
import com.raytheon.viz.awipstools.common.StormTrackData;
import com.raytheon.viz.radar.rsc.image.RadarSRMResource.SRMSource;
import com.raytheon.viz.radar.ui.RadarDisplayControls;
import com.raytheon.viz.radar.ui.RadarDisplayManager;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.IContextMenuContributor;
import com.raytheon.viz.ui.input.EditableManager;
import com.raytheon.viz.ui.input.InputAdapter;
import com.vividsolutions.jts.geom.Coordinate;
public class FSILauncherLayer extends
AbstractVizResource<FSILauncherResourceData, MapDescriptor> implements
IContextMenuContributor {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(FSILauncherLayer.class);
private MouseHandler mouseHandler;
private final MenuManager quickMenuManager;
private final MenuManager fullMenuManager;
private final Shell shell;
public FSILauncherLayer(FSILauncherResourceData fsiLauncherResourceData,
LoadProperties loadProperties) {
super(fsiLauncherResourceData, loadProperties);
IMenuListener menuListener = new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
addLauncherActions(manager);
}
};
shell = VizWorkbenchManager.getInstance().getCurrentWindow().getShell();
quickMenuManager = new MenuManager("Start FSI");
quickMenuManager.setRemoveAllWhenShown(true);
quickMenuManager.addMenuListener(menuListener);
quickMenuManager.createContextMenu(shell);
fullMenuManager = new MenuManager("Start FSI");
fullMenuManager.setRemoveAllWhenShown(true);
fullMenuManager.addMenuListener(menuListener);
getRadarList();
}
@Override
public String getName() {
return "FSI, when editable, right-click over storm";
}
@Override
protected void disposeInternal() {
getResourceContainer().unregisterMouseHandler(mouseHandler);
quickMenuManager.dispose();
fullMenuManager.dispose();
}
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
mouseHandler = new MouseHandler();
getResourceContainer().registerMouseHandler(mouseHandler);
EditableManager.makeEditable(this, true);
}
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
// nothing
}
@Override
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
if (isEditable()) {
menuManager.add(fullMenuManager);
}
}
public boolean isEditable() {
return getCapability(EditableCapability.class).isEditable();
}
private void addLauncherActions(IMenuManager manager) {
if (manager == quickMenuManager) {
Action a = new Action("Start FSI") {
};
a.setEnabled(false);
manager.add(a);
manager.add(new Separator());
}
for (String radarName : getRadarList()) {
manager.add(new LaunchFSIAction(radarName));
}
}
private String readScript(String name) {
InputStream ins = FSILauncherLayer.class.getResourceAsStream(name);
if (ins != null) {
Scanner s = new Scanner(ins);
StringBuilder sb = new StringBuilder();
while (s.hasNextLine()) {
sb.append(s.nextLine());
sb.append('\n');
}
s.close();
return sb.toString();
}
return null;
}
private List<String> getRadarList() {
ArrayList<String> result = new ArrayList<String>();
try {
String script = readScript("getFsiRadars.py");
if (script != null) {
Message message = Connector.getInstance().connectMessage(
script, null, 60000);
AbstractResponseMessage[] absresponses = message.getBody()
.getResponses();
AbstractResponseMessage response = absresponses[0];
if (response instanceof ResponseMessageError) {
ResponseMessageError rme = (ResponseMessageError) response;
VizServerSideException innerException = new VizServerSideException(
rme.toString());
throw new VizServerSideException(rme.getErrorMsg(),
innerException);
} else {
try {
for (Object o : (ArrayList<?>) ((ResponseMessageGeneric) response)
.getContents()) {
result.add((String) o);
}
} catch (RuntimeException e) {
throw new VizException("Unexpected server response", e);
}
}
} else {
throw new VizException("Could not load getFsiRadars.py");
}
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Could not retrieve FSI radar list", e);
}
return result;
}
private Coordinate geoClickedPoint;
private class MouseHandler extends InputAdapter {
private static final int MOUSE_BUTTON_TO_USE = 3;
private boolean clicked = false;
@Override
public boolean handleMouseDown(int x, int y, int mouseButton) {
geoClickedPoint = getResourceContainer().translateClick(x, y);
if (isEditable()) {
// panelClickPoint = new Point(x, y);
if (mouseButton == MOUSE_BUTTON_TO_USE) {
clicked = true;
}
}
return false;
}
@Override
public boolean handleMouseUp(int x, int y, int mouseButton) {
if (clicked && (mouseButton == MOUSE_BUTTON_TO_USE)) {
clicked = false;
/*
* Cannot relate x, y to anything on the screen, so get the
* current pointer location.
*/
Point cursorLoc = shell.getDisplay().getCursorLocation();
Menu menu = quickMenuManager.getMenu();
menu.setLocation(cursorLoc.x, cursorLoc.y);
menu.setVisible(true);
}
return false;
}
}
private static class FSIEnvironment {
public String lbOutputDir;
public String rssdHost;
}
@SuppressWarnings("unchecked")
private HashMap<String, String> getHashMapFromResponse(
AbstractResponseMessage response) {
return (HashMap<String, String>) ((ResponseMessageGeneric) response)
.getContents();
}
private FSIEnvironment getFSIEnvironment() {
FSIEnvironment result = null;
try {
String script = readScript("getFsiEnviron.py");
if (script != null) {
Message message = Connector.getInstance().connectMessage(
script, null, 60000);
AbstractResponseMessage[] absresponses = message.getBody()
.getResponses();
AbstractResponseMessage response = absresponses[0];
if (response instanceof ResponseMessageError) {
ResponseMessageError rme = (ResponseMessageError) response;
VizServerSideException innerException = new VizServerSideException(
rme.toString());
throw new VizServerSideException(rme.getErrorMsg(),
innerException);
} else {
try {
HashMap<String, String> hm = getHashMapFromResponse(response);
result = new FSIEnvironment();
result.lbOutputDir = hm.get("lbOutputDir");
result.rssdHost = hm.get("rssdHost");
} catch (RuntimeException e) {
throw new VizException("Unexpected server response", e);
}
}
} else {
throw new VizException("Could not retrieve FSI environment");
}
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Could not retrieve FSI radar list", e);
}
return result;
}
public class LaunchFSIAction extends Action {
private final String radarName;
private class StormVector {
public boolean useSTI = true;
public double speed = 25;
public double direction = 240;
}
public LaunchFSIAction(String radarName) {
super(radarName);
this.radarName = radarName;
}
/**
*
* @return storm vector {speed, direction} or null (use STI)
*/
private StormVector getStormVector() {
StormVector result = new StormVector();
final String fallbackMessage = " Using a default vector of 240 degrees, 25 kts.";
String warning = null;
RadarDisplayManager rdm = RadarDisplayManager.getInstance();
RadarDisplayControls rdc = rdm.getCurrentSettings();
SRMSource srmSource = rdc.getSrmSource();
if (srmSource == SRMSource.STI) {
result.useSTI = true;
} else if (srmSource == SRMSource.CUSTOM) {
result.useSTI = false;
result.speed = rdc.getSrmSpeed();
result.direction = rdc.getSrmDir();
} else if (srmSource == SRMSource.WARNGEN) {
result.useSTI = false;
StormTrackData stormTrackData = ToolsDataManager.getInstance()
.getStormTrackData();
if (stormTrackData != null) {
// stormTrackData.getMotionSpeed() is in kts which is what
// FSI expects
result.speed = stormTrackData.getMotionSpeed();
result.direction = stormTrackData.getMotionDirection();
} else {
warning = "Storm vector not properly set.";
}
} else {
warning = "Unknown storm vector type.";
}
if (warning != null) {
// Maybe this should go to alert viz?
MessageDialog dlg = new MessageDialog(shell,
"FSI Storm Vector", null, warning + fallbackMessage,
MessageDialog.WARNING, new String[] { "OK" }, 0);
dlg.open();
}
return result;
}
private double getRadarLowestElevation(String radarName) {
/*
* In AWIPS 1, this comes from $FXA_DATA/radar/kxxx/radarElevs.txt
* which is generated by RadarServer and/or RadarMsgHandler when
* GSMs are received.
*
* We just read the GSM. This is a waste of time for WSR-88Ds
* because the result is always 0.5.
*/
/*
* Not necessarily a dedicated radar so use EDEX instead of
* RadarServer.
*/
DbQuery query = new DbQuery("radar");
query.addConstraint("icao", radarName);
query.addConstraint("productCode", 2);
query.setOrderAscending(ResultOrder.DESC);
query.addOrderBy("dataTime");
query.setMaxResults(1);
try {
RadarRecord radarRecord = null;
try {
List<Object[]> obs = query.performQuery();
if ((obs != null) && !obs.isEmpty()
&& (obs.get(0).length > 0)) {
radarRecord = (RadarRecord) obs.get(0)[0];
} else {
// default to 0.5 for non-terminal radars, test if
// terminal
double elevation = 0.5;
if (TerminalRadarUtils.isTerminalRadar(radarName)) {
elevation = TerminalRadarUtils
.parseTerminalRadarFile().get(radarName)
.get(0);
}
return elevation;
}
} catch (RuntimeException e) {
throw new VizException("Unexpected response format", e);
}
File loc = HDF5Util.findHDF5Location(radarRecord);
IDataStore dataStore = DataStoreFactory.getDataStore(loc);
try {
RadarDataRetriever.populateRadarRecord(dataStore,
radarRecord);
// TODO: They're stored as doubles but still in tenths of a
// degree?
return radarRecord.getGsmMessage().getElevation()[0] / 10.0;
} catch (Exception e) {
throw new VizException(
"Could not retrieve latest GSM for radar", e);
}
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Could not retrieve latest GSM for radar " + radarName,
e);
}
/*
* TODO: Use ElevationInfo as a fallback? May not give the correct
* result from TDWRs.
*/
// TODO: What happens if the wrong number is returned?
// 0.5 is always correct for WSR-88Ds
return 0.5;
}
private String createControlMessage() {
FSIEnvironment env = getFSIEnvironment();
if (env == null) {
return null;
}
// According to FSI_GUI, this must have the format ##.##
String subTypeStr = String.format("%04.2f",
getRadarLowestElevation(radarName));
String latStr = "0.0";
String lonStr = "0.0";
if (geoClickedPoint != null) {
lonStr = Double.toString(geoClickedPoint.x);
latStr = Double.toString(geoClickedPoint.y);
}
StormVector stormVector = getStormVector();
String stiStr = stormVector.useSTI ? "STI" : "no STI";
String msg = "<control>\n"
+ "<command name='remove-all-sources' />\n"
+ "<command name='set-source' target='fsi' >\n"
+ "<string name='radar' value='"
+ radarName
+ "' />\n"
+
// Assumes env.lbOutputDir starts with a '/'
"<url name='source' value='orpg://"
+ env.rssdHost
+ ""
+ env.lbOutputDir
+ "/FSIradarLB_"
+ radarName
+ ".lb?protocol=xmllb' />\n"
+ "<timeinterval name='history' value='120' units='minutes' />\n"
+ "</command>\n"
+ "<command name='show-product' target='fsi' >\n"
+ "<string name='source' value='"
+ radarName
+ "'/>\n"
+ "<string name='product' value='Reflectivity'/>\n"
+ "<string name='subtype' value='"
+ subTypeStr
+ "'/>\n"
+ "<string name='jump' value='latestLowestSubtype'/>\n"
+ "</command>\n"
+ "<command name='show-vslice' target='fsi' >\n"
+ "<string name='source' value='"
+ radarName
+ "'/>\n"
+ "<string name='product' value='Reflectivity'/>\n"
+ "<angle name='latitude' value='"
+ latStr
+ "' units='degrees' />\n"
+ "<angle name='longitude' value='"
+ lonStr
+ "' units='degrees' />\n"
+ "<length name='altitude' value='2500' units='feet' />\n"
+ "</command>\n"
+ "<command name='set-storm-vector' target='fsi' >\n"
+ "<string name='source' value='"
+ radarName
+ "'/>\n"
+ "<string name='product' value='Reflectivity'/>\n"
+ "<angle name='direction' value='"
+ stormVector.direction
+ "' units='degrees' />\n"
+ "<speed name='speed' value='"
+ stormVector.speed
+ "' units='knots' />\n"
+ "<string name='STIProductName' value='"
+ stiStr
+ "' />\n"
+ "</command>\n"
+ "<command name='fsi-select-product' target='fsi'>\n"
+ "<string name='source' value='"
+ radarName
+ "'/>\n"
+ "<string name='product' value='Reflectivity'/>\n"
+ "</command>\n"
+ "<command name='fsi-move-camera' target='fsi' >\n"
+ "<angle name='latitude' value='"
+ latStr
+ "' units='degrees' />\n"
+ "<angle name='longitude' value='"
+ lonStr
+ "' units='degrees' />\n"
+ "<length name='altitude' value='50' units='meters' />\n"
+ "<length name='cappi-altitude' value='2000' units='meters' />\n"
+ "<length name='vslice-altitude' value='20000' units='meters' />\n"
+ "<angle name='3d-panel-tilt' value='45' units='degrees' />\n"
+ "<angle name='3d-panel-rotate' value='0' units='degrees' />\n"
+ "</command>\n" + "</control>";
return msg;
}
private static final String FSI_START_SCRIPT_NAME = "startWG.sh";
@Override
public void run() {
String controlMessage = createControlMessage();
if (controlMessage == null) {
return;
}
File f = PathManagerFactory.getPathManager().getStaticFile(
"fsi" + File.separator + FSI_START_SCRIPT_NAME);
if ((f == null) || !f.exists()) {
statusHandler.handle(Priority.PROBLEM,
"Could not find the FSI start script.");
return;
}
File controlLBFile = null;
File logFile = null;
IPath path = Activator.getDefault().getStateLocation();
if (path != null) {
File dir = path.toFile();
if (dir != null) {
controlLBFile = new File(dir, "FSIcontrol.lb");
logFile = new File(dir, "FSI.log");
}
}
// TODO: or temp file?
if (controlLBFile == null) {
statusHandler.handle(Priority.PROBLEM,
"Could not find location for FSI control file.");
return;
}
String[] cmd = { f.getAbsolutePath(), "-l",
controlLBFile.getAbsolutePath(), "-m", controlMessage,
"-r", logFile.getAbsolutePath() };
/*
* The startWG.sh is not being installed with execute permissions. A
* user may not have necessary permissions to change this so run the
* script with the system shell.
*/
if (!f.canExecute()) {
String[] cmd2 = new String[cmd.length + 1];
System.arraycopy(cmd, 0, cmd2, 1, cmd.length);
cmd2[0] = "sh";
cmd = cmd2;
}
final ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
// Gathers stderr and exit code and report. AWIPS 1 does *not*
// do this.
Thread t = new Thread(new Runnable() {
@Override
public void run() {
Process p = null;
try {
p = pb.start();
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
StringBuilder sb = new StringBuilder();
try {
final int MAX_LINES = 3;
int nLines = 0;
while (true) {
String s = br.readLine();
if (s == null) {
break;
}
sb.append(s);
sb.append('\n');
if (++nLines >= MAX_LINES) {
break;
}
}
} catch (IOException e) {
e.printStackTrace(System.err);
}
try {
p.getInputStream().close();
} catch (IOException e) {
// nothing
}
try {
int result = p.waitFor();
if (result != 0) {
// TODO: report error. Does this need an
// async exec?
// Is this thread-safe?
statusHandler
.handle(Priority.PROBLEM,
"FSI failed to start: "
+ sb.toString());
return;
}
} catch (InterruptedException e) {
// nothing
}
} catch (IOException e) {
statusHandler.handle(
Priority.PROBLEM,
"Could not run FSI start script: "
+ e.getMessage(), e);
} finally {
if (p != null) {
p.destroy();
}
}
}
});
t.setDaemon(true);
t.start();
}
}
}

View file

@ -1,57 +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.uf.viz.radarapps.fsi;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.MapDescriptor;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
@XmlAccessorType(XmlAccessType.NONE)
public class FSILauncherResourceData extends AbstractResourceData {
public FSILauncherResourceData() {
}
@Override
public FSILauncherLayer construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
FSILauncherLayer layer = new FSILauncherLayer(this, loadProperties);
layer.setDescriptor((MapDescriptor) descriptor);
return layer;
}
@Override
public boolean equals(Object obj) {
// All instances are the same
return obj instanceof FSILauncherResourceData;
}
@Override
public void update(Object updateData) {
// nothing
}
}

View file

@ -1,63 +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.
##
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/29/14 DR 2914 G. Armendariz Remove call to PropertiesFactory
#
import os
from com.raytheon.uf.common.message.response import ResponseMessageGeneric
from java.util import HashMap
fxa_data = os.environ.get("FXA_DATA","/data/fxa")
result = HashMap()
try:
f = open(os.path.join(fxa_data, "tstorm", "fsi-info"), "r")
try:
s = f.read()
finally:
f.close()
except:
d = dict()
else:
d = dict( [ [x[0].strip(), x[1].strip()] for x in
[ l.split(None, 1) for l in s.split('\n') ]
if len(x) == 2 ] )
# No exception handle for these because the values are required
if not d.has_key('rssdHost'):
# FSIprocessorEDEX and rssd most likely run on the same host as EDEX
import socket
d['rssdHost'] = socket.gethostname()
if not d.has_key('lbOutputDir'):
from java.lang import System
arch_dir = System.getProperty("data.archive.root")
d['lbOutputDir'] = os.path.join(arch_dir, "radar", "fsi")
for k, v in d.items():
result.put(k, v)
return ResponseMessageGeneric(result)

View file

@ -1,60 +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.
##
import os
from com.raytheon.uf.common.message.response import ResponseMessageGeneric
from java.util import ArrayList
def parseFsiRadarListLine(line):
try:
line = line.strip()
if line[0] != '/':
values = line.split()
if int(values[2]) == 1:
return values[0]
except:
pass
return False
def makeResponse(resultList):
al = ArrayList()
for value in resultList:
al.add(value)
return ResponseMessageGeneric(al)
def makeList(arrayList):
return [arrayList.get(i) for i in range(0, arrayList.size())]
# Try fsiRadarList.txt first
try:
f = open(os.path.join(os.environ['FXA_DATA'], 'tstorm', 'fsiRadarList.txt'), 'r')
try:
result = [x for x in [parseFsiRadarListLine(l) for l in f]
if x]
return makeResponse(result)
finally:
f.close()
except:
pass
# Fallback: Use radars on menu
from com.raytheon.edex.util.radar import RadarsInUseUtil
result = makeList(RadarsInUseUtil.getSite(RadarsInUseUtil.LOCAL_CONSTANT))
return makeResponse(result)

View file

@ -41,10 +41,6 @@
-->
<contribute xsi:type="command" commandId="com.raytheon.viz.awipstools.estimatedactualvelocity" menuText="Estimated Actual Velocity"
id="${icao}EstimatedActualVelocity" />
<contribute xsi:type="command"
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI" menuText="4-D Storm Investigator (FSI)"
id="${icao}4DStormInvestigatorFSI" />
<!--
<contribute xsi:type="command"
commandId="com.raytheon.viz.radar.ui.RadarDisplayControls" menuText="Radar Display Controls..."
@ -52,4 +48,4 @@
-->
<contribute xsi:type="command" commandId="com.raytheon.viz.awipstools.vrshear" menuText="VR - Shear"
id="${icao}VRShear" />
</menuTemplate>
</menuTemplate>

View file

@ -27,9 +27,6 @@
<contribute xsi:type="command"
commandId="com.raytheon.viz.awipstools.estimatedactualvelocity"
menuText="Estimated Actual Velocity" id="${icao}EstimatedActualVelocity" />
<contribute xsi:type="command"
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI" menuText="4-D Storm Investigator (FSI)"
id="${icao}4DStormInvestigatorFSI" />
<contribute xsi:type="command"
commandId="com.raytheon.uf.viz.radarapps.otr.oneTimeRequest"
menuText="One Time Request..." id="${icao}OneTimeRequest" />
@ -47,4 +44,4 @@
id="${icao}RPSListEditor" />
<contribute xsi:type="command" commandId="com.raytheon.viz.awipstools.vrshear"
menuText="VR - Shear" id="${icao}VRShear" />
</menuTemplate>
</menuTemplate>

View file

@ -19,7 +19,27 @@
further_licensing_information.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="titleItem" titleText="------ Best Res Z+SRM8 combo ------"
<contribute xsi:type="titleItem" titleText="------ Two-Panel Display ------"
id="BestResZSRM8" />
<contribute xsi:type="bundleItem"
file="bundles/site/Radar_kabr.xml" menuText="Refl. and Velocity"
id="${icao}N0QN0U">
<substitute key="product1" value="94" />
<substitute key="product2" value="99" />
</contribute>
<contribute xsi:type="bundleItem"
file="bundles/site/Radar_kabr.xml" menuText="DVL and EET"
id="${icao}DVL">
<substitute key="product1" value="134" />
<substitute key="product2" value="135" />
</contribute>
<contribute xsi:type="bundleItem"
file="bundles/site/Radar_kabr.xml" menuText="HHC and DAA"
id="${icao}HHC">
<substitute key="product1" value="177" />
<substitute key="product2" value="171" />
</contribute>
<contribute xsi:type="titleItem" titleText="------ Refl. and Velocity ------"
id="BestResZSRM8" />
<contribute xsi:type="bundleItem"
file="bundles/DefaultRadarBlendedBestRes.xml" menuText="0.5 Z+SRM8"

View file

@ -26,9 +26,6 @@
<contribute xsi:type="command"
commandId="com.raytheon.viz.awipstools.estimatedactualvelocity"
menuText="Estimated Actual Velocity" id="${icao}EstimatedActualVelocity" />
<contribute xsi:type="command"
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI" menuText="4-D Storm Investigator (FSI)"
id="${icao}4DStormInvestigatorFSI" />
<contribute xsi:type="command"
commandId="com.raytheon.uf.viz.radarapps.otr.oneTimeRequest"
menuText="One Time Request..." id="${icao}OneTimeRequest" />
@ -47,4 +44,4 @@
<contribute xsi:type="command" commandId="com.raytheon.viz.awipstools.vrshear"
menuText="VR - Shear" id="${icao}VRShear" />
</contribute>
</menuTemplate>
</menuTemplate>

View file

@ -71,10 +71,6 @@
id="com.raytheon.uf.viz.radarapps.rps.rpsListEditor"
name="RPS List Editor">
</command>
<command
id="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI"
name="4-D Storm Investigator (FSI)">
</command>
<command
id="com.raytheon.uf.viz.radarapps.config.configurator"
name="RadarServer Configurator">

View file

@ -0,0 +1,96 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/gridded data">
<persisted>
<colorMapMin>0.0</colorMapMin>
<colorMapMax>4600.011</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="1.0" interpolationState="true" alpha="1.0"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="IMAGE_WORLD">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="CLG"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintType="EQUALS" constraintValue="${modelName}"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="GH"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="gray90"/>
<capability xsi:type="densityCapability" density="0.1"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="CLG"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="GH"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintType="EQUALS" constraintValue="${modelName}"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,98 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="1.0" interpolationState="true" alpha="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/gridded data">
<persisted>
<colorMapMin>0.0</colorMapMin>
<colorMapMax>10.0</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
</capabilities>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="CONVP2hr"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="CONVP2hr"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,98 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="1.0" interpolationState="true" alpha="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/truncated warm to cold">
<persisted>
<colorMapMin>0.0</colorMapMin>
<colorMapMax>100.0</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
</capabilities>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="PROCON2hr"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="PROCON2hr"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,96 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/lowrange enhanced">
<persisted>
<colorMapMin>258.15</colorMapMin>
<colorMapMax>313.15</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="0.8" interpolationState="true" alpha="1.0"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="IMAGE_WORLD">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="2.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="FHAG"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="DpTerranl"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintType="EQUALS" constraintValue="${modelName}"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="densityCapability" density="0.5"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="black"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="2.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="FHAG"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintType="EQUALS" constraintValue="${modelName}"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="DpTerranl"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,98 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="1.0" interpolationState="true" alpha="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/gridded data">
<persisted>
<colorMapMin>0.0</colorMapMin>
<colorMapMax>10.0</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
</capabilities>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="CLGTN2hr"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="CLGTN2hr"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,98 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="1.0" interpolationState="true" alpha="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/truncated warm to cold">
<persisted>
<colorMapMin>0.0</colorMapMin>
<colorMapMax>100.0</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
</capabilities>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="PROLGHT2hr"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="DEFAULT"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="false" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.level.levelonevalue">
<constraint constraintType="EQUALS" constraintValue="0.0"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintType="EQUALS" constraintValue="SFC"/>
</mapping>
<mapping key="info.parameter.abbreviation">
<constraint constraintType="EQUALS" constraintValue="PROLGHT2hr"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintType="EQUALS" constraintValue="-999999.0"/>
</mapping>
<mapping key="pluginName">
<constraint constraintType="EQUALS" constraintValue="grid"/>
</mapping>
</metadataMap>
<alertParser xsi:type="gribDataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,169 @@
<bundle xmlns:ns2="group">
<displayList>
<displays xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d2DMapRenderableDisplay" scale="CONUS" density="1.0" magnification="1.0" zoomLevel="1.0" mapCenter="-66.2005121984067 35.94909693622639 0.0">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="ARROW" loadWithoutData="false">
<capabilities>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="2" outlineOn="true" lineStyle="SOLID"/>
<capability xsi:type="displayTypeCapability" displayType="ARROW"/>
<capability xsi:type="colorableCapability" colorAsString="white"/>
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties renderingOrderId="CONTOUR" isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.parameter.abbreviation">
<constraint constraintValue="Wind" constraintType="EQUALS"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintValue="-999999" constraintType="EQUALS"/>
</mapping>
<mapping key="pluginName">
<constraint constraintValue="grid" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintValue="FHAG" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintValue="10.0" constraintType="EQUALS"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<resourceType>PLAN_VIEW</resourceType>
<perspectiveProperty xsi:type="d2dLoadProperties" loadMode="VALID_TIME_SEQ" timeMatchBasis="true"/>
<capabilities>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="densityCapability" density="0.75"/>
<capability xsi:type="colorableCapability" colorAsString="black"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="SOLID"/>
</capabilities>
</loadProperties>
<properties isVisible="true" isHoverOn="false" isMapLayer="false" isBlinking="false" isSystemResource="false" renderingOrderId="CONTOUR">
<pdProps minDisplayWidth="0" maxDisplayWidth="100000000"/>
</properties>
<resourceData xsi:type="gridResourceData" sampling="true" spatial="false" isRequeryNecessaryOnTimeMatch="true" isUpdatingOnMetadataOnly="false" retrieveData="true">
<metadataMap>
<mapping key="info.parameter.abbreviation">
<constraint constraintValue="Terranl" constraintType="EQUALS"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintValue="-999999" constraintType="EQUALS"/>
</mapping>
<mapping key="pluginName">
<constraint constraintValue="grid" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintValue="SFC" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintValue="0.0" constraintType="EQUALS"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="CONTOUR" loadWithoutData="false">
<capabilities>
<capability xsi:type="colorableCapability" colorAsString="white"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="2" outlineOn="true" lineStyle="SOLID"/>
<capability xsi:type="displayTypeCapability" displayType="CONTOUR"/>
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.parameter.abbreviation">
<constraint constraintValue="msl-P" constraintType="EQUALS"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="pluginName">
<constraint constraintValue="grid" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintValue="SFC" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintValue="0.0" constraintType="EQUALS"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<resource>
<loadProperties xsi:type="gridLoadProperties" displayType="IMAGE" loadWithoutData="false">
<capabilities>
<capability xsi:type="imagingCapability" contrast="1.0" brightness="0.8" interpolationState="true" alpha="1.0"/>
<capability xsi:type="colorableCapability" colorAsString="coral"/>
<capability xsi:type="densityCapability" density="1.0"/>
<capability xsi:type="magnificationCapability" magnification="1.0"/>
<capability xsi:type="outlineCapability" outlineWidth="1" outlineOn="true" lineStyle="SOLID"/>
<capability xsi:type="displayTypeCapability" displayType="IMAGE"/>
<capability xsi:type="colorMapCapability">
<colorMapParameters colorMapName="Grid/Temperature F">
<persisted>
<colorMapMin>247.9278</colorMapMin>
<colorMapMax>316.483</colorMapMax>
</persisted>
</colorMapParameters>
</capability>
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties isSystemResource="false" isBlinking="false" isMapLayer="false" isHoverOn="false" isVisible="true">
<pdProps maxDisplayWidth="100000000" minDisplayWidth="0"/>
</properties>
<resourceData xsi:type="gridResourceData" retrieveData="true" isUpdatingOnMetadataOnly="false" isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="info.parameter.abbreviation">
<constraint constraintValue="Terranl" constraintType="EQUALS"/>
</mapping>
<mapping key="info.datasetId">
<constraint constraintValue="${modelName}" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.leveltwovalue">
<constraint constraintValue="-999999" constraintType="EQUALS"/>
</mapping>
<mapping key="pluginName">
<constraint constraintValue="grid" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.masterLevel.name">
<constraint constraintValue="SFC" constraintType="EQUALS"/>
</mapping>
<mapping key="info.level.levelonevalue">
<constraint constraintValue="0.0" constraintType="EQUALS"/>
</mapping>
</metadataMap>
<alertParser xsi:type="dataCubeAlertMessageParser"/>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher" deltaFilter="0" forecastFilter="0"/>
<numberOfFrames>${frameCount}</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -44,6 +44,6 @@
<contribute xsi:type="titleItem" titleText="------ Ocean Products ------"
id="OceanModelsLine" />
<contribute xsi:type="bundleItem" file="bundles/volume/HFR.xml"
menuText="High Frequency Radar (HFR) Ocean Surface Winds" id="hfr" useReferenceTime="true">
menuText="High Frequency Radar (HFR) Ocean Sfc Wind" id="hfr" useReferenceTime="true">
</contribute>
</menuTemplate>

View file

@ -33,13 +33,6 @@
<substitute key="menuName" value="DGEX" />
<substitute key="frameCount" value="41" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/allFamilies.xml">
<substitute key="modelName" value="ECMF-Global" />
<substitute key="menuName" value="ECMF Global" />
<substitute key="frameCount" value="41" />
<substitute key="TP" value="TP6hr"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/allFamilies.xml">
@ -54,6 +47,13 @@
<substitute key="menuName" value="GFS 20km" />
<substitute key="frameCount" value="41" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/lampFamilies.xml">
<substitute key="modelName" value="LAMP2p5" />
<substitute key="menuName" value="GFS-LAMP" />
<substitute key="frameCount" value="41" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/allFamilies.xml">
@ -99,19 +99,18 @@
</include>
<include installTo="menu:models"
fileName="menus/volume/allFamilies.xml">
<substitute key="modelName" value="RAP40" />
<substitute key="menuName" value="RAP 40km" />
<substitute key="modelName" value="RAP20" />
<substitute key="menuName" value="RAP 20km" />
<substitute key="frameCount" value="19" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/allFamilies.xml">
<substitute key="modelName" value="UKMET-Global" />
<substitute key="menuName" value="UKMET Global" />
<substitute key="frameCount" value="29" />
<substitute key="TP" value="TP6hr"/>
<substitute key="modelName" value="RAP40" />
<substitute key="menuName" value="RAP 40km" />
<substitute key="frameCount" value="19" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/mesoFamilies.xml">
<substitute key="modelName" value="NDFD" />
@ -119,7 +118,6 @@
<substitute key="frameCount" value="2" />
<substitute key="TP" value="TP"/>
</include>
<include installTo="menu:models"
fileName="menus/volume/mesoFamilies.xml">
<substitute key="modelName" value="RTMA" />

View file

@ -0,0 +1,54 @@
<?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.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="subMenu" menuText="${menuName}">
<contribute xsi:type="bundleItem" file="bundles/volume/SurfaceTempWind.xml"
menuText="Sfc Temperature" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/SurfaceTempError.xml"
menuText="Sfc Temperature Error" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/DewpointTemp.xml"
menuText="Sfc Dewpoint Temperature" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/DewpointTempError.xml"
menuText="Sfc Dewpoint Temperature Error" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/SfcRH.xml"
menuText="Sfc Relative Humidity" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/CeilingHeight.xml"
menuText="Ceiling Height" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/LightningPotential.xml"
menuText="2hr Lightning Potential" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/LightningProbability.xml"
menuText="2hr Lightning Probability" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/ConvectionPotential.xml"
menuText="2hr Convection Potential" id="" useReferenceTime="true">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/volume/ConvectionProbability.xml"
menuText="2hr Convection Probability" id="" useReferenceTime="true">
</contribute>
</contribute>
</menuTemplate>

View file

@ -119,10 +119,6 @@
<param name="feature"
value="edu.wisc.ssec.cimss.edex.convectprob.feature" />
</antcall>
<antcall target="build">
<param name="feature"
value="com.raytheon.uf.edex.binlightning.feature" />
</antcall>
<antcall target="build">
<param name="feature"
value="gov.nasa.msfc.sport.edex.sportlma.feature" />

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.edex.plugin.binlightning.legacy</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,8 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LegacyLightningDecoder
Bundle-SymbolicName: com.raytheon.edex.plugin.binlightning.legacy
Bundle-Version: 1.16.0
Bundle-Vendor: RAYTHEON
Fragment-Host: com.raytheon.edex.plugin.binlightning;bundle-version="1.14.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7

View file

@ -1,4 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -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.edex.plugin.binlightning.impl;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Provide the base class for the binary lightning decoders. This class
* abstracts data and methods common to the current lightning decoder types.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
* 20070912 379 jkorman Code review cleanup.
* May 14, 2014 2536 bclement removed TimeTools
* Jun 05, 2014 3226 bclement parseDate() now returns calendar
* </pre>
*
* @author jkorman
* @version 1.0
*/
abstract class BaseLightningDecoder implements IBinLightningDecoder
{
private final Calendar BASE_TIME = TimeUtil.newGmtCalendar(1980, 2, 29);
private static final int DAYS_MASK = 0xFFFE;
private static final int DAYS_SHFT = 1;
private static final int HOURS_HI_BIT_MASK = 0x0001;
private static final int HOURS_HI_BIT_SHFT = 0x0004;
private static final int HOURS_LO_NYB_MASK = 0x00F0;
private static final int HOURS_LO_NYB_SHFT = 0x0004;
private static final int MIN_P1_MASK = 0x000F;
private static final int MIN_P1_SHFT = 2;
private static final int MIN_P2_MASK = 0x00C0;
private static final int MIN_P2_SHFT = 6;
private static final int SECONDS_MASK = 0x003F;
// package private visibility - only sub-classes need to see these.
static final int FLASH_MSG_SIZE = 6;
static final int RT_MSG_SIZE = 8;
static final int TIME_SIZE = 4;
private int lastError = NO_ERROR;
private List<LightningStrikePoint> strikes = new ArrayList<LightningStrikePoint>();
/**
* Parse the date field from a given data source. It is assumed that the
* data source is pointing to the current date/time data.
*
* @return A Calendar object with the time fields set to the observation
* time.
*/
protected Calendar parseDate(IBinDataSource msgData)
{
//********* Don't reorder these reads!!!
int b1 = msgData.getU8();
int b2 = msgData.getU8();
int word1 = msgData.getU16();
//********* Don't reorder these reads!!!
Calendar obsTime = (Calendar) BASE_TIME.clone();
// number of days since BASE_TIME
int days = ((word1 & DAYS_MASK) >> DAYS_SHFT);
obsTime.add(Calendar.DAY_OF_MONTH, days);
int hours = (word1 & HOURS_HI_BIT_MASK) << HOURS_HI_BIT_SHFT;
hours += (b2 & HOURS_LO_NYB_MASK) >>> HOURS_LO_NYB_SHFT;
obsTime.set(Calendar.HOUR, hours);
int minutes = (b2 & MIN_P1_MASK) << MIN_P1_SHFT;
minutes += (b1 & MIN_P2_MASK) >>> MIN_P2_SHFT;
obsTime.set(Calendar.MINUTE, minutes);
obsTime.set(Calendar.SECOND, (b1 & SECONDS_MASK));
obsTime.set(Calendar.MILLISECOND, 0);
return obsTime;
}
/**
* Add a strike report the strikes collection.
* @param strike A strike report.
*/
void addStrike(LightningStrikePoint strike)
{
strikes.add(strike);
}
/**
* Set the current error code for this decoder.
* @param errorCode The error code.
*/
void setError(int errorCode)
{
lastError = errorCode;
}
/**
* Get the last error code set for this decoder.
* @return The last error code.
*/
public int getError()
{
return lastError;
}
/**
* Get an iterator to the decoded lightning strikes.
* @return The lightning strike iterator.
*/
@Override
public Iterator<LightningStrikePoint> iterator()
{
return strikes.iterator();
}
}

View file

@ -1,132 +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.edex.plugin.binlightning.impl;
import java.util.Calendar;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Decode one or more Flash lightning observations. Decode algorithm is taken
* from the NWS D2D binary lightning decoder.
*
* <pre>
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class FlashLightningDecoder extends BaseLightningDecoder
{
/**
* Construct and decode a portion of a lightning observation.
* @param msgData Message data.
* @param count Number of flash reports contained in the message part.
*/
public FlashLightningDecoder(IBinDataSource msgData, int count)
{
super();
doDecode(msgData,count);
}
/**
* Perform the message decode.
* @param msgData Message data.
* @param count Number of flash reports contained in the message part.
*/
private void doDecode(IBinDataSource msgData, int count)
{
if(msgData.available(TIME_SIZE))
{
Calendar baseTime = parseDate(msgData);
if(msgData.available(FLASH_MSG_SIZE * count))
{
for(int i = 0;i < count;i++)
{
double lon = getFlashLon(msgData);
double lat = getFlashLat(msgData);
double strikeStrength = msgData.getS8() * 2.0;
// strike count and 1/10s seconds
int u8 = msgData.getU8();
int flashCount = u8 & 0x0F;
Calendar obsTime = TimeUtil.newCalendar(baseTime);
obsTime.set(Calendar.MILLISECOND, ((u8 & 0xF0) >> 4) * 100);
// Create the strike record from the report info and base
// time information.
LightningStrikePoint strikeData = new LightningStrikePoint(
lat, lon, baseTime, LtgMsgType.STRIKE_MSG_FL);
strikeData.setType(DEFAULT_FLASH_TYPE);
strikeData.setStrikeStrength(strikeStrength);
strikeData.setPulseCount(flashCount);
addStrike(strikeData);
}
}
else
{
setError(IBinLightningDecoder.NOT_ENOUGH_DATA);
}
}
else
{
setError(IBinLightningDecoder.NO_TIME_INFO);
}
}
/**
* Calculate the lightning strike longitude. From D2D lightning decoder.
* @param msgData Message data source.
* @return The lightning longitude.
*/
private double getFlashLon(IBinDataSource msgData)
{
int value = msgData.getU16();
double lon = (value * 0.001068115234) - 130.0;
return lon;
}
/**
* Calculate the lightning strike latitude. From D2D lightning decoder.
* @param msgData Message data source.
* @return The lightning latitude.
*/
private double getFlashLat(IBinDataSource msgData)
{
int value = msgData.getU16() & 0x7FFF;
double lat = (value * 0.001281738) + 18.0;
return lat;
}
}

View file

@ -1,174 +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.edex.plugin.binlightning.impl;
import java.util.Calendar;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
/**
* Decode one or more Real Time Flash lightning observations. Decode algorithm
* is taken from the NWS D2D binary lightning decoder.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
* 20070821 379 jkorman Added default strike type.
* 20080823 379 jkorman getRTLat was using 24 bits instead of 23.
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class RTLightningDecoder extends BaseLightningDecoder {
/**
* Construct an instance of this decoder, and decode the message data.
*
* @param msgData
* Message data.
* @param count
* Number of flash reports contained in the message part.
*/
public RTLightningDecoder(IBinDataSource msgData, int count) {
super();
doDecode(msgData, count);
}
/**
* Perform the message decode for real time strike message.
*
* @param msgData
* Message data.
* @param count
* Number of flash reports contained in the message part.
*/
private void doDecode(IBinDataSource msgData, int count) {
if (msgData.available(TIME_SIZE + (RT_MSG_SIZE * count))) {
Calendar baseTime = parseDate(msgData);
// for now just consume some data
for (int i = 0; i < count; i++) {
long part = msgData.getU32();
double lon = getRTLon(part);
double strength = getSignalStrength(part);
part = msgData.getU32();
double lat = getRTLat(part);
int strikeCount = getMult(part);
LightningStrikePoint strikeData = new LightningStrikePoint(lat,
lon, baseTime, LtgMsgType.STRIKE_MSG_RT);
strikeData.setStrikeStrength(strength);
strikeData.setPulseCount(strikeCount);
// *****
// NCDC documents indicate that RT data can report both CC/CG
// but haven't seen any data nor is it in the D2D decoders. Set
// to default for now.
// *****
strikeData.setType(DEFAULT_FLASH_TYPE);
strikeData.setMillis(0);
addStrike(strikeData);
}
} else {
setError(IBinLightningDecoder.NO_TIME_INFO);
}
}
/**
* Decode the Real Time lightning longitude. Data is in the lower 24 bits.
*
* @param msgPart
* Unsigned 32 bit value holding the coded longitude.
* @return The decoded longitude.
*/
private double getRTLon(long msgPart) {
int value = (int) (msgPart & 0xFFFFFFL);
double lon = (value / 16777216.0 * 360.0) - 180.0;
return lon;
}
/**
* Decode the Real Time lightning latitude. Data is in the lower 24 bits.
*
* @param msgPart
* Unsigned 32 bit value holding the coded latitude.
* @return The decoded latitude.
*/
private double getRTLat(long msgPart) {
int value = (int) (msgPart & 0x7FFFFFL);
double lat = (value / 16777216.0 * 360.0) - 90.0;
return lat;
}
/**
* Decode the Real Time lightning signal strength. Data is in the upper 8
* bits.
*
* @param msgPart
* Unsigned 32 bit value holding the coded strength.
* @return The decoded signal strength.
*/
private double getSignalStrength(long msgPart) {
final int SIGNMAG = 128;
double sigStrength = 0;
int temp = (int) ((msgPart >> 24) & 0xFF);
// if the temp strength is greater than 127, the result should be
// negative.
if (temp >= SIGNMAG) {
temp = SIGNMAG - temp;
}
// Make signal strength in the range -254..254
sigStrength = temp * 2;
return sigStrength;
}
/**
* Decode the number of strikes within the strike record. Data is encoded in
* bits 24..27.
*
* @param msgPart
* Unsigned 32 bit value holding the count.
* @return The number of strikes within the strike record.
*/
private int getMult(long msgPart) {
// TODO : Need to check this! There is data in bit 28-31 but none in
// 24..27 in current data.
// NCDC document 9603 indicates that RT_FLASH doesn't report mult so
// always zero would be correct
int temp = (int) ((msgPart >> 24) & 0x0F);
return temp;
}
}

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.edex.plugin.binlightning</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,32 +0,0 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Binlightning Plug-in
Bundle-SymbolicName: com.raytheon.edex.plugin.binlightning
Bundle-Version: 1.14.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: com.raytheon.edex.plugin.binlightning.dao
Import-Package: com.raytheon.edex.esb,
com.raytheon.edex.exception,
com.raytheon.edex.plugin,
com.raytheon.uf.common.dataquery.requests,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.geospatial.adapter,
com.raytheon.uf.common.localization,
com.raytheon.uf.common.localization.exception,
com.raytheon.uf.common.numeric,
com.raytheon.uf.common.serialization,
com.raytheon.uf.common.serialization.adapters,
com.raytheon.uf.common.status,
com.raytheon.uf.common.wmo,
com.vividsolutions.jts,
com.vividsolutions.jts.geom,
com.vividsolutions.jts.geom.prep,
com.vividsolutions.jts.io,
gov.noaa.nws.ost.edex.plugin.binlightning
Require-Bundle: com.raytheon.uf.common.dataplugin.binlightning;bundle-version="1.12.1174",
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
com.raytheon.uf.edex.core;bundle-version="1.12.1174",
com.raytheon.uf.edex.database;bundle-version="1.0.0",
com.raytheon.uf.edex.decodertools;bundle-version="1.12.1174"

View file

@ -1,6 +0,0 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
utility/,\
.,\
res/

View file

@ -1,17 +0,0 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="binlightningProperties" class="com.raytheon.uf.common.dataplugin.PluginProperties">
<property name="pluginName" value="binlightning" />
<property name="pluginFQN" value="com.raytheon.uf.common.dataplugin.binlightning" />
<property name="dao" value="com.raytheon.edex.plugin.binlightning.dao.BinLightningDao" />
<property name="record" value="com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord" />
</bean>
<bean factory-bean="pluginRegistry" factory-method="register">
<constructor-arg value="binlightning"/>
<constructor-arg ref="binlightningProperties"/>
</bean>
</beans>

View file

@ -1,54 +0,0 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="binlightningDecoder"
class="com.raytheon.edex.plugin.binlightning.BinLightningDecoder" />
<bean id="totalLightningDecoder" class="com.raytheon.edex.plugin.binlightning.total.TotalLightningDecoder" />
<bean id="binlightningDistRegistry" factory-bean="distributionSrv"
factory-method="register">
<constructor-arg value="binlightning" />
<constructor-arg value="jms-durable:queue:Ingest.binlightning" />
</bean>
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
<constructor-arg ref="clusteredBinLightningRoutes" />
</bean>
<camelContext id="clusteredBinLightningRoutes" xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<!-- Begin binlightning routes -->
<route id="binlightningIngestRoute">
<from uri="jms-durable:queue:Ingest.binlightning" />
<setHeader headerName="pluginName">
<constant>binlightning</constant>
</setHeader>
<doTry>
<pipeline>
<bean ref="stringToFile" />
<choice>
<when>
<simple>${in.header.header} regex '^SFPA42 KWBC.*'</simple>
<bean ref="totalLightningDecoder" method="decode" />
</when>
<otherwise>
<bean ref="binlightningDecoder" method="decode" />
</otherwise>
</choice>
<to uri="direct-vm:persistIndexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="log:binlightning?level=ERROR" />
</doCatch>
</doTry>
<!-- bean ref="processUtil" method="delete" / -->
</route>
</camelContext>
</beans>

View file

@ -1,636 +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.edex.plugin.binlightning;
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningAESKey;
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningDataDecryptionException;
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningDecoderUtil;
import gov.noaa.nws.ost.edex.plugin.binlightning.DecryptedLightningValidator;
import gov.noaa.nws.ost.edex.plugin.binlightning.EncryptedBinLightningCipher;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import com.raytheon.edex.esb.Headers;
import com.raytheon.edex.exception.DecoderException;
import com.raytheon.edex.plugin.binlightning.filter.LightningGeoFilter;
import com.raytheon.edex.plugin.binlightning.impl.BinLightningFactory;
import com.raytheon.edex.plugin.binlightning.impl.IBinDataSource;
import com.raytheon.edex.plugin.binlightning.impl.IBinLightningDecoder;
import com.raytheon.edex.plugin.binlightning.impl.LightningDataSource;
import com.raytheon.edex.plugin.binlightning.total.LightningWMOHeader;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.wmo.WMOHeader;
import com.raytheon.uf.common.wmo.WMOTimeParser;
import com.raytheon.uf.edex.decodertools.core.DecoderTools;
/**
* AWIPS decoder adapter strategy for binary lightning data.<br/>
*
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 10, 2007 379 jkorman Initial Coding from prototype.
* Aug 17, 2007 379 jkorman Changed log info to debug in decode().
* Aug 21, 2007 379 jkorman Added SFPA41 lightning data pattern.
* Sep 12, 2007 379 jkorman Code review cleanup.
* Sep 20, 2007 379 jkorman Check for null persistence time.
* Sep 24, 2007 379 jkorman Removed HDFGroup code. Set insert_time
* directly in decode.
* Sep 26, 2007 379 jkorman Updated to set DataTime.
* Mar 18, 2008 1026 jkorman Added debug strike info.
* Apr 08, 2008 1039 jkorman Added traceId for tracing data.
* Nov 11, 2008 1684 chammack Refactored for camel integration
* May 03, 2013 DCS 112 Wufeng Zhou Modified to be able to handle both the
* new encrypted data and legacy bit-shifted
* data
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Jan 24, 2014 DR 16774 Wufeng Zhou Modified for updated Bin-lightning data spec,
* and to used WMO header to distinguish bit-shifted
* GLD360 and NLDN data.
* May 14, 2014 2536 bclement moved WMO Header to common
* Jun 03, 2014 3226 bclement removed unused WMO patterns, switched to UFStatus
* removed TimeTools usage, removed constructDataURI() call
* added decodeBinLightningData() and decodeBitShiftedBinLightningData() from BinLightningDecoderUtil
* Jun 05, 2014 3226 bclement LightningStikePoint refactor, added extractPData()
* Jun 09, 2014 3226 bclement moved data array decrypt prep to EncryptedBinLightingCipher
* Jun 10, 2014 3226 bclement added filter support
* Jun 19, 2014 3226 bclement added validator callback
* Aug 04, 2014 3488 bclement added checkBinRange(), rebin() and finalizeRecords()
* Mar 08, 2016 18336 amoore Keep-alive messages should update the legend.
* Apr 07, 2016 DR18763 mgamazaychikov Switched to using LightningWMOHeader.
* May 02, 2016 18336 amoore BinLightningRecord constructor takes source.
*
* </pre>
*
* @author jkorman
*/
public class BinLightningDecoder {
// Allow ingest up to 10 minutes into the future.
private static final long TEN_MINUTES = 10 * 60 * 1000L;
private final SimpleDateFormat SDF;
private static final IUFStatusHandler logger = UFStatus
.getHandler(BinLightningDecoder.class);
private static final boolean REBIN_INVALID_DATA = Boolean
.getBoolean("rebin.invalid.binlightning");
public static final String BINLIGHTNING_KEYSTORE_PREFIX = "binlightning";
/**
* Default lightning strike type for FLASH messages. RT_FLASH documents
* indicate no default, but D2D code defaults to STRIKE_CG also.
*/
public LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.CLOUD_TO_GROUND;
private String traceId = null;
/**
* callback for validating decryption results
*/
private static DecryptedLightningValidator validator = new DecryptedLightningValidator() {
@Override
public boolean isValid(byte[] decryptedData) {
return BinLightningDecoderUtil.isKeepAliveRecord(decryptedData)
|| BinLightningDecoderUtil
.isLightningDataRecords(decryptedData);
}
};
/**
* Construct a BinLightning decoder. Calling hasNext() after construction
* will return false, decode() will return a null.
*/
public BinLightningDecoder() {
SDF = new SimpleDateFormat("yyyyMMddHHmmss");
SDF.setTimeZone(TimeZone.getTimeZone("Zulu"));
}
/**
* Get the next decoded data record.
*
* @return One record of decoded data.
* @throws DecoderException
* Thrown if no data is available.
*/
public PluginDataObject[] decode(byte[] data, Headers headers)
throws DecoderException {
// String traceId = null;
PluginDataObject[] rval = new PluginDataObject[0];
if (data != null) {
traceId = (String) headers.get(DecoderTools.INGEST_FILE_NAME);
LightningWMOHeader wmoHdr = new LightningWMOHeader(data);
if (wmoHdr.isValid()) {
String fileName = (String) headers
.get(WMOHeader.INGEST_FILE_NAME);
Calendar baseTime = WMOTimeParser.findDataTime(
wmoHdr.getYYGGgg(), fileName);
/*
* Because binary nature of the encrypted data, the string
* created with its byte[] array may not have the same length of
* the byte[] array length So when DecoderTools.stripWMOHeader()
* assumes byte[] length == String length in its logic, it is
* observed that it may return a shorter byte[] than the real
* data array. (Looks like a bug???)
*/
// byte[] pdata = DecoderTools.stripWMOHeader(data,
// SFUS_PATTERN);
// if (pdata == null) {
// pdata = DecoderTools.stripWMOHeader(data, SFPA_PATTERN);
// }
/*
* instead the following is used to strip WMO header a little
* more safely.
*/
byte[] pdata = extractPData(wmoHdr, data);
if ((pdata == null) || (pdata.length == 0)) {
return new PluginDataObject[0];
}
/*
* Modified by Wufeng Zhou to handle both legacy bit-shifted and
* new encryted data
*
* Preserved the legacy decoding in
* BinLigntningDecoderUtil.decodeBitShiftedBinLightningData(),
* and added logic to process both encrypted data and legacy
* data
*/
Collection<LightningStrikePoint> strikes = decodeBinLightningData(
data, pdata, traceId, wmoHdr, baseTime.getTime());
/*
* Done MOD by Wufeng Zhou
*/
// post processing data
BinLightningRecord report = null;
if (strikes.size() > 0) {
// not a keep-alive
report = LightningGeoFilter.createFilteredRecord(strikes);
} else {
// keep-alive, get the source from WMO header
String source = getSourceFromHeader(wmoHdr);
synchronized (SDF) {
logger.info(traceId
+ ": found keep-alive record of base time ["
+ SDF.format(baseTime.getTime())
+ "] and source [" + source + "]");
}
report = new BinLightningRecord(baseTime, source);
}
Collection<BinLightningRecord> records = checkBinRange(report,
strikes);
rval = finalizeRecords(records, baseTime);
}
} else {
logger.error("No WMOHeader found in data");
}
logger.debug(traceId + ": Returning array of [" + rval.length
+ "] bin lightning records");
return rval;
}
/**
* Perform final actions on each record and populate a PDO array with them.
* Any invalid records will be omitted from the return array.
*
* @param records
* @param baseTime
* @return
* @throws DecoderException
*/
private PluginDataObject[] finalizeRecords(
Collection<BinLightningRecord> records, Calendar baseTime)
throws DecoderException {
Calendar c = TimeUtil.newCalendar(baseTime);
if (c == null) {
throw new DecoderException(traceId + " - Error decoding times");
}
ArrayList<BinLightningRecord> rval = new ArrayList<>(records.size());
for (BinLightningRecord record : records) {
Calendar cStart = record.getStartTime();
if (cStart.getTimeInMillis() > (c.getTimeInMillis() + TEN_MINUTES)) {
synchronized (SDF) {
logger.info("Discarding future data for " + traceId
+ " at " + SDF.format(cStart.getTime()));
}
} else {
Calendar cStop = record.getStopTime();
TimeRange range = new TimeRange(cStart.getTimeInMillis(),
cStop.getTimeInMillis());
DataTime dataTime = new DataTime(cStart, range);
record.setDataTime(dataTime);
record.setTraceId(traceId);
rval.add(record);
}
}
return rval.toArray(new PluginDataObject[rval.size()]);
}
/**
* Ensure that the record has a valid bin range. If it does, it will be the
* only record in the return value. Otherwise, {@link #REBIN_INVALID_DATA}
* is used to determine if no records should be returned or the strikes
* should be split into valid bin ranges uses {@link #rebin(Collection)}
*
* @param record
* @param strikes
* @return
*/
private Collection<BinLightningRecord> checkBinRange(
BinLightningRecord record, Collection<LightningStrikePoint> strikes) {
Collection<BinLightningRecord> rval = Collections.emptyList();
Calendar cStart = record.getStartTime();
Calendar cStop = record.getStopTime();
long binRange = cStop.getTimeInMillis() - cStart.getTimeInMillis();
if (binRange > TimeUtil.MILLIS_PER_DAY) {
if (REBIN_INVALID_DATA) {
rval = rebin(strikes);
} else {
String rangeStart;
String rangeEnd;
synchronized (SDF) {
rangeStart = SDF.format(cStart.getTime());
rangeEnd = SDF.format(cStop.getTime());
}
logger.error("Discarding data with invalid bin range of "
+ rangeStart + " to " + rangeEnd);
}
} else {
rval = Arrays.asList(record);
}
return rval;
}
/**
* Split the strikes into 1 day bins and create a new record for each bin
*
* @param strikes
* @return
*/
private Collection<BinLightningRecord> rebin(
Collection<LightningStrikePoint> strikes) {
Map<Long, Collection<LightningStrikePoint>> binMap = new HashMap<>(1);
for (LightningStrikePoint strike : strikes) {
Calendar c = TimeUtil.newCalendar(strike.getTime());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long key = c.getTimeInMillis();
Collection<LightningStrikePoint> bin = binMap.get(key);
if (bin == null) {
bin = new ArrayList<>(strikes.size());
binMap.put(key, bin);
}
bin.add(strike);
}
Collection<BinLightningRecord> rval = new ArrayList<>(binMap.size());
for (Entry<Long, Collection<LightningStrikePoint>> e : binMap
.entrySet()) {
Collection<LightningStrikePoint> bin = e.getValue();
BinLightningRecord record = new BinLightningRecord(bin);
rval.add(record);
}
return rval;
}
/**
* Remove WMO header from data and return the remaining pdata
*
* @param wmoHdr
* @param data
* @return null if data is invalid
*/
public static byte[] extractPData(LightningWMOHeader wmoHdr, byte[] data) {
byte[] pdata = null;
if (wmoHdr.isValid() && wmoHdr.getMessageDataStart() > 0) {
pdata = new byte[data.length - wmoHdr.getMessageDataStart()];
System.arraycopy(data, wmoHdr.getMessageDataStart(), pdata, 0,
data.length - wmoHdr.getMessageDataStart());
}
return pdata;
}
/**
* Decode bin lightning data, able to handle both legacy bit-shifted and new
* encryted data
*
* The BinLightningDecoder.decode() method will use this method to decode
* data, which will try to decrypt first, and decode the old fashioned way
* when decryption fails
*
* @author Wufeng Zhou
*
* @param data
* - data content from file, including WMO header section
* @param pdata
* - data with WMO header stripped, optional, if null, will strip
* WMO header internally from passed in data parameter
* @param traceId
* - the file name of the data to be deoced
* @param wmoHdr
* - WMOHeader, added 12/24/2013 to help distinguish bit-shifted
* NLDN and GLD360 data (GLD data will have header starts like
* SFPA)
* @param dataDate
* - date of the data, optional, used as a hint to find
* appropriate encryption key faster
* @return null if keep-alive record, otherwise a list (could be empty) of
* LightningStrikePoint
*/
public static List<LightningStrikePoint> decodeBinLightningData(
byte[] data, byte[] pdata, String traceId,
LightningWMOHeader wmoHdr, Date dataDate) {
if (pdata == null) { // if data without header not passed, we'll strip
// the WMO header here
LightningWMOHeader header = new LightningWMOHeader(data);
if (header.isValid() && header.getMessageDataStart() > 0) {
pdata = new byte[data.length - header.getMessageDataStart()];
System.arraycopy(data, header.getMessageDataStart(), pdata, 0,
data.length - header.getMessageDataStart());
}
}
List<LightningStrikePoint> strikes = new ArrayList<>();
boolean needDecrypt = true; // set as default unless clear evidence says
// otherwise
boolean decodeDone = false;
EncryptedBinLightningCipher cipher = new EncryptedBinLightningCipher();
/*
* Using different WMO headers to indicate whether the data is encrypted
* or not would be a nice option. However, that idea has been discussed
* but not adopted. If in the future, WMO header can be different for
* legacy and encrypted data, or some other metadata can be used to
* decide whether deceyption is needed, logic can be added here.
*
* Before that happens, we'll use hints and trial & error to decode the
* data Hints: Per lightning data format spec, there are 3 bytes in the
* WMO header starting line that indicates the size of the encrypted
* block or the ASCII sequence # for legacy bit-shifted data However,
* the starting line is optional and AWIPS decode may not see it at all
* because TG will strip that starting line away We'll try to use this
* hint first, if is is not found, then trial and error way to decrypt
* and decode
*
* As of 11/05/2013, There is change in data spec. that the 3-bytes will
* not be encoded as encrypted block size anymore (it will always be
* transmission sequence # if present) So there should have some minor
* changes in the logic below for decoding the data. However, as reading
* into the
* com.raytheon.edex.plugin.binlightning.impl.BinLightningFactory
* .getDecoder () and follow-on code, we see the following data patterns
* for legacy bit-shifted data, which could be used to reduce guess-work
* in data decryption: The bit-shifted data will have multiple groups of
* the following patterns: 1-byte (unsigned byte): for size count 1-byte
* (unsigned byte): for flash type: 0x96 for FLASH_RPT (message size is
* 6 bytes each) 0x97 for RT_FLASH_RPT (message size is 8 bytes each)
* 0xd0 for OTHER_RPT (The D2D decoders declare but do not define this
* message, so unimplemented decoder) 0xd1 for COMM_RPT (The D2D
* decoders declare but do not define this message, so unimplemented
* decoder) 4-bytes: date time multiple of 6 or 8 bytes (as determined
* by 2nd byte flash type) with count indicated in 1st byte
*
* So this is be used to determine whether the data need to be
* decrypted.
*/
/*
* // looks like previous assumption on block size bytes are not valid
* any more. 11/20/2013 if (data != null) { byte[] sizeSeqBytes =
* BinLigntningDecoderUtil.findSizeOrSeqBytesFromWMOHeader(data); if
* (sizeSeqBytes != null) { // if this is in the header (which may not),
* use that as a hint to determine which decoding route to go if
* (BinLigntningDecoderUtil
* .isPossibleWMOHeaderSequenceNumber(sizeSeqBytes) &&
* BinLigntningDecoderUtil
* .getEncryptedBlockSizeFromWMOHeader(sizeSeqBytes) != pdata.length) {
* // looks like a sequence #, and if treat as size, it does not equal
* to the data block size, so most likely legacy data needDecrypt =
* false; } } }
*/
if (needDecrypt) {
try {
byte[] encryptedData = EncryptedBinLightningCipher
.prepDataForDecryption(pdata, traceId);
byte[] decryptedData = cipher.decryptData(encryptedData,
dataDate, BINLIGHTNING_KEYSTORE_PREFIX, validator);
// decrypt ok, then decode, first check if keep-alive record
if (BinLightningDecoderUtil.isKeepAliveRecord(decryptedData)) {
logger.info(traceId
+ " - Keep-alive record detected, no strike decoding.");
decodeDone = true;
return new ArrayList<>(0);
}
/*
* not necessarily keep-alive record, then check data validity
* and decode into an ArrayList<LightningStrikePoint> of strikes
*/
if (BinLightningDecoderUtil
.isLightningDataRecords(decryptedData)) {
strikes = BinLightningDecoderUtil
.decodeDecryptedBinLightningData(decryptedData);
decodeDone = true;
} else {
logger.info(traceId
+ " - Failed data validity check of the decrypted data, will try decode the old-fashioned way.");
decodeDone = false;
}
} catch (IllegalBlockSizeException e) {
logger.info(traceId
+ " - "
+ e.getMessage()
+ ": Decryption failed, will try decode the old-fashioned way.");
decodeDone = false;
} catch (BadPaddingException e) {
logger.info(traceId
+ " - "
+ e.getMessage()
+ ": Decryption failed, will try decode the old-fashioned way.");
decodeDone = false;
} catch (BinLightningDataDecryptionException e) {
logger.info(traceId
+ " - "
+ e.getMessage()
+ ": Decryption failed, will try decode the old-fashioned way.");
decodeDone = false;
}
}
if (decodeDone == false) { // not decoded through decrypt->decode
// process, try the legacy decoder
logger.info(traceId + " - decoding as bit-shifted data");
/*
* bit-shifting data format check call here will get us some more
* information on the data, also can compare the strikes with the
* decoder result
*/
int estimatedStrikes = BinLightningDecoderUtil
.getBitShiftedDataStrikeCount(pdata);
strikes = decodeBitShiftedBinLightningData(pdata, wmoHdr);
if (estimatedStrikes != strikes.size()) {
logger.warn(traceId
+ ": bit-shifted decoder found "
+ strikes
+ " strikes, which is different from estimate from data pattern examination: "
+ estimatedStrikes);
}
}
return strikes;
}
/**
* extracted from the original {@link #decode(byte[], Headers)} method then
* modified by Wufeng Zhou
*
* @param pdata
* @param wmoHdr
* - WMOHeader, added 12/24/2013 to help distinguish bit-shifted
* NLDN and GLD360 data (GLD data will have header starts like
* SFPA)
* @return
*/
public static List<LightningStrikePoint> decodeBitShiftedBinLightningData(
byte[] pdata, LightningWMOHeader wmoHdr) {
List<LightningStrikePoint> strikes = new ArrayList<>();
IBinDataSource msgData = new LightningDataSource(pdata);
boolean continueDecode = true;
while (continueDecode) {
IBinLightningDecoder decoder = BinLightningFactory
.getDecoder(msgData);
switch (decoder.getError()) {
case IBinLightningDecoder.NO_ERROR: {
for (LightningStrikePoint strike : decoder) {
String source = getSourceFromHeader(wmoHdr);
strike.setLightSource(source);
strikes.add(strike);
}
break;
}
default: {
continueDecode = false;
}
}
}
return strikes;
}
/**
* Get the data source from the given WMO header.
*
* @param wmoHdr
* the header.
* @return the data source according to text from the header.
*/
private static String getSourceFromHeader(LightningWMOHeader wmoHdr) {
/*
* use WMO Header to distinguish NLDN or GLD360 data because no
* bit-shifted data spec available for GLD360. 12/24/2013, WZ The WMO
* header start string is defined in BinLightningAESKey.properties file
* (normally, GLD360 data will have WMO header starts with SFPA41, or
* SFPA99 for test data.)
*/
/*
* continually get the properties locally instead of as a constant
* because the properties file could be changed and reloaded by the
* user.
*/
String gld360WMOHeaderString = BinLightningAESKey.getProps()
.getProperty("binlightning.gld360WMOHeaderStartString", "");
String source = null;
if (gld360WMOHeaderString.trim().equals("") == false
&& wmoHdr.getWmoHeader().startsWith(gld360WMOHeaderString)) {
// GLD360 data based on the setup
source = "GLD";
}
/*
* default source is NLDN, which is the only other option at this time
* for this decoder (5/2/2016, DR 18336). For future sources, add here
* and modify BinLightningAESKey.properties.
*/
return BinLightningRecord.validateSource(source);
}
/**
* Set a trace identifier for the source data.
*
* @param traceId
* A unique identifier associated with the input data.
*/
public void setTraceId(String traceId) {
this.traceId = traceId;
}
}

View file

@ -1,105 +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.edex.plugin.binlightning.dao;
import java.util.Map;
import java.util.Map.Entry;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
import com.raytheon.uf.common.dataplugin.binlightning.LightningConstants;
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.StorageException;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.edex.database.plugin.PluginDao;
/**
* Data access object for access binlightning data
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/08/09 1674 bphillip Initial creation
* Jun 05, 2014 3226 bclement record now contains maps for data arrays
* </pre>
*
* @author bphillip
* @version 1.0
*/
public class BinLightningDao extends PluginDao {
/**
*
* @param pluginName The name of this plugin.
* @throws PluginException
*/
public BinLightningDao(String pluginName) throws PluginException {
super(pluginName);
}
/**
* Copy data from a Persistable object into a given DataStore container.
* @param dataStore DataStore instance to receive the Persistable data.
* @param obj The Persistable object to be stored.
* @throws Exception Any general exception thrown in this method.
*/
protected IDataStore populateDataStore(IDataStore dataStore,
IPersistable obj) throws Exception {
BinLightningRecord binLightningRec = (BinLightningRecord) obj;
Map<String, Object> strikeDataArrays = binLightningRec
.getStrikeDataArrays();
populateFromMap(dataStore, obj, binLightningRec.getDataURI(),
strikeDataArrays);
Map<String, Object> pulseDataArrays = binLightningRec
.getPulseDataArrays();
String pulseGroup = binLightningRec.getDataURI() + DataURI.SEPARATOR
+ LightningConstants.PULSE_HDF5_GROUP_SUFFIX;
populateFromMap(dataStore, obj, pulseGroup, pulseDataArrays);
return dataStore;
}
/**
* Adds each primitive data array object in map to the datastore using the
* provided group and the key of the map entry as the name
*
* @param dataStore
* @param obj
* @param group
* @param data
* @throws StorageException
*/
private void populateFromMap(IDataStore dataStore, IPersistable obj,
String group, Map<String, Object> data)
throws StorageException {
for (Entry<String, Object> e : data.entrySet()) {
String name = e.getKey();
Object dataArray = e.getValue();
IDataRecord record = DataStoreFactory.createStorageRecord(name,
group, dataArray);
record.setCorrelationObject(obj);
dataStore.addDataRecord(record);
}
}
}

View file

@ -1,136 +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.edex.plugin.binlightning.filter;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
/**
* JAXB POJO for filter bounding box
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 11, 2014 3226 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class GeoFilterBbox {
@XmlAttribute(required = true)
private double minx;
@XmlAttribute(required = true)
private double maxx;
@XmlAttribute(required = true)
private double miny;
@XmlAttribute(required = true)
private double maxy;
/**
*
*/
public GeoFilterBbox() {
}
/**
* @param minx
* @param maxx
* @param miny
* @param maxy
*/
public GeoFilterBbox(double minx, double maxx, double miny, double maxy) {
this.minx = minx;
this.maxx = maxx;
this.miny = miny;
this.maxy = maxy;
}
/**
* @return the minx
*/
public double getMinx() {
return minx;
}
/**
* @param minx
* the minx to set
*/
public void setMinx(double minx) {
this.minx = minx;
}
/**
* @return the maxx
*/
public double getMaxx() {
return maxx;
}
/**
* @param maxx
* the maxx to set
*/
public void setMaxx(double maxx) {
this.maxx = maxx;
}
/**
* @return the miny
*/
public double getMiny() {
return miny;
}
/**
* @param miny
* the miny to set
*/
public void setMiny(double miny) {
this.miny = miny;
}
/**
* @return the maxy
*/
public double getMaxy() {
return maxy;
}
/**
* @param maxy
* the maxy to set
*/
public void setMaxy(double maxy) {
this.maxy = maxy;
}
}

View file

@ -1,70 +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.edex.plugin.binlightning.filter;
/**
* Exception thrown during lightning filter config parsing
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 10, 2014 3226 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class GeoFilterException extends Exception {
private static final long serialVersionUID = -7455324971125247083L;
/**
*
*/
public GeoFilterException() {
}
/**
* @param message
*/
public GeoFilterException(String message) {
super(message);
}
/**
* @param cause
*/
public GeoFilterException(Throwable cause) {
super(cause);
}
/**
* @param message
* @param cause
*/
public GeoFilterException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -1,275 +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.edex.plugin.binlightning.filter;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBException;
import javax.xml.stream.XMLStreamException;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.geospatial.SpatialException;
import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.serialization.SerializationException;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
/**
* Parses geographic filter configuration files. Example file located in utility
* directory.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 10, 2014 3226 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class GeoFilterParser {
private static final double LAT_MIN = -90;
private static final double LAT_MAX = 90;
private static final double LON_MIN = -180;
private static final double LON_MAX = 180;
/* CWA database constants */
private static final String CWA_TABLE = "cwa";
private static final String CWA_COLUMN = "cwa";
/* helper factories */
private static JAXBManager jaxbManager;
private static volatile boolean initialized = false;
private static final GeometryFactory GEOM_FACTORY = new GeometryFactory();
/**
* initialize jaxb manager
*
* @throws JAXBException
*/
private static synchronized void initialize() throws JAXBException {
if (!initialized) {
jaxbManager = new JAXBManager(GeoFilters.class);
initialized = true;
}
}
/**
* Parse filter config file from input stream. Does not close input stream.
* Any non-fatal parsing errors are returned in result.
*
* @param in
* @return
* @throws JAXBException
* @throws SerializationException
*/
public static GeoFilterResult parse(InputStream in) throws JAXBException,
SerializationException {
if (!initialized) {
initialize();
}
Object obj = jaxbManager.unmarshalFromInputStream(in);
if (obj instanceof GeoFilters) {
return parseInternal((GeoFilters) obj);
} else {
throw new SerializationException("Unexpected XML object type: "
+ obj.getClass());
}
}
/**
* @see #parse
* @param filters
* jaxb pojo
* @return
* @throws XMLStreamException
*/
private static GeoFilterResult parseInternal(GeoFilters filters) {
List<Geometry> geoms = new ArrayList<Geometry>();
List<GeoFilterException> errors = new ArrayList<GeoFilterException>(0);
List<GeoFilterBbox> bboxes = filters.getBboxes();
if (bboxes != null && !bboxes.isEmpty()) {
for (GeoFilterBbox bbox : bboxes) {
try {
geoms.addAll(convertBbox(bbox));
} catch (GeoFilterException e) {
errors.add(e);
}
}
}
List<String> cwas = filters.getCwas();
if (cwas != null && !cwas.isEmpty()) {
for (String cwa : cwas) {
try {
geoms.addAll(getCWA(cwa));
} catch (GeoFilterException e) {
errors.add(e);
}
}
}
List<Geometry> geometries = filters.getGeometries();
if (geometries != null) {
geoms.addAll(geometries);
}
List<PreparedGeometry> rval = new ArrayList<PreparedGeometry>(
geoms.size());
for (Geometry geom : geoms) {
rval.add(PreparedGeometryFactory.prepare(geom));
}
return new GeoFilterResult(rval, errors);
}
/**
* Get county warning area geometries by name. Performs a database lookup.
*
* @param cwa
* @return
* @throws GeoFilterException
*/
private static Collection<Geometry> getCWA(String cwa)
throws GeoFilterException {
Map<String, RequestConstraint> map = new HashMap<String, RequestConstraint>();
map.put(CWA_COLUMN, new RequestConstraint(cwa));
SpatialQueryResult[] results;
try {
results = SpatialQueryFactory.create().query(CWA_TABLE, null, null,
map, null);
} catch (SpatialException e) {
throw new GeoFilterException("Unable to query database for CWA: "
+ cwa, e);
}
if (results == null || results.length == 0) {
return Collections.emptyList();
}
List<Geometry> rval = new ArrayList<Geometry>(results.length);
for (SpatialQueryResult result : results) {
rval.add(result.geometry);
}
return rval;
}
/**
* Validate bounding box coordinates in attributes. Converts bounding box to
* polygon.
*
* @param bbox
* @return
*/
private static Collection<Geometry> convertBbox(GeoFilterBbox bbox)
throws GeoFilterException {
Coordinate upper = new Coordinate(bbox.getMaxx(), bbox.getMaxy());
Coordinate lower = new Coordinate(bbox.getMinx(), bbox.getMiny());
if (lower.x > upper.x || lower.y > upper.y) {
throw new GeoFilterException(
"Invalid bounding box tag. Minimum coordinate values "
+ "cannot be larger than maximum coordinate values: "
+ lower + " " + upper);
}
if (lower.y < LAT_MIN || upper.y > LAT_MAX) {
throw new GeoFilterException(
"Invalid bounding box tag. Box cannot cross poles: "
+ lower.y + "," + upper.y);
}
List<Geometry> rval = null;
lower.x = normalizeLon(lower.x);
upper.x = normalizeLon(upper.x);
/*
* if normalization switched order, it means it crossed the antimeridian
* and needs to be split into two boxes
*/
if (lower.x > upper.x) {
/* create a new box on the left of the map */
Coordinate leftLower = new Coordinate(LON_MIN, lower.y);
Coordinate leftUpper = new Coordinate(upper.x, upper.y);
/* change the old box to only cover the right of the map */
upper.x = LON_MAX;
Geometry left = createPolygon(leftLower, leftUpper);
Geometry right = createPolygon(lower, upper);
rval = Arrays.asList(left, right);
} else {
rval = Arrays.asList(createPolygon(lower, upper));
}
return rval;
}
/**
* @param lon
* @return longitude normalized to be between -180 and 180
*/
private static double normalizeLon(double lon) {
/* 360 degrees */
final double LON_TOTAL = LON_MAX * 2;
/* account for any far out degrees */
double rval = lon % LON_TOTAL;
/* subtract or add to get in range */
if (rval > LON_MAX) {
rval -= LON_TOTAL;
} else if (rval < LON_MIN) {
rval += LON_TOTAL;
}
return rval;
}
/**
* @param mins
* @param maxes
* @return polygon defining a bounding box using corner points
*/
private static Geometry createPolygon(Coordinate mins, Coordinate maxes) {
Coordinate[] coordinates = new Coordinate[5];
coordinates[0] = new Coordinate(mins.x, mins.y);
coordinates[1] = new Coordinate(mins.x, maxes.y);
coordinates[2] = new Coordinate(maxes.x, maxes.y);
coordinates[3] = new Coordinate(maxes.x, mins.y);
/* polygons need a closed ring */
coordinates[4] = coordinates[0];
return GEOM_FACTORY.createPolygon(coordinates);
}
}

View file

@ -1,90 +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.edex.plugin.binlightning.filter;
import java.util.Collection;
import java.util.Collections;
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
/**
* Geographic filter parsing results. Wraps parsed data and any parsing errors.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 10, 2014 3226 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class GeoFilterResult {
private final Collection<GeoFilterException> errors;
private final Collection<PreparedGeometry> filters;
/**
* @param filters
*/
public GeoFilterResult(Collection<PreparedGeometry> filters) {
this(filters, Collections.<GeoFilterException> emptyList());
}
/**
* @param filters
* @param errors
*/
public GeoFilterResult(Collection<PreparedGeometry> filters,
Collection<GeoFilterException> errors) {
this.filters = filters;
this.errors = errors;
}
/**
* @return true if any errors were encountered during parsing
* @see #getErrors()
*/
public boolean hasErrors() {
return !errors.isEmpty();
}
/**
* @return the errors
* @see #hasErrors()
*/
public Collection<GeoFilterException> getErrors() {
return errors;
}
/**
* @return the filters
*/
public Collection<PreparedGeometry> getFilters() {
return filters;
}
}

View file

@ -1,127 +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.edex.plugin.binlightning.filter;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.common.geospatial.adapter.GeometryAdapter;
import com.vividsolutions.jts.geom.Geometry;
/**
* Root JAXB POJO for geographic filter configuration
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 11, 2014 3226 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
@XmlRootElement(name = "filters")
@XmlAccessorType(XmlAccessType.NONE)
public class GeoFilters {
@XmlElement(name = "wkt")
@XmlJavaTypeAdapter(value = GeometryAdapter.class)
private List<Geometry> geometries;
@XmlElement(name = "cwa")
private List<String> cwas;
@XmlElement(name = "bbox")
private List<GeoFilterBbox> bboxes;
/**
*
*/
public GeoFilters() {
}
/**
* @param geometries
* @param cwas
* @param bboxes
*/
public GeoFilters(List<Geometry> geometries,
List<String> cwas,
List<GeoFilterBbox> bboxes) {
this.geometries = geometries;
this.cwas = cwas;
this.bboxes = bboxes;
}
/**
* @return the geometries
*/
public List<Geometry> getGeometries() {
return geometries;
}
/**
* @param geometries
* the geometries to set
*/
public void setGeometries(List<Geometry> geometries) {
this.geometries = geometries;
}
/**
* @return the cwas
*/
public List<String> getCwas() {
return cwas;
}
/**
* @param cwas
* the cwas to set
*/
public void setCwas(List<String> cwas) {
this.cwas = cwas;
}
/**
* @return the bboxes
*/
public List<GeoFilterBbox> getBboxes() {
return bboxes;
}
/**
* @param bboxes
* the bboxes to set
*/
public void setBboxes(List<GeoFilterBbox> bboxes) {
this.bboxes = bboxes;
}
}

View file

@ -1,218 +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.edex.plugin.binlightning.filter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.bind.JAXBException;
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.localization.ILocalizationFile;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.prep.PreparedGeometry;
/**
* Geographic filtering utility for lightning data. Configured in localization.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 10, 2014 3226 bclement Initial creation
* Jan 27, 2016 5237 tgurney Replace LocalizationFile with
* ILocalizationFile
*
* </pre>
*
* @author bclement
* @version 1.0
* @see {@link GeoFilterParser}
*/
public class LightningGeoFilter {
private static final IUFStatusHandler log = UFStatus
.getHandler(LightningGeoFilter.class);
public static final String LOCALIZATION_FILTER_DIR = "binlightning/filters";
private static final GeometryFactory GEOM_FACTORY = new GeometryFactory();
/**
* map of lightning source names to filter geometries
*/
private static final Map<String, Collection<PreparedGeometry>> geometryMap = new ConcurrentHashMap<String, Collection<PreparedGeometry>>(
4);
private static volatile boolean initialized = false;
/**
* read filter configuration files from localization. Threadsafe and
* idempotent
*/
private static void initialize() {
synchronized (geometryMap) {
if (!initialized) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationFile[] files = pathMgr.listFiles(pathMgr
.getLocalSearchHierarchy(LocalizationType.EDEX_STATIC),
LOCALIZATION_FILTER_DIR, new String[] { ".xml" }, true,
true);
for (ILocalizationFile file : files) {
Collection<PreparedGeometry> filters = getFilterGeometries(file);
if (!filters.isEmpty()) {
String bareName = getFileNameWithoutExtension(file
.getPath());
geometryMap.put(bareName.toLowerCase(), filters);
}
}
initialized = true;
}
}
}
/**
* Parse filter geometries from filter config file
*
* @param file
* @return empty list on error
*/
private static Collection<PreparedGeometry> getFilterGeometries(
ILocalizationFile file) {
Collection<PreparedGeometry> rval;
try (InputStream in = file.openInputStream()) {
GeoFilterResult result = GeoFilterParser.parse(in);
if (result.hasErrors()) {
for (GeoFilterException e : result.getErrors()) {
log.error(e.getLocalizedMessage(), e);
}
log.warn("Filter parsing included errors, filters will be incomplete");
}
return result.getFilters();
} catch (IOException | JAXBException | LocalizationException
| SerializationException e) {
log.error("Unable to parse filter file: " + file.getPath(), e);
rval = Collections.emptyList();
}
return rval;
}
/**
* Strip the bare file name from path. Removes path and file suffix (if
* either exist)
*
* @param path
* @return
*/
private static String getFileNameWithoutExtension(String path) {
int slashIndex = path.lastIndexOf(IPathManager.SEPARATOR);
int start = slashIndex < 0 ? 0 : slashIndex + 1;
int dotIndex = path.lastIndexOf('.');
if (dotIndex < 0) {
return path.substring(start);
} else {
return path.substring(start, dotIndex);
}
}
/**
* Applies data source filter to strikes. Source is determined from sample
* strike. If no filter exists for source, provided collection is returned.
*
* @param strikes
* @return
*/
public static Collection<LightningStrikePoint> filterStrikes(
Collection<LightningStrikePoint> strikes) {
if (!initialized) {
initialize();
}
Collection<LightningStrikePoint> rval = strikes;
if (!strikes.isEmpty()) {
LightningStrikePoint sample = strikes.iterator().next();
String source = BinLightningRecord.getDataSource(sample);
Collection<PreparedGeometry> filter = geometryMap.get(source
.toLowerCase());
if (filter != null && !filter.isEmpty()) {
rval = new ArrayList<LightningStrikePoint>(strikes.size());
for (LightningStrikePoint strike : strikes) {
if (passesFilter(filter, strike)) {
rval.add(strike);
}
}
}
}
return rval;
}
/**
* @param filter
* @param strike
* @return true if strike is located in any of the filter geometries
*/
private static boolean passesFilter(Collection<PreparedGeometry> filter,
LightningStrikePoint strike) {
boolean passes = false;
Point p = GEOM_FACTORY.createPoint(new Coordinate(
strike.getLongitude(), strike.getLatitude()));
for (PreparedGeometry g : filter) {
/* covers instead of contains to include points at boundary */
if (g.covers(p)) {
passes = true;
break;
}
}
return passes;
}
/**
* Create a BinLightningRecord after applying data source filter to list of
* strikes
*
* @see #filterStrikes(Collection)
* @param strikes
* @return
*/
public static BinLightningRecord createFilteredRecord(
Collection<LightningStrikePoint> strikes) {
return new BinLightningRecord(filterStrikes(strikes));
}
}

View file

@ -1,122 +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.edex.plugin.binlightning.impl;
import static com.raytheon.edex.plugin.binlightning.impl.IBinLightningDecoder.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import com.raytheon.edex.plugin.binlightning.BinLightningDecoder;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
/**
* Read from the message data source, isolate and create a decoder for the
* current sub-message. In the event that the message decoder can not be
* created, an instance of LightningErrorDecoder is created.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
* 20160116 18408 Wufeng Zhou Remove direct dependency on bit shifting decoder
*
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class BinLightningFactory
{
private static final IUFStatusHandler logger = UFStatus.getHandler(BinLightningDecoder.class);
/**
* Read from the message data source, isolate and create a decoder for the
* current sub-message. In the event that the message decoder can not be
* created, an instance of LightningErrorDecoder is created.
* @param msgData The message data source.
* @return The decoder instance.
*/
public static IBinLightningDecoder getDecoder(IBinDataSource msgData)
{
IBinLightningDecoder decoder = null;
int count = msgData.getU8();
int decoderType = msgData.getU8();
switch(decoderType)
{
case FLASH_RPT :
{
String className = "com.raytheon.edex.plugin.binlightning.impl.FlashLightningDecoder";
decoder = loadDecoderInstance(className, msgData, count);
break;
}
case RT_FLASH_RPT :
{
String className = "com.raytheon.edex.plugin.binlightning.impl.RTLightningDecoder";
decoder = loadDecoderInstance(className, msgData, count);
break;
}
case OTHER_RPT :
{
// The D2D decoders declare but do not define this message.
decoder = new LightningErrorDecoder(UNIMPLEMENTED_DECODER);
break;
}
case COMM_RPT :
{
// The D2D decoders declare but do not define this message.
decoder = new LightningErrorDecoder(UNIMPLEMENTED_DECODER);
break;
}
default :
{
decoder = new LightningErrorDecoder(UNKNOWN_MESSAGE_TYPE);
break;
}
}
return decoder;
}
private static IBinLightningDecoder loadDecoderInstance(String className, IBinDataSource msgData, int count) {
IBinLightningDecoder decoder = null;
try {
Class<?> clazz = BinLightningFactory.class.getClassLoader().loadClass(className);
Class<?>[] types = {IBinDataSource.class, Integer.TYPE};
Constructor<?> constructor = clazz.getConstructor(types);
Object[] parameters = {msgData, count};
decoder = (IBinLightningDecoder)constructor.newInstance(parameters);
logger.info("Loaded legacy binlightning decoder class " + className);
} catch (ClassNotFoundException | InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
logger.error("Fail to load binlightning decoder class " + className + ". FYI, this is error only if you are authorized: " + e.getMessage());
decoder = new LightningErrorDecoder(UNIMPLEMENTED_DECODER);
}
return decoder;
}
}

View file

@ -1,82 +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.edex.plugin.binlightning.impl;
/**
* Implementations of this interface are adapters between some data source and
* the using client code. Note that the idea of big/small endian data is not
* addressed in the interface. This matter is specific to the data and is an
* implementation detail.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 27 July 2007 411 jkorman Initial Development
* 20070912 379 jkorman Code review cleanup.
* 26 Sep 2014 3629 mapeters Moved from uf.edex.decodertools.core.
*
* </pre>
*
* @author jkorman
* @version 1
*/
public interface IBinDataSource {
/**
* Are there at least a specified number of bytes left in the data source?
*
* @param count
* Number of bytes to check for.
* @return
*/
public boolean available(int count);
/**
* Get a signed 8 bit value from the data source.
*
* @return A signed 8 bit value.
*/
public int getS8();
/**
* Get an unsigned 8 bit value from the data source.
*
* @return An unsigned 8 bit value.
*/
public int getU8();
/**
* Get an unsigned 16 bit value from the data source.
*
* @return An unsigned 16 bit value.
*/
public int getU16();
/**
* Get an unsigned 32 bit value from the data source.
*
* @return An unsigned 32 bit value.
*/
public long getU32();
}

View file

@ -1,75 +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.edex.plugin.binlightning.impl;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
/**
* Declare the interface for binary lightning decoding. The decoders are
* expected to implement an Iterable interface. Data decoding will take place
* during construction of the element.
*
* <pre>
* the recommended constructor for this interface is
*
* @param data An IBinDataSource data source containing the data to be decoded.
* @param count The number of records that this decoder should see.
* <code>public X (IBinDataSource data, int count)</code>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
* 20070912 379 jkorman Code review cleanup.
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public interface IBinLightningDecoder extends Iterable<LightningStrikePoint>
{
public static final int NO_ERROR = 0;
public static final int NO_TIME_INFO = 1;
public static final int NOT_ENOUGH_DATA = 2;
public static final int UNKNOWN_MESSAGE_TYPE = 98;
public static final int UNIMPLEMENTED_DECODER = 99;
public static final int FLASH_RPT = 0x96;
public static final int RT_FLASH_RPT = 0x97;
public static final int OTHER_RPT = 0xD0;
public static final int COMM_RPT = 0xD1;
public static final LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.CLOUD_TO_GROUND;
/*
*/
/**
* Get the last error for the instance.
* @return The error code.
*/
public int getError();
}

View file

@ -1,121 +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.edex.plugin.binlightning.impl;
import java.io.ByteArrayInputStream;
/**
* Wraps a ByteArrayInputStream with access methods specific to binary
* lightning data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class LightningDataSource implements IBinDataSource
{
private ByteArrayInputStream msgData = null;
/**
* Create this data source from supplied byte array data.
*
* @param data
*/
public LightningDataSource(byte[] data)
{
msgData = new ByteArrayInputStream(data);
}
/**
* Are there at least a given number of bytes available in the data source.
* @param A number of bytes to check for.
* @return Are the bytes available?
*/
public boolean available(int count)
{
return (msgData.available() >= count);
}
/**
* Get a signed 8 bit value from the data source. NOTE : This conversion is
* not twos-complement!
* @return A signed 8 bit value as an int.
*/
public int getS8()
{
int s8 = msgData.read();
int sign = (s8 & 0x80);
s8 = s8 & 0x7F;
if(sign > 0)
{
s8 = 0 - s8;
}
return s8;
}
/**
* Get a unsigned 8 bit value from the data source.
* @return An unsigned 8 bit value as an int.
*/
public int getU8()
{
int u8 = msgData.read();
return u8;
}
/**
* Get a unsigned 16 bit value from the data source.
* @return An unsigned 16 bit value as an int.
*/
public int getU16()
{
int u16 = msgData.read();
u16 |= (msgData.read() << 8);
return u16 & 0xFFFF;
}
/**
* Get a unsigned 32 bit value from the data source.
* @return An unsigned 32 bit value as a long.
*/
public long getU32()
{
long u32 = msgData.read();
u32 |= (msgData.read() << 8);
u32 |= (msgData.read() << 16);
u32 |= (msgData.read() << 24);
return u32 & 0xFFFFFFFFL;
}
}

View file

@ -1,96 +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.edex.plugin.binlightning.impl;
import java.util.Iterator;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
/**
* Mock decoder that is returned from the lightning decoder factory in the event
* that a proper decoder could not be constructed. Instances are created by passing
* various "permanent" error codes that will always be returned by the instance.
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20070810 379 jkorman Initial Coding from prototype.
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class LightningErrorDecoder implements IBinLightningDecoder
{
private final int errorCode;
/**
* Construct an instance of this decoder with a constant error code.
* @param errorCode The constant error code.
*/
public LightningErrorDecoder(int errorCode)
{
this.errorCode = errorCode;
}
/**
* Get the error code for this decoder.
* @return The error code.
*/
@Override
public int getError()
{
return errorCode;
}
/**
* This Iterator always returns, hasNext() = false, next = null.
* @return The "dummy" iterator for this class.
*/
@Override
public Iterator<LightningStrikePoint> iterator()
{
return new Iterator<LightningStrikePoint>()
{
@Override
public boolean hasNext()
{
return false;
}
@Override
public LightningStrikePoint next()
{
return null;
}
@Override
public void remove()
{
}
};
}
}

View file

@ -1,23 +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.
**/
/**
* Contains implementation classes for decoding binary lightning data.
*/
package com.raytheon.edex.plugin.binlightning.impl;

View file

@ -1,24 +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.
**/
/**
* Binary Lightning decoder plugin specific code. These classes interface
* between the edex plugin proxy and the implemented decoder layer.
*/
package com.raytheon.edex.plugin.binlightning;

View file

@ -1,184 +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.edex.plugin.binlightning.total;
import java.nio.ByteBuffer;
import com.raytheon.uf.common.numeric.UnsignedNumbers;
/**
* ByteBuffer wrapper that keeps track of checksums
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 03, 2014 3226 bclement Initial creation
* Jun 09, 2014 3226 bclement Added ByteBuffer constructor
* Jul 01, 2015 4581 skorolev Added condition in the getSum(int)
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class ChecksumByteBuffer {
private static final int SHORT_SIZE = Short.SIZE / Byte.SIZE;
private static final int INT_SIZE = Integer.SIZE / Byte.SIZE;
private static final int LONG_SIZE = Integer.SIZE / Byte.SIZE;
private final ByteBuffer buff;
private long totalSum;
private long packetSum;
/**
* @see ByteBuffer#wrap(byte[])
* @param data
*/
public ChecksumByteBuffer(byte[] data) {
this.buff = ByteBuffer.wrap(data);
}
/**
* @param buff
*/
public ChecksumByteBuffer(ByteBuffer buff) {
this.buff = buff;
}
/**
* get the sum of the next numberOfBytes worth of data
*
* @param numberOfBytes
* @return
*/
private long getSum(int numberOfBytes) {
int start = buff.position();
int end = start + numberOfBytes;
long rval = 0;
if (buff.remaining() < numberOfBytes) {
throw new IllegalArgumentException("Unable to get checksum for "
+ numberOfBytes + " bytes, only " + buff.remaining()
+ " bytes in buffer.");
}
for (int i = start; i < end; ++i) {
rval += UnsignedNumbers.ubyteToShort(buff.get(i));
}
return rval;
}
/**
* @see ByteBuffer#get()
* @return
*/
public byte get() {
byte rval = buff.get();
short unsignedRval = UnsignedNumbers.ubyteToShort(rval);
totalSum += unsignedRval;
packetSum += unsignedRval;
return rval;
}
/**
* @see ByteBuffer#getShort()
* @return
*/
public short getShort() {
long sum = getSum(SHORT_SIZE);
totalSum += sum;
packetSum += sum;
return buff.getShort();
}
/**
* @see ByteBuffer#getInt()
* @return
*/
public int getInt() {
long sum = getSum(INT_SIZE);
totalSum += sum;
packetSum += sum;
return buff.getInt();
}
/**
* @see ByteBuffer#getLong()
* @return
*/
public long getLong() {
long sum = getSum(LONG_SIZE);
totalSum += sum;
packetSum += sum;
return buff.getLong();
}
/**
* reset the current packet sum to zero
*/
public void resetPacketSum() {
packetSum = 0;
}
/**
* reset all sums to zero
*/
public void resetAllSums() {
resetPacketSum();
totalSum = 0;
}
/**
* @return the totalSum
*/
public long getTotalSum() {
return totalSum;
}
/**
* @return the packetSum
*/
public long getPacketSum() {
return packetSum;
}
/**
* @see ByteBuffer#limit()
* @return
*/
public int size() {
return buff.limit();
}
/**
* @see ByteBuffer#position()
* @return
*/
public int position() {
return buff.position();
}
}

View file

@ -1,377 +0,0 @@
package com.raytheon.edex.plugin.binlightning.total;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.raytheon.uf.common.wmo.WMOTimeParser;
/**
* The LightningWMOHeader extracts and parses the relevant WMO Header
* information for lightning data. This class is based on the WMOHeader class
* and has been created because the regular expression string for the WMO Header
* for lightning data and other data types are mutually exclusive.
*
* <pre>
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 07, 2016 DR18763 mgamazaychikov Initial creation.
* </pre>
*
* @author mgamazaychikov
* @version 1
*/
public class LightningWMOHeader {
public static final String LIGHTNING_WMO_HEADER = "[A-Z]{3}[A-Z0-9](?:\\d{0,2}|[A-Z]{0,2}) [A-Z0-9]{4} \\d{6}(?: [A-Z]{3})?[^\\r\\n]*[\\r]*[\\n]";
private static Pattern LIGHTNING_WMO_HEADER_PATTERN = Pattern
.compile(LIGHTNING_WMO_HEADER);
private static final int CCCCGROUP_SIZE = 4;
private static final int DTGROUP_SIZE = 6;
private String wmoHeader;
private char t1;
private char t2;
private char a1;
private char a2;
private int ii;
private String cccc = null;
private int headerYear = -1;
private int headerMonth = -1;
private int headerDay = -1;
private int headerHour = -1;
private int headerMinute = -1;
private String YYGGgg = null;
private String BBBIndicator = null;
private boolean isValid = false;
private int messageDataStart = -1;
private int wmoHeaderStart = -1;
private Calendar headerDate = null;
private String ttaaii = null;
private String originalMessage = null;
public LightningWMOHeader(byte[] bytes) {
this(bytes, null);
}
/**
* Construct the header from a wmo message.
*
* @param messageData
* @param fileName
*/
public LightningWMOHeader(byte[] messageData, String fileName) {
// Assume not valid until proven otherwise!
isValid = false;
if (messageData != null) {
originalMessage = new String(messageData);
Matcher m = LIGHTNING_WMO_HEADER_PATTERN.matcher(originalMessage); // handles
// the skip
// ccb
if (m.find()) {
wmoHeaderStart = m.start();
messageDataStart = m.end();
wmoHeader = originalMessage.substring(m.start(), m.end())
.trim();
int hdrIndex = 0;
t1 = wmoHeader.charAt(hdrIndex++);
t2 = wmoHeader.charAt(hdrIndex++);
a1 = wmoHeader.charAt(hdrIndex++);
a2 = wmoHeader.charAt(hdrIndex++);
char t = wmoHeader.charAt(hdrIndex++);
int tt = 0;
int iiChars = 0;
// Get the ii part. The standard says there must be two digits,
// however some data contain 0 or 1 digits.
while (t != ' ') {
tt *= 10;
tt += (t - '0');
iiChars++;
t = wmoHeader.charAt(hdrIndex++);
}
if (iiChars > 0) {
ii = tt;
} else {
ii = -1;
}
t = wmoHeader.charAt(hdrIndex);
while (t == ' ') {
t = wmoHeader.charAt(hdrIndex++);
if (t != ' ') {
hdrIndex--;
}
}
cccc = wmoHeader.substring(hdrIndex, hdrIndex + CCCCGROUP_SIZE);
hdrIndex += CCCCGROUP_SIZE;
t = wmoHeader.charAt(hdrIndex);
while (t == ' ') {
t = wmoHeader.charAt(hdrIndex++);
if (t != ' ') {
hdrIndex--;
}
}
YYGGgg = wmoHeader.substring(hdrIndex, hdrIndex + DTGROUP_SIZE);
parseDateTime(YYGGgg);
headerDate = WMOTimeParser.findDataTime(YYGGgg, fileName);
// At this point headerDate will either be the current time (non-archive) or
// a time generated from the WMOHeader and filename dateStamp
headerYear = headerDate.get(Calendar.YEAR);
headerMonth = headerDate.get(Calendar.MONTH) + 1;
headerDay = headerDate.get(Calendar.DAY_OF_MONTH);
headerHour = headerDate.get(Calendar.HOUR_OF_DAY);
headerMinute = headerDate.get(Calendar.MINUTE);
hdrIndex += DTGROUP_SIZE;
// Everything else goes here for now. Leave it to the client to
// perform any BBB validation.
BBBIndicator = wmoHeader.substring(hdrIndex).trim();
isValid = true;
}
}
}
public String getOriginalMessage() {
return originalMessage;
}
/**
* Get the extracted wmo header text. Does not return the trailing carriage
* control on the header line.
*
* @return The extracted wmo header.
*/
public String getWmoHeader() {
return wmoHeader;
}
/**
* Get the T1 character.
*
* @return The T1 character.
*/
public char getT1() {
return t1;
}
/**
* Get the T2 character.
*
* @return The T2 character.
*/
public char getT2() {
return t2;
}
/**
* Get the A1 character.
*
* @return The A1 character.
*/
public char getA1() {
return a1;
}
/**
* Get the A2 character.
*
* @return The A2 character.
*/
public char getA2() {
return a2;
}
/**
* Get the ii part. If ii is not defined in the header, a value of -1 is
* returned.
*
* @return The ii part.
*/
public int getIi() {
return ii;
}
/**
* Get the sender CCCC identifier.
*
* @return The sender CCCC identifier.
*/
public String getCccc() {
return cccc;
}
/**
* @return the year YYYY
*/
public int getYear() {
return headerYear;
}
/**
* @return the month [1-12]
*/
public int getMonth() {
return headerMonth;
}
/**
* Get the day part of the header datetime.
*
* @return The day part of the header datetime.
*/
public int getDay() {
return headerDay;
}
/**
* Get the hour part of the header datetime.
*
* @return The hour part of the header datetime.
*/
public int getHour() {
return headerHour;
}
/**
* Get the minute part of the header datetime.
*
* @return The minute part of the header datetime.
*/
public int getMinute() {
return headerMinute;
}
/**
* Get the header datetime as a string.
*
* @return The header datetime information.
*/
public String getYYGGgg() {
return YYGGgg;
}
/**
* Get the BBB information. If the header does not contain BBB information
* then a null reference is returned.
*
* @return The BBB information.
*/
public String getBBBIndicator() {
return BBBIndicator;
}
/**
* Is the WMO header information valid.
*
* @return Is the WMO header information valid.
*/
public boolean isValid() {
return isValid;
}
/**
* Get the starting position of the header within the message. This position
* is the position of the first character of the WMO header.
*
* @return The message start position.
*/
public int getWmoHeaderStart() {
return wmoHeaderStart;
}
/**
* Get the starting position of the data within the message. This position
* is the position of the next character after the end of the WMO header.
*
* @return The message start position.
*/
public int getMessageDataStart() {
return messageDataStart;
}
/**
* @return the headerDate
*/
public Calendar getHeaderDate() {
return headerDate;
}
/**
*
* @return
*/
public String getTtaaii() {
if (ttaaii == null && isValid()) {
StringBuilder sb = new StringBuilder();
sb.append(wmoHeader.substring(0, 6));
int spcIndex = sb.indexOf(" ");
if (spcIndex >= 0 && spcIndex + 1 < sb.length()) {
sb.delete(spcIndex + 1, sb.length());
}
while (sb.length() < 6) {
sb.append(" ");
}
ttaaii = sb.toString();
}
return ttaaii;
}
/**
* Get the string representation of this WMO header.
*
* @return The string representation of this WMO header.
*/
public String toString() {
return wmoHeader;
}
/**
* Parse the header date time information. If any part of the YYGGgg group
* is in error, then all date elements are set to -1;
*
* @param ddhhmm
* The YYGGgg group extracted from the header.
*/
private void parseDateTime(String ddhhmm) {
try {
headerDay = Integer.parseInt(ddhhmm.substring(0, 2));
headerHour = Integer.parseInt(ddhhmm.substring(2, 4));
headerMinute = Integer.parseInt(ddhhmm.substring(4));
} catch (Exception nfe) {
// any failure in the parse above invalidates the entire date info.
headerDay = -1;
headerHour = -1;
headerMinute = -1;
}
}
}

View file

@ -1,472 +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.edex.plugin.binlightning.total;
import gov.noaa.nws.ost.edex.plugin.binlightning.DecryptedLightningValidator;
import gov.noaa.nws.ost.edex.plugin.binlightning.EncryptedBinLightningCipher;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.raytheon.edex.esb.Headers;
import com.raytheon.edex.exception.DecoderException;
import com.raytheon.edex.plugin.binlightning.BinLightningDecoder;
import com.raytheon.edex.plugin.binlightning.filter.LightningGeoFilter;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
import com.raytheon.uf.common.dataplugin.binlightning.impl.BaseLightningPoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningPulsePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgPulseType;
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
import com.raytheon.uf.common.numeric.UnsignedNumbers;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.wmo.WMOHeader;
import com.raytheon.uf.common.wmo.WMOTimeParser;
/**
* Decoder for Earth Networks Total Lightning data
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 30, 2014 3226 bclement Initial creation
* Jun 09, 2014 3226 bclement added encryption support
* Jun 10, 2014 3226 bclement added filter support
* Jun 19, 2014 3226 bclement added validator callback
* Jul 07, 2015 4581 skorolev Corrected decodeStrikes to avoid BufferUnderflowException.
* Apr 07, 2016 DR18763 mgamazaychikov Switched to using LightningWMOHeader.
* Apr 21, 2016 DR18849 mgamazaychikov Decrypt all data in decrypt method.
* May 02, 2016 18336 amoore Keep-alive messages should update the legend.
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class TotalLightningDecoder {
// flash types
public static final byte CLOUD_TO_GROUND_TYPE = 0x00;
public static final byte CLOUD_TO_CLOUD_TYPE = 0x01;
// pulse types
public static final byte RETURN_STROKE_TYPE = 0x00;
public static final byte NON_RETURN_STROKE_TYPE = 0x01;
public static final byte KEEP_ALIVE_TYPE = 0x09;
// conversions
public static final double LONLAT_SCALE_FACTOR = 0.0000001;
public static final double AMPS_PER_KILO_AMP = 1000.0;
public static final double METERS_PER_KILOMETER = 1000.0;
// constant metadata
public static final String DATA_SOURCE = "ENTLN";
/* in bytes, header is total size of flash and pulses */
private static final int COMBINATION_PACKET_HEADER_SIZE = 2;
/* in bytes, doesn't include checksum */
private static final int FLASH_PACKET_SIZE = 25;
private static final IUFStatusHandler log = UFStatus
.getHandler(TotalLightningDecoder.class);
private static final EncryptedBinLightningCipher CIPHER = new EncryptedBinLightningCipher();
public static final String TOTAL_LIGHTNING_KEYSTORE_PREFIX = "total.lightning";
private static final DecryptedLightningValidator validator = new DecryptedLightningValidator() {
@Override
public boolean isValid(byte[] data) {
return validFlashPacket(data, COMBINATION_PACKET_HEADER_SIZE);
}
};
private static final int SHORT_SIZE = 2;
/**
* Parse total lightning data into BinLightningRecords
*
* @param data
* @param headers
* @return
*/
public PluginDataObject[] decode(byte[] data, Headers headers) {
PluginDataObject[] rval;
LightningWMOHeader wmoHdr = new LightningWMOHeader(data);
String fileName = (String) headers.get(WMOHeader.INGEST_FILE_NAME);
if (wmoHdr.isValid()) {
byte[] pdata = BinLightningDecoder.extractPData(wmoHdr, data);
if (pdata != null) {
try {
rval = decodeInternal(wmoHdr, fileName, pdata);
} catch (Exception e) {
error(e, headers, wmoHdr);
rval = new PluginDataObject[0];
}
} else {
warn("Unable to separate data from headers", fileName, wmoHdr);
rval = new PluginDataObject[0];
}
} else {
warn("Invalid WMO header", fileName, wmoHdr);
rval = new PluginDataObject[0];
}
return rval;
}
/**
* @param data
* @param startIndex
* starting index of flash packet (not combination packet)
* @return true if there if a valid flash packet in data starting at index
*/
private static boolean validFlashPacket(byte[] data, int startIndex) {
/* plus one to include packet checksum */
final int packetWithChecksum = FLASH_PACKET_SIZE + 1;
if (data.length < startIndex + packetWithChecksum) {
return false;
}
ChecksumByteBuffer buff = new ChecksumByteBuffer(ByteBuffer.wrap(data,
startIndex, packetWithChecksum));
for (int i = 0; i < FLASH_PACKET_SIZE; ++i) {
/* build up sum in buffer */
buff.get();
}
return passesCheckSum(buff, false);
}
/**
* Display warning message with file and header names
*
* @param msg
* @param fileName
* @param wmoHdr
*/
private void warn(String msg, String fileName, LightningWMOHeader wmoHdr) {
log.warn(msg + ". File: " + fileName + ", WMO Header: " + wmoHdr);
}
/**
* Display error message with file and header names
*
* @param e
* @param headers
* @param wmoHdr
*/
private void error(Exception e, Headers headers, LightningWMOHeader wmoHdr) {
String fileName = (String) headers.get(WMOHeader.INGEST_FILE_NAME);
log.error(e.getLocalizedMessage() + ". File: " + fileName
+ ", WMO Header: " + wmoHdr, e);
}
/**
* @param wmoHdr
* @param fileName
* @param pdata
* data after WMO header is removed
* @return
* @throws DecoderException
*/
private PluginDataObject[] decodeInternal(LightningWMOHeader wmoHdr,
String fileName, byte[] pdata) throws DecoderException {
byte[] pdataPreDecrypt = pdata;
// determine if the data is encrypted or not based on comparing
// checksums for flash packet
pdata = decrypt(wmoHdr, fileName, pdata);
boolean isDecryptedValid = validFlashPacket(pdata,
COMBINATION_PACKET_HEADER_SIZE);
boolean isPreDecryptedValid = validFlashPacket(pdataPreDecrypt,
COMBINATION_PACKET_HEADER_SIZE);
// assume that all data is encrypted, so decrypt it
if (!isDecryptedValid && isPreDecryptedValid) {
// this means that data is not encrypted, proceed without
// decryption
pdata = pdataPreDecrypt;
}
List<LightningStrikePoint> strikes = decodeStrikes(fileName, pdata);
BinLightningRecord record;
if (!strikes.isEmpty()) {
record = LightningGeoFilter.createFilteredRecord(strikes);
} else {
// keep-alive record
Calendar baseTime = WMOTimeParser.findDataTime(wmoHdr.getYYGGgg(),
fileName);
record = new BinLightningRecord(baseTime, DATA_SOURCE);
}
return new PluginDataObject[] { record };
}
/**
* @param wmoHdr
* @param fileName
* @param pdata
* @return
* @throws DecoderException
*/
private byte[] decrypt(LightningWMOHeader wmoHdr, String fileName,
byte[] pdata) throws DecoderException {
Calendar baseTime = WMOTimeParser.findDataTime(wmoHdr.getYYGGgg(),
fileName);
pdata = EncryptedBinLightningCipher.prepDataForDecryption(pdata,
fileName);
try {
return CIPHER.decryptData(pdata, baseTime.getTime(),
TOTAL_LIGHTNING_KEYSTORE_PREFIX, validator);
} catch (Exception e) {
throw new DecoderException("Problem decrypting total lightning", e);
}
}
/**
* Extract strike data from raw binary, ignoring keep-alive strikes.
*
* @param fileName
* @param pdata
* @return list of lightning strike points, ignoring keep-alive strikes.
* @throws DecoderException
*/
private List<LightningStrikePoint> decodeStrikes(String fileName,
byte[] pdata) throws DecoderException {
List<LightningStrikePoint> rval = new ArrayList<LightningStrikePoint>();
ChecksumByteBuffer buff = new ChecksumByteBuffer(pdata);
while (buff.position() < buff.size()) {
int startingPostion = buff.position();
int totalBytes = 0;
if ((buff.size() - startingPostion) >= SHORT_SIZE) {
totalBytes = UnsignedNumbers.ushortToInt(buff.getShort());
if (totalBytes > (buff.size() - startingPostion)) {
if (validFlashPacket(pdata, buff.position())) {
log.error("Truncated total lightning packet in file: "
+ fileName);
} else {
int extra = buff.size() - startingPostion;
log.warn("Extra data at end of lightning packets: "
+ extra + " bytes");
}
break;
}
} else {
log.warn("Extra data at end of lightning packets: 1 byte");
break;
}
/* start flash packet */
buff.resetPacketSum();
/* discard flash packet size byte */
buff.get();
LtgStrikeType flashType = getStrikeType(buff.get());
LightningStrikePoint strike = new LightningStrikePoint(null,
LtgMsgType.TOTAL_LIGHTNING);
strike.setLightSource(DATA_SOURCE);
strike.setType(flashType);
decodeCommonFields(strike, buff);
int pulseCount = UnsignedNumbers.ubyteToShort(buff.get());
strike.setPulseCount(pulseCount);
ensureCheckSum(buff, false);
List<LightningPulsePoint> pulses = new ArrayList<LightningPulsePoint>(
pulseCount);
for (int i = 0; i < pulseCount; ++i) {
/* discard size of pulse packet (always 26) */
buff.get();
LtgPulseType pulseType = getPulseType(buff.get());
LightningPulsePoint pulse = new LightningPulsePoint(null,
pulseType);
decodeCommonFields(pulse, buff);
/* discard pulse count (already set in strike) */
buff.get();
ensureCheckSum(buff, false);
pulses.add(pulse);
}
strike.setPulses(pulses);
ensureCheckSum(buff, true);
if (strike.getType() != LtgStrikeType.KEEP_ALIVE) {
rval.add(strike);
}
}
return rval;
}
/**
* Extract fields common to both strikes and pulses
*
* @param point
* @param buff
*/
private static void decodeCommonFields(BaseLightningPoint point,
ChecksumByteBuffer buff) {
point.setTime(getTime(buff));
point.setLatitude(getDouble(buff, LONLAT_SCALE_FACTOR));
point.setLongitude(getDouble(buff, LONLAT_SCALE_FACTOR));
point.setStrikeStrength(getKiloAmps(buff.getInt()));
/* discard reserved byte */
buff.get();
point.setElevation(getMeters(buff.getShort()));
point.setSensorCount(UnsignedNumbers.ubyteToShort(buff.get()));
}
/**
* Create calendar from 4 byte UNIX time and 2 byte millisecond addition
*
* @param buff
* @return
*/
private static Calendar getTime(ChecksumByteBuffer buff) {
long unixTime = UnsignedNumbers.uintToLong(buff.getInt());
int additionalMillis = UnsignedNumbers.ushortToInt(buff.getShort());
long totalMillis = (unixTime * TimeUtil.MILLIS_PER_SECOND)
+ additionalMillis;
return TimeUtil.newGmtCalendar(new Date(totalMillis));
}
/**
* @see #passesCheckSum(ChecksumByteBuffer, boolean)
* @param buff
* @param total
* @throws DecoderException
*/
private static void ensureCheckSum(ChecksumByteBuffer buff, boolean total)
throws DecoderException {
if (!passesCheckSum(buff, total)) {
throw new DecoderException("Checksum failed");
}
}
/**
* Ensure data integrity, resets appropriate sum(s) in buffer after check
*
* @param buff
* @param total
* true if total sum should be checked, otherwise checks packet
* sum
* @return true if checksum passes
*/
private static boolean passesCheckSum(ChecksumByteBuffer buff, boolean total) {
long rawsum = total ? buff.getTotalSum() : buff.getPacketSum();
/* convert to overflowed unsigned byte */
rawsum &= 0xFF;
/* checksum algorithm from total lightning spec */
long mungedSum = (256 - rawsum) & 0xFF;
/* get expected after sum so it is not reflected in sum */
long expected = UnsignedNumbers.ubyteToShort(buff.get());
boolean rval = mungedSum == expected;
if (!rval) {
log.debug("Checksum failed: expected " + expected + " got "
+ mungedSum);
}
if (total) {
buff.resetAllSums();
} else {
buff.resetPacketSum();
}
return rval;
}
/**
* Get scaled double from 4 byte integer field
*
* @param buff
* @param scaleFactor
* @return
*/
private static double getDouble(ChecksumByteBuffer buff, double scaleFactor) {
int raw = buff.getInt();
return raw * scaleFactor;
}
/**
* Convert amps to kiloamps
*
* @param amps
* @return
*/
private static double getKiloAmps(int amps) {
return amps / AMPS_PER_KILO_AMP;
}
/**
* Convert kilometers to meters
*
* @param kilometers
* @return
*/
private static double getMeters(short kilometers) {
return kilometers * METERS_PER_KILOMETER;
}
/**
* Map strike byte to internal enum
*
* @param type
* @return
* @throws DecoderException
*/
public static LtgStrikeType getStrikeType(byte type)
throws DecoderException {
switch (type) {
case CLOUD_TO_GROUND_TYPE:
return LtgStrikeType.CLOUD_TO_GROUND;
case CLOUD_TO_CLOUD_TYPE:
return LtgStrikeType.CLOUD_TO_CLOUD;
case KEEP_ALIVE_TYPE:
return LtgStrikeType.KEEP_ALIVE;
}
throw new DecoderException("Unknown flash type: " + type);
}
/**
* Map pulse byte to internal enum
*
* @param type
* @return
* @throws DecoderException
*/
public static LtgPulseType getPulseType(byte type) throws DecoderException {
switch (type) {
case RETURN_STROKE_TYPE:
return LtgPulseType.RETURN_STROKE;
case NON_RETURN_STROKE_TYPE:
return LtgPulseType.NON_RETURN_STROKE;
case KEEP_ALIVE_TYPE:
return LtgPulseType.KEEP_ALIVE;
}
throw new DecoderException("Unknown pulse type: " + type);
}
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<purgeRuleSet>
<defaultRule>
<versionsToKeep>36</versionsToKeep>
<delta>=00-01:00:00</delta>
<round>00-01:00:00</round>
</defaultRule>
</purgeRuleSet>

View file

@ -1,15 +0,0 @@
<!-- example binlightning geospatial filter file
name of file corresponds to data source (eg NLDN.xml)
data is persisted if lightning strike point is in any of the filter areas
if a data source does not have any filters, all data is persisted -->
<filters>
<!-- bounding box filter: x is degrees longitude, y is degrees latitude-->
<bbox minx="-98.23" maxx="-97.24" miny="38.27" maxy="39.39" />
<!-- CWA filters: correspond to polygons defining the county warning areas -->
<cwa>OAX</cwa>
<cwa>DMX</cwa>
<cwa>FSD</cwa>
<!-- well known text geometries: x coordinates are longitude, y coordinates are latitude
first coordinate is always the same as last to close the polygon region -->
<wkt>POLYGON ((-101.24 41.4, -100.6 41.15, -101.01 40.75, -101.24 41.4))</wkt>
</filters>

View file

@ -1,24 +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.
-->
<requestPatterns xmlns:ns2="group">
<regex>^SFUS41 KWBC.*</regex>
<regex>^SFPA4[12] KWBC.*</regex>
</requestPatterns>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.edex.binlightning.feature</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.pde.FeatureBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.FeatureNature</nature>
</natures>
</projectDescription>

View file

@ -1 +0,0 @@
bin.includes = feature.xml

View file

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="com.raytheon.uf.edex.binlightning.feature"
label="EDEX Binlightning Feature"
version="1.0.0.qualifier"
provider-name="RAYTHEON">
<description url="http://www.example.com/description">
[Enter Feature Description here.]
</description>
<copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.]
</copyright>
<license url="http://www.example.com/license">
[Enter License Description here.]
</license>
<plugin
id="com.raytheon.edex.plugin.binlightning"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="gov.noaa.nws.ost.edex.plugin.binlightning"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.edex.plugin.binlightning.legacy"
download-size="0"
install-size="0"
version="0.0.0"
fragment="true"
unpack="false"/>
</feature>

View file

@ -134,24 +134,24 @@ FNEXRAD ^rad/NEXRCOMP/(...)/(...)_(........)_(....)
NEXRAD3 ^SDUS[23578]. .... (......) /p(DHR|DPR|DSP|DTA|DAA|DVL|EET|HHC|N0Q|N0S|N0U|OHA)(...)
FILE -overwrite -close -edex /awips2/data_store/radar/\3/\2/\3_\2_\1_(seq).rad
##
## ACARS
## ACARS (restricted to NWS use only)
##
# AWIPS1: POINT ^IUAX0[12].* /ispan/bufr/acars
# IUAX02 KARP 022359
ANY ^(IUAX0[12]) (....) (..)(..)(..)
FILE -overwrite -log -close
/awips2/data_store/acars/acars_encrypted/\1_\2_\3\4\5_(seq).acars.%Y%m%d%H
ANY ^(IUAX0[12]) (....) (..)(..)(..)
PIPE -close /awips2/ldm/decoders/decrypt_file
/awips2/data_store/acars/acars_decrypted/\1_\2_\3\4\5_(seq).acars.%Y%m%d%H
EXP ^/awips2/data_store/acars/acars_decrypted/(.*)
FILE -overwrite -log -close -edex
/awips2/data_store/acars/acars_decrypted/\1
#ANY ^(IUAX0[12]) (....) (..)(..)(..)
# FILE -overwrite -log -close
# /awips2/data_store/acars/acars_encrypted/\1_\2_\3\4\5_(seq).acars.%Y%m%d%H
#ANY ^(IUAX0[12]) (....) (..)(..)(..)
# PIPE -close /awips2/ldm/decoders/decrypt_file
# /awips2/data_store/acars/acars_decrypted/\1_\2_\3\4\5_(seq).acars.%Y%m%d%H
#EXP ^/awips2/data_store/acars/acars_decrypted/(.*)
# FILE -overwrite -log -close -edex
# /awips2/data_store/acars/acars_decrypted/\1
# Need to make sure that IUAK and IUAX are disallowed.
# IUAK are Alaskan profilers and IUAX has encrypted ACARS handled above!
ANY ^(IUA[^XK]0[12]) (....) (..)(..)(..)
FILE -overwrite -close -edex
/awips2/data_store/acars/acars_raw_decrypted/\1_\2_\3\4\5_(seq).bufr.%Y%m%d%H
#ANY ^(IUA[^XK]0[12]) (....) (..)(..)(..)
# FILE -overwrite -close -edex
# /awips2/data_store/acars/acars_raw_decrypted/\1_\2_\3\4\5_(seq).bufr.%Y%m%d%H
# modelSoundings
HDS ^(JUS[ABX]4[1-9]) (KW(NO|BC)) (..)(..)(..)
FILE -overwrite -close -edex /awips2/data_store/modelsounding/\1_\2_\4\5\6_(seq).bufr.%Y%m%d%H
@ -891,10 +891,9 @@ HDS ^HAXA00 KWBC ......[^!]*!grib.*/[^/]*/[^/]*/#[^/]*/([0-9]{8})([0-9]{4})/(F[0
#
# National Digital Forecast Database (NDFD)
#
# data2/ndfd/YBUZ98_KWBN_081451.grib2 !grib2/nwstg/NWS_0/#000/201603081500F012/DRCT/0 - NONE! 000011
#CONDUIT grib2/nwstg/NWS_0/..../(........)(....)(F...)/(.*)/.*! (......)
# FILE -edex -log
# /awips2/data_store/grid/NDFD/NDFD_\1\2\3_\4-\5.grib2
CONDUIT grib2/nwstg/NWS_0/..../(........)(....)(F.....)/(.*)/.*! (......)
FILE -edex -log
/awips2/data_store/grid/NDFD/NDFD_\1\2\3_\4-\5.grib2
#
# NDFD WPC Quantitative Precipitation Forecast (HPCqpfNDFD)
#
@ -924,14 +923,6 @@ HDS ^H..... ECM. ......[^!]*!grib.*/[^/]*/[^/]*/#([^/]*)/([0-9]{8})([0-9]{4})/(F
FILE -edex -log
/awips2/data_store/grid/ECMWF/ECMWF-\1_\2_\3_\4_\5-(seq).grib
#
# ECMWF HiRes
#
#HDS ^([LM].Z.{1,3}) KWBX (..)(..)(..)
# PIPE -close /awips2/ldm/decoders/decrypt_file
# /awips2/data_store/grid/ECMWF_HiRes/ecmwf_decrypted_\1_KWBX_\2\3\4-(seq).grib2
#EXP (.*ecmwf_decrypted.*)
# FILE -edex -log \1
#
# ---------------------------------------------------
# - National Precipitation Verification Unit (NPVU) -
# ---------------------------------------------------