Issue #2313 Image canvas rendering.

Change-Id: I121b61c954a27249c29f3d34c8674193af8c2417

Former-commit-id: 16c350f0c6 [formerly 0f8d0c52093a14d16a36ce353c2587633474007d]
Former-commit-id: 625aac3ed3
This commit is contained in:
Ben Steffensmeier 2014-01-15 16:58:10 -06:00
parent 8420f87348
commit 76414243ba
14 changed files with 1193 additions and 388 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Core Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.core;singleton:=true
Bundle-Version: 1.13.0.qualifier
Bundle-Version: 1.14.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.core.Activator
Bundle-Vendor: Raytheon
Require-Bundle: org.eclipse.ui,
@ -17,7 +17,6 @@ Require-Bundle: org.eclipse.ui,
com.raytheon.uf.common.status;visibility:=reexport,
org.apache.commons.lang,
javax.vecmath;bundle-version="1.3.1",
org.geotools;bundle-version="2.5.2",
javax.measure;bundle-version="1.0.0",
org.jep;bundle-version="1.0.0",
com.raytheon.uf.common.datastorage;bundle-version="1.11.11",
@ -38,7 +37,6 @@ Require-Bundle: org.eclipse.ui,
com.raytheon.uf.common.comm;bundle-version="1.12.1174",
com.raytheon.uf.common.message;bundle-version="1.12.1174",
com.raytheon.uf.common.alertmonitor;bundle-version="1.12.1174",
com.raytheon.uf.common.python;bundle-version="1.12.1174",
com.raytheon.uf.common.velocity;bundle-version="1.0.0",
ch.qos.logback;bundle-version="1.0.13",
com.raytheon.uf.common.style;bundle-version="1.0.0",

View file

@ -23,13 +23,16 @@ import java.util.ArrayList;
import java.util.List;
import com.raytheon.uf.viz.core.DrawableColorMap;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IView;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.vividsolutions.jts.geom.Coordinate;
/**
* A general implementation of the canvas rendering extension which converts
@ -39,12 +42,14 @@ import com.raytheon.uf.viz.core.exception.VizException;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
* parameters, disable colormap interpolation
* by default.
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
* parameters, disable colormap interpolation
* by default.
* Jan 14, 2014 2313 bsteffen Add method to draw images.
*
*
* </pre>
*
@ -58,10 +63,7 @@ public class GeneralCanvasRenderingExtension extends
@Override
public void drawStrings(PaintProperties paintProps,
DrawableString... parameters) throws VizException {
IExtent extent = paintProps.getView().getExtent();
double xRatio = extent.getWidth() / paintProps.getCanvasBounds().width;
double yRatio = extent.getHeight()
/ paintProps.getCanvasBounds().height;
IView view = paintProps.getView();
List<DrawableString> mapStrings = new ArrayList<DrawableString>(
parameters.length);
@ -79,10 +81,10 @@ public class GeneralCanvasRenderingExtension extends
mapString.basics.alpha = screenString.basics.alpha;
mapString.basics.xOrColors = screenString.basics.xOrColors;
mapString.basics.color = screenString.basics.color;
mapString.basics.x = extent.getMinX() + screenString.basics.x
* xRatio;
mapString.basics.y = extent.getMinY() + screenString.basics.y
* yRatio;
double[] grid = view.screenToGrid(screenString.basics.x,
screenString.basics.y, 1.0, target);
mapString.basics.x = grid[0];
mapString.basics.y = grid[1];
mapString.basics.z = screenString.basics.z;
mapStrings.add(mapString);
}
@ -94,10 +96,7 @@ public class GeneralCanvasRenderingExtension extends
@Override
public void drawLines(PaintProperties paintProps,
DrawableLine... parameters) throws VizException {
IExtent extent = paintProps.getView().getExtent();
double xRatio = extent.getWidth() / paintProps.getCanvasBounds().width;
double yRatio = extent.getHeight()
/ paintProps.getCanvasBounds().height;
IView view = paintProps.getView();
List<DrawableLine> mapLines = new ArrayList<DrawableLine>(
parameters.length);
for (DrawableLine screenLine : parameters) {
@ -108,9 +107,9 @@ public class GeneralCanvasRenderingExtension extends
mapLine.basics.color = screenLine.basics.color;
mapLine.basics.xOrColors = screenLine.basics.xOrColors;
for (double[] point : screenLine.points) {
double x = extent.getMinX() + point[0] * xRatio;
double y = extent.getMinY() + point[1] * yRatio;
mapLine.addPoint(x, y);
double[] grid = view.screenToGrid(point[0], point[1], 1.0,
target);
mapLine.addPoint(grid[0], grid[1]);
}
mapLines.add(mapLine);
}
@ -122,10 +121,7 @@ public class GeneralCanvasRenderingExtension extends
@Override
public void drawColorRamp(PaintProperties paintProps,
DrawableColorMap colorMap) throws VizException {
IExtent extent = paintProps.getView().getExtent();
double xRatio = extent.getWidth() / paintProps.getCanvasBounds().width;
double yRatio = extent.getHeight()
/ paintProps.getCanvasBounds().height;
IView view = paintProps.getView();
DrawableColorMap newColorMap = new DrawableColorMap(
colorMap.getColorMapParams());
newColorMap.alpha = colorMap.alpha;
@ -135,17 +131,49 @@ public class GeneralCanvasRenderingExtension extends
double y1 = colorMap.extent.getMinY();
double x2 = colorMap.extent.getMaxX();
double y2 = colorMap.extent.getMaxY();
double[] grid = view.screenToGrid(x1, y1, 1.0, target);
x1 = grid[0];
y1 = grid[1];
grid = view.screenToGrid(x2, y2, 1.0, target);
x2 = grid[0];
y2 = grid[1];
x1 = extent.getMinX() + x1 * xRatio;
y1 = extent.getMinY() + y1 * yRatio;
x2 = extent.getMinX() + x2 * xRatio;
y2 = extent.getMinY() + y2 * yRatio;
newColorMap.extent = new PixelExtent(x1, x2, y1, y2);
target.clearClippingPlane();
target.drawColorRamp(newColorMap);
target.setupClippingPlane(paintProps.getClippingPane());
}
@Override
public void drawImages(PaintProperties paintProps, DrawableImage... images)
throws VizException {
IView view = paintProps.getView();
List<DrawableImage> mapImages = new ArrayList<DrawableImage>(
images.length);
for (DrawableImage screenImage : images) {
PixelCoverage screenCoverage = screenImage.getCoverage();
if (screenCoverage.getMesh() != null) {
throw new VizException(
this.getClass().getSimpleName()
+ " does not support canvas rendering of images with meshes.");
}
Coordinate ul = screenCoverage.getUl();
double[] grid = view.screenToGrid(ul.x, ul.y, 1.0, target);
ul = new Coordinate(grid[0], grid[1]);
Coordinate lr = screenCoverage.getLr();
grid = view.screenToGrid(lr.x, lr.y, 1.0, target);
lr = new Coordinate(grid[0], grid[1]);
Coordinate ur = new Coordinate(lr.x, ul.y);
Coordinate ll = new Coordinate(ul.x, lr.y);
PixelCoverage mapCoverage = new PixelCoverage(ul, ur, lr, ll);
mapImages.add(new DrawableImage(screenImage.getImage(),
mapCoverage, screenImage.getMode()));
}
target.clearClippingPlane();
target.drawRasters(paintProps, mapImages.toArray(new DrawableImage[0]));
target.setupClippingPlane(paintProps.getClippingPane());
}
@Override
public int getCompatibilityValue(IGraphicsTarget target) {
return Compatibilty.GENERIC;

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.core.drawables.ext;
import com.raytheon.uf.viz.core.DrawableColorMap;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
@ -35,9 +36,11 @@ import com.raytheon.uf.viz.core.exception.VizException;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Jan 14, 2014 2313 bsteffen Add method to draw images.
*
*
* </pre>
*
@ -48,33 +51,59 @@ import com.raytheon.uf.viz.core.exception.VizException;
public interface ICanvasRenderingExtension extends IGraphicsExtensionInterface {
/**
* Draw the DrawableString object to the screen, the location of the
* Draw the DrawableString objects to the screen, the location of the
* draqwable strings should be in canvas pixels which start at 0,0 in the
* upper left.
*
* @param parameters
* @param paintProps
* the current frame paint properties
* @param strings
* the strings to draw.
* @throws VizException
*/
public abstract void drawStrings(PaintProperties paintProps,
DrawableString... parameters) throws VizException;
DrawableString... strings) throws VizException;
/**
* Draw the DrawableLine object to the screen. The points in the line should
* be in canvas pixels which start at 0,0 in the upper left.
* Draw the DrawableLine objects to the screen. The points in the line
* should be in canvas pixels which start at 0,0 in the upper left.
*
* @param paintProps
* the current frame paint properties
*
* @param lines
* the lines to draw.
*
* @param parameters
* @throws VizException
*/
public abstract void drawLines(PaintProperties paintProps,
DrawableLine... parameters) throws VizException;
DrawableLine... lines) throws VizException;
/**
* Draw the drawable colormap to the screen, the extent of the colormap
* should be in canvas pixels.
*
* @param paintProps
* the current frame paint properties
* @param colorMap
* the colorMap to draw
* @throws VizException
*/
public abstract void drawColorRamp(PaintProperties paintProps,
DrawableColorMap colorMap) throws VizException;
/**
* Draw the drawable images to the screen. the coordinates in the pixel
* coverage should be specified in canvas pixels.
*
* @param paintProps
* the current frame paint properties
* @param images
* the images to draw
* @throws VizException
*
* @since 1.14.0
*/
public abstract void drawImages(PaintProperties paintProps,
DrawableImage... images) throws VizException;
}

View file

@ -1,133 +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.uf.viz.core.interp;
import jep.INumpyable;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 8, 2009 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class InterpolationContainer implements INumpyable {
private float[] xValues;
private float[] yValues;
private float[] zValues;
private float[] xSpace;
private float[] ySpace;
private float[] interpValues;
public InterpolationContainer(float[] xValues, float[] yValues,
float[] zValues) {
this.xValues = xValues;
this.yValues = yValues;
this.zValues = zValues;
}
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumpy()
*/
@Override
public Object[] getNumpy() {
// todo
return new Object[] { xValues, yValues, zValues };
}
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumpyX()
*/
@Override
public int getNumpyX() {
return xValues.length;
}
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumpyY()
*/
@Override
public int getNumpyY() {
return 1;
}
public void setResults(float[] XI, float[] YI, float[] ZI) {
this.xSpace = XI;
this.ySpace = YI;
this.interpValues = ZI;
}
public float[] getXSpace() {
return xSpace;
}
public float[] getYSpace() {
return ySpace;
}
public float[] getInterpValues() {
return interpValues;
}
public float[] getXValues() {
return xValues;
}
public float[] getYValues() {
return yValues;
}
public float[] getZValues() {
return zValues;
}
public void setXValues(float[] values) {
xValues = values;
}
public void setYValues(float[] values) {
yValues = values;
}
public void setZValues(float[] values) {
zValues = values;
}
}

View file

