hydro feature plugin addback for 18.1.1

This commit is contained in:
mjames-upc 2018-07-26 09:56:33 -06:00
parent faa652da31
commit f382cd5a09
1207 changed files with 844554 additions and 9 deletions

View file

@ -0,0 +1,7 @@
<?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

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.cwat</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

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.cwat;singleton:=true
Bundle-Version: 1.15.0.qualifier
Bundle-Vendor: RAYTHEON
Require-Bundle: com.raytheon.uf.common.dataplugin.cwat,
com.raytheon.uf.common.colormap,
com.raytheon.uf.common.monitor,
com.raytheon.uf.common.style,
com.raytheon.uf.viz.core.grid;bundle-version="1.15.0",
com.raytheon.uf.viz.core;bundle-version="1.15.1",
com.raytheon.uf.common.dataplugin;bundle-version="1.14.0",
com.raytheon.uf.common.datastorage;bundle-version="1.15.0",
com.raytheon.uf.common.geospatial;bundle-version="1.14.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.viz.cwat

View file

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

View file

@ -0,0 +1,44 @@
<?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="com.raytheon.uf.viz.core.resource">
<resource
class="com.raytheon.uf.viz.cwat.CWATResource"
name="cwat"
recordClass="com.raytheon.uf.common.dataplugin.cwat.CWATRecord"
renderingOrderId="IMAGE_LOCAL"
resourceType="PLAN_VIEW"/>
</extension>
<!-- for making CWAT available on Localization Perspective in CAVE: 2012-05-14 from DHladky -->
<extension
point="com.raytheon.uf.viz.localization.perspective.localizationpath">
<path
application="D2D"
localizationType="common_static"
name="CWAT"
recursive="true"
value="cwat">
</path>
</extension>
</plugin>

View file

@ -0,0 +1,121 @@
/**
* 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.cwat;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import com.raytheon.uf.common.dataplugin.HDF5Util;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.cwat.CWATRecord;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
* CWATResourceData
*
* Implements contouring for cwat data
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 15Mar2009 2037 dhladky Initial Creation.
* Feb 28, 2013 1731 bsteffen Remove unneccessary query in
* getDataStore.
*
* </pre>
*
* @author dhladky
* @version 1
*/
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "cwatResourceData")
public class CWATResourceData extends AbstractRequestableResourceData {
public CWATRecord[] records;
public Map<DataTime, CWATRecord> dataObjectMap;
@Override
protected AbstractVizResource<?, ?> constructResource(
LoadProperties loadProperties, PluginDataObject[] objects) {
records = new CWATRecord[objects.length];
dataObjectMap = new HashMap<DataTime, CWATRecord>();
for (int i = 0; i < objects.length; i++) {
records[i] = (CWATRecord) objects[i];
dataObjectMap.put(records[i].getDataTime(), records[i]);
}
return new CWATResource(this, loadProperties);
}
/**
* @return the records
*/
public CWATRecord[] getRecords() {
return records;
}
/**
* @param records
* the records to set
*/
public void setRecords(CWATRecord[] records) {
this.records = records;
}
/**
* populate CWAT Record
*
* @param record
*/
public CWATRecord populateRecord(CWATRecord record)
throws VizException {
IDataStore dataStore = getDataStore(record);
record.retrieveFromDataStore(dataStore);
return record;
}
/**
* Get the data store
*
* @param record
* @return
*/
private IDataStore getDataStore(CWATRecord record) {
File loc = HDF5Util.findHDF5Location(record);
return DataStoreFactory.getDataStore(loc);
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.d2d.damagepath.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

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="com.raytheon.uf.viz.d2d.damagepath.feature"
label="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>
<requires>
<import feature="com.raytheon.uf.viz.common.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.d2d.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.radar.feature" version="1.0.0.qualifier"/>
</requires>
<plugin
id="com.raytheon.uf.viz.damagepath"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.raytheon.uf.common.damagepath"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View file

@ -0,0 +1,7 @@
<?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

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.damagepath</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

@ -0,0 +1,23 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Damage Path
Bundle-SymbolicName: com.raytheon.uf.viz.damagepath;singleton:=true
Bundle-Version: 1.16.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.raytheon.uf.viz.core,
com.raytheon.uf.viz.drawing,
com.raytheon.uf.common.time,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.json,
org.eclipse.core.runtime;bundle-version="3.8.0",
com.raytheon.viz.ui,
com.raytheon.viz.awipstools,
com.raytheon.viz.radar,
javax.measure;bundle-version="1.0.0",
com.raytheon.uf.common.util,
com.raytheon.uf.common.damagepath,
com.raytheon.uf.common.message,
org.apache.commons.lang3;bundle-version="3.4.0"
Export-Package: com.raytheon.uf.viz.damagepath
Bundle-ClassPath: com.raytheon.uf.viz.damagepath.jar

View file

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

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="com.raytheon.viz.ui.contextualMenu">
<contextualMenu
actionClass="com.raytheon.uf.viz.damagepath.NewTornadoDamagePathAction"
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
name="New Tornado Damage Path"
sortID="4">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.damagepath.ExportToLdadAction"
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
name="Export to LDAD"
sortID="5">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.damagepath.ExportDamagePathAction"
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
name="Export to File"
sortID="6">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.damagepath.ImportDamagePathAction"
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
name="Import from File"
sortID="7">
</contextualMenu>
</extension>
<extension
point="com.raytheon.uf.viz.localization.perspective.localizationpath">
<path
application="D2D"
extensionFilter=".xml"
localizationType="COMMON_STATIC"
name="Damage Path"
recursive="false"
value="damagepath">
</path>
</extension>
</plugin>

View file

@ -0,0 +1,144 @@
/**
* 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.damagepath;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
/**
* Utility class for the damage path tool's GeoJSON format.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 18, 2016 #5287 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class DamagePathGeoJsonUtils {
private static final FastDateFormat DAMAGE_PATH_DATE_FORMAT = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT;
static final String EVENTID_PROP_NAME = "eventID";
static final String HAZARD_TYPE_PROP_NAME = "hazard";
static final String NAME_PROP_NAME = "name";
static final String EVENT_TIME_PROP_NAME = "eventTime";
static final String COMMENTS_PROP_NAME = "comments";
static final String SITEID_PROP_NAME = "cwa";
static final String WORKSTATION_PROP_NAME = "workstation";
static final String USER_PROP_NAME = "user";
private DamagePathGeoJsonUtils() {
throw new AssertionError();
}
/**
* Ensures the required properties for the damage path tool's GeoJSON format
* (event time, event ID, creating CWA, creating workstation and creating
* user) have been filled. If not any missing properties will be filled and
* the properties map returned.
*
* @param geoJsonProperties
* A damage path polygon's properties map
* @return A copy of the properties map with any missing required properties
* populated.
*/
public static Map<String, String> fillRequiredProperties(
Map<String, String> geoJsonProperties) {
Map<String, String> validatedProps = new HashMap<>(geoJsonProperties);
if (!validatedProps.containsKey(EVENTID_PROP_NAME)) {
validatedProps.put(EVENTID_PROP_NAME, generateEventID());
}
if (!validatedProps.containsKey(EVENT_TIME_PROP_NAME)) {
validatedProps.put(EVENT_TIME_PROP_NAME,
formatEventTime(getDefaultEventTime()));
}
if (!validatedProps.containsKey(SITEID_PROP_NAME)) {
validatedProps.put(SITEID_PROP_NAME, getDefaultSiteID());
}
if (!validatedProps.containsKey(WORKSTATION_PROP_NAME)) {
validatedProps
.put(WORKSTATION_PROP_NAME, getDefaultWorkstationID());
}
if (!validatedProps.containsKey(USER_PROP_NAME)) {
validatedProps.put(USER_PROP_NAME, getDefaultUser());
}
return validatedProps;
}
public static String generateEventID() {
return UUID.randomUUID().toString();
}
public static Date getDefaultEventTime() {
return SimulatedTime.getSystemTime().getTime();
}
public static String formatEventTime(Date date) {
return DateFormatUtils.formatUTC(date,
DAMAGE_PATH_DATE_FORMAT.getPattern());
}
public static Date parseDateString(String dateString) throws ParseException {
return DAMAGE_PATH_DATE_FORMAT.parse(dateString);
}
public static String getDefaultUser() {
return VizApp.getWsId().getUserName();
}
public static String getDefaultWorkstationID() {
return VizApp.getWsId().getHostName();
}
public static String getDefaultSiteID() {
return LocalizationManager.getInstance().getCurrentSite();
}
}

View file

@ -0,0 +1,218 @@
/**
* 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.damagepath;
import java.util.Collection;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.commons.lang.StringUtils;
/**
* Class to represent configured list of possible hazard causes for a damage
* path. Default file is common_static/damagepath/hazard-types.xml.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 27, 2016 #5287 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@XmlRootElement(name = "HazardTypes")
@XmlAccessorType(XmlAccessType.NONE)
public class DamagePathHazardTypes {
@XmlRootElement(name = "hazard")
@XmlAccessorType(XmlAccessType.NONE)
public static class HazardTypeProperties {
@XmlElement
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
private String longName;
@XmlElement
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
private String abbreviation;
/**
* Default constructor. Should not be used except by JAXB to unmarshal
* data from XML.
*/
public HazardTypeProperties() {
this(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* Construct an instance of this object with the specified name and
* abbreviation.
*
* @param longName
* Long form description of the hazard.
* @param abbreviation
* Abbreviation for the hazard. Convention is to use 2
* characters.
*/
public HazardTypeProperties(String longName, String abbreviation) {
this.longName = longName;
this.abbreviation = abbreviation;
}
/**
* Takes the given UI string representation of the object and parses out
* just the abbreviation. Expected format is
* "<longName> (<abbreviation>)".
*
* @param uiString
* @return
*/
public static String getAbbreviationFromUIString(String uiString) {
int idx = uiString.lastIndexOf('(');
if (idx > -1) {
return uiString.substring(idx + 1, idx + 3);
}
return StringUtils.EMPTY;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("HazardTypeProperties [longName=");
builder.append(longName);
builder.append(", abbreviation=");
builder.append(abbreviation);
builder.append("]");
return builder.toString();
}
/**
* Returns a string representation of the object useful for display in
* UI elements.
*
* @return UI-friendly string representation of this object.
*/
public String toUIString() {
StringBuilder builder = new StringBuilder();
builder.append(longName);
builder.append(" (");
builder.append(abbreviation);
builder.append(")");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((abbreviation == null) ? 0 : abbreviation.hashCode());
result = prime * result
+ ((longName == null) ? 0 : longName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
HazardTypeProperties other = (HazardTypeProperties) obj;
if (abbreviation == null) {
if (other.abbreviation != null) {
return false;
}
} else if (!abbreviation.equals(other.abbreviation)) {
return false;
}
if (longName == null) {
if (other.longName != null) {
return false;
}
} else if (!longName.equals(other.longName)) {
return false;
}
return true;
}
public String getLongName() {
return longName;
}
public void setLongName(String longName) {
this.longName = longName;
}
public String getAbbreviation() {
return abbreviation;
}
public void setAbbreviation(String abbreviation) {
this.abbreviation = abbreviation;
}
}
@XmlElementRef
private Collection<HazardTypeProperties> hazards;
/**
* Default constructor. Should not be used except by JAXB to unmarshal data
* from XML.
*/
public DamagePathHazardTypes() {
}
/**
* Constructs a new instance of this object with the given collection of
* {@code HazardTypeProperties} objects.
*
* @param hazards
*/
public DamagePathHazardTypes(Collection<HazardTypeProperties> hazards) {
this.setHazards(hazards);
}
public Collection<HazardTypeProperties> getHazards() {
return hazards;
}
public void setHazards(Collection<HazardTypeProperties> hazards) {
this.hazards = hazards;
}
}

View file

@ -0,0 +1,378 @@
/**
* 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.damagepath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IMenuManager;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.raytheon.uf.common.json.geo.GeoJsonMapUtil;
import com.raytheon.uf.common.json.geo.IGeoJsonService;
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.ILocalizationFile;
import com.raytheon.uf.common.localization.ILocalizationFileObserver;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.SaveableOutputStream;
import com.raytheon.uf.common.util.Pair;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
import com.raytheon.uf.viz.drawing.polygon.PolygonUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
/**
* A layer for displaying and customizing a weather event's damage path.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 19, 2015 3974 njensen Initial creation
* Mar 31, 2015 3977 nabowle Reset polygon when initializing from the
* localization file fails.
* Apr 23, 2015 4354 dgilling Support GeoJSON Feature properties.
* Jun 03, 2015 4375 dgilling Support changes to PolygonLayer for
* multiple polygon support.
* Jun 08, 2015 4355 dgilling Fix NullPointerException in loadJob.
* Jun 12, 2015 4375 dgilling Fix ConcurrentModificationException in
* initInternal.
* Jun 18, 2015 4354 dgilling Allow each polygon to have their own
* properties.
* Jul 01, 2015 4375 dgilling Fix setDefaultPolygon.
* Jul 07, 2015 4375 dgilling Better error message for loadJob, make it
* INFO level, fix geotools CRS warning.
* Aug 05, 2015 4635 dgilling Default save location for damage path
* is now at SITE level.
* Aug 18, 2015 3806 njensen Use SaveableOutputStream to save
* Jan 11, 2016 5242 kbisanz Replaced calls to deprecated LocalizationFile methods
* Feb 18, 2016 5287 dgilling Updated for new metadata fields.
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class DamagePathLayer<T extends DamagePathResourceData> extends
PolygonLayer<T> implements ILocalizationFileObserver {
protected static final String NAME = "Damage Path";
private static final String DIR = "damagepath";
/*
* TODO: Since we've decided to use only 1 working file for this layer,
* there's no need to append numbers to the end of the file name. In some
* future release, remove this constant.
*/
private static final String OLD_FILE = "damagepath1.json";
private static final String FILE = "damagepath.json";
/*
* TODO: Since we've decided to use only 1 working file for this layer,
* there's no need to append numbers to the end of the file name. In some
* future release, remove this constant.
*/
private static final String OLD_PATH = DIR + IPathManager.SEPARATOR
+ OLD_FILE;
private static final String PATH = DIR + IPathManager.SEPARATOR + FILE;
/**
* JVM property to specify the localization level to attempt to save/load
* with. Falls back to SITE if not defined.
*/
private static final LocalizationLevel LEVEL_TO_USE = LocalizationLevel
.valueOf(System.getProperty("damage.path.localization.level",
LocalizationLevel.SITE.name()));
private final Job loadJob = new Job("Loading Damage Path") {
@Override
protected IStatus run(IProgressMonitor monitor) {
ILocalizationFile prevFile = getValidDamagePathFile();
if (prevFile != null) {
loadDamagePath(prevFile);
// reset the polygon if the localization file is invalid.
if (polygons.isEmpty()) {
statusHandler
.info("The previously saved damage path file didn't contain any polygons. Resetting to default polygon.");
setDefaultPolygon();
}
} else {
setDefaultPolygon();
}
return Status.OK_STATUS;
}
};
private final Job saveJob = new Job("Saving Damage Path") {
@Override
protected IStatus run(IProgressMonitor monitor) {
ILocalizationFile file = getDamagePathFile();
saveDamagePath(file);
return Status.OK_STATUS;
}
};
public DamagePathLayer(T resourceData, LoadProperties loadProperties) {
super(resourceData, loadProperties);
// listen for changes to the directory
LocalizationFile dir = getDamagePathFile();
dir.addFileUpdatedObserver(this);
loadJob.setSystem(true);
saveJob.setSystem(true);
}
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
super.initInternal(target);
loadJob.schedule();
}
private void setDefaultPolygon() {
Polygon polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer()
.getActiveDisplayPane().getRenderableDisplay());
DrawablePolygon drawablePolygon = new DamagePathPolygon(polygon, this);
super.resetPolygons(Arrays.asList(drawablePolygon));
}
@Override
protected void disposeInternal() {
LocalizationFile dir = PathManagerFactory.getPathManager()
.getLocalizationFile(getContext(), DIR);
dir.removeFileUpdatedObserver(this);
super.disposeInternal();
}
@Override
public String getName() {
return NAME;
}
@Override
public void resetPolygon(int index, Coordinate[] coords) {
Polygon prevPolygon = getPolygon(index);
// this call will alter the polygon unless coords is null
super.resetPolygon(index, coords);
Polygon newPolygon = getPolygon(0);
/*
* only bother saving the polygon if they're done dragging
*/
if ((prevPolygon == null && newPolygon != null)
|| (newPolygon != null && !this.uiInput.isDragging())) {
saveJob.schedule();
}
}
private LocalizationContext getContext() {
return PathManagerFactory.getPathManager().getContext(
LocalizationType.COMMON_STATIC, LEVEL_TO_USE);
}
protected LocalizationFile getDamagePathFile() {
LocalizationContext ctx = getContext();
return PathManagerFactory.getPathManager().getLocalizationFile(ctx,
PATH);
}
/*
* TODO: Since we've decided to use only 1 working file for this layer,
* there's no need to append numbers to the end of the file name. In some
* future release, remove this function and replace uses with
* getDamagePathFile.
*/
private ILocalizationFile getValidDamagePathFile() {
LocalizationContext ctx = getContext();
ILocalizationFile file = PathManagerFactory.getPathManager()
.getLocalizationFile(ctx, PATH);
ILocalizationFile oldFile = PathManagerFactory.getPathManager()
.getLocalizationFile(ctx, OLD_PATH);
if (file.exists()) {
return file;
} else if (oldFile.exists()) {
return oldFile;
} else {
return null;
}
}
@Override
public void fileUpdated(FileUpdatedMessage message) {
if (message.getFileName().equals(PATH)) {
ILocalizationFile file = getDamagePathFile();
if (file.exists()) {
loadDamagePath(file);
}
}
}
protected void loadDamagePath(ILocalizationFile file) {
try {
DamagePathLoader loader = new DamagePathLoader(file);
Collection<Pair<Polygon, Map<String, String>>> newData = loader
.getDamagePathData();
if (!newData.isEmpty()) {
Collection<DrawablePolygon> newDamagePaths = new ArrayList<>(
newData.size());
for (Pair<Polygon, Map<String, String>> data : newData) {
newDamagePaths.add(new DamagePathPolygon(data.getFirst(),
data.getSecond(), this));
}
/*
* specifically call super.resetPolygon() cause
* this.resetPolygon() will save the file and we don't want to
* do that or we could infinite loop of load, save, load,
* save...
*/
super.resetPolygons(newDamagePaths);
}
} catch (Exception e) {
statusHandler.error(
"Error loading damage path file " + file.getPath(), e);
}
}
protected void saveDamagePath(ILocalizationFile file) {
try (SaveableOutputStream sos = file.openOutputStream()) {
IGeoJsonService json = new SimpleGeoJsonService();
SimpleFeatureCollection featureCollection = buildFeatureCollection();
json.serialize(featureCollection, sos);
sos.save();
} catch (Throwable t) {
statusHandler.error(
"Error saving damage path file " + file.getPath(), t);
}
}
private SimpleFeature buildFeature(final DamagePathPolygon damagePath) {
Map<String, String> jsonProps = damagePath.getProperties();
jsonProps = DamagePathGeoJsonUtils.fillRequiredProperties(jsonProps);
String id = jsonProps.get(DamagePathGeoJsonUtils.EVENTID_PROP_NAME);
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
typeBuilder.setName("feature");
typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
Geometry polygon = damagePath.getPolygon();
typeBuilder.setDefaultGeometry("the_geom");
typeBuilder.add("the_geom", polygon.getClass());
Collection<String> keysToIgnore = Arrays.asList(GeoJsonMapUtil.ID_KEY);
Set<String> keySet = jsonProps.keySet();
List<Object> values = new ArrayList<Object>(keySet.size());
for (String key : keySet) {
if (!keysToIgnore.contains(key)) {
Object val = jsonProps.get(key);
typeBuilder.add(key, val.getClass());
values.add(val);
}
}
SimpleFeatureType type = typeBuilder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
if (polygon != null) {
featureBuilder.add(polygon);
}
featureBuilder.addAll(values);
return featureBuilder.buildFeature(id);
}
public SimpleFeatureCollection buildFeatureCollection() {
List<SimpleFeature> features = new ArrayList<>(polygons.size());
for (DrawablePolygon polygon : polygons) {
features.add(buildFeature((DamagePathPolygon) polygon));
}
return DataUtilities.collection(features);
}
@Override
public void addPolygon(Coordinate[] coords) {
super.addPolygon(new DamagePathPolygon(coords, this));
saveJob.schedule();
}
@Override
public void deletePolygon(int index) {
super.deletePolygon(index);
saveJob.schedule();
}
@Override
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
if (!getCapability(EditableCapability.class).isEditable()) {
return;
}
super.addContextMenuItems(menuManager, x, y);
int onPolygonIdx = uiInput.pointOnPolygon(x, y);
if (onPolygonIdx >= 0) {
menuManager.add(new OpenGeoJsonPropertiesDlgAction(
(DamagePathPolygon) polygons.get(onPolygonIdx)));
}
}
@Override
protected DrawablePolygon getNewDrawable() {
return new DamagePathPolygon(this);
}
protected void scheduleSaveJob() {
saveJob.schedule();
}
}

View file

@ -0,0 +1,161 @@
/**
* 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.damagepath;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import com.raytheon.uf.common.json.JsonException;
import com.raytheon.uf.common.json.geo.IGeoJsonService;
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
import com.raytheon.uf.common.localization.ILocalizationFile;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.util.Pair;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
/**
* Loads a damage path GeoJSON-formatted file from either local disk or the
* localization file store.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 05, 2015 #4375 dgilling Initial creation
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each polygon
* can have its own properties.
* Jun 30, 2015 #4354 dgilling Remove unnecessary back compat code for
* 15.1 version of damage path tool.
* Jul 01, 2015 #4375 dgilling Remove isValid check to imported
* polygons.
* Jan 11, 2016 #5242 kbisanz Replaced calls to deprecated LocalizationFile methods
* Feb 18, 2016 #5287 dgilling Updated for new metadata fields.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public final class DamagePathLoader {
private static final String UNSUPPORTED_GEOM_TYPE = "Damage path file contains invalid geometry type %s at geometry index %d. Must only contain Polygons.";
private final Collection<Pair<Polygon, Map<String, String>>> damagePathData;
public DamagePathLoader(ILocalizationFile locFile)
throws LocalizationException, IOException, JsonException {
this(locFile, null);
}
public DamagePathLoader(String filePath) throws LocalizationException,
IOException, JsonException {
this(null, Paths.get(filePath));
}
private DamagePathLoader(ILocalizationFile locFileSource,
Path realFileSource) throws LocalizationException, IOException,
JsonException {
this.damagePathData = new ArrayList<>();
if (locFileSource != null) {
loadFromLocalizationFile(locFileSource);
} else {
loadFromFileSystem(realFileSource);
}
}
public Collection<Pair<Polygon, Map<String, String>>> getDamagePathData() {
return damagePathData;
}
private void loadFromLocalizationFile(final ILocalizationFile locFile)
throws LocalizationException, IOException, JsonException {
try (InputStream is = locFile.openInputStream()) {
loadFromInputStream(is);
}
}
private void loadFromFileSystem(final Path filePath) throws IOException,
JsonException {
try (InputStream is = Files.newInputStream(filePath)) {
loadFromInputStream(is);
}
}
private void loadFromInputStream(final InputStream is) throws JsonException {
IGeoJsonService json = new SimpleGeoJsonService();
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = json
.deserializeFeatureCollection(is);
populateDataFromFeatureCollection(featureCollection);
}
private void populateDataFromFeatureCollection(
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection)
throws JsonException {
try (FeatureIterator<SimpleFeature> iter = featureCollection.features()) {
int featureIdx = 0;
while (iter.hasNext()) {
SimpleFeature feature = iter.next();
Geometry geom = (Geometry) feature.getDefaultGeometry();
if (geom instanceof Polygon) {
Polygon newPolygon = (Polygon) geom;
Map<String, String> properties = new LinkedHashMap<>();
Name defaultGeomAttrib = feature
.getDefaultGeometryProperty().getName();
for (Property p : feature.getProperties()) {
if (!defaultGeomAttrib.equals(p.getName())) {
properties.put(p.getName().toString(), p.getValue()
.toString());
}
}
Pair<Polygon, Map<String, String>> polygonAndProps = new Pair<>(
newPolygon, properties);
damagePathData.add(polygonAndProps);
} else {
throw new JsonException(String.format(
UNSUPPORTED_GEOM_TYPE, geom.getGeometryType(),
featureIdx));
}
featureIdx++;
}
}
}
}

View file

@ -0,0 +1,92 @@
/**
* 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.damagepath;
import java.util.Collections;
import java.util.Map;
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Polygon;
/**
* Extension of {@code DrawablePolygon} to support GeoJSON properties.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2015 #4354 dgilling Initial creation
* Jun 30, 2015 #4354 dgilling Force setProperties to trigger a save.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class DamagePathPolygon extends DrawablePolygon {
private static final Map<String, String> DEFAULT_PROPS = Collections
.emptyMap();
private Map<String, String> properties;
public DamagePathPolygon(DamagePathLayer<?> layer) {
super(layer);
this.properties = DEFAULT_PROPS;
}
public DamagePathPolygon(Polygon polygon, DamagePathLayer<?> layer) {
this(polygon, DEFAULT_PROPS, layer);
}
public DamagePathPolygon(Polygon polygon, Map<String, String> properties,
DamagePathLayer<?> layer) {
super(polygon, layer);
this.properties = properties;
}
public DamagePathPolygon(Coordinate[] coords, DamagePathLayer<?> layer) {
super(coords, layer);
this.properties = DEFAULT_PROPS;
}
@Override
public void resetPolygon(DrawablePolygon newPolygon) {
super.resetPolygon(newPolygon);
if (newPolygon instanceof DamagePathPolygon) {
DamagePathPolygon newDamagePath = (DamagePathPolygon) newPolygon;
properties = newDamagePath.getProperties();
}
}
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
((DamagePathLayer<?>) polygonLayer).scheduleSaveJob();
}
}

View file

@ -0,0 +1,80 @@
/**
* 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.damagepath;
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.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
* Resource data for DamagePathLayer.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 2, 2015 3974 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class DamagePathResourceData extends AbstractResourceData {
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon
* .uf.viz.core.rsc.LoadProperties,
* com.raytheon.uf.viz.core.drawables.IDescriptor)
*/
@Override
public AbstractVizResource<?, ?> construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
return new DamagePathLayer<DamagePathResourceData>(this, loadProperties);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#equals(java.lang.Object
* )
*/
@Override
public boolean equals(Object obj) {
if (obj != null) {
return this.getClass().equals(obj.getClass());
}
return false;
}
}

View file

@ -0,0 +1,513 @@
/**
* 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.damagepath;
import java.awt.geom.Point2D;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import javax.measure.converter.UnitConverter;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
import org.geotools.referencing.GeodeticCalculator;
import com.raytheon.uf.common.dataplugin.radar.RadarStation;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline;
import com.raytheon.viz.radar.util.StationUtils;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
/**
* Utility class for Damage Paths.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 3977 nabowle Initial creation
* Mar 26, 2015 3977 nabowle Limit distance to avoid polar errors. Log
* skipped points.
* Apr 01, 2015 3977 nabowle rename the status handler.
* Jun 18, 2015 3977 nabowle Fix buffering. Renamed mehtods to
* specify that they're for Tornados.
* Jun 25, 2015 3977 nabowle Redo inner-point buffering for use with
* Interactive Baselines.
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public class DamagePathUtils {
/**
* The number of degrees between points at the ends of a Tornado Damage Path
* Buffer.
*/
private static final double END_DEGREE_DIFF = 30.0D;
/** Upper degree boundary to define a sharp angle. */
private static final double SHARP_ANGLE = 100;
/** Lower degree boundary when a sharp angle straddles 0 degrees. */
private static final double SHARP_ANGLE_INV = 360 - SHARP_ANGLE;
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(DamagePathUtils.class);
/** Convert miles for the algorithm to meters. */
private static UnitConverter TO_METERS = NonSI.MILE
.getConverterTo(SI.METER);
/*
* Pre-convert algorithm constants to meters to prevent having to convert
* back and forth.
*/
private static final double ONE_TENTH_MILE = TO_METERS.convert(0.1);
private static final double THREE_TENTHS_MILE = TO_METERS.convert(0.3);
private static final double FORTY_MILES = TO_METERS.convert(40.0);
private static final double EIGHTY_MILES = TO_METERS.convert(80.0);
/**
* Maximum distance of a point to the radar station to use when estimating a
* damage path polygon. Any farther point will be ignored. Based on radar
* max extent
*/
private static final double MAX_DISTANCE = TO_METERS.convert(300.0);
private DamagePathUtils() {
super();
}
/**
* Estimates a Tornado damage path polygon for a baseline.
*
* @param baseline
* The baseline to create a tornado damage path for.
* @return The estimated tornado damage path polygon for a baseline.
*/
public static Polygon estimateTornadoDamagePath(Baseline baseline) {
Coordinate[] coords = baseline.line.getCoordinates();
RadarStation station = StationUtils.getInstance().getHomeRadarStation();
GeometryFactory gf = new GeometryFactory();
List<Coordinate> skippedCoords = new ArrayList<>();
List<Coordinate> validCoords = new ArrayList<>();
GeodeticCalculator gc = new GeodeticCalculator();
filterCoords(coords, station, skippedCoords, validCoords,
gc);
if (!skippedCoords.isEmpty()) {
StringBuilder sb = new StringBuilder();
sb.append(
"Skipped the following Coordinates for Baseline "
+ baseline.name + " because they ")
.append("are out of range of the radar station. ");
for (Coordinate coord : skippedCoords) {
sb.append("(").append(coord.x).append(", ").append(coord.y)
.append(") ");
}
statusHandler.info(sb.toString());
}
if (validCoords.isEmpty()) {
String suggestion;
if (skippedCoords.isEmpty()) {
suggestion = "Make sure the baseline is initialized.";
} else {
suggestion = "Make sure the baseline is within range of the radar station.";
}
statusHandler
.warn("Could not create a Damage Path polygon for Baseline "
+ baseline.name + ". " + suggestion);
return null;
}
Coordinate[] damagePathCoords = createTornadoBuffer(validCoords, station, gc,
gf);
Polygon polygon = gf.createPolygon(damagePathCoords);
return polygon;
}
/**
* Filter the coordinates based on their range to the given radar station.
*
* @param stormCoords
* The coordinates.
* @param station
* The radar station.
* @param skippedCoords
* A list where coordinates that are out of range of the station
* will be added to.
* @param validCoords
* A list where coordinates that are in range of the station will
* be added to.
* @param gc
* A GeodeticCalculator.
*/
private static void filterCoords(Coordinate[] stormCoords,
RadarStation station, List<Coordinate> skippedCoords,
List<Coordinate> validCoords, GeodeticCalculator gc) {
Coordinate stormCoord;
double distance;
if (stormCoords != null) {
for (int i = 0; i < stormCoords.length; i++) {
stormCoord = stormCoords[i];
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
gc.setDestinationGeographicPoint(station.getLon(),
station.getLat());
distance = gc.getOrthodromicDistance();
if (distance > MAX_DISTANCE) {
skippedCoords.add(stormCoords[i]);
} else {
validCoords.add(stormCoords[i]);
}
}
}
}
/**
* Creates a buffer around the line defined by the storm coordinates using
* Doug Speheger's tornado damage path algorithm.
*
* @param stormCoords
* The storm coordinates to create a damage path around.
* @param station
* The radar station to use.
* @param gc
* A GeodeticCalculator.
* @param gf
* A GeometryFactory.
* @return A Geometry representing an estimated Tornado Damage Path for the
* given storm coordinates. If the no coordinates are provided, null
* is returned.
*/
private static Coordinate[] createTornadoBuffer(List<Coordinate> stormCoords,
RadarStation station, GeodeticCalculator gc, GeometryFactory gf) {
// left hand side points
List<Point2D> lhsPoints = new ArrayList<>();
// right hand side points
Deque<Point2D> rhsPoints = new ArrayDeque<>();
double uncertainty;
Coordinate stormCoord;
/* Create a concave hull for a linear set of coordinates. */
for (int i = 0; i < stormCoords.size(); i++) {
stormCoord = stormCoords.get(i);
uncertainty = calculateUncertainty(station, gc, stormCoord);
if (stormCoords.size() == 1) {
/*
* In the case that there's only one coordinate, draw a circle
* around the point and break out.
*/
for (double d = -180; d < 180; d += END_DEGREE_DIFF) {
gc.setDirection(d, uncertainty);
lhsPoints.add(gc.getDestinationGeographicPoint());
}
break;
}
if (i == 0) {
createStartCap(stormCoords, gc, lhsPoints, uncertainty, i);
} else if (i < stormCoords.size() - 1) {
bufferInnerPoint(stormCoord, stormCoords, gc, lhsPoints,
rhsPoints, uncertainty, i, station);
} else {
createEndCap(stormCoords, gc, rhsPoints, uncertainty, i);
}
}
lhsPoints.addAll(rhsPoints);
Coordinate[] coordinates = new Coordinate[lhsPoints.size() + 1];
Point2D point;
for (int i = 0; i < lhsPoints.size(); i++) {
point = lhsPoints.get(i);
coordinates[i] = new Coordinate(point.getX(), point.getY());
}
coordinates[coordinates.length - 1] = coordinates[0];
return coordinates;
}
/**
* Based off of research done by Doug Speheger comparing surveyed tornado
* paths to manually identified radar tornadic vortex signatures in
* 2008-2012. In the initial dataset, 87% of tornadoes were within this
* range of uncertainty.
*
* Note: All units are in meters. Constants have been pre-converted from
* miles to meters.
*
* @param station
* @param gc
* @param coord
* @return
*/
private static double calculateUncertainty(RadarStation station,
GeodeticCalculator gc, Coordinate coord) {
gc.setStartingGeographicPoint(coord.x, coord.y);
gc.setDestinationGeographicPoint(station.getLon(), station.getLat());
double distance = gc.getOrthodromicDistance();
double uncertainty;
if (distance < FORTY_MILES) {
uncertainty = THREE_TENTHS_MILE + distance * 0.005;
} else if (distance < EIGHTY_MILES) {
uncertainty = ONE_TENTH_MILE + distance * 0.01;
} else {
uncertainty = distance * 0.015 - THREE_TENTHS_MILE;
}
return uncertainty;
}
/**
* Creates a buffer around a non-end point. If the path is on a generally
* straight path, just create two points on opposite sides of the path
* point. If the path coordinate is the vertex of an angle is sharp, create
* a couple points around the outside of the angle and create a single point
* on the inside that's uncertainty-meters from the point and both lines
* creating the angle.
*
* @param stormCoord
* @param stormCoords
* @param gc
* @param lhsPoints
* @param rhsPoints
* @param uncertainty
* @param i
* @param station
*/
private static void bufferInnerPoint(Coordinate stormCoord,
List<Coordinate> stormCoords, GeodeticCalculator gc,
List<Point2D> lhsPoints, Deque<Point2D> rhsPoints,
double uncertainty, int i, RadarStation station) {
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
Coordinate nextCoord = stormCoords.get(i + 1);
gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y);
double azimuthToNext = nonNegativeAzimuth(gc.getAzimuth());
Coordinate prevCoord = stormCoords.get(i - 1);
gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y);
double azimuthToPrev = nonNegativeAzimuth(gc.getAzimuth());
double angle = Math.abs(azimuthToPrev - azimuthToNext);
boolean sharpAngle = (angle <= SHARP_ANGLE && angle > 0)
|| (angle >= SHARP_ANGLE_INV && angle < 360);
if (sharpAngle) {
boolean rhsOnInside = angle <= SHARP_ANGLE ? azimuthToNext < azimuthToPrev
: azimuthToPrev < azimuthToNext;
double bisectionAngle = Math
.toRadians(angle >= SHARP_ANGLE_INV ? (360.0 - angle) / 2
: angle / 2);
gc.setDirection(geodeticAzimuth(azimuthToNext + 180), uncertainty);
if (rhsOnInside) {
lhsPoints.add(gc.getDestinationGeographicPoint());
createOpposingPoints(stormCoord, gc, lhsPoints,
new ArrayDeque<Point2D>(), uncertainty, azimuthToNext,
azimuthToPrev);
double innerUncertainty = Math.abs(uncertainty
/ Math.sin(bisectionAngle));
if (innerUncertainty < uncertainty) {
innerUncertainty = uncertainty;
}
createOpposingPoints(stormCoord, gc, new ArrayList<Point2D>(),
rhsPoints, innerUncertainty, azimuthToNext,
azimuthToPrev);
gc.setDirection(geodeticAzimuth(azimuthToPrev + 180),
uncertainty);
lhsPoints.add(gc.getDestinationGeographicPoint());
} else {
rhsPoints.push(gc.getDestinationGeographicPoint());
createOpposingPoints(stormCoord, gc, new ArrayList<Point2D>(),
rhsPoints, uncertainty, azimuthToNext, azimuthToPrev);
double innerUncertainty = Math.abs(uncertainty
/ Math.sin(bisectionAngle));
if (innerUncertainty < uncertainty) {
innerUncertainty = uncertainty;
}
createOpposingPoints(stormCoord, gc, lhsPoints,
new ArrayDeque<Point2D>(), innerUncertainty,
azimuthToNext, azimuthToPrev);
gc.setDirection(geodeticAzimuth(azimuthToPrev + 180),
uncertainty);
rhsPoints.push(gc.getDestinationGeographicPoint());
}
} else {
createOpposingPoints(stormCoord, gc, lhsPoints, rhsPoints, uncertainty,
azimuthToNext, azimuthToPrev);
}
}
/**
* Create two points at 180 degrees from each other on the imaginary line
* that bisects the angle created at this point.
*
* @param coord
* @param gc
* @param lhsPoints
* @param rhsPoints
* @param uncertainty
* @param azimuthToNext
* @param azimuthToPrev
*/
private static void createOpposingPoints(Coordinate coord,
GeodeticCalculator gc,
List<Point2D> lhsPoints, Deque<Point2D> rhsPoints,
double uncertainty, double azimuthToNext, double azimuthToPrev) {
gc.setStartingGeographicPoint(coord.x, coord.y);
double pointAzimuth = geodeticAzimuth(Math.min(azimuthToNext,
azimuthToPrev)
+ Math.abs(azimuthToPrev - azimuthToNext) / 2);
if (azimuthToNext <= azimuthToPrev) {
pointAzimuth = geodeticAzimuth(pointAzimuth + 180);
}
gc.setDirection(pointAzimuth, uncertainty);
lhsPoints.add(gc.getDestinationGeographicPoint());
pointAzimuth = geodeticAzimuth(pointAzimuth + 180);
gc.setDirection(pointAzimuth, uncertainty);
rhsPoints.push(gc.getDestinationGeographicPoint());
}
/**
* Create's a curved half-circle buffer around the starting coordinate.
*
* @param stormCoords
* @param gc
* @param lhsPoints
* @param uncertainty
* @param i
*/
private static void createStartCap(List<Coordinate> stormCoords,
GeodeticCalculator gc, List<Point2D> lhsPoints, double uncertainty,
int i) {
Coordinate nextCoord = stormCoords.get(i + 1);
gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y);
double azimuthToNext = gc.getAzimuth();
double pointAzimuth = geodeticAzimuth(azimuthToNext + 90);
gc.setDirection(pointAzimuth, uncertainty);
lhsPoints.add(gc.getDestinationGeographicPoint());
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
pointAzimuth = geodeticAzimuth(pointAzimuth + END_DEGREE_DIFF);
gc.setDirection(pointAzimuth, uncertainty);
lhsPoints.add(gc.getDestinationGeographicPoint());
}
}
/**
* Create's a curved half-circle buffer around the ending coordinate.
*
* @param stormCoords
* @param gc
* @param rhsPoints
* @param uncertainty
* @param i
*/
private static void createEndCap(List<Coordinate> stormCoords,
GeodeticCalculator gc, Deque<Point2D> rhsPoints,
double uncertainty, int i) {
Coordinate prevCoord = stormCoords.get(i - 1);
gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y);
double azimuthToPrev = gc.getAzimuth();
double pointAzimuth = geodeticAzimuth(azimuthToPrev - 90);
gc.setDirection(pointAzimuth, uncertainty);
rhsPoints.push(gc.getDestinationGeographicPoint());
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
pointAzimuth = geodeticAzimuth(pointAzimuth - END_DEGREE_DIFF);
gc.setDirection(pointAzimuth, uncertainty);
rhsPoints.push(gc.getDestinationGeographicPoint());
}
}
/**
* Clamps the azimuth to [-180, 180] for use with the GeodeticCalculator.
*
* @param azimuth
* The azimuth.
* @return An equivalent azimuth in [-180, 180].
*/
private static double geodeticAzimuth(double azimuth) {
double az = azimuth;
while (az < -180.0) {
az += 360.0;
}
while (az > 180.0) {
az -= 360.0;
}
return az;
}
/**
* Clamps the azimuth to [0, 360] to simplify the azimath.
*
* @param azimuth
* The azimuth.
* @return An equivalent azimuth in [0, 360].
*/
private static double nonNegativeAzimuth(double azimuth) {
double az = azimuth;
while (az < 0) {
az += 360.0;
}
while (az > 360.0) {
az -= 360.0;
}
return az;
}
}

View file

@ -0,0 +1,398 @@
/**
* 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.damagepath;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
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.SingleTypeJAXBManager;
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.viz.damagepath.DamagePathHazardTypes.HazardTypeProperties;
import com.raytheon.viz.ui.dialogs.CaveJFACEDialog;
import com.raytheon.viz.ui.widgets.DateTimeEntry;
/**
* Dialog to add/remove the key/value pairs that are part of the "properties"
* member object in GeoJSON Feature objects.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2015 #4354 dgilling Initial creation based on dialog from
* lvenable.
* Apr 30, 2015 #4354 dgilling Allow edits to properties.
* Jan 27, 2016 #5287 dgilling Re-write based on CAVEJFACEDialog, use
* pre-defined properties/attributes.
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class EditGeoJsonPropertiesDlg extends CaveJFACEDialog {
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(getClass());
private static final String HAZARD_TYPES_CONFIG_PATH = "damagepath"
+ IPathManager.SEPARATOR + "hazard-types.xml";
private static final boolean SHOW_EVENT_ID = false;
private static final int EVENTID_CHAR_LIMIT = 36;
private static final int NAME_CHAR_LIMIT = 50;
private static final int COMMENTS_CHAR_LIMIT = 200;
private static final int SITEID_FIELD_WIDTH = 3;
private static final int DEFAULT_FIELD_WIDTH = 20;
private final Map<String, String> initialProperties;
private final Map<String, String> newProperties;
private Combo hazardType;
private Text name;
private Text comments;
private DateTimeEntry eventTime;
/**
* Construct an instance of this dialog with the specified initial values.
*
* @param parentShell
* the parent shell
* @param initalProperties
* {@code Map} containing the initial properties and values for
* this damage path.
*/
public EditGeoJsonPropertiesDlg(Shell parentShell,
Map<String, String> initalProperties) {
super(parentShell);
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE);
this.initialProperties = new HashMap<>(initalProperties);
this.newProperties = new HashMap<>();
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("GeoJSON Properties Editor");
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayout(new GridLayout(2, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GC gc = new GC(getShell().getDisplay());
int charWidth = gc.getFontMetrics().getAverageCharWidth();
int lineHeight = gc.getFontMetrics().getHeight();
gc.dispose();
Label eventIDLabel = new Label(composite, SWT.NONE);
eventIDLabel.setText("Event ID:");
GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
eventIDLabel.setLayoutData(gd);
eventIDLabel.setVisible(SHOW_EVENT_ID);
Text eventID = new Text(composite, SWT.SINGLE | SWT.BORDER
| SWT.READ_ONLY);
eventID.setTextLimit(EVENTID_CHAR_LIMIT);
String initialEventID = MapUtils.getString(initialProperties,
DamagePathGeoJsonUtils.EVENTID_PROP_NAME,
DamagePathGeoJsonUtils.generateEventID());
eventID.setText(initialEventID);
newProperties.put(DamagePathGeoJsonUtils.EVENTID_PROP_NAME,
initialEventID);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
gd.widthHint = eventID.computeTrim(0, 0,
(charWidth * EVENTID_CHAR_LIMIT), SWT.DEFAULT).width;
eventID.setLayoutData(gd);
eventID.setVisible(SHOW_EVENT_ID);
Label hazardTypeLabel = new Label(composite, SWT.NONE);
hazardTypeLabel.setText("Hazard Type:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
hazardTypeLabel.setLayoutData(gd);
hazardType = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
hazardType.setItems(getHazards());
String initialHazard = initialProperties
.get(DamagePathGeoJsonUtils.HAZARD_TYPE_PROP_NAME);
if (initialHazard != null) {
initialHazard = initialHazard.trim();
int i = 0;
for (String item : hazardType.getItems()) {
if (HazardTypeProperties.getAbbreviationFromUIString(
item.trim()).equals(initialHazard)) {
hazardType.select(i);
break;
}
i++;
}
}
hazardType.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
Combo comboWidget = (Combo) e.widget;
getButton(IDialogConstants.OK_ID).setEnabled(
!comboWidget.getText().trim().isEmpty());
}
});
Label nameLabel = new Label(composite, SWT.NONE);
nameLabel.setText("Name:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
nameLabel.setLayoutData(gd);
name = new Text(composite, SWT.SINGLE | SWT.BORDER);
name.setTextLimit(NAME_CHAR_LIMIT);
String initialName = initialProperties
.get(DamagePathGeoJsonUtils.NAME_PROP_NAME);
if (initialName != null) {
name.setText(initialName.trim());
}
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
gd.widthHint = name.computeTrim(0, 0, (charWidth * NAME_CHAR_LIMIT),
SWT.DEFAULT).width;
name.setLayoutData(gd);
Label dateTimeLabel = new Label(composite, SWT.NONE);
dateTimeLabel.setText("Event Time:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
dateTimeLabel.setLayoutData(gd);
eventTime = new DateTimeEntry(composite);
eventTime.setTimeZone(TimeUtil.GMT_TIME_ZONE);
Date initialEventTime = DamagePathGeoJsonUtils.getDefaultEventTime();
String initialEventTimeString = initialProperties
.get(DamagePathGeoJsonUtils.EVENT_TIME_PROP_NAME);
if (initialEventTimeString != null) {
try {
initialEventTime = DamagePathGeoJsonUtils
.parseDateString(initialEventTimeString);
} catch (ParseException e) {
statusHandler.warn("Encountered invalid event time format: "
+ initialEventTimeString);
}
}
eventTime.setDate(initialEventTime);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
eventTime.setLayoutData(gd);
Label commentsLabel = new Label(composite, SWT.NONE);
commentsLabel.setText("Comments:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
commentsLabel.setLayoutData(gd);
comments = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP
| SWT.BORDER);
comments.setTextLimit(COMMENTS_CHAR_LIMIT);
String initialComments = initialProperties
.get(DamagePathGeoJsonUtils.COMMENTS_PROP_NAME);
if (initialComments != null) {
comments.setText(initialComments.trim());
}
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
int numLines = COMMENTS_CHAR_LIMIT / NAME_CHAR_LIMIT;
Rectangle commentsTrimSize = comments.computeTrim(0, 0,
(charWidth * NAME_CHAR_LIMIT), (lineHeight * numLines));
gd.widthHint = commentsTrimSize.width;
gd.heightHint = commentsTrimSize.height;
comments.setLayoutData(gd);
Label siteIdLabel = new Label(composite, SWT.NONE);
siteIdLabel.setText("CWA:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
siteIdLabel.setLayoutData(gd);
Text siteID = new Text(composite, SWT.SINGLE | SWT.BORDER
| SWT.READ_ONLY);
String caveSiteID = DamagePathGeoJsonUtils.getDefaultSiteID();
String initialSiteID = MapUtils.getString(initialProperties,
DamagePathGeoJsonUtils.SITEID_PROP_NAME, caveSiteID);
siteID.setText(initialSiteID);
newProperties.put(DamagePathGeoJsonUtils.SITEID_PROP_NAME,
initialSiteID);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
gd.widthHint = siteID.computeTrim(0, 0,
(charWidth * SITEID_FIELD_WIDTH), SWT.DEFAULT).width;
siteID.setLayoutData(gd);
Label workstationLabel = new Label(composite, SWT.NONE);
workstationLabel.setText("Workstation:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
workstationLabel.setLayoutData(gd);
Text workstationID = new Text(composite, SWT.SINGLE | SWT.BORDER
| SWT.READ_ONLY);
String caveWorkstationID = DamagePathGeoJsonUtils
.getDefaultWorkstationID();
String initialWorkstationID = MapUtils
.getString(initialProperties,
DamagePathGeoJsonUtils.WORKSTATION_PROP_NAME,
caveWorkstationID);
workstationID.setText(initialWorkstationID);
newProperties.put(DamagePathGeoJsonUtils.WORKSTATION_PROP_NAME,
initialWorkstationID);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
gd.widthHint = workstationID.computeTrim(0, 0,
(charWidth * DEFAULT_FIELD_WIDTH), SWT.DEFAULT).width;
workstationID.setLayoutData(gd);
Label userLabel = new Label(composite, SWT.NONE);
userLabel.setText("User:");
gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true);
userLabel.setLayoutData(gd);
Text userID = new Text(composite, SWT.SINGLE | SWT.BORDER
| SWT.READ_ONLY);
String caveUserName = DamagePathGeoJsonUtils.getDefaultUser();
String initialUserID = MapUtils.getString(initialProperties,
DamagePathGeoJsonUtils.USER_PROP_NAME, caveUserName);
userID.setText(initialUserID);
newProperties.put(DamagePathGeoJsonUtils.USER_PROP_NAME, initialUserID);
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true);
gd.widthHint = userID.computeTrim(0, 0,
(charWidth * DEFAULT_FIELD_WIDTH), SWT.DEFAULT).width;
userID.setLayoutData(gd);
return composite;
}
@Override
protected Control createButtonBar(Composite parent) {
Control buttonBar = super.createButtonBar(parent);
getButton(IDialogConstants.OK_ID).setEnabled(
!hazardType.getText().trim().isEmpty());
return buttonBar;
}
private String[] getHazards() {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationFile file = pathMgr.getStaticLocalizationFile(
LocalizationType.COMMON_STATIC, HAZARD_TYPES_CONFIG_PATH);
String[] items;
if (file != null) {
try (InputStream inStream = file.openInputStream()) {
SingleTypeJAXBManager<DamagePathHazardTypes> jaxb = SingleTypeJAXBManager
.createWithoutException(DamagePathHazardTypes.class);
DamagePathHazardTypes hazTypes = jaxb
.unmarshalFromInputStream(inStream);
Collection<String> itemsFromConfig = new ArrayList<>(hazTypes
.getHazards().size());
for (HazardTypeProperties hazard : hazTypes.getHazards()) {
itemsFromConfig.add(hazard.toUIString());
}
items = itemsFromConfig.toArray(new String[0]);
} catch (IOException | LocalizationException e) {
String msg = String.format(
"Unable to open configuration file %s:",
HAZARD_TYPES_CONFIG_PATH);
statusHandler.error(msg + e.getLocalizedMessage(), e);
items = new String[0];
} catch (Exception e) {
String msg = String.format(
"Unable to read configuration file %s:",
HAZARD_TYPES_CONFIG_PATH);
statusHandler.error(msg + e.getLocalizedMessage(), e);
items = new String[0];
}
} else {
String msg = String
.format("Unable to find configuration file %s in localization store.",
HAZARD_TYPES_CONFIG_PATH);
statusHandler.warn(msg);
items = new String[0];
}
return items;
}
@Override
protected void setReturnCode(int code) {
super.setReturnCode(code);
if (code == OK) {
newProperties.put(DamagePathGeoJsonUtils.HAZARD_TYPE_PROP_NAME,
HazardTypeProperties.getAbbreviationFromUIString(hazardType
.getText().trim()));
newProperties.put(DamagePathGeoJsonUtils.NAME_PROP_NAME, name
.getText().trim());
newProperties.put(DamagePathGeoJsonUtils.COMMENTS_PROP_NAME,
comments.getText().trim());
newProperties
.put(DamagePathGeoJsonUtils.EVENT_TIME_PROP_NAME,
DamagePathGeoJsonUtils.formatEventTime(eventTime
.getDate()));
}
}
/**
* Returns the user-entered properties for this damage path.
*
* @return {@code Map} containing the properties for this damage path. Will
* be empty if user clicked Cancel.
*/
public Map<String, String> getProperties() {
return newProperties;
}
}

View file

@ -0,0 +1,115 @@
/**
* 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.damagepath;
import java.io.FileOutputStream;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.geotools.data.simple.SimpleFeatureCollection;
import com.raytheon.uf.common.json.geo.IGeoJsonService;
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* Action to export a damage path as GeoJSON to a file specified by the user.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 09, 2015 3975 njensen Initial creation
* Apr 23, 2015 4354 dgilling Export as GeoJSON Feature object.
* Jun 05, 2015 4375 dgilling Prompt user before exporting feature
* with no polygons.
* Jun 09, 2015 4355 dgilling Rename action for UI.
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each
* polygon can have its own properties.
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class ExportDamagePathAction extends AbstractRightClickAction {
protected static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ExportDamagePathAction.class);
private static final String CONFIRM_DLG_MSG = "Damage Path has no polygons. Continue with exporting file?";
private static final String CONFIRM_DLG_TITLE = "Damage Path has no polygons!";
protected static final String[] EXTENSIONS = new String[] { "*.json" };
public ExportDamagePathAction() {
super("Export to File");
}
@Override
public void run() {
VizApp.runSync(new Runnable() {
@Override
public void run() {
Shell shell = VizWorkbenchManager.getInstance()
.getCurrentWindow().getShell();
FileDialog fd = new FileDialog(shell, SWT.SAVE);
fd.setFilterExtensions(EXTENSIONS);
String filename = fd.open();
if (filename != null) {
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
SimpleFeatureCollection featureCollection = layer
.buildFeatureCollection();
if (featureCollection.size() < 1) {
boolean export = MessageDialog.openConfirm(shell,
CONFIRM_DLG_TITLE, CONFIRM_DLG_MSG);
if (!export) {
statusHandler
.info("User chose to cancel exporting damage path file because it had no polygons.");
return;
}
}
try (FileOutputStream fos = new FileOutputStream(filename)) {
IGeoJsonService json = new SimpleGeoJsonService();
json.serialize(featureCollection, fos);
} catch (Exception e) {
statusHandler.error(
"Error exporting damage path file to "
+ filename, e);
}
}
}
});
}
}

View file

@ -0,0 +1,128 @@
/**
* 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.damagepath;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.geotools.data.simple.SimpleFeatureCollection;
import com.raytheon.uf.common.damagepath.request.ExportToLdadRequest;
import com.raytheon.uf.common.json.JsonException;
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
import com.raytheon.uf.viz.core.requests.ThriftClient;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* Legend right-click action to take the current {@code DamagePathLayer} data
* and export it to LDAD in GeoJSON format.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 08, 2015 #4355 dgilling Initial creation
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each
* polygon can have its own properties.
* Mar 11, 2016 #5288 dgilling Rewrite to spawn async Job.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class ExportToLdadAction extends AbstractRightClickAction {
private static class ExportDamagePathToLdadJob extends Job {
private static final String PLUGIN_ID = "com.raytheon.uf.viz.damagepath";
private final DamagePathLayer<?> layer;
protected ExportDamagePathToLdadJob(DamagePathLayer<?> layer) {
super("Exporting Damage Path to LDAD");
this.layer = layer;
}
@Override
protected IStatus run(IProgressMonitor monitor) {
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
SimpleFeatureCollection featureCollection = layer
.buildFeatureCollection();
new SimpleGeoJsonService().serialize(featureCollection,
outStream);
byte[] jsonData = outStream.toByteArray();
try {
String siteID = LocalizationManager.getInstance()
.getCurrentSite();
IServerRequest request = new ExportToLdadRequest(siteID,
jsonData);
String errorMsg = (String) ThriftClient
.sendRequest(request);
if (StringUtils.isNotEmpty(errorMsg)) {
String msg = "Could not export damage path data to LDAD: "
+ errorMsg;
statusHandler.error(msg);
return new Status(IStatus.ERROR, PLUGIN_ID, msg);
}
} catch (VizException e) {
String msg = "Error processing ExportToLdadRequest.";
statusHandler.error(msg, e);
return new Status(IStatus.ERROR, PLUGIN_ID, msg, e);
}
} catch (JsonException | IOException e) {
String msg = "Error serializing Damage Path data to GeoJSON.";
statusHandler.error(msg, e);
return new Status(IStatus.ERROR, PLUGIN_ID, msg, e);
}
statusHandler.info("Damage Path successfully exported.");
return Status.OK_STATUS;
}
}
protected static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ExportToLdadAction.class);
public ExportToLdadAction() {
super("Export to LDAD");
}
@Override
public void run() {
new ExportDamagePathToLdadJob((DamagePathLayer<?>) getSelectedRsc())
.schedule();
}
}

View file

@ -0,0 +1,119 @@
/**
* 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.damagepath;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.common.json.JsonException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.Pair;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
import com.vividsolutions.jts.geom.Polygon;
/**
* Action to import a damage path from a GeoJSON file specified by the user.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 12, 2015 3975 njensen Initial creation
* Mar 31, 2015 3977 nabowle Make sure the polygon is not empty.
* Apr 23, 2015 4354 dgilling Support GeoJSON Feature objects.
* Jun 03, 2015 4375 dgilling Support multiple polygons.
* Jun 09, 2015 4355 dgilling Rename action for UI.
* Jun 18, 2015 4354 dgilling Support modifications to loader so each
* polygon can have its own properties.
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class ImportDamagePathAction extends AbstractRightClickAction {
protected static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ImportDamagePathAction.class);
public ImportDamagePathAction() {
super("Import from File");
}
@Override
public void run() {
VizApp.runSync(new Runnable() {
@Override
public void run() {
Shell shell = VizWorkbenchManager.getInstance()
.getCurrentWindow().getShell();
FileDialog fd = new FileDialog(shell, SWT.OPEN);
fd.setFilterExtensions(ExportDamagePathAction.EXTENSIONS);
String filename = fd.open();
if (filename != null) {
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
try {
DamagePathLoader loader = new DamagePathLoader(filename);
Collection<Pair<Polygon, Map<String, String>>> newData = loader
.getDamagePathData();
if (!newData.isEmpty()) {
Collection<DrawablePolygon> newDamagePaths = new ArrayList<>(
newData.size());
for (Pair<Polygon, Map<String, String>> data : newData) {
newDamagePaths.add(new DamagePathPolygon(data
.getFirst(), data.getSecond(), layer));
}
layer.resetPolygons(newDamagePaths);
} else {
throw new JsonException(
"Damage path file contains no polygons.");
}
} catch (Exception e) {
statusHandler.error("Error importing damage path from "
+ filename, e);
}
}
}
});
}
@Override
public boolean isEnabled() {
AbstractVizResource<?, ?> layer = getSelectedRsc();
return layer.getCapability(EditableCapability.class).isEditable();
}
}

View file

@ -0,0 +1,220 @@
/**
* 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.damagepath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.ResourcePair;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.ResourceList;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer;
import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
import com.vividsolutions.jts.geom.Polygon;
/**
* Action to create a tornado damage path from an InteractiveBaselineLayer.
*
* Adds a menu item to the DamagePath's legend right-click menu which has a
* submenu to select one of the available baselines.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 3977 nabowle Initial creation
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
* multiple polygon support.
* Jun 18, 2015 4354 dgilling Update isEnabled to consider editable
* capability.
* Jun 19, 2015 3977 nabowle Specify Tornado Path.
* Jun 23, 2015 3977 nabowle Switch to InteractiveBaselineLayer.
* Renamed from ImportFromDistanceSpeedAction.
* </pre>
*
* @author nabowle
* @version 1.0
*/
public class NewTornadoDamagePathAction extends AbstractRightClickAction
implements IMenuCreator {
protected static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(NewTornadoDamagePathAction.class);
private Menu menu;
public NewTornadoDamagePathAction() {
super("New Tornado Path from Baseline", SWT.DROP_DOWN);
}
@Override
public Menu getMenu(Control parent) {
if (menu != null) {
menu.dispose();
}
menu = new Menu(parent);
createMenu(menu);
return menu;
}
@Override
public void dispose() {
if (menu != null) {
menu.dispose();
}
}
@Override
public Menu getMenu(Menu parent) {
if (menu != null) {
menu.dispose();
}
createMenu(parent);
return menu;
}
@Override
public IMenuCreator getMenuCreator() {
return this;
}
/**
* Creates a submenu with every displayed baseline, listed in alphabetical
* order.
*
* @param parent
*/
private void createMenu(Menu parent) {
menu = new Menu(parent);
InteractiveBaselinesLayer ibl = findImportLayer(getSelectedRsc());
if (ibl == null || ibl.getCurrentBaselines() == null) {
return;
}
List<Baseline> baselines = new ArrayList<>(Arrays.asList(ibl
.getCurrentBaselines()));
Collections.sort(baselines, new Comparator<Baseline>() {
@Override
public int compare(Baseline b1, Baseline b2) {
return b1.name.compareTo(b2.name);
}
});
for (Baseline baseline : baselines) {
ActionContributionItem aci = new ActionContributionItem(
new ImportFromBaselineInternalAction(baseline));
aci.fill(menu, -1);
}
}
@Override
public boolean isEnabled() {
AbstractVizResource<?, ?> rsc = getSelectedRsc();
boolean enabled = rsc.getCapability(EditableCapability.class)
.isEditable();
if (enabled) {
if (rsc != null) {
enabled = findImportLayer(rsc) != null;
}
}
return enabled;
}
/**
* Finds the import layer.
*
* @param rsc
* The current resource
* @return The found import layer, or null if the tool is not loaded.
*/
private InteractiveBaselinesLayer findImportLayer(
AbstractVizResource<?, ?> rsc) {
ResourceList resources = rsc.getDescriptor().getResourceList();
for (ResourcePair rp : resources) {
if (rp.getResource() instanceof InteractiveBaselinesLayer) {
return (InteractiveBaselinesLayer) rp.getResource();
}
}
return null;
}
/**
* Submenu actions for each available baseline.
*
* Each action is created with one of the available baselines, which when
* run will generate a Tornado damage path for that baseline.
*/
private class ImportFromBaselineInternalAction extends Action {
final Baseline baseline;
public ImportFromBaselineInternalAction(Baseline line) {
super(line.name, Action.AS_PUSH_BUTTON);
this.baseline = line;
}
@Override
public void run() {
VizApp.runSync(new Runnable() {
@Override
public void run() {
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
Polygon polygon = DamagePathUtils
.estimateTornadoDamagePath(baseline);
if (polygon != null) {
layer.addPolygon(polygon.getExteriorRing()
.getCoordinates());
}
}
});
getContainer().refresh();
}
@Override
public String getText() {
return baseline.name;
}
}
}

View file

