comboDict = loadCombinationsFile(comboName);
this.zoneSelector.updateCombos(comboDict);
+ applyButtonState(false);
}
}
@@ -1085,4 +1014,20 @@ public class ZoneCombinerComp extends Composite implements
});
}
}
+
+ private boolean buttonState() {
+ final boolean[] state = { false };
+ if (this.applyZoneComboBtn != null
+ && !this.applyZoneComboBtn.isDisposed()) {
+ VizApp.runSync(new Runnable() {
+ @Override
+ public void run() {
+ state[0] = ZoneCombinerComp.this.applyZoneComboBtn
+ .isEnabled();
+ }
+ });
+ }
+
+ return state[0];
+ }
}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/jobs/AutoSaveJob.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/jobs/AutoSaveJob.java
index db6879b963..97eede7351 100644
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/jobs/AutoSaveJob.java
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/jobs/AutoSaveJob.java
@@ -24,11 +24,14 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
-import com.raytheon.viz.gfe.Activator;
+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.viz.gfe.GFEPreference;
import com.raytheon.viz.gfe.PreferenceConstants;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.parm.Parm;
+import com.raytheon.viz.gfe.ui.HazardUIUtils;
/**
* Job implementing the auto save functionality. Uses user preferences to
@@ -38,7 +41,8 @@ import com.raytheon.viz.gfe.core.parm.Parm;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * Jun 25, 2008 Eric Babin Initial Creation
+ * Jun 25, 2008 Eric Babin Initial Creation
+ * Aug 27, 2013 #2302 randerso Fixed to behave more like A1, code cleanup
*
*
*
@@ -47,38 +51,34 @@ import com.raytheon.viz.gfe.core.parm.Parm;
*/
public class AutoSaveJob extends Job {
+ private static final transient IUFStatusHandler statusHandler = UFStatus
+ .getHandler(AutoSaveJob.class);
- private static final int MILLISECONDS_PER_MINUTE = 60 * 1000;
-
+ /**
+ * Max auto save interval in minutes
+ */
public static final int MAX_INTERVAL = 60;
+ /**
+ * Min auto save interval in minutes
+ */
public static final int MIN_INTERVAL = 1;
/**
- * auto save interval in minutes, 0 = disabled
+ * auto save interval in milliseconds, 0 = disabled
*/
- private static int interval;
- static {
- int i = 0;
- if (GFEPreference.storeAvailable()) {
- i = GFEPreference
- .getIntPreference(PreferenceConstants.GFE_AUTO_SAVE_INTERVAL);
- }
-
- interval = i;
- }
+ private long interval;
/**
* Set the auto save interval
*
- * @param i
+ * @param interval
* desired interval in minutes
*/
- public static void setInterval(int i) {
- interval = i;
-
- GFEPreference.setPreference(PreferenceConstants.GFE_AUTO_SAVE_INTERVAL,
- Integer.toString(i));
+ public void setInterval(int interval) {
+ this.interval = interval * TimeUtil.MILLIS_PER_MINUTE;
+ this.cancel();
+ this.reSchedule(this.interval);
}
/**
@@ -86,8 +86,8 @@ public class AutoSaveJob extends Job {
*
* @return interval in minutes
*/
- public static int getInterval() {
- return interval;
+ public int getInterval() {
+ return (int) (interval / TimeUtil.MILLIS_PER_MINUTE);
}
private DataManager dataManager;
@@ -104,17 +104,28 @@ public class AutoSaveJob extends Job {
this.dataManager = dataManager;
this.disposed = false;
this.setSystem(true);
+ int pref = GFEPreference
+ .getIntPreference(PreferenceConstants.GFE_AUTO_SAVE_INTERVAL);
+ if (pref > MAX_INTERVAL) {
+ pref = MAX_INTERVAL;
+ } else if (pref < 0) {
+ pref = 0;
+ }
- reSchedule();
+ this.interval = pref * TimeUtil.MILLIS_PER_MINUTE;
+ reSchedule(this.interval);
}
/**
- * Schedule this job to run after the desired interval
+ * Schedule this job to run after the desired
+ *
+ * @param delay
+ * interval in milliseconds
*/
- public void reSchedule() {
+ public void reSchedule(long delay) {
if (!disposed) {
- if (interval > 0) {
- this.schedule(interval * MILLISECONDS_PER_MINUTE);
+ if (delay > 0) {
+ this.schedule(delay);
}
} else {
dataManager = null;
@@ -138,53 +149,51 @@ public class AutoSaveJob extends Job {
*/
@Override
protected IStatus run(IProgressMonitor monitor) {
- IStatus status = Status.OK_STATUS;
- try {
- Parm[] parms = this.dataManager.getParmManager().getModifiedParms();
- if (parms != null && parms.length != 0) {
- String autoSaveResult = "GFE Auto Save called. Save of Parms[";
- for (int i = 0; i < parms.length; i++) {
- String name = parms[i].getParmID().getParmName();
- if (name.indexOf("Hazards") == -1) {
- autoSaveResult += saveParm(parms[i]);
- } else {
- if (!tempHazardsExist()) {
- saveParm(parms[i]);
- autoSaveResult += saveParm(parms[i]);
- }
- }
- }
- autoSaveResult += "]";
+ long delay = this.interval;
+ if (delay > 0) {
+ String msg = "GFE Auto Save called. ";
+ boolean success = false;
+ try {
+ Parm modifiedParm = getModifiedParm();
+ if (modifiedParm != null) {
+ msg += "Save of Parm "
+ + modifiedParm.getParmID().getParmName() + " = ";
- Activator.getDefault().getLog().log(
- new Status(IStatus.INFO, Activator.PLUGIN_ID,
- autoSaveResult));
+ // save the data
+ success = modifiedParm.saveParameter(false);
+ msg += (success ? "success" : "failure");
+ delay = 1500;
+ } else {
+ msg += "Nothing to save.";
+ }
+ statusHandler.info(msg);
+ } catch (Exception e) {
+ msg += "failure";
+ statusHandler.error(msg, e);
}
- } catch (Exception e) {
- status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
- "GFE auto save failed.", e);
+ reSchedule(delay);
}
- reSchedule();
- return status;
+ return Status.OK_STATUS;
}
/**
- * If tempHazards exist, then autosave kicked off in the middle of merge
- * hazard. (which creates a "temp" hazard with "haz" in the name.
+ * Find the first available modified parm. Skip Hazards if temp hazards
+ * exist
*
- * So we will ignore the "Hazard" WE parm save...
- *
- * @return if temp haz exists.
+ * @return the first available modified parm or null if none
*/
- private boolean tempHazardsExist() {
- Parm[] parms = this.dataManager.getParmManager().getDisplayedParms();
- for (int i = 0; i < parms.length; i++) {
- if (parms[i].getParmID().getParmName().indexOf("haz") != -1) {
- return true;
+ private Parm getModifiedParm() {
+ boolean tempHazDisplayed = HazardUIUtils
+ .tempHazardsExist(this.dataManager);
+ for (Parm p : this.dataManager.getParmManager().getModifiedParms()) {
+ if (p.getParmID().getParmName().contains("Hazards")
+ && tempHazDisplayed) {
+ continue;
+ } else {
+ return p;
}
}
-
- return false;
+ return null;
}
/**
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEResource.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEResource.java
index 1921b058d2..028ced353e 100644
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEResource.java
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEResource.java
@@ -161,6 +161,7 @@ import com.vividsolutions.jts.geom.Envelope;
* May 11, 2012 njensen Allow rsc to be recycled
* Nov 08, 2012 1298 rferrel Changes for non-blocking FuzzValueDialog.
* Mar 04, 2013 1637 randerso Fix time matching for ISC grids
+ * Aug 27, 2013 2287 randerso Fixed scaling and direction of wind arrows
*
*
*
@@ -617,6 +618,7 @@ public class GFEResource extends
}
clearVectorDisplays();
+ GFEVectorGraphicsRenderableFactory factory;
for (VisualizationType type : visTypes) {
switch (type) {
case WIND_ARROW:
@@ -626,24 +628,31 @@ public class GFEResource extends
if (logFactor < 0.0) {
logFactor = 0.0;
}
- // TODO: add logFactor to PointWindDisplay,
- // GriddedVectorDisplay
+ factory = new GFEVectorGraphicsRenderableFactory(
+ logFactor, parm.getGridInfo().getMaxValue());
this.vectorDisplay.add(new GriddedVectorDisplay(
mag, dir, descriptor, MapUtil
.getGridGeometry(gs.getGridInfo()
.getGridLoc()),
getVectorSize("WindArrowDefaultSize"),
- visTypeToDisplayType(type)));
+ 1.36, false, visTypeToDisplayType(type),
+ factory));
break;
case WIND_BARB:
- this.vectorDisplay.add(new GriddedVectorDisplay(
- mag, dir, descriptor, MapUtil
- .getGridGeometry(gs.getGridInfo()
- .getGridLoc()),
- getVectorSize("WindBarbDefaultSize"),
- visTypeToDisplayType(type)));
+ factory = new GFEVectorGraphicsRenderableFactory(
+ 0.0, parm.getGridInfo().getMaxValue());
+ this.vectorDisplay
+ .add(new GriddedVectorDisplay(
+ mag,
+ dir,
+ descriptor,
+ MapUtil.getGridGeometry(gs
+ .getGridInfo().getGridLoc()),
+ getVectorSize("WindBarbDefaultSize"),
+ 1.36, false,
+ visTypeToDisplayType(type), factory));
break;
case IMAGE:
@@ -1000,8 +1009,6 @@ public class GFEResource extends
size = 60;
}
- size = (int) (size / 0.8);
-
int offset = parm.getDisplayAttributes().getFontOffset()
+ Activator.getDefault().getPreferenceStore()
.getInt("Contour_font");
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderable.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderable.java
new file mode 100644
index 0000000000..80dbbbde26
--- /dev/null
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderable.java
@@ -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.viz.gfe.rsc;
+
+import com.raytheon.uf.viz.core.IGraphicsTarget;
+import com.raytheon.uf.viz.core.drawables.IDescriptor;
+import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
+import com.vividsolutions.jts.geom.Coordinate;
+
+/**
+ * GFE version of VectorGraphicsRenderable. Subclassed to better match A1 GFE
+ * behavior
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 22, 2013 #2287 randerso Initial creation
+ *
+ *
+ *
+ * @author randerso
+ * @version 1.0
+ */
+
+public class GFEVectorGraphicsRenderable extends VectorGraphicsRenderable {
+ double minLog = 0.0;
+
+ double maxLog = 0.0;
+
+ private double maxLimit;
+
+ /**
+ * @param descriptor
+ * @param target
+ * @param size
+ * @param logFactor
+ * @param maxLimit
+ */
+ public GFEVectorGraphicsRenderable(IDescriptor descriptor,
+ IGraphicsTarget target, double size, double logFactor,
+ double maxLimit) {
+ super(descriptor, target, size, logFactor);
+
+ this.maxLimit = maxLimit;
+ if (logFactor > 0.0) {
+ minLog = Math.log(logFactor);
+ maxLog = Math.log(logFactor + 1.0);
+ }
+ }
+
+ /**
+ *
+ * @param plotLoc
+ * @param adjSize
+ * @param spd
+ * @param dir
+ * barb direction in radians
+ */
+ @Override
+ public void paintBarb(Coordinate plotLoc, double adjSize, double spd,
+ double dir) {
+ paintPoint(plotLoc, adjSize);
+
+ int speed = (int) (spd + 2.5);
+ double staff = adjSize * .4;
+ double barb = staff * 0.30;
+ double add = staff * 0.105;
+ // DIRECTIONS
+ double uudd = -spd * Math.sin(dir);
+ double vvff = -spd * Math.cos(dir);
+ double dix = -uudd / spd;
+ double djy = -vvff / spd;
+ double dix1 = Math.cos(Math.toRadians(75)) * dix
+ + Math.sin(Math.toRadians(75)) * djy;
+ double djy1 = (-1) * Math.sin(Math.toRadians(75)) * dix
+ + Math.cos(Math.toRadians(75)) * djy;
+
+ // SPEED AND COUNTERS:
+ int n50 = speed / 50;
+ int calcSpd = speed - 50 * n50;
+ int n10 = calcSpd / 10;
+ calcSpd = calcSpd - 10 * n10;
+ int n5 = calcSpd / 5;
+ double sx = ((n50 + n50 + n10 + n5 + 2)) * add;
+ staff = Math.max(adjSize * .4, sx);
+
+ // DRAW STAFF
+ double ix2 = plotLoc.x;
+ double jy2 = plotLoc.y;
+ double ix1 = ix2 + dix * staff;
+ double jy1 = jy2 - djy * staff;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } });
+
+ // PLOT LONE HALF-BARB, IF NECESSARY
+ if (n50 == 0 && n10 == 0) {
+ ix2 = ix1 - dix * add;
+ jy2 = jy1 + djy * add;
+ ix1 = ix2 + dix1 * barb / 2.0;
+ jy1 = jy2 - djy1 * barb / 2.0;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 },
+ { ix1, jy1 } });
+ return;
+ }
+
+ // PLOT FLAGS, IF NECESSARY
+ for (int i = 0; i < n50; i++) {
+ ix2 = ix1 + dix1 * barb;
+ jy2 = jy1 - djy1 * barb;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 },
+ { ix1, jy1 } });
+ ix1 = ix1 - dix * add * 2;
+ jy1 = jy1 + djy * add * 2;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 },
+ { ix1, jy1 } });
+ }
+ if (n50 > 0) {
+ ix1 = ix1 - dix * add / 2.0;
+ jy1 = jy1 + djy * add / 2.0;
+ }
+
+ // PLOT BARB, IF NECESSARY
+ for (int i = 0; i < n10; i++) {
+ ix2 = ix1 + dix1 * barb;
+ jy2 = jy1 - djy1 * barb;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 },
+ { ix1, jy1 } });
+ ix1 = ix1 - dix * add;
+ jy1 = jy1 + djy * add;
+ }
+
+ // PLOT HALF-BARB, IF NECESSARY
+ if (n5 != 0) {
+ ix2 = ix1 + dix1 * barb / 2.0;
+ jy2 = jy1 - djy1 * barb / 2.0;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 },
+ { ix1, jy1 } });
+ }
+ }
+
+ @Override
+ public void paintArrow(Coordinate plotLoc, double adjSize, double mag,
+ double dir) {
+ paintPoint(plotLoc, adjSize);
+
+ double staff = 0.0;
+
+ double logFactor = this.scale;
+
+ // linear scaling
+ if (logFactor == 0.00) {
+ staff = mag * size / maxLimit;
+ } else {
+ double pcentRange = mag / maxLimit;
+ double lg = Math.log(logFactor + pcentRange);
+ double pcentLog = (lg - minLog) / (maxLog - minLog);
+ staff = pcentLog * size;
+ }
+
+ double barb = staff / 7.0;
+
+ // if (staff < barb) {
+ // return;
+ // }
+
+ double ratio = adjSize / size;
+ staff *= ratio;
+ barb *= ratio;
+
+ // DIRECTIONS
+ double uudd = -mag * Math.sin(dir);
+ double vvff = -mag * Math.cos(dir);
+ double dix = uudd / mag;
+ double djy = vvff / mag;
+ double dix1 = -dix - djy;
+ double djy1 = dix - djy;
+ double dix2 = -dix + djy;
+ double djy2 = -dix - djy;
+
+ // DRAW BODY OF ARROW
+ double ix2 = plotLoc.x;
+ double jy2 = plotLoc.y;
+ double ix1 = ix2 + dix * staff;
+ double jy1 = jy2 - djy * staff;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } });
+ // DRAW HEAD OF ARROW.
+ ix2 = ix1 + dix1 * barb;
+ jy2 = jy1 - djy1 * barb;
+ double ix3 = ix1 + dix2 * barb;
+ double jy3 = jy1 - djy2 * barb;
+ lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 },
+ { ix3, jy3 } });
+ }
+}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderableFactory.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderableFactory.java
new file mode 100644
index 0000000000..9448e8d6c5
--- /dev/null
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/GFEVectorGraphicsRenderableFactory.java
@@ -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.viz.gfe.rsc;
+
+import com.raytheon.uf.viz.core.IGraphicsTarget;
+import com.raytheon.uf.viz.core.drawables.IDescriptor;
+import com.raytheon.viz.core.contours.util.IVectorGraphicsRenderableFactory;
+import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
+
+/**
+ * GFE VectorGraphicsRenderable Factory
+ *
+ * Constructs the VectorGraphicsRenderable for GFE usage of GriddedVectorDisplay
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 22, 2013 #2287 randerso Initial creation
+ *
+ *
+ *
+ * @author randerso
+ * @version 1.0
+ */
+
+public class GFEVectorGraphicsRenderableFactory implements
+ IVectorGraphicsRenderableFactory {
+ private double logFactor;
+
+ private double maxLimit;
+
+ /**
+ * Constructor
+ *
+ * @param logFactor
+ * logFactor scaling value from parm_arrowScaling preference
+ * @param maxLimit
+ * max allowable value for parm
+ */
+ public GFEVectorGraphicsRenderableFactory(double logFactor, double maxLimit) {
+ this.logFactor = logFactor;
+ this.maxLimit = maxLimit;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.raytheon.viz.core.contours.util.IVectorGraphicsRenderableFactory#
+ * createRenderable(com.raytheon.uf.viz.core.drawables.IDescriptor,
+ * com.raytheon.uf.viz.core.IGraphicsTarget, double)
+ */
+ @Override
+ public VectorGraphicsRenderable createRenderable(IDescriptor descriptor,
+ IGraphicsTarget target, double size) {
+ return new GFEVectorGraphicsRenderable(descriptor, target, size,
+ logFactor, maxLimit);
+ }
+
+}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java
index 22a6bafaec..9c47ca94f8 100644
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/rsc/colorbar/GFEColorbarResource.java
@@ -62,9 +62,11 @@ import com.raytheon.viz.gfe.actions.SetDiscretePickupAction;
import com.raytheon.viz.gfe.actions.SetDiscreteWxPickupAction;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.ISpatialDisplayManager;
+import com.raytheon.viz.gfe.core.msgs.GridDataChangedMsg;
import com.raytheon.viz.gfe.core.msgs.IDisplayModeChangedListener;
import com.raytheon.viz.gfe.core.msgs.IDisplayedParmListChangedListener;
import com.raytheon.viz.gfe.core.msgs.IPickupValueChangedListener;
+import com.raytheon.viz.gfe.core.msgs.ISpatialEditorTimeChangedListener;
import com.raytheon.viz.gfe.core.msgs.Message;
import com.raytheon.viz.gfe.core.msgs.Message.IMessageClient;
import com.raytheon.viz.gfe.core.msgs.ShowQuickViewDataMsg;
@@ -100,6 +102,7 @@ import com.raytheon.viz.ui.input.InputAdapter;
* Changes for non-blocking SetValueDialog.
* 01/23/2013 #1524 randerso Fix error when clicking on discrete color bar when
* no grid exists
+ * 08/27/2013 #2287 randerso Fixed fitToDataColorTable for Single Grids
*
*
*
@@ -110,7 +113,7 @@ public class GFEColorbarResource extends
AbstractVizResource implements
IContextMenuProvider, IPickupValueChangedListener,
IDisplayModeChangedListener, IMessageClient,
- IDisplayedParmListChangedListener {
+ IDisplayedParmListChangedListener, ISpatialEditorTimeChangedListener {
public static final double HEIGHT = 25.0;
@@ -317,6 +320,8 @@ public class GFEColorbarResource extends
dManager.getParmManager().removeDisplayedParmListChangedListener(this);
dManager.getSpatialDisplayManager().removeDisplayModeChangedListener(
this);
+ dManager.getSpatialDisplayManager()
+ .removeSpatialEditorTimeChangedListener(this);
IDisplayPaneContainer container = getResourceContainer();
if (container != null) {
@@ -324,6 +329,7 @@ public class GFEColorbarResource extends
}
Message.unregisterInterest(this, ShowQuickViewDataMsg.class);
+ Message.unregisterInterest(this, GridDataChangedMsg.class);
if (colorbarScaleFont != null) {
colorbarScaleFont.dispose();
@@ -358,9 +364,12 @@ public class GFEColorbarResource extends
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
dManager.getSpatialDisplayManager().addDisplayModeChangedListener(this);
+ dManager.getSpatialDisplayManager()
+ .addSpatialEditorTimeChangedListener(this);
dManager.getParmManager().addDisplayedParmListChangedListener(this);
Message.registerInterest(this, ShowQuickViewDataMsg.class);
+ Message.registerInterest(this, GridDataChangedMsg.class);
colorbarScaleFont = GFEFonts.makeGFEIFont(target, "ColorBarScale_font",
1);
@@ -680,6 +689,16 @@ public class GFEColorbarResource extends
parm = gridId.getParm();
}
updateColorbar(parm);
+ } else if (message instanceof GridDataChangedMsg) {
+ GridDataChangedMsg msg = (GridDataChangedMsg) message;
+ if (currentParm != null
+ && msg.getParmID().equals(currentParm.getParmID())
+ && msg.getTimeRange().contains(
+ currentParm.getDataManager()
+ .getSpatialDisplayManager()
+ .getSpatialEditorTime())) {
+ checkFitToData();
+ }
}
}
@@ -689,6 +708,10 @@ public class GFEColorbarResource extends
* continuous colorbar range.
*/
protected void checkFitToData() {
+ if (currentParm == null) {
+ return;
+ }
+
String parmName = currentParm.getParmID().getParmName();
String fitToDataPref = parmName + "_fitToDataColorTable";
if (GFEPreference.contains(fitToDataPref)) {
@@ -836,4 +859,9 @@ public class GFEColorbarResource extends
updateColorbar(normalParm);
}
}
+
+ @Override
+ public void spatialEditorTimeChanged(Date date) {
+ checkFitToData();
+ }
}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileGenerator.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileGenerator.java
deleted file mode 100644
index d359ff50a8..0000000000
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileGenerator.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * This software was developed and / or modified by Raytheon Company,
- * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
- *
- * U.S. EXPORT CONTROLLED TECHNICAL DATA
- * This software product contains export-restricted data whose
- * export/transfer/disclosure is restricted by U.S. law. Dissemination
- * to non-U.S. persons whether in the United States or abroad requires
- * an export license or other authorization.
- *
- * Contractor Name: Raytheon Company
- * Contractor Address: 6825 Pine Street, Suite 340
- * Mail Stop B8
- * Omaha, NE 68106
- * 402.291.0100
- *
- * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
- * further licensing information.
- **/
-
-/**
- * Creating the combinations file for the TextFormatter
- *
- *
- *
- * SOFTWARE HISTORY
- *
- * Date Ticket# Engineer Description
- * ------------ ---------- ----------- --------------------------
- *6/12/2008 mnash Initial creation
- *
- *
- *
- * @author mnash
- * @version 1
- */
-package com.raytheon.viz.gfe.textformatter;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import com.raytheon.uf.common.dataplugin.gfe.request.SaveCombinationsFileRequest;
-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.PathManagerFactory;
-import com.raytheon.uf.common.util.FileUtil;
-import com.raytheon.viz.gfe.core.DataManager;
-import com.raytheon.viz.gfe.core.internal.IFPClient;
-
-public class CombinationsFileGenerator {
-
- /**
- * Generates combinations files based on just running the formatter
- *
- * @param zoneGroupList
- * @param filename
- * @throws IOException
- */
- public static void generateAutoCombinationsFile(
- List> zoneGroupList, String filename) throws Exception {
- generateCombinationsFile(zoneGroupList, filename, "");
- }
-
- /**
- * Generates combinations files based on user wanting to save
- *
- * @param zoneGroupList
- * @param filename
- * @throws IOException
- */
- public static void generateSavedCombinationsFile(
- List> zoneGroupList, String filename) throws Exception {
-
- if (filename.endsWith(".py")) {
- generateCombinationsFile(zoneGroupList, filename, "saved"
- + File.separator);
- } else {
- generateCombinationsFile(zoneGroupList, filename + ".py", "saved"
- + File.separator);
- }
- }
-
- /**
- * Called by both auto and saved functions to actually write file
- *
- * @param zoneGroupList
- * @param filename
- * @param loc
- * @throws Exception
- */
- public static void generateCombinationsFile(
- List> zoneGroupList, String filename, String loc)
- throws Exception {
- IFPClient ifpc = DataManager.getCurrentInstance().getClient();
- SaveCombinationsFileRequest req = new SaveCombinationsFileRequest();
- req.setFileName(FileUtil.join(loc, filename));
- req.setCombos(zoneGroupList);
- ifpc.makeRequest(req);
-
- IPathManager pm = PathManagerFactory.getPathManager();
- LocalizationContext ctx = pm.getContext(LocalizationType.CAVE_STATIC,
- LocalizationLevel.SITE);
- pm.getFile(ctx, FileUtil.join("gfe", "combinations", filename));
- }
-}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java
index cb47b506c8..aaea4f05be 100644
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java
@@ -20,6 +20,7 @@
package com.raytheon.viz.gfe.textformatter;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -33,7 +34,9 @@ import javax.xml.bind.annotation.XmlRootElement;
import jep.JepException;
+import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
+import com.raytheon.uf.common.dataplugin.gfe.request.SaveCombinationsFileRequest;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
@@ -49,8 +52,9 @@ import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
-import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
+import com.raytheon.viz.gfe.core.DataManagerUIFactory;
+import com.raytheon.viz.gfe.core.internal.IFPClient;
import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil.ComboData.Entry;
/**
@@ -60,7 +64,10 @@ import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil.ComboData.Entry;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * Jul 25, 2008 mnash Initial creation
+ * Jul 25, 2008 mnash Initial creation
+ * Sep 05, 2013 #2329 randerso Moved genereateAutoCombinationsFile here
+ * Cleaned up error handling
+ *
*
*
* @author mnash
@@ -200,7 +207,7 @@ public class CombinationsFileUtil {
}
@SuppressWarnings("unchecked")
- public static List> init(String comboName) {
+ public static List> init(String comboName) throws GfeException {
IPathManager pm = PathManagerFactory.getPathManager();
@@ -211,7 +218,6 @@ public class CombinationsFileUtil {
File comboFile = new File(comboName);
comboName = comboFile.getName();
- String comboPath = GfePyIncludeUtil.getCombinationsIncludePath();
String scriptPath = FileUtil.join(
GfePyIncludeUtil.getUtilitiesLF(baseContext).getFile()
.getPath(), "CombinationsInterface.py");
@@ -221,13 +227,15 @@ public class CombinationsFileUtil {
map.put("comboName", comboName);
PythonScript python = null;
try {
- python = new PythonScript(scriptPath,
- PyUtil.buildJepIncludePath(comboPath));
+ python = new PythonScript(scriptPath, PyUtil.buildJepIncludePath(
+ GfePyIncludeUtil.getCombinationsIncludePath(),
+ GfePyIncludeUtil.getCommonPythonIncludePath()),
+ CombinationsFileUtil.class.getClassLoader());
Object com = python.execute("getCombinations", map);
combos = (List>) com;
} catch (JepException e) {
- statusHandler.handle(Priority.CRITICAL,
- "Could not get combinations", e);
+ throw new GfeException("Error loading combinations file: "
+ + comboName, e);
} finally {
if (python != null) {
python.dispose();
@@ -235,4 +243,30 @@ public class CombinationsFileUtil {
}
return combos;
}
+
+ /**
+ * Generates combinations files based on just running the formatter
+ *
+ * @param zoneGroupList
+ * @param filename
+ * @throws Exception
+ * @throws IOException
+ */
+ public static void generateAutoCombinationsFile(
+ List> zoneGroupList, String filename) throws Exception {
+ IFPClient ifpc = DataManagerUIFactory.getCurrentInstance().getClient();
+ SaveCombinationsFileRequest req = new SaveCombinationsFileRequest();
+ req.setFileName(filename);
+ req.setCombos(zoneGroupList);
+ try {
+ statusHandler.info("Saving combinations file: " + filename);
+ ifpc.makeRequest(req);
+ statusHandler.info("Successfully saved combinations file: "
+ + filename);
+ } catch (Exception e) {
+ statusHandler.error("Error saving combinations file: " + filename,
+ e);
+ throw e;
+ }
+ }
}
diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java
index 1e9df6ba3c..1d0915d84f 100644
--- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java
+++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/FormatterUtil.java
@@ -20,7 +20,6 @@
package com.raytheon.viz.gfe.textformatter;
import java.text.SimpleDateFormat;
-import java.util.List;
import java.util.TimeZone;
import com.raytheon.uf.common.status.IUFStatusHandler;
@@ -40,8 +39,9 @@ import com.raytheon.viz.gfe.tasks.TaskManager;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * Sep 8, 2008 njensen Initial creation
- * Jan 15, 2010 3395 ryu Fix "issued by" functionality
+ * Sep 8, 2008 njensen Initial creation
+ * Jan 15, 2010 3395 ryu Fix "issued by" functionality
+ * Sep 05, 2013 2329 randerso Removed save of combinations file
*
*
*
@@ -63,21 +63,20 @@ public class FormatterUtil {
* the formatter instance to use
* @param productName
* the name of the text product
- * @param zoneList
- * the list of zones to produce the product for
+ * @param dbId
+ * source database
+ * @param vtecMode
+ * VTEC mode
* @param finish
* listener to fire when formatter finishes generating product
*/
public static void runFormatterScript(TextProductManager productMgr,
- String productName, List> zoneList, String dbId,
- String vtecMode, TextProductFinishListener finish) {
+ String productName, String dbId, String vtecMode,
+ TextProductFinishListener finish) {
try {
String filename = productMgr.getCombinationsFileName(productName);
boolean mapRequired = productMgr.mapRequired(productName);
if (filename != null && mapRequired) {
- String filenameExt = filename + ".py";
- CombinationsFileGenerator.generateAutoCombinationsFile(
- zoneList, filenameExt);
productMgr.reloadModule(filename);
}
} catch (Exception e) {
diff --git a/cave/com.raytheon.viz.grid/localization/styleRules/gridReprojectionRules.xml b/cave/com.raytheon.viz.grid/localization/styleRules/gridReprojectionRules.xml
new file mode 100644
index 0000000000..b996a043eb
--- /dev/null
+++ b/cave/com.raytheon.viz.grid/localization/styleRules/gridReprojectionRules.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java
index fedefeda79..434e44643d 100644
--- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java
@@ -50,6 +50,8 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation
+ * Aug 27, 2013 #2287 randerso Added densityFactor to allow application specific
+ * adjustment of density.
*
*
*
@@ -68,13 +70,17 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay {
private PointIconFactory iconFactory;
/**
+ * @param values
* @param descriptor
* @param gridGeometryOfGrid
* @param imageSize
+ * @param densityFactor
+ * adjustment factor to make density match A1
*/
public GriddedIconDisplay(float[] values, IMapDescriptor descriptor,
- GeneralGridGeometry gridGeometryOfGrid, int imageSize) {
- super(descriptor, gridGeometryOfGrid, imageSize);
+ GeneralGridGeometry gridGeometryOfGrid, int imageSize,
+ double densityFactor) {
+ super(descriptor, gridGeometryOfGrid, imageSize, densityFactor);
this.values = values;
}
@@ -126,6 +132,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay {
return (int) values[idx];
}
+ @Override
public boolean setColor(RGB color) {
if (super.setColor(color)) {
iconFactory = null;
@@ -166,8 +173,8 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay {
if (renderable.resource != empty) {
PointImage image = new PointImage(renderable.resource,
renderable.plotLocation);
- image.setHeight((double) size * magnification);
- image.setWidth((double) size * magnification);
+ image.setHeight(size * magnification);
+ image.setWidth(size * magnification);
images.add(image);
}
}
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java
index ff8574b9c8..f88268818a 100644
--- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java
@@ -87,6 +87,7 @@ import com.raytheon.viz.core.contours.rsc.displays.AbstractGriddedDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedStreamlineDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay;
+import com.raytheon.viz.core.contours.util.VectorGraphicsRenderableFactory;
import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay2;
import com.raytheon.viz.core.style.arrow.ArrowPreferences;
@@ -111,6 +112,8 @@ import com.vividsolutions.jts.geom.Coordinate;
* May 08, 2013 1980 bsteffen Set paint status in GridResources for
* KML.
* Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows.
+ * Aug 27, 2013 2287 randerso Added new parameters required by GriddedVectorDisplay
+ * and GriddedIconDisplay
*
*
*
@@ -154,13 +157,14 @@ public abstract class AbstractGridResource
protected AbstractGridResource(T resourceData, LoadProperties loadProperties) {
super(resourceData, loadProperties);
resourceData.addChangeListener(new IResourceDataChanged() {
+ @Override
public void resourceChanged(ChangeType type, Object object) {
if (type == ChangeType.DATA_UPDATE) {
if (object instanceof PluginDataObject) {
addDataObject((PluginDataObject) object);
} else if (object instanceof PluginDataObject[]) {
for (PluginDataObject pdo : (PluginDataObject[]) object) {
- addDataObject((PluginDataObject) pdo);
+ addDataObject(pdo);
}
} else if (object instanceof Object[]) {
for (Object obj : (Object[]) object) {
@@ -489,9 +493,10 @@ public abstract class AbstractGridResource
case ARROW:
case DUALARROW:
convertData(data);
+ VectorGraphicsRenderableFactory factory = new VectorGraphicsRenderableFactory();
GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay(
data.getMagnitude(), data.getDirection(), descriptor,
- gridGeometry, 64, displayType);
+ gridGeometry, 64, 0.75, true, displayType, factory);
vectorDisplay.setColor(getCapability(ColorableCapability.class)
.getColor());
vectorDisplay.setLineStyle(getCapability(OutlineCapability.class)
@@ -504,14 +509,15 @@ public abstract class AbstractGridResource
MagnificationCapability.class).getMagnification());
if (stylePreferences != null
&& stylePreferences instanceof ArrowPreferences) {
- vectorDisplay.setScale(((ArrowPreferences) stylePreferences)
+ factory.setScale(((ArrowPreferences) stylePreferences)
.getScale());
}
renderable = vectorDisplay;
break;
case ICON:
GriddedIconDisplay iconDisplay = new GriddedIconDisplay(data
- .getScalarData().array(), descriptor, gridGeometry, 80);
+ .getScalarData().array(), descriptor, gridGeometry, 80,
+ 0.75);
iconDisplay.setColor(getCapability(ColorableCapability.class)
.getColor());
iconDisplay.setDensity(getCapability(DensityCapability.class)
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java
index 6cf9d87158..53d6333731 100644
--- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java
@@ -53,6 +53,7 @@ import com.raytheon.uf.viz.core.datastructure.DataCubeContainer;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator;
import com.raytheon.uf.viz.core.rsc.DisplayType;
+import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.DisplayTypeCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
@@ -60,7 +61,7 @@ import com.raytheon.viz.grid.rsc.GridNameGenerator;
import com.raytheon.viz.grid.rsc.GridNameGenerator.IGridNameResource;
import com.raytheon.viz.grid.rsc.GridNameGenerator.LegendParameters;
import com.raytheon.viz.grid.rsc.GridResourceData;
-import com.raytheon.viz.grid.util.ConformalityUtil;
+import com.raytheon.viz.grid.util.ReprojectionUtil;
import com.raytheon.viz.grid.xml.FieldDisplayTypesFactory;
import com.vividsolutions.jts.geom.Coordinate;
@@ -79,6 +80,9 @@ import com.vividsolutions.jts.geom.Coordinate;
* constructor to avoid duplicate data
* requests.
* Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows.
+ * Aug 27, 2013 2287 randerso Removed 180 degree adjustment required by error
+ * in Maputil.rotation
+ * Sep 24, 2013 DR 15972 D. Friedman Make reprojection of grids configurable.
*
*
*
@@ -92,6 +96,8 @@ public class D2DGridResource extends GridResource implements
private boolean reprojectedData = false;
+ private Boolean lastInterpolationState = null;
+
public D2DGridResource(GridResourceData resourceData,
LoadProperties loadProperties) {
super(resourceData, loadProperties);
@@ -101,7 +107,10 @@ public class D2DGridResource extends GridResource implements
for (GridRecord record : resourceData.getRecords()) {
addDataObject(record);
}
-
+ if (this.hasCapability(ImagingCapability.class)) {
+ lastInterpolationState = this.getCapability(ImagingCapability.class)
+ .isInterpolationState();
+ }
}
@Override
@@ -141,17 +150,15 @@ public class D2DGridResource extends GridResource implements
return null;
}
}
- // For world wide lat lon grids we reproject, this is done to match A1,
- // but it also makes the wind barbs look more evenly spaced near the
- // pole.
+ // For some grids, we may reproject (e.g., world-wide lat/lon grids),
+ // this is done to match A1, but it also makes the wind barbs look
+ // more evenly spaced near the pole.
GridCoverage location = gridRecord.getLocation();
GeneralGridData data = getData(dataRecs, location.getGridGeometry(),
dataUnit);
- if (location != null && location.getSpacingUnit().equals("degree")) {
- if (!ConformalityUtil.testConformality(location.getGridGeometry(),
- descriptor.getGridGeometry())) {
- data = reprojectData(data);
- }
+ if (ReprojectionUtil.shouldReproject(gridRecord,
+ getDisplayType(), descriptor.getGridGeometry())) {
+ data = reprojectData(data);
}
// Wind Direction(and possibly others) can be set so that we rotate the
// direction to be relative to the north pole instead of grid relative.
@@ -174,7 +181,7 @@ public class D2DGridResource extends GridResource implements
crs2ll.transform(dp, dp);
Coordinate ll = new Coordinate(dp.x, dp.y);
float rot = (float) MapUtil.rotation(ll, geom);
- dir = (dir + rot + 180) % 360;
+ dir = (dir + rot) % 360;
data.getScalarData().put(index, dir);
}
}
@@ -316,4 +323,19 @@ public class D2DGridResource extends GridResource implements
super.project(crs);
}
+ @Override
+ protected void resourceDataChanged(ChangeType type, Object updateObject) {
+ super.resourceDataChanged(type, updateObject);
+ if (type == ChangeType.CAPABILITY) {
+ if (updateObject instanceof ImagingCapability && reprojectedData) {
+ ImagingCapability capability = (ImagingCapability) updateObject;
+ if (lastInterpolationState == null
+ || capability.isInterpolationState() != lastInterpolationState) {
+ lastInterpolationState = capability.isInterpolationState();
+ clearRequestedData();
+ }
+ }
+ }
+ }
+
}
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java
index a199f7f0e7..862861e277 100644
--- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java
@@ -56,7 +56,9 @@ import com.vividsolutions.jts.geom.Coordinate;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * Mar 9, 2011 bsteffen Initial creation
+ * Mar 9, 2011 bsteffen Initial creation
+ * Aug 27, 2013 #2287 randerso Removed 180 degree adjustment required by error
+ * in Maputil.rotation
*
*
*
@@ -247,8 +249,8 @@ public class GeneralGridData {
Coordinate ll = new Coordinate(dp.x, dp.y);
double rot = MapUtil.rotation(ll, newGeom);
double rot2 = MapUtil.rotation(ll, gridGeometry);
- double cos = Math.cos(Math.toRadians(180 + rot - rot2));
- double sin = Math.sin(Math.toRadians(180 + rot - rot2));
+ double cos = Math.cos(Math.toRadians(rot - rot2));
+ double sin = Math.sin(Math.toRadians(rot - rot2));
double u = udata[index];
double v = vdata[index];
udata[index] = (float) (cos * u - sin * v);
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ConformalityUtil.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ConformalityUtil.java
index 04bb98c6e4..f81809bb7e 100644
--- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ConformalityUtil.java
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ConformalityUtil.java
@@ -35,7 +35,8 @@ import org.opengis.referencing.operation.TransformException;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 06/19/2012 14988 D. Friedman Initial revision
- *
+ * 09/24/2013 DR 15972 D. Friedman Do not require contiguous mapping.
+ *
*
*/
public class ConformalityUtil {
@@ -96,11 +97,17 @@ public class ConformalityUtil {
if (! evaluateNonContig(evaluatedDomain)) {
System.out.format("%s -> %s : not contiguous?\n", sourceGG, destGG);
return false;
+ /*
+ * This test is not necessary for AWIPS II because it can cope
+ * with non-contiguous mappings.
+ */
+ /*
} else if (maxRatio/minRatio > maxRatioRatio ||
(minRatio > 0 && maxRatio/minRatio > maxRatioRatio) || // ?
(minRatio < 0 && minRatio/maxRatio > maxRatioRatio)) {
System.out.format("%s -> %s : not conformal enough somehow\n", sourceGG, destGG);
return false;
+ */
} else {
System.out.format("%s -> %s : conformal enough (%f, %f)\n",
sourceGG, destGG, rr, maxRatio/minRatio);
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ReprojectionUtil.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ReprojectionUtil.java
new file mode 100644
index 0000000000..6830ec8725
--- /dev/null
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/util/ReprojectionUtil.java
@@ -0,0 +1,159 @@
+package com.raytheon.viz.grid.util;
+
+import java.util.regex.Pattern;
+
+import org.geotools.coverage.grid.GeneralGridGeometry;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.operation.projection.MapProjection;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.raytheon.uf.common.dataplugin.grid.GridRecord;
+import com.raytheon.uf.common.gridcoverage.GridCoverage;
+import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile;
+import com.raytheon.uf.common.localization.AutoUpdatingLocalizationFile.AutoUpdatingFileChangedListener;
+import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
+import com.raytheon.uf.common.localization.exception.LocalizationException;
+import com.raytheon.uf.common.serialization.JAXBManager;
+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.rsc.DisplayType;
+import com.raytheon.viz.grid.xml.GridReprojectionRules;
+import com.raytheon.viz.grid.xml.GridReprojectionRules.Reproject;
+import com.raytheon.viz.grid.xml.GridReprojectionRules.Rule;
+
+/**
+ * Determines if a grid should be reprojected based display properties and
+ * a configuration file.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ---------------- --------------------------
+ * Sep 23, 2013 DR 15972 D. Friedman Initial creation
+ *
+ *
+ *
+ */
+public class ReprojectionUtil {
+ private static final String RULES_PATH = "styleRules/gridReprojectionRules.xml";
+
+ private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(ReprojectionUtil.class);
+
+ private static ReprojectionUtil instance;
+
+ static ReprojectionUtil getInstance() {
+ if (instance == null) {
+ synchronized (ReprojectionUtil.class) {
+ if (instance == null)
+ instance = new ReprojectionUtil();
+ }
+ }
+ return instance;
+ }
+
+ GridReprojectionRules rules;
+ AutoUpdatingLocalizationFile file;
+ boolean fileChanged = false;
+
+ public static boolean shouldReproject(GridRecord record, DisplayType displayType, GeneralGridGeometry dstGridGeometry) {
+ GridReprojectionRules rules = getInstance().getRules();
+ if (rules != null) {
+ for (Rule rule : rules.getRules()) {
+ if (matches(rule, record, displayType, dstGridGeometry)) {
+ Reproject reproject = rule.getReproject();
+ if (reproject == Reproject.ALWAYS) {
+ return true;
+ } else if (reproject == Reproject.NEVER) {
+ return false;
+ } else if (reproject == Reproject.TEST || reproject == null) {
+ return !ConformalityUtil.testConformality(record
+ .getLocation().getGridGeometry(),
+ dstGridGeometry);
+ } else {
+ throw new RuntimeException(
+ String.format("Unknown reprojection behavior "
+ + reproject));
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean matches(Rule rule, GridRecord record, DisplayType displayType,
+ GeneralGridGeometry dstGridGeometry) {
+ return matches(rule.getModelName(), record.getDatasetId()) &&
+ matches(rule.getSrcProjection(), getProjectionName(record.getLocation())) &&
+ matches(rule.getDstProjection(), getProjectionName(dstGridGeometry)) &&
+ matches(rule.getDisplayType(), displayType.toString());
+ }
+
+ private static boolean matches(String pattern, String value) {
+ if (pattern == null)
+ return true;
+ return Pattern.matches(pattern, value != null ? value : "");
+ }
+
+ private static String getProjectionName(GridCoverage coverage) {
+ return coverage != null ? getProjectionName(coverage.getCrs()) : null;
+ }
+
+ private static String getProjectionName(GeneralGridGeometry gridGeometry) {
+ return gridGeometry != null ? getProjectionName(gridGeometry.getCoordinateReferenceSystem()) : null;
+ }
+
+ private static String getProjectionName(CoordinateReferenceSystem crs) {
+ MapProjection projection = CRS.getMapProjection(crs);
+ return projection != null ? projection.getName() : null;
+ }
+
+ public GridReprojectionRules getRules() {
+ try {
+ synchronized(this) {
+ if (checkFileChanged()) {
+ GridReprojectionRules newRules = file.loadObject(
+ new JAXBManager(GridReprojectionRules.class),
+ GridReprojectionRules.class);
+ if (newRules == null)
+ throw new LocalizationException("No " + RULES_PATH + "found");
+ rules = newRules;
+ }
+ }
+ } catch (Exception e) {
+ statusHandler.handle(
+ Priority.PROBLEM,
+ "Error occurred loading grid reproject rules",
+ e);
+ }
+ return rules;
+ }
+
+ private synchronized boolean checkFileChanged() throws LocalizationException {
+ if (file == null) {
+ file = new AutoUpdatingLocalizationFile(RULES_PATH, LocalizationType.CAVE_STATIC);
+ file.addListener(new AutoUpdatingFileChangedListener() {
+ @Override
+ public void fileChanged(AutoUpdatingLocalizationFile file) {
+ synchronized (ReprojectionUtil.this) {
+ fileChanged = true;
+ };
+ }
+ });
+ return true;
+ } else {
+ /*
+ * Only return true once per noticed file changed (and not after the
+ * file has been read.) This is done to prevent a flood of AlertViz
+ * errors if there is something wrong with the file.
+ */
+ if (fileChanged) {
+ fileChanged = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+}
diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/xml/GridReprojectionRules.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/xml/GridReprojectionRules.java
new file mode 100644
index 0000000000..575397e7d7
--- /dev/null
+++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/xml/GridReprojectionRules.java
@@ -0,0 +1,85 @@
+package com.raytheon.viz.grid.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Container for a list of rules that describe how gridded data should be
+ * re-projected on various map projections.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ---------------- --------------------------
+ * Sep 23, 2013 DR 15972 D. Friedman Initial creation
+ *
+ *
+ *
+ */
+@XmlRootElement()
+@XmlAccessorType(XmlAccessType.NONE)
+public class GridReprojectionRules {
+ public static enum Reproject {
+ ALWAYS, NEVER, TEST
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ public static class Rule {
+ @XmlAttribute
+ private String modelName;
+ @XmlAttribute
+ private String displayType;
+ @XmlAttribute
+ private String srcProjection;
+ @XmlAttribute
+ private String dstProjection;
+ @XmlAttribute
+ private Reproject reproject;
+
+ public String getModelName() {
+ return modelName;
+ }
+ public void setModelName(String modelName) {
+ this.modelName = modelName;
+ }
+ public String getDisplayType() {
+ return displayType;
+ }
+ public void setDisplayType(String displayType) {
+ this.displayType = displayType;
+ }
+ public String getSrcProjection() {
+ return srcProjection;
+ }
+ public void setSrcProjection(String srcProjection) {
+ this.srcProjection = srcProjection;
+ }
+ public String getDstProjection() {
+ return dstProjection;
+ }
+ public void setDstProjection(String dstProjection) {
+ this.dstProjection = dstProjection;
+ }
+ public Reproject getReproject() {
+ return reproject;
+ }
+ public void setReproject(Reproject reproject) {
+ this.reproject = reproject;
+ }
+ }
+
+ @XmlElement(name = "rule")
+ private List rules = new ArrayList(0);
+
+ public List getRules() {
+ return rules;
+ }
+
+}
diff --git a/cave/com.raytheon.viz.hydro/localization/bundles/hydro/FFGLmosaic.xml b/cave/com.raytheon.viz.hydro/localization/bundles/hydro/FFGLmosaic.xml
index d57a5a8bd5..bf3fa18b8a 100644
--- a/cave/com.raytheon.viz.hydro/localization/bundles/hydro/FFGLmosaic.xml
+++ b/cave/com.raytheon.viz.hydro/localization/bundles/hydro/FFGLmosaic.xml
@@ -47,7 +47,7 @@