@ -1,140 +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.uf.viz.core.interp;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import jep.JepException;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PythonScript;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.Activator;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.core.slice.request.HeightScale.ScaleType;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 8, 2009 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class PythonInterpolation implements IInterpolation {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(PythonInterpolation.class);
/** the python function to call */
protected String function;
protected String localizationScript = "scripts/interpolation.py";
protected static PythonScript ps = null;
protected File interpolationFile = null;
public PythonInterpolation(ScaleType scale) {
switch (scale) {
case LIN: {
function = "linInterpolate";
break;
}
default: {
function = "logInterpolate";
}
}
}
/*
* (non-Javadoc)
*
* @seecom.raytheon.uf.viz.core.interp.IInterpolation#interpolate(
* com.raytheon.uf.viz.core.interp.InterpolationRequest,
* org.geotools.coverage.grid.GridGeometry2D)
*/
@Override
public InterpolationResult interpolate(InterpolationRequest request) {
long t0 = System.currentTimeMillis();
InterpolationContainer container = new InterpolationContainer(request
.getXData(), request.getYData(), request.getZData());
try {
if (interpolationFile == null) {
interpolationFile = PathManagerFactory.getPathManager()
.getStaticLocalizationFile(localizationScript)
.getFile();
}
if (ps == null) {
String file = interpolationFile.getAbsolutePath();
ps = new PythonScript(file, "", PythonInterpolation.class
.getClassLoader());
}
Map<String, Object> args = new HashMap<String, Object>();
args.put("data", container);
args.put("gridX", request.getGridX());
args.put("gridY", request.getGridY());
args.put("xMin", request.getMinX());
args.put("xMax", request.getMaxX());
args.put("yMin", request.getMinY());
args.put("yMax", request.getMaxY());
ps.execute(function, args);
System.out.println("Time to execute interpolation: "
+ (System.currentTimeMillis() - t0));
InterpolationResult result = new InterpolationResult();
result.setValues(container.getInterpValues());
float[] xspace = container.getXSpace();
float[] yspace = container.getYSpace();
double minX = Math.min(xspace[0], xspace[xspace.length - 1]);
double maxX = Math.max(xspace[0], xspace[xspace.length - 1]);
double minY = Math.min(yspace[0], yspace[yspace.length - 1]);
double maxY = Math.max(yspace[0], yspace[yspace.length - 1]);
GeneralEnvelope env = new GeneralEnvelope(
new double[] { minX, minY }, new double[] { maxX, maxY });
GeneralGridEnvelope range = new GeneralGridEnvelope(new int[] { 0,
0 }, new int[] { xspace.length, yspace.length }, false);
result.setGeometry(new GridGeometry2D(range, env));
return result;
} catch (JepException e) {
statusHandler.handle(Priority.CRITICAL,
"Error running interpolation", e);
}
return null;
}
}

View file

@ -2,20 +2,17 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Drawing
Bundle-SymbolicName: com.raytheon.uf.viz.drawing;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 1.14.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.drawing.Activator
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core
Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
com.raytheon.viz.ui;bundle-version="1.12.1174",
org.geotools,
com.raytheon.viz.core;bundle-version="1.12.1174"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Import-Package: com.raytheon.uf.common.time,
com.vividsolutions.jts.geom
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.0",
org.eclipse.ui;bundle-version="3.8.0",
org.eclipse.core.runtime;bundle-version="3.8.0",
com.raytheon.uf.common.geospatial,
com.raytheon.viz.ui,
com.raytheon.uf.common.time
Import-Package: com.raytheon.viz.core
Export-Package: com.raytheon.uf.viz.drawing

View file

@ -20,4 +20,39 @@
-->
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.ui.commands">
<command
defaultHandler="com.raytheon.uf.viz.drawing.image.OpenImageFileAction"
id="com.raytheon.uf.viz.image.file.rsc"
name="Open Image">
<commandParameter
id="imageImportMode"
name="imageImportMode"
optional="true">
</commandParameter>
</command>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="menu:import">
<command
commandId="com.raytheon.uf.viz.image.file.rsc"
label="Background..."
style="push">
<parameter
name="imageImportMode"
value="Background">
</parameter>
</command>
<command
commandId="com.raytheon.uf.viz.image.file.rsc"
label="Image..."
style="push">
</command>
</menuContribution>
</extension>
</plugin>

View file