@ -0,0 +1,93 @@
/**
* 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.damagepath;
import java.util.Map;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
/**
* {@code Action} class to launch the {@code EditGeoJsonPropertiesDlg}.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2015 #4354 dgilling Initial creation
* Jun 09, 2015 #4355 dgilling Rename action for UI.
* Jun 18, 2015 #4354 dgilling Allow individual properties object for
* each polygon.
* Jun 30, 2015 #4354 dgilling Fix NullPointerException.
* Jan 27, 2016 #5287 dgilling Support updated
* EditGeoJsonPropertiesDlg.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
private final DamagePathPolygon damagePath;
public OpenGeoJsonPropertiesDlgAction(final DamagePathPolygon damagePath) {
super("Set Properties...");
this.damagePath = damagePath;
}
@Override
public void run() {
VizApp.runSync(new Runnable() {
@Override
public void run() {
Shell shell = VizWorkbenchManager.getInstance()
.getCurrentWindow().getShell();
final Map<String, String> geoJsonProps = damagePath
.getProperties();
final EditGeoJsonPropertiesDlg dlg = new EditGeoJsonPropertiesDlg(
shell, geoJsonProps);
dlg.addCloseCallback(new ICloseCallback() {
@Override
public void dialogClosed(Object returnValue) {
int returnCode = ((Number) returnValue).intValue();
Map<String, String> updatedProperties = dlg
.getProperties();
if ((Window.OK == returnCode)
&& (!geoJsonProps.equals(updatedProperties))) {
damagePath.setProperties(updatedProperties);
}
}
});
dlg.open();
}
});
}
}

View file

@ -0,0 +1,7 @@
<?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

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.hpe</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

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

View file

@ -0,0 +1,30 @@
<?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.3"?>
<plugin>
<extension
point="com.raytheon.viz.ui.displayCustomizer">
<displayCustomizer
customizer="com.raytheon.uf.viz.hpe.D2DHpeDisplayCustomizer"
perspective="D2D">
</displayCustomizer>
</extension>
</plugin>

View file

@ -0,0 +1,265 @@
/**
* 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.hpe;
import java.util.ArrayList;
import java.util.List;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
import com.raytheon.uf.viz.core.drawables.ResourcePair;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource.ResourceStatus;
import com.raytheon.uf.viz.core.rsc.IInitListener;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.ResourceList;
import com.raytheon.uf.viz.core.rsc.ResourceList.AddListener;
import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener;
import com.raytheon.uf.viz.hpe.rsc.HpeLabelResourceData;
import com.raytheon.uf.viz.hpe.util.HpeUtils;
import com.raytheon.viz.grid.rsc.general.D2DGridResource;
import com.raytheon.viz.ui.perspectives.IRenderableDisplayCustomizer;
/**
* This class listens to existing resources and adds the HPE "legend" text as
* needed.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 5, 2014 3026 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class D2DHpeDisplayCustomizer implements IRenderableDisplayCustomizer {
/** List of listeners we have for renderable displays */
private final List<D2DHpeResourceListener> listeners = new ArrayList<D2DHpeResourceListener>();
@Override
public void customizeDisplay(IRenderableDisplay display) {
boolean add = true;
for (D2DHpeResourceListener listener : listeners) {
if (display == listener.getDisplay()) {
add = false;
break;
}
}
if (add) {
listeners.add(new D2DHpeResourceListener(display));
}
}
@Override
public void uncustomizeDisplay(IRenderableDisplay display) {
D2DHpeResourceListener toRemove = null;
for (D2DHpeResourceListener listener : listeners) {
if (listener.getDisplay() == display) {
toRemove = listener;
break;
}
}
if (toRemove != null) {
toRemove.dispose();
listeners.remove(toRemove);
}
}
private static class D2DHpeResourceListener implements AddListener,
RemoveListener, IInitListener {
private final IRenderableDisplay display;
private boolean resourcesAdded = false;
private ResourcePair hpeResourcePair;
public D2DHpeResourceListener(IRenderableDisplay display) {
this.display = display;
IDescriptor descriptor = display.getDescriptor();
ResourceList list = descriptor.getResourceList();
if (hasCompatibleResource(list)) {
addResources(descriptor);
}
list.addPostAddListener(this);
list.addPostRemoveListener(this);
}
public void dispose() {
ResourceList list = display.getDescriptor().getResourceList();
list.removePostAddListener(this);
list.removePostRemoveListener(this);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener#notifyRemove
* (com.raytheon.uf.viz.core.drawables.ResourcePair)
*/
@Override
public synchronized void notifyRemove(ResourcePair rp)
throws VizException {
if (resourcesAdded) {
if (rp.getResource() != null) {
rp.getResource().unregisterListener(this);
}
if (isCompatibleResource(rp)) {
IDescriptor descriptor = display.getDescriptor();
if (hasCompatibleResource(descriptor.getResourceList()) == false) {
removeResources(descriptor);
}
}
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.ResourceList.AddListener#notifyAdd(com
* .raytheon .uf.viz.core.drawables.ResourcePair)
*/
@Override
public synchronized void notifyAdd(ResourcePair rp) throws VizException {
if (!resourcesAdded) {
AbstractVizResource<?, ?> rsc = rp.getResource();
if (rsc != null) {
rsc.registerListener(this);
if (rsc.getStatus() == ResourceStatus.INITIALIZED
&& isCompatibleResource(rp)) {
addResources(display.getDescriptor());
}
}
}
}
private boolean hasCompatibleResource(ResourceList list) {
for (ResourcePair rp : list) {
if (isCompatibleResource(rp)) {
return true;
}
}
return false;
}
private boolean isCompatibleResource(ResourcePair rp) {
AbstractVizResource<?, ?> resource = rp.getResource();
if (resource != null) {
if (resource instanceof D2DGridResource) {
D2DGridResource rsc = (D2DGridResource) resource;
return HpeUtils.isHpe(rsc.getCurrentGridRecord());
}
}
return false;
}
private synchronized void addResources(IDescriptor descriptor) {
if (!resourcesAdded) {
ResourceList list = descriptor.getResourceList();
hpeResourcePair = constructHpeLabelResource();
list.add(hpeResourcePair);
list.instantiateResources(descriptor, true);
resourcesAdded = true;
// add hpe resource as a listener
for (ResourcePair rp : list) {
AbstractVizResource<?, ?> resource = rp.getResource();
if (resource != null) {
if (resource instanceof D2DGridResource) {
D2DGridResource rsc = (D2DGridResource) resource;
rsc.getResourceData().addChangeListener(
(IResourceDataChanged) hpeResourcePair
.getResource());
return;
}
}
}
}
}
private synchronized void removeResources(IDescriptor descriptor) {
if (resourcesAdded) {
if (hpeResourcePair != null) {
ResourceList list = descriptor.getResourceList();
list.remove(hpeResourcePair);
for (ResourcePair rp : list) {
AbstractVizResource<?, ?> resource = rp.getResource();
if (resource != null) {
if (resource instanceof D2DGridResource) {
D2DGridResource rsc = (D2DGridResource) resource;
rsc.getResourceData().removeChangeListener(
(IResourceDataChanged) hpeResourcePair
.getResource());
}
}
}
hpeResourcePair = null;
}
resourcesAdded = false;
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.IInitListener#inited(com.raytheon.uf
* .viz.core.rsc.AbstractVizResource)
*/
@Override
public synchronized void inited(AbstractVizResource<?, ?> rsc) {
if (rsc instanceof D2DGridResource) {
GridRecord gridRec = ((D2DGridResource) rsc)
.getCurrentGridRecord();
if (!resourcesAdded && HpeUtils.isHpe(gridRec)) {
addResources(rsc.getDescriptor());
}
}
}
/**
* Get the IRenderableDisplay
*
* @return the display
*/
public IRenderableDisplay getDisplay() {
return display;
}
}
private static ResourcePair constructHpeLabelResource() {
return ResourcePair
.constructSystemResourcePair(new HpeLabelResourceData());
}
}

View file

@ -0,0 +1,71 @@
/**
* 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.hpe.rsc;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
* Resource data object for the HpeLabelResource.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 5, 2014 3026 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HpeLabelResourceData extends AbstractResourceData {
@Override
public AbstractVizResource<?, ?> construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
HpeLabelResource rsc = new HpeLabelResource(this, loadProperties);
addChangeListener(rsc);
return rsc;
}
@Override
public void update(Object updateData) {
// No op
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || (!(obj instanceof HpeLabelResourceData))) {
return false;
}
return false;
}
}

View file

@ -0,0 +1,73 @@
/**
* 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.hpe.util;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.grid.dataset.DatasetInfo;
import com.raytheon.uf.common.dataplugin.grid.dataset.DatasetInfoLookup;
/**
* HPE Utilities
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 6, 2014 3026 mpduff Initial creation.
* Jan 6, 2015 3026 mpduff Added Bias HPE.
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class HpeUtils {
private static final String HPE = "HPE";
private static final String BIAS_HPE = "BiasHPE";
/**
* Determine if this title represents an HPE model.
*
* @param gridRecord
* The gridRecord to check
* @return true if model is HPE, false otherwise
*
*/
public static boolean isHpe(GridRecord gridRecord) {
String title = null;
if (gridRecord != null) {
DatasetInfo info = DatasetInfoLookup.getInstance().getInfo(
gridRecord.getDatasetId());
if (info != null) {
title = info.getTitle();
}
}
if (title == null) {
return false;
}
return HPE.equals(title) || BIAS_HPE.equals(title);
}
}

View file

@ -0,0 +1,7 @@
<?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

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.viz.monitor.ffmp</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

@ -0,0 +1,33 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ffmp Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.monitor.ffmp;singleton:=true
Bundle-Version: 1.16.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.monitor.ffmp.Activator
Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.core.runtime,
com.raytheon.uf.common.monitor;bundle-version="1.0.0",
com.raytheon.uf.viz.core;bundle-version="1.16.0",
com.raytheon.uf.common.dataplugin;bundle-version="1.14.0",
com.raytheon.uf.common.datastorage;bundle-version="1.15.2",
com.raytheon.viz.alerts;bundle-version="1.10.13",
com.raytheon.viz.ui;bundle-version="1.16.0",
com.raytheon.uf.viz.monitor;bundle-version="1.11.1",
com.raytheon.uf.common.dataplugin.ffmp;bundle-version="1.11.9",
javax.measure;bundle-version="1.0.0",
com.raytheon.uf.common.stats;bundle-version="1.0.0",
com.raytheon.uf.viz.stats;bundle-version="1.0.0",
com.raytheon.uf.common.dataaccess;bundle-version="1.0.0",
com.raytheon.uf.common.colormap;bundle-version="1.15.1",
com.raytheon.uf.common.style;bundle-version="1.0.0",
com.raytheon.uf.common.plugin.hpe;bundle-version="1.14.3",
com.raytheon.uf.viz.core.rsc;bundle-version="1.14.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Import-Package: com.raytheon.viz.core
Export-Package: com.raytheon.uf.viz.monitor.ffmp,
com.raytheon.uf.viz.monitor.ffmp.ffti,
com.raytheon.uf.viz.monitor.ffmp.ui.listeners,
com.raytheon.uf.viz.monitor.ffmp.ui.rsc,
com.raytheon.uf.viz.monitor.ffmp.xml
Bundle-ClassPath: com.raytheon.uf.viz.monitor.ffmp.jar

View file

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

View file

@ -0,0 +1,67 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<bundle>
<displayList>
<displays xsi:type="d2DMapRenderableDisplay"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties loadWithoutData="true">
<capabilities>
<capability xsi:type="imagingCapability"
interpolationState="true" brightness="0.8"
contrast="1.0" alpha="1.0" />
</capabilities>
</loadProperties>
<properties isSystemResource="false"
isBlinking="false" isMapLayer="false" isHoverOn="false"
isVisible="true" />
<resourceData xsi:type="ffmpResourceData"
sourceName="${sourceName}" huc="ALL" siteKey="${siteKey}"
dataKey="${dataKey}" isUpdatingOnMetadataOnly="false"
isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="pluginName">
<constraint constraintValue="ffmp"
constraintType="EQUALS" />
</mapping>
<mapping key="sourceName">
<constraint constraintValue="${sourceName}"
constraintType="EQUALS" />
</mapping>
<mapping key="siteKey">
<constraint constraintValue="${siteKey}"
constraintType="EQUALS" />
</mapping>
</metadataMap>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher"
deltaFilter="0" forecastFilter="0" />
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,74 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<bundle>
<displayList>
<displays xsi:type="d2DMapRenderableDisplay"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties loadWithoutData="true">
<capabilities>
<capability xsi:type="imagingCapability"
interpolationState="true" brightness="1.0"
contrast="1.0" alpha="1.0" />
<capability xsi:type="colorableCapability"
colorAsString="#9b9b9b" />
</capabilities>
</loadProperties>
<properties isSystemResource="false"
isBlinking="false" isMapLayer="false" isHoverOn="false"
isVisible="true" />
<resourceData xsi:type="ffmpResourceData"
sourceName="${sourceName}" huc="${huc}" siteKey="${siteKey}"
dataKey="${dataKey}" isUpdatingOnMetadataOnly="false"
isRequeryNecessaryOnTimeMatch="true">
<metadataMap>
<mapping key="pluginName">
<constraint constraintValue="ffmp"
constraintType="EQUALS" />
</mapping>
<mapping key="sourceName">
<constraint constraintValue="${sourceName}"
constraintType="EQUALS" />
</mapping>
<mapping key="siteKey">
<constraint constraintValue="${siteKey}"
constraintType="EQUALS" />
</mapping>
<mapping key="dataKey">
<constraint constraintValue="${dataKey}"
constraintType="EQUALS" />
</mapping>
</metadataMap>
</resourceData>
</resource>
<timeMatcher xsi:type="d2DTimeMatcher"
deltaFilter="0" forecastFilter="0" />
<numberOfFrames>1</numberOfFrames>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,56 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<bundle>
<displayList>
<displays xsi:type="mapRenderableDisplay"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties>
<capabilities>
<capability xsi:type="outlineCapability"
lineStyle="SOLID" outlineOn="true"
outlineWidth="1" />
<capability xsi:type="colorableCapability"
colorAsString="#9b9b9b" />
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties isSystemResource="false"
isBlinking="false" isMapLayer="true" isHoverOn="false"
isVisible="true">
<pdProps maxDisplayWidth="100000000"
minDisplayWidth="0" />
</properties>
<resourceData xsi:type="dbMapResourceData">
<table>mapdata.ffmp_basins</table>
<mapName>FFMP Small Stream Basins</mapName>
</resourceData>
</resource>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,56 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<bundle>
<displayList>
<displays xsi:type="mapRenderableDisplay"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties>
<capabilities>
<capability xsi:type="outlineCapability"
lineStyle="SOLID" outlineOn="true"
outlineWidth="1" />
<capability xsi:type="colorableCapability"
colorAsString="#9b9b9b" />
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties isSystemResource="false"
isBlinking="false" isMapLayer="true" isHoverOn="false"
isVisible="true">
<pdProps maxDisplayWidth="100000000"
minDisplayWidth="0" />
</properties>
<resourceData xsi:type="dbMapResourceData">
<table>mapdata.ffmp_streams</table>
<mapName>FFMP Small Stream Basin Links</mapName>
</resourceData>
</resource>
</descriptor>
</displays>
</displayList>
</bundle>

View file

@ -0,0 +1,135 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<FfmpConfigBasin>
<LinkToFrame>true</LinkToFrame>
<WorstCase>true</WorstCase>
<MaintainLayer>false</MaintainLayer>
<OnlyForParent>true</OnlyForParent>
<AutoRefresh>true</AutoRefresh>
<TimeFrame>1.5</TimeFrame>
<D2DType>qpe</D2DType>
<ColumnSorted>RATIO,RFCFFG</ColumnSorted>
<Layer>COUNTY</Layer>
<GroupID>xxxxx</GroupID>
<GuidSrc>xxxxx</GuidSrc>
<IncludedCWAs></IncludedCWAs>
<IncludedGuids>RFCFFG</IncludedGuids>
<IncludedQPF>xxxxx</IncludedQPF>
<Underlay>qpe</Underlay>
<BasinTrendPlots>qpe,rate</BasinTrendPlots>
<!-- Table Column Definitions -->
<TableColumn>
<ColumnName>NAME</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>-9.998</Filter>
<Low>999</Low>
<Mid>999</Mid>
<Upper>999</Upper>
<Sort>Ascending</Sort>
<ColorCell>false</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>15letID</Units>
<BasinTrendPlotColor>white</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>RATE</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>.01</Filter>
<Low>.1</Low>
<Mid>.5</Mid>
<Upper>1.0</Upper>
<Sort>Descending</Sort>
<ColorCell>true</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>inch/hr</Units>
<BasinTrendPlotColor>blue</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>QPE</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>.01</Filter>
<Low>2.0</Low>
<Mid>3.5</Mid>
<Upper>5.0</Upper>
<Sort>Descending</Sort>
<ColorCell>true</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>inch</Units>
<BasinTrendPlotColor>black</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>QPF</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>.01</Filter>
<Low>2.0</Low>
<Mid>3.5</Mid>
<Upper>5.0</Upper>
<Sort>Descending</Sort>
<ColorCell>true</ColorCell>
<DisplayedInTable>false</DisplayedInTable>
<Units>inch</Units>
<BasinTrendPlotColor>orange</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>GUID</ColumnName>
<ReverseFilter>true</ReverseFilter>
<Filter>6.0</Filter>
<Low>1.0</Low>
<Mid>3.0</Mid>
<Upper>5.0</Upper>
<Sort>Ascending</Sort>
<ColorCell>false</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>inch</Units>
<BasinTrendPlotColor>purple</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>RATIO</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>5</Filter>
<Low>25</Low>
<Mid>50</Mid>
<Upper>90</Upper>
<Sort>Descending</Sort>
<ColorCell>true</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>%</Units>
<BasinTrendPlotColor>white</BasinTrendPlotColor>
</TableColumn>
<TableColumn>
<ColumnName>DIFF</ColumnName>
<ReverseFilter>false</ReverseFilter>
<Filter>-4.0</Filter>
<Low>-3.0</Low>
<Mid>-2.0</Mid>
<Upper>-0.5</Upper>
<Sort>Descending</Sort>
<ColorCell>true</ColorCell>
<DisplayedInTable>true</DisplayedInTable>
<Units>inch</Units>
<BasinTrendPlotColor>white</BasinTrendPlotColor>
</TableColumn>
</FfmpConfigBasin>

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -0,0 +1,31 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="command" id="FFTI"
commandId="com.raytheon.uf.viz.monitor.ffmp.openFFTI" menuText="FFTI"/>
<contribute xsi:type="command" id="FFFG"
commandId="com.raytheon.uf.viz.monitor.ffmp.openFFFG" menuText="FFFG"/>
</menuTemplate>

View file

@ -0,0 +1,33 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="bundleItem" file="bundles/ffmp/ffmpImage.xml"
menuText="FFMP ${site} ${displayName} Display" id="FFG ${displayName}">
<substitute key="sourceName" value="${source}" />
<substitute key="dataKey" value="${dataKey}" />
<substitute key="siteKey" value="${site}" />
</contribute>
</menuTemplate>

View file

@ -0,0 +1,34 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="bundleItem" file="bundles/ffmp/ffmpTable.xml"
menuText="FFMP ${site} Table/Basins ${displayName} Display" id="${site}Table/Basins ${source}">
<substitute key="sourceName" value="${source}" />
<substitute key="huc" value="COUNTY" />
<substitute key="siteKey" value="${site}" />
<substitute key="dataKey" value="${dataKey}" />
</contribute>
</menuTemplate>

View file

@ -0,0 +1,33 @@
<?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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<contribute xsi:type="bundleItem" file="bundles/ffmp/ffmpImage.xml"
menuText="FFMP ${site} ${displayName} Display" id="${displayName}QPF3">
<substitute key="sourceName" value="${source}" />
<substitute key="dataKey" value="${dataKey}" />
<substitute key="siteKey" value="${site}" />
</contribute>
</menuTemplate>

View file

@ -0,0 +1,125 @@
<?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.uf.viz.monitor.ffmp.openFFMP"
name="FFMP">
</command>
</extension>
<extension
point="org.eclipse.ui.commands">
<command
id="com.raytheon.uf.viz.monitor.ffmp.openFFTI"
name="FFTI">
</command>
</extension>
<extension
point="org.eclipse.ui.commands">
<command
id="com.raytheon.uf.viz.monitor.ffmp.openFFFG"
name="FFFG">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFMPAction"
commandId="com.raytheon.uf.viz.monitor.ffmp.openFFMP">
</handler>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFTIAction"
commandId="com.raytheon.uf.viz.monitor.ffmp.openFFTI">
</handler>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFFGAction"
commandId="com.raytheon.uf.viz.monitor.ffmp.openFFFG">
</handler>
</extension>
<extension
point="com.raytheon.uf.viz.core.resource">
<resource
class="com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource"
name="FFMPResource"
recordClass="com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord"
renderingOrderId="IMAGE_LOCAL"
resourceType="PLAN_VIEW">
</resource>
</extension>
<extension point="com.raytheon.viz.ui.contextualMenu">
<contextualMenu
actionClass="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFMPColorDisplayToggleAction"
name="FFMP Color Display"
sortID="112">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.monitor.ffmp.ui.actions.StreamToggleAction"
name="Up/Down Stream Display"
sortID="113">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFMPTraceColorAction"
name="Change Up/Down Stream Color..."
sortID="114">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.monitor.ffmp.ui.actions.BasinToggleAction"
name="Basin Boundary Display"
sortID="115">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.uf.viz.monitor.ffmp.ui.actions.FFMPBasinColorAction"
name="Change Basin Boundary Color..."
sortID="116">
</contextualMenu>
</extension>
<extension
point="com.raytheon.uf.viz.localization.perspective.localizationpath">
<path
application="D2D"
localizationType="common_static"
name="FFMP"
recursive="true"
value="ffmp">
</path>
<path
application="D2D"
localizationType="common_static"
name="Monitoring"
recursive="true"
value="monitoring">
</path>
<path
application="D2D"
localizationType="cave_static"
name="FFMP GUI CONFIG"
value="ffmp/guiConfig">
</path>
</extension>
</plugin>

View file

@ -0,0 +1,69 @@
/**
* 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.ffmp;
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.monitor.ffmp";
// 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

@ -0,0 +1,195 @@
/**
* 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.ffmp;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import com.raytheon.uf.common.monitor.data.MonitorConfigConstants.ffmpTable;
import com.raytheon.uf.common.monitor.data.MonitorConfigConstants.tableFields;
import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore;
/**
* FFMPMonitorConfiguration object stores configuration data specific to FFMP.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 29 June, 2009 2521 dhladky Initial creation
* Jan 04, 2016 5115 skorolev Corrected imports.
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class FFMPMonitorConfiguration {
// SCAN Stuff
private String[] pluginName;
private boolean[] ffmpTableAttributes;
/**
* Constructor
*/
public FFMPMonitorConfiguration() {
}
/**
* @return HierarchicalPreferenceStore
*/
private HierarchicalPreferenceStore getStore() {
return (HierarchicalPreferenceStore) Activator.getDefault()
.getPreferenceStore();
}
/**
* Retrieve one set of values for all attributes on a given table.
*
* @param scanTable
* Table to retrieve values from.
* @param field
* Field name to retrieve.
*
* @return HashMap<String, String> of attribute/value pairs.
*/
public HashMap<String, String> getValues(ffmpTable ffmpTable,
tableFields field) {
HierarchicalPreferenceStore store = getStore();
HashMap<String, String> map = new HashMap<String, String>();
for (ffmpTable table : ffmpTable.values()) {
String value = store.getString(table.toString(field));
map.put(table.toString(), value);
}
return map;
}
/**
* Retrieve all fields for a single attribute from the FFMP Table.
*
* @param attribute
* from the ffmp table.
* @return HashMap<String, String> containing field value pairs for the
* given attribute.
*/
public HashMap<String, String> getValues(ffmpTable attribute) {
HierarchicalPreferenceStore store = getStore();
HashMap<String, String> map = new HashMap<String, String>();
for (tableFields field : tableFields.values()) {
map.put(field.toString(),
store.getString(attribute.toString(field)));
}
return map;
}
/**
* Retrieve the threshold data for one of the SCAN tables. Only returns
* those attributes that have thresholds other than the default "999" value.
*
* @param table
* FFMPTables value: either CELL, MESO, or TVS.
* @return HashMap<String, String[]> keyed on the attribute name and the
* three threshold values: low, mid, and upp in that order.
*/
public HashMap<String, String[]> getThresholds(ffmpTable table) {
HashMap<String, String[]> map = new HashMap<String, String[]>();
HashMap<String, String> low = getValues(table, tableFields.LOW);
HashMap<String, String> mid = getValues(table, tableFields.MID);
HashMap<String, String> upp = getValues(table, tableFields.UPP);
Set<String> keys = low.keySet();
Iterator<String> iter = keys.iterator();
while (iter.hasNext()) {
String key = iter.next();
String[] values = new String[3];
values[0] = low.get(key);
values[1] = mid.get(key);
values[2] = upp.get(key);
map.put(key, values);
}
return map;
}
/**
* Set the value of one attribute in the Cell table.
*
* @param attribute
* An attribute from the cellTable enum.
* @param field
* An field from the tableFields enum.
* @param value
* Value to save.
*/
public void setValue(ffmpTable attribute, tableFields field, String value) {
getStore().setValue(attribute.toString(field), value);
}
/**
* @return String[] pluginName
*/
public String[] getPluginName() {
return pluginName;
}
/**
* @param pluginName
* String[]
*/
public void setPluginName(String[] pluginName) {
this.pluginName = pluginName;
}
/**
* Get a boolean array representing the visibility of the attributes for a
* given table.
*
* @param table
* FFMPTables
*
* @return boolean[]
*/
public boolean[] getTableAttributes(ffmpTable table) {
return ffmpTableAttributes.clone();
}
/**
* Get the boolean array representing the visibility of the attributes for a
* given table.
*
* @param table
* FFMPTables
* @param tableAttributes
* boolean[]
*/
public void setTableAttributes(ffmpTable table, boolean[] tableAttributes) {
this.ffmpTableAttributes = tableAttributes.clone();
}
}

View file

@ -0,0 +1,128 @@
/**
* 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.ffmp;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager.SOURCE_TYPE;
import com.raytheon.uf.common.monitor.xml.SourceXML;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Processes the FFMP URIs. Extracted from FFMPMonitor.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 7, 2013 njensen Initial creation
* Jul 15, 2013 2184 dhladky Removed all HUC's but ALL
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class FFMPProcessUris {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(FFMPProcessUris.class);
private final NavigableMap<Date, List<String>> furiMap;
private final String fsiteKey;
private final String fsourceName;
private final Date fbarrierTime;
private final FFMPMonitor ffmpMonitor;
public FFMPProcessUris(FFMPMonitor ffmpMonitor,
NavigableMap<Date, List<String>> uriMap, String siteKey,
String sourceName, Date barrierTime) {
this.furiMap = uriMap;
this.fsiteKey = siteKey;
this.fbarrierTime = barrierTime;
this.fsourceName = sourceName;
this.ffmpMonitor = ffmpMonitor;
}
public void run(IProgressMonitor monitor) {
if (furiMap != null) {
SourceXML source = ffmpMonitor.getSourceConfig().getSource(
fsourceName);
boolean isGuidance = false;
if (source != null
&& source.getSourceType().equals(
SOURCE_TYPE.GUIDANCE.getSourceType())) {
isGuidance = true;
}
List<String> loadedUris = ffmpMonitor.getLoadedUris(fsiteKey,
fsourceName);
Set<FFMPRecord> populatedRecords = new HashSet<FFMPRecord>();
for (List<String> uris : furiMap.descendingMap().values()) {
for (String uri : uris) {
if (uri == null || loadedUris.contains(uri)) {
continue;
}
FFMPRecord record = new FFMPRecord(uri);
if (record.getDataTime().getRefTime().after(fbarrierTime)
|| isGuidance) {
try {
record = ffmpMonitor.populateFFMPRecord(uri,
fsiteKey, fsourceName);
if (record != null) {
populatedRecords.add(record);
if (source != null) {
record.setExpiration(source
.getExpirationMinutes(fsiteKey));
record.setRate(source.isRate());
}
}
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
"FFMP Can't retrieve FFMP URI, " + uri, e);
}
}
}
}
monitor.beginTask(null, populatedRecords.size());
for (FFMPRecord record : populatedRecords) {
record.getBasinData().loadNow();
monitor.worked(1);
}
}
}
}

View file

@ -0,0 +1,132 @@
/**
* 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^M
* 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.ffmp.fffg;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Displays the FFFG About information
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Nov 29, 2012 1353 rferrel Made dialog non-blocking.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class AboutDlg extends CaveSWTDialog {
/**
* The label object.
*/
private Label aboutLbl;
/**
* Constructor.
*
* @param parent
* Parent shell.
*/
public AboutDlg(Shell parent) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
setText("About ForcedFFG");
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(final Shell shell) {
setReturnValue(false);
// Initialize layout
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.widthHint = 400;
gd.heightHint = 100;
aboutLbl = new Label(shell, SWT.None);
aboutLbl.setLayoutData(gd);
// Add a close button
Composite centeredComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(1, false);
centeredComp.setLayout(gl);
GridData gd2 = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
centeredComp.setLayoutData(gd2);
Button closeBtn = new Button(centeredComp, SWT.NONE);
closeBtn.setText("OK");
closeBtn.setLayoutData(gd2);
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
shell.dispose();
}
});
populateDlg();
}
private void populateDlg() {
String aboutText = " The ForceFFG GUI was closely followed FFMP, LSR,\n"
+ " ForcedFFG applications and was based on input from\n"
+ " the AWIPS User Interface Working Group. Visit \n"
+ " http://www.nws.noaa.gov/mdl/ffmp/ for more details\n"
+ " regarding this ForcedFFG GUI.";
this.aboutLbl.setText(aboutText);
this.shell.pack();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
super.disposed();
}
}

View file

@ -0,0 +1,130 @@
/**
* 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^M
* 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.ffmp.fffg;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Dialog to dispaly FFFG Acknowledgments.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Nov 29, 2012 1353 rferrel Made dialog non-blocking.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class AcknowledgmentsDlg extends CaveSWTDialog {
/**
* Create the label object.
*/
private Label acknowledgmentsLbl;
/**
* Constructor.
*
* @param parent
* Parent shell.
*/
public AcknowledgmentsDlg(Shell parent) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
setText("Acknowledgments");
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(final Shell shell) {
setReturnValue(false);
// Initialize layout
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.widthHint = 390;
gd.heightHint = 80;
acknowledgmentsLbl = new Label(shell, SWT.None);
acknowledgmentsLbl.setLayoutData(gd);
// Add a close button
Composite centeredComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(1, false);
centeredComp.setLayout(gl);
GridData gd2 = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
centeredComp.setLayoutData(gd2);
// Add a close button
Button closeBtn = new Button(centeredComp, SWT.NONE);
closeBtn.setText("OK");
closeBtn.setLayoutData(gd2);
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
shell.dispose();
}
});
populateDlg();
}
private void populateDlg() {
String acknowledgementsText = " Special thanks to Lingyan Xin, Tom Filiaggi, Qinglu Lin,\n"
+ " Mike Churma, Arthur Taylor, Xuning Tan, Bei Wang and\n"
+ " others in MDL for their many valuable help for their\n"
+ " many valuable help and suggestions!";
this.acknowledgmentsLbl.setText(acknowledgementsText);
this.shell.pack();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
super.disposed();
}
}

View file

@ -0,0 +1,178 @@
/**
* 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.ffmp.fffg;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPCounties;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPCounty;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates.MODE;
import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager;
import com.raytheon.uf.common.monitor.xml.DomainXML;
import com.raytheon.uf.common.monitor.xml.FFMPRunXML;
import com.raytheon.uf.common.monitor.xml.ProductRunXML;
import com.raytheon.uf.common.monitor.xml.SourceXML;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
/**
* Forced Flash Flood Guidace Dialog data class.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 13, 2011 11007 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class FFFGData implements Runnable {
private FFMPTemplates templates;
private FFMPRunXML runner = null;
private FFMPCounties counties;
private IFFFGData callback;
private LinkedHashMap<String, SrcDisplayDurationData> guidData = null;
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
guidData = new LinkedHashMap<String, SrcDisplayDurationData>();
getTemplates();
getCounties();
getGuidData();
callback.setCounties(counties);
callback.setTemplates(templates);
callback.setGuidances(guidData);
callback.dataLoadComplete();
}
/**
* Get the FFMPTemplates.
*/
private FFMPTemplates getTemplates() {
if (templates == null) {
String siteName = LocalizationManager.getInstance()
.getCurrentSite().toUpperCase();
FFMPRunConfigurationManager frcm = FFMPRunConfigurationManager
.getInstance();
runner = frcm.getRunner(siteName);
this.templates = FFMPTemplates.getInstance(
runner.getPrimaryDomain(), MODE.CAVE);
// backup domains
ArrayList<DomainXML> backupDomainList = runner.getBackupDomains();
if (backupDomainList != null) {
for (DomainXML backup : backupDomainList) {
templates.addDomain(backup);
}
} else {
templates.done = true;
}
}
return templates;
}
/**
* Populate the counties data.
*/
private void getCounties() {
if (runner == null) {
String cwaName = LocalizationManager.getInstance().getCurrentSite()
.toUpperCase();
// load a runner by finding the primary domain
FFMPRunConfigurationManager frcm = FFMPRunConfigurationManager
.getInstance();
runner = frcm.getRunner(cwaName);
}
for (ProductRunXML product : runner.getProducts()) {
FFMPCounties countyList = getTemplates().getCounties(
product.getProductKey());
if (counties == null) {
counties = countyList;
counties.getCounties().addAll(countyList.getCounties());
} else {
for (FFMPCounty county : countyList.getCounties()) {
if (!counties.getCounties().contains(county)) {
counties.addCounty(county);
}
}
}
// Create a HashSet which allows no duplicates
HashSet<FFMPCounty> hashSet = new HashSet<FFMPCounty>(
counties.getCounties());
// Assign the HashSet to a new ArrayList
ArrayList<FFMPCounty> newCounties = new ArrayList<FFMPCounty>(
hashSet);
// Ensure correct order, since HashSet doesn't
Collections.sort(newCounties);
counties.setCounties(newCounties);
}
}
/**
* Get the Guidance data for the FFFG dialog.
*/
private void getGuidData() {
FFMPSourceConfigurationManager srcConfigMgr = FFMPSourceConfigurationManager.getInstance();
ArrayList<String> guidances = srcConfigMgr.getGuidances();
for (String guidance: guidances) {
SourceXML source = srcConfigMgr.getSource(guidance);
double dur = source.getDurationHour();
String dispName = source.getDisplayName();
SrcDisplayDurationData sddd = new SrcDisplayDurationData(dispName, dur);
guidData.put(source.getSourceName(), sddd);
}
}
/**
* Set the callback for this class.
*
* @param IFFFGData FFFGData interface callback
*/
public void setCallback(IFFFGData callback) {
this.callback = callback;
}
}

View file

@ -0,0 +1,64 @@
/**
* 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.ffmp.fffg;
import com.raytheon.uf.viz.monitor.ffmp.fffg.FFMPBasins.BasinSort;
public class FFMPBasinNameIdData implements Comparable<FFMPBasinNameIdData>
{
private Long pfaf = Long.MIN_VALUE;
private String basinName;
public FFMPBasinNameIdData(Long pfaf, String basinName)
{
this.pfaf = pfaf;
this.basinName = basinName;
}
public Long getPfaf() {
return pfaf;
}
public String getBasinName() {
return basinName;
}
@Override
public int compareTo(FFMPBasinNameIdData obj)
{
if (FFMPBasins.getSortBy() == BasinSort.NAME)
{
return this.basinName.compareTo(obj.getBasinName());
}
else if (FFMPBasins.getSortBy() == BasinSort.ID)
{
if (this.pfaf < obj.getPfaf())
{
return -1;
}
else if (this.pfaf > obj.getPfaf())
{
return 1;
}
}
return 0;
}
}

View file

@ -0,0 +1,64 @@
/**
* 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.ffmp.fffg;
import java.util.ArrayList;
import java.util.Collections;
public class FFMPBasins
{
public enum BasinSort {NAME, ID};
private static BasinSort sortBy = BasinSort.ID;
private ArrayList<FFMPBasinNameIdData> basinArray;
public FFMPBasins(ArrayList<FFMPBasinNameIdData> basinArray, BasinSort sortBy)
{
this.basinArray = basinArray;
sortBy(sortBy);
}
public ArrayList<FFMPBasinNameIdData> getBasins()
{
return basinArray;
}
public void setBasins(ArrayList<FFMPBasinNameIdData> basinArray)
{
this.basinArray = basinArray;
Collections.sort(basinArray);
}
public void sortBy(BasinSort sortBy)
{
FFMPBasins.sortBy = sortBy;
if (basinArray != null)
{
Collections.sort(basinArray);
}
}
public static BasinSort getSortBy()
{
return sortBy;
}
}

View file

@ -0,0 +1,139 @@
/**
* 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^M
* 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.ffmp.fffg;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Dialog to dispaly FFFG help.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Nov 29, 2012 1353 rferrel Made dialog non-blocking.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class HelpDlg extends CaveSWTDialog {
/**
* Create the label object.
*/
private Label helpLbl;
/**
* Constructor.
*
* @param parent
* Parent shell.
*/
public HelpDlg(Shell parent) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
setText("Help for ForcedFFG");
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(final Shell shell) {
setReturnValue(false);
// Initialize layout
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.widthHint = 400;
gd.heightHint = 270;
helpLbl = new Label(shell, SWT.None);
helpLbl.setLayoutData(gd);
// Add a close button
Composite centeredComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(1, false);
centeredComp.setLayout(gl);
GridData gd2 = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
centeredComp.setLayoutData(gd2);
Button closeBtn = new Button(centeredComp, SWT.NONE);
closeBtn.setText("OK");
closeBtn.setLayoutData(gd2);
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
shell.dispose();
}
});
populateDlg();
}
private void populateDlg() {
String helpText = " - To add FFG to counties: Left click on the county name \n"
+ " in the leftmost column and click on the button \n"
+ " 'Add/Update selected County(ies)' \n"
+ " - To add FFG to basins: Left click on the basin name \n"
+ " in the leftmost column and click on the button \n"
+ " 'Add/Update selected Basin(s)' \n"
+ " - To remove FFG from counties: Left click on the county name \n"
+ " in the rightmost column and click on the button \n"
+ " 'Remove County(ies)' \n"
+ " - To remove FFG from basins: Left click on the basin name \n"
+ " in the rightmost column and click on the button \n"
+ " 'Remove Basin(s)' \n"
+ " - Basin value override county value.\n"
+ " - County value override CWA value.\n"
+ " - Visit http://www.nws.noaa.gov/mdl/ffmp/ \n"
+ " for more details.";
this.helpLbl.setText(helpText);
this.shell.pack();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
super.disposed();
}
}

