Merge remote-tracking branch 'asm/asm_16.1.2' into master_16.1.2
Former-commit-id: b4a41b2992ddfa2cea55a3ae25204ba57aeb3a00
This commit is contained in:
commit
c98e7908fe
13 changed files with 907 additions and 47 deletions
|
@ -89,6 +89,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* 10/15/2012 1229 rferrel Changes for non-blocking HelpUsageDlg.
|
||||
* 16 Aug 2013 #2256 lvenable Fixed image and cursor memory leaks.
|
||||
* 19Mar2014 #2925 lvenable Added dispose checks for runAsync.
|
||||
* 12/22/2015 18342 zhao Modified code for 'jnt' in objReceived()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -886,7 +887,7 @@ public class CigVisDistributionDlg extends CaveSWTDialog implements
|
|||
int flightCat = (Integer) list.get(3);
|
||||
float cig = (Float) list.get(4);
|
||||
float vis = (Float) list.get(5);
|
||||
float jnt = Math.min(cig, vis);
|
||||
float jnt = (Float) list.get(6);
|
||||
|
||||
data.set(month, hour, windDir, flightCat, vis, cig, jnt);
|
||||
} else {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# Jul 07, 2015 16907 zhao Modified to work with new ids- files
|
||||
# Dec 22, 2015 18341 zhao Modified __writeHDFData to avoid 'bad' input
|
||||
|
||||
import sys
|
||||
sys.argv = [__name__]
|
||||
|
@ -465,6 +466,8 @@ required NCDC data.
|
|||
shape = f_col.descr._v_colObjects[col].shape[0] - 1
|
||||
#datum = datum + [self.__get_msng(f_col.type)]*(f_col.shape[0]-len(datum))
|
||||
datum = datum + [self.__get_msng(f_col.type)] * (f_col.descr._v_colObjects[col].shape[0] - len(datum))
|
||||
if len(numpy.array(datum)) != len(row[col]):
|
||||
continue
|
||||
row[col] = numpy.array(datum).astype(f_col.type)
|
||||
except Exception, e:
|
||||
self.__updateMonitor(str(e) + '\n')
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
# Generates ceiling/visibility distribution by month, hour and wind direction
|
||||
# George Trojan, SAIC/MDL, December 2005
|
||||
# last update: 03/14/06
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- -----------------------------------
|
||||
# Dec 22, 2015 18342 zhao Modified _process() to also pass 'jnt_count'
|
||||
|
||||
|
||||
import logging, os, time, cPickle
|
||||
import Avn, ClimLib
|
||||
|
@ -174,7 +178,7 @@ def get_data(table, queue):
|
|||
for windDir in range(num_wind_dir):
|
||||
for flightCat in range(num_cat+1):
|
||||
sendObj = [month, hour, windDir, flightCat, float(cig_count[month][hour][windDir][flightCat]),
|
||||
float(vis_count[month][hour][windDir][flightCat])]#, float(jnt_count[month][hour][windDir][flightCat])]
|
||||
float(vis_count[month][hour][windDir][flightCat]), float(jnt_count[month][hour][windDir][flightCat])]
|
||||
#print "sendObj", sendObj
|
||||
queue.put(sendObj)
|
||||
queue.put("done")
|
||||
|
|
|
@ -26,7 +26,9 @@ Require-Bundle: org.eclipse.ui,
|
|||
com.raytheon.viz.alerts,
|
||||
com.raytheon.uf.common.site,
|
||||
com.raytheon.viz.core.contours,
|
||||
com.raytheon.uf.viz.core.rsc
|
||||
com.raytheon.uf.viz.core.rsc,
|
||||
org.eclipse.core.databinding;bundle-version="1.4.1",
|
||||
com.raytheon.uf.common.auth;bundle-version="1.14.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.raytheon.viz.warngen,
|
||||
com.raytheon.viz.warngen.gis,
|
||||
|
|
|
@ -99,4 +99,12 @@
|
|||
recursive="true">
|
||||
</path>
|
||||
</extension>
|
||||
<extension
|
||||
point="com.raytheon.viz.ui.contextualMenu">
|
||||
<contextualMenu
|
||||
actionClass="com.raytheon.viz.warngen.gui.ShowExtensionAreaToggleAction"
|
||||
name="com.raytheon.viz.warngen.ShowExtensionAreaToggle"
|
||||
sortID="600">
|
||||
</contextualMenu>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -96,6 +96,7 @@ import com.vividsolutions.jts.precision.SimpleGeometryPrecisionReducer;
|
|||
* 05/08/2015 DR 17310 D. Friedman Prevent reducePoints from generating invalid polygons.
|
||||
* 09/22/2015 DR 18033 Qinglu Lin Updated removeOverlaidLinesegments(), removed one computeSlope().
|
||||
* 12/09/2015 DR 18209 D. Friedman Support cwaStretch.
|
||||
* 12/21/2015 DCS 17942 D. Friedman Support extension area. Work around glitch in contour adjustment.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -136,10 +137,12 @@ public class PolygonUtil {
|
|||
}
|
||||
|
||||
public Polygon hatchWarningArea(Polygon origPolygon,
|
||||
Geometry origWarningArea, Polygon oldWarningPolygon,
|
||||
boolean cwaStretch)
|
||||
Geometry origWarningArea, Geometry extensionArea,
|
||||
Polygon oldWarningPolygon, boolean cwaStretch)
|
||||
throws VizException {
|
||||
float[][] contourAreaData = toFloatData(origWarningArea);
|
||||
if (extensionArea != null)
|
||||
toFloatData(extensionArea, contourAreaData);
|
||||
|
||||
/*
|
||||
* If we have an oldWarningPolygon, we can take a shortcut and see if
|
||||
|
@ -226,7 +229,7 @@ public class PolygonUtil {
|
|||
boolean showContour = false;
|
||||
if (contour != null && !showContour) {
|
||||
rval = awips1PointReduction(contour, origPolygon, origWarningArea,
|
||||
config, oldWarningPolygon);
|
||||
extensionArea, config, oldWarningPolygon, contourAreaData);
|
||||
if (rval == null) {
|
||||
return (Polygon) origPolygon.clone();
|
||||
}
|
||||
|
@ -247,14 +250,38 @@ public class PolygonUtil {
|
|||
* @return null if the original warningPolygon should be used
|
||||
*/
|
||||
private Polygon awips1PointReduction(Coordinate[] longest,
|
||||
Polygon warningPolygon, Geometry warningArea, FortConConfig config,
|
||||
Polygon oldWarningPolygon) throws VizException {
|
||||
Polygon warningPolygon, Geometry warningArea,
|
||||
Geometry extensionArea, FortConConfig config,
|
||||
Polygon oldWarningPolygon, float[][] warningAreaData)
|
||||
throws VizException {
|
||||
if (extensionArea != null) {
|
||||
/*
|
||||
* Attempt to avoid a glitch in the code below in which it chooses
|
||||
* an inappropriate side of the polygon on which to project an
|
||||
* unmatched contour point. The glitch is likely to occur when a
|
||||
* polygon point is outside the contour space, so clip the polygon
|
||||
* to it.
|
||||
*/
|
||||
Polygon wpc = WarngenLayer.convertGeom(warningPolygon, latLonToContour);
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
Coordinate[] coords = new Coordinate[5];
|
||||
coords[0] = new Coordinate(0, 0);
|
||||
coords[1] = new Coordinate(nx, 0);
|
||||
coords[2] = new Coordinate(nx, ny);
|
||||
coords[3] = new Coordinate(0, ny);
|
||||
coords[4] = new Coordinate(0, 0);
|
||||
Polygon clip = gf.createPolygon(gf.createLinearRing(coords), null);
|
||||
Geometry g = clip.intersection(wpc);
|
||||
if (g instanceof Polygon) {
|
||||
warningPolygon = WarngenLayer.convertGeom((Polygon) g, contourToLatLon);
|
||||
}
|
||||
}
|
||||
Coordinate[] vertices = warningPolygon.getCoordinates();
|
||||
vertices = Arrays.copyOf(vertices, vertices.length - 1);
|
||||
|
||||
// Extract data
|
||||
float[][] contourPolyData = toFloatData(warningPolygon);
|
||||
float[][] currentPolyData = toFloatData(warningArea);
|
||||
float[][] currentPolyData = warningAreaData;
|
||||
|
||||
// If same area is hatched, just use the current polygon.
|
||||
if (areasEqual(contourPolyData, currentPolyData)) {
|
||||
|
@ -1176,7 +1203,13 @@ public class PolygonUtil {
|
|||
}
|
||||
}
|
||||
|
||||
private float[][] toFloatData(Geometry warningArea) throws VizException {
|
||||
public float[][] toFloatData(Geometry warningArea) throws VizException {
|
||||
float[][] contourAreaData = new float[nx][ny];
|
||||
toFloatData(warningArea, contourAreaData);
|
||||
return contourAreaData;
|
||||
}
|
||||
|
||||
public void toFloatData(Geometry warningArea, float[][] contourAreaData) throws VizException {
|
||||
Geometry contoured = layer.convertGeom(warningArea, latLonToContour);
|
||||
List<Geometry> geomList = new ArrayList<Geometry>(
|
||||
contoured.getNumGeometries());
|
||||
|
@ -1190,7 +1223,6 @@ public class PolygonUtil {
|
|||
GeometryFactory gf = warningArea.getFactory();
|
||||
Point point = gf.createPoint(new Coordinate(0, 0));
|
||||
CoordinateSequence pointCS = point.getCoordinateSequence();
|
||||
float[][] contourAreaData = new float[nx][ny];
|
||||
|
||||
for (PreparedGeometry geom : prepped) {
|
||||
Envelope env = geom.getGeometry().getEnvelopeInternal();
|
||||
|
@ -1198,13 +1230,14 @@ public class PolygonUtil {
|
|||
int startY = (int) env.getMinY();
|
||||
int width = (int) env.getMaxX();
|
||||
int height = (int) env.getMaxY();
|
||||
if (startX < 0 || width > nx || startY < 0 || height > ny) {
|
||||
continue;
|
||||
}
|
||||
|
||||
startX = Math.max(0, startX - 1);
|
||||
startY = Math.max(0, startY - 1);
|
||||
width = Math.min(nx, width + 1);
|
||||
height = Math.min(ny, height + 1);
|
||||
if (width < 0 || startX >= nx || height < 0 || startY >= ny) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int x = startX; x < width; ++x) {
|
||||
for (int y = startY; y < height; ++y) {
|
||||
|
@ -1217,7 +1250,6 @@ public class PolygonUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
return contourAreaData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
package com.raytheon.viz.warngen.gui;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
|
||||
import org.eclipse.core.databinding.observable.ChangeEvent;
|
||||
import org.eclipse.core.databinding.observable.IChangeListener;
|
||||
import org.eclipse.core.databinding.observable.value.WritableValue;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import com.raytheon.viz.warngen.gui.WarngenLayer.ExtensionAreaOptions;
|
||||
|
||||
/**
|
||||
* GUI for advanced WarnGen options.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ------------ --------------------------
|
||||
* 12/21/2015 DCS 17942 D. Friedman Initial revision
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class PolygonOptionsComposite extends Composite {
|
||||
private WarngenLayer warngenLayer;
|
||||
|
||||
private Button allowExtendedPolygonButton;
|
||||
private Text extensionDistanceText;
|
||||
private Text extensionSimplificationToleranceText;
|
||||
private Button visualizeExtensionButton;
|
||||
|
||||
private WritableValue observableOptions;
|
||||
private boolean ignoreControls;
|
||||
private boolean ignoreOptions;
|
||||
|
||||
public PolygonOptionsComposite(Composite parent, WarngenLayer warngenLayer) {
|
||||
super(parent, SWT.NONE);
|
||||
this.warngenLayer = warngenLayer;
|
||||
observableOptions = warngenLayer.getObservableExtensionAreaOptions();
|
||||
createControls();
|
||||
}
|
||||
|
||||
private void createControls() {
|
||||
GridLayout gl = new GridLayout();
|
||||
gl.numColumns = 2;
|
||||
setLayout(gl);
|
||||
|
||||
Label label;
|
||||
|
||||
GridData textGD = new GridData();
|
||||
textGD.horizontalAlignment = GridData.FILL;
|
||||
textGD.grabExcessHorizontalSpace = true;
|
||||
|
||||
GridData fillGD = new GridData();
|
||||
fillGD.horizontalAlignment = GridData.FILL;
|
||||
fillGD.grabExcessHorizontalSpace = true;
|
||||
fillGD.horizontalSpan = 2;
|
||||
|
||||
label = new Label(this, SWT.CENTER);
|
||||
label.setText("Extension Area Options");
|
||||
label.setLayoutData(fillGD);
|
||||
|
||||
allowExtendedPolygonButton = new Button(this, SWT.CHECK);
|
||||
allowExtendedPolygonButton.setText("Allow polygon to extend past valid hatching area");
|
||||
allowExtendedPolygonButton.setLayoutData(fillGD);
|
||||
allowExtendedPolygonButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (ignoreControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExtensionAreaOptions options = getExtensionAreaOptions().clone();
|
||||
options.setEnabled(allowExtendedPolygonButton.getSelection());
|
||||
setOptions(options);
|
||||
}
|
||||
});
|
||||
|
||||
visualizeExtensionButton = new Button(this, SWT.CHECK);
|
||||
visualizeExtensionButton.setText("Show extension area");
|
||||
visualizeExtensionButton.setLayoutData(fillGD);
|
||||
visualizeExtensionButton.setSelection(warngenLayer.isExtensionAreaVisible());
|
||||
visualizeExtensionButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (ignoreControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
warngenLayer.setExtensionAreaVisualized(visualizeExtensionButton.getSelection());
|
||||
}
|
||||
});
|
||||
warngenLayer.getObservableExtensionAreaVisible().addChangeListener(new IChangeListener() {
|
||||
@Override
|
||||
public void handleChange(ChangeEvent event) {
|
||||
visualizeExtensionButton.setSelection(warngenLayer.isExtensionAreaVisible());
|
||||
}
|
||||
});
|
||||
|
||||
label = new Label(this, SWT.LEFT);
|
||||
label.setText("Extension distance (mi)");
|
||||
extensionDistanceText = new Text(this, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
|
||||
extensionDistanceText.setLayoutData(textGD);
|
||||
new DistanceController() {
|
||||
@Override
|
||||
void setValue(double value) {
|
||||
if (ignoreControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExtensionAreaOptions options = getExtensionAreaOptions().clone();
|
||||
options.setDistance(value);
|
||||
setOptions(options);
|
||||
}
|
||||
}.setControl(extensionDistanceText);
|
||||
|
||||
label = new Label(this, SWT.LEFT);
|
||||
label.setText("Simplification tolerance (mi)");
|
||||
extensionSimplificationToleranceText = new Text(this, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
|
||||
extensionSimplificationToleranceText.setLayoutData(textGD);
|
||||
new DistanceController() {
|
||||
@Override
|
||||
void setValue(double value) {
|
||||
if (ignoreControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExtensionAreaOptions options = getExtensionAreaOptions().clone();
|
||||
options.setSimplificationTolerance(value);
|
||||
setOptions(options);
|
||||
}
|
||||
@Override
|
||||
public boolean validate(double value) {
|
||||
return value >= WarngenLayer.ExtensionAreaOptions.MINIMUM_SIMPLIFICATION_TOLERANCE;
|
||||
}
|
||||
}.setControl(extensionSimplificationToleranceText);
|
||||
|
||||
realizeExtensionAreaOptions();
|
||||
|
||||
observableOptions.addChangeListener(new IChangeListener() {
|
||||
@Override
|
||||
public void handleChange(ChangeEvent event) {
|
||||
if (! ignoreOptions) {
|
||||
realizeExtensionAreaOptions();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setOptions(ExtensionAreaOptions options) {
|
||||
ignoreOptions = true;
|
||||
try {
|
||||
observableOptions.setValue(options);
|
||||
} finally {
|
||||
ignoreOptions = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void realizeExtensionAreaOptions() {
|
||||
UnitConverter metersToMile = WarngenLayer.MILES_TO_METER.inverse();
|
||||
ExtensionAreaOptions options = getExtensionAreaOptions();
|
||||
|
||||
ignoreControls = true;
|
||||
try {
|
||||
allowExtendedPolygonButton.setSelection(options.isEnabled());
|
||||
extensionDistanceText.setText(Double.toString(
|
||||
metersToMile.convert(options.getDistance())));
|
||||
extensionSimplificationToleranceText.setText(Double.toString(
|
||||
metersToMile.convert(options.getSimplificationTolerance())));
|
||||
} finally {
|
||||
ignoreControls = false;
|
||||
}
|
||||
}
|
||||
|
||||
private ExtensionAreaOptions getExtensionAreaOptions() {
|
||||
return (ExtensionAreaOptions) observableOptions.getValue();
|
||||
}
|
||||
|
||||
private static abstract class DistanceController implements ModifyListener {
|
||||
Text text;
|
||||
public DistanceController() {
|
||||
}
|
||||
void setControl(Text text) {
|
||||
text.setTextLimit(10);
|
||||
this.text = text;
|
||||
text.addModifyListener(this);
|
||||
}
|
||||
@Override
|
||||
public void modifyText(ModifyEvent event) {
|
||||
boolean ok = false;
|
||||
double newValue = Double.NaN;
|
||||
String s = text.getText();
|
||||
s = s.trim();
|
||||
if (s.length() > 0) {
|
||||
try {
|
||||
newValue = WarngenLayer.MILES_TO_METER.convert(
|
||||
Double.parseDouble(s));
|
||||
} catch (RuntimeException e) {
|
||||
// ignore
|
||||
}
|
||||
ok = validate(newValue);
|
||||
text.setBackground(text.getDisplay().getSystemColor(
|
||||
ok ? SWT.COLOR_LIST_BACKGROUND : SWT.COLOR_RED));
|
||||
if (ok) {
|
||||
setValue(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
abstract void setValue(double value);
|
||||
public boolean validate(double value) { return ! Double.isNaN(value); }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.raytheon.viz.warngen.gui;
|
||||
|
||||
import org.eclipse.jface.action.IAction;
|
||||
|
||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||
|
||||
/**
|
||||
* Action to toggle the display of the extension are in WarngenLayer
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ------------ --------------------------
|
||||
* 12/21/2015 DCS 17942 D. Friedman Initial revision
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class ShowExtensionAreaToggleAction extends AbstractRightClickAction {
|
||||
|
||||
WarngenLayer warngenLayer;
|
||||
|
||||
public void setSelectedRsc(ResourcePair selectedRsc) {
|
||||
super.setSelectedRsc(selectedRsc);
|
||||
AbstractVizResource<?, ?> rsc = selectedRsc != null ? selectedRsc.getResource() : null;
|
||||
if (rsc instanceof WarngenLayer) {
|
||||
warngenLayer = (WarngenLayer) rsc;
|
||||
setChecked(warngenLayer.isExtensionAreaVisible());
|
||||
} else {
|
||||
warngenLayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (warngenLayer != null) {
|
||||
boolean checked = ! warngenLayer.isExtensionAreaVisible();
|
||||
warngenLayer.setExtensionAreaVisualized(checked);
|
||||
setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStyle() {
|
||||
return IAction.AS_CHECK_BOX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Show Extension Area";
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,8 @@ import org.eclipse.jface.dialogs.ErrorDialog;
|
|||
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
|
||||
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.CTabFolder;
|
||||
import org.eclipse.swt.custom.CTabItem;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
|
@ -62,6 +64,7 @@ import org.eclipse.swt.widgets.Shell;
|
|||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
import com.raytheon.uf.common.auth.req.CheckAuthorizationRequest;
|
||||
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
|
||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.BulletActionGroup;
|
||||
|
@ -81,8 +84,10 @@ import com.raytheon.uf.viz.core.VizApp;
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.uf.viz.core.maps.MapManager;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.DisplayType;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.Mode;
|
||||
import com.raytheon.viz.core.mode.CAVEMode;
|
||||
import com.raytheon.viz.texteditor.msgs.IWarngenObserver;
|
||||
import com.raytheon.viz.texteditor.util.VtecUtil;
|
||||
import com.raytheon.viz.ui.EditorUtil;
|
||||
|
@ -171,6 +176,7 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
* Jun 05, 2015 DR 17428 D. Friedman Fixed duration-related user interface issues. Added duration logging.
|
||||
* Sep 22, 2015 4859 dgilling Prevent product generation in DRT mode.
|
||||
* Dec 9, 2015 DR 18209 D. Friedman Support cwaStretch dam break polygons.
|
||||
* Dec 21, 2015 DCS 17942 D. Friedman Add advanced options tab
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -372,7 +378,21 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
}
|
||||
});
|
||||
|
||||
Composite mainComposite = new Composite(shell, SWT.NONE);
|
||||
Composite parent = shell;
|
||||
boolean advanced = isAdvancedOptionsEnabled();
|
||||
CTabFolder tabs = null;
|
||||
CTabItem tabItem = null;
|
||||
if (advanced) {
|
||||
tabs = new CTabFolder(shell, SWT.FLAT|SWT.TOP);
|
||||
parent = tabs;
|
||||
}
|
||||
|
||||
Composite mainComposite = new Composite(parent, SWT.NONE);
|
||||
if (advanced) {
|
||||
tabItem = new CTabItem(tabs, SWT.NONE);
|
||||
tabItem.setText("Product");
|
||||
tabItem.setControl(mainComposite);
|
||||
}
|
||||
GridLayout gl = new GridLayout(1, false);
|
||||
gl.verticalSpacing = 2;
|
||||
gl.marginHeight = 1;
|
||||
|
@ -386,6 +406,12 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
createBulletListAndLabel(mainComposite);
|
||||
createBottomButtons(mainComposite);
|
||||
setInstructions();
|
||||
|
||||
if (advanced) {
|
||||
tabItem = new CTabItem(tabs, SWT.NONE);
|
||||
tabItem.setText("Polygon Options");
|
||||
tabItem.setControl(new PolygonOptionsComposite(tabs, warngenLayer));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2729,4 +2755,20 @@ public class WarngenDialog extends CaveSWTDialog implements
|
|||
DamInfoBullet bullet = bulletListManager.getSelectedDamInfoBullet();
|
||||
return bullet != null && bullet.isCwaStretch();
|
||||
}
|
||||
|
||||
private static boolean isAdvancedOptionsEnabled() {
|
||||
boolean hasPermission = false;
|
||||
|
||||
try {
|
||||
String userId = LocalizationManager.getInstance().getCurrentUser();
|
||||
CheckAuthorizationRequest request = new CheckAuthorizationRequest(
|
||||
userId, "advancedOptions", "WarnGen");
|
||||
hasPermission = (Boolean) ThriftClient.sendRequest(request);
|
||||
} catch (Exception e) {
|
||||
statusHandler.error("error checking permissions", e);
|
||||
}
|
||||
|
||||
return ((hasPermission && CAVEMode.getMode() == CAVEMode.PRACTICE)
|
||||
|| WarngenLayer.isWarngenDeveloperMode());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -39,6 +42,9 @@ import javax.measure.converter.UnitConverter;
|
|||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
|
||||
import org.eclipse.core.databinding.observable.ChangeEvent;
|
||||
import org.eclipse.core.databinding.observable.IChangeListener;
|
||||
import org.eclipse.core.databinding.observable.value.WritableValue;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
@ -65,6 +71,7 @@ import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
|||
import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.BulletActionGroup;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.ExtensionArea;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.GridSpacing;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GenerateGeospatialDataResult;
|
||||
|
@ -141,6 +148,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometry;
|
|||
import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
|
||||
import com.vividsolutions.jts.io.ParseException;
|
||||
import com.vividsolutions.jts.io.WKTReader;
|
||||
import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
|
||||
|
||||
/**
|
||||
* Warngen drawing layer. Need to do EVERYTHING in stereographic over centoid of
|
||||
|
@ -241,6 +249,8 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* 05/07/2015 ASM #17438 D. Friedman Clean up debug and performance logging.
|
||||
* 05/08/2015 ASM #17310 D. Friedman Log input polygon when output of AreaHatcher is invalid.
|
||||
* 12/09/2015 ASM #18209 D. Friedman Support cwaStretch dam break polygons.
|
||||
* 12/21/2015 DCS 17942 D. Friedman Support "extension area": polygon can extend past normal features into WFO's marine/land areas.
|
||||
* Show preview of redrawn polygon when developer mode property is set.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -254,6 +264,9 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
private static final IPerformanceStatusHandler perfLog = PerformanceStatus
|
||||
.getHandler("WG:");
|
||||
|
||||
/*package*/ static final UnitConverter MILES_TO_METER = NonSI.MILE
|
||||
.getConverterTo(SI.METER);
|
||||
|
||||
String uniqueFip = null;
|
||||
|
||||
String backupOfficeShort = null;
|
||||
|
@ -326,7 +339,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
* polygon to intersect with in lat/lon space
|
||||
* @return the warning area in screen projection
|
||||
*/
|
||||
private Geometry buildArea(Polygon polygon, boolean cwaStretch) {
|
||||
private Geometry buildArea(Geometry polygon, boolean cwaStretch) {
|
||||
polygon = latLonToLocal(polygon);
|
||||
Geometry area = null;
|
||||
if (polygon != null) {
|
||||
|
@ -483,6 +496,10 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
private boolean cwaStretch;
|
||||
|
||||
private Future<Geometry> extensionAreaFuture;
|
||||
|
||||
private GeospatialDataAccessor extensionAreaGDA;
|
||||
|
||||
public AreaHatcher(PolygonUtil polygonUtil) {
|
||||
super("Hatching Warning Area");
|
||||
setSystem(true);
|
||||
|
@ -499,11 +516,15 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
protected IStatus run(IProgressMonitor monitor) {
|
||||
Geometry warningArea;
|
||||
Polygon warningPolygon;
|
||||
GeospatialDataAccessor extensionAreaGDA;
|
||||
Future<Geometry> extensionAreaFuture;
|
||||
|
||||
synchronized (polygonUtil) {
|
||||
warningArea = this.warningArea;
|
||||
warningPolygon = this.warningPolygon;
|
||||
this.warningArea = this.warningPolygon = null;
|
||||
extensionAreaGDA = this.extensionAreaGDA;
|
||||
extensionAreaFuture = this.extensionAreaFuture;
|
||||
}
|
||||
|
||||
if ((warningArea != null) && (warningPolygon != null)) {
|
||||
|
@ -512,14 +533,22 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
Polygon outputHatchedArea = null;
|
||||
Geometry outputHatchedWarningArea = null;
|
||||
String adjustmentMessage = null;
|
||||
Geometry extensionArea = null;
|
||||
try {
|
||||
if (extensionAreaGDA != null && extensionAreaFuture != null) {
|
||||
Geometry staticExtensionArea = extensionAreaFuture.get();
|
||||
extensionArea = extensionAreaGDA.buildArea(warningPolygon, false); // never uses cwaStretch
|
||||
if (extensionArea != null && staticExtensionArea != null)
|
||||
extensionArea = GeometryUtil.intersection(extensionArea, staticExtensionArea);
|
||||
}
|
||||
|
||||
warningPolygon = PolygonUtil
|
||||
.removeDuplicateCoordinate(warningPolygon);
|
||||
Polygon hatched = polygonUtil.hatchWarningArea(
|
||||
warningPolygon,
|
||||
removeCounties(warningArea,
|
||||
state.getFipsOutsidePolygon()),
|
||||
oldWarningPolygon,
|
||||
extensionArea, oldWarningPolygon,
|
||||
cwaStretch);
|
||||
if (hatched != null) {
|
||||
// DR 15559
|
||||
|
@ -603,6 +632,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
this.hatchedArea = outputHatchedArea;
|
||||
this.hatchedWarningArea = outputHatchedWarningArea;
|
||||
setOutputPolygon(outputHatchedArea);
|
||||
} catch (Exception e) {
|
||||
this.hatchException = e;
|
||||
/*
|
||||
|
@ -614,6 +644,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
statusHandler.handle(Priority.DEBUG, String.format(
|
||||
"Error redrawing polygon: %s\n Input: %s\nAdjustments: %s\n",
|
||||
e.getLocalizedMessage(), inputWarningPolygon, adjustmentMessage), e);
|
||||
setOutputPolygon(null);
|
||||
}
|
||||
perfLog.logDuration("AreaHatcher total", System.currentTimeMillis() - t0);
|
||||
}
|
||||
|
@ -629,6 +660,14 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
this.oldWarningPolygon = oldWarningPolygon;
|
||||
this.cwaStretch = isCwaStretch();
|
||||
|
||||
if (extensionAreaManager.isExtensionAreaActive()) {
|
||||
this.extensionAreaFuture = extensionAreaManager.getGeometryFuture();
|
||||
this.extensionAreaGDA = extensionAreaManager.getGDA();
|
||||
} else {
|
||||
this.extensionAreaFuture = null;
|
||||
this.extensionAreaGDA = null;
|
||||
}
|
||||
|
||||
this.hatchedArea = null;
|
||||
this.hatchedWarningArea = null;
|
||||
this.hatchException = null;
|
||||
|
@ -667,6 +706,269 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
}
|
||||
|
||||
private void setOutputPolygon(final Polygon polygon) {
|
||||
VizApp.runAsync(new Runnable() {
|
||||
public void run() {
|
||||
outputPolygon = polygon;
|
||||
issueRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ExtensionAreaOptions implements Cloneable {
|
||||
public static final double DEFAULT_SIMPLIFICATION_TOLERANCE = 1609.344; // 1 mile
|
||||
public static final double MINIMUM_SIMPLIFICATION_TOLERANCE = 80.4672; // 0.05 miles
|
||||
private boolean enabled;
|
||||
private double distance = 0.0;
|
||||
private double simplificationTolerance = DEFAULT_SIMPLIFICATION_TOLERANCE;
|
||||
|
||||
public ExtensionAreaOptions() {
|
||||
|
||||
}
|
||||
|
||||
public ExtensionAreaOptions(ExtensionArea ea) {
|
||||
if (ea != null) {
|
||||
// Relying on converters to return NaN for NaN input
|
||||
this.distance = MILES_TO_METER.convert(ea.getDistance());
|
||||
if (! (this.distance > 0)) {
|
||||
this.distance = 0.0;
|
||||
}
|
||||
double v = MILES_TO_METER.convert(ea.getSimplificationTolerance());
|
||||
if (Double.isNaN(v)) {
|
||||
v = DEFAULT_SIMPLIFICATION_TOLERANCE;
|
||||
} else if (! (v >= MINIMUM_SIMPLIFICATION_TOLERANCE)) {
|
||||
v = MINIMUM_SIMPLIFICATION_TOLERANCE;
|
||||
}
|
||||
this.simplificationTolerance = v;
|
||||
this.enabled = this.distance > 0.0;
|
||||
} else {
|
||||
this.distance = 0.0;
|
||||
this.simplificationTolerance = DEFAULT_SIMPLIFICATION_TOLERANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
public double getSimplificationTolerance() {
|
||||
return simplificationTolerance;
|
||||
}
|
||||
public void setSimplificationTolerance(double simplificationTolerance) {
|
||||
this.simplificationTolerance = simplificationTolerance;
|
||||
}
|
||||
|
||||
public ExtensionAreaOptions clone() {
|
||||
try {
|
||||
return (ExtensionAreaOptions) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ExtensionAreaManager extends Job implements IChangeListener {
|
||||
private ExtensionAreaOptions options = new ExtensionAreaOptions();
|
||||
private WritableValue observableOptions = new WritableValue(options, null);
|
||||
|
||||
private GeospatialDataAccessor primaryGDA;
|
||||
private GeospatialDataAccessor gda;
|
||||
|
||||
private Geometry geometry;
|
||||
private FutureTask<Geometry> geometryFuture;
|
||||
|
||||
public ExtensionAreaManager() {
|
||||
super("Generate extension area");
|
||||
observableOptions.addChangeListener(this);
|
||||
}
|
||||
|
||||
public GeospatialDataAccessor getGDA() {
|
||||
return gda;
|
||||
}
|
||||
|
||||
public Future<Geometry> getGeometryFuture() {
|
||||
return geometryFuture;
|
||||
}
|
||||
|
||||
public boolean isExtensionAreaActive() {
|
||||
return options.isEnabled() && options.getDistance() > 0.0;
|
||||
}
|
||||
|
||||
public void setExtensionAreaConfig(ExtensionArea extensionAreaConfig) {
|
||||
observableOptions.setValue(new ExtensionAreaOptions(extensionAreaConfig));
|
||||
}
|
||||
|
||||
private void realizeOptions(ExtensionAreaOptions options) {
|
||||
if (options == null) {
|
||||
throw new NullPointerException("options must not be null");
|
||||
}
|
||||
boolean recreateArea = true;
|
||||
ExtensionAreaOptions oldOptions = this.options;
|
||||
if (oldOptions != null) {
|
||||
if (primaryGDA == geoAccessor
|
||||
&& oldOptions.getDistance() == options.getDistance()
|
||||
&& oldOptions.getSimplificationTolerance() ==
|
||||
options.getSimplificationTolerance()) {
|
||||
recreateArea = false;
|
||||
}
|
||||
}
|
||||
this.options = options.clone();
|
||||
if (recreateArea) {
|
||||
geometry = null;
|
||||
if (geometryFuture != null) {
|
||||
geometryFuture.cancel(true);
|
||||
geometryFuture = null;
|
||||
}
|
||||
extensionAreaVis = null;
|
||||
if (extensionAreaShadedShape != null) {
|
||||
extensionAreaShadedShape.reset();
|
||||
issueRefresh();
|
||||
}
|
||||
gda = null;
|
||||
if (isExtensionAreaDefined()) {
|
||||
Exception error = null;
|
||||
primaryGDA = geoAccessor;
|
||||
try {
|
||||
gda = getPolygonExtensionGDA();
|
||||
} catch (Exception e) {
|
||||
error = e;
|
||||
}
|
||||
if (gda != null) {
|
||||
geometryFuture = new FutureTask<Geometry>(
|
||||
new ExtensionAreaGeometryTask(options,
|
||||
primaryGDA, gda));
|
||||
schedule();
|
||||
} else {
|
||||
statusHandler.handle(Priority.WARN,
|
||||
"Could not determine geospatial data type for polygon extension area",
|
||||
error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Polygon polygon = getWarngenState().getWarningPolygon();
|
||||
if (polygon != null) {
|
||||
try {
|
||||
updateWarnedAreas(true);
|
||||
} catch (VizException e) {
|
||||
statusHandler.error("Error re-hatching", e);
|
||||
}
|
||||
issueRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
FutureTask<Geometry> future = geometryFuture;
|
||||
if (future != null) {
|
||||
future.run();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
public boolean isExtensionAreaDefined() {
|
||||
return options.getDistance() > 0;
|
||||
}
|
||||
|
||||
protected GeospatialDataAccessor getPolygonExtensionGDA() throws Exception {
|
||||
GeoFeatureType geoFeatureType = getDefaultExtensionAreaGeoType();
|
||||
return geoFeatureType != null ? getGeospatialDataAcessor(geoFeatureType)
|
||||
: null;
|
||||
}
|
||||
|
||||
protected GeoFeatureType getDefaultExtensionAreaGeoType() {
|
||||
GeoFeatureType otherType = null;
|
||||
AreaSourceConfiguration asc = getConfiguration().getHatchedAreaSource();
|
||||
if (asc != null) {
|
||||
String areaSource = asc.getAreaSource().toLowerCase();
|
||||
if (areaSource.contains("marinezones"))
|
||||
otherType = GeoFeatureType.COUNTY;
|
||||
else if (areaSource.contains("county") || areaSource.contains("zone")) {
|
||||
otherType = GeoFeatureType.MARINE;
|
||||
} else {
|
||||
otherType = GeoFeatureType.COUNTY;
|
||||
}
|
||||
}
|
||||
return otherType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleChange(ChangeEvent event) {
|
||||
ExtensionAreaOptions options = (ExtensionAreaOptions) ((WritableValue) event
|
||||
.getObservable()).getValue();
|
||||
realizeOptions(options != null ? options : new ExtensionAreaOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public WritableValue getObservableExtensionAreaOptions() {
|
||||
return extensionAreaManager.observableOptions;
|
||||
}
|
||||
|
||||
private class ExtensionAreaGeometryTask implements Callable<Geometry> {
|
||||
ExtensionAreaOptions options;
|
||||
GeospatialDataAccessor primaryGDA;
|
||||
GeospatialDataAccessor extensionGDA;
|
||||
|
||||
public ExtensionAreaGeometryTask(ExtensionAreaOptions options,
|
||||
GeospatialDataAccessor primaryGDA, GeospatialDataAccessor extensionGDA) {
|
||||
if (! (options.getDistance() > 0)) {
|
||||
throw new IllegalArgumentException("Extension distance must be greater than zero.");
|
||||
}
|
||||
this.options = options;
|
||||
this.primaryGDA = primaryGDA;
|
||||
this.extensionGDA = extensionGDA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Geometry call() throws Exception {
|
||||
return createExtensionArea();
|
||||
}
|
||||
|
||||
private Geometry createExtensionArea() throws Exception {
|
||||
GeospatialData[] features = primaryGDA.geoData.getFeatures(false); // Never uses cwaStretch feactures.
|
||||
Geometry[] g = new Geometry[features.length];
|
||||
for (int i = 0; i < g.length; ++i) {
|
||||
/*
|
||||
* Pre-simplify as an optmization. Makes it possible to
|
||||
* change the static extension distance in real time.
|
||||
*/
|
||||
g[i] = extensionSimplify(
|
||||
convertGeom(features[i].geometry, primaryGDA.geoData.latLonToLocal),
|
||||
options.getSimplificationTolerance()).
|
||||
buffer(options.getDistance());
|
||||
}
|
||||
Geometry r = GeometryUtil.union(g);
|
||||
r = createExtensionAreaFromLocal(r);
|
||||
extensionAreaVis = extensionGDA.buildArea(r, false);
|
||||
issueRefresh();
|
||||
return r;
|
||||
}
|
||||
|
||||
private Geometry createExtensionAreaFromLocal(Geometry geom) {
|
||||
// geom should be simlified so that the following ops are not painful.
|
||||
Geometry r = geom;
|
||||
r = r.buffer(0);
|
||||
r = extensionSimplify(r, options.getSimplificationTolerance());
|
||||
r = convertGeom(r, primaryGDA.geoData.localToLatLon);
|
||||
return r;
|
||||
}
|
||||
|
||||
private Geometry extensionSimplify(Geometry geom, double tolerance) {
|
||||
if (tolerance >= 0) {
|
||||
geom = TopologyPreservingSimplifier.simplify(geom, tolerance);
|
||||
}
|
||||
return geom;
|
||||
}
|
||||
}
|
||||
|
||||
private static class GeomMetaDataUpdateNotificationObserver implements
|
||||
|
@ -798,6 +1100,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
private GeomMetaDataUpdateNotificationObserver geomUpdateObserver;
|
||||
|
||||
private ExtensionAreaManager extensionAreaManager = new ExtensionAreaManager();
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
if ((i % 32) == 0) {
|
||||
|
@ -840,6 +1144,13 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
setSpeedAndAngle();
|
||||
setDuration();
|
||||
|
||||
observableExtensionAreaVisible.addChangeListener(new IChangeListener() {
|
||||
@Override
|
||||
public void handleChange(ChangeEvent event) {
|
||||
issueRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1005,6 +1316,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
coveredAreaFrame = target.createWireframeShape(true, this.descriptor);
|
||||
shadedCoveredArea = target.createShadedShape(true,
|
||||
this.descriptor.getGridGeometry(), true);
|
||||
extensionAreaShadedShape = target.createShadedShape(true,
|
||||
this.descriptor.getGridGeometry());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1082,6 +1395,20 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
}
|
||||
}
|
||||
|
||||
if ((Boolean) observableExtensionAreaVisible.getValue()) {
|
||||
if (extensionAreaVis != null) {
|
||||
extensionAreaShadedShape.reset();
|
||||
JTSCompiler comp = new JTSCompiler(extensionAreaShadedShape, null, descriptor);
|
||||
Geometry g = extensionAreaVis;
|
||||
extensionAreaVis = null;
|
||||
if (g != null) {
|
||||
comp.handle(g, extensionAreaVisualizationColor);
|
||||
}
|
||||
}
|
||||
target.drawShadedShape(extensionAreaShadedShape,
|
||||
extensionAreaVisualizationAlpha);
|
||||
}
|
||||
|
||||
lastMode = displayState.mode;
|
||||
}
|
||||
|
||||
|
@ -1090,17 +1417,51 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
displayState.intialFrame = trackUtil.getCurrentFrame(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @param paintProps
|
||||
* @param thePrimitivePolygon2
|
||||
*/
|
||||
private static class PolygonStyle {
|
||||
public boolean show;
|
||||
public RGB color;
|
||||
public int lineWidth;
|
||||
public boolean showVertices;
|
||||
public PolygonStyle(boolean show, RGB color, int lineWidth, boolean showVertices) {
|
||||
this.show = show;
|
||||
this.color = color;
|
||||
this.lineWidth = lineWidth;
|
||||
this.showVertices = showVertices;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String OUTPUT_POLYGON = "Result";
|
||||
private static final String EDIT_POLYGON = "Edit";
|
||||
|
||||
private Polygon outputPolygon = null;
|
||||
private Map<String, PolygonStyle> polygonStyles = new HashMap<String, PolygonStyle>();
|
||||
{
|
||||
polygonStyles.put(OUTPUT_POLYGON, new PolygonStyle(isWarngenDeveloperMode(),
|
||||
new RGB(0, 128, 128), 5, true));
|
||||
polygonStyles.put(EDIT_POLYGON, new PolygonStyle(true,
|
||||
new RGB(255, 255, 255), 3, true));
|
||||
}
|
||||
|
||||
private void paintPolygon(IGraphicsTarget target,
|
||||
PaintProperties paintProps, Polygon thePrimitivePolygon)
|
||||
throws VizException {
|
||||
RGB color = getCapability(ColorableCapability.class).getColor();
|
||||
float LINE_WIDTH = getCapability(OutlineCapability.class)
|
||||
.getOutlineWidth();
|
||||
if (outputPolygon != null) {
|
||||
paintPolygon(target, paintProps, outputPolygon,
|
||||
polygonStyles.get(OUTPUT_POLYGON));
|
||||
}
|
||||
PolygonStyle editStyle = polygonStyles.get(EDIT_POLYGON);
|
||||
editStyle.color = getCapability(ColorableCapability.class).getColor();
|
||||
editStyle.lineWidth = getCapability(OutlineCapability.class).getOutlineWidth();
|
||||
paintPolygon(target, paintProps, thePrimitivePolygon, editStyle);
|
||||
}
|
||||
|
||||
private void paintPolygon(IGraphicsTarget target,
|
||||
PaintProperties paintProps, Polygon thePrimitivePolygon, PolygonStyle style)
|
||||
throws VizException {
|
||||
if (!style.show)
|
||||
return;
|
||||
RGB color = style.color;
|
||||
float LINE_WIDTH = style.lineWidth;
|
||||
float zoomLevel = paintProps.getZoomLevel();
|
||||
if (LINE_WIDTH < 1.5f) {
|
||||
LINE_WIDTH = 1.5f;
|
||||
|
@ -1130,29 +1491,31 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
line.width = LINE_WIDTH;
|
||||
lines.add(line);
|
||||
|
||||
double delta;
|
||||
if (style.showVertices) {
|
||||
double delta;
|
||||
|
||||
if (!boxEditable) {
|
||||
delta = 25 * zoomLevel;
|
||||
} else {
|
||||
delta = 80 * zoomLevel;
|
||||
if (!boxEditable) {
|
||||
delta = 25 * zoomLevel;
|
||||
} else {
|
||||
delta = 80 * zoomLevel;
|
||||
}
|
||||
// Build triangle control points
|
||||
|
||||
double[] triTop = new double[] { out1[0], out1[1] - delta };
|
||||
double[] triLeft = new double[] { out1[0] - delta,
|
||||
out1[1] + delta };
|
||||
double[] triRight = new double[] { out1[0] + delta,
|
||||
out1[1] + delta };
|
||||
|
||||
DrawableLine line2 = new DrawableLine();
|
||||
line2.setCoordinates(triLeft[0], triLeft[1]);
|
||||
line2.addPoint(triTop[0], triTop[1]);
|
||||
line2.addPoint(triRight[0], triRight[1]);
|
||||
line2.addPoint(triLeft[0], triLeft[1]);
|
||||
line2.basics.color = color;
|
||||
line2.width = LINE_WIDTH;
|
||||
lines.add(line2);
|
||||
}
|
||||
// Build triangle control points
|
||||
|
||||
double[] triTop = new double[] { out1[0], out1[1] - delta };
|
||||
double[] triLeft = new double[] { out1[0] - delta,
|
||||
out1[1] + delta };
|
||||
double[] triRight = new double[] { out1[0] + delta,
|
||||
out1[1] + delta };
|
||||
|
||||
DrawableLine line2 = new DrawableLine();
|
||||
line2.setCoordinates(triLeft[0], triLeft[1]);
|
||||
line2.addPoint(triTop[0], triTop[1]);
|
||||
line2.addPoint(triRight[0], triRight[1]);
|
||||
line2.addPoint(triLeft[0], triLeft[1]);
|
||||
line2.basics.color = color;
|
||||
line2.width = LINE_WIDTH;
|
||||
lines.add(line2);
|
||||
}
|
||||
target.drawLine(lines.toArray(new DrawableLine[0]));
|
||||
}
|
||||
|
@ -1223,6 +1586,51 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
target.drawStrings(strings);
|
||||
}
|
||||
|
||||
private Geometry extensionAreaVis;
|
||||
|
||||
private WritableValue observableExtensionAreaVisible = new WritableValue(false, null);
|
||||
|
||||
private RGB extensionAreaVisualizationColor = new RGB(240, 128, 128);
|
||||
|
||||
private float extensionAreaVisualizationAlpha = 0.4f;
|
||||
|
||||
private IShadedShape extensionAreaShadedShape = null;
|
||||
|
||||
public WritableValue getObservableExtensionAreaVisible() {
|
||||
return observableExtensionAreaVisible;
|
||||
}
|
||||
|
||||
public boolean isExtensionAreaVisible() {
|
||||
return (Boolean) observableExtensionAreaVisible.getValue();
|
||||
}
|
||||
|
||||
public void setExtensionAreaVisualized(boolean visible) {
|
||||
observableExtensionAreaVisible.setValue(visible);
|
||||
}
|
||||
|
||||
public RGB getExtensionAreaVisualizationColor() {
|
||||
return extensionAreaVisualizationColor;
|
||||
}
|
||||
|
||||
public void setExtensionAreaVisualizationColor(
|
||||
RGB extensionAreaVisualizationColor) {
|
||||
if (extensionAreaVisualizationColor == null) {
|
||||
throw new NullPointerException("extensionAreaVisualizationColor must be non-null");
|
||||
}
|
||||
this.extensionAreaVisualizationColor = extensionAreaVisualizationColor;
|
||||
issueRefresh();
|
||||
}
|
||||
|
||||
public float getExtensionAreaVisualizationAlpha() {
|
||||
return extensionAreaVisualizationAlpha;
|
||||
}
|
||||
|
||||
public void setExtensionAreaVisualizationAlpha(
|
||||
float extensionAreaVisualizationAlpha) {
|
||||
this.extensionAreaVisualizationAlpha = extensionAreaVisualizationAlpha;
|
||||
issueRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param templateName
|
||||
* the templateName to set
|
||||
|
@ -1289,6 +1697,7 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
createAreaAndCentroidMaps();
|
||||
|
||||
this.configuration = config;
|
||||
extensionAreaManager.setExtensionAreaConfig(config.getExtensionArea());
|
||||
}// end synchronize
|
||||
|
||||
perfLog.logDuration("Init warngen config",
|
||||
|
@ -3886,4 +4295,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
! isBoxEditable();
|
||||
}
|
||||
|
||||
private static boolean warngenDeveloperMode =
|
||||
Boolean.getBoolean("com.raytheon.viz.warngen.developerMode");
|
||||
|
||||
public static boolean isWarngenDeveloperMode() {
|
||||
return warngenDeveloperMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<nwsRoleData xmlns:ns2="group">
|
||||
<!-- AWIPS 2 WarnGen permissions file -->
|
||||
<application>WarnGen</application>
|
||||
<permission id="advancedOptions">
|
||||
<description>
|
||||
This permission allows the user to view advanced options in practice mode.
|
||||
</description>
|
||||
</permission>
|
||||
</nwsRoleData>
|
|
@ -0,0 +1,51 @@
|
|||
package com.raytheon.uf.common.dataplugin.warning.config;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
/**
|
||||
* Describes how polygon is allowed to extend into a site's marine areas
|
||||
* (for land-based warnings) or onto land (for marine-based warnings.)
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ------------ --------------------------
|
||||
* 12/21/2015 DCS 17942 D. Friedman Initial revision
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class ExtensionArea implements Cloneable {
|
||||
private double distance = Double.NaN;
|
||||
private double simplificationTolerance = Double.NaN;
|
||||
|
||||
@XmlAttribute
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
@XmlAttribute(name="simplification")
|
||||
public double getSimplificationTolerance() {
|
||||
return simplificationTolerance;
|
||||
}
|
||||
|
||||
public void setSimplificationTolerance(double simplificationTolerance) {
|
||||
this.simplificationTolerance = simplificationTolerance;
|
||||
}
|
||||
|
||||
public ExtensionArea clone() {
|
||||
try {
|
||||
return (ExtensionArea) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
* Oct 22, 2013 2361 njensen Removed ISerializableObject
|
||||
* Apr 28, 2014 3033 jsanchez Properly handled back up configuration (*.xml) files.
|
||||
* Aug 28, 2014 ASM #15658 D. Friedman Add marine zone watch wording option.
|
||||
* Dec 21, 2015 DCS 17942 D. Friedman Add extension area specification.
|
||||
* </pre>
|
||||
*
|
||||
* @author chammack
|
||||
|
@ -154,6 +155,9 @@ public class WarngenConfiguration {
|
|||
@XmlElement(name = "lockedGroupsOnFollowup")
|
||||
private String lockedGroupsOnFollowup;
|
||||
|
||||
@XmlElement
|
||||
private ExtensionArea extensionArea;
|
||||
|
||||
/**
|
||||
* Method used to load a configuration file for a newly selected Warngen
|
||||
* template.
|
||||
|
@ -522,4 +526,12 @@ public class WarngenConfiguration {
|
|||
this.hatchedAreaSource = hatchedAreaSource;
|
||||
}
|
||||
|
||||
public ExtensionArea getExtensionArea() {
|
||||
return extensionArea;
|
||||
}
|
||||
|
||||
public void setExtensionArea(ExtensionArea extensionArea) {
|
||||
this.extensionArea = extensionArea;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue