Issue #1780 Changes for obtaining AvnFPS monitor's grid data for all sites in one call to the server.

Code review changes 3.

Change-Id: I0cc7be0e219ab7874fa1a7f4cd8847d07e02724c

Former-commit-id: 70bd9aafa7 [formerly 4deb731bd0] [formerly b421c97d86 [formerly 225cb945e2008a56de323c7c01591ae27b3fd381]]
Former-commit-id: b421c97d86
Former-commit-id: 334f2c4a57
This commit is contained in:
Roger Ferrel 2013-03-06 15:53:16 -06:00
parent be87f2adc3
commit 0deb290c24
13 changed files with 797 additions and 196 deletions

View file

@ -1,19 +1,19 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
@ -140,10 +140,20 @@
# Relationship Type: In Response to
# Status: TEST
# Title: AvnFPS: Lack of customization in QC check
#
#
#**
#*
#*
#* <pre>
#* SOFTWARE HISTORY
#* Date Ticket# Engineer Description
#* ------------ ---------- ----------- --------------------------
#* Initial creation.
#* Mar 07, 2013 1735 rferrel Changes to obtain grid data for a list of sites.
##
#
import logging, os, time, ConfigParser, sys
import Avn, AvnLib, AvnParser
import logging, os, time, ConfigParser
import Avn, AvnLib, AvnParser, JUtil, cPickle
import PointDataView, GfeValues
_Missing = ''
@ -443,8 +453,11 @@ def _readPrbConf():
prb_conf['after9hr'][wx] = conf.getint('after9hr',wx)
return prb_conf
def makeData(siteID, timeSeconds):
def makeData(siteID, timeSeconds):
data = retrieveData(siteID, timeSeconds)
return formatData(siteID, timeSeconds, data)
def formatData(siteID, timeSeconds, data):
if data is None or data['issuetime'] < time.time() - 86400:
msg = 'Grid data is not available'
_Logger.info(msg)
@ -491,42 +504,51 @@ def makeTable(siteID, timeSeconds):
msg = 'Grid data for %s is not available', siteID
raise Avn.AvnError(msg)
def retrieveData(siteID, timeSeconds, parameters=Parameters):
results = _retrieveMapData([siteID], timeSeconds, parameters)
return results[siteID]
def retrieveData(siteID, timeSeconds):
def retrieveMapData(siteIDs, timeSeconds, parameters=Parameters):
r = _retrieveMapData(siteIDs, timeSeconds, parameters=Parameters)
results = {}
for siteID in siteIDs:
results[siteID] = cPickle.dumps(r[siteID])
return JUtil.pyDictToJavaMap(results)
def _retrieveMapData(siteIDs, timeSeconds, parameters=Parameters):
import JUtil
from com.raytheon.uf.common.dataplugin.gfe.request import GetPointDataRequest
from com.vividsolutions.jts.geom import Coordinate
from com.raytheon.viz.aviation.guidance import GuidanceUtil
from com.raytheon.uf.viz.core.localization import LocalizationManager
#timerStart = time.clock()
#print 'GridData retrieveData, siteID %s, timeSeconds %d' % (siteID, timeSeconds)
config = AvnParser.getTafSiteCfg(siteID)
lat = config['geography']['lat']
lon = config['geography']['lon']
gfeSiteId = LocalizationManager.getInstance().getCurrentSite()
#print '\tgfeSiteId: %s, lat %s, lon %s' % (gfeSiteId, lat, lon)
task = GetPointDataRequest()
task.setSiteID(gfeSiteId);
c = Coordinate(float(lon), float(lat))
task.setCoordinate(c)
task.setNumberHours(_NumHours)
task.setStartTime(long(timeSeconds * 1000))
for p in Parameters:
task.addParameter(p)
db = gfeSiteId + '_GRID__Official_00000000_0000'
task.setDatabaseID(db)
pdc = GuidanceUtil.getGFEPointData(task)
data = _getData(pdc, timeSeconds * 1000)
#print '\tdata: ', data
#timerEnd = time.clock()
#print '\ttime: ', timerEnd - timerStart
if data is None :
_Logger.info('Data not available for %s', siteID)
#sys.stdout.flush()
return data
for siteID in siteIDs:
config = AvnParser.getTafSiteCfg(siteID)
lat = config['geography']['lat']
lon = config['geography']['lon']
c = Coordinate(float(lon), float(lat))
task.addCoordinate(c)
task.setNumberHours(_NumHours)
task.setStartTime(long(timeSeconds * 1000))
for p in parameters:
task.addParameter(p)
pdcs = GuidanceUtil.getGFEPointsData(task)
i = 0
results = {}
for siteID in siteIDs:
pdc = pdcs.getContainer(i)
if i < pdcs.getSize() :
++i
data = _getData(pdc, timeSeconds * 1000)
if data is None:
_Logger.info('Data not available for %s', siteID)
results[siteID] = data
return results
###############################################################################
if __name__ == '__main__':

View file