View file

@ -0,0 +1,52 @@
/**
* 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.ffmp.fffg;
import java.util.LinkedHashMap;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPCounties;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates;
/**
* Forced Flash Flood Dialog Data object.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 13, 2011 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public interface IFFFGData {
public void setCounties(FFMPCounties counties);
public void setTemplates(FFMPTemplates templates);
public void setGuidances(LinkedHashMap<String, SrcDisplayDurationData> guidances);
public void dataLoadComplete();
}

View file

@ -0,0 +1,30 @@
/**
* 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.ffmp.fffg;
import com.raytheon.uf.common.monitor.config.SourceCompData;
public interface ISourceCompAction {
void removeSource(SourceComp srcComp);
void addNewSource(SourceCompData sourceCompData);
void selectSource(SourceComp srcComp);
void setModified(boolean isModified);
void setStatusMsg(int status, String message);
}

View file

@ -0,0 +1,237 @@
/**
* 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.ffmp.fffg;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Dialog used to bring data in for the FFFG dialog. There are 3 options:
*
* Retrieve - Clear current data entirely and load data from the selected file.
*
* Merge - Retain current data and load data from the selected file. Current
* data will NOT be overwritten by incoming data when the two conflict.
*
* Merge/Overwrite - Retain current data and load data from the selected file.
* Incoming data will overwrite current data when the two conflict.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 13, 2010 lvenable Initial creation
* Nov 29, 2012 1353 rferrel Convert to CavSWTDialog
* and make non-blocking
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class RetrieveMergeDlg extends CaveSWTDialog {
/**
* Enumeration of the retrieve options.
*/
public static enum RetrieveMergeAction {
RETRIEVE("Retrieve"), MERGE_OVERWRITE("Merge/Overwrite"), MERGE("Merge"), CANCEL(
"Cancel");
private String actionName;
RetrieveMergeAction(String name) {
actionName = name;
}
public String getActionName() {
return actionName;
}
}
/**
* Retrieve radio button.
*/
private Button retrieveRdo;
/**
* Merge/Overwrite button.
*/
private Button mergeOvrWriteRdo;
/**
* Merge button.
*/
private Button mergeRdo;
/**
* The selected button.
*/
private Button selectedRdo;
/**
* Constructor.
*
* @param parent
* Parent control.
*/
public RetrieveMergeDlg(Shell parent) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
setText("Retrieve/Merge FFG File");
}
@Override
protected void initializeComponents(Shell shell) {
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 3;
mainLayout.marginWidth = 3;
shell.setLayout(mainLayout);
// Initialize all of the controls and layouts
initializeComponents();
}
/**
* Initialize the controls on the dialog.
*/
private void initializeComponents() {
createRetrieveMergeControls();
createBottomButtons();
}
/**
* Create the Retrieve, Merge/Overwrite, and Merge controls.
*/
private void createRetrieveMergeControls() {
Group controlGrp = new Group(shell, SWT.BORDER);
GridLayout gl = new GridLayout(2, false);
gl.verticalSpacing = 20;
controlGrp.setLayout(gl);
controlGrp.setText(" Please choose your selection: ");
SelectionListener listener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Button button = (Button) e.widget;
if (button.getSelection()) {
selectedRdo = button;
}
}
};
GridData gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
retrieveRdo = new Button(controlGrp, SWT.RADIO);
retrieveRdo.setText("Retrieve: ");
retrieveRdo.setSelection(true);
selectedRdo = retrieveRdo;
selectedRdo.addSelectionListener(listener);
selectedRdo.setData(RetrieveMergeAction.RETRIEVE);
retrieveRdo.setLayoutData(gd);
Label retrieveLbl = new Label(controlGrp, SWT.NONE);
retrieveLbl
.setText("Clear current data entirely and load data\nfrom the selected file.");
/*
* ** NOTE: The merge features are disabled due to the limitations of
* having 4 sources to edit. If 3 unique sources are to be merged with 3
* other unique sources on the display there would be 6 sources trying
* to fit into 4 available areas. I have ideas for a more elegant
* solution that will allow more than just 4 sources.
*/
gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
mergeOvrWriteRdo = new Button(controlGrp, SWT.RADIO);
mergeOvrWriteRdo.setText("Merge Overwrite: ");
mergeOvrWriteRdo.addSelectionListener(listener);
mergeOvrWriteRdo.setData(RetrieveMergeAction.MERGE_OVERWRITE);
mergeOvrWriteRdo.setLayoutData(gd);
Label mergeOvrWriteLbl = new Label(controlGrp, SWT.NONE);
mergeOvrWriteLbl.setText("Retain current data and load data from the\n"
+ "selected file. Incoming data will overwrite\n"
+ "current data when the two conflict.");
gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
mergeRdo = new Button(controlGrp, SWT.RADIO);
mergeRdo.setText("Merge: ");
mergeRdo.addSelectionListener(listener);
mergeRdo.setData(RetrieveMergeAction.MERGE);
mergeRdo.setLayoutData(gd);
Label mergeLbl = new Label(controlGrp, SWT.NONE);
mergeLbl.setText("Retain current data and load data from the\n"
+ "selected file. Current data will NOT be\n"
+ "overwritten by incoming data when the two\n" + "conflict.");
}
/**
* Create the buttons on the bottom of the display.
*/
private void createBottomButtons() {
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Composite buttonComp = new Composite(shell, SWT.NONE);
buttonComp.setLayout(new GridLayout(2, false));
buttonComp.setLayoutData(gd);
int buttonWidth = 100;
gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
Button okBtn = new Button(buttonComp, SWT.PUSH);
okBtn.setText("OK");
okBtn.setLayoutData(gd);
okBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setReturnValue(selectedRdo.getData());
close();
}
});
gd = new GridData(SWT.LEFT, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
Button cancelBtn = new Button(buttonComp, SWT.PUSH);
cancelBtn.setText("Cancel");
cancelBtn.setLayoutData(gd);
cancelBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
}

View file

@ -0,0 +1,85 @@
/**
* 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.ffmp.fffg;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 28, 2010 lvenable Initial creation
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class SrcDisplayDurationData {
private String displayName;
private double durationHrs = 0;
public SrcDisplayDurationData(String displayName, double durationHrs) {
this.displayName = displayName;
this.durationHrs = durationHrs;
}
public String getDisplayName() {
return displayName;
}
public double getDurationHrs() {
return durationHrs;
}
public String getDurationHrsString() {
return String.valueOf(durationHrs);
}
public boolean dataMatch(String name, int dur) {
if ((name.compareTo(displayName) == 0) && (dur == durationHrs)) {
return true;
}
return false;
}
public boolean dataMatch(String name, String dur) {
if ((name.compareTo(displayName) == 0)
&& (dur.compareTo(String.valueOf(durationHrs)) == 0)) {
return true;
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return displayName + ":" + durationHrs;
}
}

View file

@ -0,0 +1,283 @@
/**
* 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.ffmp.ffti;
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Scale;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager;
import com.raytheon.uf.common.monitor.config.FFTIDataManager;
import com.raytheon.uf.common.monitor.xml.SourceXML;
public class DurHoursScaleComp extends Composite {
private Composite parent;
private Canvas scaleValueCanvas;
private Canvas scaleRangeCanvas;
private Scale timeDurScale;
private Font canvasFont;
private double timeDurHours = 0.0;
private final int CANVAS_HEIGHT = 20;
private int CANVAS_WIDTH = 100;
private int xCoordOffset = 5;
private double lowerVal = 0.50;
private double upperVal = 6.00;
private double rangeVal = upperVal - lowerVal;
private double[] displayNumbers;
private DurationInterface owner = null;
public DurHoursScaleComp(Composite parent) {
super(parent, 0);
this.parent = parent;
init();
}
private void init() {
FFMPSourceConfigurationManager fscm = FFMPSourceConfigurationManager
.getInstance();
ArrayList<String> guidSources = fscm.getGuidances();
FFTIDataManager fdm = FFTIDataManager.getInstance();
lowerVal = Double.MAX_VALUE;
upperVal = Double.MIN_VALUE;
for (String sourceName : guidSources) {
SourceXML source = fscm.getSource(sourceName);
if (source.getDurationHour() < lowerVal) {
lowerVal = source.getDurationHour();
}
if (source.getDurationHour() > upperVal) {
upperVal = source.getDurationHour();
}
}
if ((lowerVal == Double.MAX_VALUE) || (lowerVal <= 0.0)) {
lowerVal = 0.0;
}
// get the smallest QPF value
ArrayList<String> qpfSources = fscm.getQPFSources();
double lowestQpfVal = Double.MAX_VALUE;
if (qpfSources != null) {
for (String sourceName : qpfSources) {
SourceXML source = fscm.getSource(sourceName);
String durHour = String.valueOf(source.getDurationHour());
if (lowestQpfVal > Double.parseDouble(durHour))
lowestQpfVal = Double.parseDouble(durHour);
}
} else {
lowestQpfVal = 1.0;
}
// if qpf is active, the use the lowest qpf value
if (fdm.getSettingList().size() > 0) {
// FFTISettingXML fsx = fdm.getSettingList().get(0);
// if (fsx.getQPFSource().getDurationHour() > 0.0) { // QPF is
// active
if (lowestQpfVal < lowerVal) {
lowerVal = lowestQpfVal;
}
}
if (upperVal == Double.MIN_VALUE) {
upperVal = 6.00;
}
timeDurHours = lowerVal * 4;
displayNumbers = new double[] { lowerVal, upperVal };
rangeVal = upperVal - lowerVal;
canvasFont = new Font(parent.getDisplay(), "Monospace", 8, SWT.NORMAL);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
GridLayout gl = new GridLayout(1, false);
gl.verticalSpacing = 0;
gl.marginHeight = 0;
this.setLayout(gl);
this.setLayoutData(gd);
createControls();
this.pack();
this.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent arg0) {
canvasFont.dispose();
}
});
}
private void createControls() {
scaleValueCanvas = new Canvas(this, SWT.DOUBLE_BUFFERED);
scaleValueCanvas.setLayoutData(new GridData(CANVAS_WIDTH + 10,
CANVAS_HEIGHT));
scaleValueCanvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawScaleValueCanvas(e.gc);
}
});
GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
gd.widthHint = CANVAS_WIDTH;
timeDurScale = new Scale(this, SWT.HORIZONTAL);
timeDurScale.setMinimum((int) (lowerVal * 4));
timeDurScale.setMaximum((int) (upperVal * 4));
timeDurScale.setIncrement(1);
timeDurScale.setPageIncrement(1);
timeDurScale.setSelection((int) (lowerVal * 4));
timeDurScale.setLayoutData(gd);
timeDurScale.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
updateTimeDuration();
}
});
calcTimeDurHours();
scaleRangeCanvas = new Canvas(this, SWT.DOUBLE_BUFFERED);
scaleRangeCanvas.setLayoutData(new GridData(CANVAS_WIDTH + 10,
CANVAS_HEIGHT));
scaleRangeCanvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawScaleRangeCanvas(e.gc);
}
});
}
private void drawScaleValueCanvas(GC gc) {
double pixPerInc = (CANVAS_WIDTH - 25 - xCoordOffset) / rangeVal;
gc.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
int newXCoord = (int) Math.round((this.timeDurHours - lowerVal)
* pixPerInc);
gc.drawString(String.format("%2.2f", this.timeDurHours), newXCoord, 1,
true);
}
private void drawScaleRangeCanvas(GC gc) {
double pixPerInc = (CANVAS_WIDTH - 25 - xCoordOffset) / rangeVal;
gc.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
for (double dVal : displayNumbers) {
int newXCoord = (int) Math.round((dVal - lowerVal) * pixPerInc);
gc.drawString(String.format("%2.2f", dVal), newXCoord, 1, true);
}
}
private void calcTimeDurHours() {
timeDurHours = timeDurScale.getSelection() * .25;
}
private void setTimeDurationScale(double val) {
timeDurScale.setSelection((int) ((val / .25)));
}
public void setOwner(DurationInterface owner) {
this.owner = owner;
}
private void updateTimeDuration() {
calcTimeDurHours();
scaleValueCanvas.redraw();
if (owner != null) {
owner.updateQPEDurHour(timeDurHours);
owner.updateTotalDurHour(timeDurHours);
}
}
public void setTimeDuration(double val) {
setTimeDurationScale(val);
calcTimeDurHours();
scaleValueCanvas.redraw();
}
public void setTimeDurationAndUpdate(double val) {
setTimeDurationScale(val);
calcTimeDurHours();
scaleValueCanvas.redraw();
}
public double getSelectedValue() {
return timeDurHours;
}
/**
* enable the duration hour scale base on the state of enabled variable.
*
* @param enabled
*/
public void enableScale(boolean enabled) {
this.timeDurScale.setEnabled(enabled);
this.setEnabled(enabled);
}
public double getLowerVal() {
return lowerVal;
}
public double getUpperVal() {
return upperVal;
}
}

View file

@ -0,0 +1,11 @@
package com.raytheon.uf.viz.monitor.ffmp.ffti;
public interface DurationInterface {
public void updateQPEDurHour(double guidDurHour);
public void updateTotalDurHour(double guidDurHour);
public void updateGuidDurHour(double durHour);
public boolean getGuidEnabled() ;
public void updateAccumAttrib (double totalDurHr) ;
public double getTotalDurHr();
public double adjustTotalDurationHr (double durHr) ;
}

View file

@ -0,0 +1,70 @@
package com.raytheon.uf.viz.monitor.ffmp.ffti;
public class FFTIAttribute {
private double min;
private double yellowThreshold;
private double redThreshold;
private double max;
private double inc;
public FFTIAttribute(double inc, double min, double yellowThreshold, double redThreshold, double max) {
this.min = min;
this.yellowThreshold = yellowThreshold;
this.redThreshold = redThreshold;
this.max = max;
this.inc = inc;
}
public void setMin(double min) {
this.min = min;
}
public double getMin() {
return min;
}
public void setYellowThreshold(double yellowThreshold) {
this.yellowThreshold = yellowThreshold;
}
public double getYellowThreshold() {
return yellowThreshold;
}
public void setRedThreshold(double redThreshold) {
this.redThreshold = redThreshold;
}
public double getRedThreshold() {
return redThreshold;
}
public void setMax(double max) {
this.max = max;
if (redThreshold > max)
{
redThreshold = max;
}
if (yellowThreshold > redThreshold)
{
yellowThreshold = redThreshold;
}
}
public double getMax() {
return max;
}
public void setInc(double inc) {
this.inc = inc;
}
public double getInc() {
return inc;
}
}

View file

@ -0,0 +1,519 @@
/**
* 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.ffmp.ffti;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager;
import com.raytheon.uf.common.monitor.config.FFTIDataManager;
import com.raytheon.uf.common.monitor.xml.DomainXML;
import com.raytheon.uf.common.monitor.xml.FFMPRunXML;
import com.raytheon.uf.common.monitor.xml.FFTISettingXML;
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.localization.LocalizationManager;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Flash Flood Threat Indicator display dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Dec 5, 2012 1353 rferrel Convert to CaveSWTDialog and made non-blocking.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class FFTIControlDlg extends CaveSWTDialog {
/**
* THe CWAs monitor selection buttons.
*/
private Map<String, Button> cwa_list;
/**
* Adds setting tab items to the FFTI tab folder.
*/
private Button addSettingBtn;
/**
* Remove setting tab items from the FFTI tab folder.
*/
private Button removeSettingBtn;
/**
* The FFTI tab folder.
*/
private TabFolder fftiTabFolder;
/**
* Setting tab item names.
*/
private final String[] tabTitles = new String[] { "Setting 1", "Setting 2",
"Setting 3", "Setting 4", "Setting 5" };
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(FFTIControlDlg.class);
/**
* Constructor to set up non-blocking dialog.
*
* @param parent
*/
public FFTIControlDlg(Shell parent) {
super(parent, SWT.DIALOG_TRIM | SWT.RESIZE, CAVE.DO_NOT_BLOCK);
setText("Flash Flood Threat Indicator (FFTI) Control");
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(Shell shell) {
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 3;
mainLayout.marginWidth = 3;
shell.setLayout(mainLayout);
// Initialize all of the controls and layouts
initializeComponents();
}
/**
* Set up dialog components.
*/
private void initializeComponents() {
try {
createCwaControls();
addSeparator(shell);
createTabFolderControls();
createSettingTabFolder();
createBottomButtons();
createSettingTabs();
updateTabSettings();
} catch (Exception e) {
statusHandler.handle(Priority.ERROR, "FFTI Can not load...", e);
}
}
/**
* Set up selection buttons for the CWAs monitors.
*/
private void createCwaControls() {
GridLayout gl = new GridLayout(10, false);
Composite cwaComp = new Composite(shell, SWT.NONE);
cwaComp.setLayout(gl);
Label cwaLbl = new Label(cwaComp, SWT.NONE);
cwaLbl.setText("CWAs Monitored: ");
cwa_list = new HashMap<String, Button>();
String siteName = LocalizationManager.getInstance().getCurrentSite()
.toUpperCase();
// load a runner by finding the primary domain
FFMPRunConfigurationManager frcm = FFMPRunConfigurationManager
.getInstance();
FFMPRunXML runner = frcm.getRunner(siteName);
if (runner.getBackupDomains() != null) {
for (DomainXML domain : runner.getBackupDomains()) {
Button cwa_bt = new Button(cwaComp, SWT.CHECK);
cwa_bt.setText(domain.getCwa());
cwa_list.put(domain.getCwa(), cwa_bt);
}
}
Button cwa_bt = new Button(cwaComp, SWT.CHECK);
cwa_bt.setText(runner.getPrimaryDomain().getCwa());
cwa_list.put(runner.getPrimaryDomain().getCwa(), cwa_bt);
cwa_list.get(runner.getPrimaryDomain().getCwa()).setSelection(true);
FFTIDataManager fftiDataMgr = FFTIDataManager.getInstance();
// initialize the CWAs
ArrayList<String> cwaList = fftiDataMgr.getCwaList();
if ((cwaList != null) && (cwaList.size() > 0)) {
for (String cwa : cwaList) {
if (cwa_list.get(cwa) != null) {
cwa_list.get(cwa).setSelection(true);
}
}
} else {
// cwa_list.get(CWAs.get(0)).setSelection(true);
}
}
/**
* Buttons to add remove tab items from the FFTI tab.
*/
private void createTabFolderControls() {
Composite tabControlComp = new Composite(shell, SWT.NONE);
tabControlComp.setLayout(new GridLayout(2, false));
int buttonWidth = 120;
GridData gd = new GridData(buttonWidth, SWT.DEFAULT);
addSettingBtn = new Button(tabControlComp, SWT.PUSH);
addSettingBtn.setText("Add Setting");
addSettingBtn.setLayoutData(gd);
addSettingBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
addSettingTab();
}
});
gd = new GridData(buttonWidth, SWT.DEFAULT);
removeSettingBtn = new Button(tabControlComp, SWT.PUSH);
removeSettingBtn.setText("Remove Setting");
removeSettingBtn.setLayoutData(gd);
removeSettingBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
removeSettingTab();
}
});
}
/**
* Layout the FFTI tab folder.
*/
private void createSettingTabFolder() {
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
fftiTabFolder = new TabFolder(shell, SWT.NONE);
fftiTabFolder.setLayoutData(gd);
fftiTabFolder.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateTabSettings();
}
});
}
/**
* The bottom save and close buttons.
*/
private void createBottomButtons() {
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Composite buttonComp = new Composite(shell, SWT.NONE);
buttonComp.setLayout(new GridLayout(2, false));
buttonComp.setLayoutData(gd);
int buttonWidth = 140;
gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
Button saveSettingsBtn = new Button(buttonComp, SWT.PUSH);
saveSettingsBtn.setText("Save All Settings");
saveSettingsBtn.setLayoutData(gd);
saveSettingsBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
saveAllSettings();
}
});
gd = new GridData(SWT.LEFT, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
Button closeBtn = new Button(buttonComp, SWT.PUSH);
closeBtn.setText("Close");
closeBtn.setLayoutData(gd);
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
/**
* Get the duplicated settings.
*
* @return duplicate list
*/
private Set<Integer> getDuplicates() {
Set<Integer> duplicateLst = new HashSet<Integer>();
for (int i = 0; i < fftiTabFolder.getItemCount(); i++) {
SettingComp thisItem = (SettingComp) fftiTabFolder.getItem(i)
.getControl();
for (int j = (i + 1); j < fftiTabFolder.getItemCount(); j++) {
SettingComp nextItem = (SettingComp) fftiTabFolder.getItem(j)
.getControl();
if (thisItem.getSelectedAttribType().endsWith(
nextItem.getSelectedAttribType())
&& (thisItem.getYellowThreshold() == nextItem
.getYellowThreshold())
&& (thisItem.getRedThreshold() == nextItem
.getRedThreshold())
&& (thisItem.getQpeDurHr() == nextItem.getQpeDurHr())
&& (thisItem.getGuidDurHr() == nextItem.getGuidDurHr())
&& (thisItem.getQpfDurHr() == nextItem.getQpfDurHr())
&& (thisItem.getTotalDurHr() == nextItem
.getTotalDurHr())
&& (thisItem.getQpeSrc().length > 0
&& nextItem.getQpeSrc().length > 0 && thisItem
.getQpeSrc()[0].equals(nextItem.getQpeSrc()[0]))
&& (thisItem.getQpfSrc().length > 0
&& nextItem.getQpfSrc().length > 0 && thisItem
.getQpfSrc()[0].equals(nextItem.getQpfSrc()[0]))
&& (thisItem.getGuidSrc().length > 0
&& nextItem.getGuidSrc().length > 0 && thisItem
.getGuidSrc()[0]
.equals(nextItem.getGuidSrc()[0]))) {
duplicateLst.add(i + 1);
duplicateLst.add(j + 1);
}
}
}
return duplicateLst;
}
/**
* Save the current settings to the FFTIDataManger.
*/
protected void saveAllSettings() {
// Find duplicates
Set<Integer> duplicates = getDuplicates();
if (duplicates.size() > 0) {
StringBuilder message = new StringBuilder("Sets ");
String separator = "";
for (int setIndex : duplicates) {
message.append(separator).append(setIndex);
separator = "/";
}
message.append(" are duplicated!\nModify the configuration before saving.");
MessageBox messageBox = new MessageBox(shell, SWT.OK);
messageBox.setText("Warning: Duplicate Setting(s)!");
messageBox.setMessage(message.toString());
messageBox.open();
return;
}
FFTIDataManager fdm = FFTIDataManager.getInstance();
// Clear out old settings
fdm.clear();
// get the selected CWA list
List<String> selectedCwas = getCWASelectionIDs();
fdm.setCwaList((ArrayList<String>) selectedCwas);
// get attribute, and sources for each tab
TabItem[] tabItemArray = fftiTabFolder.getItems();
List<FFTISettingXML> settings = new ArrayList<FFTISettingXML>();
for (TabItem ti : tabItemArray) {
SettingComp sc = (SettingComp) ti.getControl();
FFTISettingXML aSetting = new FFTISettingXML();
// get attributes: name yellow threshold, red threshold
aSetting.getAttribute()
.setAttributeName(sc.getSelectedAttribType());
aSetting.getAttribute().setYellowThrshld(sc.getYellowThreshold());
aSetting.getAttribute().setRedThrshld(sc.getRedThreshold());
// get precipitation source + value
if (sc.getqpeToggle().getToggleState()) {
for (String src : sc.getQpeSrc()) {
aSetting.getQpeSource().addDisplayName(src);
}
aSetting.getQpeSource().setDurationHour(sc.getQpeDurHr());
}
if (sc.getGuidToggle().getToggleState()) {
for (String src : sc.getGuidSrc()) {
aSetting.getGuidSource().addDisplayName(src);
}
aSetting.getGuidSource().setDurationHour(sc.getGuidDurHr());
}
if (sc.getQpfToggle().getToggleState()) {
for (String src : sc.getQpfSrc()) {
aSetting.getQpfSource().addDisplayName(src);
}
aSetting.getQpfSource().setDurationHour(sc.getQpfDurHr());
}
settings.add(aSetting);
}
fdm.setSettings((ArrayList<FFTISettingXML>) settings);
fdm.saveConfigXml();
}
/**
* Add a new setting tab in the FFTI tab folder.
*/
private void createSettingTabs() {
FFTIDataManager fftiDataMgr = FFTIDataManager.getInstance();
if (fftiDataMgr.getSettingList().size() == 0) {
TabItem settingTab = new TabItem(fftiTabFolder, SWT.NONE);
settingTab.setText(tabTitles[0]);
settingTab.setControl(new SettingComp(fftiTabFolder));
} else {
for (int i = 0; i < fftiDataMgr.getSettingList().size(); i++) {
FFTISettingXML fftiSetting = fftiDataMgr.getSettingList()
.get(i);
TabItem settingTab = new TabItem(fftiTabFolder, SWT.NONE);
settingTab.setText(tabTitles[i]);
SettingComp sc = new SettingComp(fftiTabFolder, fftiSetting);
settingTab.setControl(sc);
}
}
}
/**
* Place horizontal separator in the component.
*
* @param parentComp
*/
private void addSeparator(Composite parentComp) {
GridLayout gl = (GridLayout) parentComp.getLayout();
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gd.horizontalSpan = gl.numColumns;
Label sepLbl = new Label(parentComp, SWT.SEPARATOR | SWT.HORIZONTAL);
sepLbl.setLayoutData(gd);
}
/**
* Add a new settings tab.
*/
private void addSettingTab() {
// Add tab
TabItem settingTab = new TabItem(fftiTabFolder, SWT.NONE);
settingTab.setText(tabTitles[fftiTabFolder.getItemCount() - 1]);
settingTab.setControl(new SettingComp(fftiTabFolder));
updateTabSettings();
fftiTabFolder.setSelection(settingTab);
removeSettingBtn.setEnabled(true);
}
/**
* Dispose of the control in the selected tab and then dispose of the tab.
*/
private void removeSettingTab() {
int selectedTab = fftiTabFolder.getSelectionIndex();
fftiTabFolder.getItem(selectedTab).getControl().dispose();
fftiTabFolder.getItem(selectedTab).dispose();
renameTabs();
updateTabSettings();
fftiTabFolder.setSelection(0);
removeSettingBtn.setEnabled(false);
}
/**
* Update the enable status of tab control buttons.
*/
private void updateTabSettings() {
if (fftiTabFolder.getItemCount() > 1) {
if (fftiTabFolder.getSelectionIndex() == 0) {
removeSettingBtn.setEnabled(false);
} else {
removeSettingBtn.setEnabled(true);
}
} else {
removeSettingBtn.setEnabled(false);
}
if (fftiTabFolder.getItemCount() < 5) {
addSettingBtn.setEnabled(true);
} else {
addSettingBtn.setEnabled(false);
}
}
/**
* Adjust the names of the FFTI tab folder items.
*/
private void renameTabs() {
TabItem[] tabItemArray = fftiTabFolder.getItems();
for (int i = 0; i < tabItemArray.length; i++) {
tabItemArray[i].setText(tabTitles[i]);
}
}
/**
* Get CWA names whose buttons are selected.
*
* @return cwaIds
*/
public List<String> getCWASelectionIDs() {
List<String> cwaIds = new ArrayList<String>();
for (Object id : cwa_list.keySet().toArray()) {
Button cwa_bt = cwa_list.get(id);
if (cwa_bt.getSelection()) {
cwaIds.add(id.toString());
}
}
return cwaIds;
}
}

View file

@ -0,0 +1,507 @@
/**
* 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.ffmp.ffti;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
/**
* FFTI Slider Canvas
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 05, 2015 #5070 randerso Changed to use system font name (not AWT)
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class FFTISliderCanvas {
private Composite parentComp;
private Display display;
private Color blackColor;
private Color canvasBgColor;
/*
* Canvas information
*/
private Canvas canvas;
private final int CANVAS_WIDTH = 460;
private final int CANVAS_HEIGHT = 50;
/*
* Bar information.
*/
private int barBottomYCoord = 45;
private int barWidth = 400;
private int barHeight = 10;
private int barXCoord = 25;
private int barYCoord = 35;
private int barEndPixVal = barXCoord + barWidth;
/*
* Bar colors. These are not to be disposed because they are system colors.
*/
private Color redColor;
private Color yellowColor;
private Color greenColor;
/*
* Upper arrow, label and values
*/
private Region upperRegion;
private int[] upperPtArray = new int[] { 0, 0 };
private int upperArrowXCoord = 150;
private Rectangle upperLblRect;
private String upperStr;
private int upperLblYCoord = 1;
private boolean moveUpper = false;
private Double upperDisplayVal = 0.0;
/*
* Lower arrow, label and values
*/
private Region lowerRegion;
private int[] lowerPtArray = new int[] { 0, 0 };
private int lowerArrowXCoord = 50;
private Rectangle lowerLblRect;
private String lowerStr;
private int lowerLblYCoord = 14;
private boolean moveLower = false;
private Double lowerDisplayVal = 0.0;
/*
* Mouse information.
*/
private Point mousePt;
private boolean mouseDown = false;
/*
* Font/text information
*/
private Font labelFont;
private int textWidth = 0;
private int textHeight = 0;
/*
* Min/Range/Increment information
*/
private double minValue = Double.NaN;
private double maxValue = Double.NaN;
private double rangeValue = Double.NaN;
private double incValue = Double.NaN;
private double incPerPixel = Double.NaN;
private boolean displayAtInt = false;
private String formatStr;
private FFTIAttribute attribVal;
public FFTISliderCanvas(Composite parentComp, FFTIAttribute accumAttrib) {
this.parentComp = parentComp;
display = this.parentComp.getDisplay();
this.attribVal = accumAttrib;
setValuesNoRedraw(attribVal.getMin(), attribVal.getMax(),
attribVal.getInc(), attribVal.getRedThreshold(),
attribVal.getYellowThreshold());
init();
createCanvas();
}
public void updateSliderVals(FFTIAttribute fftiAttrib) {
attribVal = fftiAttrib;
}
private void init() {
redColor = display.getSystemColor(SWT.COLOR_RED);
yellowColor = display.getSystemColor(SWT.COLOR_YELLOW);
greenColor = display.getSystemColor(SWT.COLOR_GREEN);
canvasBgColor = new Color(display, 120, 120, 110);
blackColor = display.getSystemColor(SWT.COLOR_BLACK);
upperLblRect = new Rectangle(0, 0, 0, 0);
lowerLblRect = new Rectangle(0, 0, 0, 0);
labelFont = new Font(display, "Monospace", 10, SWT.BOLD);
mousePt = new Point(0, 0);
upperRegion = new Region(display);
lowerRegion = new Region(display);
makeCalculations();
}
private void createCanvas() {
canvas = new Canvas(parentComp, SWT.DOUBLE_BUFFERED | SWT.BORDER);
// canvas = new Canvas(shell, SWT.NO_BACKGROUND);
GridData gd = new GridData(SWT.DEFAULT, SWT.CENTER, false, true);
gd.heightHint = CANVAS_HEIGHT;
gd.widthHint = CANVAS_WIDTH;
canvas.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
canvas.setLayoutData(gd);
canvas.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
drawCanvas(e.gc);
}
});
canvas.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (upperRegion.contains(e.x, e.y) == true
|| upperLblRect.contains(e.x, e.y) == true) {
mousePt.x = e.x;
mousePt.y = e.y;
mouseDown = true;
moveUpper = true;
} else if (lowerRegion.contains(e.x, e.y) == true
|| lowerLblRect.contains(e.x, e.y) == true) {
mousePt.x = e.x;
mousePt.y = e.y;
mouseDown = true;
moveLower = true;
}
}
@Override
public void mouseUp(MouseEvent e) {
mouseDown = false;
moveLower = false;
moveUpper = false;
}
});
canvas.addMouseMoveListener(new MouseMoveListener() {
@Override
public void mouseMove(MouseEvent e) {
handleMouseMove(e);
}
});
canvas.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
upperRegion.dispose();
lowerRegion.dispose();
labelFont.dispose();
canvasBgColor.dispose();
}
});
}
private void drawCanvas(GC gc) {
gc.setAntialias(SWT.ON);
gc.setFont(labelFont);
gc.setBackground(canvasBgColor);
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.setBackground(greenColor);
gc.fillRectangle(barXCoord, barYCoord, barWidth, barHeight);
gc.setBackground(yellowColor);
gc.fillRectangle(lowerArrowXCoord, barYCoord, barWidth + 25
- lowerArrowXCoord, barHeight);
gc.setBackground(redColor);
gc.fillRectangle(upperArrowXCoord, barYCoord, barWidth + 25
- upperArrowXCoord, barHeight);
gc.setForeground(blackColor);
gc.drawRectangle(barXCoord, barYCoord, barWidth, barHeight);
updateLowerArrow(gc);
updateLowerLabel(gc);
updateUpperArrow(gc);
updateUpperLabel(gc);
}
private void updateUpperArrow(GC gc) {
upperRegion.subtract(upperPtArray);
upperPtArray = new int[] { upperArrowXCoord,
barBottomYCoord - barHeight - 3, upperArrowXCoord + 4,
barBottomYCoord, upperArrowXCoord - 4, barBottomYCoord };
upperRegion.add(upperPtArray);
gc.setBackground(redColor);
gc.fillPolygon(upperPtArray);
gc.setForeground(blackColor);
gc.drawPolygon(upperPtArray);
}
private void updateUpperLabel(GC gc) {
gc.setForeground(redColor);
upperStr = calcDisplayString(upperDisplayVal);
int lblXCoord = upperArrowXCoord - (textWidth * upperStr.length() / 2);
gc.drawString(upperStr, lblXCoord, upperLblYCoord, true);
upperLblRect.x = lblXCoord;
upperLblRect.y = upperLblYCoord;
upperLblRect.width = textWidth * upperStr.length();
upperLblRect.height = textHeight;
this.attribVal.setRedThreshold(upperDisplayVal);
}
private void updateLowerArrow(GC gc) {
lowerRegion.subtract(lowerPtArray);
lowerPtArray = new int[] { lowerArrowXCoord,
barBottomYCoord - barHeight - 3, lowerArrowXCoord + 4,
barBottomYCoord, lowerArrowXCoord - 4, barBottomYCoord };
lowerRegion.add(lowerPtArray);
gc.setBackground(yellowColor);
gc.fillPolygon(lowerPtArray);
gc.setForeground(blackColor);
gc.drawPolygon(lowerPtArray);
}
private void updateLowerLabel(GC gc) {
gc.setForeground(yellowColor);
lowerStr = calcDisplayString(lowerDisplayVal);
int lblXCoord = (int) (lowerArrowXCoord - ((double) textWidth
* (double) lowerStr.length() / 2));
gc.drawString(lowerStr, lblXCoord, lowerLblYCoord, true);
lowerLblRect.x = lblXCoord;
lowerLblRect.y = lowerLblYCoord;
lowerLblRect.width = textWidth * lowerStr.length();
lowerLblRect.height = textHeight;
this.attribVal.setYellowThreshold(lowerDisplayVal);
}
private void handleMouseMove(MouseEvent e) {
if (mouseDown == false) {
return;
}
if (moveUpper == true) {
int xDiff = e.x - mousePt.x;
upperArrowXCoord += xDiff;
if (upperArrowXCoord > barEndPixVal) {
upperArrowXCoord = barEndPixVal;
} else if (upperArrowXCoord < barXCoord) {
upperArrowXCoord = barXCoord;
} else if (upperArrowXCoord < lowerArrowXCoord) {
upperArrowXCoord = lowerArrowXCoord;
}
upperDisplayVal = calcDisplayValue(upperArrowXCoord);
} else if (moveLower == true) {
int xDiff = e.x - mousePt.x;
lowerArrowXCoord += xDiff;
if (lowerArrowXCoord > barEndPixVal) {
lowerArrowXCoord = barEndPixVal;
} else if (lowerArrowXCoord < barXCoord) {
lowerArrowXCoord = barXCoord;
} else if (lowerArrowXCoord > upperArrowXCoord) {
lowerArrowXCoord = upperArrowXCoord;
}
lowerDisplayVal = calcDisplayValue(lowerArrowXCoord);
}
mousePt.x = e.x;
mousePt.y = e.y;
canvas.redraw();
}
private void makeCalculations() {
Image image = new Image(display, 100, 100);
GC gc = new GC(image);
gc.setFont(labelFont);
textWidth = gc.getFontMetrics().getAverageCharWidth();
textHeight = gc.getFontMetrics().getHeight();
gc.dispose();
image.dispose();
}
private double calcDisplayValue(int xCoord) {
// calculate the display value to .10 or .05 increments
double xCoordAsValue = (xCoord - barXCoord) * incPerPixel + minValue;
if (xCoordAsValue >= this.maxValue) {
return this.maxValue;
}
if (incValue == .25) {
return (Math.round(xCoordAsValue * 4.00)) / 4.00;
} else if (incValue == .05) {
return Math.round(xCoordAsValue * 20.0) / 20.0;
} else if (incValue == .10) {
return (Math.round(xCoordAsValue * 10.00)) / 10.00;
} else {
return Math.round(xCoordAsValue);
}
}
private String calcDisplayString(Double displVal) {
if (displayAtInt == true) {
return String.format(formatStr, Math.round(displVal));
} else {
return String.format(formatStr, displVal);
}
}
private int calcValueToBarXCoord(double val) {
int result = (int) Math.round((val - minValue) / incPerPixel
+ barXCoord);
return result;
}
private void setValuesNoRedraw(double min, double max, double inc,
double startingUpperVal, double startingLowerVal) {
if (max < min) {
return;
}
this.maxValue = max;
this.minValue = min;
this.rangeValue = max - min;
this.incValue = inc;
incPerPixel = this.rangeValue / barWidth;
if (inc < 1.00) {
displayAtInt = false;
formatStr = "%1.2f";
} else {
displayAtInt = true;
formatStr = "%d";
}
upperArrowXCoord = calcValueToBarXCoord(startingUpperVal);
lowerArrowXCoord = calcValueToBarXCoord(startingLowerVal);
upperDisplayVal = calcDisplayValue(upperArrowXCoord);
lowerDisplayVal = calcDisplayValue(lowerArrowXCoord);
}
public void setValues(FFTIAttribute attribVal) {
this.attribVal = attribVal;
setValues(attribVal.getMin(), attribVal.getMax(), attribVal.getInc(),
attribVal.getRedThreshold(), attribVal.getYellowThreshold());
}
public void setValues(double min, double max, double inc,
double startingUpperVal, double startingLowerVal) {
setValuesNoRedraw(min, max, inc, startingUpperVal, startingLowerVal);
canvas.redraw();
}
public void setMaxAndIncValues(double newMaxValue, double newIncValue) {
this.maxValue = newMaxValue;
this.incValue = newIncValue;
double startingUpperVal = Double.NaN;
double startingLowerVal = Double.NaN;
if (lowerDisplayVal > maxValue) {
startingUpperVal = maxValue;
startingLowerVal = maxValue;
setValues(this.minValue, this.maxValue, this.incValue,
startingUpperVal, startingLowerVal);
} else if (upperDisplayVal > maxValue) {
startingUpperVal = maxValue;
setValues(this.minValue, this.maxValue, this.incValue,
startingUpperVal, getLowerValue());
} else {
setValues(this.minValue, this.maxValue, this.incValue,
getUpperValue(), getLowerValue());
}
}
public double getUpperValue() {
return upperDisplayVal;
}
public double getLowerValue() {
return lowerDisplayVal;
}
}

View file

@ -0,0 +1,948 @@
/**
* 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.ffmp.ffti;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.TabFolder;
import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager;
import com.raytheon.uf.common.monitor.xml.FFTISettingXML;
import com.raytheon.uf.common.monitor.xml.ProductRunXML;
import com.raytheon.uf.common.monitor.xml.ProductXML;
import com.raytheon.uf.common.monitor.xml.SourceXML;
/**
* FFTI Setting Composite.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 08/07/2012 578 mpduff FFTI now only a single selection and populates
* correctly.
* </pre>
*/
public class SettingComp extends Composite implements DurationInterface {
/**
* Parent tab folder.
*/
private TabFolder parent;
private Font labelFont;
private Button accumRdo;
private Button ratioRdo;
private Button diffRdo;
private FFTISliderCanvas sliderCanvas;
private Label sliderCanvasLabel;
private ToggleCanvas qpeToggle;
private ToggleCanvas guidToggle;
private ToggleCanvas qpfToggle;
private List qpeList;
private List guidList;
private List qpfList;
private Label qpeDurLbl;
private Label guidDurLbl;
private Label qpfDurLbl;
// duration hour for QPE
private double qpeDurHr;
private DurHoursScaleComp guidDurSlider;
private Combo qpfDurCbo;
private TotalDurScaleComp totalDurScale;
private final String durHoursStr = "Duration (hrs): ";
// attributes with default values
private FFTIAttribute accumAttrib = new FFTIAttribute(0.05, 0, 1, 3, 4);
private FFTIAttribute ratioAttrib = new FFTIAttribute(0.05, 0, 0.5, 0.8,
1.25);
private FFTIAttribute diffAttrib = new FFTIAttribute(0.1, -3, 1, 2.5, 3.5);
// temporary storage for qpf
private String selectedQpfVal = "0";
private FFTISettingXML fftiSetting;
public SettingComp(TabFolder parent) {
super(parent, 0);
this.parent = parent;
init();
}
public SettingComp(TabFolder parent, FFTISettingXML fftiSetting) {
super(parent, 0);
this.parent = parent;
this.fftiSetting = fftiSetting;
init();
// set the attributes
if (fftiSetting.getAttribute().getAttributeName()
.equalsIgnoreCase("accum")) {
accumAttrib.setRedThreshold(fftiSetting.getAttribute()
.getRedThrshld());
accumAttrib.setYellowThreshold(fftiSetting.getAttribute()
.getYellowThrshld());
accumRdo.setSelection(true);
ratioRdo.setSelection(false);
diffRdo.setSelection(false);
accumAction(accumAttrib);
} else if (fftiSetting.getAttribute().getAttributeName()
.equalsIgnoreCase("ratio")) {
ratioAttrib.setRedThreshold(fftiSetting.getAttribute()
.getRedThrshld());
ratioAttrib.setYellowThreshold(fftiSetting.getAttribute()
.getYellowThrshld());
ratioRdo.setSelection(true);
accumRdo.setSelection(false);
diffRdo.setSelection(false);
ratioAction(ratioAttrib);
} else { // must be diff
diffAttrib.setRedThreshold(fftiSetting.getAttribute()
.getRedThrshld());
diffAttrib.setYellowThreshold(fftiSetting.getAttribute()
.getYellowThrshld());
diffRdo.setSelection(true);
accumRdo.setSelection(false);
ratioRdo.setSelection(false);
diffAction(diffAttrib);
}
// set qpe
setQPEDurHr(fftiSetting.getQpeSource().getDurationHour());
// set guid
guidToggle
.setToggleState(fftiSetting.getGuidSource().getDurationHour() != 0);
guidDurSlider.setTimeDuration(fftiSetting.getGuidSource()
.getDurationHour());
// set qpf
double qpfVal = fftiSetting.getQpfSource().getDurationHour();
if (qpfVal == -999.0)
qpfVal = 0.0;
this.qpfToggle.setToggleState(qpfVal != 0);
for (int i = 0; i < qpfDurCbo.getItemCount(); i++) {
double qpfCboDur = Double.parseDouble(qpfDurCbo.getItem(i));
if (qpfCboDur == fftiSetting.getQpfSource().getDurationHour()) {
qpfDurCbo.select(i);
selectedQpfVal = qpfDurCbo.getItem(i);
}
}
// the total duration slider
double totalDur = 0;
if (fftiSetting.getQpeSource().getDurationHour() > 0)
totalDur = fftiSetting.getQpeSource().getDurationHour();
if (fftiSetting.getQpfSource().getDurationHour() > 0)
totalDur += fftiSetting.getQpfSource().getDurationHour();
totalDurScale.setTimeDuration(totalDur);
updateAccumAttrib(totalDur);
if (qpfToggle.getToggleState()) {
totalDurScale.setScaleToYellow();
} else {
totalDurScale.setScaleToGrey();
}
}
private void init() {
labelFont = new Font(this.getDisplay(), "Sans", 10, SWT.BOLD);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
GridLayout gl = new GridLayout(1, false);
gl.verticalSpacing = 2;
gl.marginHeight = 2;
gl.marginWidth = 2;
this.setLayout(gl);
this.setLayoutData(gd);
this.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent arg0) {
labelFont.dispose();
}
});
/*
* Add the controls to the display.
*/
createAttributeControls();
createPrecipitationControls();
createTotalDurationControls();
accumRdo.setEnabled(true);
accumAction(accumAttrib);
setSettings();
}
private void createAttributeControls() {
createHeaderLabel("Attribute that will be monitored");
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
GridLayout gl = new GridLayout(3, false);
gl.horizontalSpacing = 20;
Composite attrComp = new Composite(this, SWT.NONE);
attrComp.setLayout(gl);
attrComp.setLayoutData(gd);
/*
* Radio buttons
*/
gd = new GridData();
gd.horizontalIndent = 10;
Composite radioComp = new Composite(attrComp, SWT.NONE);
GridLayout radGl = new GridLayout(1, false);
radGl.verticalSpacing = 1;
radioComp.setLayout(radGl);
radioComp.setLayoutData(gd);
accumRdo = new Button(radioComp, SWT.RADIO);
accumRdo.setText("Accum");
accumRdo.setSelection(true);
accumRdo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
accumAction(accumAttrib);
}
});
ratioRdo = new Button(radioComp, SWT.RADIO);
ratioRdo.setText("Ratio");
ratioRdo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ratioAction(ratioAttrib);
}
});
diffRdo = new Button(radioComp, SWT.RADIO);
diffRdo.setText("Diff");
diffRdo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
diffAction(diffAttrib);
}
});
/*
* Slider control and label
*/
sliderCanvas = new FFTISliderCanvas(attrComp, accumAttrib);
gd = new GridData(SWT.DEFAULT, SWT.CENTER, false, true);
gd.widthHint = 60;
sliderCanvasLabel = new Label(attrComp, SWT.NONE);
sliderCanvasLabel.setText("inches");
sliderCanvasLabel.setLayoutData(gd);
}
private void createPrecipitationControls() {
int listWidth = 225;
int listHeight = 125;
createHeaderLabel("Precipitation Sources");
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
GridLayout gl = new GridLayout(5, false);
gl.horizontalSpacing = 20;
Composite precipSrcComp = new Composite(this, SWT.NONE);
precipSrcComp.setLayout(gl);
precipSrcComp.setLayoutData(gd);
/*
* Toggles *************************
*/
// QPE
qpeToggle = new ToggleCanvas(precipSrcComp, "QPE", true);
// GUID
guidToggle = new ToggleCanvas(precipSrcComp, "GUID", true, 2);
// QPF
qpfToggle = new ToggleCanvas(precipSrcComp, "QPF", true, 2);
qpfToggle.setOwner(this);
qpeToggle.setOwner(this);
System.out.println("Toggle state QPF::" + qpfToggle.getToggleState()
+ "\n");
/*
* List controls *************************
*/
// QPE
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = listWidth;
gd.heightHint = listHeight;
qpeList = new List(precipSrcComp, SWT.BORDER | SWT.V_SCROLL);
qpeList.setLayoutData(gd);
fillQpeList();
// GUID
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.horizontalSpan = 2;
gd.widthHint = listWidth - 75;
gd.heightHint = listHeight;
guidList = new List(precipSrcComp, SWT.BORDER | SWT.V_SCROLL);
guidList.setLayoutData(gd);
fillGuidList();
// QPF
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.horizontalSpan = 2;
gd.widthHint = listWidth;
gd.heightHint = listHeight;
qpfList = new List(precipSrcComp, SWT.BORDER | SWT.V_SCROLL);
qpfList.setLayoutData(gd);
fillQpfList();
/*
* Duration controls **********************
*/
// QPE
gd = new GridData(SWT.CENTER, SWT.CENTER, true, true);
qpeDurLbl = new Label(precipSrcComp, SWT.NONE);
setQPEDurHr(1);
qpeDurLbl.setLayoutData(gd);
qpeDurLbl.setFont(labelFont);
// GUID
gd = new GridData();
guidDurLbl = new Label(precipSrcComp, SWT.NONE);
guidDurLbl.setText(durHoursStr);
guidDurLbl.setLayoutData(gd);
guidDurLbl.setFont(labelFont);
guidDurSlider = new DurHoursScaleComp(precipSrcComp);
guidDurSlider.setOwner(this);
// QPF
gd = new GridData();
qpfDurLbl = new Label(precipSrcComp, SWT.NONE);
qpfDurLbl.setText(durHoursStr);
qpfDurLbl.setLayoutData(gd);
qpfDurLbl.setFont(labelFont);
gd = new GridData(60, SWT.DEFAULT);
qpfDurCbo = new Combo(precipSrcComp, SWT.DROP_DOWN | SWT.READ_ONLY);
qpfDurCbo.setLayoutData(gd);
fillqpfDurCbo();
}
/**
* fill in the GUID names for GUID from FFMPSourceConfig.xml
*/
private void fillGuidList() {
FFMPSourceConfigurationManager fscm = FFMPSourceConfigurationManager
.getInstance();
ArrayList<String> guidSources = fscm.getGuidanceDisplayNames();
if (guidSources == null) {
return;
}
HashSet<String> guidSet = new HashSet<String>();// use HashSet just to
// make an unique
// guidList
for (String sourceName : guidSources) {
guidSet.add(sourceName);
guidList.add(sourceName);
}
guidList.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
int index = ((List) e.getSource()).getSelectionIndex();
String source = ((List) e.getSource()).getItem(index);
FFMPSourceConfigurationManager srcConfigMgr = FFMPSourceConfigurationManager
.getInstance();
SourceXML mysource = srcConfigMgr
.getSourceByDisplayName(source);
guidDurSlider.setTimeDuration(mysource.getDurationHour());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
private void fillQpeList() {
FFMPRunConfigurationManager runConfigMgr = FFMPRunConfigurationManager
.getInstance();
ArrayList<ProductRunXML> products = runConfigMgr.getProducts();
FFMPSourceConfigurationManager srcConfigMgr = FFMPSourceConfigurationManager
.getInstance();
if (products == null) {
return;
}
HashSet<String> qpeSet = new HashSet<String>();
for (ProductRunXML product : products) {
for (ProductXML pr : srcConfigMgr.getProducts()) {
String str = null;
SourceXML source = srcConfigMgr.getSource(pr.getQpe());
if (source.isMosaic()) {
if (!qpeSet.contains(product.getProductKey())) {
String displayName = source.getDisplayName();
if (!qpeSet.contains(displayName)) {
qpeSet.add(displayName);
qpeList.add(displayName);
}
break;
}
} else {
if (pr.getPrimarySource().equals(product.getProductName())) {
str = product.getProductKey() + "-"
+ source.getDisplayName();
if (!qpeSet.contains(product.getProductKey())) {
if (qpeSet.contains(str) == false) {
if (!qpeSet.contains(source.getDisplayName())) {
qpeSet.add(str);
qpeList.add(str);
}
}
}
}
}
}
}
}
/**
* fill in the QPF names for QPF from FFMPSourceConfig.xml
*/
private void fillQpfList() {
FFMPRunConfigurationManager runConfigMgr = FFMPRunConfigurationManager
.getInstance();
ArrayList<ProductRunXML> products = runConfigMgr.getProducts();
FFMPSourceConfigurationManager srcConfigMgr = FFMPSourceConfigurationManager
.getInstance();
if (products == null) {
return;
}
HashSet<String> qpfSet = new HashSet<String>();
for (ProductRunXML product : products) {
for (ProductXML pr : srcConfigMgr.getProducts()) {
String str = null;
for (int i = 0; i < pr.getQpfList().size(); i++) {
SourceXML source = srcConfigMgr.getSource(pr.getQpf(i));
if (source.isMosaic()) {
if (!qpfSet.contains(product.getProductKey())) {
if (!qpfSet.contains(source.getDisplayName())) {
qpfSet.add(source.getDisplayName());
qpfList.add(source.getDisplayName());
break;
}
}
} else {
if (pr.getPrimarySource().equals(
product.getProductName())) {
str = product.getProductKey() + "-"
+ source.getDisplayName();
if (!qpfSet.contains(product.getProductKey())) {
if (qpfSet.contains(str) == false) {
if (!qpfSet.contains(source
.getDisplayName())) {
qpfSet.add(str);
qpfList.add(str);
break;
}
}
}
}
}
}
}
}
}
/**
* fill in the duration hours for QPF from FFMPSourceConfig.xml
*/
private void fillqpfDurCbo() {
FFMPSourceConfigurationManager fscm = FFMPSourceConfigurationManager
.getInstance();
ArrayList<String> qpfSources = fscm.getQPFSources();
if (qpfSources == null) {
return;
}
HashSet<String> qpfSet = new HashSet<String>();// HashSet to make an
// unique List
for (String sourceName : qpfSources) {
SourceXML source = fscm.getSource(sourceName);
String durHour = String.valueOf(source.getDurationHour());
if (!qpfSet.contains(durHour)) {
qpfSet.add(durHour);
qpfDurCbo.add(durHour);
}
}
if (qpfDurCbo.getItemCount() > 0) {
qpfDurCbo.select(0);
selectedQpfVal = qpfDurCbo.getItem(0);
}
}
private void createTotalDurationControls() {
createHeaderLabel("Total Duration across All Sources");
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
GridLayout gl = new GridLayout(2, false);
gl.horizontalSpacing = 10;
Composite totalDurComp = new Composite(this, SWT.NONE);
totalDurComp.setLayout(gl);
totalDurComp.setLayoutData(gd);
totalDurScale = new TotalDurScaleComp(totalDurComp);
totalDurScale.setOwner(this);
gd = new GridData(SWT.LEFT, SWT.CENTER, true, true);
Label hoursLbl = new Label(totalDurComp, SWT.NONE);
hoursLbl.setText("Hours");
hoursLbl.setFont(labelFont);
hoursLbl.setLayoutData(gd);
if (qpfToggle.getToggleState()) {
totalDurScale.setScaleToYellow();
} else {
totalDurScale.setScaleToGrey();
}
totalDurScale.setTimeDuration(getQpeDurHr() + getQpfDurHr());
updateAccumAttrib(getQpeDurHr() + getQpfDurHr());
}
private void createHeaderLabel(String text) {
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
GridLayout gl = new GridLayout(1, false);
gl.marginHeight = 0;
Composite lblComp = new Composite(this, SWT.NONE);
lblComp.setLayout(gl);
lblComp.setLayoutData(gd);
lblComp.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_DARK_GRAY));
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
Label attrLbl = new Label(lblComp, SWT.NONE);
attrLbl.setText(text);
attrLbl.setFont(labelFont);
attrLbl.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_DARK_GRAY));
attrLbl.setForeground(parent.getDisplay().getSystemColor(
SWT.COLOR_WHITE));
attrLbl.setLayoutData(gd);
}
/**
* Set the dialog to reflect the saved configuration.
*/
private void setSettings() {
// Select the configured items, otherwise select the first
if (this.fftiSetting != null) {
// QPE
if (fftiSetting.getQpeSource().getDisplayNameList() == null ||
fftiSetting.getQpeSource().getDisplayNameList().isEmpty()) {
qpeList.setSelection(0);
} else {
// Only using the first one in the list to match A1
java.util.List<String> items = Arrays.asList(qpeList.getItems());
String name = fftiSetting.getQpeSource().getDisplayNameList().get(0);
int idx = items.indexOf(name);
qpeList.select(idx);
qpeList.showSelection();
}
// GUID
if (fftiSetting.getGuidSource().getDisplayNameList() == null ||
fftiSetting.getGuidSource().getDisplayNameList().isEmpty()) {
guidList.setSelection(0);
} else {
// Only using the first one in the list to match A1
java.util.List<String> items = Arrays.asList(guidList.getItems());
String name = fftiSetting.getGuidSource().getDisplayNameList().get(0);
int idx = items.indexOf(name);
guidList.select(idx);
guidList.showSelection();
}
// QPF
if (fftiSetting.getQpfSource().getDisplayNameList() == null ||
fftiSetting.getQpfSource().getDisplayNameList().isEmpty()) {
qpfList.setSelection(0);
} else {
// Only using the first one in the list to match A1
java.util.List<String> items = Arrays.asList(qpfList.getItems());
String name = fftiSetting.getQpfSource().getDisplayNameList().get(0);
int idx = items.indexOf(name);
qpfList.select(idx);
qpfList.showSelection();
}
}
}
private void accumAction(FFTIAttribute attribVal) {
// change attribute values
sliderCanvasLabel.setText("inches");
this.sliderCanvas.setValues(attribVal);
// deactivate guid
guidToggle.setToggleState(false);
guidDurSlider.setTimeDuration(guidDurSlider.getLowerVal());
guidDurSlider.enableScale(false);
guidList.setEnabled(false);
}
private void ratioAction(FFTIAttribute attribVal) {
// change attribute values
sliderCanvasLabel.setText("x100%");
this.sliderCanvas.setValues(attribVal);
// reset guid, qpe and total duartion hour if GUID was off
if (!guidToggle.getToggleState()) {
this.updateGuidDurHour(1.0);
this.updateQPEDurHour(1.0);
this.updateTotalDurHour(1.0);
}
// activate guid
guidToggle.setToggleState(true);
guidDurSlider.enableScale(true);
guidList.setEnabled(true);
}
private void diffAction(FFTIAttribute attribVal) {
// change attribute value
sliderCanvasLabel.setText("inches");
this.sliderCanvas.setValues(attribVal);
if (!guidToggle.getToggleState()) {
this.updateGuidDurHour(1.0);
this.updateQPEDurHour(1.0);
this.updateTotalDurHour(1.0);
}
// activate guid
guidToggle.setToggleState(true);
guidDurSlider.enableScale(true);
guidList.setEnabled(true);
}
public ToggleCanvas getQpfToggle() {
return qpfToggle;
}
public ToggleCanvas getGuidToggle() {
return guidToggle;
}
public ToggleCanvas getqpeToggle() {
return qpeToggle;
}
public void setQpeToggleState(boolean state) {
qpeToggle.setToggleState(state);
}
public void qpeSrcToggled(boolean qpeState) {
if (this.isAccumRdoSelected() && qpeState) {
qpeToggle.setToggleState(!qpeState); // toggle the QPE src
// duration value to 0.0
setQPEDurHr(0.0);
// update the total duration
if (this.qpfToggle.getToggleState()) {
double durHr = Double.parseDouble(qpfDurCbo.getItem(qpfDurCbo
.getSelectionIndex()));
updateTotalDurHour(durHr);
} else {
updateTotalDurHour(0.0);
}
}
}
public void qpfSrcToggled(boolean qpfState) {
// update the QPF duration hour combo
int index = qpfDurCbo.getSelectionIndex();
if (qpfState) { // change back to original value
qpfDurCbo.setItem(index, selectedQpfVal);
} else {// change selected value to '0'
selectedQpfVal = qpfDurCbo.getItem(index);
qpfDurCbo.setItem(index, "0");
}
qpfDurCbo.select(index);
if (isAccumRdoSelected()) // update total slider
{
double totalDurHr = getQpeDurHr() + getQpfDurHr();
updateTotalDurHour(totalDurHr);
updateAccumAttrib(totalDurHr);
} else // update QPE
{
updateQPEDurHour(getTotalDurHr());
}
if (qpfState) {
totalDurScale.setScaleToYellow();
double qpfDurHr = Double.parseDouble(qpfDurCbo.getItem(qpfDurCbo
.getSelectionIndex()));
if (getTotalDurHr() < qpfDurHr) {
updateTotalDurHour(qpfDurHr);
}
} else {
totalDurScale.setScaleToGrey();
}
}
public boolean isAccumRdoSelected() {
return accumRdo.getSelection();
}
public String getSelectedAttribType() {
if (accumRdo.getSelection()) {
return "Accum";
} else if (this.ratioRdo.getSelection()) {
return "Ratio";
}
return "Diff";
}
public double getYellowThreshold() {
return sliderCanvas.getLowerValue();
}
public double getRedThreshold() {
return sliderCanvas.getUpperValue();
}
/**
* update QPE duration hour
*/
public void updateQPEDurHour(double durHour) {
if (this.qpfToggle.getToggleState()) {
double qpfDurHr = Double.parseDouble(this.qpfDurCbo
.getItem(qpfDurCbo.getSelectionIndex()));
durHour = durHour - qpfDurHr;
}
setQPEDurHr(durHour);
}
/**
* update QPE duration hour
*/
public void setQPEDurHr(double durHour) {
qpeDurHr = durHour;
if (durHour < 0.0) {
qpeDurHr = 0;
}
qpeToggle.setToggleState(qpeDurHr != 0);
this.qpeDurLbl.setText(durHoursStr + String.format("%2.2f", qpeDurHr));
qpeDurLbl.setSize(160, 20);
}
/**
* update total duration hour
*/
public void updateTotalDurHour(double guidDurHour) {
double totalDurHr = guidDurHour;
double qpfDurHr = Double.parseDouble(this.qpfDurCbo.getItem(qpfDurCbo
.getSelectionIndex()));
if (totalDurHr < qpfDurHr) {
totalDurHr = qpfDurHr;
}
if (totalDurHr < guidDurSlider.getLowerVal()) {
totalDurHr = guidDurSlider.getLowerVal();
}
if (totalDurHr > guidDurSlider.getUpperVal()) {
totalDurHr = guidDurSlider.getUpperVal();
}
this.totalDurScale.setTimeDuration(guidDurHour);
updateAccumAttrib(guidDurHour);
}
/**
* update GUID duration hour (from total scale)
*/
public void updateGuidDurHour(double durHour) {
if (!this.guidDurSlider.getEnabled()) {
return;
}
double totalDurHr = durHour;
if (totalDurHr < guidDurSlider.getLowerVal()) {
totalDurHr = guidDurSlider.getLowerVal();
}
if (totalDurHr > guidDurSlider.getUpperVal()) {
totalDurHr = guidDurSlider.getUpperVal();
}
this.guidDurSlider.setTimeDuration(totalDurHr);
}
public boolean getGuidEnabled() {
return this.guidDurSlider.getEnabled();
}
public String[] getQpfSrc() {
return qpfList.getSelection();
}
public double getQpfDurHr() {
if (this.qpfToggle.getToggleState() == false) {
return 0;
}
return Double.parseDouble(qpfDurCbo.getItem(qpfDurCbo
.getSelectionIndex()));
}
public String[] getGuidSrc() {
return guidList.getSelection();
}
public double getGuidDurHr() {
if (this.guidToggle.getToggleState() == false) {
return 0.0;
}
return this.guidDurSlider.getSelectedValue();
}
public String[] getQpeSrc() {
return qpeList.getSelection();
}
public double getQpeDurHr() {
if (this.qpeToggle.getToggleState() == false) {
return 0.0;
}
return qpeDurHr;
}
public void updateAccumAttrib(double totalDurHr) {
double accumMax = 1.0;
if (totalDurHr <= 0.25) {
accumMax = 1.0;
accumAttrib.setInc(0.05);
} else if (totalDurHr <= 4) {
accumMax = totalDurHr * 4;
accumAttrib.setInc(0.05);
} else if (totalDurHr <= 12) {
accumMax = totalDurHr * 3;
accumAttrib.setInc(0.1);
} else {
accumMax = totalDurHr * 2;
accumAttrib.setInc(0.25);
}
this.accumAttrib.setMax(accumMax);
if (this.isAccumRdoSelected()) {
this.accumAction(accumAttrib);
}
}
@Override
public double getTotalDurHr() {
return this.totalDurScale.getSelectedValue();
}
@Override
public double adjustTotalDurationHr(double durHr) {
double totalDurHr = durHr;
if (!isAccumRdoSelected()) {
if (totalDurHr > guidDurSlider.getUpperVal()) {
totalDurHr = guidDurSlider.getUpperVal();
}
}
if (totalDurHr < getQpfDurHr()) {
totalDurHr = getQpfDurHr();
}
return totalDurHr;
}
}

View file

@ -0,0 +1,212 @@
/**
* 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.ffmp.ffti;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
/**
*
* Toggle canvas to emulate toggle switches.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* ???????????? lvenable Initial creation
* Oct 10, 2013 #2464 lvenable Fix font memory leak.
* Nov 05, 2015 #5070 randerso Changed to use system font name (not AWT)
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class ToggleCanvas {
private Composite parentComp;
private Display display;
private String text;
private boolean toggleState = false;
private boolean toggleEnabled = true;
/*
* Canvas information
*/
private Canvas canvas;
private final int CANVAS_WIDTH = 70;
private final int CANVAS_HEIGHT = 20;
private int horizontalSpan = 1;
/*
* Font/text information
*/
private Font labelFont;
/*
* for change the QPE toggle and the total slider color
*/
SettingComp ownerComp = null;
/**
* Constructor.
*
* @param parentComp
* Parent composite.
* @param text
* Label text.
* @param toggleState
* Toggle state (on/off)
*/
public ToggleCanvas(Composite parentComp, String text, boolean toggleState) {
this(parentComp, text, toggleState, 1);
}
/**
* Constructor.
*
* @param parentComp
* Parent composite.
* @param text
* Label text.
* @param toggleState
* Toggle state (on/off)
* @param horizontalSpan
* How many columns to span.
*/
public ToggleCanvas(Composite parentComp, String text, boolean toggleState,
int horizontalSpan) {
this.parentComp = parentComp;
this.text = text;
this.toggleState = toggleState;
this.horizontalSpan = horizontalSpan;
display = this.parentComp.getDisplay();
init();
createCanvas();
}
private void init() {
labelFont = new Font(display, "Monospace", 10, SWT.BOLD);
parentComp.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
labelFont.dispose();
}
});
}
private void createCanvas() {
canvas = new Canvas(parentComp, SWT.DOUBLE_BUFFERED);
GridData gd = new GridData(SWT.CENTER, SWT.CENTER, true, true);
gd.horizontalSpan = horizontalSpan;
gd.heightHint = CANVAS_HEIGHT;
gd.widthHint = CANVAS_WIDTH;
canvas.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
canvas.setLayoutData(gd);
canvas.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
drawCanvas(e.gc);
}
});
canvas.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (toggleEnabled == false) {
return;
}
if ((ownerComp != null) && text.equals("QPF")) {
toggleState = !toggleState;
canvas.redraw();
ownerComp.qpfSrcToggled(toggleState);
}
}
});
}
private void drawCanvas(GC gc) {
gc.setAntialias(SWT.ON);
gc.setFont(labelFont);
gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
/*
* Draw toggle box
*/
if (toggleState == true) {
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
gc.fillRectangle(5, 5, 10, 10);
}
gc.setLineWidth(2);
gc.drawRectangle(4, 4, 12, 12);
/*
* Draw string
*/
gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
gc.drawString(text, 20, 2, true);
}
public void setToggleState(boolean state) {
toggleState = state;
canvas.redraw();
}
public boolean getToggleState() {
return toggleState;
}
public void setOwner(SettingComp owner) {
this.ownerComp = owner;
}
public void setToggleEnabled(boolean enabledFlag) {
this.toggleEnabled = enabledFlag;
}
}

View file

@ -0,0 +1,349 @@
/**
* 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.ffmp.ffti;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Scale;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery;
import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage;
import com.raytheon.uf.viz.core.exception.VizException;
/**
*
* Total duration scale for the FFTI display.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* ???? Initial creation
* Oct 7, 2013 #2437 lvenable Fixed color memory leak
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class TotalDurScaleComp extends Composite {
/** Parent composite. */
private Composite parent;
/** Scale value canvas. */
private Canvas scaleValueCanvas;
/** Scale range canvas. */
private Canvas scaleRangeCanvas;
/** Time duration scale control. */
private Scale timeDurScale;
/** Font for the canvas. */
private Font canvasFont;
/** Time duration hours. */
private double timeDurHours = 0.0;
/** Canvas height. */
private final int CANVAS_HEIGHT = 20;
/** Canvas width. */
private int CANVAS_WIDTH = 650;
/** X coordinate offset in pixels. */
private int xCoordOffset = 5;
/** Low value. */
private double lowerVal = 0.00;
/** Default retention time. */
private final int DEFAULT_RETENTION_TIME = 24;
/** Retention time. */
private int retentiontime = DEFAULT_RETENTION_TIME;
/** Range value. */
private double rangeVal = 12;
/** Array of display numbers. */
private double[] displayNumbers;
/** Duration interface. */
private DurationInterface owner = null;
/** Color yellow. */
private Color yellowClr;
/** Color grey. */
private Color greyClr;
/**
* Constructor.
*
* @param parent
*/
public TotalDurScaleComp(Composite parent) {
super(parent, 0);
this.parent = parent;
init();
}
private void init() {
retentiontime = this.getFFMPRetentiontime();
rangeVal = (Math.abs(lowerVal) + Math.abs(retentiontime));
displayNumbers = new double[(int) rangeVal / 2 + 1];
for (int i = 0; i < displayNumbers.length; i++)
displayNumbers[i] = lowerVal + i * 2;
// Set the font and colors.
canvasFont = new Font(parent.getDisplay(), "Monospace", 8, SWT.NORMAL);
yellowClr = new Color(parent.getDisplay(), 255, 255, 224);
greyClr = new Color(parent.getDisplay(), 239, 239, 239);
GridData gd = new GridData(SWT.FILL, SWT.FILL, false, true);
GridLayout gl = new GridLayout(1, false);
gl.verticalSpacing = 0;
gl.marginHeight = 0;
this.setLayout(gl);
this.setLayoutData(gd);
createControls();
this.pack();
this.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent arg0) {
canvasFont.dispose();
yellowClr.dispose();
greyClr.dispose();
}
});
}
private void createControls() {
scaleValueCanvas = new Canvas(this, SWT.DOUBLE_BUFFERED);
scaleValueCanvas.setLayoutData(new GridData(CANVAS_WIDTH + 10,
CANVAS_HEIGHT));
scaleValueCanvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawScaleValueCanvas(e.gc);
}
});
GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
gd.widthHint = CANVAS_WIDTH;
timeDurScale = new Scale(this, SWT.HORIZONTAL);
timeDurScale.setMinimum(0);
timeDurScale.setMaximum(retentiontime * 4);
timeDurScale.setIncrement(1);
timeDurScale.setPageIncrement(1);
timeDurScale.setLayoutData(gd);
timeDurScale.getDisplay();
timeDurScale.addMouseListener(new MouseListener() {
@Override
public void mouseDoubleClick(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
}
@Override
public void mouseUp(MouseEvent e) {
owner.updateQPEDurHour(timeDurHours);
owner.updateGuidDurHour(timeDurHours);
owner.updateAccumAttrib(timeDurHours);
}
});
timeDurScale.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
calcTimeDurHours();
setTimeDuration(timeDurHours);
owner.updateAccumAttrib(timeDurHours);
}
});
calcTimeDurHours();
scaleRangeCanvas = new Canvas(this, SWT.DOUBLE_BUFFERED);
scaleRangeCanvas.setLayoutData(new GridData(CANVAS_WIDTH + 10,
CANVAS_HEIGHT));
scaleRangeCanvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawScaleRangeCanvas(e.gc);
}
});
}
public void setScaleToYellow() {
timeDurScale.setForeground(yellowClr);
timeDurScale.setBackground(yellowClr);
}
public void setScaleToGrey() {
timeDurScale.setForeground(greyClr);
timeDurScale.setBackground(greyClr);
}
private void drawScaleValueCanvas(GC gc) {
int fontAveWidth = (int) gc.getFontMetrics().getAverageCharWidth();
double pixPerInc = (CANVAS_WIDTH - 35 - xCoordOffset) / rangeVal;
gc.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
int newXCoord = (int) Math.round(((this.timeDurHours + Math
.abs(lowerVal)) * pixPerInc + xCoordOffset));
if (Math.abs(this.timeDurHours) >= 10) {
newXCoord -= fontAveWidth / 2 - 2;
}
if (this.timeDurHours < 0.0) {
newXCoord -= 5;
}
gc.drawString(String.format("%2.2f", this.timeDurHours), newXCoord, 1,
true);
}
private void drawScaleRangeCanvas(GC gc) {
int fontAveWidth = (int) gc.getFontMetrics().getAverageCharWidth();
double pixPerInc = (CANVAS_WIDTH - 35 - xCoordOffset) / rangeVal;
gc.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
gc.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
for (double dVal : displayNumbers) {
int newXCoord = (int) Math.round(((dVal + Math.abs(lowerVal))
* pixPerInc + xCoordOffset));
if (Math.abs(dVal) >= 10) {
newXCoord -= fontAveWidth / 2 - 2;
}
if (dVal < 0.0) {
newXCoord -= 5;
}
gc.drawString(String.format("%2.2f", dVal), newXCoord, 1, true);
}
}
private void calcTimeDurHours() {
timeDurHours = ((((double) timeDurScale.getSelection()) * .25));
}
private void setTimeDurationScale(double val) {
timeDurScale.setSelection((int) (val / .25));
}
/**
* An equavalant of changeTotalDur in FFTIhandler.C
*
* @param val
*/
public void setTimeDuration(double val) {
timeDurHours = owner.adjustTotalDurationHr(val);
setTimeDurationScale(timeDurHours);
scaleValueCanvas.redraw();
}
/**
* Get the selected value.
*
* @return The selected value.
*/
public double getSelectedValue() {
return timeDurHours;
}
/**
* get the retention time (purge hour) from metadata.plugin_info
*
* @return retention time
*/
private int getFFMPRetentiontime() {
StringBuilder query = new StringBuilder();
query.append("select retentiontime from plugin_info where name = 'ffmp'");
List<Object[]> results;
try {
results = DirectDbQuery.executeQuery(query.toString(), "metadata",
QueryLanguage.SQL);
if (results.size() == 1) { // there should be only one
Object[] objs = results.get(0);
Integer retentiontime = (Integer) objs[0];
return retentiontime.intValue();
}
} catch (VizException e) {
return DEFAULT_RETENTION_TIME;
}
return DEFAULT_RETENTION_TIME;
}
/**
* Set the owner.
*
* @param owner
* The owner.
*/
public void setOwner(DurationInterface owner) {
this.owner = owner;
}
}

View file

@ -0,0 +1,70 @@
/**
* 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.ffmp.ui.actions;
import com.raytheon.uf.viz.monitor.ffmp.FFMPMonitor;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* FFMP Color Display toggle action.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 13, 2011 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class BasinToggleAction extends AbstractRightClickAction {
@Override
public void run() {
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (resource.isBasinToggle()) {
resource.setBasinToggle(false);
this.setChecked(false);
} else {
resource.setBasinToggle(true);
this.setChecked(true);
}
FFMPMonitor.getInstance().fireMonitorEvent();
resource.refresh();
}
@Override
public boolean isHidden() {
if (getSelectedRsc() instanceof FFMPResource) {
return false;
}
return true;
}
@Override
public String getText() {
return "FFMP Basin Display";
}
}

View file

@ -0,0 +1,65 @@
/**
* 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.ffmp.ui.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import com.raytheon.uf.viz.monitor.ffmp.fffg.FFFGDlg;
/**
* Kick off the FFMP dialog and application backend processes.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/27/09 dhladky Initial Creation.
* 1/29/2012 1353 rferrel Changes for non-blocking FFFGDlg.
*
* </pre>
*
* @author dhladky
*
*/
public class FFFGAction extends AbstractHandler {
private FFFGDlg fffgDlg;
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
// Independent dialog is disposed on close and cannot be reopened.
if (fffgDlg == null || fffgDlg.getShell() == null
|| fffgDlg.isDisposed()) {
Shell fshell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
fffgDlg = new FFFGDlg(fshell);
}
fffgDlg.open();
return null;
}
}

View file

@ -0,0 +1,57 @@
/**
* 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.ffmp.ui.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
/**
* Kick off the FFMP dialog and application backend processes.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/27/09 dhladky Initial Creation.
*
* </pre>
*
* @author dhladky
*
*/
public class FFMPAction extends AbstractHandler {
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
@SuppressWarnings("unused")
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
System.out.println("Activating/Action the FFMP plugin...");
return null;
}
}

View file

@ -0,0 +1,166 @@
package com.raytheon.uf.viz.monitor.ffmp.ui.actions;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.core.ColorUtil;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
import com.raytheon.viz.ui.cmenu.ChangeColorAction;
public class FFMPBasinColorAction extends ChangeColorAction {
@Override
public String getText() {
return "Change Basin Boundary Color...";
}
@Override
public boolean isHidden() {
if (getSelectedRsc() instanceof FFMPResource) {
return false;
}
return true;
}
@Override
public void fillMenu(Menu menu, Display d) {
ActionContributionItem.setUseColorIconsInToolbars(true);
RGB[] rgbPresets = ColorUtil.getResourceColorPresets();
boolean found = false;
FFMPResource resource = ((FFMPResource) getSelectedRsc());
RGB currentColor = resource.getBasinBoundaryColor();
for (RGB rgb : rgbPresets) {
boolean selected = rgb.equals(currentColor);
found |= selected;
ActionContributionItem actionItem = new ActionContributionItem(
new ChangeColorInternalAction(rgb, d, selected));
actionItem.fill(menu, -1);
}
if (!found && (currentColor != null)) {
ActionContributionItem actionItem = new ActionContributionItem(
new ChangeColorInternalAction(currentColor, d, true));
actionItem.fill(menu, -1);
}
ActionContributionItem actionItem = new ActionContributionItem(
new ChooseColorInternalAction(this));
actionItem.fill(menu, -1);
}
private class ChangeColorInternalAction extends Action {
private RGB rgb;
public ChangeColorInternalAction(RGB rgb, Display d, boolean selected) {
super(RGBColors.getColorName(rgb));
// super(new
// StringBuilder("R:").append(rgb.red).append(" G:").append(
// rgb.green).append(" B:").append(rgb.blue).toString());
this.rgb = rgb;
Image image = new Image(d, 20, 20);
Rectangle bounds = image.getBounds();
Color color = new Color(d, rgb);
GC gc = new GC(image);
gc.setBackground(color);
gc.fillRectangle(bounds);
gc.setForeground(d.getSystemColor(SWT.COLOR_BLACK));
gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1,
bounds.height - 1);
if (selected) {
gc.setLineWidth(2);
gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width - 1,
bounds.y + bounds.height - 1);
gc.drawLine(bounds.x + bounds.width - 1, bounds.y, bounds.x,
bounds.y + bounds.height - 1);
}
gc.dispose();
color.dispose();
setImageDescriptor(ImageDescriptor.createFromImage(image));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#getText()
*/
@Override
public String getText() {
return super.getText();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (rgb != null) {
resource.setBasinBoundaryColor(rgb);
}
resource.refresh();
}
}
private class ChooseColorInternalAction extends Action {
private AbstractRightClickAction parentAction;
public ChooseColorInternalAction(AbstractRightClickAction parent) {
super("Choose Color...");
this.parentAction = parent;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#getText()
*/
@Override
public String getText() {
return super.getText();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
ColorDialog cd = new ColorDialog(VizWorkbenchManager.getInstance()
.getCurrentWindow().getShell());
cd.setRGB(parentAction.getTopMostSelectedResource()
.getCapability(ColorableCapability.class).getColor());
cd.setText(parentAction.getTopMostSelectedResource().getName());
RGB result = cd.open();
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (result != null) {
resource.setBasinBoundaryColor(result);
}
resource.refresh();
}
}
}

View file

@ -0,0 +1,70 @@
/**
* 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.ffmp.ui.actions;
import com.raytheon.uf.viz.monitor.ffmp.FFMPMonitor;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* FFMP Color Display toggle action.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 9, 2011 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class FFMPColorDisplayToggleAction extends AbstractRightClickAction {
@Override
public void run() {
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (resource.isFfmpDataToggle()) {
resource.setFfmpDataToggle(false);
this.setChecked(false);
} else {
resource.setFfmpDataToggle(true);
this.setChecked(true);
}
FFMPMonitor.getInstance().fireMonitorEvent();
resource.refresh();
}
@Override
public boolean isHidden() {
if (getSelectedRsc() instanceof FFMPResource) {
return false;
}
return true;
}
@Override
public String getText() {
return "FFMP Color Display";
}
}

View file

@ -0,0 +1,166 @@
package com.raytheon.uf.viz.monitor.ffmp.ui.actions;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.core.ColorUtil;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
import com.raytheon.viz.ui.cmenu.ChangeColorAction;
public class FFMPTraceColorAction extends ChangeColorAction {
@Override
public String getText() {
return "Change Up/Down Stream Color...";
}
@Override
public boolean isHidden() {
if (getSelectedRsc() instanceof FFMPResource) {
return false;
}
return true;
}
@Override
public void fillMenu(Menu menu, Display d) {
ActionContributionItem.setUseColorIconsInToolbars(true);
RGB[] rgbPresets = ColorUtil.getResourceColorPresets();
boolean found = false;
FFMPResource resource = ((FFMPResource) getSelectedRsc());
RGB currentColor = resource.getBasinTraceColor();
for (RGB rgb : rgbPresets) {
boolean selected = rgb.equals(currentColor);
found |= selected;
ActionContributionItem actionItem = new ActionContributionItem(
new ChangeColorInternalAction(rgb, d, selected));
actionItem.fill(menu, -1);
}
if (!found && (currentColor != null)) {
ActionContributionItem actionItem = new ActionContributionItem(
new ChangeColorInternalAction(currentColor, d, true));
actionItem.fill(menu, -1);
}
ActionContributionItem actionItem = new ActionContributionItem(
new ChooseColorInternalAction(this));
actionItem.fill(menu, -1);
}
private class ChangeColorInternalAction extends Action {
private RGB rgb;
public ChangeColorInternalAction(RGB rgb, Display d, boolean selected) {
super(RGBColors.getColorName(rgb));
// super(new
// StringBuilder("R:").append(rgb.red).append(" G:").append(
// rgb.green).append(" B:").append(rgb.blue).toString());
this.rgb = rgb;
Image image = new Image(d, 20, 20);
Rectangle bounds = image.getBounds();
Color color = new Color(d, rgb);
GC gc = new GC(image);
gc.setBackground(color);
gc.fillRectangle(bounds);
gc.setForeground(d.getSystemColor(SWT.COLOR_BLACK));
gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1,
bounds.height - 1);
if (selected) {
gc.setLineWidth(2);
gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width - 1,
bounds.y + bounds.height - 1);
gc.drawLine(bounds.x + bounds.width - 1, bounds.y, bounds.x,
bounds.y + bounds.height - 1);
}
gc.dispose();
color.dispose();
setImageDescriptor(ImageDescriptor.createFromImage(image));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#getText()
*/
@Override
public String getText() {
return super.getText();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (rgb != null) {
resource.setBasinTraceColor(rgb);
}
resource.refresh();
}
}
private class ChooseColorInternalAction extends Action {
private AbstractRightClickAction parentAction;
public ChooseColorInternalAction(AbstractRightClickAction parent) {
super("Choose Color...");
this.parentAction = parent;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#getText()
*/
@Override
public String getText() {
return super.getText();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.action.Action#run()
*/
@Override
public void run() {
ColorDialog cd = new ColorDialog(VizWorkbenchManager.getInstance()
.getCurrentWindow().getShell());
cd.setRGB(parentAction.getTopMostSelectedResource()
.getCapability(ColorableCapability.class).getColor());
cd.setText(parentAction.getTopMostSelectedResource().getName());
RGB result = cd.open();
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (result != null) {
resource.setBasinTraceColor(result);
}
resource.refresh();
}
}
}

View file

@ -0,0 +1,68 @@
/**
* 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.ffmp.ui.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import com.raytheon.uf.viz.monitor.ffmp.ffti.FFTIControlDlg;
/**
* Kick off the FFTI dialog and application backend processes.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/27/10 4265 dhladky Initial Creation.
* 12/05/2012 1353 rferrel Changes for non-blocking FFTIControlDlg.
* 03/28/2013 1790 rferrel Bug fix for non-blocking dialogs.
*
* </pre>
*
* @author dhladky
*
*/
public class FFTIAction extends AbstractHandler {
private FFTIControlDlg fftiControlDlg;
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
if (fftiControlDlg == null || fftiControlDlg.isDisposed()) {
fftiControlDlg = new FFTIControlDlg(shell);
fftiControlDlg.open();
} else {
fftiControlDlg.bringToTop();
}
shell.setCursor(null);
return null;
}
}

View file

@ -0,0 +1,70 @@
/**
* 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.ffmp.ui.actions;
import com.raytheon.uf.viz.monitor.ffmp.FFMPMonitor;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* FFMP up/down stream toggle action.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 13, 2011 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class StreamToggleAction extends AbstractRightClickAction {
@Override
public void run() {
FFMPResource resource = ((FFMPResource) getSelectedRsc());
if (resource.isStreamToggle()) {
resource.setStreamToggle(false);
this.setChecked(false);
} else {
resource.setStreamToggle(true);
this.setChecked(true);
}
FFMPMonitor.getInstance().fireMonitorEvent();
resource.refresh();
}
@Override
public boolean isHidden() {
if (getSelectedRsc() instanceof FFMPResource) {
return false;
}
return true;
}
@Override
public String getText() {
return "Up/Down Stream Display";
}
}

View file

@ -0,0 +1,292 @@
/**
* 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.ffmp.ui.dialogs;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.TableCellColor;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.ThreshColNames;
import com.raytheon.uf.viz.monitor.ffmp.xml.FFMPTableColumnXML;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* FFMP Basin Table Threshold attribute display dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Dec 6, 2012 1353 rferrel Changes for non-blocking dialog.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class AttributeThresholdDlg extends CaveSWTDialog {
private Text upperText;
private Text midText;
private Text lowerText;
private Text filterText;
private ThreshColNames threshCol;
private Double upperVal = Double.NaN;
private Double midVal = Double.NaN;
private Double lowerVal = Double.NaN;
private Double filterVal = Double.NaN;
private IThreshDisplay threshActionCB;
public AttributeThresholdDlg(Shell parent, ThreshColNames threshCol,
IThreshDisplay threshActionCB) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
this.threshCol = threshCol;
this.threshActionCB = threshActionCB;
setText("Attributes " + threshCol.name());
}
@Override
protected Layout constructShellLayout() {
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 0;
mainLayout.marginWidth = 2;
mainLayout.verticalSpacing = 2;
return mainLayout;
}
@Override
protected void initializeComponents(Shell shell) {
createControls();
createBottomButtons();
}
private void createControls() {
int labelWidth = 75;
FFMPConfig ffmpCfg = FFMPConfig.getInstance();
Composite controlComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(2, false);
gl.horizontalSpacing = 10;
controlComp.setLayout(gl);
controlComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true,
false));
/*
* Upper threshold controls.
*/
GridData gd = new GridData(SWT.FILL, SWT.CENTER, false, true);
gd.widthHint = labelWidth;
Label upperLbl = new Label(controlComp, SWT.RIGHT);
upperLbl.setText("Upper:");
upperLbl.setLayoutData(gd);
gd = new GridData(100, SWT.DEFAULT);
upperText = new Text(controlComp, SWT.BORDER);
upperText.setLayoutData(gd);
upperText.setBackground(ffmpCfg.getCellColor(TableCellColor.Upper));
/*
* Mid threshold controls.
*/
gd = new GridData(SWT.FILL, SWT.CENTER, false, true);
gd.widthHint = labelWidth;
Label midLbl = new Label(controlComp, SWT.RIGHT);
midLbl.setText("Mid:");
midLbl.setLayoutData(gd);
gd = new GridData(100, SWT.DEFAULT);
midText = new Text(controlComp, SWT.BORDER);
midText.setLayoutData(gd);
midText.setBackground(ffmpCfg.getCellColor(TableCellColor.Mid));
/*
* Lower threshold controls.
*/
gd = new GridData(SWT.FILL, SWT.CENTER, false, true);
gd.widthHint = labelWidth;
Label lowerLbl = new Label(controlComp, SWT.RIGHT);
lowerLbl.setText("Lower:");
lowerLbl.setLayoutData(gd);
gd = new GridData(100, SWT.DEFAULT);
lowerText = new Text(controlComp, SWT.BORDER);
lowerText.setLayoutData(gd);
lowerText.setBackground(ffmpCfg.getCellColor(TableCellColor.Lower));
/*
* Filter controls.
*/
gd = new GridData(SWT.FILL, SWT.CENTER, false, true);
gd.widthHint = labelWidth;
Label filterLbl = new Label(controlComp, SWT.RIGHT);
filterLbl.setText("Filter:");
filterLbl.setLayoutData(gd);
gd = new GridData(100, SWT.DEFAULT);
filterText = new Text(controlComp, SWT.BORDER);
filterText.setLayoutData(gd);
updateTextControls(ffmpCfg);
}
private void createBottomButtons() {
Composite buttonComp = new Composite(shell, SWT.NONE);
buttonComp.setLayout(new GridLayout(2, true));
buttonComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true,
false));
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = 80;
Button applyBtn = new Button(buttonComp, SWT.PUSH);
applyBtn.setText("Apply");
applyBtn.setLayoutData(gd);
applyBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (validateEntries() == false) {
return;
}
updateThresholdValues();
shell.dispose();
}
});
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = 80;
Button cancelBtn = new Button(buttonComp, SWT.PUSH);
cancelBtn.setText("Cancel");
cancelBtn.setLayoutData(gd);
cancelBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
shell.dispose();
}
});
}
private void updateTextControls(FFMPConfig ffmpCfg) {
FFMPTableColumnXML tcXML;
tcXML = ffmpCfg.getTableColumnData(this.threshCol);
upperText.setText(String.valueOf(tcXML.getUpper()));
tcXML = ffmpCfg.getTableColumnData(this.threshCol);
midText.setText(String.valueOf(tcXML.getMid()));
tcXML = ffmpCfg.getTableColumnData(this.threshCol);
lowerText.setText(String.valueOf(tcXML.getLow()));
tcXML = ffmpCfg.getTableColumnData(this.threshCol);
filterText.setText(String.valueOf(tcXML.getFilter()));
}
private boolean validateEntries() {
upperVal = textIsANumber(upperText.getText());
if (upperVal.isNaN() == true) {
displayMessage("Upper value is not a number.");
return false;
}
midVal = textIsANumber(midText.getText());
if (midVal.isNaN() == true) {
displayMessage("Mid value is not a number.");
return false;
}
lowerVal = textIsANumber(lowerText.getText());
if (lowerVal.isNaN() == true) {
displayMessage("Lower value is not a number.");
return false;
}
filterVal = textIsANumber(filterText.getText());
if (filterVal.isNaN() == true) {
displayMessage("Filter value is not a number.");
return false;
}
if (upperVal < midVal) {
displayMessage("Upper value is less than mid value.");
return false;
}
if (midVal < lowerVal) {
displayMessage("Mid value is less than lower value.");
return false;
}
return true;
}
private void updateThresholdValues() {
FFMPConfig ffmpCfg = FFMPConfig.getInstance();
ffmpCfg.updateThresholdValues(this.threshCol, upperVal, midVal,
lowerVal, filterVal);
threshActionCB.thresholdUpdated(this.threshCol);
}
private Double textIsANumber(String text) {
try {
Double ds = Double.parseDouble(text);
return ds;
} catch (NumberFormatException nfe) {
return Double.NaN;
}
}
private void displayMessage(String message) {
MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
mb.setText("Threshold Error");
mb.setMessage(message);
mb.open();
}
public void newThreshold(ThreshColNames threshCol) {
this.threshCol = threshCol;
shell.setText("Attributes " + threshCol.name());
FFMPConfig ffmpCfg = FFMPConfig.getInstance();
updateTextControls(ffmpCfg);
}
}

View file

@ -0,0 +1,350 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager;
import com.raytheon.uf.common.monitor.xml.ProductRunXML;
import com.raytheon.uf.common.monitor.xml.ProductXML;
import com.raytheon.uf.viz.monitor.ffmp.FFMPMonitor;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FfmpTableConfigData.COLUMN_NAME;
import com.raytheon.uf.viz.monitor.ffmp.ui.rsc.FFMPResource;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Display FFMP Basin Table Attributes.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Dec 6, 2012 rferrel Change to non-blocking dialog.
* Oct, 21 2015 4821 dhladky Fixed bad ffgType subString and width.
* Mar 16, 2016 5463 dhladky Fixed config loading and button matching.
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class AttributesDlg extends CaveSWTDialog {
private Button rateChk;
private Button qpeChk;
private Button qpfChk;
private Button guidChk;
private Button ratioChk;
private Button diffChk;
private ArrayList<Button> attributeChkBtns;
/**
* List of QPF data radio buttons.
*/
private List<Button> qpfRdoBtns = new ArrayList<Button>();
/**
* List of QPF data radio buttons.
*/
private List<Button> ffgChkBtns = new ArrayList<Button>();
private IAttributeDisplay attributeDisplayCb;
private FFMPResource resource;
private boolean updateData = false;
private AttributesDlgData attrData;
private Shell parent = null;
public AttributesDlg(Shell parent, FFMPResource resource,
AttributesDlgData attrData, IAttributeDisplay attributeDisplayCb) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
this.parent = parent;
this.resource = resource;
setText("Attributes");
this.attributeDisplayCb = attributeDisplayCb;
this.attrData = attrData;
}
@Override
protected Layout constructShellLayout() {
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 0;
mainLayout.marginWidth = 2;
mainLayout.verticalSpacing = 2;
return mainLayout;
}
@Override
protected void initializeComponents(Shell shell) {
createAttributeControls();
addSeparator(shell);
createBottomButtons();
}
private void createAttributeControls() {
attributeChkBtns = new ArrayList<Button>();
Composite attrComp = new Composite(shell, SWT.NONE | SWT.NO_RADIO_GROUP);
attrComp.setLayout(new GridLayout(1, false));
rateChk = new Button(attrComp, SWT.CHECK);
rateChk.setText("rate");
rateChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.RATE
.getColumnName()));
rateChk.setData(COLUMN_NAME.RATE.getColumnName());
addCheckBoxListener(rateChk);
attributeChkBtns.add(rateChk);
qpeChk = new Button(attrComp, SWT.CHECK);
qpeChk.setText("qpe");
qpeChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.QPE
.getColumnName()));
qpeChk.setData(COLUMN_NAME.QPE.getColumnName());
addCheckBoxListener(qpeChk);
attributeChkBtns.add(qpeChk);
qpfChk = new Button(attrComp, SWT.CHECK);
qpfChk.setText("qpf");
qpfChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.QPF
.getColumnName()));
qpfChk.setData(COLUMN_NAME.QPF.getColumnName());
attributeChkBtns.add(qpfChk);
qpfChk.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
for (Button btn : qpfRdoBtns) {
btn.setEnabled(qpfChk.getSelection());
}
updateAction(qpfChk);
}
});
FFMPMonitor monitor = FFMPMonitor.getInstance();
ProductXML prodXml = monitor.getProductXML(resource.getPrimarySource());
GridData gd = new GridData();
FfmpTableConfigData ffmpTableCfgData = FfmpTableConfig.getInstance()
.getTableConfigData(resource.getSiteKey());
FFMPRunConfigurationManager runManager = FFMPRunConfigurationManager
.getInstance();
ProductRunXML productRun = runManager.getProduct(resource.getSiteKey());
ArrayList<String> qpfTypes = productRun.getQpfTypes(prodXml);
String qpfType = ffmpTableCfgData.getQpfType();
for (String name : qpfTypes) {
final Button qpfBtn = new Button(attrComp, SWT.RADIO);
qpfBtn.setText(name);
qpfBtn.setData(name);
gd.horizontalIndent = 15;
qpfBtn.setLayoutData(gd);
qpfBtn.setEnabled(qpfChk.getSelection());
qpfRdoBtns.add(qpfBtn);
qpfBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String qpfType = ((Button) e.getSource()).getText();
for (int i = 0; i < qpfRdoBtns.size(); i++) {
Button rdo = qpfRdoBtns.get(i);
if (rdo.getText().equals(qpfType)) {
parent.setCursor(getDisplay().getSystemCursor(
SWT.CURSOR_WAIT));
FfmpTableConfigData ffmpTableCfgData = FfmpTableConfig
.getInstance().getTableConfigData(
resource.getSiteKey());
ffmpTableCfgData.setQpfType(qpfType,
resource.getSiteKey());
attrData.setQpfType(qpfType);
rdo.setSelection(true);
} else {
rdo.setSelection(false);
}
}
updateData = true;
updateAction(qpfChk);
}
});
if (qpfType.startsWith(name)) {
qpfBtn.setSelection(true);
updateAction(qpfBtn);
}
}
guidChk = new Button(attrComp, SWT.CHECK);
guidChk.setText("guid");
guidChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.GUID
.getColumnName()));
guidChk.setData(COLUMN_NAME.GUID.getColumnName());
addCheckBoxListener(guidChk);
attributeChkBtns.add(guidChk);
ratioChk = new Button(attrComp, SWT.CHECK);
ratioChk.setText("ratio");
ratioChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.RATIO
.getColumnName()));
ratioChk.setData(COLUMN_NAME.RATIO.getColumnName());
addCheckBoxListener(ratioChk);
attributeChkBtns.add(ratioChk);
diffChk = new Button(attrComp, SWT.CHECK);
diffChk.setText("diff");
diffChk.setSelection(attrData.isColumnVisible(COLUMN_NAME.DIFF
.getColumnName()));
diffChk.setData(COLUMN_NAME.DIFF.getColumnName());
addCheckBoxListener(diffChk);
attributeChkBtns.add(diffChk);
addSeparator(attrComp);
gd.horizontalIndent = 15;
gd.widthHint = 180;
ArrayList<String> guidTypes = productRun.getGuidanceTypes(prodXml);
for (String name : guidTypes) {
final Button ffgBtn = new Button(attrComp, SWT.CHECK);
ffgBtn.setText(name);
ffgBtn.setData("GUIDSrc:" + name);
gd.horizontalIndent = 15;
ffgBtn.setLayoutData(gd);
ffgBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateAction(ffgBtn);
}
});
// default selection(s) based on config
if (attrData.getGuidanceList().containsKey(name)) {
ffgBtn.setSelection(true);
updateAction(ffgBtn);
}
ffgChkBtns.add(ffgBtn);
}
}
private void createBottomButtons() {
Composite buttonComp = new Composite(shell, SWT.NONE);
buttonComp.setLayout(new GridLayout(1, false));
buttonComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true,
false));
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
Button closeBtn = new Button(buttonComp, SWT.PUSH);
closeBtn.setText(" Close ");
closeBtn.setLayoutData(gd);
closeBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
private void addCheckBoxListener(final Button checkBox) {
checkBox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateAction(checkBox);
}
});
}
private void addSeparator(Composite parentComp) {
GridLayout gl = (GridLayout) parentComp.getLayout();
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gd.horizontalSpan = gl.numColumns;
Label sepLbl = new Label(parentComp, SWT.SEPARATOR | SWT.HORIZONTAL);
sepLbl.setLayoutData(gd);
}
private void updateAction(Button chk) {
String key = null;
String guidSrc = null;
String data = (String) chk.getData();
if (data.contains(":")) {
String[] parts = data.split(":");
guidSrc = parts[1];
key = parts[0];
} else {
key = data;
attrData.setColumnVisible(key, chk.getSelection());
if (key.equalsIgnoreCase("QPF")) {
String qpfType = "xxxxxx";
for (Button button : qpfRdoBtns) {
if (button.getSelection()) {
qpfType = button.getText();
// split window requires redraw on change
updateData = true;
break;
}
}
attrData.setQpfType(qpfType);
}
}
// update included guid sources if needed
if (guidSrc != null) {
HashMap<String, Boolean> guidMap = attrData.getGuidanceList();
if (chk.getSelection()) {
guidMap.put(guidSrc, chk.getSelection());
} else {
guidMap.remove(guidSrc);
}
attrData.setGuidanceMap(guidMap);
updateData = true;
}
// Call the call back with the updated columns
attributeDisplayCb.attributeDisplayAction(updateData, attrData);
}
}

View file

