Omaha #3873 Obs now load in the background @ startup, doesn't block CAVE.

Change-Id: I92a1a45abbd9c523313e379f179d78e8cabdb8ca

Former-commit-id: 0673bf2ac43d3e0849ec99097d6361c09ed98806
This commit is contained in:
Dave Hladky 2015-10-21 16:08:36 -05:00
parent 68edb4bcbb
commit 52bc5bd69e
4 changed files with 275 additions and 120 deletions

View file

@ -84,6 +84,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Apr 28, 2014 3086 skorolev Removed local getMonitorAreaConfig method.
* Sep 04, 2014 3220 skorolev Updated configUpdate method and added updateMonitoringArea.
* Sep 18, 2015 3873 skorolev Removed common definitions. Replaced deprecated NotificationMessage.
* Oct 21, 2015 3873 dhladky Get Obs load off UI thread.
*
* </pre>
*
@ -351,6 +352,9 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
monitor.removeMonitorListener(zoneDialog);
monitor.fogResources.removeAll(getMonitorListeners());
stopObserver(OBS, this);
if (obsJob != null) {
obsJob.cancel();
}
monitor = null;
}
@ -633,4 +637,5 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
}
MonitoringArea.setPlatformMap(zones);
}
}

View file

@ -20,14 +20,13 @@
package com.raytheon.uf.viz.monitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.swt.widgets.Display;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
import com.raytheon.uf.common.dataplugin.fssobs.FSSObsRecord;
@ -41,7 +40,6 @@ import com.raytheon.uf.common.pointdata.PointDataContainer;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.alerts.AlertMessage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
@ -66,6 +64,7 @@ import com.vividsolutions.jts.geom.Geometry;
* May 08, 2014 3086 skorolev Added current site definition.
* Sep 04, 2014 3220 skorolev Removed cwa and monitorUsefrom vals.
* Sep 18, 2015 3873 skorolev Included common definitions.
* Oct 21, 2015 3873 dhladky Get Obs load off UI thread.
*
* </pre>
*
@ -79,6 +78,8 @@ public abstract class ObsMonitor extends Monitor {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(ObsMonitor.class);
protected ProcessObsJob obsJob = null;
/*
* (non-Javadoc)
*
@ -229,7 +230,7 @@ public abstract class ObsMonitor extends Monitor {
try {
Map<String, RequestConstraint> constraints = RequestConstraint
.toConstraintMapping(DataURIUtil.createDataURIMap(dataURI));
FSSObsRecord[] pdos = requestFSSObs(constraints, null);
FSSObsRecord[] pdos = requestFSSObs(constraints);
if (pdos.length > 0 && pdos[0].getTimeObs() != null) {
final FSSObsRecord objectToSend = pdos[0];
try {
@ -272,47 +273,19 @@ public abstract class ObsMonitor extends Monitor {
*/
public void processProductAtStartup() {
/**
* Assume this number for MaxNumObsTimes is larger enough to cover data
* of all observations (at least 24 hours' worth of data) in database
* [changed from 10 to 240 on May, 18, 2010 for DR #6015, zhao]
*/
int MaxNumObsTimes = 240;
Map<String, RequestConstraint> vals = new HashMap<String, RequestConstraint>();
try {
vals.put(FSSObsRecord.PLUGIN_NAME_ID, new RequestConstraint(
FSSObsRecord.PLUGIN_NAME));
DataTime[] dataTimesAvailable = DataCubeContainer.performTimeQuery(
vals, false);
DataTime[] selectedTimes = dataTimesAvailable;
// Ensure that the latest product is retrieved.
// [Modified: retrieve at most MaxNumObsTimes data
// points, Feb
// 19, 2010, zhao]
if (dataTimesAvailable.length > 0) {
Arrays.sort(dataTimesAvailable);
// at most, MaxNumObsTimes observation times are
// considered
if (dataTimesAvailable.length > MaxNumObsTimes) {
selectedTimes = new DataTime[MaxNumObsTimes];
System.arraycopy(dataTimesAvailable,
dataTimesAvailable.length - MaxNumObsTimes,
selectedTimes, 0, MaxNumObsTimes);
}
FSSObsRecord[] obsRecords = requestFSSObs(vals, selectedTimes);
for (FSSObsRecord objectToSend : obsRecords) {
ObReport result = GenerateFSSObReport
.generateObReport(objectToSend);
processAtStartup(result);
}
final long start = System.currentTimeMillis();
obsJob = null;
obsJob = new ProcessObsJob(this);
obsJob.addJobChangeListener(new JobChangeAdapter() {
@Override
public void done(IJobChangeEvent event) {
// do nothing at this point
final long end = System.currentTimeMillis();
statusHandler.info("Obs Load took: "+(end-start)+" ms");
obsJob = null;
}
} catch (DataCubeException e) {
statusHandler.handle(Priority.PROBLEM,
"No data in database at startup.");
}
});
obsJob.schedule();
}
/**
@ -324,17 +297,9 @@ public abstract class ObsMonitor extends Monitor {
* @throws VizException
* @throws DataCubeException
*/
private FSSObsRecord[] requestFSSObs(
Map<String, RequestConstraint> constraints, DataTime[] times)
protected FSSObsRecord[] requestFSSObs(
Map<String, RequestConstraint> constraints)
throws DataCubeException {
if (times != null) {
String[] timeStrs = new String[times.length];
for (int i = 0; i < times.length; ++i) {
timeStrs[i] = times[i].toString();
}
constraints.put(PluginDataObject.DATATIME_ID,
new RequestConstraint(timeStrs));
}
PointDataContainer pdc = DataCubeContainer.getPointData(
FSSObsRecord.PLUGIN_NAME, FSSObsRecordTransform.FSSOBS_PARAMS,
constraints);

View file

@ -0,0 +1,140 @@
/**
* 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.monitor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import com.raytheon.uf.common.dataplugin.fssobs.FSSObsRecord;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
import com.raytheon.uf.common.inventory.exception.DataCubeException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.monitor.data.ObReport;
/**
*
* Load Obs off the UI thread.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 21, 2015 3873 dhladky Initial creation.
*
* </pre>
*
* @author dhladky
* @version 1.0
*
*/
public class ProcessObsJob extends Job {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(ProcessObsJob.class);
protected static final int PROGRESS_FACTOR = 1;
/** how many hours do FSSObs go back we wish to load here **/
public static final int HOUR_BACK = 24;
private ObsMonitor obsMonitor;
public ProcessObsJob(ObsMonitor obsMonitor) {
super("Obs Load Process");
this.setSystem(false);
this.setPriority(INTERACTIVE);
this.obsMonitor = obsMonitor;
}
public IStatus run(IProgressMonitor monitor) {
try {
long backTime = TimeUtil.newCalendar().getTimeInMillis();
Date time = new Date(backTime - (HOUR_BACK * TimeUtil.MILLIS_PER_HOUR));
Map<String, RequestConstraint> vals = new HashMap<String, RequestConstraint>();
vals.put("dataTime.refTime", new RequestConstraint(
TimeUtil.formatToSqlTimestamp(time),
ConstraintType.GREATER_THAN_EQUALS));
long startPoint = System.currentTimeMillis();
FSSObsRecord[] recs = obsMonitor.requestFSSObs(vals);
long endPoint = System.currentTimeMillis();
SubMonitor smonitor = SubMonitor.convert(monitor, "Loading "+recs.length+" observations...",
recs.length);
smonitor.beginTask(null, recs.length);
statusHandler.info("Point Data Request, took: "
+ (endPoint - startPoint) + " ms");
for (FSSObsRecord rec : recs) {
if (rec != null) {
if (!this.shouldRun()) {
return Status.CANCEL_STATUS;
}
long start = System.currentTimeMillis();
doOb(rec, smonitor.newChild(PROGRESS_FACTOR));
long end = System.currentTimeMillis();
statusHandler.info("Processed "
+ rec.getIdentifier()
+ " in " + (end - start) + " ms");
}
}
statusHandler.info("Processed " + recs.length + " FSSObs records.");
} catch (DataCubeException e) {
statusHandler.handle(Priority.PROBLEM,
"No data in database at startup.");
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
/**
* Processes the Ob
*
* @param objectToSend
**/
protected void doOb(FSSObsRecord objectToSend, SubMonitor smonitor) {
smonitor.beginTask(null, PROGRESS_FACTOR);
ObReport result = GenerateFSSObReport
.generateObReport(objectToSend);
obsMonitor.processAtStartup(result);
}
}

View file

@ -21,6 +21,8 @@ package com.raytheon.uf.viz.monitor.data;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.raytheon.uf.common.geospatial.ISpatialQuery;
import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
@ -30,6 +32,8 @@ import com.raytheon.uf.common.monitor.data.CommonConfig.AppName;
import com.raytheon.uf.common.monitor.data.ObConst;
import com.raytheon.uf.common.monitor.data.ObConst.DataUsageKey;
import com.raytheon.uf.common.monitor.xml.AreaIdXML;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.monitor.config.CommonTableConfig;
import com.raytheon.uf.viz.monitor.config.CommonTableConfig.CellType;
import com.raytheon.uf.viz.monitor.config.CommonTableConfig.ObsHistType;
@ -52,6 +56,7 @@ import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
* Feb 28, 2013 14410 zhao Modified getCellTypeForBlizWarn
* May 23, 2014 3086 skorolev Corrected ObsHistType. Cleaned code.
* Sep 18, 2015 3873 skorolev Added coordinates in the hover text for a newly added zones.Corrected code for Fog and SNOW table data.
* Oct 22, 2015 3873 dhladky Cached off the zone/station hover texts.
*
* </pre>
*
@ -61,13 +66,36 @@ import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
public final class TableUtil {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(TableUtil.class);
/** Conversion coefficient of nautical miles to statute miles. */
public static final float milesPerNauticalMile = 1.15078f;
/** Singleton instance of this class */
private static TableUtil tableUtil = new TableUtil();
/** Hover text lookup map **/
public Map<String, String> zoneHoverTextMap = null;
/** station text lookup map **/
public Map<String, String> stationHoverTextMap = null;
/**
* Constructor
* Actual initialization if necessary
*
* @return
*/
public static synchronized TableUtil getInstance() {
if (tableUtil == null) {
tableUtil = new TableUtil();
}
return tableUtil;
}
private TableUtil() {
zoneHoverTextMap = new ConcurrentHashMap<String, String>();
stationHoverTextMap = new ConcurrentHashMap<String, String>();
}
/**
@ -976,42 +1004,50 @@ public final class TableUtil {
private static String getZoneHoverText(AreaIdXML zoneXML) {
String zone = zoneXML.getAreaId();
ISpatialQuery sq = null;
String sql = null;
String hoverText = zone.substring(0, 2) + ", ";
String hoverText = tableUtil.zoneHoverTextMap.get(zone);
try {
if (MonitorAreaUtils.isMarineZone(zone)) {
sql = "select name from mapdata.marinezones where id = '"
+ zone + "'";
} else if (zone.charAt(2) == 'Z') { // forecast zone
String state_zone = zone.substring(0, 2) + zone.substring(3);
sql = "select name from mapdata.zone where state_zone = '"
+ state_zone + "'";
} else { // County
String state = zone.substring(0, 2);
String fipsLike = "%" + zone.substring(3);
sql = "select countyname from mapdata.county where state = '"
+ state + "' and fips like '" + fipsLike + "'";
}
if (hoverText == null) {
sq = SpatialQueryFactory.create();
Object[] results = sq.dbRequest(sql, "maps");
if (results.length > 0) {
if (results[0] instanceof Object[]) {
Object[] res = (Object[]) results[0];
hoverText += (String) res[0];
ISpatialQuery sq = null;
String sql = null;
hoverText = zone.substring(0, 2) + ", ";
try {
if (MonitorAreaUtils.isMarineZone(zone)) {
sql = "select name from mapdata.marinezones where id = '"
+ zone + "'";
} else if (zone.charAt(2) == 'Z') { // forecast zone
String state_zone = zone.substring(0, 2)
+ zone.substring(3);
sql = "select name from mapdata.zone where state_zone = '"
+ state_zone + "'";
} else { // County
String state = zone.substring(0, 2);
String fipsLike = "%" + zone.substring(3);
sql = "select countyname from mapdata.county where state = '"
+ state + "' and fips like '" + fipsLike + "'";
}
sq = SpatialQueryFactory.create();
Object[] results = sq.dbRequest(sql, "maps");
if (results.length > 0) {
if (results[0] instanceof Object[]) {
Object[] res = (Object[]) results[0];
hoverText += (String) res[0];
} else {
hoverText += (String) results[0].toString();
}
} else {
hoverText += (String) results[0].toString();
}
} else {
if (zoneXML.getCLat() != null) {
hoverText += "(" + zoneXML.getCLat() + ", "
+ zoneXML.getCLon() + ")";
if (zoneXML.getCLat() != null) {
hoverText += "(" + zoneXML.getCLat() + ", "
+ zoneXML.getCLon() + ")";
}
}
} catch (Exception e) {
statusHandler.error("Unable to query Zone Hover Text: sql: "+sql, e);
}
} catch (Exception e) {
e.printStackTrace();
tableUtil.zoneHoverTextMap.put(zone, hoverText);
}
return hoverText;
@ -1025,41 +1061,50 @@ public final class TableUtil {
*/
private static String getStationHoverText(String stnId) {
String sql = "select catalogtype, name from common_obs_spatial where ( catalogtype=1 or catalogtype=33 or catalogtype = 32 or catalogtype=1000) and stationid = '"
+ stnId + "'";
String hoverText = null;
ISpatialQuery sq = null;
Integer stnType = null;
String stnName = null;
try {
sq = SpatialQueryFactory.create();
Object[] results = sq.dbRequest(sql, "metadata");
if (results.length > 0) {
if (results[0] instanceof Object[]) {
Object[] res = (Object[]) results[0];
stnType = (Integer) res[0];
stnName = (String) res[1];
String hoverText = tableUtil.stationHoverTextMap.get(stnId);
if (hoverText == null) {
String sql = "select catalogtype, name from common_obs_spatial where ( catalogtype=1 or catalogtype=33 or catalogtype = 32 or catalogtype=1000) and stationid = '"
+ stnId + "'";
ISpatialQuery sq = null;
Integer stnType = null;
String stnName = null;
try {
sq = SpatialQueryFactory.create();
Object[] results = sq.dbRequest(sql, "metadata");
if (results.length > 0) {
if (results[0] instanceof Object[]) {
Object[] res = (Object[]) results[0];
stnType = (Integer) res[0];
stnName = (String) res[1];
} else {
stnType = (Integer) results[0];
stnName = (String) results[1];
}
if (stnType.intValue() == 1) {
hoverText = stnId + "#METAR -- " + stnName;
} else if (stnType.intValue() == 33
|| stnType.intValue() == 32) {
hoverText = stnId + "#MARITIME -- " + stnName;
} else if (stnType.intValue() == 1000) {
hoverText = stnId + "#MESONET -- " + stnName;
}
} else {
stnType = (Integer) results[0];
stnName = (String) results[1];
}
if (stnType.intValue() == 1) {
hoverText = stnId + "#METAR -- " + stnName;
} else if (stnType.intValue() == 33 || stnType.intValue() == 32) {
hoverText = stnId + "#MARITIME -- " + stnName;
} else if (stnType.intValue() == 1000) {
hoverText = stnId + "#MESONET -- " + stnName;
}
} else {
hoverText = stnId;
}
} catch (Exception e) {
statusHandler.error("Unable to query Station Hover Text: sql: "+sql, e);
}
} catch (Exception e) {
e.printStackTrace();
tableUtil.stationHoverTextMap.put(stnId, hoverText);
}
return hoverText;
}
/**