@ -1,19 +1,19 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
@ -125,10 +125,20 @@
# IFPS grids monitoring module
# Author: George Trojan, SAIC/MDL, August 2003
# last update: 04/20/06
#**
#*
#*
#* <pre>
#* SOFTWARE HISTORY
#* Date Ticket# Engineer Description
#* ------------ ---------- ----------- --------------------------
#* Initial creation.
#* Mar 07, 2013 1735 rferrel Use SiteGridManger to limit calls to server.
##
import logging, time
import Avn, AvnLib, Globals, GridData, MonitorP, TafDecoder, TafGen
import logging, time, cPickle
import Avn, AvnLib, Globals, GridData, MonitorP, TafDecoder, TafGen, JUtil
from com.raytheon.viz.aviation.monitor import SiteGridManager
_Logger = logging.getLogger(Avn.CATEGORY)
##############################################################################
@ -142,7 +152,21 @@ class Monitor(MonitorP.Monitor):
def __makeData(self, t):
try:
data = GridData.makeData(self.info['ident'], t)
siteID = self.info['ident']
timeSeconds = long(t)
if SiteGridManager.needData(timeSeconds) :
siteIDs = JUtil.javaStringListToPylist(SiteGridManager.getSiteIDs())
containersMap = GridData.retrieveMapData(siteIDs, timeSeconds)
SiteGridManager.setContainersMap(containersMap)
return None
o = SiteGridManager.getData(siteID, timeSeconds)
if o is None :
return None
ndata = cPickle.loads(o)
data = GridData.formatData(siteID, timeSeconds, ndata)
bbb = 'RRA'
tc=TafGen.TafGen('grid',data,bbb)
taf=tc.createTaf(False)

View file

@ -23,7 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainer;
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainers;
import com.raytheon.uf.common.dataplugin.gfe.request.GetPointDataRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.dataplugin.obs.metar.MetarRecord;
@ -36,7 +36,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.requests.ThriftClient;
/**
* TODO Add Description
* Static utility methods for use with python code.
*
* <pre>
*
@ -44,6 +44,7 @@ import com.raytheon.uf.viz.core.requests.ThriftClient;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 29, 2009 njensen Initial creation
* Mar 11, 2013 1735 rferrel Get a list of GFE Point Data Containers
*
* </pre>
*
@ -85,17 +86,17 @@ public class GuidanceUtil {
}
/**
* Get the GFE Point Data information for the task request.
* Get a list of GFE Point Data information for the task request.
*
* @param task
* @return gfePointDataContainer
* @return gfePointDataContainers
* @throws VizException
*/
@SuppressWarnings("unchecked")
public static GFEPointDataContainer getGFEPointData(GetPointDataRequest task)
throws VizException {
public static GFEPointDataContainers getGFEPointsData(
GetPointDataRequest task) throws VizException {
task.setWorkstationID(VizApp.getWsId());
ServerResponse<GFEPointDataContainer> sr = (ServerResponse<GFEPointDataContainer>) ThriftClient
ServerResponse<GFEPointDataContainers> sr = (ServerResponse<GFEPointDataContainers>) ThriftClient
.sendRequest(task);
return sr.getPayload();
}

View file

@ -59,7 +59,7 @@ import com.raytheon.viz.aviation.monitor.AvnPyUtil;
* Apr 14, 2011 8065 rferrel Implemented enqueue to place
* Alerts at the front of the queue
* and work with data caching.
* Nov 28, 2012 1363 rferrel No longer add a dispose listner so the
* Nov 28, 2012 1363 rferrel No longer add a dispose listener so the
* creation of instance can be done on
* any thread.
*

View file

@ -0,0 +1,44 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.aviation.monitor;
/**
* A listener interface for notifying clients when grid data retrieved.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 6, 2013 1735 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public interface IGridDataRetrieveListener {
/**
* Use by SiteGridManger to notify when grid data is available.
*/
public void gridDataRetrieved();
}

View file