@ -0,0 +1,95 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.HashMap;
/**
* State of the Attributes Dialog
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 5, 2011 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class AttributesDlgData {
private HashMap<String, Boolean> columnVisibilityMap = new HashMap<String, Boolean>();
private HashMap<String, Boolean> guidanceMap = new HashMap<String, Boolean>();
private String qpfType = null;
public boolean isGuidColumnIncluded(String colName) {
if (guidanceMap.containsKey(colName)) {
return guidanceMap.get(colName);
} else {
return false;
}
}
public boolean isColumnVisible(String colName) {
return columnVisibilityMap.get(colName);
}
public void setGuidColumnIncluded(String colName, boolean visible) {
guidanceMap.put(colName, visible);
}
public void setColumnVisible(String colName, boolean visible) {
columnVisibilityMap.put(colName, visible);
}
/**
* @return the guidanceMap
*/
public HashMap<String, Boolean> getGuidanceList() {
return guidanceMap;
}
/**
* @param guidanceMap the guidanceMap to set
*/
public void setGuidanceMap(HashMap<String, Boolean> guidanceMap) {
this.guidanceMap = guidanceMap;
}
/**
* @return the qpfType
*/
public String getQpfType() {
return qpfType;
}
/**
* @param qpfType the qpfType to set
*/
public void setQpfType(String qpfType) {
this.qpfType = qpfType;
}
}

View file

@ -0,0 +1,103 @@
/**
* 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.ffmp.ui.dialogs;
/**
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 05 2017 DR 14336 lshi FFMP VGB value differences between A1 and A2
* changed "vgb" label to "gauge"
*/
public class BasinTrendCommon
{
public BasinTrendCommon()
{
}
public enum PlotItems
{
RATE("rate"), QPE("qpe"), QPF("qpf"), QPFSCAN("QPFSCAN"), GUID("guid"),
RFCFFG("RFCFFG"), VGB("gauge");
private String itemName;
PlotItems(String name)
{
itemName = name;
}
public String getItemName()
{
return itemName;
}
}
public enum Underlays
{
RATE("rate"), QPE("qpe"), RATIO("ratio"), DIFF("diff");
private String itemName;
Underlays(String name)
{
itemName = name;
}
public String getUnderlayName()
{
return itemName;
}
}
public enum TimeDuration
{
ALL("All hr.", 24, 16), HR_1("1 hr.", 1, 5), HR_3("3 hr.", 3, 9), HR_6("6 hr.", 6, 12),
HR_12("12 hr.", 12, 14), HR_24("24 hr.", 24, 16);
private String timeDurName;
private int hours;
private int yCoordHours;
TimeDuration(String name, int hrs, int yCoordHrs)
{
timeDurName = name;
hours = hrs;
yCoordHours = yCoordHrs;
}
public String getTimeDurName()
{
return timeDurName;
}
public int getHours()
{
return hours;
}
public int getYCoordHours()
{
return yCoordHours;
}
}
}

View file

@ -0,0 +1,105 @@
/**
* 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.ffmp.ui.dialogs;
/**
* This class sets the Basin Trend Graph's boundaries.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 10, 2015 4756 dhladky Initial creation
* Feb 15, 2016 5360 tjensen Update getSkipValue to improve labeling
*
* </pre>
*
* @author dhladky
* @version 1.0
*/
public class BasinTrendGraphBounds {
/** name of the graph **/
private String timeDurName;
/** hours, (X Axis) **/
private int hours;
/** number of y Coordinate values **/
private int yCoordValues;
public BasinTrendGraphBounds() {
}
public String getTimeDurName()
{
return timeDurName;
}
public int getHours()
{
return hours;
}
public int getYCoordValues()
{
return yCoordValues;
}
public void setYCoordValues(int yCoordValues) {
this.yCoordValues = yCoordValues;
}
public void setTimeDurName(String timeDurName) {
this.timeDurName = timeDurName;
}
public void setHours(int hours) {
this.hours = hours;
}
/**
* Gets the label skipping for the Y axis of the Basin trend Graph.
* @return int
*/
public int getSkipValue() {
int skip = 1;
if (yCoordValues > 0) {
if (yCoordValues >= 20 && yCoordValues < 40) {
skip = 2;
} else if (yCoordValues >= 40 && yCoordValues < 100) {
skip = 5;
} else if (yCoordValues >= 100 && yCoordValues < 200) {
skip = 10;
} else if (yCoordValues >= 200 && yCoordValues < 500) {
skip = 25;
} else if (yCoordValues >= 500) {
skip = 50;
}
}
return skip;
}
}

View file

@ -0,0 +1,147 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.ArrayList;
import java.util.Iterator;
public class ConfigSummaryData
{
private String layer = "";
private boolean linkToFrame = false;
private boolean worstCase = false;
private boolean zoomMaintainLayer = false;
private boolean zoomOnlyBasins = false;
private ArrayList<String> includedCWAs = new ArrayList<String>();
private String d2dClickAction = "";
private String d2dDisplayType = "";
private boolean autoRefresh = false;
public ConfigSummaryData(String layer, boolean linkToFrame, boolean worstCase,
boolean zoomMaintainLayer, boolean zoomOnlyBasins, ArrayList<String> includedCWAs,
String clickAction, String displayType, boolean autoRefresh)
{
this.layer = layer;
this.linkToFrame = linkToFrame;
this.worstCase = worstCase;
this.zoomMaintainLayer = zoomMaintainLayer;
this.zoomOnlyBasins = zoomOnlyBasins;
this.includedCWAs = includedCWAs;
this.d2dClickAction = clickAction;
this.d2dDisplayType = displayType;
this.autoRefresh = autoRefresh;
}
public String getLayer()
{
return layer;
}
public String getLinkToFrame()
{
if (linkToFrame == true)
{
return "y";
}
return "n";
}
public String getWorstCase()
{
if (worstCase == true)
{
return "y";
}
return "n";
}
public String getZoomMaintainLayer()
{
if (zoomMaintainLayer == true)
{
return "y";
}
return "n";
}
public String getZoomOnlyBasins()
{
if (zoomOnlyBasins == true)
{
return "y";
}
return "n";
}
public String getIncludedCWAs()
{
StringBuilder sb = new StringBuilder();
Iterator<String> iter = includedCWAs.iterator();
while (iter.hasNext() == true)
{
sb.append(iter.next());
if (iter.hasNext() == true)
{
sb.append(", ");
}
}
return sb.toString();
}
public String getD2dClickAction()
{
return d2dClickAction;
}
public String getD2dDisplayType()
{
return d2dDisplayType;
}
public String getAutoRefresh()
{
if (autoRefresh == true)
{
return "y";
}
return "n";
}
public String[] getDisplayData()
{
String[] dataArray = new String[9];
dataArray[0] = getLayer();
dataArray[1] = getLinkToFrame();
dataArray[2] = getWorstCase();
dataArray[3] = getZoomMaintainLayer();
dataArray[4] = getZoomOnlyBasins();
dataArray[5] = getIncludedCWAs();
dataArray[6] = getD2dClickAction();
dataArray[7] = getD2dDisplayType();
dataArray[8] = getAutoRefresh();
return dataArray;
}
}

View file

@ -0,0 +1,363 @@
/**
* 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.ffmp.ui.dialogs;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Display FFMP Basin Table's configuration summary data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Dec 6, 2012 1353 rferrel Convert to CaveSWTDialog and made non-blocking.
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class ConfigSummaryDlg extends CaveSWTDialog {
/**
* Canvas to display the information.
*/
private Canvas canvas;
/**
* Canvas width.
*/
private int canvasWidth = 50;
/**
* Canvas height.
*/
private int canvasHeight = 50;
/**
* Color of the left side of the canvas.
*/
private Color leftSideColor;
/**
* Color of the right side of the canvas.
*/
private Color rightSideColor;
/**
* Text font.
*/
private Font textFont;
/**
* Coordinates of the button that launched this dialog.
*/
private Point controlLoc;
/**
* Configuration summary data to be displayed.
*/
private ConfigSummaryData cfgSumData;
/**
* Maximum data label characters.
*/
private int maxDataLabelLen = -1;
/**
* Maximum configuration data characters.
*/
private int maxCfgDataLen = -1;
/**
* Width of the black colon band in the middle of the dialog.
*/
private int colonBand = 10;
/**
* Size of the borer in pixels.
*/
private int borderSize = 5;
/**
* Width of the text.
*/
private int textWidth = 8;
/**
* Height of the text.
*/
private int textHeight = 17;
/**
* Vertical space between the text.
*/
private int spaceBetweenText = 5;
/**
* String array of config data.
*/
private String[] cfgData;
/**
* Data labels.
*/
private final String[] dataLabels = new String[] { "Layer",
"Link to Frame", "Worst Case", "Zoom: Maintain Layer",
"Zoom: only Basins in Parent", "Include CWAs", "D2D Click Action",
"D2D Display Type", "Auto-Refresh" };
/**
* Constructor.
*
* @param parent
* Parent shell.
* @param controlLocation
* Location of the control that launched this dialog.
* @param cfgSumData
* Configuration summary dialog.
*/
public ConfigSummaryDlg(Shell parent, Point controlLocation,
ConfigSummaryData cfgSumData) {
super(parent, SWT.NO_TRIM, CAVE.DO_NOT_BLOCK);
this.controlLoc = controlLocation;
this.cfgSumData = cfgSumData;
cfgData = this.cfgSumData.getDisplayData();
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(Shell shell) {
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 0;
mainLayout.marginWidth = 0;
shell.setLayout(mainLayout);
// Initialize all of the controls and layouts
initializeComponents();
}
private void initializeComponents() {
Display display = shell.getDisplay();
/*
* Setup the font and colors.
*/
leftSideColor = new Color(display, 245, 245, 212);
rightSideColor = new Color(display, 255, 238, 190);
textFont = new Font(display, "Monospace", 10, SWT.BOLD);
// Make the calculation for the canvas.
makeCalculations();
// Create the canvas.
createCanvas();
}
private void createCanvas() {
canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
GridData gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
gd.heightHint = canvasHeight;
gd.widthHint = canvasWidth;
canvas.setSize(canvasWidth, canvasHeight);
canvas.setLayoutData(gd);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawCanvas(e.gc);
}
});
/*
* Add mouse listeners to the canvas so it will be closed when the user
* moves the mouse outside the dialog or it is clicked.
*/
canvas.addMouseTrackListener(new MouseTrackAdapter() {
@Override
public void mouseExit(MouseEvent e) {
close();
}
});
canvas.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
close();
}
});
}
/**
* Draw on the canvas.
*
* @param gc
* Graphic context.
*/
private void drawCanvas(GC gc) {
Display display = shell.getDisplay();
gc.setFont(textFont);
gc.setTextAntialias(SWT.ON);
gc.setBackground(leftSideColor);
int tmpWidth = (borderSize * 2) + (maxDataLabelLen * textWidth) + 3;
gc.fillRectangle(0, 0, tmpWidth, canvasHeight);
gc.setBackground(rightSideColor);
int tmpX = (borderSize * 2) + (maxDataLabelLen * textWidth) + colonBand;
tmpWidth = canvasWidth
- ((borderSize * 2) + colonBand + (maxDataLabelLen * textWidth));
gc.fillRectangle(tmpX, 0, tmpWidth, canvasHeight);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
/*
* Draw data labels
*/
int xCoord = (borderSize) + (maxDataLabelLen * textWidth);
int yCoord = 0;
for (int i = 0; i < dataLabels.length; i++) {
xCoord = (borderSize) + (maxDataLabelLen * textWidth)
- (dataLabels[i].length() * textWidth);
yCoord = borderSize + (textHeight * i) + (spaceBetweenText * i);
gc.drawString(dataLabels[i], xCoord, yCoord, true);
}
/*
* Draw color band
*/
xCoord = (borderSize * 2) + (maxDataLabelLen * textWidth);
yCoord = 0;
gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
gc.fillRectangle(xCoord, yCoord, colonBand, canvasHeight);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
xCoord = (borderSize * 2) + (maxDataLabelLen * textWidth) + colonBand
/ 2 - 4;
yCoord = 0;
for (int i = 0; i < cfgData.length; i++) {
yCoord = borderSize + (textHeight * i) + (spaceBetweenText * i);
gc.drawString(":", xCoord, yCoord, true);
}
/*
* Draw config data labels
*/
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
xCoord = (borderSize * 3) + colonBand + (maxDataLabelLen * textWidth);
yCoord = 0;
for (int i = 0; i < cfgData.length; i++) {
yCoord = borderSize + (textHeight * i) + (spaceBetweenText * i);
gc.drawString(cfgData[i], xCoord, yCoord, true);
}
}
/**
* Make the calculation used for draw the data on the canvas.
*/
private void makeCalculations() {
Display display = shell.getDisplay();
Image image = new Image(display, 100, 100);
GC gc = new GC(image);
gc.setFont(textFont);
textWidth = gc.getFontMetrics().getAverageCharWidth();
textHeight = gc.getFontMetrics().getHeight();
gc.dispose();
image.dispose();
// Find largest data label
for (String str : dataLabels) {
if (maxDataLabelLen < str.length()) {
maxDataLabelLen = str.length();
}
}
// Find largest config data
for (String str : cfgData) {
if (maxCfgDataLen < str.length()) {
maxCfgDataLen = str.length();
}
}
// Calculate the canvas width & height
canvasWidth = (maxDataLabelLen * textWidth) + (borderSize * 4)
+ (maxCfgDataLen * textWidth) + colonBand;
canvasHeight = (borderSize * 2) + (dataLabels.length * textHeight)
+ (spaceBetweenText * dataLabels.length - 1);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialog#preOpened()
*/
@Override
protected void preOpened() {
super.preOpened();
shell.setLocation(controlLoc.x - 100, controlLoc.y - 100);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
leftSideColor.dispose();
rightSideColor.dispose();
textFont.dispose();
}
}

View file

@ -0,0 +1,670 @@
/**
* 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.ffmp.ui.dialogs;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXB;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord.FIELDS;
import com.raytheon.uf.common.localization.ILocalizationFile;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.SaveableOutputStream;
import com.raytheon.uf.common.monitor.config.FFMPRunConfigurationManager;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager;
import com.raytheon.uf.common.monitor.xml.FFMPRunXML;
import com.raytheon.uf.common.monitor.xml.ProductRunXML;
import com.raytheon.uf.common.monitor.xml.ProductXML;
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.monitor.ffmp.FFMPMonitor;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FfmpTableConfigData.COLUMN_NAME;
import com.raytheon.uf.viz.monitor.ffmp.xml.FFMPConfigBasinXML;
import com.raytheon.uf.viz.monitor.ffmp.xml.FFMPTableColumnXML;
/**
* FFMP GUI Config Object.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 01, 2012 14168 mpduff Add convenience methods for
* getting ColorCell and ReverseFilter
* Apr 12, 2013 1902 mpduff Speed up cell coloring.
* Apr 15, 2013 1904 mpduff Don't allow this class to be nulled out
* Apr 26, 2013 1954 bsteffen Minor code cleanup throughout FFMP.
* Jan 11, 2016 5242 kbisanz Replaced calls to deprecated LocalizationFile methods
* and replace printStackTrace with
* statusHandler.error()
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class FFMPConfig {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(FFMPConfig.class);
private static FFMPConfig classInstance = new FFMPConfig();
public static enum TableCellColor {
Upper, Mid, Lower, BelowLower, Default, ForcedFFG, VGB
};
public static enum ThreshColNames {
RATE(1), QPE(2), QPF(3), GUID(4), RATIO(5), DIFF(6);
private int colIndex;
ThreshColNames(int idx) {
colIndex = idx;
}
public int getColIndex() {
return colIndex;
}
}
private FFMPConfigBasinXML ffmpCfgBasin;
private final Color upperColor = new Color(Display.getDefault(), 255, 152,
116);
private final Color midColor = new Color(Display.getDefault(), 251, 255,
121);
private final Color lowerColor = new Color(Display.getDefault(), 70, 255,
113);
private final Color belowLowerColor = new Color(Display.getDefault(), 215,
215, 215);
private final Color defaultColor = new Color(Display.getDefault(), 167,
167, 167);
private final Color forcedFFGColor = new Color(Display.getDefault(), 255,
165, 0);
private final Color vgbColor = new Color(Display.getDefault(), 196, 137,
250);
private static final String DEFAULT_CONFIG_XML = "ffmp"
+ IPathManager.SEPARATOR + "guiConfig" + IPathManager.SEPARATOR
+ "DefaultFFMPconfig_basin.xml";
/**
* Used for looking up data - NOT for editing.
*/
private Map<ThreshColNames, ThresholdManager> threshMgrMap;
private Map<String, ThreshColNames> thresholdLookup;
private AttributesDlgData attrData = null;
private boolean reReadAttrData = false;
private FFMPConfig() {
init();
}
public static FFMPConfig getInstance() {
return classInstance;
}
private void init() {
threshMgrMap = new EnumMap<ThreshColNames, ThresholdManager>(
ThreshColNames.class);
thresholdLookup = new HashMap<String, ThreshColNames>();
for (ThreshColNames threshColName : ThreshColNames.values()) {
thresholdLookup.put(threshColName.name(), threshColName);
}
readDefaultFFMPConfigBasin();
}
public boolean isThreshold(String colName) {
return thresholdLookup.containsKey(colName);
}
public ThreshColNames getThreshold(String colName) {
return thresholdLookup.get(colName);
}
public Color getCellColor(TableCellColor tblCellColor) {
switch (tblCellColor) {
case Upper:
return upperColor;
case Mid:
return midColor;
case Lower:
return lowerColor;
case BelowLower:
return belowLowerColor;
case Default:
return defaultColor;
case ForcedFFG:
return forcedFFGColor;
case VGB:
return vgbColor;
}
return defaultColor;
}
public FFMPConfigBasinXML getFFMPConfigData() {
return ffmpCfgBasin;
}
public void loadNewConfig(LocalizationFile newConfigFile) {
readNewFFMPConfigBasin(newConfigFile);
}
public void loadDefaultConfig() {
readDefaultFFMPConfigBasin();
}
private void readNewFFMPConfigBasin(ILocalizationFile xmlFileName) {
ffmpCfgBasin = null;
try (InputStream strm = xmlFileName.openInputStream()) {
ffmpCfgBasin = JAXB.unmarshal(strm, FFMPConfigBasinXML.class);
createThresholdManager();
} catch (Exception e) {
statusHandler.error("Error reading FFMP Basin config "
+ xmlFileName.getPath(), e);
}
}
private void readDefaultFFMPConfigBasin() {
ffmpCfgBasin = null;
try {
IPathManager pm = PathManagerFactory.getPathManager();
File file = pm.getStaticFile(DEFAULT_CONFIG_XML);
if (file == null) {
// Should never get here since there is a baseline version of
// the file.
statusHandler.handle(Priority.ERROR,
"Default FFMP Configuration File Not Found.");
return;
}
ffmpCfgBasin = JAXB.unmarshal(file, FFMPConfigBasinXML.class);
createThresholdManager();
} catch (Exception e) {
statusHandler.error("Error reading default FFMP Basin config "
+ DEFAULT_CONFIG_XML, e);
}
}
public void saveFFMPBasinConfig(ILocalizationFile xmlFileName) {
try (SaveableOutputStream strm = xmlFileName.openOutputStream()) {
JAXB.marshal(ffmpCfgBasin, strm);
strm.save();
createThresholdManager();
} catch (Exception e) {
statusHandler.error(
"Error saving FFMP Basin config " + xmlFileName.getPath(),
e);
}
}
public FFMPTableColumnXML getTableColumnData(ThreshColNames colName) {
ArrayList<FFMPTableColumnXML> ffmpTableCols = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tableColData : ffmpTableCols) {
if (tableColData.getColumnName().compareTo(colName.name()) == 0) {
return tableColData;
}
}
return null;
}
/**
* Get the guidance column data. Must have a separate method for this column
* since it does not have thresholds.
*
* @return the guidance FFMPTableColumnXML object
*/
public FFMPTableColumnXML getGuidColumnData() {
ArrayList<FFMPTableColumnXML> ffmpTableCols = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tableColData : ffmpTableCols) {
if (tableColData.getColumnName().compareTo("") == 0) {
return tableColData;
}
}
return null;
}
public void updateThresholdValues(ThreshColNames colName, Double upperVal,
Double midVal, Double lowerVal, Double filterVal) {
FFMPTableColumnXML tcXML = getTableColumnData(colName);
tcXML.setUpper(upperVal);
tcXML.setMid(midVal);
tcXML.setLow(lowerVal);
tcXML.setFilter(filterVal);
createThresholdManager();
}
public String getBasinTrendPlotColorName(String itemName) {
ArrayList<FFMPTableColumnXML> tcXmlArray = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML data : tcXmlArray) {
if (itemName.compareTo(data.getColumnName().trim()) == 0) {
return data.getBasinTrendPlotColor();
}
}
return "grey";
}
/**
* Get the threshold color.
*
* @param colName
* The column name
* @param val
* The value
* @return The color of the threshold, or default color if configured to not
* color based on threshold
*/
public Color getThresholdColor(String colName, double val) {
ThreshColNames colNames = thresholdLookup.get(colName);
if (colNames != null) {
FFMPTableColumnXML tableColData = ffmpCfgBasin
.getTableColumnData(colName);
if (tableColData.getColorCell()) {
TableCellColor cellColor = threshMgrMap.get(colNames)
.getThresholdColor(val);
return getCellColor(cellColor);
}
}
return defaultColor;
}
public Color getBasinThresholdColor(String colName, double val) {
if (thresholdLookup.containsKey(colName) == true) {
return getCellColor(threshMgrMap.get(thresholdLookup.get(colName))
.getBasinThresholdColor(val));
}
return defaultColor;
}
private void createThresholdManager() {
threshMgrMap.clear();
List<FFMPTableColumnXML> tableColData = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tcXML : tableColData) {
ThreshColNames colNames = thresholdLookup
.get(tcXML.getColumnName());
if (colNames != null) {
ThresholdManager threshMgr = new ThresholdManager(tcXML);
threshMgrMap.put(colNames, threshMgr);
}
}
}
public ThresholdManager getThresholdManager(String threshName) {
if (thresholdLookup.containsKey(threshName) == true) {
return threshMgrMap.get(thresholdLookup.get(threshName));
}
return null;
}
public void createAttributesDlgData(String siteKey) {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
FfmpTableConfig tableConfig = FfmpTableConfig.getInstance();
FfmpTableConfigData tableConfigData = tableConfig
.getTableConfigData(siteKey);
String[] columns = tableConfigData.getTableColumnKeys();
attrData = new AttributesDlgData();
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
String displayName = null;
for (FFMPTableColumnXML tcXML : columnData) {
if (column.contains("_")) {
String[] parts = column.split("_");
displayName = parts[0];
column = parts[1];
}
if (column.equalsIgnoreCase(tcXML.getColumnName())) {
boolean includedInTable = false;
if (column.equalsIgnoreCase(COLUMN_NAME.GUID
.getColumnName())
|| column.equalsIgnoreCase(COLUMN_NAME.RATIO
.getColumnName())
|| column.equalsIgnoreCase(COLUMN_NAME.DIFF
.getColumnName())) {
if (ffmpCfgBasin.getIncludedGuids().contains(
displayName)) {
includedInTable = true;
attrData.setGuidColumnIncluded(displayName,
includedInTable);
}
}
attrData.setColumnVisible(column,
tcXML.getDisplayedInTable());
break;
}
}
}
}
public AttributesDlgData getVisibleColumns(String siteKey,
boolean reReadAttrData) {
this.reReadAttrData = reReadAttrData;
return getVisibleColumns(siteKey);
}
public AttributesDlgData getVisibleColumns(String siteKey) {
if ((attrData == null) || reReadAttrData) {
createAttributesDlgData(siteKey);
}
return attrData;
}
public void setVisibleColumns(AttributesDlgData attrData) {
this.attrData = attrData;
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tcXML : columnData) {
if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.RATE.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.RATE.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.NAME.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.NAME.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.QPE.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.QPE.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.QPF.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.QPF.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.GUID.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.GUID.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.RATIO.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.RATIO.getColumnName()));
} else if (tcXML.getColumnName().equalsIgnoreCase(
COLUMN_NAME.DIFF.getColumnName())) {
tcXML.setDisplayedInTable(attrData
.isColumnVisible(COLUMN_NAME.DIFF.getColumnName()));
}
}
HashMap<String, Boolean> guidanceMap = attrData.getGuidanceList();
String list = "";
boolean first = true;
for (String key : guidanceMap.keySet()) {
if (first == false) {
list.concat(",");
}
list = list.concat(key);
first = false;
}
ffmpCfgBasin.setIncludedGuids(list);
ffmpCfgBasin.setIncludedQPF(attrData.getQpfType());
}
public boolean isSplit() {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tcXML : columnData) {
if (tcXML.getColumnName().compareTo(FIELDS.QPF.name()) == 0) {
return tcXML.getDisplayedInTable();
}
}
return false;
}
public double getTimeFrame() {
return ffmpCfgBasin.getTimeFrame();
}
public String getUnderlay() {
return ffmpCfgBasin.getUnderlay();
}
public String[] getActiveBasinTrendPlots() {
String basinPlots = ffmpCfgBasin.getBasinTrendPlots();
String[] plotsArray = basinPlots.split(",");
return plotsArray;
}
public boolean columnIsVisible(String colName) {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
for (FFMPTableColumnXML tcXML : columnData) {
if (tcXML.getColumnName().compareTo(colName) == 0) {
return tcXML.getDisplayedInTable();
}
}
return false;
}
/**
* Get the index of the column to be sorted when the dialog initially
* starts. If the column is not visible then default the sort column to be
* the name column.
*
* @param siteKey
* The siteKey being used
* @return Column index.
*/
public int getStartSortIndex(String siteKey) {
FFMPMonitor monitor = FFMPMonitor.getInstance();
FFMPRunConfigurationManager configManager = FFMPRunConfigurationManager
.getInstance();
FfmpTableConfig tableCfg = FfmpTableConfig.getInstance();
FFMPSourceConfigurationManager sourceConfigManager = FFMPSourceConfigurationManager
.getInstance();
FFMPRunXML runner = configManager.getRunner(monitor.getWfo());
ProductRunXML prodRunXml = runner.getProduct(siteKey);
String name = prodRunXml.getProductName();
ProductXML productXml = sourceConfigManager.getProduct(name);
ArrayList<String> guidTypes = productXml.getAvailableGuidanceTypes();
String guidRankSource = null;
if (guidTypes.size() > 1) {
String colSorted = ffmpCfgBasin.getColumnSorted();
if (colSorted.contains(",")) {
String[] parts = colSorted.split(",");
guidRankSource = parts[1];
}
}
FfmpTableConfigData tableCfgData = tableCfg.getTableConfigData(siteKey);
String[] tableColumns = tableCfgData.getTableColumnKeys();
String sortedColName = ffmpCfgBasin.getColumnSorted();
if (sortedColName.contains(",")) {
String[] parts = sortedColName.split(",");
sortedColName = parts[0];
}
String guidType = null;
for (int i = 0; i < tableColumns.length; i++) {
String column = tableColumns[i];
if (isColumnGuid(column)) {
String[] parts = column.split("_");
column = parts[1];
guidType = parts[0];
}
if (column.equalsIgnoreCase(sortedColName)) {
if ((guidType != null) && (guidRankSource != null)) {
if (guidType.equalsIgnoreCase(guidRankSource)) {
if (columnIsVisible(column)) {
return i;
}
}
} else {
if (columnIsVisible(column)) {
return i;
}
}
}
}
return 0;
}
private boolean isColumnGuid(String columnName) {
if (columnName.contains("_")) {
return true;
}
return false;
}
/**
* Get the filter value for this column.
*
* @param threshColName
* @return The filter value
*/
public double getFilterValue(ThreshColNames threshColName) {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
FFMPTableColumnXML data = columnData.get(threshColName.getColIndex());
return data.getFilter();
}
/**
* Get the ColorCell value for this column.
*
* @param threshColName
* @return The ColorCell value
*/
public boolean isColorCell(ThreshColNames threshColName) {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
FFMPTableColumnXML data = columnData.get(threshColName.getColIndex());
return data.getColorCell();
}
/**
* Get the reverse filter value for this column.
*
* @param threshColName
* @return The Reverse Filter value
*/
public boolean isReverseFilter(ThreshColNames threshColName) {
ArrayList<FFMPTableColumnXML> columnData = ffmpCfgBasin
.getTableColumnData();
FFMPTableColumnXML data = columnData.get(threshColName.getColIndex());
return data.getReverseFilter();
}
/**
* @return the attrData
*/
public AttributesDlgData getAttrData() {
return attrData;
}
/**
* @param attrData
* the attrData to set
*/
public void setAttrData(AttributesDlgData attrData) {
this.attrData = attrData;
}
/**
* @return the reReadAttrData
*/
public boolean isReReadAttrData() {
return reReadAttrData;
}
/**
* @param reReadAttrData
* the reReadAttrData to set
*/
public void setReReadAttrData(boolean reReadAttrData) {
this.reReadAttrData = reReadAttrData;
}
public String getIncludedGuids() {
return ffmpCfgBasin.getIncludedGuids();
}
}

View file

@ -0,0 +1,213 @@
/**
* 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.ffmp.ui.dialogs;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
/**
* Display FFMP Basin Table's splash page dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Initial creation
* Dec 7, 2012 1353 rferrel Covert to CaveSWTDialog and make non-blocking.
* Aug 9, 2013 2033 mschenke Switched File.separator to IPathManager.SEPARATOR
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class FFMPSplash extends CaveSWTDialog {
/**
* The display control.
*/
private Display display;
/**
* Canvas to display the information.
*/
private Canvas canvas;
private Font textFont;
/**
* Canvas width.
*/
private int canvasWidth = 300;
/**
* Canvas height.
*/
private int canvasHeight = 200;
private Image loadImage = null;
public FFMPSplash(Shell parent) {
super(parent, SWT.NO_TRIM | SWT.ON_TOP, CAVE.DO_NOT_BLOCK);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(Shell shell) {
display = shell.getDisplay();
// Create the main layout for the shell.
GridLayout mainLayout = new GridLayout(1, false);
mainLayout.marginHeight = 0;
mainLayout.marginWidth = 0;
shell.setLayout(mainLayout);
// Initialize all of the controls and layouts
initializeComponents();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialog#preOpened()
*/
@Override
protected void preOpened() {
super.preOpened();
centerOnScreen();
}
private void initializeComponents() {
textFont = new Font(display, "Monospace", 50, SWT.BOLD);
String imageName = loadImage();
if (imageName != null) {
loadImage = new Image(display, imageName);
}
// Make the calculation for the canvas.
// makeCalculations();
// Create the canvas.
createCanvas();
}
private void createCanvas() {
canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED);
GridData gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
gd.heightHint = canvasHeight;
gd.widthHint = canvasWidth;
canvas.setSize(canvasWidth, canvasHeight);
canvas.setLayoutData(gd);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawCanvas(e.gc);
}
});
}
private void drawCanvas(GC gc) {
gc.setFont(textFont);
gc.setTextAntialias(SWT.ON);
if (loadImage != null) {
gc.drawImage(loadImage, 0, 0);
} else {
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillRectangle(0, 0, canvasWidth, canvasHeight);
}
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.setLineWidth(3);
gc.drawRectangle(1, 1, canvasWidth - 3, canvasHeight - 3);
}
/**
* Center on the screen that CAVE is on.
*/
private void centerOnScreen() {
Shell tmpShell = getParent().getShell();
Monitor[] monitors = getParent().getDisplay().getMonitors();
int displayMonitor = 0;
for (int i = 0; i < monitors.length; i++) {
displayMonitor = i;
int rightEdge = monitors[i].getBounds().x
+ monitors[i].getBounds().width;
if (tmpShell.getBounds().x < rightEdge) {
break;
}
}
Monitor monitor = monitors[displayMonitor];
Rectangle monRect = monitor.getBounds();
int xCoord = ((monRect.x + (monRect.width / 2)) - (canvasWidth / 2));
int yCoord = (monRect.height / 2) - (canvasHeight / 2);
shell.setLocation(xCoord, yCoord);
}
private String loadImage() {
IPathManager pm = PathManagerFactory.getPathManager();
String path = pm.getStaticFile(
"ffmp" + IPathManager.SEPARATOR + "images"
+ IPathManager.SEPARATOR + "ffmpLoading.png")
.getAbsolutePath();
return path;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
textFont.dispose();
loadImage.dispose();
shell.dispose();
}
}

View file