@ -0,0 +1,307 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.drawing.image;
import java.util.EnumSet;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.viz.ui.input.InputAdapter;
/**
* Input handler for editing a rectangle. Provides the ability to move and
* resize, moving edges individually or from a corner.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 15, 2014 2313 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class EditRectangleInputHandler extends InputAdapter {
private static final int CLICK_WIDTH = 15;
private static final int MOUSE_BUTTON = 1;
private final EditRectangleTarget target;
private EnumSet<ResizeDirection> activeModes = EnumSet
.noneOf(ResizeDirection.class);
private Point movePoint = null;
public EditRectangleInputHandler(EditRectangleTarget target) {
this.target = target;
}
@Override
public boolean handleMouseMove(int x, int y) {
Rectangle rect = target.getRectangle();
if (rect == null) {
return false;
}
if (ResizeDirection.NORTH.intersects(rect, x, y)) {
if (ResizeDirection.EAST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZENE);
} else if (ResizeDirection.WEST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZENW);
} else {
setCursor(SWT.CURSOR_SIZEN);
}
} else if (ResizeDirection.SOUTH.intersects(rect, x, y)) {
if (ResizeDirection.EAST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZESE);
} else if (ResizeDirection.WEST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZESW);
} else {
setCursor(SWT.CURSOR_SIZES);
}
} else if (ResizeDirection.EAST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZEE);
} else if (ResizeDirection.WEST.intersects(rect, x, y)) {
setCursor(SWT.CURSOR_SIZEW);
} else if (rect.contains(x, y)) {
setCursor(SWT.CURSOR_HAND);
} else {
unsetCursor();
}
return true;
}
@Override
public boolean handleMouseDown(int x, int y, int mouseButton) {
if (mouseButton != MOUSE_BUTTON) {
return false;
}
Rectangle rect = target.getRectangle();
if (rect == null) {
return false;
}
for (ResizeDirection mode : ResizeDirection.values()) {
if (mode.intersects(rect, x, y)) {
activeModes.add(mode);
}
}
if (activeModes.isEmpty()) {
if (rect.contains(x, y)) {
movePoint = new Point(x, y);
return true;
}
return false;
} else {
return true;
}
}
@Override
public boolean handleMouseDownMove(int x, int y, int mouseButton) {
if (mouseButton != MOUSE_BUTTON) {
return false;
}
Rectangle rect = target.getRectangle();
if (rect == null) {
return false;
}
if (movePoint != null) {
int xDist = x - movePoint.x;
int yDist = y - movePoint.y;
target.resize(new Rectangle(rect.x + xDist, rect.y + yDist,
rect.width, rect.height));
movePoint = new Point(x, y);
setCursor(SWT.CURSOR_SIZEALL);
return true;
} else if (!activeModes.isEmpty()) {
for (ResizeDirection mode : activeModes) {
rect = mode.resize(rect, x, y);
}
target.resize(rect);
return true;
}
return false;
}
@Override
public boolean handleMouseUp(int x, int y, int mouseButton) {
if (handleMouseDownMove(x, y, mouseButton)) {
activeModes.clear();
movePoint = null;
handleMouseMove(x, y);
return true;
} else {
return false;
}
}
@Override
public boolean handleMouseExit(Event event) {
unsetCursor();
return false;
}
@Override
public boolean handleMouseEnter(Event event) {
return handleMouseMove(event.x, event.y);
}
public void enable(IDisplayPaneContainer container) {
if (container == null) {
return;
}
container.registerMouseHandler(this);
}
public void disable(IDisplayPaneContainer container) {
if (container == null) {
return;
}
container.unregisterMouseHandler(this);
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
unsetCursor();
}
});
}
protected void unsetCursor() {
getShell().setCursor(null);
}
protected void setCursor(int cursor) {
Shell shell = getShell();
Display display = shell.getDisplay();
shell.setCursor(display.getSystemCursor(cursor));
}
protected Shell getShell() {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
return window.getShell();
}
public static interface EditRectangleTarget {
public Rectangle getRectangle();
public void resize(Rectangle rect);
}
private static enum ResizeDirection {
NORTH {
public boolean intersects(Rectangle rect, int cx, int cy) {
int x = rect.x - CLICK_WIDTH;
int y = rect.y - CLICK_WIDTH;
int width = rect.width + CLICK_WIDTH * 2;
int height = CLICK_WIDTH * 2;
Rectangle area = new Rectangle(x, y, width, height);
return area.contains(cx, cy);
}
public Rectangle resize(Rectangle rect, int cx, int cy) {
int x = rect.x;
int y = cy;
int width = rect.width;
int height = rect.height - y + rect.y;
return new Rectangle(x, y, width, height);
}
},
SOUTH {
public boolean intersects(Rectangle rect, int cx, int cy) {
int x = rect.x - CLICK_WIDTH;
int y = rect.y + rect.height - CLICK_WIDTH;
int width = rect.width + CLICK_WIDTH * 2;
int height = CLICK_WIDTH * 2;
Rectangle area = new Rectangle(x, y, width, height);
return area.contains(cx, cy);
}
public Rectangle resize(Rectangle rect, int cx, int cy) {
int x = rect.x;
int y = rect.y;
int width = rect.width;
int height = rect.height + cy - rect.y - rect.height;
return new Rectangle(x, y, width, height);
}
},
WEST {
public boolean intersects(Rectangle rect, int cx, int cy) {
int x = rect.x - CLICK_WIDTH;
int y = rect.y - CLICK_WIDTH;
int width = CLICK_WIDTH * 2;
int height = rect.height + CLICK_WIDTH * 2;
Rectangle area = new Rectangle(x, y, width, height);
return area.contains(cx, cy);
}
public Rectangle resize(Rectangle rect, int cx, int cy) {
int x = cx;
int y = rect.y;
int width = rect.width - cx + rect.x;
int height = rect.height;
return new Rectangle(x, y, width, height);
}
},
EAST {
public boolean intersects(Rectangle rect, int cx, int cy) {
int x = rect.x + rect.width - CLICK_WIDTH;
int y = rect.y - CLICK_WIDTH;
int width = CLICK_WIDTH * 2;
int height = rect.height + CLICK_WIDTH * 2;
Rectangle area = new Rectangle(x, y, width, height);
return area.contains(cx, cy);
}
public Rectangle resize(Rectangle rect, int cx, int cy) {
int x = rect.x;
int y = rect.y;
int width = rect.width + cx - rect.x - rect.width;
int height = rect.height;
return new Rectangle(x, y, width, height);
}
};
public abstract boolean intersects(Rectangle rect, int cx, int cy);
public abstract Rectangle resize(Rectangle rect, int cx, int cy);
};
}

View file

@ -0,0 +1,187 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.drawing.image;
import org.eclipse.swt.graphics.Rectangle;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.ICanvasRenderingExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.drawing.image.EditRectangleInputHandler.EditRectangleTarget;
import com.vividsolutions.jts.geom.Coordinate;
/**
* Resource for displaying a non geolocated image.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 15, 2014 2313 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class ImageFileResource extends
AbstractVizResource<ImageFileResourceData, IDescriptor> implements
EditRectangleTarget {
private IImage image;
private EditRectangleInputHandler inputHandler;
private Rectangle canvasBounds;
protected ImageFileResource(ImageFileResourceData resourceData,
LoadProperties loadProperties) {
super(resourceData, loadProperties);
inputHandler = new EditRectangleInputHandler(this);
}
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
image = target.initializeRaster(new RenderedImageFileCallback(
resourceData.getFile()));
checkEditable();
checkImagingProperties();
}
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
canvasBounds = paintProps.getCanvasBounds();
Rectangle rect = getRectangle();
Coordinate ul = new Coordinate(rect.x, rect.y);
Coordinate ur = new Coordinate(rect.x + rect.width, rect.y);
Coordinate lr = new Coordinate(rect.x + rect.width, rect.y
+ rect.height);
Coordinate ll = new Coordinate(rect.x, rect.y + rect.height);
PixelCoverage pc = new PixelCoverage(ul, ur, lr, ll);
ICanvasRenderingExtension renderer = target
.getExtension(ICanvasRenderingExtension.class);
renderer.drawImages(paintProps, new DrawableImage(image, pc));
EditableCapability eCap = getCapability(EditableCapability.class);
if (eCap.isEditable()) {
DrawableLine box = new DrawableLine();
ColorableCapability cCap = getCapability(ColorableCapability.class);
box.basics.color = cCap.getColor();
box.width = 3.0f;
box.addPoint(ul.x, ul.y);
box.addPoint(ur.x, ur.y);
box.addPoint(lr.x, lr.y);
box.addPoint(ll.x, ll.y);
box.addPoint(ul.x, ul.y);
renderer.drawLines(paintProps, box);
}
}
@Override
protected void disposeInternal() {
if (image != null) {
image.dispose();
image = null;
}
inputHandler.disable(getResourceContainer());
}
@Override
protected void resourceDataChanged(ChangeType type, Object updateObject) {
super.resourceDataChanged(type, updateObject);
if (type == ChangeType.CAPABILITY) {
if (updateObject instanceof EditableCapability) {
checkEditable();
} else if (updateObject instanceof ImagingCapability) {
checkImagingProperties();
}
}
}
@Override
public String getName() {
return resourceData.getFile().getName();
}
@Override
public Rectangle getRectangle() {
if (canvasBounds == null) {
return null;
}
int north = (int) (canvasBounds.y + resourceData.getNorth()
* canvasBounds.height / 100.0);
int east = (int) (canvasBounds.x + resourceData.getEast()
* canvasBounds.width / 100.0);
int south = (int) (canvasBounds.y + resourceData.getSouth()
* canvasBounds.height / 100.0);
int west = (int) (canvasBounds.x + resourceData.getWest()
* canvasBounds.width / 100.0);
return new Rectangle(west, north, east - west, south - north);
}
@Override
public void resize(Rectangle rect) {
resourceData.setNorth((rect.y - canvasBounds.y) * 100.0
/ canvasBounds.height);
resourceData.setEast((rect.x + rect.width - canvasBounds.x) * 100.0
/ canvasBounds.width);
resourceData.setSouth((rect.y + rect.height - canvasBounds.y) * 100.0
/ canvasBounds.height);
resourceData.setWest((rect.x - canvasBounds.x) * 100.0
/ canvasBounds.width);
issueRefresh();
}
protected void checkEditable() {
EditableCapability eCap = getCapability(EditableCapability.class);
if (eCap.isEditable()) {
inputHandler.enable(getResourceContainer());
} else {
inputHandler.disable(getResourceContainer());
}
issueRefresh();
}
protected void checkImagingProperties() {
if (image != null) {
ImagingCapability iCap = getCapability(ImagingCapability.class);
image.setBrightness(iCap.getBrightness());
image.setContrast(iCap.getContrast());
}
}
}

View file

@ -0,0 +1,184 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.drawing.image;
import java.io.File;
import javax.annotation.Generated;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
* Resource data for displaying a non geolocated image, contains an image file
* name and position.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 15, 2014 2313 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class ImageFileResourceData extends AbstractResourceData {
@XmlAttribute
private String fileName;
@XmlAttribute
private double north = 0;
@XmlAttribute
private double east = 100;
@XmlAttribute
private double south = 100;
@XmlAttribute
private double west = 0;
public ImageFileResourceData() {
super();
}
public ImageFileResourceData(String fileName) {
this();
this.fileName = fileName;
}
@Override
public ImageFileResource construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
return new ImageFileResource(this, loadProperties);
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public double getNorth() {
return north;
}
public void setNorth(double north) {
this.north = north;
}
public double getEast() {
return east;
}
public void setEast(double east) {
this.east = east;
}
public double getSouth() {
return south;
}
public void setSouth(double south) {
this.south = south;
}
public double getWest() {
return west;
}
public void setWest(double west) {
this.west = west;
}
public File getFile() {
return new File(fileName);
}
@Override
public void update(Object updateData) {
// Nothing updates this resource
}
@Override
@Generated(value = "org.eclipse.jdt.ui.actions.GenerateHashCodeEqualsAction", comments = "3.8.2.v20130107-165834")
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(east);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result
+ ((fileName == null) ? 0 : fileName.hashCode());
temp = Double.doubleToLongBits(north);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(south);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(west);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
@Generated(value = "org.eclipse.jdt.ui.actions.GenerateHashCodeEqualsAction", comments = "3.8.2.v20130107-165834")
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ImageFileResourceData other = (ImageFileResourceData) obj;
if (Double.doubleToLongBits(east) != Double
.doubleToLongBits(other.east))
return false;
if (fileName == null) {
if (other.fileName != null)
return false;
} else if (!fileName.equals(other.fileName))
return false;
if (Double.doubleToLongBits(north) != Double
.doubleToLongBits(other.north))
return false;
if (Double.doubleToLongBits(south) != Double
.doubleToLongBits(other.south))
return false;
if (Double.doubleToLongBits(west) != Double
.doubleToLongBits(other.west))
return false;
return true;
}
}

View file

@ -0,0 +1,178 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.drawing.image;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
import com.raytheon.viz.core.ColorUtil;
import com.raytheon.viz.ui.EditorUtil;
/**
*
* Action for loading an image onto the screen.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 15, 2014 2313 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class OpenImageFileAction extends AbstractHandler {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(OpenImageFileAction.class);
private static final String BACKGROUND = "Background";
@Override
public Object execute(ExecutionEvent event) {
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
if (container == null) {
return null;
}
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
FileDialog fd = new FileDialog(shell, SWT.OPEN);
fd.setText("Import Image");
String[] suffixes = ImageIO.getReaderFileSuffixes();
StringBuilder filter = new StringBuilder(suffixes.length * 7);
for (String suffix : suffixes) {
if (!suffix.isEmpty()) {
if (filter.length() != 0) {
filter.append(';');
}
filter.append("*.").append(suffix);
}
}
fd.setFilterExtensions(new String[] { filter.toString() });
fd.setFilterNames(new String[] { "All Images" });
if (fd.open() == null) {
return null;
}
String fileName = fd.getFilterPath() + File.separator
+ fd.getFileName();
IRenderableDisplay display = container.getActiveDisplayPane()
.getRenderableDisplay();
IDescriptor desc = display.getDescriptor();
ImageFileResourceData data = new ImageFileResourceData(fileName);
LoadProperties lProps = new LoadProperties();
/* Get a new resource color */
ColorableCapability cCap = lProps.getCapabilities().getCapability(data,
ColorableCapability.class);
RGB color = ColorUtil.getNewColor(desc);
cCap.setColor(color);
ResourceProperties rProps = new ResourceProperties();
String importMode = event.getParameter("imageImportMode");
if (BACKGROUND.equalsIgnoreCase(importMode)) {
/* Render as background */
rProps.setRenderingOrder(ResourceOrder.LOWEST.value);
/* Fill the screen */
data.setNorth(0);
data.setWest(0);
data.setSouth(100);
data.setEast(100);
} else {
/* Render as foreground */
rProps.setRenderingOrder(ResourceOrder.HIGHEST.value);
/* Size the same as the image */
Rectangle canvasBounds = display.getBounds();
Rectangle imageBounds;
try {
imageBounds = getImageBounds(fileName);
} catch (IOException e) {
statusHandler.handle(Priority.PROBLEM, "Error Loading Image.",
e);
return null;
}
data.setNorth(0);
data.setWest(0);
data.setEast(imageBounds.width * 100.0 / canvasBounds.width);
data.setSouth(imageBounds.height * 100.0 / canvasBounds.height);
}
try {
ImageFileResource rsc = data.construct(lProps, desc);
desc.getResourceList().add(rsc, rProps);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM, "Error Loading Image.", e);
}
return null;
}
protected static Rectangle getImageBounds(String fileName)
throws IOException {
Rectangle imageBounds = null;
ImageInputStream in = ImageIO
.createImageInputStream(new File(fileName));
ImageReader reader = null;
try {
Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
reader = readers.next();
reader.setInput(in);
imageBounds = new Rectangle(0, 0, reader.getWidth(0),
reader.getHeight(0));
}
} finally {
in.close();
if (reader != null) {
reader.dispose();
}
}
return imageBounds;
}
}