@ -41,7 +41,6 @@ import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.jobs.AbstractQueueJob;
import com.raytheon.uf.viz.core.jobs.IRequestCompleteListener;
import com.raytheon.viz.aviation.activator.Activator;
import com.raytheon.viz.aviation.guidance.PythonGuidanceJob;
/**
* A job that performs the monitoring/rules compare within python. A FIFO queue
@ -57,7 +56,8 @@ import com.raytheon.viz.aviation.guidance.PythonGuidanceJob;
* ------------ ---------- ----------- --------------------------
* Sep 3, 2009 njensen Initial creation
* Sep 27,2010 6185 rferrel Allow multiple jobs off a static queue.
* May 13,2011 8611 rferrel Adde request's type to the results
* May 13,2011 8611 rferrel Added request's type to the results
* Mar 06, 2013 1735 rferrel Have python reference proper class.
*
* </pre>
*
@ -91,7 +91,7 @@ public class PythonMonitorJob extends AbstractQueueJob<MonitorRequest> {
.getPath(), AvnPyUtil.getLoggingHandlerDir(), AvnPyUtil
.getPointDataDir(), AvnPyUtil.getCommonPythonDir());
python = new PythonScript(filePath, includePath,
PythonGuidanceJob.class.getClassLoader());
PythonMonitorJob.class.getClassLoader());
}
/**

View file

@ -0,0 +1,230 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.aviation.monitor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* This class coordinates getting the Grid data for the sites being monitored by
* AvnFPS.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 6, 2013 1735 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class SiteGridManager {
/** Singleton instance of class used for synchronization. */
private static final SiteGridManager instance = new SiteGridManager();
/** Time out for performing a reset in milliseconds */
private static final long RESET_TIME = 5L * TimeUtil.MILLIS_PER_MINUTE;
/** The list of sites that need grid information. */
private final List<String> siteIDs = new ArrayList<String>();
/** Python pickle of the grid information for sites */
private final Map<String, String> dataMap = new HashMap<String, String>();
/** The time value for values in dataMap. */
private long timeSeconds = 0L;
/** When true grid maps are being retrieved. */
private boolean gettingData = false;
/** Listeners to notified when the grid data has arrived. */
private final List<IGridDataRetrieveListener> listeners = new ArrayList<IGridDataRetrieveListener>();
/**
* Timer to force retrieval of grid data. Currently no way to notify if the
* grid data for a given time has been updated.
*/
private Job resetJob;
/**
* Add sites to list of sites needing grid data.
*
* @param siteIDs
*/
public static void addSiteIDs(List<String> siteIDs) {
synchronized (instance) {
instance.siteIDs.addAll(siteIDs);
}
}
/**
* The list of sites needing grid information.
*
* @return siteIDs
*/
public static List<String> getSiteIDs() {
synchronized (instance) {
return new ArrayList<String>(instance.siteIDs);
}
}
/**
* Clear data Maps sites and time.
*/
public static void clear() {
synchronized (instance) {
instance.siteIDs.clear();
instance.dataMap.clear();
instance.timeSeconds = 0L;
instance.gettingData = false;
instance.resetJob.cancel();
}
}
/**
* Used by python to set all grid data for siteIDs and notify listeners that
* grid data has arrived.
*
* @param dataMap
*/
public static void setContainersMap(Map<String, String> dataMap) {
synchronized (instance) {
instance.dataMap.clear();
instance.dataMap.putAll(dataMap);
instance.gettingData = false;
}
instance.resetJob.cancel();
instance.resetJob.schedule(RESET_TIME);
notifyListeners();
}
/**
* Used by python to determine if grid data must be retrieved. This allows
* only one Job to retrieve the data.
*
* @param timeSeconds
* - The time for the grid data.
* @return true retrieve grid data otherwise false
*/
public static boolean needData(long timeSeconds) {
boolean state = false;
synchronized (instance) {
if (!instance.gettingData && instance.timeSeconds != timeSeconds) {
state = true;
instance.timeSeconds = timeSeconds;
instance.dataMap.clear();
instance.gettingData = true;
}
}
return state;
}
/**
* Add listener to be notified when grid data is retrieved.
*
* @param listener
*/
public static void addRetrieveDataListener(
IGridDataRetrieveListener listener) {
synchronized (instance) {
instance.listeners.add(listener);
}
}
/**
* Remove the listener.
*
* @param listener
*/
public static void removeRetrieveDataListener(
IGridDataRetrieveListener listener) {
synchronized (instance) {
instance.listeners.remove(listener);
}
}
/**
* Inform listeners that grid data has arrived.
*/
private static void notifyListeners() {
List<IGridDataRetrieveListener> listeners = null;
synchronized (instance) {
listeners = new ArrayList<IGridDataRetrieveListener>(
instance.listeners);
}
for (IGridDataRetrieveListener listener : listeners) {
listener.gridDataRetrieved();
}
}
/**
* Get the python data for the desired site and time. If data not yet
* retrieved null is returned.
*
* @param siteID
* @param timeSeconds
* @return data
*/
public static String getData(String siteID, long timeSeconds) {
synchronized (instance) {
return instance.dataMap.get(siteID);
}
}
/**
* Private constructor to allow only the one instance.
*/
private SiteGridManager() {
resetJob = new Job("SiteGridManger reset") {
@Override
protected IStatus run(IProgressMonitor monitor) {
SiteGridManager.this.reset();
return Status.OK_STATUS;
}
};
resetJob.setSystem(true);
}
/**
* Perform reset so the next data request will query for the grid data.
*/
private synchronized void reset() {
dataMap.clear();
timeSeconds = 0L;
gettingData = false;
}
}

View file

