Issue #2363 Add more vector configuration optons.

Change-Id: I1a3e564629b9e4afe93a0a4ceee8e57681aa0644

Former-commit-id: 1aa1f72b68 [formerly 860258e49c] [formerly ff06ea1c5a] [formerly 20853f7333 [formerly ff06ea1c5a [formerly 8af298f9ef2c1c03e6be690c07829d0569b1dedd]]]
Former-commit-id: 20853f7333
Former-commit-id: d31fc0b096d78305c15905ad2838ab76dd9d9f67 [formerly 6c7c693581]
Former-commit-id: bf0642450c
This commit is contained in:
Ben Steffensmeier 2013-09-26 12:47:43 -05:00
parent 4354bf629b
commit 075a394152
19 changed files with 1256 additions and 726 deletions

View file

@ -81,7 +81,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability;
import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderableFactory; import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay; import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay.GriddedImagePaintProperties; import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay.GriddedImagePaintProperties;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
@ -92,12 +92,13 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Nov 5, 2009 randerso Initial creation * Nov 05, 2009 randerso Initial creation
* Jan 8, 2010 4205 jelkins add equals checking for OA resources * Jan 08, 2010 4205 jelkins add equals checking for OA resources
* Aug 27, 2013 2287 randerso Added new parameters to GriddedVectorDisplay * Aug 27, 2013 2287 randerso Added new parameters to
* constructor * GriddedVectorDisplay constructor
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -113,6 +114,9 @@ public class OAResource extends
private static final int GRID_SIZE = 300; private static final int GRID_SIZE = 300;
/* Unknown source, seems to be provide acceptable density. */
private static final double VECTOR_DENSITY_FACTOR = 1.875;
private class OAUpateJob extends Job { private class OAUpateJob extends Job {
public OAUpateJob() { public OAUpateJob() {
@ -427,10 +431,10 @@ public class OAResource extends
FloatBuffer mag = data; FloatBuffer mag = data;
data.position(transformer.getNx() * transformer.getNy()); data.position(transformer.getNx() * transformer.getNy());
FloatBuffer dir = data.slice(); FloatBuffer dir = data.slice();
VectorGraphicsRenderableFactory factory = new VectorGraphicsRenderableFactory();
GriddedVectorDisplay vector = new GriddedVectorDisplay(mag, GriddedVectorDisplay vector = new GriddedVectorDisplay(mag,
dir, descriptor, transformer.getGridGeom(), 80, 0.75, dir, descriptor, transformer.getGridGeom(),
true, displayType, factory); VECTOR_DENSITY_FACTOR,
true, displayType, new VectorGraphicsConfig());
renderableMap.put(dataTime, vector); renderableMap.put(dataTime, vector);
break; break;

View file

@ -30,7 +30,6 @@ import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
import com.raytheon.uf.common.style.StyleException; import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.StyleManager; import com.raytheon.uf.common.style.StyleManager;
import com.raytheon.uf.common.style.StyleRule; import com.raytheon.uf.common.style.StyleRule;
import com.raytheon.uf.common.style.arrow.ArrowPreferences;
import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IGraphicsTarget;
@ -45,8 +44,8 @@ import com.raytheon.uf.viz.core.rsc.capabilities.DisplayTypeCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability;
import com.raytheon.uf.viz.xy.crosssection.adapter.AbstractCrossSectionAdapter; import com.raytheon.uf.viz.xy.crosssection.adapter.AbstractCrossSectionAdapter;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable; import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
import com.raytheon.viz.core.graphing.xy.XYWindImageData;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
/** /**
@ -55,10 +54,11 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jun 15, 2010 bsteffen Initial creation * Jun 15, 2010 bsteffen Initial creation
* Feb 14, 2011 8244 bkowal enabled magnification capability. * Feb 14, 2011 8244 bkowal enabled magnification capability.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -68,9 +68,8 @@ import com.vividsolutions.jts.geom.Coordinate;
public class CrossSectionVectorResource extends AbstractCrossSectionResource { public class CrossSectionVectorResource extends AbstractCrossSectionResource {
private ArrowPreferences arrowPrefs; /* Unknown source, provides acceptable density. */
private static final int VECTOR_SPACING = 60;
private int imageSize = XYWindImageData.IMAGE_SIZE;
/** /**
* @param data * @param data
@ -94,7 +93,7 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
e.printStackTrace(); e.printStackTrace();
} }
if (sr != null) { if (sr != null) {
prefs = arrowPrefs = (ArrowPreferences) sr.getPreferences(); prefs = sr.getPreferences();
} }
} }
@ -116,8 +115,6 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
double density = getCapability(DensityCapability.class).getDensity(); double density = getCapability(DensityCapability.class).getDensity();
RGB color = getCapability(ColorableCapability.class).getColor(); RGB color = getCapability(ColorableCapability.class).getColor();
int scaledSize = (int) (this.imageSize * magnification);
IExtent graphArea = descriptor.getGraph(this).getExtent(); IExtent graphArea = descriptor.getGraph(this).getExtent();
if (graphArea == null) { if (graphArea == null) {
return; return;
@ -131,13 +128,15 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
double ratio = paintProps.getView().getExtent().getWidth() double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width; / paintProps.getCanvasBounds().width;
int spacing = (int) ((geometry.getGridRange2D().getMaxX() int spacing = (int) ((geometry.getGridRange2D().getMaxX()
* this.imageSize * .75 * ratio / Math.min(2.0, density) * magnification) * VECTOR_SPACING * ratio / Math.min(2.0, density) * magnification)
/ paintProps.getCanvasBounds().width + 1); / paintProps.getCanvasBounds().width + 1);
IExtent viewableArea = paintProps.getView().getExtent() IExtent viewableArea = paintProps.getView().getExtent()
.intersection(graphArea); .intersection(graphArea);
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setSizeScaler(magnification * ratio);
VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(descriptor, VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(descriptor,
target, this.imageSize, 1.0f); target, config);
for (int i = spacing / 2; i < geometry.getGridRange2D().getMaxX(); i += spacing) { for (int i = spacing / 2; i < geometry.getGridRange2D().getMaxX(); i += spacing) {
for (int j = spacing / 2; j < geometry.getGridRange2D().getMaxY(); j += spacing) { for (int j = spacing / 2; j < geometry.getGridRange2D().getMaxY(); j += spacing) {
@ -156,11 +155,10 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
double spd = Math.hypot(uudd, vvff); double spd = Math.hypot(uudd, vvff);
double dir = Math.atan2(-uudd, -vvff); double dir = Math.atan2(-uudd, -vvff);
Coordinate plotLoc = new Coordinate(screenX, screenY); Coordinate plotLoc = new Coordinate(screenX, screenY);
double adjSize = scaledSize * ratio;
if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) { if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) {
vgr.paintArrow(plotLoc, adjSize, spd, dir); vgr.paintArrow(plotLoc, spd, dir);
} else { } else {
vgr.paintBarb(plotLoc, adjSize, spd, dir); vgr.paintBarb(plotLoc, spd, dir);
} }
} }
} }
@ -194,8 +192,8 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
&& y < geometry.getGridRange().getSpan(1) && y < geometry.getGridRange().getSpan(1)
&& sliceMap.get(time) != null) { && sliceMap.get(time) != null) {
int index = y * geometry.getGridRange().getSpan(0) + x; int index = y * geometry.getGridRange().getSpan(0) + x;
float[] ufd = (float[]) sliceMap.get(time).get(2); float[] ufd = sliceMap.get(time).get(2);
float[] vfd = (float[]) sliceMap.get(time).get(3); float[] vfd = sliceMap.get(time).get(3);
double val = Math.hypot(ufd[index], vfd[index]); double val = Math.hypot(ufd[index], vfd[index]);
ColorMapParameters colorMapParams = getCapability( ColorMapParameters colorMapParams = getCapability(

View file

@ -6,43 +6,24 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.xy.timeheight.Activator Bundle-Activator: com.raytheon.uf.viz.xy.timeheight.Activator
Bundle-Vendor: RAYTHEON Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.core.runtime, Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui;bundle-version="3.4.1", org.eclipse.ui,
com.raytheon.uf.common.colormap,
com.raytheon.uf.common.dataquery,
com.raytheon.uf.common.geospatial, com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.colormap;bundle-version="1.12.1174" com.raytheon.uf.common.style,
com.raytheon.uf.viz.core,
com.raytheon.uf.viz.d2d.core,
com.raytheon.uf.viz.xy,
com.raytheon.uf.viz.xy.varheight,
javax.measure
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core, com.raytheon.viz.core Eclipse-RegisterBuddy: com.raytheon.uf.viz.core, com.raytheon.viz.core
Import-Package: com.raytheon.uf.common.dataplugin, Import-Package: com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.dataquery.requests,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.geospatial.interpolation,
com.raytheon.uf.common.serialization,
com.raytheon.uf.common.status, com.raytheon.uf.common.status,
com.raytheon.uf.common.style,
com.raytheon.uf.common.style.arrow,
com.raytheon.uf.common.style.contour,
com.raytheon.uf.common.style.image, com.raytheon.uf.common.style.image,
com.raytheon.uf.common.time, com.raytheon.uf.common.time,
com.raytheon.uf.viz.core,
com.raytheon.uf.viz.core.data,
com.raytheon.uf.viz.core.data.prep,
com.raytheon.uf.viz.core.drawables,
com.raytheon.uf.viz.core.exception,
com.raytheon.uf.viz.core.interp,
com.raytheon.uf.viz.core.map,
com.raytheon.uf.viz.core.rsc,
com.raytheon.uf.viz.core.rsc.capabilities,
com.raytheon.uf.viz.core.rsc.sampling,
com.raytheon.uf.viz.core.status,
com.raytheon.uf.viz.d2d.core.map,
com.raytheon.uf.viz.d2d.ui, com.raytheon.uf.viz.d2d.ui,
com.raytheon.uf.viz.xy,
com.raytheon.uf.viz.xy.graph,
com.raytheon.uf.viz.xy.graph.axis,
com.raytheon.uf.viz.xy.graph.labeling,
com.raytheon.uf.viz.xy.map.rsc,
com.raytheon.uf.viz.xy.varheight.adapter,
com.raytheon.uf.viz.xy.varheight.rsc,
com.raytheon.viz.core.contours, com.raytheon.viz.core.contours,
com.raytheon.viz.core.contours.util, com.raytheon.viz.core.contours.util,
com.raytheon.viz.core.graphing.util, com.raytheon.viz.core.graphing.util,
@ -51,18 +32,7 @@ Import-Package: com.raytheon.uf.common.dataplugin,
com.raytheon.viz.core.map, com.raytheon.viz.core.map,
com.raytheon.viz.core.rsc, com.raytheon.viz.core.rsc,
com.raytheon.viz.core.slice.request, com.raytheon.viz.core.slice.request,
com.raytheon.viz.grid.rsc, com.raytheon.viz.grid.rsc
com.raytheon.viz.pointdata,
com.raytheon.viz.ui.editor,
com.raytheon.viz.ui.input,
com.vividsolutions.jts.geom,
javax.measure.converter,
javax.measure.unit,
org.geotools.coverage.grid,
org.geotools.geometry,
org.opengis.coverage.grid,
org.opengis.geometry,
org.opengis.referencing.operation
Export-Package: com.raytheon.uf.viz.xy.timeheight, Export-Package: com.raytheon.uf.viz.xy.timeheight,
com.raytheon.uf.viz.xy.timeheight.display, com.raytheon.uf.viz.xy.timeheight.display,
com.raytheon.uf.viz.xy.timeheight.graph, com.raytheon.uf.viz.xy.timeheight.graph,

View file

@ -31,10 +31,9 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.style.ParamLevelMatchCriteria; import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.StyleManager; import com.raytheon.uf.common.style.StyleManager;
import com.raytheon.uf.common.style.StyleRule; import com.raytheon.uf.common.style.StyleRule;
import com.raytheon.uf.common.style.StyleException;
import com.raytheon.uf.common.style.arrow.ArrowPreferences;
import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IGraphicsTarget;
@ -54,6 +53,7 @@ import com.raytheon.uf.viz.xy.graph.IGraph;
import com.raytheon.uf.viz.xy.timeheight.display.TimeHeightDescriptor; import com.raytheon.uf.viz.xy.timeheight.display.TimeHeightDescriptor;
import com.raytheon.uf.viz.xy.timeheight.display.TimeHeightDescriptor.TimeDirection; import com.raytheon.uf.viz.xy.timeheight.display.TimeHeightDescriptor.TimeDirection;
import com.raytheon.uf.viz.xy.varheight.adapter.AbstractVarHeightAdapter; import com.raytheon.uf.viz.xy.varheight.adapter.AbstractVarHeightAdapter;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable; import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
import com.raytheon.viz.core.graphing.xy.XYData; import com.raytheon.viz.core.graphing.xy.XYData;
import com.raytheon.viz.core.graphing.xy.XYWindImageData; import com.raytheon.viz.core.graphing.xy.XYWindImageData;
@ -64,13 +64,14 @@ import com.vividsolutions.jts.geom.Coordinate;
* *
* <pre> * <pre>
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Dec 4, 2007 njensen Initial creation * Dec 04, 2007 njensen Initial creation
* Feb 20, 2009 njensen Refactored to new rsc architecture * Feb 20, 2009 njensen Refactored to new rsc architecture
* Feb 14, 2011 8244 bkowal enabled the magnification capability. * Feb 14, 2011 8244 bkowal enabled the magnification capability.
* Get graph in loadInterpolatedData after * Get graph in loadInterpolatedData after
* we ensure that it is not NULL. * we ensure that it is not NULL.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -83,12 +84,11 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(TimeHeightVectorResource.class); .getHandler(TimeHeightVectorResource.class);
/* Unknown source, provides acceptable density. */
private static final int VECTOR_SPACING = 60;
private float[] vInterpolatedData; private float[] vInterpolatedData;
private ArrowPreferences arrowPrefs;
private int imageSize;
private Map<Coordinate, IImage> imageMap = new HashMap<Coordinate, IImage>(); private Map<Coordinate, IImage> imageMap = new HashMap<Coordinate, IImage>();
public TimeHeightVectorResource(TimeHeightResourceData data, public TimeHeightVectorResource(TimeHeightResourceData data,
@ -109,7 +109,7 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
e.printStackTrace(); e.printStackTrace();
} }
if (sr != null) { if (sr != null) {
prefs = arrowPrefs = (ArrowPreferences) sr.getPreferences(); prefs = sr.getPreferences();
} }
this.getResourceData().addChangeListener(this); this.getResourceData().addChangeListener(this);
getCapability(DisplayTypeCapability.class).setAlternativeDisplayTypes( getCapability(DisplayTypeCapability.class).setAlternativeDisplayTypes(
@ -160,7 +160,6 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
List<XYData> vList = new ArrayList<XYData>(dataList.size()); List<XYData> vList = new ArrayList<XYData>(dataList.size());
for (XYData xyData : dataList) { for (XYData xyData : dataList) {
XYWindImageData windData = (XYWindImageData) xyData; XYWindImageData windData = (XYWindImageData) xyData;
imageSize = windData.getDefaultSize()[0];
double dir = windData.getWindDir(); double dir = windData.getWindDir();
double spd = windData.getWindSpd(); double spd = windData.getWindSpd();
dir = Math.toRadians(dir); dir = Math.toRadians(dir);
@ -216,11 +215,6 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
double density = getCapability(DensityCapability.class).getDensity(); double density = getCapability(DensityCapability.class).getDensity();
RGB color = getCapability(ColorableCapability.class).getColor(); RGB color = getCapability(ColorableCapability.class).getColor();
int scaledSize = (int) (this.imageSize * magnification);
VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(
this.descriptor, target, this.imageSize, 1.0f);
IExtent graphArea = descriptor.getGraph(this).getExtent(); IExtent graphArea = descriptor.getGraph(this).getExtent();
if (graphArea == null) { if (graphArea == null) {
return; return;
@ -234,11 +228,16 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
imagePaintProperties.setAlpha(1.0f); imagePaintProperties.setAlpha(1.0f);
double ratio = paintProps.getView().getExtent().getWidth() double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width; / paintProps.getCanvasBounds().width;
int spacing = (int) ((geometry.getGridRange2D().getMaxX() * imageSize int spacing = (int) ((geometry.getGridRange2D().getMaxX()
* .75 * ratio / Math.min(2.0, density)) * VECTOR_SPACING * ratio / Math.min(2.0, density))
/ paintProps.getCanvasBounds().width + 1); / paintProps.getCanvasBounds().width + 1);
IExtent viewableArea = paintProps.getView().getExtent() IExtent viewableArea = paintProps.getView().getExtent()
.intersection(graphArea); .intersection(graphArea);
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setSizeScaler(magnification * ratio);
VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(
this.descriptor, target, config);
for (int i = spacing / 2; i < geometry.getGridRange2D().getMaxX(); i += spacing) { for (int i = spacing / 2; i < geometry.getGridRange2D().getMaxX(); i += spacing) {
for (int j = spacing / 2; j < geometry.getGridRange2D().getMaxY(); j += spacing) { for (int j = spacing / 2; j < geometry.getGridRange2D().getMaxY(); j += spacing) {
double screenX = graphArea.getMinX() + (i + 0.5) * width; double screenX = graphArea.getMinX() + (i + 0.5) * width;
@ -258,12 +257,11 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
double spd = Math.hypot(uudd, vvff); double spd = Math.hypot(uudd, vvff);
double dir = Math.atan2(-uudd, -vvff); double dir = Math.atan2(-uudd, -vvff);
Coordinate plotLoc = new Coordinate(screenX, screenY); Coordinate plotLoc = new Coordinate(screenX, screenY);
double adjSize = scaledSize * ratio;
if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) { if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) {
vgr.paintArrow(plotLoc, adjSize, spd, dir); vgr.paintArrow(plotLoc, spd, dir);
} else { } else {
vgr.paintBarb(plotLoc, adjSize, spd, dir); vgr.paintBarb(plotLoc, spd, dir);
} }
} }
} }

View file

@ -57,6 +57,7 @@ import com.raytheon.uf.viz.xy.map.rsc.IInsetMapResource;
import com.raytheon.uf.viz.xy.map.rsc.PointRenderable; import com.raytheon.uf.viz.xy.map.rsc.PointRenderable;
import com.raytheon.uf.viz.xy.varheight.adapter.AbstractVarHeightAdapter; import com.raytheon.uf.viz.xy.varheight.adapter.AbstractVarHeightAdapter;
import com.raytheon.uf.viz.xy.varheight.display.VarHeightDescriptor; import com.raytheon.uf.viz.xy.varheight.display.VarHeightDescriptor;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable; import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
import com.raytheon.viz.core.graphing.util.GraphPrefsFactory; import com.raytheon.viz.core.graphing.util.GraphPrefsFactory;
import com.raytheon.viz.core.graphing.xy.XYData; import com.raytheon.viz.core.graphing.xy.XYData;
@ -75,10 +76,12 @@ import com.vividsolutions.jts.geom.Geometry;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Nov 23, 2009 mschenke Initial creation * Nov 23, 2009 mschenke Initial creation
* Feb 10, 2011 8344 bkowal enabled the magnification capability. * Feb 10, 2011 8344 bkowal enabled the magnification capability.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* *
* </pre> * </pre>
* *
@ -109,8 +112,6 @@ public class VarHeightResource extends
protected DataTime currentTime = null; protected DataTime currentTime = null;
private double imageSize = XYWindImageData.IMAGE_SIZE;
protected VarHeightResource(VarHeightResourceData resourceData, protected VarHeightResource(VarHeightResourceData resourceData,
LoadProperties loadProperties, AbstractVarHeightAdapter<?> adapter) LoadProperties loadProperties, AbstractVarHeightAdapter<?> adapter)
throws VizException { throws VizException {
@ -319,9 +320,14 @@ public class VarHeightResource extends
descriptor.getGraph(this).setCurrentMagnification(magnification); descriptor.getGraph(this).setCurrentMagnification(magnification);
target.setupClippingPlane(descriptor.getGraph(this).getExtent()); target.setupClippingPlane(descriptor.getGraph(this).getExtent());
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
// build the renderable // build the renderable
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setSizeScaler(magnification * ratio);
VectorGraphicsRenderable vgr = new VectorGraphicsRenderable( VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(
this.descriptor, target, this.imageSize, 1.0f); this.descriptor, target, config);
for (int i = 0; i < data.size(); i++) { for (int i = 0; i < data.size(); i++) {
XYData d = data.get(i); XYData d = data.get(i);
double x = ((Number) d.getX()).doubleValue(); double x = ((Number) d.getX()).doubleValue();
@ -332,8 +338,6 @@ public class VarHeightResource extends
double screenX = screenLoc[0]; double screenX = screenLoc[0];
double screenY = screenLoc[1]; double screenY = screenLoc[1];
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
IExtent graphExtent = descriptor.getGraph(this).getExtent(); IExtent graphExtent = descriptor.getGraph(this).getExtent();
@ -349,8 +353,7 @@ public class VarHeightResource extends
} }
if (withinBounds) { if (withinBounds) {
double adjSize = (this.imageSize * magnification) * ratio; vgr.paintBarb(plotLoc, dd.getWindSpd(),
vgr.paintBarb(plotLoc, adjSize, dd.getWindSpd(),
dd.getWindDir() * DEGREE_TO_RADIAN); dd.getWindDir() * DEGREE_TO_RADIAN);
vgr.setColor(color); vgr.setColor(color);
vgr.setLineWidth(getCapability(OutlineCapability.class) vgr.setLineWidth(getCapability(OutlineCapability.class)

View file

@ -53,15 +53,17 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation * Apr 23, 2010 bsteffen Initial creation
* Aug 07, 2013 2077 bsteffen Revise pixel size calculations. * Aug 07, 2013 2077 bsteffen Revise pixel size calculations.
* Aug 27, 2013 2287 randerso Replaced hard coded constant with densityFactor * Aug 27, 2013 2287 randerso Replaced hard coded constant with
* parameter to allow application specific density * densityFactor parameter to allow
* scaling to better match A1 displays * application specific density scaling to
* Sep 10, 2013 DR 16257 MPorricelli Fix so that wind for global grids displays on * better match A1 displays
* mercator maps. * Sep 10, 2013 16257 MPorricelli Fix so that wind for global grids displays on
* mercator maps.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -106,7 +108,7 @@ public abstract class AbstractGriddedDisplay<T> implements IRenderable {
protected IGraphicsTarget target; protected IGraphicsTarget target;
protected final int size; protected final double size;
protected final double densityFactor; protected final double densityFactor;
@ -131,7 +133,7 @@ public abstract class AbstractGriddedDisplay<T> implements IRenderable {
* adjustment factor to make density match A1 * adjustment factor to make density match A1
*/ */
public AbstractGriddedDisplay(IMapDescriptor descriptor, public AbstractGriddedDisplay(IMapDescriptor descriptor,
GeneralGridGeometry gridGeometryOfGrid, int size, GeneralGridGeometry gridGeometryOfGrid, double size,
double densityFactor) { double densityFactor) {
this.calculationQueue = new ConcurrentLinkedQueue<Coordinate>(); this.calculationQueue = new ConcurrentLinkedQueue<Coordinate>();

View file

@ -34,7 +34,7 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.rsc.DisplayType; import com.raytheon.uf.viz.core.rsc.DisplayType;
import com.raytheon.viz.core.contours.util.IVectorGraphicsRenderableFactory; import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable; import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
@ -49,22 +49,24 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jun 22, 2010 bsteffen Initial creation * Jun 22, 2010 bsteffen Initial creation
* Feb 07, 2011 7948 bkowal added a public method to get * Feb 07, 2011 7948 bkowal added a public method to get the
* the direction. * direction.
* Aug 27, 2013 2287 randerso Added VectorGraphicsRenderable Factory to allow * Aug 27, 2013 2287 randerso Added VectorGraphicsRenderable Factory to
* application specific rendering of wind barbs and * allow application specific rendering of
* arrows. * wind barbs and arrows. Added
* Added densityFactor to allow application specific * densityFactor to allow application
* adjustment of density. * specific adjustment of density. Added
* Added gridRelative flag to indicate whether direction * gridRelative flag to indicate whether
* data is relative to grid or true north * direction data is relative to grid or
* Sep 9, 2013 DR16257 MPorricelli When setDestinationGeographicPoint fails (which can * true north
* happen for global lat/lon grid winds displayed on * Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails (which can
* Equidistant Cylindrical map) try again with different * happen for global lat/lon grid winds displayed on
* pixel location. * Equidistant Cylindrical map) try again with different
* pixel location.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -83,6 +85,8 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private IExtent lastExtent; private IExtent lastExtent;
private VectorGraphicsConfig vectorConfig;
private VectorGraphicsRenderable vectorRenderable; private VectorGraphicsRenderable vectorRenderable;
private boolean gridRelative; private boolean gridRelative;
@ -91,8 +95,6 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private GeodeticCalculator gc; private GeodeticCalculator gc;
private IVectorGraphicsRenderableFactory factory;
/** /**
* @param magnitude * @param magnitude
* @param direction * @param direction
@ -109,15 +111,16 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
*/ */
public GriddedVectorDisplay(FloatBuffer magnitude, FloatBuffer direction, public GriddedVectorDisplay(FloatBuffer magnitude, FloatBuffer direction,
IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid, IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid,
int size, double densityFactor, boolean gridRelative, double densityFactor, boolean gridRelative,
DisplayType displayType, IVectorGraphicsRenderableFactory factory) { DisplayType displayType, VectorGraphicsConfig config) {
super(descriptor, gridGeometryOfGrid, size, densityFactor); super(descriptor, gridGeometryOfGrid, config.getBaseSize(),
densityFactor);
this.magnitude = magnitude; this.magnitude = magnitude;
this.direction = direction; this.direction = direction;
this.gridRelative = gridRelative; this.gridRelative = gridRelative;
this.displayType = displayType; this.displayType = displayType;
this.gc = new GeodeticCalculator(descriptor.getCRS()); this.gc = new GeodeticCalculator(descriptor.getCRS());
this.factory = factory; this.vectorConfig = config;
} }
@Override @Override
@ -129,8 +132,8 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
lastExtent = paintProps.getView().getExtent().clone(); lastExtent = paintProps.getView().getExtent().clone();
} }
if (vectorRenderable == null) { if (vectorRenderable == null) {
vectorRenderable = factory.createRenderable(descriptor, target, vectorRenderable = new VectorGraphicsRenderable(descriptor,
this.size); target, vectorConfig);
super.paint(target, paintProps); super.paint(target, paintProps);
} }
vectorRenderable.setColor(this.color); vectorRenderable.setColor(this.color);
@ -207,15 +210,16 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
} }
dir = (float) Math.toRadians(dir); dir = (float) Math.toRadians(dir);
vectorConfig.setSizeScaler(adjSize / size);
switch (displayType) { switch (displayType) {
case ARROW: case ARROW:
vectorRenderable.paintArrow(plotLoc, adjSize, spd, dir); vectorRenderable.paintArrow(plotLoc, spd, dir);
break; break;
case BARB: case BARB:
vectorRenderable.paintBarb(plotLoc, adjSize, spd, dir); vectorRenderable.paintBarb(plotLoc, spd, dir);
break; break;
case DUALARROW: case DUALARROW:
vectorRenderable.paintDualArrow(plotLoc, adjSize, spd, dir); vectorRenderable.paintDualArrow(plotLoc, spd, dir);
break; break;
default: default:
throw new VizException("Unsupported disply type: " + displayType); throw new VizException("Unsupported disply type: " + displayType);

View file

@ -0,0 +1,612 @@
/**
* 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.core.contours.util;
import com.vividsolutions.jts.geom.Coordinate;
/**
*
* Configuration options to control how vectors are rendered when using
* {@link VectorGraphicsRenderable}. These config options are applied
* immediately when you call
* {@link VectorGraphicsRenderable#paintBarb(Coordinate, double, double)},
* {@link VectorGraphicsRenderable#paintArrow(Coordinate, double, double)}, or
* {@link VectorGraphicsRenderable#paintDualArrow(Coordinate, double, double)}.
* This means that multiple vectors can be rendered with different styles using
* the same renderable. For example the following snippet will render two barbs,
* one with clockwise barbs and one with counterclockwise barbs using the same
* renderable.
*
* <pre>
* {
* &#064;code
* VectorGraphicsRenderable renderable = new VectorGraphicsRenderable(
* descriptor, target);
* renderable.getConfig().setBarbRotationClockwise();
* renderable.paintBarb(location1, magnitude1, direction1);
* renderable.getConfig().setBarbRotationCounterClockwise();
* renderable.paintBarb(location2, magnitude2, direction2);
* renderable.paint(target);
* }
* </pre>
*
* This class contains configuration for wind barbs, arrows, and calm circles.
* The barb options apply only when paintBarb is used. The arrow options apply
* to both paintArrow and paintDualArrow. The calm circles options apply to both
* paintBarb and paintArrow.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Sep 23, 2013 2363 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
* @See {@link VectorGraphicsRenderable}
*/
public class VectorGraphicsConfig {
/**
* Interface for providing complex arrow scaling algorithms. For most simple
* parameters linear scaling works well enough, however some data is easier
* to understand by using complex logarithmic scaling.
*/
public static interface IArrowScaler {
/**
* This method should calculate the length of an arrow(in pixels) for a
* single vector.
*
* @param magnitude
* the magnitude of a single vector.
* @return the length of the arrow(in pixels).
*/
public double scale(double magnitude);
}
/**
* Simple linear scaling for arrows that multiplies the magnitude by a
* constant scaleFactor.
*/
public static class LinearArrowScaler implements IArrowScaler {
protected final double scaleFactor;
public LinearArrowScaler(double scaleFactor) {
this.scaleFactor = scaleFactor;
}
@Override
public double scale(double magnitude) {
return magnitude * scaleFactor;
}
}
protected double baseSize;
protected double sizeScaler;
protected double offsetRatio;
protected double minimumMagnitude;
protected double barbRotationRadians;
protected double barbLengthRatio;
protected double barbSpacingRatio;
protected boolean barbFillFiftyTriangle;
protected double calmCircleMaximumMagnitude;
protected double calmCircleSizeRatio;
protected double arrowHeadSizeRatio;
protected double arrowHeadStaffRatio;
protected IArrowScaler arrowScaler;
/**
* Creates a new config with <em>reasonable</em> defalt values
*/
public VectorGraphicsConfig() {
setBaseSize(32.0);
setOffsetRatio(0.0);
setMinimumMagnitude(2.5);
setBarbRotationDegrees(75);
setBarbLengthRatio(0.3);
setBarbSpacingRatio(0.105);
setBarbFillFiftyTriangle(false);
setCalmCircleMaximumMagnitude(2.5);
setCalmCircleSizeRatio(0.075);
setArrowHeadSizeRatio(0.1875);
setLinearArrowScaleFactor(1.0);
}
/**
* Construct a new instance with all fields copied from the other object.
*
* @param other
* an existing config to copy.
*/
public VectorGraphicsConfig(VectorGraphicsConfig other) {
this.baseSize = other.baseSize;
this.sizeScaler = other.sizeScaler;
this.offsetRatio = other.offsetRatio;
this.minimumMagnitude = other.minimumMagnitude;
this.barbRotationRadians = other.barbRotationRadians;
this.barbLengthRatio = other.barbLengthRatio;
this.barbSpacingRatio = other.barbSpacingRatio;
this.barbFillFiftyTriangle = other.barbFillFiftyTriangle;
this.calmCircleMaximumMagnitude = other.calmCircleMaximumMagnitude;
this.calmCircleSizeRatio = other.calmCircleSizeRatio;
this.arrowHeadSizeRatio = other.arrowHeadSizeRatio;
this.arrowHeadStaffRatio = other.arrowHeadStaffRatio;
this.arrowScaler = other.arrowScaler;
}
/**
* Set the base size. Base size combined with size scaler is used for barb
* length and as the base measurement for all ratios when rendering wind
* barbs or arrows.
*
* @param size
* the base size of the barb in descriptor grid pixels
* @see #setSizeScaler(double)
* @see #getScaledSize()
*/
public void setBaseSize(double size) {
this.baseSize = size;
}
/**
* Set the linear size scaler. All rendered lines are linearly scaled by
* this constant. This is used for implementing magnification and/or scaling
* the descriptor grid into screen pixels. Scale factor should by a positive
* value. A value of 1.0 is a no-op and all lines will be the default size.
* Values less than 1 will shrink the lines and values greater than 1 cause
* them to grow. Although the same renderings could be achieved by
* manipulating base size directly, using the size scaler provides a
* convenient way to have a fixed base size that needs to be frequently
* modified by a changing scale factor.
*
* @param sizeScaler
* a factor to scale baseSize.
* @see #setBaseSize(double)
* @see #getScaledSize()
*/
public void setSizeScaler(double sizeScaler) {
this.sizeScaler = sizeScaler;
}
/**
* Set a ratio describing the distance from the plot location that a barb or
* arrow will be rendered relative to scaled size. This value will be
* multiplied by the scaled size do determine the actual offset distance.
* For most applications a value between 0 and 1 is reasonable. A negative
* value will cause the barb to overlap the plot location rather than
* extending from the plot location. Using excessively large values will
* cause the barb to be very far away from the plot location and is not
* advised. This offset can be used to leave space for other symbols that
* are being rendered at plot location.
*
* @param offsetRatio
* distance from plot location to start rendering.
* @see #getScaledSize()
*/
public void setOffsetRatio(double offsetRatio) {
this.offsetRatio = offsetRatio;
}
/**
* Set a minimum magnitude for rendering. Any calls to
* {@link VectorGraphicsRenderable} that paint a vector with magnitude less
* than this value will not be rendered. A calm circle will still be
* rendered if the value is less than the calm circle maximum magnitude.
*
* @param minimumMagnitude
* the minimum magnitude that will be rendered.
* @see #setCalmCircleMaximumMagnitude(double)
* @see #alwaysIncludeVector()
*/
public void setMinimumMagnitude(double minimumMagnitude) {
this.minimumMagnitude = minimumMagnitude;
}
/**
* Shortcut method to set this configuration to always draw vectors
* regardless of the magnitude. This is equivalent to
* <code>setMinimumMagnitude(0.0)</code>
*/
public void alwaysIncludeVector() {
setMinimumMagnitude(0.0);
}
/**
* Set the rotation in radians of the barbs from the shaft.
*
* @param barbRotationRadians
* rotation in radians.
*/
public void setBarbRotationRadians(double barbRotationRadians) {
this.barbRotationRadians = barbRotationRadians;
}
/**
* Set the rotation in degrees of the barbs from the shaft. Internally it
* will be converted to radians. This is equivalent to
* <code>setBarbRotationRadians(Math.toRadians(barbRotationDegrees))</code>
*
* @param barbRotationDegrees
* rotation in degrees.
* @see #setBarbRotationRadians(double)
*/
public void setBarbRotationDegrees(double barbRotationDegrees) {
setBarbRotationRadians(Math.toRadians(barbRotationDegrees));
}
/**
* Shortcut method to set the barb rotation angle so that barbs are
* clockwise. Since any positive angle will be clockwise this simply sets
* the rotation to the absolute value of its current value. The same result
* can be achieved by using #setBarbRotationRadians(double) directly.
*
* @see #setBarbRotationRadians(double)
*/
public void setBarbRotationClockwise() {
setBarbRotationRadians(Math.abs(barbRotationRadians));
}
/**
* Shortcut method to set the barb rotation angle so that barbs are counter
* clockwise. Since any negative angle will be counter clockwise this simply
* sets the rotation to the negative absolute value of its current value.
* The same result can be achieved by using #setBarbRotationRadians(double)
* directly.
*
* @see #setBarbRotationRadians(double)
*/
public void setBarbRotationCounterClockwise() {
setBarbRotationRadians(-1 * Math.abs(barbRotationRadians));
}
/**
* Set a ratio describing the length of the barb relative to scaled size.
* This should be a value between 0 and 1 and will be multiplied by the
* scaled size do determine the actual barb length. The half barb will
* always be half of this distance. Values too close to 0 will be difficult
* to see and values too close to 1 will make it hard to distinguish the
* barb from the shaft.
*
* @param barbLengthRatio
* length of the barbs
* @see #getScaledSize()
*/
public void setBarbLengthRatio(double barbLengthRatio) {
if (barbLengthRatio <= 0 || barbLengthRatio >= 1) {
throw new IllegalArgumentException(
"Barb length Ratio must be between 0 and 1");
}
this.barbLengthRatio = barbLengthRatio;
}
/**
* Set a ratio describing the distance between barbs along the shaft
* relative to the scaled size. This should be a value between 0 and 1 and
* will be multiplied by the scaled size do determine the actual barb
* spacing. In practice this value should be much smaller than 1 so that
* high wind speeds will fit.
*
* @param barbSpacingRatio
* distance between barbs along the shaft
* @see #getScaledSize()
*/
public void setBarbSpacingRatio(double barbSpacingRatio) {
if (barbSpacingRatio <= 0 || barbSpacingRatio >= 1) {
throw new IllegalArgumentException(
"Barb Spacing Ratio must be between 0 and 1");
}
this.barbSpacingRatio = barbSpacingRatio;
}
/**
* Boolean value to indicate if winds over fifty should use a filled
* triangle or just an outline.
*
* @param barbFillFiftyTriangle
* true to render a filled triangle, false to render an outline
* only.
* @see #setBarbFillFiftyTriangle();
* @see #setBarbOutlineFiftyTriangle();
*/
public void setBarbFillFiftyTriangle(boolean barbFillFiftyTriangle) {
this.barbFillFiftyTriangle = barbFillFiftyTriangle;
}
/**
* Set the maximum magnitude for which to draw a calm circle. If this value
* is the same as minimum magnitude then for each paintArrow or paintBarb
* method either a vector or calm circle will be drawn. If this is larger
* than minimum magnitude then some or all vectors will contain both an
* arrow/barb and a calm circle and if it is smaller than minimum magnitude
* than some vectors might not be drawn at all.
*
* @param calmCircleMaximumMagnitude
* the maximum vector magnitude for which calm circles should be
* rendered.
* @see #setMinimumMagnitude(double)
* @see #disableCalmCircle()
* @see #alwaysIncludeCalmCircle()
*/
public void setCalmCircleMaximumMagnitude(double calmCircleMaximumMagnitude) {
this.calmCircleMaximumMagnitude = calmCircleMaximumMagnitude;
}
/**
* Shortcut method to disable drawing calm circles. This is equivalent to
* <code>setCalmCircleMaximumMagnitude(0.0)</code>
*
* @see #setCalmCircleMaximumMagnitude(double)
*/
public void disableCalmCircle() {
setCalmCircleMaximumMagnitude(0.0);
}
/**
* Shortcut method to alwaysthe vector is painted the size scaler is used to
* change the size of all elements of the vector by draw calm circles
* regardless of the magnitude. This is equivalent to
* <code>setCalmCircleMaximumMagnitude(Double.POSITIVE_INFINITY)</code>
*
* @see #setCalmCircleMaximumMagnitude(double)
*/
public void alwaysIncludeCalmCircle() {
setCalmCircleMaximumMagnitude(Double.POSITIVE_INFINITY);
}
/**
* Set a ratio describing the size of the calm circle relative to scaled
* size. This should be positive number and will be multiplied by the scaled
* size do determine the actual calm circle size. Usually the calm circle is
* significantly smaller than the wind barb so the value should be
* significantly less than 1.
*
* @param calmCircleSizeRatio
* size of the calm circle.
* @see #getScaledSize()
*/
public void setCalmCircleSizeRatio(double calmCircleSizeRatio) {
if (calmCircleSizeRatio <= 0) {
throw new IllegalArgumentException(
"Calm circle size ratio must be a positive value");
}
this.calmCircleSizeRatio = calmCircleSizeRatio;
}
/**
* Set a ratio describing the size of an arrow head relative to scaled size.
* This should be a value between 0 and 1 and will be multiplied by the
* scaled size do determine the actual arrow head size. This can be used for
* constant size arrow heads, if the arrow head should change size when
* magnitude changes #setArrowHeadStaffRatio(double) should be used instead.
*
* @param arrowHeadSizeRatio
* size of the arrow head.
* @see #getScaledSize()
* @see #setArrowHeadStaffRatio(double)
*/
public void setArrowHeadSizeRatio(double arrowHeadSizeRatio) {
if (arrowHeadSizeRatio <= 0 || arrowHeadSizeRatio >= 1) {
throw new IllegalArgumentException(
"Arrow Head Size Ratio must be between 0 and 1");
}
this.arrowHeadSizeRatio = arrowHeadSizeRatio;
this.arrowHeadStaffRatio = 0.0;
}
/**
* Set a ratio describing the size of an arrow head relative to the scaled
* length of the arrow staff. This should be a value between 0 and 1 and
* will be multiplied by the scaled staff size do determine the actual arrow
* head size. This can be used to render arrow heads with a size dependent
* on the magnitude, if the arrow head should be constant size then
* #setArrowHeadSizeRatio(double) should be used instead.
*
* @param arrowHeadSizeRatio
* size of the arrow head.
* @see #getScaledSize()
* @see #setArrowHeadSizeRatio(double)
*/
public void setArrowHeadStaffRatio(double arrowHeadStaffRatio) {
if (arrowHeadSizeRatio <= 0 || arrowHeadSizeRatio >= 1) {
throw new IllegalArgumentException(
"Arrow Head Staff Ratio must be between 0 and 1");
}
this.arrowHeadStaffRatio = arrowHeadStaffRatio;
this.arrowHeadSizeRatio = 0.0;
}
/**
* Set a custom arrow scaling algorithm for rendering arrows. After custom
* scaling is applied the size scaler will also be used to further scale the
* arrow.
*
* @param arrowScaler
* custom scaling algorithm
* @see IArrowScaler
* @see #setSizeScaler(double)
*/
public void setArrowScaler(IArrowScaler arrowScaler) {
this.arrowScaler = arrowScaler;
}
/**
* Shortcut method to set the arrow scaler to a {@link LinearArrowScaler}.
* This is equivalent to
* <code>setArrowScaler(new LinearArrowScaler(scaleFactor))</code>
*
* @param scaleFactor
* linear scale factor for arrow sizing.
*/
public void setLinearArrowScaleFactor(double scaleFactor) {
setArrowScaler(new LinearArrowScaler(scaleFactor));
}
/**
* @return the base size in descriptor pixels
* @see #setBaseSize(double)
*/
public double getBaseSize() {
return baseSize;
}
/**
* @return the size scaler
* @see #setSizeScaler(double)
* @see #getScaledSize()
*/
public double getSizeScaler() {
return sizeScaler;
}
/**
* Get the scaled size. This is the baseSize multiplied by the size scaler.
* When a barb is painted this will be the length of the shaft. All size
* ratios are multiplied by this value to get the actual size of the
* rendered lines in descriptor pixels.
*
* @return the scaled size.
* @see #setBaseSize(double)
* @see #setSizeScaler(double)
*/
public double getScaledSize() {
return baseSize * sizeScaler;
}
/**
* @return the offset ratio
* @see #setOffsetRatio(double)
*/
public double getOffsetRatio() {
return offsetRatio;
}
/**
* @return the minimum magnitude
* @see #setMinimumMagnitude(double)
*/
public double getMinimumMagnitude() {
return minimumMagnitude;
}
/**
* @return the barb rotation angle in radians.
* @see #setBarbRotationRadians(double)
*/
public double getBarbRotationRadians() {
return barbRotationRadians;
}
/**
* @return the barb rotation angle in degrees.
* @see #setBarbRotationDegrees(double)
*/
public double getBarbRotationDegrees() {
return Math.toDegrees(barbRotationRadians);
}
/**
* @return the barb length ratio
* @see #setBarbLengthRatio(double)
*/
public double getBarbLengthRatio() {
return barbLengthRatio;
}
/**
* @return the barb spacing ratio
* @see #setBarbSpacingRatio(double)
*/
public double getBarbSpacingRatio() {
return barbSpacingRatio;
}
/**
* @return the barbFillFiftyTriangle
* @see #setBarbFillFiftyTriangle()
*/
public boolean isBarbFillFiftyTriangle() {
return barbFillFiftyTriangle;
}
/**
* @return the calmCircleMaximumMagnitude
* @see #setCalmCircleMaximumMagnitude(double)
*/
public double getCalmCircleMaximumMagnitude() {
return calmCircleMaximumMagnitude;
}
/**
* @return the calmCircleSizeRatio
* @see #setCalmCircleSizeRatio(double)
*/
public double getCalmCircleSizeRatio() {
return calmCircleSizeRatio;
}
/**
* @return the arrowHeadSizeRatio
* @see #setArrowHeadSizeRatio(double)
*/
public double getArrowHeadSizeRatio() {
return arrowHeadSizeRatio;
}
/**
* @return the arrowHeadStaffRatio
* @see #setArrowHeadStaffRatio(double)
*/
public double getArrowHeadStaffRatio() {
return arrowHeadStaffRatio;
}
/**
* @return the arrowScaler
* @see #setArrowScaler(IArrowScaler)
*/
public IArrowScaler getArrowScaler() {
return arrowScaler;
}
@Override
public VectorGraphicsConfig clone() {
return new VectorGraphicsConfig(this);
}
}

View file

@ -19,94 +19,226 @@
**/ **/
package com.raytheon.viz.core.contours.util; package com.raytheon.viz.core.contours.util;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IShadedShape;
import com.raytheon.uf.viz.core.drawables.IWireframeShape; import com.raytheon.uf.viz.core.drawables.IWireframeShape;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormapShadedShapeExtension;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormapShadedShapeExtension.IColormapShadedShape;
import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.exception.VizException;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
/** /**
* *
* TODO Add Description * Class for bulk rendering vectors efficiently using {@link IWireframeShape}
* and {@link IShadedShape}. All dimensions of rendered objects can be
* controlled using a {@link VectorGraphicsConfig}. Several additional style
* attributes can be set within this class to control the rendering in the
* {@link #paint(IGraphicsTarget)} method.
*
* Data is rendered by using one or more of the three paint vector methods:
* {@link #paintArrow(Coordinate, double, double)},
* {@link #paintBarb(Coordinate, double, double)}, and
* {@link #paintDualArrow(Coordinate, double, double)}. These methods do not
* actually draw the data to the screen, the add the vector to the internal
* structure that can be painted with {@link #paint(IGraphicsTarget)}.
*
* *
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* May 27, 2011 bsteffen Initial creation * May 27, 2011 bsteffen Initial creation
* Aug 27, 2013 #2287 randerso Refactored to allow subclassing * Aug 27, 2013 2287 randerso Refactored to allow subclassing
* Sep 23, 2013 2363 bsteffen Add more configuration options.
* *
* </pre> * </pre>
* *
* @author bsteffen * @author bsteffen
* @version 1.0 * @version 1.0
* @see VectorGraphicsConfig
*/ */
public class VectorGraphicsRenderable { public class VectorGraphicsRenderable {
protected IWireframeShape lastShape; protected final IWireframeShape lineShape;
protected double size = 80; protected final IColormapShadedShape filledShape;
protected double scale = 1.0;
protected RGB color; protected RGB color;
protected float lineWidth = 1.0f; protected float lineWidth = 1.0f;
protected LineStyle lineStyle; protected LineStyle lineStyle = LineStyle.DEFAULT;
protected RGB blankColor = null;
protected float blankWidthRatio = 10.0f;
protected VectorGraphicsConfig config;
public VectorGraphicsRenderable(IDescriptor descriptor, public VectorGraphicsRenderable(IDescriptor descriptor,
IGraphicsTarget target, double size, double scale) { IGraphicsTarget target) throws VizException {
this.lastShape = target.createWireframeShape(true, descriptor); this(descriptor, target, new VectorGraphicsConfig());
this.size = size;
this.scale = scale;
} }
public VectorGraphicsRenderable(IDescriptor descriptor,
IGraphicsTarget target, VectorGraphicsConfig config)
throws VizException {
this.lineShape = target.createWireframeShape(true, descriptor);
this.filledShape = target.getExtension(
IColormapShadedShapeExtension.class).createColormapShadedShape(
descriptor.getGridGeometry(), false);
this.config = config;
}
/**
* Set the color of the rendered vectors. This setting takes effect when
* {@link #paint(IGraphicsTarget)} is called and applies to all vectors.
*
* @param color
* the color.
*/
public void setColor(RGB color) { public void setColor(RGB color) {
this.color = color; this.color = color;
} }
/**
* Set the line width of the rendered vectors. This setting takes effect
* when {@link #paint(IGraphicsTarget)} is called and applies to all
* vectors.
*
* @param lineWidth
* the line width
*/
public void setLineWidth(float lineWidth) { public void setLineWidth(float lineWidth) {
this.lineWidth = lineWidth; this.lineWidth = lineWidth;
} }
/**
* Set the line style of the rendered vectors. This setting takes effect
* when {@link #paint(IGraphicsTarget)} is called and applies to all
* vectors.
*
* @param lineStyle
* the line style
*/
public void setLineStyle(LineStyle lineStyle) { public void setLineStyle(LineStyle lineStyle) {
this.lineStyle = lineStyle; this.lineStyle = lineStyle;
} }
/** /**
* Enable blanking with a reasonable width ratio of 10.
*
* @param color
* the blanking color
* @see #enableBlanking(RGB, float)
*/
public void enableBlanking(RGB color) {
enableBlanking(color, 10);
}
/**
* Enable blanking. Blanking will render an area of the specified color
* behind the barb to make it easier to see on cluttered dispaly. The size
* of the blanked area is controlled with blankLineWidthRatio.
*
* @param color
* the blanking color.
* @param blankLineWidthRatio
* the width of the line, the actual width is this value
* multiplied by lineWidth so wider vectors will have wider
* blanked areas.
*/
public void enableBlanking(RGB color,
float blankLineWidthRatio) {
this.blankColor = color;
this.blankWidthRatio = blankLineWidthRatio;
}
/**
* Turn off all blanking
*
* @see #enableBlanking(RGB, float)
*/
public void disableBlanking() {
this.blankColor = null;
}
/**
* Set the configuration for rendering vectors. The
* {@link VectorGraphicsConfig} controls all the dimensions of the lines of
* the rendered vectors. The configuration takes affect when
* {@link #paintArrow(Coordinate, double, double)},
* {@link #paintBarb(Coordinate, double, double)}, or
* {@link #paintDualArrow(Coordinate, double, double)} is called.
*
* @param config
* the configuration.
*/
public void setConfig(VectorGraphicsConfig config) {
this.config = config;
}
/**
* @return the current vector configuration
* @see #setConfig(VectorGraphicsConfig)
*/
public VectorGraphicsConfig getConfig() {
return config;
}
/**
* Add a wind barb to be painted. The direction is indicated by the
* orientation of the shaft and barbs are drawn to indicate speed. Wind
* speeds are always rounded to the nearest unit of 5, for example a
* magnitude of 18 will be rounded up to 20 and a magnitude of 17 will be
* rounded down to 15.
* *
* @param plotLoc * @param plotLoc
* @param adjSize * the location on the screen where the barb originates in
* @param spd * descriptor pixel space.
* @param dir * @param magnitude
* barb direction in radians * the magnitude of the barb, this is translated into barbs.
* @param direction
* the direction of the vector, this is used to orient the shaft.
* @see VectorGraphicsConfig
*/ */
public void paintBarb(Coordinate plotLoc, double adjSize, double spd, public void paintBarb(Coordinate plotLoc, double magnitude, double direction) {
double dir) { if (magnitude < config.getCalmCircleMaximumMagnitude()) {
if (spd < 2.5) { paintPoint(plotLoc);
paintPoint(plotLoc, adjSize); }
if (magnitude < config.getMinimumMagnitude()) {
return; return;
} }
int speed = (int) (spd + 2.5); /* adding 2.5 will round barbs to nearest 5 */
double staff = adjSize * .4; int speed = (int) (magnitude + 2.5);
double barb = staff * 0.30; double size = config.getScaledSize();
double add = staff * 0.105; double barb = size * config.getBarbLengthRatio();
double add = size * config.getBarbSpacingRatio();
// DIRECTIONS // DIRECTIONS
double uudd = -spd * Math.sin(dir); double uudd = -magnitude * Math.sin(direction);
double vvff = -spd * Math.cos(dir); double vvff = -magnitude * Math.cos(direction);
double dix = -uudd / spd; double dix = -uudd / magnitude;
double djy = -vvff / spd; double djy = -vvff / magnitude;
double dix1 = Math.cos(Math.toRadians(75)) * dix double barbRotationRadians = config.getBarbRotationRadians();
+ Math.sin(Math.toRadians(75)) * djy; double dix1 = Math.cos(barbRotationRadians) * dix
double djy1 = (-1) * Math.sin(Math.toRadians(75)) * dix + Math.sin(barbRotationRadians) * djy;
+ Math.cos(Math.toRadians(75)) * djy; double djy1 = (-1) * Math.sin(barbRotationRadians) * dix
+ Math.cos(barbRotationRadians) * djy;
// SPEED AND COUNTERS: // SPEED AND COUNTERS:
int n50 = speed / 50; int n50 = speed / 50;
@ -115,14 +247,14 @@ public class VectorGraphicsRenderable {
calcSpd = calcSpd - 10 * n10; calcSpd = calcSpd - 10 * n10;
int n5 = calcSpd / 5; int n5 = calcSpd / 5;
double sx = ((n50 + n50 + n10 + n5 + 2)) * add; double sx = ((n50 + n50 + n10 + n5 + 2)) * add;
staff = Math.max(adjSize * .4, sx); double staff = Math.max(size, sx);
// DRAW STAFF // DRAW STAFF
double ix2 = plotLoc.x; double ix2 = plotLoc.x + dix * size * config.getOffsetRatio();
double jy2 = plotLoc.y; double jy2 = plotLoc.y - djy * size * config.getOffsetRatio();
double ix1 = ix2 + dix * staff; double ix1 = ix2 + dix * staff;
double jy1 = jy2 - djy * staff; double jy1 = jy2 - djy * staff;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } }); lineShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } });
// PLOT LONE HALF-BARB, IF NECESSARY // PLOT LONE HALF-BARB, IF NECESSARY
if (n50 == 0 && n10 == 0) { if (n50 == 0 && n10 == 0) {
@ -130,7 +262,7 @@ public class VectorGraphicsRenderable {
jy2 = jy1 + djy * add; jy2 = jy1 + djy * add;
ix1 = ix2 + dix1 * barb / 2.0; ix1 = ix2 + dix1 * barb / 2.0;
jy1 = jy2 - djy1 * barb / 2.0; jy1 = jy2 - djy1 * barb / 2.0;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } }); { ix1, jy1 } });
return; return;
} }
@ -139,23 +271,30 @@ public class VectorGraphicsRenderable {
for (int i = 0; i < n50; i++) { for (int i = 0; i < n50; i++) {
ix2 = ix1 + dix1 * barb; ix2 = ix1 + dix1 * barb;
jy2 = jy1 - djy1 * barb; jy2 = jy1 - djy1 * barb;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, double ix3 = ix1 - dix * add * 2;
double jy3 = jy1 + djy * add * 2;
lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } }); { ix1, jy1 } });
lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix3, jy3 } });
if (config.isBarbFillFiftyTriangle()) {
double[] triangleRaw = { ix1, jy1, ix2, jy2, ix3, jy3 };
CoordinateSequence triangleSeq = new PackedCoordinateSequence.Double(
triangleRaw, 2);
LineString triangleLS = new GeometryFactory()
.createLineString(triangleSeq);
filledShape.addPolygonPixelSpace(
new LineString[] { triangleLS }, this);
}
ix1 = ix1 - dix * add * 2; ix1 = ix1 - dix * add * 2;
jy1 = jy1 + djy * 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 // PLOT BARB, IF NECESSARY
for (int i = 0; i < n10; i++) { for (int i = 0; i < n10; i++) {
ix2 = ix1 + dix1 * barb; ix2 = ix1 + dix1 * barb;
jy2 = jy1 - djy1 * barb; jy2 = jy1 - djy1 * barb;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } }); { ix1, jy1 } });
ix1 = ix1 - dix * add; ix1 = ix1 - dix * add;
jy1 = jy1 + djy * add; jy1 = jy1 + djy * add;
@ -165,16 +304,17 @@ public class VectorGraphicsRenderable {
if (n5 != 0) { if (n5 != 0) {
ix2 = ix1 + dix1 * barb / 2.0; ix2 = ix1 + dix1 * barb / 2.0;
jy2 = jy1 - djy1 * barb / 2.0; jy2 = jy1 - djy1 * barb / 2.0;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } }); { ix1, jy1 } });
} }
} }
protected void paintPoint(Coordinate plotLoc, double adjSize) { protected void paintPoint(Coordinate plotLoc) {
double[][] line = new double[9][2]; double[][] line = new double[9][2];
double aa = adjSize * .030; double aa = config.getScaledSize() * config.getCalmCircleSizeRatio();
double saa = aa * 0.707; double saa = aa * 0.7071067811865475;
line[8][0] = line[0][0] = plotLoc.x + aa; line[8][0] = line[0][0] = plotLoc.x + aa;
line[8][1] = line[0][1] = plotLoc.y; line[8][1] = line[0][1] = plotLoc.y;
@ -199,42 +339,46 @@ public class VectorGraphicsRenderable {
line[7][0] = plotLoc.x + saa; line[7][0] = plotLoc.x + saa;
line[7][1] = plotLoc.y - saa; line[7][1] = plotLoc.y - saa;
lastShape.addLineSegment(line); lineShape.addLineSegment(line);
} }
public void paintDualArrow(Coordinate plotLoc, double adjSize, double spd, /**
double dir) { * Add a dual arrow to be painted. This is an arrow that has half a head on
if (spd < 4.0) { * one end and the other half on the other end. It is used for deformation.
*
* @param plotLoc
* the location on the screen where the arrow originates in
* descriptor pixel space.
* @param magnitude
* the magnitude of the arrow, this is translated into the length
* of the arrow
* @param direction
* the direction of the vector, this is used to orient the staff.
* @see VectorGraphicsConfig
*/
public void paintDualArrow(Coordinate plotLoc, double magnitude,
double direction) {
if (magnitude < config.getMinimumMagnitude()) {
return; return;
} }
double staff = 0.0; double size = config.getScaledSize();
if (this.scale > 0.0) { double staff = config.getArrowScaler().scale(magnitude)
staff = spd * this.scale; * config.getSizeScaler();
} else { double barb = size * config.getArrowHeadSizeRatio()
staff = Math.log10(spd * -this.scale) * 10 + 10; + staff
} * config.getArrowHeadStaffRatio();
double barb = 4.0;
if (staff < barb) {
return;
}
double ratio = adjSize / size;
staff *= ratio;
barb *= ratio;
// DIRECTIONS // DIRECTIONS
double uudd = -spd * Math.sin(dir); double uudd = -magnitude * Math.sin(direction);
double vvff = -spd * Math.cos(dir); double vvff = -magnitude * Math.cos(direction);
double dix = uudd / spd; double dix = uudd / magnitude;
double djy = vvff / spd; double djy = vvff / magnitude;
double dix1 = -dix - djy; double dix1 = -dix - djy;
double djy1 = dix - djy; double djy1 = dix - djy;
// DRAW BODY OF ARROW // DRAW BODY OF ARROW
double ix2 = plotLoc.x; double ix2 = plotLoc.x + dix * size * config.getOffsetRatio();
double jy2 = plotLoc.y; double jy2 = plotLoc.y - djy * size * config.getOffsetRatio();
double ix1 = ix2 + dix * staff; double ix1 = ix2 + dix * staff;
double jy1 = jy2 - djy * staff; double jy1 = jy2 - djy * staff;
@ -242,38 +386,43 @@ public class VectorGraphicsRenderable {
double jy3 = jy1 - djy1 * barb; double jy3 = jy1 - djy1 * barb;
double ix4 = ix2 - dix1 * barb; double ix4 = ix2 - dix1 * barb;
double jy4 = jy2 + djy1 * barb; double jy4 = jy2 + djy1 * barb;
lastShape.addLineSegment(new double[][] { { ix4, jy4 }, { ix2, jy2 }, lineShape.addLineSegment(new double[][] { { ix4, jy4 }, { ix2, jy2 },
{ ix1, jy1 }, { ix3, jy3 } }); { ix1, jy1 }, { ix3, jy3 } });
} }
public void paintArrow(Coordinate plotLoc, double adjSize, double spd, /**
double dir) { * Add an arrow to be painted.
if (spd == 0.0) { *
* @param plotLoc
* the location on the screen where the arrow originates in
* descriptor pixel space.
* @param magnitude
* the magnitude of the arrow, this is translated into the length
* of the arrow
* @param direction
* the direction of the vector, this is used to orient the staff.
* @see VectorGraphicsConfig
*/
public void paintArrow(Coordinate plotLoc, double magnitude,
double direction) {
if (magnitude < config.getCalmCircleMaximumMagnitude()) {
paintPoint(plotLoc);
}
if (magnitude < config.getMinimumMagnitude()) {
return; return;
} }
double staff = 0.0; double size = config.getScaledSize();
if (this.scale > 0.0) { double staff = config.getArrowScaler().scale(magnitude)
staff = spd * this.scale; * config.getSizeScaler();
} else { double barb = size * config.getArrowHeadSizeRatio() + staff
staff = Math.log10(spd * -this.scale) * 10 + 10; * config.getArrowHeadStaffRatio();
}
double barb = 4.0;
if (staff < barb) {
return;
}
double ratio = adjSize / size;
staff *= ratio;
barb *= ratio;
// DIRECTIONS // DIRECTIONS
double uudd = -spd * Math.sin(dir); double uudd = -magnitude * Math.sin(direction);
double vvff = -spd * Math.cos(dir); double vvff = -magnitude * Math.cos(direction);
double dix = uudd / spd; double dix = uudd / magnitude;
double djy = vvff / spd; double djy = vvff / magnitude;
double dix1 = -dix - djy; double dix1 = -dix - djy;
double djy1 = dix - djy; double djy1 = dix - djy;
double dix2 = -dix + djy; double dix2 = -dix + djy;
@ -284,27 +433,48 @@ public class VectorGraphicsRenderable {
double jy2 = plotLoc.y; double jy2 = plotLoc.y;
double ix1 = ix2 + dix * staff; double ix1 = ix2 + dix * staff;
double jy1 = jy2 - djy * staff; double jy1 = jy2 - djy * staff;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } }); lineShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 } });
// DRAW HEAD OF ARROW. // DRAW HEAD OF ARROW.
ix2 = ix1 + dix1 * barb; ix2 = ix1 + dix1 * barb;
jy2 = jy1 - djy1 * barb; jy2 = jy1 - djy1 * barb;
double ix3 = ix1 + dix2 * barb; double ix3 = ix1 + dix2 * barb;
double jy3 = jy1 - djy2 * barb; double jy3 = jy1 - djy2 * barb;
lastShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 }, lineShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 },
{ ix3, jy3 } }); { ix3, jy3 } });
} }
/**
* Draw all the vectors to the screen.
*
* @param target
* a graphics target, this must be the same type of target that
* was available during construction.
*
* @throws VizException
* occurs when the target fails to render some shapes.
*/
public void paint(IGraphicsTarget target) throws VizException { public void paint(IGraphicsTarget target) throws VizException {
if (lastShape != null) { if (blankColor != null) {
target.drawWireframeShape(lastShape, color, lineWidth, lineStyle); target.drawWireframeShape(lineShape, blankColor, lineWidth
* blankWidthRatio,
LineStyle.SOLID);
}
target.drawWireframeShape(lineShape, color, lineWidth, lineStyle);
if (filledShape.isDrawable()) {
Map<Object, RGB> colorMap = new HashMap<Object, RGB>();
colorMap.put(this, color);
target.getExtension(IColormapShadedShapeExtension.class)
.drawColormapShadedShape(filledShape, colorMap, 1.0f, 1.0f);
} }
} }
/**
* Clean up internal graphics resources. This must be called to avoid
* leaking memory and/or graohics resources.
*/
public void dispose() { public void dispose() {
if (lastShape != null) { lineShape.dispose();
lastShape.dispose(); filledShape.dispose();
lastShape = null;
}
} }
} }

