Omaha #3974 initial extensible drawing of polygons and preliminary
damage path tool Change-Id: I0355b0a8a889bb0339412e4ad17e1b3f678d06c2 Former-commit-id: 9e748a3b6f49c17e7b9d84af1d4953b70a647b0a
This commit is contained in:
parent
995d60fb54
commit
672b872990
19 changed files with 1418 additions and 18 deletions
|
@ -41,10 +41,17 @@
|
|||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.points"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.raytheon.uf.viz.damagepath"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
</feature>
|
||||
|
|
7
cave/com.raytheon.uf.viz.damagepath/.classpath
Normal file
7
cave/com.raytheon.uf.viz.damagepath/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cave/com.raytheon.uf.viz.damagepath/.project
Normal file
28
cave/com.raytheon.uf.viz.damagepath/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.damagepath</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
12
cave/com.raytheon.uf.viz.damagepath/META-INF/MANIFEST.MF
Normal file
12
cave/com.raytheon.uf.viz.damagepath/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,12 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Damage Path
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.damagepath
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.6",
|
||||
com.raytheon.uf.viz.drawing;bundle-version="1.14.0",
|
||||
com.raytheon.uf.common.time;bundle-version="1.14.0",
|
||||
com.raytheon.uf.common.geospatial;bundle-version="1.14.2"
|
||||
Export-Package: com.raytheon.uf.viz.damagepath
|
5
cave/com.raytheon.uf.viz.damagepath/build.properties
Normal file
5
cave/com.raytheon.uf.viz.damagepath/build.properties
Normal file
|
@ -0,0 +1,5 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
localization/
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||
|
||||
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||
This_software_product_contains_export-restricted_data_whose
|
||||
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||
an_export_license_or_other_authorization.
|
||||
|
||||
Contractor_Name:________Raytheon_Company
|
||||
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||
________________________Mail_Stop_B8
|
||||
________________________Omaha,_NE_68106
|
||||
________________________402.291.0100
|
||||
|
||||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<bundle>
|
||||
<displayList>
|
||||
<displays xsi:type="mapRenderableDisplay" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<descriptor xsi:type="mapDescriptor">
|
||||
<resource>
|
||||
<loadProperties/>
|
||||
<resourceData xsi:type="damagePathResourceData" />
|
||||
</resource>
|
||||
</descriptor>
|
||||
</displays>
|
||||
</displayList>
|
||||
</bundle>
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
|
||||
import com.raytheon.uf.viz.drawing.polygon.PolygonUtil;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* A layer for displaying and customizing a weather event's damage path.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 19, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||
PolygonLayer<T> {
|
||||
|
||||
protected static final String NAME = "Damage Path";
|
||||
|
||||
public DamagePathLayer(T resourceData, LoadProperties loadProperties) {
|
||||
super(resourceData, loadProperties);
|
||||
|
||||
/*
|
||||
* TODO default load from localization file that contains geoJSON
|
||||
* version of the damage track
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initInternal(IGraphicsTarget target) throws VizException {
|
||||
super.initInternal(target);
|
||||
if (polygon == null) {
|
||||
polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer()
|
||||
.getActiveDisplayPane().getRenderableDisplay());
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO potentially need to register to listen to changes to a damage
|
||||
* track file at the site level to support showing the damage track on
|
||||
* multiple workstations. That will get complicated if we are planning
|
||||
* on supporting more than one damage path at a time though.
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
protected Polygon loadLocalizationPolygon(LocalizationFile file) {
|
||||
/*
|
||||
* TODO load from a localization file
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Polygon loadStormTrackPolygon() {
|
||||
/*
|
||||
* TODO get storm track file, use mathematical algorithm to derive
|
||||
* damage track
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Polygon loadFilesystemPolygon(File file) {
|
||||
/*
|
||||
* TODO load a polygon that was selected from a file chooser dialog from
|
||||
* an import menu
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Polygon loadMousePolygon() {
|
||||
/*
|
||||
* TODO create a new InputAdapter that takes highest priority and blocks
|
||||
* other inputs. left clicking adds vertices, right click indicates the
|
||||
* last point on the polygon, then connect the first and last point.
|
||||
*
|
||||
* afterwards, remove and dispose of that input adapter
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetPolygon(Coordinate[] coords) {
|
||||
super.resetPolygon(coords);
|
||||
|
||||
/*
|
||||
* TODO need to save the polygon to a site level localization file
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||
|
||||
/**
|
||||
* Resource data for DamagePathLayer.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 2, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class DamagePathResourceData extends AbstractResourceData {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon
|
||||
* .uf.viz.core.rsc.LoadProperties,
|
||||
* com.raytheon.uf.viz.core.drawables.IDescriptor)
|
||||
*/
|
||||
@Override
|
||||
public AbstractVizResource<?, ?> construct(LoadProperties loadProperties,
|
||||
IDescriptor descriptor) throws VizException {
|
||||
return new DamagePathLayer<DamagePathResourceData>(this, loadProperties);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.rsc.AbstractResourceData#equals(java.lang.Object
|
||||
* )
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null) {
|
||||
return this.getClass().equals(obj.getClass());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,11 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Drawing
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.drawing;singleton:=true
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.drawing.Activator
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
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",
|
||||
|
@ -14,5 +14,6 @@ Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.0",
|
|||
com.raytheon.viz.ui,
|
||||
com.raytheon.uf.common.time
|
||||
Import-Package: com.raytheon.viz.core
|
||||
Export-Package: com.raytheon.uf.viz.drawing
|
||||
Export-Package: com.raytheon.uf.viz.drawing,
|
||||
com.raytheon.uf.viz.drawing.polygon
|
||||
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.drawing;
|
||||
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
|
||||
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
|
||||
import com.raytheon.uf.viz.core.map.MapDescriptor;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||
import com.raytheon.uf.viz.drawing.polygon.filter.LatLonToScreenFilter;
|
||||
import com.raytheon.uf.viz.drawing.polygon.filter.ScreenToLatLonFilter;
|
||||
import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||
import com.raytheon.viz.ui.input.InputAdapter;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* An input adapter for a resource/layer that is displayed on a map. Provides
|
||||
* convenience methods to assist with custom input handling.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 29, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class RscInputAdapter<R extends AbstractVizResource<?, MapDescriptor>>
|
||||
extends InputAdapter {
|
||||
|
||||
protected R rsc;
|
||||
|
||||
protected LatLonToScreenFilter latlonToScreen;
|
||||
|
||||
protected ScreenToLatLonFilter screenToLatLon;
|
||||
|
||||
protected RscInputAdapter(R rsc) {
|
||||
this.rsc = rsc;
|
||||
latlonToScreen = new LatLonToScreenFilter(rsc);
|
||||
screenToLatLon = new ScreenToLatLonFilter(rsc);
|
||||
}
|
||||
|
||||
protected Coordinate screenToLatLon(int screenX, int screenY) {
|
||||
return getContainer().translateClick(screenX, screenY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the cursor with the specified cursor val
|
||||
*
|
||||
* @param cursor
|
||||
* the cursor value as specified by SWT.CURSOR_
|
||||
*/
|
||||
protected void updateCursor(int cursor) {
|
||||
IWorkbenchWindow window = VizWorkbenchManager.getInstance()
|
||||
.getCurrentWindow();
|
||||
window.getShell().setCursor(
|
||||
window.getShell().getDisplay().getSystemCursor(cursor));
|
||||
}
|
||||
|
||||
protected IDisplayPaneContainer getContainer() {
|
||||
return rsc.getResourceContainer();
|
||||
}
|
||||
|
||||
protected boolean withinDisplayBounds(int x, int y) {
|
||||
// Checks if the x/y location is within the display bounds
|
||||
IRenderableDisplay display = rsc.getDescriptor().getRenderableDisplay();
|
||||
return display.getBounds().contains(x, y);
|
||||
}
|
||||
|
||||
protected boolean availableForInput() {
|
||||
boolean available = rsc.getProperties().isVisible();
|
||||
if (rsc.hasCapability(EditableCapability.class)) {
|
||||
available = (available && rsc.getCapability(
|
||||
EditableCapability.class).isEditable());
|
||||
}
|
||||
return available;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
/**
|
||||
* 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.polygon;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
|
||||
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||
import com.raytheon.uf.viz.drawing.RscInputAdapter;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.LineString;
|
||||
import com.vividsolutions.jts.geom.LinearRing;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
import com.vividsolutions.jts.geom.util.AffineTransformation;
|
||||
|
||||
/**
|
||||
* An input adapter for editing a drawn polygon. This enables dragging a vertex,
|
||||
* dragging the entire polygon, inserting a vertex, and removing a vertex.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 19, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PolygonInputAdapter extends RscInputAdapter<PolygonLayer<?>> {
|
||||
|
||||
/**
|
||||
* a fudge factor in screen coordinates to detect if the coordinate is
|
||||
* pretty close to an edge, instead of precisely on top of an edge
|
||||
*/
|
||||
protected static final double EDGE_PROXIMITY = 4.0;
|
||||
|
||||
/** Last mouse x/y location */
|
||||
protected int lastX, lastY;
|
||||
|
||||
/** Current cursor type */
|
||||
protected int currentCursor = SWT.CURSOR_ARROW;
|
||||
|
||||
/** original vertex being dragged */
|
||||
protected int draggedVertexIndex = -1;
|
||||
|
||||
/** is the entire polygon being dragged */
|
||||
protected boolean draggingPolygon = false;
|
||||
|
||||
public PolygonInputAdapter(PolygonLayer<?> layer) {
|
||||
super(layer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseDown(int x, int y, int mouseButton) {
|
||||
boolean blockOtherHandlers = false;
|
||||
if (availableForInput()) {
|
||||
int vertexIdx = pointOnVertex(x, y);
|
||||
if (mouseButton == 1) {
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
if (vertexIdx > -1) {
|
||||
// user started dragging a vertex
|
||||
draggedVertexIndex = vertexIdx;
|
||||
} else if (pointOnPolygon(x, y)) {
|
||||
// user started dragging the entire polygon
|
||||
draggingPolygon = true;
|
||||
}
|
||||
blockOtherHandlers = isDragging();
|
||||
} else if (mouseButton == 2) {
|
||||
if (vertexIdx > -1) {
|
||||
removeVertex(vertexIdx);
|
||||
blockOtherHandlers = true;
|
||||
} else if (pointOnEdge(x, y)) {
|
||||
addVertex(x, y);
|
||||
blockOtherHandlers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return blockOtherHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseDownMove(int x, int y, int mouseButton) {
|
||||
boolean blockOtherHandlers = false;
|
||||
if (availableForInput()) {
|
||||
if (mouseButton == 1) {
|
||||
blockOtherHandlers = isDragging();
|
||||
if (isDragging() && withinDisplayBounds(x, y)) {
|
||||
int diffX = x - lastX;
|
||||
int diffY = y - lastY;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
if (draggedVertexIndex > -1) {
|
||||
dragVertex(draggedVertexIndex, x, y);
|
||||
} else if (draggingPolygon) {
|
||||
dragPolygon(diffX, diffY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return blockOtherHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseUp(int x, int y, int mouseButton) {
|
||||
boolean blockOtherHandlers = false;
|
||||
if (availableForInput()) {
|
||||
if (mouseButton == 1) {
|
||||
// user done dragging
|
||||
blockOtherHandlers = isDragging();
|
||||
if (draggedVertexIndex > -1) {
|
||||
dragVertex(draggedVertexIndex, x, y);
|
||||
draggedVertexIndex = -1;
|
||||
} else if (draggingPolygon) {
|
||||
int diffX = x - lastX;
|
||||
int diffY = y - lastY;
|
||||
dragPolygon(diffX, diffY);
|
||||
draggingPolygon = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockOtherHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseMove(int x, int y) {
|
||||
if (availableForInput()) {
|
||||
int mouseCursor = SWT.CURSOR_ARROW;
|
||||
int idx = pointOnVertex(x, y);
|
||||
if (idx > -1) {
|
||||
// We are hovering over a vertex
|
||||
mouseCursor = SWT.CURSOR_HAND;
|
||||
} else if (pointOnEdge(x, y)) {
|
||||
// do nothing, don't change the cursor
|
||||
} else if (pointOnPolygon(x, y)) {
|
||||
/*
|
||||
* We are hovering over the polygon but not the vertices or
|
||||
* edges
|
||||
*/
|
||||
mouseCursor = SWT.CURSOR_SIZEALL;
|
||||
}
|
||||
|
||||
if (mouseCursor != currentCursor) {
|
||||
// Update the mouse
|
||||
updateCursor(mouseCursor);
|
||||
currentCursor = mouseCursor;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is some kind of dragging operation related to the polygon
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean isDragging() {
|
||||
return (draggedVertexIndex > -1 || draggingPolygon);
|
||||
}
|
||||
|
||||
protected int pointOnVertex(int screenX, int screenY) {
|
||||
IDisplayPaneContainer container = getContainer();
|
||||
Coordinate screenCoord = new Coordinate(screenX, screenY);
|
||||
int rval = -1;
|
||||
int i = 0;
|
||||
Polygon poly = rsc.getPolygon();
|
||||
if (poly != null) {
|
||||
Coordinate[] coords = poly.getExteriorRing().getCoordinates();
|
||||
for (Coordinate c : coords) {
|
||||
double[] screen = container.translateInverseClick(c);
|
||||
if (screen != null) {
|
||||
c = new Coordinate(screen[0], screen[1]);
|
||||
if (c.distance(screenCoord) <= PolygonLayer.VERTEX_RADIUS) {
|
||||
rval = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the screen coordinate is on the polygon
|
||||
*
|
||||
* @param screenX
|
||||
* @param screenY
|
||||
* @return
|
||||
*/
|
||||
protected boolean pointOnPolygon(int screenX, int screenY) {
|
||||
boolean overPolygon = false;
|
||||
Coordinate worldCoord = screenToLatLon(screenX, screenY);
|
||||
if (worldCoord != null) {
|
||||
overPolygon = PolygonUtil.FACTORY.createPoint(worldCoord).within(
|
||||
rsc.getPolygon());
|
||||
}
|
||||
return overPolygon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified x and y screen coordinates are over or very close
|
||||
* to an edge (aka exterior ring) of the polygon
|
||||
*
|
||||
* @param screenX
|
||||
* @param screenY
|
||||
* @return
|
||||
*/
|
||||
protected boolean pointOnEdge(int screenX, int screenY) {
|
||||
boolean overEdge = false;
|
||||
Polygon screenPolygon = (Polygon) rsc.getPolygon().clone();
|
||||
screenPolygon.apply(latlonToScreen);
|
||||
if (latlonToScreen.success()) {
|
||||
Coordinate screenCoord = new Coordinate(screenX, screenY);
|
||||
overEdge = screenPolygon.getExteriorRing().distance(
|
||||
PolygonUtil.FACTORY.createPoint(screenCoord)) <= EDGE_PROXIMITY;
|
||||
}
|
||||
|
||||
return overEdge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drags the vertex at the specified index to the specified screen
|
||||
* coordinates.
|
||||
*
|
||||
* @param pointIndex
|
||||
* @param screenX
|
||||
* @param screenY
|
||||
*/
|
||||
protected void dragVertex(int pointIndex, int screenX, int screenY) {
|
||||
Coordinate newLoc = screenToLatLon(screenX, screenY);
|
||||
if (newLoc != null) {
|
||||
Coordinate[] c = rsc.getPolygon().getCoordinates();
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
if (i == pointIndex) {
|
||||
c[i] = newLoc;
|
||||
if (i == 0) {
|
||||
// it's both the first and last point, need to update
|
||||
// both
|
||||
c[c.length - 1] = newLoc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
rsc.resetPolygon(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drags/shifts the entire polygon by screen x and y differences
|
||||
*
|
||||
* @param diffX
|
||||
* @param diffY
|
||||
*/
|
||||
protected void dragPolygon(int diffX, int diffY) {
|
||||
// clone in case something goes wrong
|
||||
Polygon movedPolygon = (Polygon) rsc.getPolygon().clone();
|
||||
|
||||
/*
|
||||
* shift the coordinates of the polygon to the screen space the user is
|
||||
* viewing, then afterwards shift back to latlon coordinate space
|
||||
*/
|
||||
movedPolygon.apply(latlonToScreen);
|
||||
if (latlonToScreen.success()) {
|
||||
AffineTransformation transform = AffineTransformation
|
||||
.translationInstance(diffX, diffY);
|
||||
movedPolygon.apply(transform);
|
||||
movedPolygon.apply(screenToLatLon);
|
||||
if (screenToLatLon.success()) {
|
||||
rsc.resetPolygon(movedPolygon.getCoordinates());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a vertex at the specified screen coordinates.
|
||||
*
|
||||
* @param screenX
|
||||
* @param screenY
|
||||
*/
|
||||
protected void addVertex(int screenX, int screenY) {
|
||||
Coordinate vertex = screenToLatLon(screenX, screenY);
|
||||
LinearRing ring = (LinearRing) PolygonUtil.addVertex(rsc.getPolygon()
|
||||
.getExteriorRing(), vertex);
|
||||
rsc.resetPolygon(ring.getCoordinates());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a vertex at the specified index.
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
protected void removeVertex(int index) {
|
||||
if (index > -1) {
|
||||
LineString line = PolygonUtil.removeVertex(rsc.getPolygon()
|
||||
.getExteriorRing(), index);
|
||||
rsc.resetPolygon(line.getCoordinates());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.drawing.polygon;
|
||||
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
|
||||
import com.raytheon.uf.viz.core.DrawableCircle;
|
||||
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
|
||||
import com.raytheon.uf.viz.core.drawables.IShadedShape;
|
||||
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.map.MapDescriptor;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
|
||||
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.OutlineCapability;
|
||||
import com.raytheon.viz.ui.input.EditableManager;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.LineString;
|
||||
import com.vividsolutions.jts.geom.LinearRing;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* A layer for displaying a filled polygon on a map and altering it through
|
||||
* mouse interactions. This layer only supports an exterior ring, ie a polygon
|
||||
* without holes/interior rings.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 19, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
* @param <T>
|
||||
*/
|
||||
|
||||
public class PolygonLayer<T extends AbstractResourceData> extends
|
||||
AbstractVizResource<T, MapDescriptor> {
|
||||
|
||||
protected static final double VERTEX_RADIUS = 7.0;
|
||||
|
||||
protected PolygonInputAdapter uiInput = new PolygonInputAdapter(this);
|
||||
|
||||
/** the polygon as represented in latlon coordinates **/
|
||||
protected Polygon polygon;
|
||||
|
||||
protected IWireframeShape wireframeShape;
|
||||
|
||||
protected IShadedShape shadedShape;
|
||||
|
||||
protected Object shapeLock = new Object();
|
||||
|
||||
public PolygonLayer(T resourceData, LoadProperties loadProperties) {
|
||||
super(resourceData, loadProperties);
|
||||
getCapability(EditableCapability.class).setEditable(true);
|
||||
getCapability(OutlineCapability.class).setOutlineWidth(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initInternal(IGraphicsTarget target) throws VizException {
|
||||
EditableManager.makeEditable(this,
|
||||
this.getCapability(EditableCapability.class).isEditable());
|
||||
IDisplayPaneContainer container = getResourceContainer();
|
||||
if (container != null) {
|
||||
container.registerMouseHandler(uiInput);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintInternal(IGraphicsTarget target,
|
||||
PaintProperties paintProps) throws VizException {
|
||||
// prepare to create lines of the polygon
|
||||
LinearRing ring = (LinearRing) polygon.getExteriorRing();
|
||||
Coordinate[] c = polygon.getCoordinates();
|
||||
RGB color = getCapability(ColorableCapability.class).getColor();
|
||||
OutlineCapability lineCap = getCapability(OutlineCapability.class);
|
||||
float width = lineCap.getOutlineWidth();
|
||||
LineStyle style = lineCap.getLineStyle();
|
||||
|
||||
synchronized (shapeLock) {
|
||||
if (wireframeShape == null) {
|
||||
wireframeShape = target.createWireframeShape(true, descriptor);
|
||||
}
|
||||
if (shadedShape == null) {
|
||||
shadedShape = target.createShadedShape(false,
|
||||
descriptor.getGridGeometry());
|
||||
}
|
||||
|
||||
if (!wireframeShape.isDrawable() || !shadedShape.isDrawable()) {
|
||||
wireframeShape.addLineSegment(c);
|
||||
shadedShape.addPolygon(new LineString[] { ring }, color);
|
||||
}
|
||||
|
||||
target.drawWireframeShape(wireframeShape, color, width, style);
|
||||
target.drawShadedShape(shadedShape, 0.5f);
|
||||
}
|
||||
|
||||
// only show the vertices if in editable mode
|
||||
if (getCapability(EditableCapability.class).isEditable()) {
|
||||
DrawableCircle[] vertices = new DrawableCircle[c.length - 1];
|
||||
double[] origCoord = new double[2];
|
||||
double[] pxCoord = new double[2];
|
||||
for (int i = 0; i < c.length - 1; i++) {
|
||||
DrawableCircle circle = new DrawableCircle();
|
||||
origCoord[0] = c[i].x;
|
||||
origCoord[1] = c[i].y;
|
||||
if (uiInput.draggedVertexIndex == i) {
|
||||
// they're dragging, replace this circle with mouse position
|
||||
pxCoord = descriptor.getRenderableDisplay().screenToGrid(
|
||||
uiInput.lastX, uiInput.lastY, 0, target);
|
||||
} else {
|
||||
pxCoord = this.descriptor.worldToPixel(origCoord);
|
||||
}
|
||||
circle.setCoordinates(pxCoord[0], pxCoord[1]);
|
||||
circle.screenRadius = VERTEX_RADIUS;
|
||||
circle.basics.color = color;
|
||||
circle.filled = true;
|
||||
vertices[i] = circle;
|
||||
}
|
||||
target.drawCircle(vertices);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeInternal() {
|
||||
IDisplayPaneContainer container = getResourceContainer();
|
||||
if (container != null) {
|
||||
container.unregisterMouseHandler(uiInput);
|
||||
}
|
||||
|
||||
synchronized (shapeLock) {
|
||||
wireframeShape.dispose();
|
||||
shadedShape.dispose();
|
||||
}
|
||||
|
||||
// FIXME the shaded shape gets messed up in collaboration
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new polygon based on the coordinates and makes that the
|
||||
* internal polygon.
|
||||
*
|
||||
* @param coords
|
||||
*/
|
||||
public void resetPolygon(Coordinate[] coords) {
|
||||
|
||||
synchronized (shapeLock) {
|
||||
if (coords != null) {
|
||||
polygon = PolygonUtil.FACTORY.createPolygon(coords);
|
||||
}
|
||||
if (wireframeShape != null) {
|
||||
wireframeShape.reset();
|
||||
}
|
||||
if (shadedShape != null) {
|
||||
shadedShape.reset();
|
||||
}
|
||||
}
|
||||
issueRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void resourceDataChanged(ChangeType type, Object updateObject) {
|
||||
if (type.equals(ChangeType.CAPABILITY)) {
|
||||
resetPolygon(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void project(CoordinateReferenceSystem crs) throws VizException {
|
||||
synchronized (shapeLock) {
|
||||
if (wireframeShape != null) {
|
||||
wireframeShape.dispose();
|
||||
wireframeShape = null;
|
||||
}
|
||||
if (shadedShape != null) {
|
||||
shadedShape.dispose();
|
||||
shadedShape = null;
|
||||
}
|
||||
resetPolygon(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Polygon getPolygon() {
|
||||
return polygon;
|
||||
}
|
||||
|
||||
public void setPolygon(Polygon polygon) {
|
||||
resetPolygon(polygon.getExteriorRing().getCoordinates());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.drawing.polygon;
|
||||
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.LineSegment;
|
||||
import com.vividsolutions.jts.geom.LineString;
|
||||
import com.vividsolutions.jts.geom.LinearRing;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Various utilities for making or changing {@link Polygon} objects.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 26, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PolygonUtil {
|
||||
|
||||
public static final GeometryFactory FACTORY = new GeometryFactory();
|
||||
|
||||
private PolygonUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a rectangular polygon based on the display aspect ratio
|
||||
*
|
||||
* @param display
|
||||
* @return a basic rectangle
|
||||
*/
|
||||
public static Polygon makeDefaultPolygon(IRenderableDisplay display) {
|
||||
IExtent extent = display.getExtent();
|
||||
IDescriptor descriptor = display.getDescriptor();
|
||||
|
||||
double[] center = extent.getCenter();
|
||||
IExtent clone = extent.clone();
|
||||
clone.scaleAndBias(.2, center[0], center[1]);
|
||||
Coordinate[] square = new Coordinate[5];
|
||||
|
||||
double[] pxUL = new double[] { clone.getMinX(), clone.getMaxY() };
|
||||
double[] cUL = descriptor.pixelToWorld(pxUL);
|
||||
square[0] = new Coordinate(cUL[0], cUL[1]);
|
||||
|
||||
double[] pxLL = new double[] { clone.getMinX(), clone.getMinY() };
|
||||
double[] cLL = descriptor.pixelToWorld(pxLL);
|
||||
square[1] = new Coordinate(cLL[0], cLL[1]);
|
||||
|
||||
double[] pxLR = new double[] { clone.getMaxX(), clone.getMinY() };
|
||||
double[] cLR = descriptor.pixelToWorld(pxLR);
|
||||
square[2] = new Coordinate(cLR[0], cLR[1]);
|
||||
|
||||
double[] pxUR = new double[] { clone.getMaxX(), clone.getMaxY() };
|
||||
double[] cUR = descriptor.pixelToWorld(pxUR);
|
||||
square[3] = new Coordinate(cUR[0], cUR[1]);
|
||||
|
||||
square[4] = (Coordinate) square[0].clone();
|
||||
|
||||
return FACTORY.createPolygon(square);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a vertex to a LineString at the specified coordinate, attempting to
|
||||
* find the closest segment to determine where in the LineString the vertex
|
||||
* should go.
|
||||
*
|
||||
* This function operates on the assumption that the LineString and the
|
||||
* Coordinate are in the same CRS. It does not bother to check that the
|
||||
* coordinate is near the line string, calling code should determine if the
|
||||
* proximity to the line is acceptable.
|
||||
*
|
||||
* Note that this does not change the original reference, instead returning
|
||||
* a new LineString.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* @param vertexToAdd
|
||||
* @return a new line string with an extra vertex inserted at the coordinate
|
||||
*/
|
||||
public static LineString addVertex(LineString line, Coordinate vertexToAdd) {
|
||||
Coordinate[] coords = line.getCoordinates();
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
int index = -1;
|
||||
for (int i = 0; i < coords.length - 1; i++) {
|
||||
LineSegment segment = new LineSegment(coords[i], coords[i + 1]);
|
||||
double distance = segment.distance(vertexToAdd);
|
||||
if (distance < bestDistance) {
|
||||
index = i + 1;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > -1) {
|
||||
Coordinate[] newLine = new Coordinate[coords.length + 1];
|
||||
System.arraycopy(coords, 0, newLine, 0, index);
|
||||
newLine[index] = vertexToAdd;
|
||||
System.arraycopy(coords, index, newLine, index + 1, coords.length
|
||||
- index);
|
||||
if (newLine[0].equals(newLine[newLine.length - 1])) {
|
||||
return FACTORY.createLinearRing(newLine);
|
||||
} else {
|
||||
return FACTORY.createLineString(newLine);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* TODO contemplate throwing exception instead of returning original
|
||||
* line
|
||||
*/
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a vertex from a LineString at the specified coordinate,
|
||||
* attempting to find the closest vertex to remove and connecting the two
|
||||
* points on either side of it.
|
||||
*
|
||||
* This function operates on the assumption that the LineString and the
|
||||
* Coordinate are in the same CRS. It does not bother to check that the
|
||||
* coordinate is near the line string, calling code should determine if the
|
||||
* proximity to the line is acceptable.
|
||||
*
|
||||
* Note that this does not change the original reference, instead returning
|
||||
* a new LineString.
|
||||
*
|
||||
*
|
||||
* @param line
|
||||
* @param vertexToRemove
|
||||
* @return a new line string with the vertex nearest the coordinate removed
|
||||
*/
|
||||
public static LineString removeVertex(LineString line,
|
||||
Coordinate vertexToRemove) {
|
||||
Coordinate[] coords = line.getCoordinates();
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
int index = -1;
|
||||
for (int i = 0; i < coords.length - 1; i++) {
|
||||
double distance = coords[i].distance(vertexToRemove);
|
||||
if (distance < bestDistance) {
|
||||
index = i;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > -1) {
|
||||
return removeVertex(line, index);
|
||||
} else {
|
||||
/*
|
||||
* TODO contemplate throwing exception instead of returning original
|
||||
* line
|
||||
*/
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a vertex from a LineString at the specified index. If the
|
||||
* LineString is a LinearRing, it will not remove the vertex if there are
|
||||
* not enough points to have a LinearRing after removing the vertex.
|
||||
*
|
||||
* Note that this does not change the original reference, instead returning
|
||||
* a new LineString.
|
||||
*
|
||||
* @param line
|
||||
* @param index
|
||||
* @return a new line string with the vertex nearest the coordinate removed
|
||||
*/
|
||||
public static LineString removeVertex(LineString line, int index) {
|
||||
Coordinate[] coords = line.getCoordinates();
|
||||
boolean isRing = (line instanceof LinearRing);
|
||||
if (index > -1 && (!isRing || coords.length > 4)) {
|
||||
Coordinate[] newLine = new Coordinate[coords.length - 1];
|
||||
System.arraycopy(coords, 0, newLine, 0, index);
|
||||
System.arraycopy(coords, index + 1, newLine, index, newLine.length
|
||||
- index);
|
||||
if (isRing) {
|
||||
return FACTORY.createLinearRing(newLine);
|
||||
} else {
|
||||
return FACTORY.createLineString(newLine);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* TODO contemplate throwing exception instead of returning original
|
||||
* line
|
||||
*/
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* 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.polygon.filter;
|
||||
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||
|
||||
/**
|
||||
* A CoordinateSequenceFilter that converts the CoordinateSequence's points from
|
||||
* a lat/lon CRS to the screen coordinates (ie SWT coordinates).
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 26, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class LatLonToScreenFilter extends StatusCoordSequenceFilter {
|
||||
|
||||
public LatLonToScreenFilter(AbstractVizResource<?, ?> display) {
|
||||
super(display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(CoordinateSequence seq, int i) {
|
||||
Coordinate c = seq.getCoordinate(i);
|
||||
double[] screen = getContainer().translateInverseClick(c);
|
||||
c.x = screen[0];
|
||||
c.y = screen[1];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* 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.polygon.filter;
|
||||
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||
|
||||
/**
|
||||
* A CoordinateSequenceFilter that converts the CoordinateSequence's points from
|
||||
* screen coordinates (ie SWT) to a lat/lon CRS.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 26, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ScreenToLatLonFilter extends StatusCoordSequenceFilter {
|
||||
|
||||
public ScreenToLatLonFilter(AbstractVizResource<?, ?> display) {
|
||||
super(display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(CoordinateSequence seq, int i) {
|
||||
Coordinate screen = seq.getCoordinate(i);
|
||||
Coordinate c = getContainer().translateClick(screen.x, screen.y);
|
||||
if (c != null) {
|
||||
screen.x = c.x;
|
||||
screen.y = c.y;
|
||||
} else {
|
||||
// a coordinate that was on the screen moved off the screen
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* 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.polygon.filter;
|
||||
|
||||
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.vividsolutions.jts.geom.CoordinateSequenceFilter;
|
||||
|
||||
/**
|
||||
* An incomplete CoordinateSequenceFilter that is associated with an
|
||||
* AbstractVizResource and reports on the status of an apply operation.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 26, 2015 3974 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class StatusCoordSequenceFilter implements
|
||||
CoordinateSequenceFilter {
|
||||
|
||||
private final AbstractVizResource<?, ?> rsc;
|
||||
|
||||
protected boolean valid = true;
|
||||
|
||||
protected StatusCoordSequenceFilter(AbstractVizResource<?, ?> rsc) {
|
||||
this.rsc = rsc;
|
||||
}
|
||||
|
||||
protected IDisplayPaneContainer getContainer() {
|
||||
return rsc.getResourceContainer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeometryChanged() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
// exit before completion if invalid point was encountered
|
||||
return !valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the filter and returns the state of the previous time
|
||||
* the filter was applied to a geometry. If true, the filter completed
|
||||
* successfully. If false, the filter had an issue and the modified polygon
|
||||
* should not be trusted.
|
||||
*
|
||||
* @return the state of the previous run of this filter
|
||||
*/
|
||||
public boolean success() {
|
||||
boolean temp = valid;
|
||||
valid = true;
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
|
@ -73,7 +73,8 @@ import com.raytheon.uf.viz.kml.export.graphics.ext.KmlRasterImage;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 1, 2012 bsteffen Initial creation
|
||||
* Jun 01, 2012 bsteffen Initial creation
|
||||
* Jan 26, 2015 3974 njensen Removed tesselate parameter for createShadedShape()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -86,7 +87,7 @@ public class KmlGraphicsTarget extends AbstractGraphicsTarget {
|
|||
|
||||
private final KmlFont defaultFont = new KmlFont();
|
||||
|
||||
private List<KmlFeatureGenerator> generators = new ArrayList<KmlFeatureGenerator>(
|
||||
private final List<KmlFeatureGenerator> generators = new ArrayList<KmlFeatureGenerator>(
|
||||
256);
|
||||
|
||||
protected IView view;
|
||||
|
@ -226,7 +227,7 @@ public class KmlGraphicsTarget extends AbstractGraphicsTarget {
|
|||
|
||||
@Override
|
||||
public IShadedShape createShadedShape(boolean mutable,
|
||||
GeneralGridGeometry targetGeometry, boolean tesselate) {
|
||||
GeneralGridGeometry targetGeometry) {
|
||||
return new KmlShadedShape(targetGeometry);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,8 +115,9 @@ import com.raytheon.uf.viz.remote.graphics.objects.DispatchingWireframeShape;
|
|||
* {@link IGraphicsTarget} methods.
|
||||
* Jul 28, 2014 3429 mapeters Updated deprecated drawLine() calls.
|
||||
* Aug 07, 2014 3492 mapeters Updated deprecated createWireframeShape() calls
|
||||
* and removed unused setUseBuiltinColorbar(),
|
||||
* and removed unused setUseBuiltinColorbar(),
|
||||
* drawFilledCircle(), and buildColorMap() methods.
|
||||
* Jan 26, 2015 3974 njensen Updated createShadedShape() calls
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -134,7 +135,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
|
||||
private RGB backgroundColor = new RGB(0, 0, 0);
|
||||
|
||||
private GraphicsExtensionManager extensionManager;
|
||||
private final GraphicsExtensionManager extensionManager;
|
||||
|
||||
private Rectangle bounds;
|
||||
|
||||
|
@ -156,6 +157,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
* {@link #initializeRaster(IRenderedImageCallback)}. Other
|
||||
* image construction methods should be done through extensions
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public IImage initializeRaster(IDataPreparer preparer,
|
||||
ColorMapParameters optionalParams) {
|
||||
|
@ -249,6 +251,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
* com.raytheon.uf.viz.core.drawables.IFont.FontType, float,
|
||||
* com.raytheon.uf.viz.core.drawables.IFont.Style[])} should be used instead
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public IFont initializeFont(File fontFile, float size, Style[] styles) {
|
||||
return initializeFont(fontFile, FontType.TRUETYPE, size, styles);
|
||||
|
@ -260,7 +263,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
* @param size
|
||||
* @param styles
|
||||
* @return
|
||||
* @see
|
||||
* @see
|
||||
* com.raytheon.uf.viz.core.IGraphicsTarget#initializeFont(java.io.File,
|
||||
* com.raytheon.uf.viz.core.drawables.IFont.FontType float,
|
||||
* com.raytheon.uf.viz.core.drawables.IFont.Style[])
|
||||
|
@ -682,6 +685,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated: Use {@link #drawCircle(DrawableCircle...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawArc(double x1, double y1, double z1, double radius,
|
||||
RGB color, float width, int startAzimuth, int endAzimuth,
|
||||
|
@ -879,6 +883,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
* {@link #createShadedShape(boolean, GeneralGridGeometry, boolean)}
|
||||
* instead
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public IShadedShape createShadedShape(boolean mutable,
|
||||
IDescriptor descriptor, boolean tesselate) {
|
||||
|
@ -886,6 +891,12 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
tesselate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IShadedShape createShadedShape(boolean mutable,
|
||||
GeneralGridGeometry targetGeometry) {
|
||||
return createShadedShape(mutable, targetGeometry, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mutable
|
||||
* @param descriptor
|
||||
|
@ -905,6 +916,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
CreateShadedShapeEvent.class, shape);
|
||||
event.setTargetGeometry(targetGeometry);
|
||||
event.setMutable(mutable);
|
||||
// TODO remove tesselate from event in backwards compatible way
|
||||
event.setTesselate(tesselate);
|
||||
dispatch(event);
|
||||
return shape;
|
||||
|
@ -1061,6 +1073,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Should not be used for anything
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public String getViewType() {
|
||||
return VizConstants.VIEW_2D;
|
||||
|
@ -1136,6 +1149,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawStrings(DrawableString...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawString(IFont font, String text, double x, double y,
|
||||
double z, TextStyle textStyle, RGB color,
|
||||
|
@ -1155,6 +1169,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawStrings(DrawableString...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawString(IFont font, String text, double x, double y,
|
||||
double z, TextStyle textStyle, RGB color,
|
||||
|
@ -1172,6 +1187,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawStrings(DrawableString...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawStrings(IFont font, String[] text, double x, double y,
|
||||
double z, TextStyle textStyle, RGB[] colors,
|
||||
|
@ -1189,6 +1205,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #getStringsBounds(DrawableString)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Rectangle2D getStringBounds(IFont font, String text) {
|
||||
DrawableString params = new DrawableString(text, null);
|
||||
|
@ -1199,6 +1216,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #getStringsBounds(DrawableString)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Rectangle2D getStringBounds(IFont font, String[] text,
|
||||
TextStyle style) {
|
||||
|
@ -1211,6 +1229,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawCircle(DrawableCircle...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawCircle(double x1, double y1, double z1, double radius,
|
||||
RGB color, float width) throws VizException {
|
||||
|
@ -1225,6 +1244,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawLine(DrawableLine...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawLine(double x1, double y1, double z1, double x2, double y2,
|
||||
double z2, RGB color, float width, LineStyle lineStyle)
|
||||
|
@ -1241,6 +1261,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
|
|||
/**
|
||||
* @deprecated Use {@link #drawLine(DrawableLine...)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void drawLine(double x1, double y1, double z1, double x2, double y2,
|
||||
double z2, RGB color, float width) throws VizException {
|
||||
|
|
|
@ -28,7 +28,11 @@
|
|||
|
||||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.awipstools.choosebyid"
|
||||
menuText="Choose By ID..." />
|
||||
menuText="Choose By ID..." id="chooseByIDTool" />
|
||||
|
||||
<!-- TODO move into damage path plugin somehow -->
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/DamagePath.xml"
|
||||
menuText="Damage Path" id="damagePathTool" timeQuery="false" />
|
||||
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/DistanceBearing.xml"
|
||||
menuText="Distance Bearing" id="distanceBearingTool" timeQuery="false" />
|
||||
|
@ -40,19 +44,15 @@
|
|||
<contribute xsi:type="bundleItem" file="bundles/tools/DistanceScale.xml"
|
||||
menuText="Distance Scale" id="distanceScaleTool" timeQuery="false" />
|
||||
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/EstimatedActualVelocity.xml"
|
||||
menuText="Estimated Actual Velocity" id="estimatedActualVelocityTool" timeQuery="false" />
|
||||
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/FeatureFollowingZoom.xml"
|
||||
menuText="Feature Following Zoom" id="featureFollowingZoomTool" timeQuery="false" />
|
||||
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/EstimatedActualVelocity.xml"
|
||||
menuText="Estimated Actual Velocity" id="estimatedActualVelocityTool" timeQuery="false" />
|
||||
|
||||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.ui.viz.radarapps.fsi.startFSI"
|
||||
menuText="4-D Storm Investigator (FSI)" />
|
||||
|
||||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.awipstools.timeofarrival"
|
||||
menuText="Time Of Arrival / Lead Time" />
|
||||
menuText="4-D Storm Investigator (FSI)" />
|
||||
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/Home.xml"
|
||||
menuText="Home" id="homeTool" timeQuery="false" />
|
||||
|
@ -61,6 +61,7 @@
|
|||
commandId="com.raytheon.viz.awipstools.lapstools"
|
||||
menuText="LAPS tools..." />
|
||||
|
||||
<!-- TODO move into points plugin somehow -->
|
||||
<contribute xsi:type="bundleItem" file="bundles/tools/Points.xml"
|
||||
menuText="Points" id="pointsTool" timeQuery="false" />
|
||||
|
||||
|
@ -82,6 +83,10 @@
|
|||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.texteditor.opentexteditor"
|
||||
menuText="Text Window..." />
|
||||
|
||||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.awipstools.timeofarrival"
|
||||
menuText="Time Of Arrival / Lead Time" />
|
||||
|
||||
<contribute xsi:type="command"
|
||||
commandId="com.raytheon.viz.awipstools.unitscalculator"
|
||||
|
|
Loading…
Add table
Reference in a new issue