@ -92,6 +92,7 @@ import com.raytheon.viz.avnconfig.IStatusSettable;
* 04/26/2012 14717 zhao Indicator labels turn gray when Metar is outdated
* 20JUL2012 14570 gzhang/zhao Add data structure for highlighting correct time groups in TAF viewer
* 01/02/2013 15606 gzhang Remove GridData widthHint so button/label size change with GUI
* 03/07/2013 1735 rferrel Flag to indicate grid data is needed.
* </pre>
*
* @author lvenable
@ -99,6 +100,10 @@ import com.raytheon.viz.avnconfig.IStatusSettable;
*
*/
public class TafSiteComp {
/**
*
*/
public static final String GRID_MONITOR_CLASS = "GridMonitor";
/**
* Number of seconds to blink the button.
@ -113,26 +118,28 @@ public class TafSiteComp {
* DR14717: changed grace period from 10 minutes to 5 minutes.
*/
private final static long METAR_TIMEOUT = (1L * 60L + 5L) * 60L * 1000L;
/**
* DR14717: When Metar is 2 hours old, the persistence indicators turn gray.
* DR14717: When Metar is 2 hours old, the persistence indicators turn gray.
* This is the timeout in milliseconds for 2 hours.
*/
public final static long METAR_TIMEOUT_2HR = 2L * 60L * 60L * 1000L;
/**
* DR14717: When Metar is 4 hours plus 10 minutes old, Metar Time Label is replaced by "None",
* and the current observation and persistence indicators turn gray.
* This is the timeout in milliseconds for 4 hours plus 10 minutes.
* DR14717: When Metar is 4 hours plus 10 minutes old, Metar Time Label is
* replaced by "None", and the current observation and persistence
* indicators turn gray. This is the timeout in milliseconds for 4 hours
* plus 10 minutes.
*/
public final static long METAR_TIMEOUT_4HR10MIN = (4L * 60L + 10L) * 60L * 1000L;
/**
* DR14717:
*/
private long latestMtrTime = -1;
private boolean persistMonitorProcessedFirst = false;
/**
* A TAF is good for up to 6 hours and can be issued up to 40 minutes before
* they take affect. This time out is in milliseconds for 6 hours with a 40
@ -230,6 +237,8 @@ public class TafSiteComp {
return alertMap;
}
private boolean haveGridMontior = false;
private TafRecord lastTaf;
private boolean updatable;
@ -300,7 +309,7 @@ public class TafSiteComp {
ResourceConfigMgr configMgr = ResourceConfigMgr.getInstance();
GridData gd = new GridData();
// gd.widthHint = 70; // DR 15606
// gd.widthHint = 70; // DR 15606
gd.minimumWidth = 70;
siteIdBtn = new Button(parent, SWT.PUSH);
configMgr.setDefaultFontAndColors(siteIdBtn, "WWWW", gd);
@ -384,15 +393,22 @@ public class TafSiteComp {
monitorArray = new ArrayList<SiteMonitor>();
alertMap = new HashMap<String, String[]>();
ArrayList<MonitorCfg> monitorCfgs = tafMonCfg.getMonitorCfgs();
alertTimeMap = new HashMap<String,String>();/* DR 14570 */
tempoMap = new HashMap<String,String[]>();//20120711
alertTimeMap = new HashMap<String, String>();/* DR 14570 */
tempoMap = new HashMap<String, String[]>();// 20120711
for (MonitorCfg monCfg : monitorCfgs) {
SiteMonitor monitor = null;
if ("MetarMonitor".equals(monCfg.getClassName())) {
monitor = new SiteMonitor(parent, this, monCfg, alertMap, /* DR 14570 */alertTimeMap,tempoMap);
metarMontiorIndex = monitorArray.size();
// DR14570
monitor = new SiteMonitor(parent, this, monCfg, alertMap,
alertTimeMap, tempoMap);
metarMontiorIndex = monitorArray.size();
} else {
monitor = new SiteMonitor(parent, this, monCfg, null, /* DR 14570 */null,null);
if (GRID_MONITOR_CLASS.equals(monCfg.getClassName())) {
haveGridMontior = true;
}
// DR14570
monitor = new SiteMonitor(parent, this, monCfg, null, null,
null);
}
monitorArray.add(monitor);
}
@ -449,7 +465,7 @@ public class TafSiteComp {
GridData gd = new GridData();
gd.minimumWidth = btnMinWidth;
// gd.widthHint = btnMinWidth; // DR 15606
// gd.widthHint = btnMinWidth; // DR 15606
amdBtn = new Button(btnStatusComp, SWT.PUSH);
configMgr.setDefaultFontAndColors(amdBtn, "Amd", gd);
amdBtn.addSelectionListener(new SelectionAdapter() {
@ -466,7 +482,7 @@ public class TafSiteComp {
gd = new GridData();
gd.minimumWidth = btnMinWidth;
// gd.widthHint = btnMinWidth; // DR 15606
// gd.widthHint = btnMinWidth; // DR 15606
rtdBtn = new Button(btnStatusComp, SWT.PUSH);
configMgr.setDefaultFontAndColors(rtdBtn, "Rtd", gd);
rtdBtn.addSelectionListener(new SelectionAdapter() {
@ -483,7 +499,7 @@ public class TafSiteComp {
gd = new GridData();
gd.minimumWidth = btnMinWidth;
// gd.widthHint = btnMinWidth; // DR 15606
// gd.widthHint = btnMinWidth; // DR 15606
corBtn = new Button(btnStatusComp, SWT.PUSH);
configMgr.setDefaultFontAndColors(corBtn, "Cor", gd);
corBtn.addSelectionListener(new SelectionAdapter() {
@ -653,31 +669,32 @@ public class TafSiteComp {
+ timestamp.substring(4, 6));
long currentTime = SimulatedTime.getSystemTime().getTime()
.getTime();
if ( currentTime > ( metarTime + METAR_TIMEOUT_4HR10MIN ) ) {
mtrTimeLbl.setText("None");
if (currentTime > (metarTime + METAR_TIMEOUT_4HR10MIN)) {
mtrTimeLbl.setText("None");
mtrTimeLbl.setBackground(getBackgroundColor());
if ( persistMonitorProcessedFirst ) {
SiteMonitor psstMonitor = monitorArray.get(1);
Color grayColor = psstMonitor.getGraySeverityColor();
Map<String, Label> psstLabelMap = psstMonitor.getLabelMap();
Set<String> psstKeys = psstLabelMap.keySet();
for ( String key : psstKeys ) {
psstLabelMap.get(key).setBackground(grayColor);
}
}
if (persistMonitorProcessedFirst) {
SiteMonitor psstMonitor = monitorArray.get(1);
Color grayColor = psstMonitor.getGraySeverityColor();
Map<String, Label> psstLabelMap = psstMonitor.getLabelMap();
Set<String> psstKeys = psstLabelMap.keySet();
for (String key : psstKeys) {
psstLabelMap.get(key).setBackground(grayColor);
}
}
} else if (currentTime > (metarTime + METAR_TIMEOUT)) {
mtrTimeLbl.setBackground(getWarningColor());
if ( currentTime > ( metarTime + METAR_TIMEOUT_2HR ) ) {
if ( persistMonitorProcessedFirst ) {
SiteMonitor psstMonitor = monitorArray.get(1);
Color grayColor = psstMonitor.getGraySeverityColor();
Map<String, Label> psstLabelMap = psstMonitor.getLabelMap();
Set<String> psstKeys = psstLabelMap.keySet();
for ( String key : psstKeys ) {
psstLabelMap.get(key).setBackground(grayColor);
}
}
if (currentTime > (metarTime + METAR_TIMEOUT_2HR)) {
if (persistMonitorProcessedFirst) {
SiteMonitor psstMonitor = monitorArray.get(1);
Color grayColor = psstMonitor.getGraySeverityColor();
Map<String, Label> psstLabelMap = psstMonitor
.getLabelMap();
Set<String> psstKeys = psstLabelMap.keySet();
for (String key : psstKeys) {
psstLabelMap.get(key).setBackground(grayColor);
}
}
}
} else {
mtrTimeLbl.setBackground(getBackgroundColor());
@ -814,21 +831,32 @@ public class TafSiteComp {
}
}
public void setPersistMonitorProcessedFirst(boolean b) {
persistMonitorProcessedFirst = b;
}
public void setLatestMtrTime(long latestMtrTime) {
this.latestMtrTime = latestMtrTime;
}
public boolean doGridMonitor() {
return haveGridMontior;
}
public long getLatestMtrTime() {
return latestMtrTime;
}
//------------------------------- DR 14570:
private Map<String, String[]> tempoMap = null;//20120711
private Map<String, String> alertTimeMap = null;
public Map<String,String> getAlertTimeMap(){ return alertTimeMap;}
public Map<String,String[]> getTempoMap(){return tempoMap;}//20120711
public void setPersistMonitorProcessedFirst(boolean b) {
persistMonitorProcessedFirst = b;
}
public void setLatestMtrTime(long latestMtrTime) {
this.latestMtrTime = latestMtrTime;
}
public long getLatestMtrTime() {
return latestMtrTime;
}
// ------------------------------- DR 14570:
private Map<String, String[]> tempoMap = null;// 20120711
private Map<String, String> alertTimeMap = null;
public Map<String, String> getAlertTimeMap() {
return alertTimeMap;
}
public Map<String, String[]> getTempoMap() {
return tempoMap;
}// 20120711
}

View file

@ -53,7 +53,6 @@ import org.eclipse.ui.actions.ActionFactory;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.viz.alerts.observers.ProductAlertObserver;
// import com.raytheon.viz.aviation.cachedata.PythonCacheGuidanceJob;
import com.raytheon.viz.aviation.climatology.ClimateMenuDlg;
import com.raytheon.viz.aviation.climatology.WeatherPlotDialog;
import com.raytheon.viz.aviation.editor.ITafSettable;
@ -68,11 +67,13 @@ import com.raytheon.viz.aviation.monitor.EtaBufMonitorObserver;
import com.raytheon.viz.aviation.monitor.EtaMonitorObserver;
import com.raytheon.viz.aviation.monitor.GfsLampMonitorObserver;
import com.raytheon.viz.aviation.monitor.GfsMonitorObserver;
import com.raytheon.viz.aviation.monitor.IGridDataRetrieveListener;
import com.raytheon.viz.aviation.monitor.LtgMonitorObserver;
import com.raytheon.viz.aviation.monitor.MetarMonitorObserver;
import com.raytheon.viz.aviation.monitor.PythonMonitorJob;
import com.raytheon.viz.aviation.monitor.RltgMonitorObserver;
import com.raytheon.viz.aviation.monitor.ScheduledMonitorTask;
import com.raytheon.viz.aviation.monitor.SiteGridManager;
import com.raytheon.viz.aviation.monitor.TafMonitorObserver;
import com.raytheon.viz.aviation.monitor.TafSiteComp;
import com.raytheon.viz.aviation.resource.ResourceConfigMgr;
@ -143,13 +144,15 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* 10/15/2012 1229 rferrel Changes for non-blocking HelpUsageDlg.
* 11/28/2012 1363 rferrel Dispose of PythonGuidanceJob when closing.
* 01/02/2013 15606 gzhang Remove GridData widthHint so button/label size change with GUI
* 03/07/2013 1735 rferrel Performance speed up for retrieving grid data.
*
* </pre>
*
* @author grichard
* @version 1.0
*/
public class TafMonitorDlg extends CaveSWTDialog {
public class TafMonitorDlg extends CaveSWTDialog implements
IGridDataRetrieveListener {
/**
* The station list.
@ -296,6 +299,7 @@ public class TafMonitorDlg extends CaveSWTDialog {
@Override
protected void disposed() {
SiteGridManager.clear();
cleanupMonitoring();
tveDlg.disposeDialog();
}
@ -754,7 +758,8 @@ public class TafMonitorDlg extends CaveSWTDialog {
gl.verticalSpacing = 1;
scrolledComp.setLayout(gl);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
// gd.heightHint = SCROLLED_COMP_HEIGHT_perStn * stationList.size(); // DR 15606
// gd.heightHint = SCROLLED_COMP_HEIGHT_perStn * stationList.size(); //
// DR 15606
scrolledComp.setLayoutData(gd);
configMgr.setDefaultColors(scrolledComp);
@ -897,8 +902,9 @@ public class TafMonitorDlg extends CaveSWTDialog {
}
tveDlg.disposeDialog();
// PythonCacheGuidanceJob.dispose();
PythonGuidanceJob.dispose();
SiteGridManager.removeRetrieveDataListener(this);
SiteGridManager.clear();
return close();
}
@ -911,6 +917,9 @@ public class TafMonitorDlg extends CaveSWTDialog {
// (3) add MetWatch listener for TAFs. New this up with `this' and
// propagate to simple MetWatch factory to use as IMonitorable
// interface.
SiteGridManager.removeRetrieveDataListener(this);
SiteGridManager.clear();
SiteGridManager.addSiteIDs(stationList);
if (stationList != null) {
for (String stationOfInterest : stationList) {
if (stationOfInterest != null) {
@ -922,13 +931,15 @@ public class TafMonitorDlg extends CaveSWTDialog {
stationOfInterest, tveDlg, tafMonCfg, msgStatComp);
tsc.setBlinkable(blinkMenuItem.getSelection());
siteRows.add(tsc);
// Perform ObStation database dip to populate model.
// ObStationModel.getInstance().obStationDatabaseDip(
// stationOfInterest);
}
}
if (siteRows.size() > 0 && siteRows.get(0).doGridMonitor()) {
// Only add listener when displaying grid data.
SiteGridManager.addRetrieveDataListener(this);
}
}
}
private void addHorizontalSeparator(Composite parentComp) {
@ -1028,4 +1039,18 @@ public class TafMonitorDlg extends CaveSWTDialog {
}
return tempoMap;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.aviation.monitor.IGridDataRetrieveListener#gridDataRetrieved
* ()
*/
@Override
public void gridDataRetrieved() {
for (TafSiteComp tsc : siteRows) {
tsc.fireMonitor(TafSiteComp.GRID_MONITOR_CLASS);
}
}
}

View file

@ -131,7 +131,6 @@ public class ResourceConfigMgr implements IResourceAction {
display.addListener(SWT.Dispose, new Listener() {
@Override
public void handleEvent(Event event) {
System.out.println("Display disposed");
resrcDataMgr.dispose();
}
});

View file

@ -21,7 +21,9 @@ package com.raytheon.edex.plugin.gfe.server.handler;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
@ -39,6 +41,7 @@ import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainer;
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainers;
import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataView;
import com.raytheon.uf.common.dataplugin.gfe.request.GetPointDataRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
@ -52,10 +55,11 @@ import com.raytheon.uf.common.geospatial.PointUtil;
import com.raytheon.uf.common.pointdata.PointDataDescription.Type;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.vividsolutions.jts.geom.Coordinate;
/**
* TODO Add Description
* Generates results for Point(s) on requested grid database.
*
* <pre>
*
@ -63,6 +67,8 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 11, 2009 njensen Initial creation
* Mar 06, 2013 1735 rferrel Change to retrieve multiple points
* in a single grid request.
*
* </pre>
*
@ -75,6 +81,14 @@ public class GetPointDataHandler implements
protected final transient Log logger = LogFactory.getLog(getClass());
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest
* (com.raytheon.uf.common.serialization.comm.IServerRequest)
*/
@SuppressWarnings("unchecked")
@Override
public ServerResponse<?> handleRequest(GetPointDataRequest request)
throws Exception {
@ -82,18 +96,8 @@ public class GetPointDataHandler implements
DatabaseID db = new DatabaseID(request.getDatabaseID());
List<ParmID> parmIds = new ArrayList<ParmID>(parameters.size());
for (String p : parameters) {
parmIds.add(new ParmID(p, db));
}
List<TimeRange> times = new ArrayList<TimeRange>();
for (int i = 0; i < request.getNumberHours(); i++) {
TimeRange tr = new TimeRange(request.getStartTime() + (i * 3600)
* 1000, request.getStartTime() + ((i + 1) * 3600 * 1000));
times.add(tr);
}
GridLocation loc = null;
try {
loc = IFPServerConfigManager.getServerConfig(db.getSiteId())
.dbDomain();
@ -105,18 +109,47 @@ public class GetPointDataHandler implements
error.addMessage(msg);
return error;
}
GridGeometry2D geom = MapUtil.getGridGeometry(loc);
GFEPointDataContainer container = new GFEPointDataContainer();
ServerResponse<GFEPointDataContainer> resp = new ServerResponse<GFEPointDataContainer>();
for (String p : parameters) {
parmIds.add(new ParmID(p, db));
}
Coordinate coordinate = request.getCoordinate();
Point index = PointUtil.determineIndex(coordinate, loc.getCrs(), geom);
int x = index.x;
int y = index.y;
boolean containsCoord = true;
if (x < 0 || x >= loc.getNx() || y < 0 || y >= loc.getNy()) {
containsCoord = false;
List<TimeRange> times = new ArrayList<TimeRange>();
for (int i = 0; i < request.getNumberHours(); i++) {
long iStartTime = request.getStartTime()
+ (i * TimeUtil.MILLIS_PER_HOUR);
long iEndTime = iStartTime + TimeUtil.MILLIS_PER_HOUR;
TimeRange tr = new TimeRange(iStartTime, iEndTime);
times.add(tr);
}
List<Coordinate> coordinates = request.getCoordinates();
ServerResponse<?> resp = null;
resp = new ServerResponse<GFEPointDataContainers>();
Map<Coordinate, CoordinateInfo> infoMap = new HashMap<Coordinate, CoordinateInfo>();
boolean getSlices = false;
// See if any of the coordinates need the grid slices and set up info
// map.
for (Coordinate coordinate : coordinates) {
CoordinateInfo info = new CoordinateInfo();
infoMap.put(coordinate, info);
info.container = new GFEPointDataContainer();
Point index = PointUtil.determineIndex(coordinate, loc.getCrs(),
geom);
info.x = index.x;
info.y = index.y;
info.containsCoord = !((info.x < 0) || (info.x >= loc.getNx())
|| (info.y < 0) || (info.y >= loc.getNy()));
if (!getSlices) {
getSlices = info.containsCoord;
}
}
for (TimeRange tr : times) {
@ -124,8 +157,8 @@ public class GetPointDataHandler implements
for (ParmID p : parmIds) {
GetGridRequest req = new GetGridRequest();
req.setParmId(p);
List<GFERecord> reqRecList = new ArrayList<GFERecord>(times
.size());
List<GFERecord> reqRecList = new ArrayList<GFERecord>(
times.size());
GFERecord rec = new GFERecord(p, tr);
reqRecList.add(rec);
req.setRecords(reqRecList);
@ -133,58 +166,91 @@ public class GetPointDataHandler implements
}
try {
GFEPointDataView view = new GFEPointDataView();
view.setData("time", Type.LONG, SI.MILLI(SI.SECOND), tr
.getStart().getTime());
view.setData("lat", Type.FLOAT, null, coordinate.y);
view.setData("lon", Type.FLOAT, null, coordinate.x);
// initially set all requested params to missing
for (String param : parameters) {
view.setData(param, Type.FLOAT, Unit.ONE, 999.0f);
ServerResponse<List<IGridSlice>> sr = null;
if (getSlices) {
sr = GridParmManager.getGridData(reqList);
}
if (containsCoord) {
// get the data for each requested parm at a single time
ServerResponse<List<IGridSlice>> sr = GridParmManager
.getGridData(reqList);
for (Coordinate coordinate : coordinates) {
CoordinateInfo info = infoMap.get(coordinate);
boolean containsCoord = info.containsCoord;
GFEPointDataContainer container = info.container;
GFEPointDataView view = new GFEPointDataView();
int x = info.x;
int y = info.y;
// set the retrieved data
for (IGridSlice slice : sr.getPayload()) {
String param = slice.getGridInfo().getParmID()
.getParmName();
Unit<?> unit = slice.getGridInfo().getUnitObject();
if (slice instanceof VectorGridSlice) {
VectorGridSlice gs = (VectorGridSlice) slice;
Type type = Type.FLOAT;
view.setData(param + "Dir", type,
NonSI.DEGREE_ANGLE, gs.getDirGrid().get(x,
y));
view.setData(param + "Spd", type, unit, gs
.getMagGrid().get(x, y));
} else if (slice instanceof ScalarGridSlice) {
ScalarGridSlice gs = (ScalarGridSlice) slice;
float val = gs.getScalarGrid().get(x, y);
Type type = Type.FLOAT;
view.setData(param, type, unit, val);
} else if (slice instanceof DiscreteGridSlice) {
DiscreteGridSlice gs = (DiscreteGridSlice) slice;
byte value = gs.getDiscreteGrid().get(x, y);
String key = gs.getKey()[value].toString();
Type type = Type.STRING;
view.setData(param, type, unit, key);
view.setData("time", Type.LONG, SI.MILLI(SI.SECOND), tr
.getStart().getTime());
view.setData("lat", Type.FLOAT, null, coordinate.y);
view.setData("lon", Type.FLOAT, null, coordinate.x);
// initially set all requested params to missing
for (String param : parameters) {
view.setData(param, Type.FLOAT, Unit.ONE, 999.0f);
}
if (containsCoord) {
// set the retrieved data
for (IGridSlice slice : sr.getPayload()) {
String param = slice.getGridInfo().getParmID()
.getParmName();
Unit<?> unit = slice.getGridInfo().getUnitObject();
if (slice instanceof VectorGridSlice) {
VectorGridSlice gs = (VectorGridSlice) slice;
Type type = Type.FLOAT;
view.setData(param + "Dir", type,
NonSI.DEGREE_ANGLE, gs.getDirGrid()
.get(x, y));
view.setData(param + "Spd", type, unit, gs
.getMagGrid().get(x, y));
} else if (slice instanceof ScalarGridSlice) {
ScalarGridSlice gs = (ScalarGridSlice) slice;
float val = gs.getScalarGrid().get(x, y);
Type type = Type.FLOAT;
view.setData(param, type, unit, val);
} else if (slice instanceof DiscreteGridSlice) {
DiscreteGridSlice gs = (DiscreteGridSlice) slice;
byte value = gs.getDiscreteGrid().get(x, y);
String key = gs.getKey()[value].toString();
Type type = Type.STRING;
view.setData(param, type, unit, key);
}
}
}
container.append(view);
}
container.append(view);
} catch (Exception e) {
resp.addMessage(e.getMessage());
}
}
resp.setPayload(container);
GFEPointDataContainers gfeContainers = new GFEPointDataContainers();
List<GFEPointDataContainer> containers = new ArrayList<GFEPointDataContainer>(
coordinates.size());
// Keep the results list in the same order as the request's
// coordinate list.
for (Coordinate coordinate : coordinates) {
containers.add(infoMap.get(coordinate).container);
}
gfeContainers.setContainers(containers);
((ServerResponse<GFEPointDataContainers>) resp)
.setPayload(gfeContainers);
return resp;
}
/**
* Information for a coordinate.
*/
private class CoordinateInfo {
GFEPointDataContainer container;
boolean containsCoord;
int x;
int y;
}
}

View file

@ -0,0 +1,89 @@
/**
* 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.common.dataplugin.gfe.point;
import java.util.List;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* List of GFE Point Data containers.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 6, 2013 1735 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
@DynamicSerialize
public class GFEPointDataContainers {
/** Results for a list of coordinates. */
@DynamicSerializeElement
private List<GFEPointDataContainer> containers;
/**
* Get list of containers.
*
* @return containers
*/
public List<GFEPointDataContainer> getContainers() {
return containers;
}
/**
* Set list of containers.
*
* @param containers
*/
public void setContainers(List<GFEPointDataContainer> containers) {
this.containers = containers;
}
/**
* Get the number of containers in the list.
*
* @return size
*/
public int getSize() {
int size = 0;
if (containers != null) {
size = containers.size();
}
return size;
}
/**
* Obtain specific container.
*
* @param index
* @return container
*/
public GFEPointDataContainer getContainer(int index) {
return containers.get(index);
}
}

View file

@ -27,7 +27,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.vividsolutions.jts.geom.Coordinate;
/**
* TODO Add Description
* Class for requesting Grid Point data for a list of coordinates.
*
* <pre>
*
@ -35,6 +35,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 4, 2009 njensen Initial creation
* Mar 6, 2013 1735 rferrel Now handles a list of coordinates.
*
* </pre>
*
@ -45,61 +46,133 @@ import com.vividsolutions.jts.geom.Coordinate;
@DynamicSerialize
public class GetPointDataRequest extends AbstractGfeRequest {
/** Id of data base containing the grid. */
@DynamicSerializeElement
private String databaseID;
/** List of coordinates requesting values. */
@DynamicSerializeElement
private Coordinate coordinate;
private List<Coordinate> coordinates = new ArrayList<Coordinate>();
/** Parameters to to obtain for each coordinate. */
@DynamicSerializeElement
private List<String> parameters = new ArrayList<String>();
/** Start time for the interval to obtain values for. */
@DynamicSerializeElement
private long startTime;
/** Number of hours to obtain values for. */
@DynamicSerializeElement
private int numberHours;
/**
* Parameter to add to the list.
*
* @param parmShortName
*/
public void addParameter(String parmShortName) {
parameters.add(parmShortName);
}
/**
* Obtain the data base ID for the grid.
*
* @return databaseID
*/
public String getDatabaseID() {
return databaseID;
}
/**
* Set the data base ID.
*
* @param databaseID
*/
public void setDatabaseID(String databaseID) {
this.databaseID = databaseID;
}
/**
* Get list of parameters to obtain.
*
* @return parameters
*/
public List<String> getParameters() {
return parameters;
}
/**
* Set the parmater list.
*
* @param parameters
*/
public void setParameters(List<String> parameters) {
this.parameters = parameters;
}
public Coordinate getCoordinate() {
return coordinate;
/**
* Get list of coordinates.
*
* @return coordinates
*/
public List<Coordinate> getCoordinates() {
return coordinates;
}
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
/**
* Set list of coordinates.
*
* @param coordinates
*/
public void setCoordinates(List<Coordinate> coordinates) {
this.coordinates = coordinates;
}
/**
* Add coordinate to the list.
*
* @param coordinate
*/
public void addCoordinate(Coordinate coordinate) {
if (coordinates == null) {
coordinates = new ArrayList<Coordinate>();
}
coordinates.add(coordinate);
}
/**
* Get start time.
*
* @return startTime
*/
public long getStartTime() {
return startTime;
}
/**
* Set the start time.
*
* @param startTime
*/
public void setStartTime(long startTime) {
this.startTime = startTime;
}
/**
* Get the number of hours desired.
*
* @return numberHours
*/
public int getNumberHours() {
return numberHours;
}
/**
* Set the number of hours.
*
* @param numberHours
*/
public void setNumberHours(int numberHours) {
this.numberHours = numberHours;
}