View file

@ -1,77 +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.
**/
package com.raytheon.viz.core.contours.util;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
/**
* VectorGraphicsRenderable Factory
*
* Constructs the VectorGraphicsRenderable for D2D usage of GriddedVectorDisplay
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 22, 2013 #2287 randerso Initial creation
*
* </pre>
*
* @author randerso
* @version 1.0
*/
public class VectorGraphicsRenderableFactory implements
IVectorGraphicsRenderableFactory {
private double scale;
public VectorGraphicsRenderableFactory() {
this.scale = 0.6;
}
public VectorGraphicsRenderableFactory(double scale) {
this.scale = scale;
}
/**
* @param scale
* the scale to set
*/
public void setScale(double scale) {
this.scale = scale;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.contours.util.IVectorGraphicsRenderableFactory#
* createRenderable()
*/
@Override
public VectorGraphicsRenderable createRenderable(IDescriptor descriptor,
IGraphicsTarget target, double size) {
return new VectorGraphicsRenderable(descriptor, target, size, scale);
}
}

View file

@ -75,6 +75,7 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.style.LabelingPreferences; import com.raytheon.uf.common.style.LabelingPreferences;
import com.raytheon.uf.common.style.contour.ContourPreferences;
import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.DrawableString; import com.raytheon.uf.viz.core.DrawableString;
@ -108,10 +109,10 @@ import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability;
import com.raytheon.uf.viz.core.time.TimeMatchingJob; import com.raytheon.uf.viz.core.time.TimeMatchingJob;
import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay; import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay.GriddedImagePaintProperties; import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay.GriddedImagePaintProperties;
import com.raytheon.viz.core.rsc.jts.JTSCompiler; import com.raytheon.viz.core.rsc.jts.JTSCompiler;
import com.raytheon.uf.common.style.contour.ContourPreferences;
import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEPreference; import com.raytheon.viz.gfe.GFEPreference;
import com.raytheon.viz.gfe.actions.ChangeCombineMode; import com.raytheon.viz.gfe.actions.ChangeCombineMode;
@ -153,15 +154,16 @@ import com.vividsolutions.jts.geom.Envelope;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 03/01/2008 chammack Initial Creation. * Mar 01, 2008 chammack Initial Creation.
* Aug 20, 2008 dglazesk Update for the ColorMap interface change * Aug 20, 2008 dglazesk Update for the ColorMap interface change
* Nov 23, 2011 mli set vector lineStyle * Nov 23, 2011 mli set vector lineStyle
* May 11, 2012 njensen Allow rsc to be recycled * May 11, 2012 njensen Allow rsc to be recycled
* Nov 08, 2012 1298 rferrel Changes for non-blocking FuzzValueDialog. * Nov 08, 2012 1298 rferrel Changes for non-blocking FuzzValueDialog.
* Mar 04, 2013 1637 randerso Fix time matching for ISC grids * Mar 04, 2013 1637 randerso Fix time matching for ISC grids
* Aug 27, 2013 2287 randerso Fixed scaling and direction of wind arrows * Aug 27, 2013 2287 randerso Fixed scaling and direction of wind arrows
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -173,6 +175,16 @@ import com.vividsolutions.jts.geom.Envelope;
public class GFEResource extends public class GFEResource extends
AbstractVizResource<GFEResourceData, MapDescriptor> implements AbstractVizResource<GFEResourceData, MapDescriptor> implements
IResourceDataChanged, IContextMenuContributor, IMessageClient { IResourceDataChanged, IContextMenuContributor, IMessageClient {
/* arbitrary value chosen to most closely match A1 */
private static final double VECTOR_DENSITY_FACTOR = 1.36;
/* Unknown source, provides acceptable sized barbs. */
private static final double BARB_SCALE_FACTOR = 0.4;
/* Unknown source, provides acceptable sized arrows heads. */
private static final double ARROW_HEAD_RATIO = 1.0 / 7.0;
private final transient IUFStatusHandler statusHandler = UFStatus private final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(GFEResource.class); .getHandler(GFEResource.class);
@ -618,41 +630,55 @@ public class GFEResource extends
} }
clearVectorDisplays(); clearVectorDisplays();
GFEVectorGraphicsRenderableFactory factory; VectorGraphicsConfig vectorConfig;
for (VisualizationType type : visTypes) { for (VisualizationType type : visTypes) {
switch (type) { switch (type) {
case WIND_ARROW: case WIND_ARROW:
vectorConfig = new VectorGraphicsConfig();
double size = getVectorSize("WindArrowDefaultSize");
vectorConfig.setBaseSize(size);
vectorConfig.setCalmCircleSizeRatio(vectorConfig
.getCalmCircleSizeRatio()
* BARB_SCALE_FACTOR);
vectorConfig
.setArrowHeadStaffRatio(ARROW_HEAD_RATIO);
vectorConfig.alwaysIncludeCalmCircle();
vectorConfig.alwaysIncludeVector();
// get the logFactor // get the logFactor
double logFactor = prefs.getDouble(parm.getParmID() double logFactor = prefs.getDouble(parm.getParmID()
.compositeNameUI() + "_arrowScaling"); .compositeNameUI() + "_arrowScaling");
if (logFactor < 0.0) { double maxVal = parm.getGridInfo().getMaxValue();
logFactor = 0.0; if (logFactor <= 0.0) {
vectorConfig.setLinearArrowScaleFactor(size
/ maxVal);
} else {
vectorConfig.setArrowScaler(new LogArrowScalar(
size, logFactor, maxVal));
} }
factory = new GFEVectorGraphicsRenderableFactory(
logFactor, parm.getGridInfo().getMaxValue());
this.vectorDisplay.add(new GriddedVectorDisplay( this.vectorDisplay.add(new GriddedVectorDisplay(
mag, dir, descriptor, MapUtil mag, dir, descriptor, MapUtil
.getGridGeometry(gs.getGridInfo() .getGridGeometry(gs.getGridInfo()
.getGridLoc()), .getGridLoc()),
getVectorSize("WindArrowDefaultSize"), VECTOR_DENSITY_FACTOR,
1.36, false, visTypeToDisplayType(type), false, visTypeToDisplayType(type),
factory)); vectorConfig));
break; break;
case WIND_BARB: case WIND_BARB:
factory = new GFEVectorGraphicsRenderableFactory( vectorConfig = new VectorGraphicsConfig();
0.0, parm.getGridInfo().getMaxValue()); vectorConfig
this.vectorDisplay .setBaseSize(getVectorSize("WindBarbDefaultSize")
.add(new GriddedVectorDisplay( * BARB_SCALE_FACTOR);
mag, vectorConfig.alwaysIncludeCalmCircle();
dir, vectorConfig.alwaysIncludeVector();
descriptor, this.vectorDisplay.add(new GriddedVectorDisplay(
MapUtil.getGridGeometry(gs mag, dir, descriptor, MapUtil
.getGridInfo().getGridLoc()), .getGridGeometry(gs.getGridInfo()
getVectorSize("WindBarbDefaultSize"), .getGridLoc()),
1.36, false, VECTOR_DENSITY_FACTOR / BARB_SCALE_FACTOR,
visTypeToDisplayType(type), factory)); false, visTypeToDisplayType(type),
vectorConfig));
break; break;
case IMAGE: case IMAGE:

View file

@ -1,213 +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.
**/
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
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 22, 2013 #2287 randerso Initial creation
*
* </pre>
*
* @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 } });
}
}