View file

@ -0,0 +1,66 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.drawing.image;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.exception.VizException;
/**
*
* Callback which loads an image from a file when it is needed for rendering.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jan 15, 2014 2313 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class RenderedImageFileCallback implements
IRenderedImageCallback {
private final File file;
public RenderedImageFileCallback(File file) {
super();
this.file = file;
}
@Override
public RenderedImage getImage() throws VizException {
try {
return ImageIO.read(file);
} catch (IOException e) {
throw new VizException(e);
}
}
}

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.viz.kml.export.graphics.ext;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@ -34,12 +35,17 @@ import java.util.Map;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.DrawableColorMap;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment;
import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle;
import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
import com.raytheon.uf.viz.core.drawables.ext.ICanvasRenderingExtension;
@ -48,6 +54,7 @@ import com.raytheon.uf.viz.kml.export.KmlFeatureGenerator;
import com.raytheon.uf.viz.kml.export.graphics.KmlFont;
import com.raytheon.uf.viz.kml.export.graphics.KmlGraphicsTarget;
import com.raytheon.uf.viz.kml.export.io.KmlOutputManager;
import com.vividsolutions.jts.geom.Coordinate;
import de.micromata.opengis.kml.v_2_2_0.ScreenOverlay;
import de.micromata.opengis.kml.v_2_2_0.Units;
@ -60,9 +67,10 @@ import de.micromata.opengis.kml.v_2_2_0.Vec2;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Jun 26, 2012 bsteffen Initial creation
* Jan 14, 2013 2313 bsteffen Add image rendering
*
* </pre>
*
@ -74,6 +82,9 @@ public class KmlCanvasRenderingExtension extends
GraphicsExtension<KmlGraphicsTarget> implements
ICanvasRenderingExtension {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(KmlCanvasRenderingExtension.class);
@Override
public void drawStrings(PaintProperties paintProps,
DrawableString... parameters) throws VizException {
@ -92,6 +103,13 @@ public class KmlCanvasRenderingExtension extends
getGenerator(paintProps).addColorMaps(colorMap);
}
@Override
public void drawImages(PaintProperties paintProps, DrawableImage... images)
throws VizException {
getGenerator(paintProps).addImages(images);
}
protected Generator getGenerator(PaintProperties paintProps) {
for (KmlFeatureGenerator generator : target.getGenerators()) {
if (generator instanceof Generator) {
@ -152,6 +170,10 @@ public class KmlCanvasRenderingExtension extends
this.objects.addAll(Arrays.asList(colorMaps));
}
public void addImages(DrawableImage... colorMaps) {
this.objects.addAll(Arrays.asList(colorMaps));
}
@Override
public void addFeature(KmlOutputManager outputManager) {
Map<Object, Rectangle2D> boundsMap = new IdentityHashMap<Object, Rectangle2D>();
@ -181,16 +203,18 @@ public class KmlCanvasRenderingExtension extends
Vec2 screenxy = overlay.createAndSetScreenXY();
screenxy.withXunits(Units.FRACTION).withYunits(Units.FRACTION);
// This is fairly complex placement code but it produces rather
// nice results on any size of display. Basically if something
// is flush against either the left or right of the screen it
// ends up anchored on that side, if some is smack in the center
// than the anchor point is in the middle of both the overlay
// and the display. Now if an object is offcenter to the left or
// right than the anchor point moves in the correct direction in
// proportion to how far off center it is, its hard to explain
// without a picture but at the end of the day it produces a
// nice result.
/*
* This is fairly complex placement code but it produces rather
* nice results on any size of display. Basically if something
* is flush against either the left or right of the screen it
* ends up anchored on that side, if some is smack in the center
* than the anchor point is in the middle of both the overlay
* and the display. Now if an object is offcenter to the left or
* right than the anchor point moves in the correct direction in
* proportion to how far off center it is, its hard to explain
* without a picture but at the end of the day it produces a
* nice result.
*/
double leftFrac = bounds.getMinX() / canvasBounds.width;
double rightFrac = 1.0 - bounds.getMaxX() / canvasBounds.width;
if (leftFrac < rightFrac) {
@ -210,8 +234,10 @@ public class KmlCanvasRenderingExtension extends
} else {
overlayxy.setY(botFrac / topFrac / 2);
}
// all this 1.0 - stuff is because the math is mostly assuming 0
// is up and 1.0 is down but kml expects the opposite.
/*
* all this 1.0 - stuff is because the math is mostly assuming 0
* is up and 1.0 is down but kml expects the opposite.
*/
double y = 1.0
- (bounds.getY() + bounds.getHeight()
* (1.0 - overlayxy.getY()))
@ -230,8 +256,10 @@ public class KmlCanvasRenderingExtension extends
Rectangle2D b = it.next();
if (b.intersects(bounds)) {
if (!b.contains(bounds)) {
// need to recheck the larger rectangle of b for any new
// intersections.
/*
* need to recheck the larger rectangle of b for any new
* intersections.
*/
it.remove();
b.add(bounds);
addBounds(allBounds, b);
@ -250,6 +278,8 @@ public class KmlCanvasRenderingExtension extends
drawLines(graphics, imageBounds, (DrawableLine) object);
} else if (object instanceof DrawableColorMap) {
drawColorMap(graphics, imageBounds, (DrawableColorMap) object);
} else if (object instanceof DrawableImage) {
drawImage(graphics, imageBounds, (DrawableImage) object);
}
}
@ -330,6 +360,25 @@ public class KmlCanvasRenderingExtension extends
}
}
protected void drawImage(Graphics graphics, Rectangle2D imageBounds,
DrawableImage image) {
KmlRasterImage kmlImage = (KmlRasterImage) image.getImage();
PixelCoverage coverage = image.getCoverage();
Coordinate ul = coverage.getUl();
Coordinate lr = coverage.getLr();
try {
Image toDraw = (Image) kmlImage.getImage();
int x = (int) (ul.x - imageBounds.getX());
int y = (int) (ul.y - imageBounds.getY());
int w = (int) (lr.x - ul.x);
int h = (int) (lr.y - ul.y);
graphics.drawImage(toDraw, x, y, w, h, null);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
e);
}
}
protected void setColor(Graphics graphics, RGB color) {
graphics.setColor(new Color(color.red, color.green, color.blue));
}
@ -341,6 +390,8 @@ public class KmlCanvasRenderingExtension extends
return getLineBounds((DrawableLine) object);
} else if (object instanceof DrawableColorMap) {
return getColorMapBounds((DrawableColorMap) object);
} else if (object instanceof DrawableImage) {
return getImageBounds((DrawableImage) object);
}
return null;
}
@ -354,8 +405,10 @@ public class KmlCanvasRenderingExtension extends
bounds.add(point[0], point[1]);
}
}
// add a buffer region to ensure we have room for wide lines on
// the edge.
/*
* add a buffer region to ensure we have room for wide lines on the
* edge.
*/
bounds.add(bounds.getMinX() - line.width, bounds.getMinY()
- line.width);
bounds.add(bounds.getMaxX() + line.width, bounds.getMaxY()
@ -407,6 +460,13 @@ public class KmlCanvasRenderingExtension extends
colorMap.extent.getMinY(), colorMap.extent.getWidth(),
colorMap.extent.getHeight());
}
protected Rectangle2D getImageBounds(DrawableImage image) {
PixelCoverage coverage = image.getCoverage();
Coordinate ul = coverage.getUl();
Coordinate lr = coverage.getLr();
return new Rectangle2D.Double(ul.x, ul.y, lr.x - ul.x, lr.y - ul.y);
}
}
}