@ -0,0 +1,911 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.monitor.data.CommonConfig.AppName;
import com.raytheon.uf.viz.monitor.data.ColumnAttribData;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.ThreshColNames;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FfmpTableConfigData.COLUMN_NAME;
import com.raytheon.uf.viz.monitor.ffmp.xml.FFMPConfigBasinXML;
import com.raytheon.uf.viz.monitor.ffmp.xml.FFMPTableColumnXML;
/**
* Abstract table composite that is the main foundation for a table displaying
* TableData.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------------------------
* Apr 07, 2009 lvenable Initial creation
* Mar 15,2012 4406 gzhang Fixing QPF Column Title Missing
* Mar 20,2012 4250 gzhang Eliminating column Missing values
* Aug 01, 2012 14168 mpduff Only allow filtering if ColorCell is true
* Jun 04, 2013 1984 lvenable Save images instead of disposing them when
* setting the table column images. This is to
* fix the Windows issue on the images being
* blank and throwing errors. Also cleaned up
* some code.
* Jun 11, 2013 2075 njensen Optimized createTableItems()
* Nov 07, 2013 16703 gzhang Check in code for Lee for FFMP Table line
* May 10, 2016 5516 randerso Lots of GUI clean up
* Sep 14, 2017 20297 lshi FFMP AlertViz errors when changing layers and
* opening basin trend graphs
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public abstract class FFMPTable extends Composite {
/** Default column width */
protected static final int DEFAULT_COLUMN_WIDTH = 95;// DR14406: old value:
// 75 too small
private static final String NAME = "Name";
protected String currentPfaf = null;
/**
* Main table control.
*/
protected Table table;
/**
* Parent composite.
*/
protected Composite parent;
/**
* Data to be displayed in the table.
*/
protected FFMPTableData tableData;
/**
* Application name.
*/
protected CommonConfig.AppName appName = AppName.FFMP;
/**
* Table index variable to keep track of the table index.
*/
protected int tableIndex = -1;
/**
* Color of the lines defining the borders of the table cell.
*/
private Color lineColor;
/**
* Color of the table column when sorted.
*/
private Color sortColor;
/**
* Default width for each column.
*/
private int defaultColWidth;
protected boolean columnMinimumSize = false;
private TableColumn sortedTableColumn;
private FFMPConfig ffmpConfig;
private String siteKey;
protected int imageWidth = 0;
protected int imageHeight = 0;
private ArrayList<Integer> indexArray = new ArrayList<Integer>();
private Point extent = new Point(0, 0);
/**
* Array of images displayed in the table columns.
*/
protected List<Image> columnImgs = new ArrayList<Image>();
/**
* Constructor.
*
* @param parent
* Parent composite.
* @param data
* Data to be displayed in the table.
*/
public FFMPTable(Composite parent, FFMPTableData data, String siteKey) {
super(parent, 0);
this.siteKey = siteKey;
this.parent = parent;
this.tableData = data;
ffmpConfig = FFMPConfig.getInstance();
}
/**
* Initialize method.
*/
protected void init() {
sortColor = new Color(parent.getDisplay(), 133, 104, 190);
lineColor = new Color(parent.getDisplay(), 80, 80, 80);
defaultColWidth = getDefaultColWidth();
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
GridLayout gl = new GridLayout(1, true);// false);
gl.verticalSpacing = 2;
gl.marginHeight = 2;
gl.marginWidth = 2;
this.setLayout(gl);
this.setLayoutData(gd);
makeImageCalculations();
addTopTableControls(this);
createTable();
createTableColumns();
ffmpConfig.createAttributesDlgData(siteKey);
sortTableUsingConfig();
this.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent arg0) {
lineColor.dispose();
sortColor.dispose();
disposeColumnImages();
}
});
}
/**
* Create the table.
*/
private void createTable() {
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.heightHint = 350;
table = new Table(this, SWT.BORDER | SWT.VIRTUAL | SWT.V_SCROLL
| SWT.FULL_SELECTION);
table.setLayoutData(gd);
table.setHeaderVisible(true);
/*
* Add a paint listener to the table that will draw lines around each
* cell and also draw a blue line to show the selected row.
*/
table.addListener(SWT.PaintItem, new Listener() {
@Override
public void handleEvent(Event event) {
table.deselectAll();
event.gc.setForeground(lineColor);
event.gc.setLineWidth(1);
int currentCol = event.index;
TableItem ti = (TableItem) event.item;
Rectangle rect = ((TableItem) event.item).getBounds(currentCol);
event.gc.drawRectangle(rect.x - 1, rect.y - 1, rect.width,
rect.height);
// Draw an extra line on the edges of the table cell to hide the
// white lines
// dividing the columns;
event.gc.setLineWidth(1);
event.gc.drawLine(rect.x + rect.width - 2, rect.y - 1, rect.x
+ rect.width - 2, rect.y - 1 + rect.height);
// Draw a top line
event.gc.drawLine(rect.x, rect.y, rect.x + rect.width, rect.y);
// Draw a bottom line if this is the last row of the table
int index = table.indexOf(ti);
if (index == table.getItemCount() - 1) {
event.gc.drawLine(rect.x, rect.y + rect.height - 2, rect.x
+ rect.width, rect.y + rect.height - 2);
}
if ((tableIndex >= 0) && (tableIndex < table.getItemCount())) {
event.gc.setForeground(parent.getDisplay().getSystemColor(
SWT.COLOR_BLUE));
event.gc.setLineWidth(3);
TableItem item = table.getItem(tableIndex);
rect = item.getBounds(currentCol);
event.gc.drawRectangle(rect.x - 1, rect.y - 1, rect.width,
rect.height);
}
}
});
table.addListener(SWT.SetData, new Listener() {
@Override
public void handleEvent(Event event) {
TableItem item = (TableItem) event.item;
int tmpIndex = table.indexOf(item);
int index = tableIndexToDataIndex(tmpIndex);
FFMPTableCellData[] cellData = tableData.getTableRows()
.get(index).getTableCellDataArray();
for (int j = 0; j < cellData.length; j++) {
if (cellData[j] != null) {
item.setText(j, cellData[j].displayString());
item.setBackground(j, cellData[j].getBackgroungColor());
}
}
table.getColumn(0).setWidth(extent.x + 10);
table.redraw();
}
});
/*
* Add a mouse listener to the table.
*/
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent event) {
tableMouseDownAction(event);
}
});
table.addMouseMoveListener(new MouseMoveListener() {
@Override
public void mouseMove(MouseEvent e) {
tableMouseMoveAction(e);
}
});
}
/**
* Create the table columns.
*/
private void createTableColumns() {
TableColumn tc;
String[] columns = getColumnKeys();
for (int i = 0; i < columns.length; i++) {
/*
* Left justify the first column and center the remaining columns.
*/
if (i == 0) {
tc = new TableColumn(table, SWT.LEFT);
} else {
tc = new TableColumn(table, SWT.CENTER);
}
tc.setData(columns[i]);
tc.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
TableColumn[] cols = table.getColumns();
for (int j = 0; j < cols.length; j++) {
cols[j].setImage(null);
cols[j].setWidth(defaultColWidth);
}
// reset the tableIndex
tableIndex = -1;
/*
* Check of the column is sortable.
*/
TableColumn tc = (TableColumn) event.getSource();
sortedTableColumn = tc;
if (tc.getWidth() < defaultColWidth) {
tc.setWidth(defaultColWidth);
}
// Sort the table data.
sortTableData(tc);
}
});
if (columnMinimumSize == true) {
tc.addControlListener(new ControlAdapter() {
@Override
public void controlResized(ControlEvent e) {
/*
* Prevent the user from resizing the column to be
* smaller than the default column size.
*/
TableColumn tc = (TableColumn) e.getSource();
if ((tc.getWidth() < defaultColWidth)
&& (tc.getWidth() != 0)) {
tc.setWidth(defaultColWidth);
}
}
});
}
}
int sortedColIdx = ffmpConfig.getStartSortIndex(this.siteKey);
TableColumn stc = table.getColumn(sortedColIdx);
sortedTableColumn = stc;
}
/**
* Create the table items.
*/
private void createTableItems() {
int sortColIndex = table.indexOf(sortedTableColumn);
boolean isAFilterCol = false;
ThreshColNames sortedThreshCol = null;
boolean reverseFilter = false;
double filterNum = Double.NaN;
String sortedColumnName = getColumnKeys()[sortColIndex];
FFMPConfigBasinXML ffmpCfgBasin = FFMPConfig.getInstance()
.getFFMPConfigData();
ArrayList<FFMPTableColumnXML> ffmpTableCols = ffmpCfgBasin
.getTableColumnData();
boolean sortedColumnIsName = sortedColumnName.equalsIgnoreCase(NAME);
if (!sortedColumnIsName) {
for (ThreshColNames threshColName : ThreshColNames.values()) {
if (sortedColumnName.contains(threshColName.name())) {
sortedThreshCol = threshColName;
break;
}
}
// Check if the sorted column is a column that will contain a
// filter. Check the gui config to see if colorCell is true. If
// false then do not apply filter
for (FFMPTableColumnXML xml : ffmpTableCols) {
if (xml.getColumnName().contains(sortedThreshCol.name())) {
if (ffmpConfig.isColorCell(sortedThreshCol)) {
// Only filter if colorCell is true
isAFilterCol = true;
filterNum = ffmpConfig.getFilterValue(sortedThreshCol);
reverseFilter = ffmpConfig
.isReverseFilter(sortedThreshCol);
}
break;
}
}
}
table.removeAll();
if (tableData == null) {
return;
}
// Loop of the rows of data in the table data object.
indexArray.clear();
FFMPTableRowData rowData;
ArrayList<FFMPTableRowData> rowArray = tableData.getTableRows();
indexArray.ensureCapacity(rowArray.size());
GC gc = new GC(table);
for (int t = 0; t < rowArray.size(); t++) {
rowData = rowArray.get(t);
FFMPTableCellData[] cellData = rowData.getTableCellDataArray();
extent.x = Math.max(gc.stringExtent(cellData[0].displayString()).x,
extent.x);
/*
* Check if the data value is Not A Number.
*/
if (!sortedColumnIsName) {
float dataVal = cellData[sortColIndex].getValueAsFloat();
// DR 14250 fix: any value not a number will be omitted
if (Float.isNaN(dataVal)) {
continue;
}
if (isAFilterCol) {
if (reverseFilter) {
if (dataVal > filterNum) {
continue;
}
} else {
if (dataVal < filterNum) {
continue;
}
}
}
}
indexArray.add(t);
// Check to see if this is the selected row
if (rowData.getPfaf().equals(currentPfaf)) {
tableIndex = indexArray.indexOf(t);
}
}
/*
* VIRTUAL TABLE
*
* If a virtual table is going to be used then we may have to create a
* temp Table Data object that will only contain the data that will be
* displayed in the table (filtered data). It may work better for the
* display if the the virtual table is loading from a second data set
* for the display. This will allow a 1 to 1 with the index of the table
* item and the index of the data. Not sure what the overhead will be
* but it shouldn't be too bad. The table data is fairly small in size
* and shouldn't be a memory issue.
*
* Below, instead of creating table items the data should be moved to
* the new list and then the table setItemCount should be called with
* the about of data in the new list.
*
* NOTE: When the data is ordered, filtering takes place on the column
* of data. The filtered data is not displayed so setItemCount will only
* display x number of rows. If the filtered data is at the bottom then
* there shouldn't be an issue.
*
* One possible way to solve this is to have an array that holds only
* the indexes into the table data. For example: the array would be an
* array of indexes and the size would be the number of table items that
* should be displayed in the table.
*
* When you select a table item cross-reference the table index with the
* index array to get the right table data element.
*/
// Set this for the virtual table
table.setItemCount(indexArray.size());
showHideTableColumns();
if (indexArray.size() > 0) {
table.getColumn(0).setWidth(extent.x + 10);
table.getColumn(0).pack();
}
gc.dispose();
}
/**
* Set the data to be displayed in the table.
*
* @param td
*/
public void setTableData(FFMPTableData td) {
extent.x = 0;
clearTableSelection();
tableData = td;
sortTableData(sortedTableColumn);
calculateTableSize();
}
/**
* Calculate the table size by adding the widths of each column + a little
* extra.
*/
public void calculateTableSize() {
int hsize = 0;
TableColumn[] tCols = table.getColumns();
for (int i = 0; i < tCols.length; i++) {
if (i == 0) {
hsize += this.extent.x + 10;
} else {
hsize += tCols[i].getWidth();
}
}
hsize += 20;
((GridData) table.getLayoutData()).widthHint = hsize;
}
/**
* Clear the table selection.
*/
public void clearTableSelection() {
tableIndex = -1;
table.deselectAll();
}
/**
* Sort the table using the configuration data.
*/
public void sortTableUsingConfig() {
int sortedColIdx = ffmpConfig.getStartSortIndex(this.siteKey);
TableColumn tc = table.getColumn(sortedColIdx);
sortedTableColumn = tc;
TableColumn[] cols = table.getColumns();
for (int j = 0; j < cols.length; j++) {
cols[j].setImage(null);
cols[j].setWidth(defaultColWidth);
}
/*
* Set the sort image, pack the column and sort the data.
*/
setColumnImages();
tc.pack();
if (tc.getWidth() < defaultColWidth) {
tc.setWidth(defaultColWidth);
}
sortTableData(tc);
}
/**
* Get the index list
*
* @return list of indices
*/
protected List<Integer> getIndexList() {
return indexArray;
}
/**
* Get the data index from the table index.
*
* @param tableIndex
* The table index
* @return the data index
*/
protected int tableIndexToDataIndex(int tableIndex) {
if (tableIndex >= indexArray.size() || tableIndex < 0) {
return 0;
}
return indexArray.get(tableIndex);
}
/**
* Sort the data in the table by the specified table column.
*
* @param tc
* Table column to sort.
*/
private void sortTableData(TableColumn tc) {
if (tableData == null) {
return;
}
String sortCol = (String) tc.getData();
int sortDir = getColumnAttributeData(sortCol).getSortDir();
int columnIndex = getColumnIndex(sortCol);
tableData.sortData(columnIndex, sortDir);
FfmpTableConfigData ffmpTableCfgData = FfmpTableConfig.getInstance()
.getTableConfigData(this.siteKey);
String[] colNames = ffmpTableCfgData.getTableColumnKeys();
String sortedColName = colNames[columnIndex];
String guidRankSource = null;
if (sortedColName.contains("_")) {
String[] parts = sortedColName.split("_");
sortedColName = parts[1];
guidRankSource = parts[0];
}
ffmpConfig.getFFMPConfigData().setColumnSorted(
sortedColName + "," + guidRankSource);
setColumnImages();
createTableItems();
showHideTableColumns();
}
/**
* Determine the height and width of the image displayed in the table
* column. Since all of the icons have to be the same size, all of the table
* column names have to be looked at to determine the number of lines and
* the maximum number of characters for the largest table column title.
*/
private void makeImageCalculations() {
Image image = new Image(this.getDisplay(), 100, 100);
GC gc = new GC(image);
int maxTextWidth = defaultColWidth;
int textHeight = gc.getFontMetrics().getHeight();
FfmpTableConfigData ffmpTableCfgData = FfmpTableConfig.getInstance()
.getTableConfigData(siteKey);
String[] colNameKeys = ffmpTableCfgData.getTableColumnKeys();
for (int i = 0; i < colNameKeys.length; i++) {
String colName = ffmpTableCfgData
.getTableColumnAttr(colNameKeys[i]).getSplitColumnName();
String[] nameArray = colName.split("\n");
for (String tmpStr : nameArray) {
maxTextWidth = Math.max(maxTextWidth, gc.textExtent(tmpStr).x);
}
}
int margin = gc.textExtent(" ").x;
imageWidth = maxTextWidth + margin;
imageHeight = textHeight * 2;
gc.dispose();
image.dispose();
}
/**
* For each table column create an image and then set the table column to
* that image.
*/
private void setColumnImages() {
FfmpTableConfigData ffmpTableCfgData = FfmpTableConfig.getInstance()
.getTableConfigData(siteKey);
String[] colNameKeys = ffmpTableCfgData.getTableColumnKeys();
TableColumn tc;
disposeColumnImages();
// Loop over the column name keys
for (int i = 0; i < colNameKeys.length; i++) {
String colName = ffmpTableCfgData
.getTableColumnAttr(colNameKeys[i]).getSplitColumnName();
tc = table.getColumn(i);
Image img = new Image(this.getDisplay(), imageWidth, imageHeight);
GC gc = new GC(img);
int textHeight = gc.getFontMetrics().getHeight();
// Set the initial foreground and background colors.
gc.setForeground(this.getDisplay().getSystemColor(SWT.COLOR_WHITE));
gc.setBackground(this.getDisplay().getSystemColor(SWT.COLOR_BLACK));
// Set the background color to the sort color if that column is
// sorted.
if (tc == sortedTableColumn) {
gc.setBackground(sortColor);
}
gc.fillRectangle(0, 0, imageWidth, imageHeight);
/*
* If there is a \n in the string then find the largest of the 2
* strings and use that to determine the x coord. For the y coord
* set y based on
*/
int xCoord = 0;
int yCoord = 0;
if (colName.indexOf("\n") == -1) {
yCoord = imageHeight / 2 - textHeight / 2 - 1;
}
String[] splitName = colName.split("\n");
for (String s : splitName) {
int textWidth = gc.textExtent(s).x;
if (tc.getAlignment() == SWT.CENTER) {
xCoord = (imageWidth - textWidth) / 2;
} else {
xCoord = gc.textExtent(" ").x;
}
gc.drawText(s, xCoord, yCoord, true);
yCoord += textHeight;
}
gc.dispose();
tc.setImage(img);
columnImgs.add(img);
}
}
/**
* Dispose of all the table column images and clear the array of images.
*/
protected void disposeColumnImages() {
for (Image img : columnImgs) {
if (img != null) {
img.dispose();
}
}
columnImgs.clear();
}
/**
* Get the list of visible table columns.
*
* @return Boolean array indicating which columns are visible or not.
*/
public AttributesDlgData getVisibleColumns() {
return ffmpConfig.getVisibleColumns(siteKey);
}
/**
* Show/Hide table columns.
*
* @param visCols
* Boolean array indicating which table columns are visible.
*/
public void showHideTableColumns(AttributesDlgData attrData) {
TableColumn[] tCols = table.getColumns();
String[] columnKeys = getColumnKeys();
String source = null;
for (int i = 0; i < columnKeys.length; i++) {
String col = columnKeys[i];
if (col.contains(COLUMN_NAME.GUID.getColumnName())
|| col.contains(COLUMN_NAME.RATIO.getColumnName())
|| col.contains(COLUMN_NAME.DIFF.getColumnName())) {
if (col.contains("_")) {
String[] parts = col.split("_");
source = parts[0];
col = parts[1];
}
if (attrData.isGuidColumnIncluded(source)) {
if (attrData.isColumnVisible(col)) {
tCols[i].setWidth(defaultColWidth);
} else {
tCols[i].setWidth(0);
}
} else {
tCols[i].setWidth(0);
}
} else {
if (attrData.isColumnVisible(col)) {
if (i == 0) {
tCols[i].setWidth(table.getColumn(i).getWidth());
} else {
tCols[i].setWidth(defaultColWidth);
}
setQPFColName(tCols[i], col);
} else {
tCols[i].setWidth(0);
}
}
}
}
/**
* Show and hide the columns based on the configuration data.
*/
public void showHideTableColumns() {
AttributesDlgData attrData = ffmpConfig.getVisibleColumns(siteKey);
showHideTableColumns(attrData);
}
/**
* Handle the mouse button down on the table.
*
* @param event
* Mouse event.
*/
protected abstract void tableMouseDownAction(MouseEvent event);
/**
* Handle the mouse hover on the table.
*
* @param event
* Mouse event.
*/
protected abstract void tableMouseMoveAction(MouseEvent event);
/**
* Add controls above the table (if needed).
*
* @param parentComp
* Parent composite.
*/
protected abstract void addTopTableControls(Composite parentComp);
/**
* Get the default column width.
*
* @return The column width.
*/
protected abstract int getDefaultColWidth();
/**
* Get the column keys.
*
* @return String array of column keys.
*/
protected abstract String[] getColumnKeys();
/**
* Get the column attributes for the specified column name.
*
* @param colName
* Column name.
* @return Column attribute data.
*/
protected abstract ColumnAttribData getColumnAttributeData(String colName);
/**
* Get the column index.
*
* @param sortCol
* Sort column.
* @return Column index.
*/
protected abstract int getColumnIndex(String sortCol);
/**
* DR14406 code: QPF column's name should be re-set when a user choose
* another type of QPF from the Attributes... button.
*
* See FfmpTableConfigData.setQpfType() with ColumnAttribData
*
* @param tCols
* : TableColumn
* @param col
* : Column name
*/
private void setQPFColName(TableColumn tCols, String col) {
if (COLUMN_NAME.QPF.getColumnName().equalsIgnoreCase(col)) {
setColumnImages();
tCols.setWidth(defaultColWidth);
}
}
}

View file

@ -0,0 +1,266 @@
/**
* 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.ffmp.ui.dialogs;
import org.eclipse.swt.graphics.Color;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord.FIELDS;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.TableCellColor;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.ThreshColNames;
/**
* Table cell data class to define how the data is to be displayed in a table.
* At this time cell data only supports black text (default) but can be modified
* to handle foreground (text) color.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 06, 2009 lvenable Initial creation
* Apr 12, 2013 1902 mpduff Optimized the color assignments.
* May 07, 2013 1986 njensen Optimized sortBy
* Jun 10, 2013 2085 njensen Generate color on demand
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class FFMPTableCellData {
/**
* Cell text.
*/
private String cellText = null;
/**
* Text to be displayed when the mouse hovers over the table cell.
*/
private String hoverText = null;
/**
* Numerical value.
*/
private Float value = Float.NaN;
/**
* Flag indicating the value is of type integer.
*/
private boolean displayAsInt = false;
private Color backgroundColor;
private FIELDS columnName;
private static final FFMPConfig ffmpCfg = FFMPConfig.getInstance();
private boolean vgbFlag = false;
private boolean guidForcedFlag = false;
private String displayStr = null;
private double colorValue;
/**
* Constructor.
*
* @param columnName
* The column name
* @param value
* The column value
*/
public FFMPTableCellData(FIELDS columnName, float value) {
this(columnName, value, false);
}
/**
* Constructor.
*
* @param columnName
* Numerical value.
* @param value
* Value.
* @param forced
* Forced flag.
*/
public FFMPTableCellData(FIELDS columnName, float value, boolean forced) {
if (columnName == FIELDS.RATIO) {
displayAsInt = true;
}
this.columnName = columnName;
this.value = value;
this.guidForcedFlag = forced;
if (displayAsInt == true) {
colorValue = Math.rint(value);
} else {
if (!this.value.isNaN()) {
colorValue = ((Math.round(value * 100.0)) / 100.0);
} else {
colorValue = Float.NaN;
}
}
}
/**
* Constructor.
*
* @param columnName
* Column name.
* @param cellText
* Test to be displayed in the table cell.
* @param hoverText
* Hover text.
*/
public FFMPTableCellData(FIELDS columnName, String cellText,
String hoverText) {
if (columnName == FIELDS.VIRTUAL) {
this.columnName = FIELDS.NAME;
backgroundColor = ffmpCfg.getCellColor(TableCellColor.VGB);
vgbFlag = true;
} else {
this.columnName = columnName;
backgroundColor = ffmpCfg.getCellColor(TableCellColor.Default);
vgbFlag = false;
}
this.cellText = cellText;
this.hoverText = hoverText;
}
/**
* Get value as an float.
*
* @return Value as a float.
*/
public float getValueAsFloat() {
return value;
}
/**
* Flag indicating if this is a VGB
*
* @return True if this is a VGB, false otherwise.
*/
public boolean isVGB() {
return vgbFlag;
}
/**
* Get the cell text.
*
* @return The cell text.
*/
public String getCellText() {
return cellText;
}
/**
* Set the RGB which is the cell background color.
*/
private Color generateCellColor() {
Color retVal = null;
if ((columnName == FIELDS.GUIDANCE) && this.guidForcedFlag) {
if (this.value.isNaN()) {
retVal = ffmpCfg.getCellColor(TableCellColor.Default);
} else {
retVal = ffmpCfg.getCellColor(TableCellColor.ForcedFFG);
}
} else if (columnName == FIELDS.GUIDANCE) {
retVal = ffmpCfg.getThresholdColor(ThreshColNames.GUID.name(),
colorValue);
} else {
retVal = ffmpCfg.getThresholdColor(columnName.name(), colorValue);
}
return retVal;
}
/**
* Get the hover text (mouse hover).
*
* @return The hover text.
*/
public String getHoverText() {
return this.hoverText;
}
public float sortByNumber() {
if (!value.isNaN()) {
if (displayAsInt == true) {
return (float) Math.round(value);
}
return value.floatValue();
} else {
// NaN is not displayed in the table when sorting by
// this column, so the value to return here is not especially
// important
return Float.NEGATIVE_INFINITY;
}
}
public String displayString() {
if (this.displayStr == null) {
/*
* Format the data for the display.
*/
if (cellText != null) {
displayStr = cellText;
} else if (value.isNaN() == false) {
if (displayAsInt == true) {
displayStr = String.valueOf(Math.round(value));
} else {
displayStr = String.format("%1.2f", value);
}
} else if (value.isNaN() == true) {
displayStr = "M";
} else {
displayStr = "Unknown";
}
}
return displayStr;
}
/**
* Get the cell background RGB.
*
* @return The cell background RGB.
*/
public Color getBackgroungColor() {
if (backgroundColor == null) {
synchronized (this) {
if (backgroundColor == null) {
backgroundColor = generateCellColor();
}
}
}
return backgroundColor;
}
public void clearColor() {
synchronized (this) {
backgroundColor = null;
}
}
}

View file

@ -0,0 +1,167 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.ArrayList;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.TableItem;
import com.raytheon.uf.viz.monitor.data.ColumnAttribData;
import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FFMPConfig.ThreshColNames;
public class FFMPTableComp extends FFMPTable {
private FfmpTableConfig tableConfig;
/**
* Table selection callback.
*/
private ITableSelection tableSelectionCB;
/**
* Mouse point.
*/
private Point mousePt = new Point(0, 0);
private boolean vgb;
private String siteKey;
public FFMPTableComp(Composite parent, FFMPTableData data,
ITableSelection tableSelectionCB, String siteKey) {
super(parent, data, siteKey);
this.siteKey = siteKey;
this.tableSelectionCB = tableSelectionCB;
tableConfig = FfmpTableConfig.getInstance();
columnMinimumSize = true;
init();
}
@Override
protected void addTopTableControls(Composite parentComp) {
// No controls needed
}
@Override
protected ColumnAttribData getColumnAttributeData(String colName) {
return tableConfig.getTableConfigData(siteKey).getTableColumnAttr(
colName);
}
@Override
protected int getColumnIndex(String sortCol) {
return tableConfig.getTableConfigData(siteKey).getTableColumnIndex(
sortCol);
}
@Override
protected String[] getColumnKeys() {
return tableConfig.getTableConfigData(siteKey).getTableColumnKeys();
}
@Override
protected int getDefaultColWidth() {
return DEFAULT_COLUMN_WIDTH;
}
@Override
protected void tableMouseDownAction(MouseEvent event) {
tableIndex = table.getSelectionIndex();
mousePt.x = event.x;
mousePt.y = event.y;
TableItem item = table.getItem(mousePt);
if ((item == null) || item.isDisposed()) {
return;
}
int tmpIndex = table.indexOf(item);
int index = tableIndexToDataIndex(tmpIndex);
vgb = tableData.getTableRows().get(index).getTableCellData(0).isVGB();
Rectangle rect = item.getBounds(0);
if (rect.contains(mousePt)) {
currentPfaf = tableData.getTableRows().get(index).getPfaf();
if (event.button == 1) {
String name = item.getText(0);
tableSelectionCB.tableSelection(currentPfaf, name);
} else if (event.button == 3) {
tableSelectionCB.displayBasinTrend(currentPfaf);
}
}
table.deselectAll();
table.redraw();
}
@Override
protected void tableMouseMoveAction(MouseEvent event) {
mousePt.x = event.x;
mousePt.y = event.y;
TableItem item = table.getItem(mousePt);
if (item == null) {
table.setToolTipText(null);
return;
}
int tmpIndex = table.indexOf(item);
int index = tableIndexToDataIndex(tmpIndex);
Rectangle rect;
for (int i = 0; i < table.getColumnCount(); i++) {
rect = item.getBounds(i);
if (rect.contains(mousePt)) {
table.setToolTipText(tableData.getTableRows().get(index)
.getTableCellDataArray()[i].getHoverText());
}
}
}
public void updateThresholds(ThreshColNames threshColumn) {
// TODO : loop over index array
ArrayList<FFMPTableRowData> rowData = tableData.getTableRows();
for (int i = 0; i < rowData.size(); i++) {
rowData.get(i).getTableCellData(threshColumn.getColIndex())
.clearColor();
}
sortTableUsingConfig();
}
public boolean isVGB() {
return vgb;
}
public String getCurrentPfaf() {
return currentPfaf;
}
}

View file

@ -0,0 +1,190 @@
/**
* 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.ffmp.ui.dialogs;
import java.util.ArrayList;
import java.util.Collections;
import org.eclipse.swt.SWT;
import com.raytheon.uf.viz.monitor.ui.dialogs.ISortColumn;
/**
* Data class that contains an array of TableRowData objects. Each TableRowData
* object is one row of data in the table.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 7, 2009 lvenable Initial creation
* May 7, 2013 1986 njensen Optimized sortData()
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class FFMPTableData implements ISortColumn {
/**
* Array of TableRowData.
*/
private ArrayList<FFMPTableRowData> tableRows;
/**
* Current column index to sort on.
*/
private int currentSortColumnIndex = 0;
/**
* Current sort direction.
*/
private int currentSortDirection = SWT.DOWN;
/**
* Constructor.
*/
public FFMPTableData() {
tableRows = new ArrayList<FFMPTableRowData>();
}
/**
* Constructor.
*/
public FFMPTableData(int initialCapacity) {
tableRows = new ArrayList<FFMPTableRowData>(initialCapacity);
}
/**
* Add a row of cell data to the table rows collection.
*
* @param data
* Table row data.
*/
public synchronized void addDataRow(FFMPTableRowData data) {
tableRows.add(data);
}
/**
* Replace the data in a table cell.
*
* @param columnIndex
* Column index.
* @param areaID
* Area ID (acts like a primary key).
* @param data
* Table cell data.
*/
public void replaceTableCellData(int columnIndex, String areaID,
FFMPTableCellData data) {
for (FFMPTableRowData tableRowData : tableRows) {
if (areaID.equals(tableRowData.getTableCellData(0).getCellText()) == true) {
tableRowData.setTableCellData(columnIndex, data);
}
}
}
/**
* Get the table cell data.
*
* @param columnIndex
* Column index.
* @param areaID
* Area ID (acts like a primary key).
* @return Table cell data.
*/
public FFMPTableCellData getTableCellData(int columnIndex, String areaID) {
for (FFMPTableRowData tableRowData : tableRows) {
if (areaID.equals(tableRowData.getTableCellData(0).getCellText()) == true) {
return tableRowData.getTableCellData(0);
}
}
return null;
}
/**
* Get table row data.
*
* @param id
* Area ID.
* @return Table row data.
*/
public FFMPTableRowData getTableRowData(String id) {
for (FFMPTableRowData trd : tableRows) {
if (id.equals(trd.getTableCellData(0).getCellText()) == true) {
return trd;
}
}
return null;
}
/**
* Get array of table row data.
*
* @return Array of table row data.
*/
public ArrayList<FFMPTableRowData> getTableRows() {
return tableRows;
}
/**
* Get the sort column index.
*
* @return The index of the column to be sorted.
*/
@Override
public int getSortColumn() {
return currentSortColumnIndex;
}
/**
* Get the sort direction.
*
* @return The sort direction.
*/
@Override
public int getSortDirection() {
return currentSortDirection;
}
/**
* Sort the table data.
*
* @param columnIndex
* the column to sort on
* @param direction
* the direction to sort by
*/
public void sortData(int columnIndex, int direction) {
if (columnIndex != currentSortColumnIndex
|| direction != currentSortDirection) {
currentSortColumnIndex = columnIndex;
currentSortDirection = direction;
Collections.sort(tableRows);
if (getSortDirection() == SWT.DOWN) {
Collections.reverse(tableRows);
}
}
}
}

View file

@ -0,0 +1,152 @@
/**
* 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.ffmp.ui.dialogs;
import com.raytheon.uf.viz.monitor.ui.dialogs.ISortColumn;
/**
* Data class that contains an array of TableCellData. Each TableCellData
* represents one cell of data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 7, 2009 lvenable Initial creation
* May 7, 2013 1986 njensen Sped up compareTo()
*
* </pre>
*
* @author lvenable
* @version 1.0
*/
public class FFMPTableRowData implements Comparable<FFMPTableRowData> {
/**
* Array of TableCellData.
*/
private FFMPTableCellData[] rowCells;
/**
* Number of cells in a row.
*/
private int numCells = 0;
/**
* Sort callback.
*/
private ISortColumn sortCB = null;
private String pfaf;
/**
* Constructor.
*
* @param numberOfColumns
* Number of columns (cells) to be in the array.
*/
public FFMPTableRowData(int numberOfColumns) {
numCells = numberOfColumns;
rowCells = new FFMPTableCellData[numCells];
}
/**
* Get the table cell data.
*
* @param columnIndex
* Column index.
* @return Table cell data.
*/
public FFMPTableCellData getTableCellData(int columnIndex) {
return rowCells[columnIndex];
}
/**
* Set the table cell data.
*
* @param columnIndex
* Column index.
* @param newData
* New table cell data.
*/
public void setTableCellData(int columnIndex, FFMPTableCellData newData) {
if (columnIndex >= rowCells.length) {
return;
}
rowCells[columnIndex] = newData;
}
/**
* Set the sort callback.
*
* @param callback
* Sort callback.
*/
public void setSortCallback(ISortColumn callback) {
sortCB = callback;
}
/**
* Get the number of table cell data.
*
* @return The number of table cell data.
*/
public int getNumberOfCellData() {
return rowCells.length;
}
/**
* Get the array of table cell data.
*
* @return Array of table cell data.
*/
public FFMPTableCellData[] getTableCellDataArray() {
return rowCells;
}
public void setPfaf(String pfaf) {
this.pfaf = pfaf;
}
public String getPfaf() {
return pfaf;
}
/**
* compareTo method used to sort the data.
*/
@Override
public int compareTo(FFMPTableRowData otherObj) {
int selectedIndex = sortCB.getSortColumn();
FFMPTableCellData selectedCell = rowCells[selectedIndex];
if (selectedCell.getCellText() != null) {
String thisText = selectedCell.getCellText();
String otherText = otherObj.rowCells[selectedIndex].getCellText();
return thisText.compareTo(otherText);
} else {
float thisFloat = selectedCell.sortByNumber();
float otherFloat = otherObj.rowCells[selectedIndex].sortByNumber();
return Float.compare(thisFloat, otherFloat);
}
}
}

Some files were not shown because too many files have changed in this diff Show more