View file

@ -1,80 +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.
**/
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
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 22, 2013 #2287 randerso Initial creation
*
* </pre>
*
* @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);
}
}

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.viz.gfe.rsc;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig.IArrowScaler;
/**
*
* Provides logarithmic scaling of arrows.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Sep 23, 2013 2363 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
* @see VectorGraphicsConfig
*/
public class LogArrowScalar implements IArrowScaler {
protected final double baseSize;
protected final double logFactor;
protected final double minLog;
protected final double maxLog;
protected final double maxLimit;
public LogArrowScalar(double baseSize, double logFactor, double maxLimit) {
this.baseSize = baseSize;
this.logFactor = logFactor;
this.maxLimit = maxLimit;
minLog = Math.log(logFactor);
maxLog = Math.log(logFactor + 1.0);
}
@Override
public double scale(double magnitude) {
double pcentRange = magnitude / maxLimit;
double lg = Math.log(logFactor + pcentRange);
double pcentLog = (lg - minLog) / (maxLog - minLog);
return pcentLog * baseSize;
}
}

View file

@ -47,11 +47,12 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation * Apr 23, 2010 bsteffen Initial creation
* Aug 27, 2013 #2287 randerso Added densityFactor to allow application specific * Aug 27, 2013 2287 randerso Added densityFactor to allow application
* adjustment of density. * specific adjustment of density.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -109,7 +110,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
@Override @Override
protected IImage createResource(Coordinate coord) throws VizException { protected IImage createResource(Coordinate coord) throws VizException {
if (iconFactory == null) { if (iconFactory == null) {
iconFactory = new PointIconFactory(color, size); iconFactory = new PointIconFactory(color, (int) size);
} }
int i = getValue(coord); int i = getValue(coord);
IImage image = images.get(i); IImage image = images.get(i);

View file

@ -89,7 +89,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.GriddedContourDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedStreamlineDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedStreamlineDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay; import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderableFactory; import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay2; import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay2;
import com.raytheon.viz.grid.rsc.GriddedIconDisplay; import com.raytheon.viz.grid.rsc.GriddedIconDisplay;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
@ -104,15 +104,17 @@ import com.vividsolutions.jts.geom.Coordinate;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Mar 09, 2011 bsteffen Initial creation * Mar 09, 2011 bsteffen Initial creation
* May 08, 2013 1980 bsteffen Set paint status in GridResources for * May 08, 2013 1980 bsteffen Set paint status in GridResources for
* KML. * KML.
* Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows. * Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows.
* Aug 27, 2013 2287 randerso Added new parameters required by GriddedVectorDisplay * Aug 27, 2013 2287 randerso Added new parameters required by
* and GriddedIconDisplay * GriddedVectorDisplay and
* Sep 24, 2013 2404 bclement colormap params now created using match criteria * GriddedIconDisplay
* Sep 24, 2013 2404 bclement colormap params now created using match criteria
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -125,6 +127,12 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(AbstractGridResource.class); .getHandler(AbstractGridResource.class);
/* Unknown source, provides acceptable vector size. */
private static final double VECTOR_SIZE = 25.6;
/* Unknown source, provides acceptable density. */
private static final double VECTOR_DENSITY_FACTOR = 1.875;
public static final String INTERROGATE_VALUE = "value"; public static final String INTERROGATE_VALUE = "value";
public static final String INTERROGATE_UNIT = "unit"; public static final String INTERROGATE_UNIT = "unit";
@ -496,10 +504,30 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
case ARROW: case ARROW:
case DUALARROW: case DUALARROW:
convertData(data); convertData(data);
VectorGraphicsRenderableFactory factory = new VectorGraphicsRenderableFactory(); VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setBaseSize(VECTOR_SIZE);
if (displayType != DisplayType.BARB) {
config.setArrowHeadSizeRatio(0.15625);
config.setMinimumMagnitude(VECTOR_SIZE
* config.getArrowHeadSizeRatio());
config.disableCalmCircle();
if (stylePreferences != null
&& stylePreferences instanceof ArrowPreferences) {
double scale = ((ArrowPreferences) stylePreferences)
.getScale();
if (scale >= 0.0) {
config.setLinearArrowScaleFactor(scale);
} else {
config.setArrowScaler(new LogArrowScaler(-1 * scale));
}
} else {
config.setLinearArrowScaleFactor(1.0);
}
}
GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay( GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay(
data.getMagnitude(), data.getDirection(), descriptor, data.getMagnitude(), data.getDirection(), descriptor,
gridGeometry, 64, 0.75, true, displayType, factory); gridGeometry, VECTOR_DENSITY_FACTOR, true, displayType,
config);
vectorDisplay.setColor(getCapability(ColorableCapability.class) vectorDisplay.setColor(getCapability(ColorableCapability.class)
.getColor()); .getColor());
vectorDisplay.setLineStyle(getCapability(OutlineCapability.class) vectorDisplay.setLineStyle(getCapability(OutlineCapability.class)
@ -510,11 +538,6 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
.getDensity()); .getDensity());
vectorDisplay.setMagnification(getCapability( vectorDisplay.setMagnification(getCapability(
MagnificationCapability.class).getMagnification()); MagnificationCapability.class).getMagnification());
if (stylePreferences != null
&& stylePreferences instanceof ArrowPreferences) {
factory.setScale(((ArrowPreferences) stylePreferences)
.getScale());
}
renderable = vectorDisplay; renderable = vectorDisplay;
break; break;
case ICON: case ICON:

View file

@ -17,30 +17,40 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information. * further licensing information.
**/ **/
package com.raytheon.viz.core.contours.util; package com.raytheon.viz.grid.rsc.general;
import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.uf.viz.core.drawables.IDescriptor; import com.raytheon.viz.core.contours.util.VectorGraphicsConfig.IArrowScaler;
/** /**
* Interface for factory class to create a VectorGraphicsRenderable for *
* GriddedVectorDisplay * Provides logarithmic scaling of arrows.
* *
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Aug 22, 2013 #2287 randerso Initial creation * Sep 23, 2013 2363 bsteffen Initial creation
* *
* </pre> * </pre>
* *
* @author randerso * @author bsteffen
* @version 1.0 * @version 1.0
* @see VectorGraphicsConfig
*/ */
public class LogArrowScaler implements IArrowScaler {
public interface IVectorGraphicsRenderableFactory { protected final double scaleFactor;
public VectorGraphicsRenderable createRenderable(IDescriptor descriptor,
IGraphicsTarget target, double size); public LogArrowScaler(double scaleFactor) {
} this.scaleFactor = scaleFactor;
}
@Override
public double scale(double magnitude) {
return Math.log10(magnitude * scaleFactor) * 10 + 10;
}
}

View file

@ -60,6 +60,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability; import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
import com.raytheon.viz.awipstools.capabilities.RangeRingsOverlayCapability; import com.raytheon.viz.awipstools.capabilities.RangeRingsOverlayCapability;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable; import com.raytheon.viz.core.contours.util.VectorGraphicsRenderable;
import com.raytheon.viz.radar.RadarHelper; import com.raytheon.viz.radar.RadarHelper;
import com.raytheon.viz.radar.VizRadarRecord; import com.raytheon.viz.radar.VizRadarRecord;
@ -74,13 +75,14 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Mar 16, 2009 askripsk Initial creation * Mar 16, 2009 askripsk Initial creation
* Jul 26, 2010 #3723 bkowal Now implements the magnification * Jul 26, 2010 3723 bkowal Now implements the magnification
* capability. * capability.
* Mar 19, 2013 1804 bsteffen Remove empty data structures from radar * Mar 19, 2013 1804 bsteffen Remove empty data structures from radar
* hdf5. * hdf5.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* *
* </pre> * </pre>
* *
@ -90,6 +92,15 @@ import com.vividsolutions.jts.geom.Coordinate;
public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> { public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
/* Unknown source, provides acceptable barb size. */
private static final double BARB_SIZE = 25.6;
protected static final int X_OFFSET_NWP = 0;
protected static final int Y_OFFSET_NWP = 80;
protected static final double SCALAR = 1.6;
protected HashMap<Coordinate, String> screenStringMap = new HashMap<Coordinate, String>(); protected HashMap<Coordinate, String> screenStringMap = new HashMap<Coordinate, String>();
protected List<UnlinkedVector> unlinkedLines = new ArrayList<UnlinkedVector>(); protected List<UnlinkedVector> unlinkedLines = new ArrayList<UnlinkedVector>();
@ -98,12 +109,6 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
protected List<WindBarbPoint> points = new ArrayList<WindBarbPoint>(); protected List<WindBarbPoint> points = new ArrayList<WindBarbPoint>();
protected int xOffsetNWP = 0;
protected int yOffsetNWP = 80;
protected double scalar = 1.6;
protected IFont font; protected IFont font;
protected boolean initPlotObjects = true; protected boolean initPlotObjects = true;
@ -196,12 +201,12 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
width *= xScale; width *= xScale;
height *= yScale; height *= yScale;
width *= scalar; width *= SCALAR;
height *= scalar; height *= SCALAR;
double upper = (yOffsetNWP + jStart) * scalar; double upper = (Y_OFFSET_NWP + jStart) * SCALAR;
double lower = upper + height; double lower = upper + height;
double left = (xOffsetNWP + iStart) * scalar; double left = (X_OFFSET_NWP + iStart) * SCALAR;
double right = left + width; double right = left + width;
return new PixelCoverage(new Coordinate(left, upper), new Coordinate( return new PixelCoverage(new Coordinate(left, upper), new Coordinate(
@ -216,19 +221,19 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
// Paint unlinked lines // Paint unlinked lines
for (UnlinkedVector currVec : this.unlinkedLines) { for (UnlinkedVector currVec : this.unlinkedLines) {
target.drawLine((currVec.i1 + xOffsetNWP) * scalar, target.drawLine((currVec.i1 + X_OFFSET_NWP) * SCALAR,
(currVec.j1 + yOffsetNWP) * scalar, 0, (currVec.j1 + Y_OFFSET_NWP) * SCALAR, 0,
(currVec.i2 + xOffsetNWP) * scalar, (currVec.i2 + X_OFFSET_NWP) * SCALAR,
(currVec.j2 + yOffsetNWP) * scalar, 0, (currVec.j2 + Y_OFFSET_NWP) * SCALAR, 0,
getVectorColor(currVec), 1 * magnification); getVectorColor(currVec), 1 * magnification);
} }
// Paint linked lines // Paint linked lines
for (LinkedVector currVec : this.linkedLines) { for (LinkedVector currVec : this.linkedLines) {
target.drawLine((currVec.i1 + xOffsetNWP) * scalar, target.drawLine((currVec.i1 + X_OFFSET_NWP) * SCALAR,
(currVec.j1 + yOffsetNWP) * scalar, 0, (currVec.j1 + Y_OFFSET_NWP) * SCALAR, 0,
(currVec.i2 + xOffsetNWP) * scalar, (currVec.i2 + X_OFFSET_NWP) * SCALAR,
(currVec.j2 + yOffsetNWP) * scalar, 0, (currVec.j2 + Y_OFFSET_NWP) * SCALAR, 0,
getVectorColor(currVec), 1 * magnification); getVectorColor(currVec), 1 * magnification);
} }
} }
@ -242,9 +247,12 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
.getCanvasBounds().width) * magnification; .getCanvasBounds().width) * magnification;
VectorGraphicsRenderable[] renderables = new VectorGraphicsRenderable[6]; VectorGraphicsRenderable[] renderables = new VectorGraphicsRenderable[6];
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setBaseSize(BARB_SIZE);
config.setSizeScaler(ratio);
for (int i = 0; i < renderables.length; i++) { for (int i = 0; i < renderables.length; i++) {
renderables[i] = new VectorGraphicsRenderable(descriptor, target, renderables[i] = new VectorGraphicsRenderable(descriptor, target,
64, 1.0); config);
renderables[i].setLineWidth(magnification); renderables[i].setLineWidth(magnification);
} }
renderables[0].setColor(RadarHelper.WHITE); renderables[0].setColor(RadarHelper.WHITE);
@ -259,12 +267,12 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
index = 0; index = 0;
} }
Coordinate plotLoc = new Coordinate(point.i, point.j); Coordinate plotLoc = new Coordinate(point.i, point.j);
plotLoc.x += xOffsetNWP; plotLoc.x += X_OFFSET_NWP;
plotLoc.y += yOffsetNWP; plotLoc.y += Y_OFFSET_NWP;
plotLoc.y -= 2; plotLoc.y -= 2;
plotLoc.x *= scalar; plotLoc.x *= SCALAR;
plotLoc.y *= scalar; plotLoc.y *= SCALAR;
renderables[index].paintBarb(plotLoc, 64 * ratio, renderables[index].paintBarb(plotLoc,
point.getWindBarbSpd(), point.getWindBarbSpd(),
Math.toRadians(point.getWindBarbDir())); Math.toRadians(point.getWindBarbDir()));
} }
@ -282,8 +290,8 @@ public class RadarXYResource extends RadarImageResource<RadarXYDescriptor> {
DrawableString string = new DrawableString( DrawableString string = new DrawableString(
this.screenStringMap.get(c), null); this.screenStringMap.get(c), null);
string.font = font; string.font = font;
string.setCoordinates((c.x + xOffsetNWP) * scalar, string.setCoordinates((c.x + X_OFFSET_NWP) * SCALAR,
(c.y + yOffsetNWP) * scalar, 0.0); (c.y + Y_OFFSET_NWP) * SCALAR, 0.0);
string.horizontalAlignment = HorizontalAlignment.LEFT; string.horizontalAlignment = HorizontalAlignment.LEFT;
string.verticallAlignment = VerticalAlignment.TOP; string.verticallAlignment = VerticalAlignment.TOP;
strings.add(string); strings.add(string);

View file

@ -188,12 +188,12 @@ public class RadarXsectXYResource extends RadarXYResource implements
double width = 460; double width = 460;
double height = 430; double height = 430;
width *= scalar; width *= SCALAR;
height *= scalar; height *= SCALAR;
double upper = (yOffsetNWP + jStart) * scalar; double upper = (Y_OFFSET_NWP + jStart) * SCALAR;
double lower = upper + height; double lower = upper + height;
double left = (xOffsetNWP + iStart) * scalar; double left = (X_OFFSET_NWP + iStart) * SCALAR;
double right = left + width; double right = left + width;
return new PixelCoverage(new Coordinate(right, lower), new Coordinate( return new PixelCoverage(new Coordinate(right, lower), new Coordinate(