Merge branch 'omaha_16.1.1' of ssh://awips2omaha.com:29418/AWIPS2_baseline into master_16.1.1

Former-commit-id: 8d226c9b37cffc193340db848d31c93094ffe1ee
This commit is contained in:
Shawn.Hooper 2015-10-28 22:31:39 -04:00
commit f14284a075
6 changed files with 312 additions and 142 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>
*
@ -78,6 +77,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,15 +66,38 @@ 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;
/**
* Constructor
*/
private TableUtil() {
}
/** 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;
/**
* 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>();
}
/**
* Returns the nominal time for a caller-specified time (to be consistent
* with D2D, here "Nominal time" is defined as the hour of an one-hour
@ -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);
if (hoverText == null) {
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 + "'";
}
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];
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;
}
/**

View file

@ -38,6 +38,7 @@ import com.raytheon.viz.texteditor.TextWarningConstants;
* ------------ ---------- ----------- --------------------------
* 06182008 bwoodle additional format method overloads, javadocs.
* Sep 12, 2014 ASM RM#15551 Qinglu Lin Added formatUseNoonMidnight().
* Oct 21, 2015 5022 randerso Changes for mixed case WarnGen products
*
* </pre>
*
@ -110,11 +111,14 @@ public class DateUtil {
return str;
}
public String formatUseNoonMidnight(Date date, DateFormat format, int interval, String tz) {
return formatUseNoonMidnight(date, format, interval, getTimeZoneFromString(tz));
public String formatUseNoonMidnight(Date date, DateFormat format,
int interval, String tz) {
return formatUseNoonMidnight(date, format, interval,
getTimeZoneFromString(tz));
}
public String formatUseNoonMidnight(Date date, DateFormat format, int interval, TimeZone tz) {
public String formatUseNoonMidnight(Date date, DateFormat format,
int interval, TimeZone tz) {
String str;
Date workingDate = date;
if (interval > 0) {
@ -125,9 +129,9 @@ public class DateUtil {
str = format.format(workingDate);
}
Matcher m = timePtrn.matcher(str);
if(m.find()) {
str = str.replace("1200 AM", "MIDNIGHT");
str = str.replace("1200 PM", "NOON");
if (m.find()) {
str = str.replace("1200 AM", "midnight");
str = str.replace("1200 PM", "noon");
}
return str;
}
@ -194,11 +198,11 @@ public class DateUtil {
Matcher m = periodPtrn.matcher(format(date, format, interval, tz));
if (m.find()) {
if (m.group(2).equalsIgnoreCase("AM")) {
return " MORNING";
return " morning";
} else if (Integer.parseInt(m.group(1)) < 600) {
return " AFTERNOON";
return " afternoon";
} else {
return " EVENING";
return " evening";
}
} else {
return "";

View file

@ -44,6 +44,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
* single request.
* Mar 05, 2015 4217 mapeters Available times are sorted in DataAccessLayer.
* May 12, 2015 4409 mapeters Fix spacing in assembleGetData().
* Oct 23, 2015 5013 mapeters Alias automatically retrieved columns in assembleGetData().
*
* </pre>
*
@ -59,6 +60,10 @@ public class HydroQueryAssembler {
private static final String LID_COL = "lid";
private static final String TIME_COL_ALIAS = "timeColumn" + TIME_COL;
private static final String LID_COL_ALIAS = "locationColumn" + LID_COL;
/**
* Don't allow instantiation
*/
@ -107,11 +112,13 @@ public class HydroQueryAssembler {
private static CharSequence assembleGetData(IDataRequest request,
CharSequence timeConstraint) {
StringBuilder sb = new StringBuilder();
// this method assembles a sql string such as:
// select d.lid, d.productttime, d.value, l.lat, l.lon from height d,
// location l where d.lid = 'ABRN1' and d.lid = l.lid;
// It is requesting the lat/lons of the location every time which
// could potentially be improved in efficiency.
/*
* this method assembles a sql string such as: select d.lid as
* locationColumnlid, d.producttime as timeColumnproducttime, d.value,
* l.lat, l.lon from height d, location l where d.lid = 'ABRN1' and
* d.lid = l.lid; It is requesting the lat/lons of the location every
* time which could potentially be improved in efficiency.
*/
// select
sb.append(buildSelectParams(request));
@ -123,10 +130,13 @@ public class HydroQueryAssembler {
CharSequence where = buildWhere(request, timeConstraint);
if (where.length() > 0) {
sb.append(where);
sb.append(" and d.lid = l.lid");
sb.append(" and ");
} else {
sb.append(" where d.lid = l.lid");
sb.append(" where ");
}
sb.append("d.lid = l.lid");
// order by
sb.append(buildOrderByTime());
sb.append(";");
@ -163,8 +173,9 @@ public class HydroQueryAssembler {
}
/**
* Assembles a select statement of a query, such as
* "select d.lid, d.producttime, l.lat, l.lon, d.value"
* Assembles a select statement of a query, such as "select d.lid as
* locationColumnlid, d.producttime as timeColumnproducttime, l.lat, l.lon,
* d.value"
*
* @param request
* the request to form a select statement on
@ -174,10 +185,10 @@ public class HydroQueryAssembler {
StringBuilder sb = new StringBuilder();
// always want the location name and time even if they didn't request it
// so that returned objects will have that information
sb.append("select d.");
sb.append(LID_COL);
sb.append(", d.");
sb.append(TIME_COL);
sb.append("select d.").append(LID_COL).append(" as ")
.append(LID_COL_ALIAS);
sb.append(", d.").append(TIME_COL).append(" as ")
.append(TIME_COL_ALIAS);
// request lat and lon for the returned geometry objects
sb.append(", l.lat, l.lon");