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.viz.core.contours.rsc.displays.GriddedContourDisplay;
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.GriddedImagePaintProperties;
import com.vividsolutions.jts.geom.Coordinate;
@ -92,12 +92,13 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 5, 2009 randerso Initial creation
* Jan 8, 2010 4205 jelkins add equals checking for OA resources
* Aug 27, 2013 2287 randerso Added new parameters to GriddedVectorDisplay
* constructor
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Nov 05, 2009 randerso Initial creation
* Jan 08, 2010 4205 jelkins add equals checking for OA resources
* Aug 27, 2013 2287 randerso Added new parameters to
* GriddedVectorDisplay constructor
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -113,6 +114,9 @@ public class OAResource extends
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 {
public OAUpateJob() {
@ -427,10 +431,10 @@ public class OAResource extends
FloatBuffer mag = data;
data.position(transformer.getNx() * transformer.getNy());
FloatBuffer dir = data.slice();
VectorGraphicsRenderableFactory factory = new VectorGraphicsRenderableFactory();
GriddedVectorDisplay vector = new GriddedVectorDisplay(mag,
dir, descriptor, transformer.getGridGeom(), 80, 0.75,
true, displayType, factory);
dir, descriptor, transformer.getGridGeom(),
VECTOR_DENSITY_FACTOR,
true, displayType, new VectorGraphicsConfig());
renderableMap.put(dataTime, vector);
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.StyleManager;
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.viz.core.IExtent;
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.OutlineCapability;
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.graphing.xy.XYWindImageData;
import com.vividsolutions.jts.geom.Coordinate;
/**
@ -55,10 +54,11 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 15, 2010 bsteffen Initial creation
* Feb 14, 2011 8244 bkowal enabled magnification capability.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jun 15, 2010 bsteffen Initial creation
* Feb 14, 2011 8244 bkowal enabled magnification capability.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -68,9 +68,8 @@ import com.vividsolutions.jts.geom.Coordinate;
public class CrossSectionVectorResource extends AbstractCrossSectionResource {
private ArrowPreferences arrowPrefs;
private int imageSize = XYWindImageData.IMAGE_SIZE;
/* Unknown source, provides acceptable density. */
private static final int VECTOR_SPACING = 60;
/**
* @param data
@ -94,7 +93,7 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
e.printStackTrace();
}
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();
RGB color = getCapability(ColorableCapability.class).getColor();
int scaledSize = (int) (this.imageSize * magnification);
IExtent graphArea = descriptor.getGraph(this).getExtent();
if (graphArea == null) {
return;
@ -131,13 +128,15 @@ public class CrossSectionVectorResource extends AbstractCrossSectionResource {
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
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);
IExtent viewableArea = paintProps.getView().getExtent()
.intersection(graphArea);
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setSizeScaler(magnification * ratio);
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 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 dir = Math.atan2(-uudd, -vvff);
Coordinate plotLoc = new Coordinate(screenX, screenY);
double adjSize = scaledSize * ratio;
if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) {
vgr.paintArrow(plotLoc, adjSize, spd, dir);
vgr.paintArrow(plotLoc, spd, dir);
} 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)
&& sliceMap.get(time) != null) {
int index = y * geometry.getGridRange().getSpan(0) + x;
float[] ufd = (float[]) sliceMap.get(time).get(2);
float[] vfd = (float[]) sliceMap.get(time).get(3);
float[] ufd = sliceMap.get(time).get(2);
float[] vfd = sliceMap.get(time).get(3);
double val = Math.hypot(ufd[index], vfd[index]);
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-Vendor: RAYTHEON
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.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-ActivationPolicy: lazy
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core, com.raytheon.viz.core
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.style,
com.raytheon.uf.common.style.arrow,
com.raytheon.uf.common.style.contour,
com.raytheon.uf.common.style.image,
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.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.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.rsc,
com.raytheon.viz.core.slice.request,
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
com.raytheon.viz.grid.rsc
Export-Package: com.raytheon.uf.viz.xy.timeheight,
com.raytheon.uf.viz.xy.timeheight.display,
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.Priority;
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.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.viz.core.IExtent;
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.TimeDirection;
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.graphing.xy.XYData;
import com.raytheon.viz.core.graphing.xy.XYWindImageData;
@ -64,13 +64,14 @@ import com.vividsolutions.jts.geom.Coordinate;
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 4, 2007 njensen Initial creation
* Feb 20, 2009 njensen Refactored to new rsc architecture
* Feb 14, 2011 8244 bkowal enabled the magnification capability.
* Get graph in loadInterpolatedData after
* we ensure that it is not NULL.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Dec 04, 2007 njensen Initial creation
* Feb 20, 2009 njensen Refactored to new rsc architecture
* Feb 14, 2011 8244 bkowal enabled the magnification capability.
* Get graph in loadInterpolatedData after
* we ensure that it is not NULL.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -83,12 +84,11 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(TimeHeightVectorResource.class);
/* Unknown source, provides acceptable density. */
private static final int VECTOR_SPACING = 60;
private float[] vInterpolatedData;
private ArrowPreferences arrowPrefs;
private int imageSize;
private Map<Coordinate, IImage> imageMap = new HashMap<Coordinate, IImage>();
public TimeHeightVectorResource(TimeHeightResourceData data,
@ -109,7 +109,7 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
e.printStackTrace();
}
if (sr != null) {
prefs = arrowPrefs = (ArrowPreferences) sr.getPreferences();
prefs = sr.getPreferences();
}
this.getResourceData().addChangeListener(this);
getCapability(DisplayTypeCapability.class).setAlternativeDisplayTypes(
@ -160,7 +160,6 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
List<XYData> vList = new ArrayList<XYData>(dataList.size());
for (XYData xyData : dataList) {
XYWindImageData windData = (XYWindImageData) xyData;
imageSize = windData.getDefaultSize()[0];
double dir = windData.getWindDir();
double spd = windData.getWindSpd();
dir = Math.toRadians(dir);
@ -216,11 +215,6 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
double density = getCapability(DensityCapability.class).getDensity();
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();
if (graphArea == null) {
return;
@ -234,11 +228,16 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
imagePaintProperties.setAlpha(1.0f);
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
int spacing = (int) ((geometry.getGridRange2D().getMaxX() * imageSize
* .75 * ratio / Math.min(2.0, density))
int spacing = (int) ((geometry.getGridRange2D().getMaxX()
* VECTOR_SPACING * ratio / Math.min(2.0, density))
/ paintProps.getCanvasBounds().width + 1);
IExtent viewableArea = paintProps.getView().getExtent()
.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 j = spacing / 2; j < geometry.getGridRange2D().getMaxY(); j += spacing) {
double screenX = graphArea.getMinX() + (i + 0.5) * width;
@ -258,12 +257,11 @@ public class TimeHeightVectorResource extends AbstractTimeHeightResource
double spd = Math.hypot(uudd, vvff);
double dir = Math.atan2(-uudd, -vvff);
Coordinate plotLoc = new Coordinate(screenX, screenY);
double adjSize = scaledSize * ratio;
if (getCapability(DisplayTypeCapability.class).getDisplayType() == DisplayType.ARROW) {
vgr.paintArrow(plotLoc, adjSize, spd, dir);
vgr.paintArrow(plotLoc, spd, dir);
} 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.varheight.adapter.AbstractVarHeightAdapter;
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.graphing.util.GraphPrefsFactory;
import com.raytheon.viz.core.graphing.xy.XYData;
@ -75,10 +76,12 @@ import com.vividsolutions.jts.geom.Geometry;
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 23, 2009 mschenke Initial creation
* Feb 10, 2011 8344 bkowal enabled the magnification capability.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Nov 23, 2009 mschenke Initial creation
* Feb 10, 2011 8344 bkowal enabled the magnification capability.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
*
* </pre>
*
@ -109,8 +112,6 @@ public class VarHeightResource extends
protected DataTime currentTime = null;
private double imageSize = XYWindImageData.IMAGE_SIZE;
protected VarHeightResource(VarHeightResourceData resourceData,
LoadProperties loadProperties, AbstractVarHeightAdapter<?> adapter)
throws VizException {
@ -319,9 +320,14 @@ public class VarHeightResource extends
descriptor.getGraph(this).setCurrentMagnification(magnification);
target.setupClippingPlane(descriptor.getGraph(this).getExtent());
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
// build the renderable
VectorGraphicsConfig config = new VectorGraphicsConfig();
config.setSizeScaler(magnification * ratio);
VectorGraphicsRenderable vgr = new VectorGraphicsRenderable(
this.descriptor, target, this.imageSize, 1.0f);
this.descriptor, target, config);
for (int i = 0; i < data.size(); i++) {
XYData d = data.get(i);
double x = ((Number) d.getX()).doubleValue();
@ -332,8 +338,6 @@ public class VarHeightResource extends
double screenX = screenLoc[0];
double screenY = screenLoc[1];
double ratio = paintProps.getView().getExtent().getWidth()
/ paintProps.getCanvasBounds().width;
IExtent graphExtent = descriptor.getGraph(this).getExtent();
@ -349,8 +353,7 @@ public class VarHeightResource extends
}
if (withinBounds) {
double adjSize = (this.imageSize * magnification) * ratio;
vgr.paintBarb(plotLoc, adjSize, dd.getWindSpd(),
vgr.paintBarb(plotLoc, dd.getWindSpd(),
dd.getWindDir() * DEGREE_TO_RADIAN);
vgr.setColor(color);
vgr.setLineWidth(getCapability(OutlineCapability.class)

View file

@ -53,15 +53,17 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation
* Aug 07, 2013 2077 bsteffen Revise pixel size calculations.
* Aug 27, 2013 2287 randerso Replaced hard coded constant with densityFactor
* parameter to allow application specific density
* scaling to better match A1 displays
* Sep 10, 2013 DR 16257 MPorricelli Fix so that wind for global grids displays on
* mercator maps.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation
* Aug 07, 2013 2077 bsteffen Revise pixel size calculations.
* Aug 27, 2013 2287 randerso Replaced hard coded constant with
* densityFactor parameter to allow
* application specific density scaling to
* better match A1 displays
* 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>
*
@ -106,7 +108,7 @@ public abstract class AbstractGriddedDisplay<T> implements IRenderable {
protected IGraphicsTarget target;
protected final int size;
protected final double size;
protected final double densityFactor;
@ -131,7 +133,7 @@ public abstract class AbstractGriddedDisplay<T> implements IRenderable {
* adjustment factor to make density match A1
*/
public AbstractGriddedDisplay(IMapDescriptor descriptor,
GeneralGridGeometry gridGeometryOfGrid, int size,
GeneralGridGeometry gridGeometryOfGrid, double size,
double densityFactor) {
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.map.IMapDescriptor;
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.vividsolutions.jts.geom.Coordinate;
@ -49,22 +49,24 @@ import com.vividsolutions.jts.geom.Coordinate;
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 22, 2010 bsteffen Initial creation
* Feb 07, 2011 7948 bkowal added a public method to get
* the direction.
* Aug 27, 2013 2287 randerso Added VectorGraphicsRenderable Factory to allow
* application specific rendering of wind barbs and
* arrows.
* Added densityFactor to allow application specific
* adjustment of density.
* Added gridRelative flag to indicate whether direction
* data is relative to grid or true north
* Sep 9, 2013 DR16257 MPorricelli When setDestinationGeographicPoint fails (which can
* happen for global lat/lon grid winds displayed on
* Equidistant Cylindrical map) try again with different
* pixel location.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jun 22, 2010 bsteffen Initial creation
* Feb 07, 2011 7948 bkowal added a public method to get the
* direction.
* Aug 27, 2013 2287 randerso Added VectorGraphicsRenderable Factory to
* allow application specific rendering of
* wind barbs and arrows. Added
* densityFactor to allow application
* specific adjustment of density. Added
* gridRelative flag to indicate whether
* direction data is relative to grid or
* true north
* Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails (which can
* happen for global lat/lon grid winds displayed on
* Equidistant Cylindrical map) try again with different
* pixel location.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -83,6 +85,8 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private IExtent lastExtent;
private VectorGraphicsConfig vectorConfig;
private VectorGraphicsRenderable vectorRenderable;
private boolean gridRelative;
@ -91,8 +95,6 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private GeodeticCalculator gc;
private IVectorGraphicsRenderableFactory factory;
/**
* @param magnitude
* @param direction
@ -109,15 +111,16 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
*/
public GriddedVectorDisplay(FloatBuffer magnitude, FloatBuffer direction,
IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid,
int size, double densityFactor, boolean gridRelative,
DisplayType displayType, IVectorGraphicsRenderableFactory factory) {
super(descriptor, gridGeometryOfGrid, size, densityFactor);
double densityFactor, boolean gridRelative,
DisplayType displayType, VectorGraphicsConfig config) {
super(descriptor, gridGeometryOfGrid, config.getBaseSize(),
densityFactor);
this.magnitude = magnitude;
this.direction = direction;
this.gridRelative = gridRelative;
this.displayType = displayType;
this.gc = new GeodeticCalculator(descriptor.getCRS());
this.factory = factory;
this.vectorConfig = config;
}
@Override
@ -129,8 +132,8 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
lastExtent = paintProps.getView().getExtent().clone();
}
if (vectorRenderable == null) {
vectorRenderable = factory.createRenderable(descriptor, target,
this.size);
vectorRenderable = new VectorGraphicsRenderable(descriptor,
target, vectorConfig);
super.paint(target, paintProps);
}
vectorRenderable.setColor(this.color);
@ -207,15 +210,16 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
}
dir = (float) Math.toRadians(dir);
vectorConfig.setSizeScaler(adjSize / size);
switch (displayType) {
case ARROW:
vectorRenderable.paintArrow(plotLoc, adjSize, spd, dir);
vectorRenderable.paintArrow(plotLoc, spd, dir);
break;
case BARB:
vectorRenderable.paintBarb(plotLoc, adjSize, spd, dir);
vectorRenderable.paintBarb(plotLoc, spd, dir);
break;
case DUALARROW:
vectorRenderable.paintDualArrow(plotLoc, adjSize, spd, dir);
vectorRenderable.paintDualArrow(plotLoc, spd, dir);
break;
default:
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;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.graphics.RGB;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
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.ext.colormap.IColormapShadedShapeExtension;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormapShadedShapeExtension.IColormapShadedShape;
import com.raytheon.uf.viz.core.exception.VizException;
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>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 27, 2011 bsteffen Initial creation
* Aug 27, 2013 #2287 randerso Refactored to allow subclassing
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* May 27, 2011 bsteffen Initial creation
* Aug 27, 2013 2287 randerso Refactored to allow subclassing
* Sep 23, 2013 2363 bsteffen Add more configuration options.
*
* </pre>
*
* @author bsteffen
* @version 1.0
* @see VectorGraphicsConfig
*/
public class VectorGraphicsRenderable {
protected IWireframeShape lastShape;
protected final IWireframeShape lineShape;
protected double size = 80;
protected double scale = 1.0;
protected final IColormapShadedShape filledShape;
protected RGB color;
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,
IGraphicsTarget target, double size, double scale) {
this.lastShape = target.createWireframeShape(true, descriptor);
this.size = size;
this.scale = scale;
IGraphicsTarget target) throws VizException {
this(descriptor, target, new VectorGraphicsConfig());
}
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) {
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) {
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) {
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 adjSize
* @param spd
* @param dir
* barb direction in radians
* the location on the screen where the barb originates in
* descriptor pixel space.
* @param magnitude
* 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,
double dir) {
if (spd < 2.5) {
paintPoint(plotLoc, adjSize);
public void paintBarb(Coordinate plotLoc, double magnitude, double direction) {
if (magnitude < config.getCalmCircleMaximumMagnitude()) {
paintPoint(plotLoc);
}
if (magnitude < config.getMinimumMagnitude()) {
return;
}
int speed = (int) (spd + 2.5);
double staff = adjSize * .4;
double barb = staff * 0.30;
double add = staff * 0.105;
/* adding 2.5 will round barbs to nearest 5 */
int speed = (int) (magnitude + 2.5);
double size = config.getScaledSize();
double barb = size * config.getBarbLengthRatio();
double add = size * config.getBarbSpacingRatio();
// 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;
double uudd = -magnitude * Math.sin(direction);
double vvff = -magnitude * Math.cos(direction);
double dix = -uudd / magnitude;
double djy = -vvff / magnitude;
double barbRotationRadians = config.getBarbRotationRadians();
double dix1 = Math.cos(barbRotationRadians) * dix
+ Math.sin(barbRotationRadians) * djy;
double djy1 = (-1) * Math.sin(barbRotationRadians) * dix
+ Math.cos(barbRotationRadians) * djy;
// SPEED AND COUNTERS:
int n50 = speed / 50;
@ -115,14 +247,14 @@ public class VectorGraphicsRenderable {
calcSpd = calcSpd - 10 * n10;
int n5 = calcSpd / 5;
double sx = ((n50 + n50 + n10 + n5 + 2)) * add;
staff = Math.max(adjSize * .4, sx);
double staff = Math.max(size, sx);
// DRAW STAFF
double ix2 = plotLoc.x;
double jy2 = plotLoc.y;
double ix2 = plotLoc.x + dix * size * config.getOffsetRatio();
double jy2 = plotLoc.y - djy * size * config.getOffsetRatio();
double ix1 = ix2 + dix * 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
if (n50 == 0 && n10 == 0) {
@ -130,7 +262,7 @@ public class VectorGraphicsRenderable {
jy2 = jy1 + djy * add;
ix1 = ix2 + dix1 * barb / 2.0;
jy1 = jy2 - djy1 * barb / 2.0;
lastShape.addLineSegment(new double[][] { { ix2, jy2 },
lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } });
return;
}
@ -139,23 +271,30 @@ public class VectorGraphicsRenderable {
for (int i = 0; i < n50; i++) {
ix2 = ix1 + dix1 * 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 } });
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;
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 },
lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } });
ix1 = ix1 - dix * add;
jy1 = jy1 + djy * add;
@ -165,16 +304,17 @@ public class VectorGraphicsRenderable {
if (n5 != 0) {
ix2 = ix1 + dix1 * barb / 2.0;
jy2 = jy1 - djy1 * barb / 2.0;
lastShape.addLineSegment(new double[][] { { ix2, jy2 },
lineShape.addLineSegment(new double[][] { { ix2, jy2 },
{ ix1, jy1 } });
}
}
protected void paintPoint(Coordinate plotLoc, double adjSize) {
protected void paintPoint(Coordinate plotLoc) {
double[][] line = new double[9][2];
double aa = adjSize * .030;
double saa = aa * 0.707;
double aa = config.getScaledSize() * config.getCalmCircleSizeRatio();
double saa = aa * 0.7071067811865475;
line[8][0] = line[0][0] = plotLoc.x + aa;
line[8][1] = line[0][1] = plotLoc.y;
@ -199,42 +339,46 @@ public class VectorGraphicsRenderable {
line[7][0] = plotLoc.x + saa;
line[7][1] = plotLoc.y - saa;
lastShape.addLineSegment(line);
lineShape.addLineSegment(line);
}
public void paintDualArrow(Coordinate plotLoc, double adjSize, double spd,
double dir) {
if (spd < 4.0) {
/**
* Add a dual arrow to be painted. This is an arrow that has half a head on
* 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;
}
double staff = 0.0;
if (this.scale > 0.0) {
staff = spd * this.scale;
} else {
staff = Math.log10(spd * -this.scale) * 10 + 10;
}
double barb = 4.0;
if (staff < barb) {
return;
}
double ratio = adjSize / size;
staff *= ratio;
barb *= ratio;
double size = config.getScaledSize();
double staff = config.getArrowScaler().scale(magnitude)
* config.getSizeScaler();
double barb = size * config.getArrowHeadSizeRatio()
+ staff
* config.getArrowHeadStaffRatio();
// DIRECTIONS
double uudd = -spd * Math.sin(dir);
double vvff = -spd * Math.cos(dir);
double dix = uudd / spd;
double djy = vvff / spd;
double uudd = -magnitude * Math.sin(direction);
double vvff = -magnitude * Math.cos(direction);
double dix = uudd / magnitude;
double djy = vvff / magnitude;
double dix1 = -dix - djy;
double djy1 = dix - djy;
// DRAW BODY OF ARROW
double ix2 = plotLoc.x;
double jy2 = plotLoc.y;
double ix2 = plotLoc.x + dix * size * config.getOffsetRatio();
double jy2 = plotLoc.y - djy * size * config.getOffsetRatio();
double ix1 = ix2 + dix * staff;
double jy1 = jy2 - djy * staff;
@ -242,38 +386,43 @@ public class VectorGraphicsRenderable {
double jy3 = jy1 - djy1 * barb;
double ix4 = ix2 - dix1 * 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 } });
}
public void paintArrow(Coordinate plotLoc, double adjSize, double spd,
double dir) {
if (spd == 0.0) {
/**
* Add an arrow to be painted.
*
* @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;
}
double staff = 0.0;
if (this.scale > 0.0) {
staff = spd * this.scale;
} else {
staff = Math.log10(spd * -this.scale) * 10 + 10;
}
double barb = 4.0;
if (staff < barb) {
return;
}
double ratio = adjSize / size;
staff *= ratio;
barb *= ratio;
double size = config.getScaledSize();
double staff = config.getArrowScaler().scale(magnitude)
* config.getSizeScaler();
double barb = size * config.getArrowHeadSizeRatio() + staff
* config.getArrowHeadStaffRatio();
// DIRECTIONS
double uudd = -spd * Math.sin(dir);
double vvff = -spd * Math.cos(dir);
double dix = uudd / spd;
double djy = vvff / spd;
double uudd = -magnitude * Math.sin(direction);
double vvff = -magnitude * Math.cos(direction);
double dix = uudd / magnitude;
double djy = vvff / magnitude;
double dix1 = -dix - djy;
double djy1 = dix - djy;
double dix2 = -dix + djy;
@ -284,27 +433,48 @@ public class VectorGraphicsRenderable {
double jy2 = plotLoc.y;
double ix1 = ix2 + dix * 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.
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 },
lineShape.addLineSegment(new double[][] { { ix2, jy2 }, { ix1, jy1 },
{ 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 {
if (lastShape != null) {
target.drawWireframeShape(lastShape, color, lineWidth, lineStyle);
if (blankColor != null) {
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() {
if (lastShape != null) {
lastShape.dispose();
lastShape = null;
}
lineShape.dispose();
filledShape.dispose();
}
}

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.Priority;
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.TimeRange;
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.viz.core.contours.rsc.displays.GriddedContourDisplay;
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.GriddedImagePaintProperties;
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.GFEPreference;
import com.raytheon.viz.gfe.actions.ChangeCombineMode;
@ -153,15 +154,16 @@ import com.vividsolutions.jts.geom.Envelope;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 03/01/2008 chammack Initial Creation.
* Aug 20, 2008 dglazesk Update for the ColorMap interface change
* Nov 23, 2011 mli set vector lineStyle
* May 11, 2012 njensen Allow rsc to be recycled
* Nov 08, 2012 1298 rferrel Changes for non-blocking FuzzValueDialog.
* Mar 04, 2013 1637 randerso Fix time matching for ISC grids
* Aug 27, 2013 2287 randerso Fixed scaling and direction of wind arrows
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Mar 01, 2008 chammack Initial Creation.
* Aug 20, 2008 dglazesk Update for the ColorMap interface change
* Nov 23, 2011 mli set vector lineStyle
* May 11, 2012 njensen Allow rsc to be recycled
* Nov 08, 2012 1298 rferrel Changes for non-blocking FuzzValueDialog.
* Mar 04, 2013 1637 randerso Fix time matching for ISC grids
* Aug 27, 2013 2287 randerso Fixed scaling and direction of wind arrows
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -173,6 +175,16 @@ import com.vividsolutions.jts.geom.Envelope;
public class GFEResource extends
AbstractVizResource<GFEResourceData, MapDescriptor> implements
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
.getHandler(GFEResource.class);
@ -618,41 +630,55 @@ public class GFEResource extends
}
clearVectorDisplays();
GFEVectorGraphicsRenderableFactory factory;
VectorGraphicsConfig vectorConfig;
for (VisualizationType type : visTypes) {
switch (type) {
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
double logFactor = prefs.getDouble(parm.getParmID()
.compositeNameUI() + "_arrowScaling");
if (logFactor < 0.0) {
logFactor = 0.0;
double maxVal = parm.getGridInfo().getMaxValue();
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(
mag, dir, descriptor, MapUtil
.getGridGeometry(gs.getGridInfo()
.getGridLoc()),
getVectorSize("WindArrowDefaultSize"),
1.36, false, visTypeToDisplayType(type),
factory));
VECTOR_DENSITY_FACTOR,
false, visTypeToDisplayType(type),
vectorConfig));
break;
case WIND_BARB:
factory = new GFEVectorGraphicsRenderableFactory(
0.0, parm.getGridInfo().getMaxValue());
this.vectorDisplay
.add(new GriddedVectorDisplay(
mag,
dir,
descriptor,
MapUtil.getGridGeometry(gs
.getGridInfo().getGridLoc()),
getVectorSize("WindBarbDefaultSize"),
1.36, false,
visTypeToDisplayType(type), factory));
vectorConfig = new VectorGraphicsConfig();
vectorConfig
.setBaseSize(getVectorSize("WindBarbDefaultSize")
* BARB_SCALE_FACTOR);
vectorConfig.alwaysIncludeCalmCircle();
vectorConfig.alwaysIncludeVector();
this.vectorDisplay.add(new GriddedVectorDisplay(
mag, dir, descriptor, MapUtil
.getGridGeometry(gs.getGridInfo()
.getGridLoc()),
VECTOR_DENSITY_FACTOR / BARB_SCALE_FACTOR,
false, visTypeToDisplayType(type),
vectorConfig));
break;
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>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation
* Aug 27, 2013 #2287 randerso Added densityFactor to allow application specific
* adjustment of density.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Apr 23, 2010 bsteffen Initial creation
* Aug 27, 2013 2287 randerso Added densityFactor to allow application
* specific adjustment of density.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -109,7 +110,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
@Override
protected IImage createResource(Coordinate coord) throws VizException {
if (iconFactory == null) {
iconFactory = new PointIconFactory(color, size);
iconFactory = new PointIconFactory(color, (int) size);
}
int i = getValue(coord);
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.GriddedStreamlineDisplay;
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.grid.rsc.GriddedIconDisplay;
import com.vividsolutions.jts.geom.Coordinate;
@ -104,15 +104,17 @@ import com.vividsolutions.jts.geom.Coordinate;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 09, 2011 bsteffen Initial creation
* May 08, 2013 1980 bsteffen Set paint status in GridResources for
* KML.
* Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows.
* Aug 27, 2013 2287 randerso Added new parameters required by GriddedVectorDisplay
* and GriddedIconDisplay
* Sep 24, 2013 2404 bclement colormap params now created using match criteria
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Mar 09, 2011 bsteffen Initial creation
* May 08, 2013 1980 bsteffen Set paint status in GridResources for
* KML.
* Jul 15, 2013 2107 bsteffen Fix sampling of grid vector arrows.
* Aug 27, 2013 2287 randerso Added new parameters required by
* GriddedVectorDisplay and
* GriddedIconDisplay
* Sep 24, 2013 2404 bclement colormap params now created using match criteria
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
*
* </pre>
*
@ -125,6 +127,12 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
private static final transient IUFStatusHandler statusHandler = UFStatus
.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_UNIT = "unit";
@ -496,10 +504,30 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
case ARROW:
case DUALARROW:
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(
data.getMagnitude(), data.getDirection(), descriptor,
gridGeometry, 64, 0.75, true, displayType, factory);
gridGeometry, VECTOR_DENSITY_FACTOR, true, displayType,
config);
vectorDisplay.setColor(getCapability(ColorableCapability.class)
.getColor());
vectorDisplay.setLineStyle(getCapability(OutlineCapability.class)
@ -510,11 +538,6 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
.getDensity());
vectorDisplay.setMagnification(getCapability(
MagnificationCapability.class).getMagnification());
if (stylePreferences != null
&& stylePreferences instanceof ArrowPreferences) {
factory.setScale(((ArrowPreferences) stylePreferences)
.getScale());
}
renderable = vectorDisplay;
break;
case ICON:

View file

@ -17,30 +17,40 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* 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.uf.viz.core.drawables.IDescriptor;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
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>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 22, 2013 #2287 randerso Initial creation
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Sep 23, 2013 2363 bsteffen Initial creation
*
* </pre>
*
* @author randerso
* @author bsteffen
* @version 1.0
* @see VectorGraphicsConfig
*/
public class LogArrowScaler implements IArrowScaler {
protected final double scaleFactor;
public LogArrowScaler(double scaleFactor) {
this.scaleFactor = scaleFactor;
}
@Override
public double scale(double magnitude) {
return Math.log10(magnitude * scaleFactor) * 10 + 10;
}
public interface IVectorGraphicsRenderableFactory {
public VectorGraphicsRenderable createRenderable(IDescriptor descriptor,
IGraphicsTarget target, double size);
}

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

View file

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