View file

@ -64,7 +64,6 @@ import com.raytheon.viz.core.imagery.ImageCombiner.IImageCombinerListener;
import com.raytheon.viz.ui.VizWorkbenchManager;
import com.raytheon.viz.ui.dialogs.ColormapComp.IColormapCompChangeListener;
import com.raytheon.viz.ui.dialogs.colordialog.ColorEditDialog;
import com.raytheon.viz.ui.editor.AbstractEditor;
import com.raytheon.viz.ui.editor.IMultiPaneEditor;
/**
@ -72,18 +71,23 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 26, 2006 chammack Initial Creation.
* Jul 10, 2008 #980 lvenable Changed to a SWT dialog to correct a problem
* caused by a JFace/shell issue. I also rearranged
* the controls a bit, used labels instead of text
* controls since the text is not being edited, changed
* sliders to scales, added tooltiptext to buttons to
* show full colormap names, and added comments &amp; Javadoc.
* Aug 20, 2008 dglazesk Updated for the new ColorMap interface
* Feb 10, 2011 #7842 bkowal set caveStyle for dialog to INDEPENDENT SHELL
* Oct 17, 2012 #1229 rferrel Make dialog non-blocking.
* Date Ticket# Engineer Description
* ------------- -------- ----------- -----------------------------------------
* Nov 26, 2006 chammack Initial Creation.
* Jul 10, 2008 980 lvenable Changed to a SWT dialog to correct a
* problem caused by a JFace/shell issue. I
* also rearranged the controls a bit, used
* labels instead of text controls since the
* text is not being edited, changed sliders
* to scales, added tooltiptext to buttons to
* show full colormap names, and added
* comments &amp; Javadoc.
* Aug 20, 2008 dglazesk Updated for the new ColorMap interface
* Feb 10, 2011 7842 bkowal set caveStyle for dialog to INDEPENDENT
* SHELL
* Oct 17, 2012 1229 rferrel Make dialog non-blocking.
* Jan 15, 2015 2313 bsteffen Disable color map selection when
* ColorMapCapability is not present.
*
* </pre>
*
@ -707,26 +711,6 @@ public class ImagingDialog extends CaveSWTDialog implements
contrastScale.setEnabled(true);
interpolationChk.setEnabled(true);
final ColorMapCapability cmcap = topResource
.getCapability(ColorMapCapability.class);
String currentCMap = "Not Selected";
if (cmcap.getColorMapParameters() != null
&& cmcap.getColorMapParameters().getColorMap() != null) {
currentCMap = cmcap.getColorMapParameters().getColorMap()
.getName();
if (currentCMap == null) {
currentCMap = "";
}
}
topColormapComp.setCap(cmcap);
topColormapComp.setParams(cmcap.getColorMapParameters());
if (currentCMap != null) {
if (currentCMap.isEmpty()) {
currentCMap = UNSAVED_CMAP_DISPLAY_NAME;
}
topColormapComp.getCMapButton().setText(currentCMap);
}
String topResourceName = topResource.getName();
if (editables.size() > 1) {
if (blended) {
@ -742,8 +726,35 @@ public class ImagingDialog extends CaveSWTDialog implements
} else {
topColorMapButton.setToolTipText(null);
}
topColorMapButton.setText("Edit " + topResourceName);
if (topResource.hasCapability(ColorMapCapability.class)) {
final ColorMapCapability cmcap = topResource
.getCapability(ColorMapCapability.class);
String currentCMap = "Not Selected";
if (cmcap.getColorMapParameters() != null
&& cmcap.getColorMapParameters().getColorMap() != null) {
currentCMap = cmcap.getColorMapParameters().getColorMap()
.getName();
if (currentCMap == null) {
currentCMap = "";
}
}
topColormapComp.setCap(cmcap);
topColormapComp.setParams(cmcap.getColorMapParameters());
if (currentCMap.isEmpty()) {
currentCMap = UNSAVED_CMAP_DISPLAY_NAME;
}
topColormapComp.getCMapButton().setText(currentCMap);
topColorMapButton.setText("Edit " + topResourceName);
} else {
topColorMapButton.setText(topResourceName
+ " is not color mapped.");
topColormapComp.getCMapButton().setText("Not Selected");
topColorMapButton.setEnabled(false);
topColormapComp.getCMapButton().setEnabled(false);
interpolationChk.setEnabled(false);
interpolationChk.setSelection(false);
}
ImagingCapability imgCap = topResource
.getCapability(ImagingCapability.class);
brightnessScale
@ -804,12 +815,10 @@ public class ImagingDialog extends CaveSWTDialog implements
bottomColormapComp.setCap(bottomCap);
bottomColormapComp.setParams(bottomCap.getColorMapParameters());
if (currentCMap != null) {
if (currentCMap.isEmpty()) {
currentCMap = UNSAVED_CMAP_DISPLAY_NAME;
}
bottomColormapComp.getCMapButton().setText(currentCMap);
if (currentCMap.isEmpty()) {
currentCMap = UNSAVED_CMAP_DISPLAY_NAME;
}
bottomColormapComp.getCMapButton().setText(currentCMap);
String bottomResourceName = bottomResource.getName();
if (editables.size() > 1) {
@ -925,7 +934,7 @@ public class ImagingDialog extends CaveSWTDialog implements
@Override
public void editorChanged(IDisplayPaneContainer container) {
IDisplayPaneContainer oldEditor = currentEditor;
currentEditor = (AbstractEditor) container;
currentEditor = container;
refreshComponents();
setupListeners(oldEditor, currentEditor);
}