Omaha #3977 Add ability to import DamagePath from DistanceSpeed
Change-Id: Ibdede2ec4d973251b5755eabdb65bb5d926dfa27 Former-commit-id: e6bfe389158dbc6a0739e60c08c8175a2e53b084
This commit is contained in:
parent
d87f7c6215
commit
a3d925b745
4 changed files with 282 additions and 2 deletions
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Damage Path
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.damagepath;singleton:=true
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Version: 1.15.1.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.6",
|
||||
|
@ -11,5 +11,8 @@ Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.6",
|
|||
com.raytheon.uf.common.geospatial;bundle-version="1.14.2",
|
||||
com.raytheon.uf.common.json;bundle-version="1.0.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.8.0",
|
||||
com.raytheon.viz.ui;bundle-version="1.14.1"
|
||||
com.raytheon.viz.ui;bundle-version="1.14.1",
|
||||
com.raytheon.viz.awipstools;bundle-version="1.14.0",
|
||||
com.raytheon.viz.radar;bundle-version="1.14.0",
|
||||
javax.measure;bundle-version="1.0.0"
|
||||
Export-Package: com.raytheon.uf.viz.damagepath
|
||||
|
|
|
@ -15,5 +15,11 @@
|
|||
name="Import GeoJSON"
|
||||
sortID="4">
|
||||
</contextualMenu>
|
||||
<contextualMenu
|
||||
actionClass="com.raytheon.uf.viz.damagepath.ImportFromDistanceSpeedAction"
|
||||
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
|
||||
name="Import from Distance Speed Tool"
|
||||
sortID="5">
|
||||
</contextualMenu>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* 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.measure.converter.UnitConverter;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarStation;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||
import com.raytheon.viz.radar.util.StationUtils;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Utility class for Damage Paths.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DamagePathUtils {
|
||||
/** Convert meters returned the GeodeticCalculator to the desired unit. */
|
||||
private static UnitConverter METERS_TO = SI.METER
|
||||
.getConverterTo(NonSI.MILE);
|
||||
|
||||
private DamagePathUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Estimates the damage path polygon for a storm track.
|
||||
*
|
||||
* @param stormTrack
|
||||
* The storm track to create a damage path for.
|
||||
* @return The estimated damage path polygon for a storm track.
|
||||
*/
|
||||
public static Polygon estimateDamagePath(
|
||||
AbstractStormTrackResource stormTrack) {
|
||||
|
||||
StormTrackState stState = stormTrack.getStormTrackState();
|
||||
|
||||
RadarStation station = StationUtils.getInstance().getHomeRadarStation();
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
|
||||
Geometry damagePathBuffer = createBuffer(stState.timePoints, station,
|
||||
gf, null);
|
||||
damagePathBuffer = createBuffer(stState.futurePoints, station, gf,
|
||||
damagePathBuffer);
|
||||
|
||||
// user likely tried to import before creating track
|
||||
if (damagePathBuffer == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Polygon polygon = gf.createPolygon(damagePathBuffer.convexHull()
|
||||
.getCoordinates());
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a buffers a buffer around the storm coordinates. If
|
||||
* damagePathBuffer is non null, the created buffer will be the union of the
|
||||
* two buffers.
|
||||
*
|
||||
* @param stormCoords
|
||||
* The storm track coordinates.
|
||||
* @param station
|
||||
* The station to base distance on.
|
||||
* @param gf
|
||||
* The geometry factory.
|
||||
* @param damagePathBuffer
|
||||
* The current damage path buffer. May be null.
|
||||
* @return The created buffer. If damagePathBuffer is not null, the created
|
||||
* buffer will included damagePathBuffer.
|
||||
*/
|
||||
private static Geometry createBuffer(
|
||||
StormTrackState.StormCoord[] stormCoords, RadarStation station,
|
||||
GeometryFactory gf, Geometry damagePathBuffer) {
|
||||
if (stormCoords == null || stormCoords.length == 0) {
|
||||
return damagePathBuffer;
|
||||
}
|
||||
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
Point point;
|
||||
Geometry buffer;
|
||||
double distanceMeters; // distance in meters
|
||||
double distance; // distance in the desired unit
|
||||
double uncertainty;
|
||||
Coordinate stormCoord;
|
||||
for (int i = 0; i < stormCoords.length; i++) {
|
||||
stormCoord = stormCoords[i].coord;
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(), station.getLat());
|
||||
distanceMeters = gc.getOrthodromicDistance();
|
||||
distance = METERS_TO.convert(distanceMeters);
|
||||
|
||||
/*
|
||||
* Based off of research done by Doug Speheger comparing surveyed
|
||||
* tornado paths to manually identified radar tornadic vortex
|
||||
* signatures in 2008-2012. In the initial dataset, 87% of tornadoes
|
||||
* were within this range of uncertainty.
|
||||
*/
|
||||
if (distance < 40.0) {
|
||||
uncertainty = 0.3 + distance * 0.005;
|
||||
} else if (distance < 80.0) {
|
||||
uncertainty = 0.1 + distance * 0.01;
|
||||
} else {
|
||||
uncertainty = distance * 0.015 - 0.3;
|
||||
}
|
||||
|
||||
point = gf.createPoint(stormCoord);
|
||||
buffer = point.buffer(uncertainty);
|
||||
if (damagePathBuffer == null) {
|
||||
damagePathBuffer = buffer;
|
||||
} else {
|
||||
damagePathBuffer = damagePathBuffer.union(buffer);
|
||||
}
|
||||
}
|
||||
return damagePathBuffer;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* 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 com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||
import com.raytheon.viz.awipstools.ui.layer.DistanceSpeedLayer;
|
||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Action to create a damage path from a DistanceSpeedLayer.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
||||
|
||||
protected static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(ImportFromDistanceSpeedAction.class);
|
||||
|
||||
public ImportFromDistanceSpeedAction() {
|
||||
super("Import from Distance Speed Tool");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
VizApp.runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||
DistanceSpeedLayer dsLayer = findImportLayer(layer);
|
||||
|
||||
// The Distance Speed tool has not been loaded.
|
||||
if (dsLayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon polygon = DamagePathUtils.estimateDamagePath(dsLayer);
|
||||
|
||||
if (polygon != null) {
|
||||
layer.setPolygon(polygon);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff super.isEnabled() is true and the DistanceSpeed tool is
|
||||
* loaded, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
boolean enabled = super.isEnabled();
|
||||
if (enabled) {
|
||||
AbstractVizResource<?, ?> rsc = getSelectedRsc();
|
||||
if (rsc != null) {
|
||||
enabled = findImportLayer(rsc) != null;
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the DistanceSpeedLayer.
|
||||
*
|
||||
* @param rsc
|
||||
* The current resource
|
||||
* @return The found DistanceSpeedLayer, or null if the tool is not loaded.
|
||||
*/
|
||||
private DistanceSpeedLayer findImportLayer(AbstractVizResource<?, ?> rsc) {
|
||||
ResourceList resources = rsc.getDescriptor().getResourceList();
|
||||
for (ResourcePair rp : resources) {
|
||||
if (rp.getResource() instanceof DistanceSpeedLayer) {
|
||||
return (DistanceSpeedLayer) rp.getResource();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue