VLab Issue #5061. LAPS Tools; fixes #5061

Change-Id: I447e7e94b931ad2efad687efa90e16cebb2e7bf9

Former-commit-id: e05f01c705953d0c9528cfea6604f88455a5f5ac
This commit is contained in:
Paula McCaslin 2014-11-12 13:58:24 -07:00
parent dc13fce4dc
commit a5c805cf4d
5 changed files with 712 additions and 562 deletions

View file

@ -23,6 +23,10 @@ package com.raytheon.viz.awipstools.ui.action;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
@ -30,9 +34,8 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.awipstools.Activator;
import com.raytheon.viz.awipstools.ui.dialog.LAPSToolsDlg;
import com.raytheon.viz.ui.EditorUtil;
/**
* TODO Add Description
@ -43,7 +46,9 @@ import com.raytheon.viz.awipstools.ui.dialog.LAPSToolsDlg;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
*
* May 2009 # bsteffen Initial creation
* Nov 2013 # mccaslin Only one GUI dialog at a time
* Oct 2014 # mccaslin Improved error handeling
*
* </pre>
*
@ -53,15 +58,59 @@ import com.raytheon.viz.awipstools.ui.dialog.LAPSToolsDlg;
public class LapsToolsAction extends AbstractHandler {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(LapsToolsAction.class);
/**
* LAPS Tools dialog.
*/
private static LAPSToolsDlg lapsToolsDlg = null;
public static LAPSToolsDlg getLapsToolsDlg() {
return lapsToolsDlg;
}
public Object execute(ExecutionEvent arg0) throws ExecutionException {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
try {
new LAPSToolsDlg(shell).open();
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Error: Cannot open LAPS Tools", e);
if (lapsToolsDlg == null) {
try {
lapsToolsDlg = new LAPSToolsDlg(shell);
lapsToolsDlg.addListener(SWT.Dispose, new Listener() {
@Override
public void handleEvent(Event event) {
lapsToolsDlg = null;
}
});
if (lapsToolsDlg.isLapsInstalled()) {
lapsToolsDlg.open();
} else {
String whatLapsIs ="LAPS data assimilation system, system requirements: " +
"\n\to LAPS v2.0 installed" +
"\n\to EDEX 'SITE' file containing LAPS domain, i.e. domain.xml" +
"\n\n\n(Sorry LAPS does not work in the ADAM implementation of AWIPS.)";
//Note: Go through the LAPS v2.0 Scripting Interface first, if you find that LAPS is not installed.
MessageBox mb = new MessageBox(EditorUtil.getActiveEditor().getSite().getShell(), SWT.ICON_WARNING | SWT.OK);
mb.setText("Cannot open LAPS V2.0 Tools GUI");
mb.setMessage(whatLapsIs);
mb.open();
lapsToolsDlg = null;
//int val = mb.open();
//if (val == SWT.OK) {
// AlertViz Customization Update
//return false;
//}
}
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Error: Cannot open LAPS V2.0 Tools GUI", e);
}
}
return null;
}

View file

@ -1,7 +1,11 @@
package com.raytheon.viz.awipstools.ui.action;
import java.awt.geom.Point2D;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.geotools.referencing.GeodeticCalculator;
import com.vividsolutions.jts.geom.Coordinate;
@ -19,24 +23,24 @@ public class LapsToolsData {
private Double gridSpacing;
private Double dp;
private Double lowp;
private Double lat;
private Double lat2;
private Double lon;
private Coordinate[] corners;
private Envelope cwaArea;
private Envelope validArea;
private Envelope validAreaOrig;
private Envelope validAreaDefault;
private Envelope gridArea;
private String areaCoverageString;
private Boolean belowLimits;
public Coordinate getGridCenter() {
return gridCenter;
}
@ -61,22 +65,38 @@ public class LapsToolsData {
return gridSpacing;
}
public Double getDp() {
return dp;
}
public String getAreaCoverageString() {
double nxDist = getNx()*getGridSpacing()/1000;
double nyDist = getNy()*getGridSpacing()/1000;
double areaCoverage = nxDist * nyDist;
this.areaCoverageString = String.format("%.1f km by %.1f km = %.2f km2",
nxDist, nyDist, areaCoverage);
double maximumArea = 14140140.;
double minimumArea = 150000.;
public Double getLowp() {
return lowp;
}
if(areaCoverage > maximumArea) {
System.out.print("LAPS Tools Data: problem with this domain exceeding the RUC 236 background\n");
MessageDialog.openWarning(getShell(), "Domain Size Error",
"The size of new domain would exceed the maximum limits \n\tdefined by model background (the RAP40 grid).\n");
} else if(areaCoverage < minimumArea) {
System.out.print("LAPS Tools Data: problem with this domain coverage area being smaller than the CWA coverage area\n");
MessageDialog.openWarning(getShell(), "Domain Size Error",
"The size of new domain area would LESS than the minimum limits \n\tdefined by the CWA coverage area.");
}
public Double getLat() {
return areaCoverageString;
}
private Shell getShell() {
// TODO Auto-generated method stub
return null;
}
public Double getLat() {
return lat;
}
public Double getLat2() {
return lat2;
}
public Double getLon() {
return lon;
}
@ -85,22 +105,57 @@ public class LapsToolsData {
return cwaArea;
}
public void setLimits(Boolean belowLimits) {
this.belowLimits = belowLimits;
}
public Boolean getLimits() {
return belowLimits;
}
public Envelope getValidArea() {
if (validArea == null) {
double halfHeight = Math.abs(corners[3].x - corners[0].x) / 2;
double halfWidth = Math.abs(corners[0].y - corners[3].y) / 2;
double cwa_dist_lat = halfHeight - cwaArea.getHeight() / 2;
double cwa_dist_lon = halfWidth - cwaArea.getWidth() / 2;
double buffer = .1; // tenth of a degree buffer around CWA (in km)
double cosBuffer = Math.abs(2*Math.cos(cwaArea.centre().y));
double cwa_dist_lat = Math.abs(cwaArea.getHeight() / 2) + (2 * buffer);
double cwa_dist_lon = Math.abs(cwaArea.getWidth() / 2) + (2 * buffer * cosBuffer);
validArea = new Envelope(cwaArea.centre());
validArea.expandBy(cwa_dist_lon, cwa_dist_lat);
validArea.expandBy(cwa_dist_lon, cwa_dist_lat);
double z = Math.abs(cwaArea.getHeight() / cwaArea.getWidth()) ;
System.out.print("LAPS Tools Data: cwa height = "+cwaArea.getHeight()+"\n");
System.out.print("cwa width = "+cwaArea.getWidth()+"\n");
System.out.print("z ratio = "+z+"\n");
}
return validArea;
}
public Envelope getValidAreaOrig() {
if (validAreaOrig == null) {
double cwa_dist_lat = Math.abs(cwaArea.getHeight() / 2);
double cwa_dist_lon = Math.abs(cwaArea.getWidth() / 2);
validAreaOrig = new Envelope(cwaArea.centre());
validAreaOrig.expandBy(cwa_dist_lon, cwa_dist_lat);
}
return validAreaOrig;
}
public Envelope getValidAreaDefault() {
if (validAreaDefault == null) {
double buffer = 1; // half degree buffer around CWA (in km)
double cosBuffer = Math.abs(2*Math.cos(cwaArea.centre().y));
double cwa_dist_lat = Math.abs(cwaArea.getHeight() / 2) + (2 * buffer);
double cwa_dist_lon = Math.abs(cwaArea.getWidth() / 2) + (2 * buffer * cosBuffer);
validAreaDefault = new Envelope(cwaArea.centre());
validAreaDefault.expandBy(cwa_dist_lon, cwa_dist_lat);
}
return validAreaDefault;
}
public Envelope getGridArea() {
if (gridArea == null) {
double width = gridSpacing * nx;
double height = gridSpacing * ny;
double width = getGridSpacing() * nx;
double height = getGridSpacing() * ny;
GeodeticCalculator gc = new GeodeticCalculator();
gc.setStartingGeographicPoint(gridCenter.x, gridCenter.y);
gc.setDirection(0.0, height / 2);
@ -129,16 +184,7 @@ public class LapsToolsData {
}
return gridArea;
}
public Coordinate[] getCorners() {
return corners;
}
public void setCorners(Coordinate[] corners) {
validArea = null;
this.corners = corners;
}
public void setCwaArea(Envelope cwaArea) {
validArea = null;
this.cwaArea = cwaArea;
@ -178,24 +224,71 @@ public class LapsToolsData {
this.nz = nz;
}
public void setDp(Double dp) {
this.dp = dp;
}
public void setLowp(Double lowp) {
this.lowp = lowp;
}
public void setLat(Double lat) {
this.lat = lat;
}
public void setLat2(Double lat2) {
this.lat2 = lat2;
}
public void setLon(Double lon) {
this.lon = lon;
}
//LAPS domain.xml has <domain> tags and <NX_L> tags, etc
@XmlRootElement(name="domain", namespace="")
public static class LapsDomain {
private Integer nx;
private Integer ny;
private Integer nz;
private Double gridSpacing;
private Double lat;
private Double lon;
public int getNx() {
return nx;
}
@XmlElement(name = "NX_L")
public void setNx(int nx) {
this.nx = nx;
}
public int getNy() {
return ny;
}
@XmlElement(name = "NY_L")
public void setNy(int ny) {
this.ny = ny;
}
public int getNz() {
return nz;
}
@XmlElement(name = "NK_LAPS")
public void setNz(int nz) {
this.nz = nz;
}
public Double getGridSpacing() {
return gridSpacing;
}
@XmlElement(name = "GRID_SPACING_M")
public void setGridSpacing(Double gridSpacing) {
this.gridSpacing = gridSpacing;
}
public Double getGridCenLat() {
return lat;
}
@XmlElement(name = "GRID_CEN_LAT")
public void setGridCenLat(Double lat) {
this.lat = lat;
}
public Double getGridCenLon() {
return lon;
}
@XmlElement(name = "GRID_CEN_LON")
public void setGridCenLon(Double lon) {
this.lon = lon;
}
}
}

View file

@ -4,12 +4,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
@ -17,28 +12,41 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.geospatial.SpatialException;
import com.raytheon.uf.common.geospatial.SpatialQueryFactory;
import com.raytheon.uf.common.geospatial.SpatialQueryResult;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
import com.vividsolutions.jts.geom.Coordinate;
import com.raytheon.viz.awipstools.ui.action.LapsToolsData.LapsDomain;
import com.vividsolutions.jts.geom.Envelope;
/**
* This class performs all the filesystem and server input/output for the laps
* tools. This implementation was ported as directly as possible from awips1,
* and is not necessarily a good design for multiprocess and multisystem
* communication.
* This class no longer performs all the file system, server input/output for laps.
* LAPS support scripts now conduct the localization process.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 2009 # bsteffen Initial creation
* Nov 2013 # mccaslin New design approach, changed from OS calls to file io, read xml code, etc
*
* </pre>
*
@ -47,331 +55,147 @@ import com.vividsolutions.jts.geom.Coordinate;
*/
public class LapsToolsIO {
private static final String SERVER_STATUS_CMD_FRMT = "%s uname -n";
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(LapsToolsIO.class);
private static final String TIMESTAMP_CMD_FRMT = "%s %s/etc/fxalogdir.pl";
private static final String SURFACE_LOG_CMD_FRMT = "%s %s/sfc.pl -l%s -rlaps_sfc";
private static final String OTHER_LOG_CMD_FRMT = "%s %s/%s %s";
private static final String CHANGE_CENTER_CMD_FMT = "%s/etc/change-center.pl %s";
private static final String WINDOW_DOMAIN_CMD_FMT = "%s/etc/window_domain_rt.pl -w laps -i %s -s %s -t %s -c";
private static final String RELOCALIZE_CMD_FMT = "%s/etc/wfo-relocalization.pl";
private static final String FINALIZE_CMD_FMT = "/awips/fxa/bin/fxaAnnounce '%s' SYSTEM SIGNIFICANT; rm %s";
private static String serverName;
private static File lapsRoot;
private static File scriptDir;
private static String execCmd;
private static File nest7grid;
private static File nest7grid_template;
private static File nest7grid_orig;
private static final String WHATGOTIN_FILE_FRMT = "%s/%s.wgi";
private static File fxaData;
private static File lapsLogs;
private static List<String> whatgotinFiles;
private static List<String> dataChoices;
private static List<String> dataScripts;
private static File cornerPointFile;
private static File lockFile;
static {
// TODO all this configuration should be customizable by the user.
serverName = "px1f";
// --- For what got in log files ---
if (System.getenv("FXA_DATA") == null) {
fxaData = new File("/awips/fxa");
fxaData = new File("/data/fxa");
} else {
fxaData = new File(System.getenv("FXA_DATA"));
}
if (System.getenv("LAPSROOT") == null) {
lapsRoot = new File(fxaData + "/laps");
} else {
lapsRoot = new File(System.getenv("LAPSROOT"));
}
scriptDir = new File(lapsRoot + "/etc");
execCmd = "ssh -q " + serverName;
dataChoices = Arrays.asList("Surface", "Wind", "Humidity", "Clouds",
"Temperature");
dataScripts = Arrays.asList("sfc.pl", "wind3d.pl", "hum3d.pl",
"cloud.pl", "temp.pl");
nest7grid = new File(fxaData + "/laps/static/nest7grid.parms");
nest7grid_orig = new File(fxaData + "/laps_data/static/nest7grid.parms");
nest7grid_template = new File(fxaData + "/laps_domain/nest7grid.parms");
cornerPointFile = new File(fxaData + "/laps/static/corners.dat");
lockFile = new File(fxaData + "/laps_domain/lock_laps_ui");
lapsLogs = new File(fxaData + "/laps/log/wgi");
whatgotinFiles = Arrays.asList("sfc", "wind", "lq3driver", "cloud", "temp");
dataChoices = Arrays.asList("Surface Analysis",
"Wind Analysis",
"Humidity Analysis",
"Cloud Analysis",
"Temperature Analysis");
}
public static Collection<String> getDataChoices() {
return dataChoices;
}
public static void lockLaps() throws VizException {
if (lockFile.exists()) {
throw new VizException(
"Sorry, but LAPS tool is currently processing another request and will not be available until the current process has completed.");
}
// For some reason awips1 doesn't actually lock it until you localize
}
public static void unlockLaps() {
if (lockFile.exists()) {
lockFile.delete();
}
}
public static String getFailover() throws IOException,
InterruptedException, VizException {
Process p = null;
try {
p = Runtime.getRuntime().exec(
String.format(SERVER_STATUS_CMD_FRMT, execCmd));
int status = p.waitFor();
String result = readOutput(p);
if (status == 0) {
// Success getting to machine
String actual_name = result.split("-")[0];
if (!serverName.replaceAll("f$", "").equals(actual_name)) {
// Failover state
return String
.format("Note: %s is running in a failover state. LAPS log files may not yet be available.",
serverName);
}
} else {
throw new VizException(
String.format(
"Sorry, error getting to %s system. The LAPS Tools GUI is not available.",
serverName));
}
} finally {
if (p != null) {
p.destroy();
}
}
return null;
}
public static String getLogs(String type) throws IOException,
InterruptedException {
Process tsProcess = null;
Process logProcess = null;
try {
tsProcess = Runtime.getRuntime().exec(
String.format(TIMESTAMP_CMD_FRMT, execCmd, lapsRoot));
tsProcess.waitFor();
String timeStamp = readOutput(tsProcess);
String cmd = null;
if (type.equals("Surface")) {
cmd = String.format(SURFACE_LOG_CMD_FRMT, execCmd, scriptDir,
timeStamp);
} else {
cmd = String.format(OTHER_LOG_CMD_FRMT, execCmd, scriptDir,
dataScripts.get(dataChoices.indexOf(type)), timeStamp);
}
logProcess = Runtime.getRuntime().exec(cmd);
logProcess.waitFor();
String result = readOutput(logProcess);
return result;
} finally {
if (tsProcess != null) {
tsProcess.destroy();
}
if (logProcess != null) {
logProcess.destroy();
}
}
VizException {
String wgiFile = String.format(WHATGOTIN_FILE_FRMT, lapsLogs,
whatgotinFiles.get(dataChoices.indexOf(type)));
String resultIO = loadWhatGotInFile(wgiFile, type);
return (resultIO);
}
private static String loadWhatGotInFile(String wfile, String type)
throws IOException {
BufferedReader reader;
StringBuilder output = new StringBuilder();
File file = new File(wfile);
try {
reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
String arg = String.format("*** Cannot find expected log file for %s." +
"\n*** File %s ....does not appear to exist.\n\n",
type, file.getAbsolutePath());
output.append(arg);
return output.toString();
}
String line;
int lineNumber = 0;
while ((line = reader.readLine()) != null) {
String arg = String.format("%04d: %s%n", ++lineNumber, line);
output.append(arg);
}
reader.close();
return output.toString();
}
public static LapsToolsData loadData() throws IOException, VizException,
SpatialException {
LapsToolsData data = new LapsToolsData();
LapsToolsIO.readParmsFile(data);
LapsToolsIO.readCornerPointsFile(data);
LapsToolsIO.readCountyWarningArea(data);
if(LapsToolsIO.readXmlFile(data)) {
LapsToolsIO.readCountyWarningArea(data);
} else {
data = null;
}
return data;
}
public static String getLocalizationQuestion() {
String date = new SimpleDateFormat("HH:mm").format(SimulatedTime
.getSystemTime().getTime());
return String
.format("Are you sure you want to localize? \n- The procedure takes five minutes. Consider that it is %s and LAPS runs at 20 after the hour. \n\n- Localization runs remotely on %s. The LAPS Tools will be unavailable until the relocalization is complete, which will be noted in the AlertViz window.",
date, serverName);
public static boolean readXmlFile(LapsToolsData data)
throws IOException, VizException {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext lc = pm.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.SITE);
LocalizationFile xmlLocalizationFile = pm.getLocalizationFile(lc, "LAPS/domain" +
".xml");
if(!xmlLocalizationFile.exists()) return false;
LapsDomain domain = new LapsDomain();
try {
JAXBContext jaxbContext = JAXBContext.newInstance(LapsDomain.class);
//unmarshal XML file to java object
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
domain = (LapsDomain) jaxbUnmarshaller.unmarshal(xmlLocalizationFile.getFile());
} catch (JAXBException e) {
throw new VizException("xml is unreadable: "+e.getLocalizedMessage());
}
data.setNx(domain.getNx());
data.setNy(domain.getNy());
data.setNz(domain.getNz());
data.setGridSpacing(domain.getGridSpacing());
data.setGridCenterLon(domain.getGridCenLon());
data.setGridCenterLat(domain.getGridCenLat());
return true;
}
public static void localize(LapsToolsData data) throws IOException,
InterruptedException {
if (!lockFile.getParentFile().exists()) {
lockFile.getParentFile().mkdir();
}
if (!lockFile.exists()) {
lockFile.createNewFile();
}
if (!nest7grid_template.getParentFile().exists()) {
nest7grid_template.getParentFile().mkdir();
}
Writer writer = new FileWriter(nest7grid_template);
writer.write(" &lapsparms_nl\n");
writer.write(String.format(" GRID_CEN_LAT_CMN=%s,\n",
data.getGridCenter().y));
writer.write(String.format(" GRID_CEN_LON_CMN=%s,\n",
data.getGridCenter().x));
writer.write(String.format(" NX_L_CMN=%s,\n", data.getNx()));
writer.write(String.format(" NY_L_CMN=%s,\n", data.getNy()));
writer.write(String.format(" NK_LAPS=%s,\n", data.getNz()));
writer.write("/\n");
writer.close();
String centerPoints = data.getGridCenter().y + " "
+ data.getGridCenter().x;
String dir = lapsRoot.getAbsolutePath();
String templateDir = nest7grid_template.getParent();
String msg = "LAPS localization is finished.";
// execute the command in a shell to achieve proper IO redirection to
// laps_ui.log
Process p = null;
try {
p = Runtime.getRuntime().exec("/bin/sh");
writer = new OutputStreamWriter(p.getOutputStream());
writer.write(execCmd);
writer.write(" \"");
writer.write(String
.format(CHANGE_CENTER_CMD_FMT, dir, centerPoints));
writer.write("; ");
writer.write(String.format(WINDOW_DOMAIN_CMD_FMT, dir, dir, dir,
templateDir));
writer.write("; ");
writer.write(String.format(RELOCALIZE_CMD_FMT, dir));
writer.write("; ");
writer.write(String.format(FINALIZE_CMD_FMT, msg, lockFile));
writer.write("\"");
writer.write(" >& /tmp/laps_ui.log &");
writer.write("\n");
writer.close();
// Don't wait for the process to finish.
final Process process = p;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
process.waitFor();
} catch (InterruptedException e) {
// Ignore
} finally {
process.destroy();
}
}
});
// Let the Thread do the destroy when process is finished.
p = null;
t.start();
} finally {
if (p != null) {
p.destroy();
}
}
}
public static void readParmsFile(LapsToolsData data) throws IOException,
VizException {
loadFileParms(nest7grid, data);
}
public static void readDefaultParmsFile(LapsToolsData data)
public static void defaultDomain(LapsToolsData data)
throws IOException, VizException {
if (!nest7grid_orig.isFile()) {
loadFileParms(nest7grid_orig, data);
}
loadFileParms(nest7grid_orig, data);
}
double distance = 111; //111 km per 1 degree
double gridSpacingDefault = 3500.;
double dim = 200;
double N = dim * dim;
Envelope shapeArea = data.getValidAreaOrig();
double widthY = Math.abs(shapeArea.getHeight() * distance);
double widthX = Math.abs( (shapeArea.getWidth() * distance) * (Math.cos(shapeArea.centre().x) ) );
double aspectRatio = widthY / widthX;
double buffer = 0.5;
int nX = (int) (Math.sqrt(N/aspectRatio) + buffer);
int nY = (int) ((aspectRatio * nX) + buffer);
System.out.print("LAPS Tools IO:\nheight = "+shapeArea.getHeight()+ " width = "+shapeArea.getWidth());
System.out.print("\naspect ratio = "+aspectRatio);
System.out.print("\nnX = "+nX+", nY = "+nY+"\n");
private static void loadFileParms(File file, LapsToolsData data)
throws VizException, IOException {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
throw new VizException(String.format(
"LAPS Tools GUI cannot run. %s does not exist.",
file.getAbsolutePath()), e);
}
int index = 0;
for (String line = reader.readLine(); line != null; line = reader
.readLine()) {
index += 1;
if (index == 1 || line.length() < 3 || line.startsWith("c")
|| line.startsWith(" &")) {
// Ignore comments, short lines and the first line, because
// Awips1 does
} else {
line = line.trim();
line = line.replaceAll(",$", "");
String[] halves = line.split("=");
String var = halves[0].toLowerCase().trim();
if (var.equals("grid_cen_lon_cmn")) {
data.setGridCenterLon(Double.valueOf(halves[1].trim()));
} else if (var.equals("grid_cen_lat_cmn")) {
data.setGridCenterLat(Double.valueOf(halves[1].trim()));
} else if (var.equals("grid_spacing_m_cmn")) {
data.setGridSpacing(Double.valueOf(halves[1].trim()));
} else if (var.equals("nx_l_cmn")) {
data.setNx(Integer.valueOf(halves[1].trim()));
} else if (var.equals("ny_l_cmn")) {
data.setNy(Integer.valueOf(halves[1].trim()));
} else if (var.equals("standard_latitude")) {
data.setLat(Double.valueOf(halves[1].trim()));
} else if (var.equals("standard_latitude2")) {
data.setLat2(Double.valueOf(halves[1].trim()));
} else if (var.equals("standard_longitude")) {
data.setLon(Double.valueOf(halves[1].trim()));
} else if (var.equals("nk_laps")) {
data.setNz(Integer.valueOf(halves[1].trim()));
} else if (var.equals("pressure_interval_l")) {
data.setDp(Double.valueOf(halves[1].trim()));
} else if (var.equals("pressure_bottom_l")) {
data.setLowp(Double.valueOf(halves[1].trim()));
}
}
}
}
private static void readCornerPointsFile(LapsToolsData data)
throws VizException, NumberFormatException, IOException {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(cornerPointFile));
} catch (FileNotFoundException e) {
throw new VizException(String.format(
"LAPS Tools GUI cannot run. %s does not exist.",
cornerPointFile.getAbsolutePath()), e);
}
Coordinate[] corners = new Coordinate[4];
int count = 0;
for (String line = reader.readLine(); line != null; line = reader
.readLine()) {
corners[count] = new Coordinate(Double.valueOf(line.trim().split(
" ", 2)[0].trim()), Double.valueOf(line.trim()
.split(" ", 2)[1].trim()));
count += 1;
}
data.setCorners(corners);
reader.close();
LapsDomain domain = new LapsDomain();
domain.setNx(nX);
domain.setNy(nY);
domain.setNz(43);
domain.setGridSpacing(gridSpacingDefault);
domain.setGridCenLon(data.getCwaCenter().x);
domain.setGridCenLat(data.getCwaCenter().y);
data.setNx(domain.getNx());
data.setNy(domain.getNy());
data.setNz(domain.getNz());
data.setGridSpacing(domain.getGridSpacing());
data.setGridCenterLon(data.getCwaCenter().x);
data.setGridCenterLat(data.getCwaCenter().y);
}
private static void readCountyWarningArea(LapsToolsData data)
@ -385,18 +209,31 @@ public class LapsToolsIO {
return;
}
data.setCwaArea(result[0].geometry.getEnvelopeInternal());
}
public static String getWriteXmlQuestion() {
String date = new SimpleDateFormat("HH:mm").format(SimulatedTime
.getSystemTime().getTime());
return String.format("Are you sure you want write domain.xml?" +
"\nNote: Its %s and LAPS runs at ~20 minutes after the hour.",date);
}
private static String readOutput(Process p) throws IOException,
InterruptedException {
StringBuilder output = new StringBuilder();
char[] buf = new char[10];
Reader reader = new InputStreamReader(p.getInputStream());
for (int count = 0; count != -1; count = reader.read(buf)) {
output.append(buf, 0, count);
}
reader.close();
return output.toString();
public static void writeXmlFile(LapsToolsData data) throws IOException,
InterruptedException, VizException {
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext lc = pm.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.SITE);
LocalizationFile xmlLocalizationFile = pm.getLocalizationFile(lc, "LAPS/domain-output" +
".xml");
LapsDomain lapsdomain = new LapsDomain();
lapsdomain.setNx(data.getNx());
lapsdomain.setNy(data.getNy());
lapsdomain.setNz(data.getNz());
lapsdomain.setGridSpacing(data.getGridSpacing());
lapsdomain.setGridCenLat(data.getGridCenter().y);
lapsdomain.setGridCenLon(data.getGridCenter().x);
//marshal java object to XML file
JAXB.marshal(lapsdomain, xmlLocalizationFile.getFile());
}
}

View file

@ -31,11 +31,14 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
@ -50,8 +53,6 @@ import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.uf.viz.core.rsc.tools.GenericToolsResourceData;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.awipstools.Activator;
import com.raytheon.viz.awipstools.ui.action.LapsToolsData;
import com.raytheon.viz.awipstools.ui.action.LapsToolsIO;
import com.raytheon.viz.awipstools.ui.layer.LapsToolLayer;
@ -68,7 +69,7 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
*
* Nov 2013 # mccaslin Improved layout, more user friendly, no system calls
*
* </pre>
*
@ -76,6 +77,7 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
* @version 1.0
*/
public class LAPSToolsDlg extends CaveSWTDialog {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(LAPSToolsDlg.class);
private final LapsToolsData data;
@ -85,6 +87,8 @@ public class LAPSToolsDlg extends CaveSWTDialog {
*/
private Composite mainComp;
public final String DIALOG_TITLE = "LAPS V2.0 Tools";
/**
* Label indicating which tool is selected.
*/
@ -93,14 +97,19 @@ public class LAPSToolsDlg extends CaveSWTDialog {
/**
* Current Analysis string.
*/
private final String dataUsedByAnalysis = "Data Used by Current Analysis";
private final String dataUsedByAnalysis = "What-got-in to the Current Analysis Product";
/**
* Configure Analysis string.
*/
private final String configureAnalysis = "Configure Analysis Domain";
private final String configureAnalysis = "View or Redefine Analysis Domain";
/**
* Flag indicating if LAPS 2.0 is installed.
*/
private boolean isLapsInstalled = false;
/**
* Flag indicating which tool is active.
*/
private boolean isDataUsedByAnalysis = true;
@ -130,19 +139,13 @@ public class LAPSToolsDlg extends CaveSWTDialog {
*/
private Font selectToolLabelFont;
/*
/**
* Spinner controls
*/
private Spinner cenLatSpnr;
private Spinner cenLonSpnr;
private Spinner latSpnr;
private Spinner lat2Spnr;
private Spinner lonSpnr;
private Spinner nxSpnr;
private Spinner nySpnr;
@ -151,31 +154,31 @@ public class LAPSToolsDlg extends CaveSWTDialog {
private Spinner nzSpnr;
private Spinner dpPaSpnr;
private Spinner lowPaSpnr;
/*
/**
* Settings buttons
*/
private Button defaultBtn;
private Button resetBtn;
/*
* LAPS Relocator buttons.
/**
* LAPS display domain buttons.
*/
private Button loadBtn;
private Button applyBtn;
private Button localizeLapsBtn;
private Button writeDomainBtn;
/**
* Stack layout.
*/
private StackLayout stackLayout;
private MessageBox areaDialog;
private Label areaStrLbl;
/**
* Constructor.
*
@ -185,18 +188,19 @@ public class LAPSToolsDlg extends CaveSWTDialog {
*/
public LAPSToolsDlg(Shell parent) throws VizException {
super(parent, SWT.DIALOG_TRIM);
setText(DIALOG_TITLE);
try {
LapsToolsIO.lockLaps();
String failover = LapsToolsIO.getFailover();
if (failover != null) {
MessageDialog.openInformation(shell,
"LAPS is running in failover.", failover);
}
this.data = LapsToolsIO.loadData();
if(data==null){
isLapsInstalled = false;
} else {
isLapsInstalled = true;
}
} catch (VizException e) {
MessageDialog
.openInformation(shell, "LAPS Tools GUI is not available.",
.openInformation(shell, "LAPS Tools GUI cannot run.",
e.getLocalizedMessage());
throw e;
} catch (Exception e) {
@ -226,7 +230,6 @@ public class LAPSToolsDlg extends CaveSWTDialog {
protected void initializeComponents(Shell shell) {
selectToolLabelFont = new Font(this.getDisplay(), "Sans", 10, SWT.BOLD
| SWT.ITALIC);
mainComp = new Composite(shell, SWT.NONE);
GridLayout gl = new GridLayout(1, true);
gl.marginHeight = 2;
@ -237,6 +240,11 @@ public class LAPSToolsDlg extends CaveSWTDialog {
createMenus();
createMainControls();
// create dialog with OK and cancel button and info icon
areaDialog =
new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
areaDialog.setText("Size of LAPS Domain");
}
/**
@ -344,18 +352,27 @@ public class LAPSToolsDlg extends CaveSWTDialog {
// Create the Help menu item with a Help "dropdown" menu
Menu helpMenu = new Menu(menuBar);
helpMenuItem.setMenu(helpMenu);
// create dialog with OK and cancel button and info icon
final MessageBox dialog =
new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
dialog.setText("About LAPS details");
dialog.setMessage("For additional detailed information about LAPS Tools go to the URL" +
"\n\t http://laps.noaa.gov/awipsii/");
// ------------------------------------------------------
// Create all the items in the Help dropdown menu
// ------------------------------------------------------
// Administration menu item
// Administration menu item
MenuItem aboutMI = new MenuItem(helpMenu, SWT.NONE);
aboutMI.setText("About...");
aboutMI.setText("About LAPS...");
aboutMI.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
dialog.open();
}
});
}
/**
@ -399,24 +416,36 @@ public class LAPSToolsDlg extends CaveSWTDialog {
true, false));
Composite controlComp = new Composite(currentAnalysisComp, SWT.NONE);
controlComp.setLayout(new GridLayout(3, false));
controlComp.setLayout(new GridLayout(4, false));
controlComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true,
false));
Label selectTypeLbl = new Label(controlComp, SWT.NONE);
selectTypeLbl.setText("Select Type: ");
selectTypeLbl.setText("What got into the: ");
Combo typeCbo = new Combo(controlComp, SWT.DROP_DOWN | SWT.READ_ONLY);
populateTypeCombo(typeCbo);
typeCbo.select(0);
typeCbo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Combo c = (Combo) e.widget;
typeAction((c.getItem(c.getSelectionIndex())));
if(c.getSelectionIndex() == 0 && c.getItem(0) == "-- Select a Type --") {
//no action
} else if(c.getSelectionIndex() != 0 && c.getItem(0) == "-- Select a Type --") {
c.remove(0);
typeAction((c.getItem(c.getSelectionIndex())));
} else {
typeAction((c.getItem(c.getSelectionIndex())));
}
}
});
typeCbo.select(0);
typeCbo.setToolTipText("Select one of the options to see what got into this LAPS product." );
Label blank = new Label(controlComp, SWT.NONE);
blank.setText(" ");
Button clearBtn = new Button(controlComp, SWT.PUSH);
clearBtn.setText(" Clear ");
clearBtn.addSelectionListener(new SelectionAdapter() {
@ -425,12 +454,13 @@ public class LAPSToolsDlg extends CaveSWTDialog {
clearAction();
}
});
clearBtn.setToolTipText("Clear screen.");
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
gd.widthHint = 500;
gd.heightHint = 300;
stText = new StyledText(currentAnalysisComp, SWT.BORDER | SWT.MULTI
| SWT.V_SCROLL | SWT.H_SCROLL);
| SWT.V_SCROLL | SWT.H_SCROLL | SWT.Deactivate);
stText.setLayoutData(gd);
}
@ -448,21 +478,25 @@ public class LAPSToolsDlg extends CaveSWTDialog {
createProjectionGroup();
createGridGroup();
createAreaGroup();
createSettingsLapsGroups();
populateSpinners();
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = 180;
gd.verticalIndent = 15;
localizeLapsBtn = new Button(configureAnalysisComp, SWT.PUSH);
localizeLapsBtn.setText("Localize LAPS");
localizeLapsBtn.setLayoutData(gd);
localizeLapsBtn.addSelectionListener(new SelectionAdapter() {
writeDomainBtn = new Button(configureAnalysisComp, SWT.PUSH);
writeDomainBtn.setText("Write file");
writeDomainBtn.setLayoutData(gd);
writeDomainBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
localizeLapsAction();
writeXmlfileAction();
}
});
writeDomainBtn.setToolTipText("Write LAPS domain.xml file AND Exit.\n" +
"This step will cause scripts to run that redefine the LAPS domain.\n" +
"Next cycle of the analysis will show the change in domain made here." );
}
/**
@ -480,7 +514,7 @@ public class LAPSToolsDlg extends CaveSWTDialog {
*/
gd = new GridData(120, SWT.DEFAULT);
Label projectionStrLbl = new Label(projectionGroup, SWT.CENTER);
projectionStrLbl.setText("PolarStr");
projectionStrLbl.setText("Polar Stereographic");
projectionStrLbl.setLayoutData(gd);
/*
@ -533,62 +567,6 @@ public class LAPSToolsDlg extends CaveSWTDialog {
cenLonSpnr.setIncrement(1000);
cenLonSpnr.setLayoutData(gd);
// 3 Filler Label
new Label(projectionGroup, SWT.NONE);
new Label(projectionGroup, SWT.NONE);
new Label(projectionGroup, SWT.NONE);
/*
* Lat
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
Label latLbl = new Label(projectionGroup, SWT.NONE);
latLbl.setText("Lat: ");
latLbl.setLayoutData(gd);
gd = new GridData(50, SWT.DEFAULT);
latSpnr = new Spinner(projectionGroup, SWT.BORDER);
latSpnr.setDigits(4);
latSpnr.setMinimum(-900000);
latSpnr.setMaximum(900000);
latSpnr.setIncrement(1000);
latSpnr.setEnabled(false);
latSpnr.setLayoutData(gd);
/*
* Lat2
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
Label lat2Lbl = new Label(projectionGroup, SWT.NONE);
lat2Lbl.setText("Lat2: ");
lat2Lbl.setLayoutData(gd);
gd = new GridData(50, SWT.DEFAULT);
lat2Spnr = new Spinner(projectionGroup, SWT.BORDER);
lat2Spnr.setDigits(4);
lat2Spnr.setMinimum(-900000);
lat2Spnr.setMaximum(900000);
lat2Spnr.setIncrement(1000);
lat2Spnr.setEnabled(false);
lat2Spnr.setLayoutData(gd);
/*
* Lon
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
gd.widthHint = 60;
Label lonLbl = new Label(projectionGroup, SWT.RIGHT);
lonLbl.setText("Lon: ");
lonLbl.setLayoutData(gd);
gd = new GridData(50, SWT.DEFAULT);
lonSpnr = new Spinner(projectionGroup, SWT.BORDER);
lonSpnr.setDigits(4);
lonSpnr.setMinimum(-1800000);
lonSpnr.setMaximum(1800000);
lonSpnr.setIncrement(1000);
lonSpnr.setEnabled(false);
lonSpnr.setLayoutData(gd);
}
/**
@ -622,12 +600,42 @@ public class LAPSToolsDlg extends CaveSWTDialog {
gd = new GridData(50, SWT.DEFAULT);
nxSpnr = new Spinner(gridGroup, SWT.BORDER);
nxSpnr.setDigits(0);
nxSpnr.setMinimum(1);
nxSpnr.setMaximum(100);
nxSpnr.setMinimum(61);
nxSpnr.setMaximum(301);
nxSpnr.setIncrement(1);
nxSpnr.setEnabled(false);
nxSpnr.setEnabled(true);
nxSpnr.setLayoutData(gd);
nxSpnr.addListener(SWT.Verify, new Listener() {
@Override
public void handleEvent(Event event) {
data.setNx(nxSpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
});
/*nxSpnr.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
data.setNx(nxSpnr.getSelection());
//areaStrLbl.setText(data.getAreaCoverageString());
}
@Override
public void focusLost(FocusEvent e) {
data.setNx(nxSpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
});
nxSpnr.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
data.setNx(nxSpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
*/
/*
* Ny
*/
@ -641,16 +649,34 @@ public class LAPSToolsDlg extends CaveSWTDialog {
gd = new GridData(50, SWT.DEFAULT);
nySpnr = new Spinner(gridGroup, SWT.BORDER);
nySpnr.setDigits(0);
nySpnr.setMinimum(1);
nySpnr.setMaximum(100);
nySpnr.setMinimum(61);
nySpnr.setMaximum(301);
nySpnr.setIncrement(1);
nySpnr.setEnabled(false);
nySpnr.setEnabled(true);
nySpnr.setLayoutData(gd);
nySpnr.addListener(SWT.Verify, new Listener() {
@Override
public void handleEvent(Event event) {
data.setNy(nySpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
});
/*nySpnr.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
data.setNy(nySpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
*/
/*
* Dx(m)
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
gd.horizontalIndent = 5;
gd.widthHint = 60;
Label dxmLbl = new Label(gridGroup, SWT.RIGHT);
dxmLbl.setText("Dx(m): ");
@ -659,12 +685,29 @@ public class LAPSToolsDlg extends CaveSWTDialog {
gd = new GridData(50, SWT.DEFAULT);
dxmSpnr = new Spinner(gridGroup, SWT.BORDER);
dxmSpnr.setDigits(0);
dxmSpnr.setMinimum(1000);
dxmSpnr.setMaximum(100000);
dxmSpnr.setIncrement(1000);
dxmSpnr.setEnabled(false);
dxmSpnr.setMaximum(12500);
dxmSpnr.setIncrement(500);
dxmSpnr.setEnabled(true);
dxmSpnr.setLayoutData(gd);
dxmSpnr.setMinimum(1000);
dxmSpnr.addListener(SWT.Verify, new Listener() {
@Override
public void handleEvent(Event event) {
data.setGridSpacing((double) dxmSpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
});
/*dxmSpnr.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
data.setGridSpacing((double) dxmSpnr.getSelection());
areaStrLbl.setText(data.getAreaCoverageString());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
*/
/*
* Vertical label
*/
@ -690,39 +733,28 @@ public class LAPSToolsDlg extends CaveSWTDialog {
nzSpnr.setEnabled(false);
nzSpnr.setLayoutData(gd);
/*
* Dp(Pa)
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
Label dppaLbl = new Label(gridGroup, SWT.NONE);
dppaLbl.setText("Dp(Pa): ");
dppaLbl.setLayoutData(gd);
}
gd = new GridData(50, SWT.DEFAULT);
dpPaSpnr = new Spinner(gridGroup, SWT.BORDER);
dpPaSpnr.setDigits(0);
dpPaSpnr.setMinimum(0);
dpPaSpnr.setMaximum(200);
dpPaSpnr.setIncrement(10);
dpPaSpnr.setEnabled(false);
dpPaSpnr.setLayoutData(gd);
/**
* Create the area group.
*/
private void createAreaGroup() {
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Group gridGroup = new Group(configureAnalysisComp, SWT.NONE);
gridGroup.setLayout(new GridLayout(1, false));
gridGroup.setLayoutData(gd);
gridGroup.setText(" Area of Coverage ");
/*
* Low(Pa)
* Calculated Area label
*/
gd = new GridData(SWT.RIGHT, SWT.CENTER, false, true);
Label lowPaLbl = new Label(gridGroup, SWT.RIGHT);
lowPaLbl.setText("Low(Pa): ");
lowPaLbl.setLayoutData(gd);
gd = new GridData(50, SWT.DEFAULT);
lowPaSpnr = new Spinner(gridGroup, SWT.BORDER);
lowPaSpnr.setDigits(0);
lowPaSpnr.setMinimum(0);
lowPaSpnr.setMaximum(1050);
lowPaSpnr.setIncrement(10);
lowPaSpnr.setEnabled(false);
lowPaSpnr.setLayoutData(gd);
gd = new GridData(500, SWT.DEFAULT);
gd.widthHint = 500;
gd.horizontalIndent = 25;
areaStrLbl = new Label(gridGroup, SWT.HORIZONTAL);
areaStrLbl.setLayoutData(gd);
areaStrLbl.setText(data.getAreaCoverageString());
}
/**
@ -736,8 +768,7 @@ public class LAPSToolsDlg extends CaveSWTDialog {
Composite groupComp = new Composite(configureAnalysisComp, SWT.NONE);
groupComp.setLayout(gl);
groupComp
.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
groupComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
/*
* Settings
@ -759,6 +790,8 @@ public class LAPSToolsDlg extends CaveSWTDialog {
setDefaultDomain();
}
});
//defaultBtn.setToolTipText("Set to the default");
defaultBtn.setToolTipText("Reset all variables to values so that the LAPS domain will fully include the CWA area");
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
@ -769,10 +802,10 @@ public class LAPSToolsDlg extends CaveSWTDialog {
@Override
public void widgetSelected(SelectionEvent e) {
resetDomain();
}
});
resetBtn.setToolTipText("Set to the values that you started with" );
/*
* LAPS Relocator
*/
@ -780,12 +813,12 @@ public class LAPSToolsDlg extends CaveSWTDialog {
Group lapsRelocatorGroup = new Group(groupComp, SWT.NONE);
lapsRelocatorGroup.setLayout(new GridLayout(2, true));
lapsRelocatorGroup.setLayoutData(gd);
lapsRelocatorGroup.setText(" LAPS Relocator ");
lapsRelocatorGroup.setText(" LAPS Domain Viewer and Relocator ");
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
loadBtn = new Button(lapsRelocatorGroup, SWT.PUSH);
loadBtn.setText("Load");
loadBtn.setText("Load in display");
loadBtn.setLayoutData(gd);
loadBtn.addSelectionListener(new SelectionAdapter() {
@Override
@ -793,11 +826,13 @@ public class LAPSToolsDlg extends CaveSWTDialog {
loadAction();
}
});
loadBtn.setToolTipText("Load the grid info into the display." +
"\nRelocate the domain by selecting and moving the grid center.");
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
gd.widthHint = buttonWidth;
applyBtn = new Button(lapsRelocatorGroup, SWT.PUSH);
applyBtn.setText("Apply");
applyBtn.setText("Apply changes");
applyBtn.setLayoutData(gd);
applyBtn.setEnabled(false);
applyBtn.addSelectionListener(new SelectionAdapter() {
@ -806,6 +841,8 @@ public class LAPSToolsDlg extends CaveSWTDialog {
applyAction();
}
});
applyBtn.setToolTipText("Fill the selectors with new values, if you" +
"\nmoved the domain by relocating the center point." );
}
/**
@ -842,16 +879,18 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
private void populateTypeCombo(Combo combo) {
for (String choice : LapsToolsIO.getDataChoices()) {
combo.add("-- Select a Type --");
for (String choice : LapsToolsIO.getDataChoices()) {
combo.add(choice);
}
}
private void typeAction(String type) {
try {
stText.append("Begin "+type+"\n");
stText.append(LapsToolsIO.getLogs(type));
stText.append("\n");
stText.append("__________________________________________\n");
stText.append("End of "+type);
stText.append("\n__________________________________________\n\n");
stText.setTopIndex(stText.getLineCount());
} catch (Exception ex) {
statusHandler.handle(Priority.PROBLEM,
@ -860,25 +899,23 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
private void populateSpinners() {
configureSpinner(latSpnr, data.getGridCenter().y);
configureSpinner(lat2Spnr, data.getLat2());
configureSpinner(lonSpnr, data.getLon());
configureSpinner(cenLatSpnr, data.getGridCenter().y, data
.getValidArea().getMinY(), data.getValidArea().getMaxY());
configureSpinner(cenLonSpnr, data.getGridCenter().x, data
.getValidArea().getMinX(), data.getValidArea().getMaxX());
configureSpinner(cenLatSpnr, data.getGridCenter().y,
data.getValidArea().getMinY(), data.getValidArea().getMaxY());
configureSpinner(cenLonSpnr, data.getGridCenter().x,
data.getValidArea().getMinX(), data.getValidArea().getMaxX());
configureSpinner(nxSpnr, data.getNx());
configureSpinner(nySpnr, data.getNy());
configureSpinner(dxmSpnr, data.getGridSpacing());
configureSpinner(nzSpnr, data.getNz());
configureSpinner(dpPaSpnr, data.getDp());
configureSpinner(lowPaSpnr, data.getLowp());
}
private void readSpinners() {
public void readSpinners() {
data.setGridCenterLat(readSpinner(cenLatSpnr));
data.setLat(readSpinner(cenLatSpnr));
data.setGridCenterLon(readSpinner(cenLonSpnr));
data.setNx(nxSpnr.getSelection());
data.setNy(nySpnr.getSelection());
data.setGridSpacing(readSpinner(dxmSpnr));
}
private Double readSpinner(Spinner spinner) {
@ -909,10 +946,10 @@ public class LAPSToolsDlg extends CaveSWTDialog {
private void setDefaultDomain() {
boolean ok = MessageDialog
.openConfirm(getShell(), "Confirm Exit",
"This will reset all variables to the default WFO localization values.");
"This will reset all variables to values so that the LAPS domain will fully includes the CWA area.");
if (ok) {
try {
LapsToolsIO.readDefaultParmsFile(data);
LapsToolsIO.defaultDomain(data);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
@ -925,10 +962,10 @@ public class LAPSToolsDlg extends CaveSWTDialog {
private void resetDomain() {
boolean ok = MessageDialog
.openConfirm(getShell(), "Confirm Exit",
"This will reset all variables to the existing localization values.");
"This will reset all variables to values of the existing LAPS domain.");
if (ok) {
try {
LapsToolsIO.readParmsFile(data);
LapsToolsIO.readXmlFile(data);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
@ -938,13 +975,26 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
private void applyAction() {
if(data.getLimits()) {
System.out.print("LAPS Tools Dlg: problem with domain not covering CWA");
boolean yes = MessageDialog
.openQuestion(getShell(), "Domain Size Error",
"The size of the LAPS domain does not cover the entire CWA." +
"\nWould you like to move and recenter domain?" +
"\n\n(Answering 'No' will allow you to reedit text values, instead.)");
if(yes){ return; }
}
cenLatSpnr.setEnabled(true);
cenLonSpnr.setEnabled(true);
nxSpnr.setEnabled(true);
nySpnr.setEnabled(true);
dxmSpnr.setEnabled(true);
applyBtn.setEnabled(false);
loadBtn.setEnabled(true);
resetBtn.setEnabled(true);
defaultBtn.setEnabled(true);
localizeLapsBtn.setEnabled(true);
writeDomainBtn.setEnabled(true);
populateSpinners();
IDisplayPaneContainer container = EditorUtil.getActiveVizContainer();
@ -961,15 +1011,19 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
}
private void loadAction() {
private void loadAction() {
cenLatSpnr.setEnabled(false);
cenLonSpnr.setEnabled(false);
nxSpnr.setEnabled(false);
nySpnr.setEnabled(false);
dxmSpnr.setEnabled(false);
applyBtn.setEnabled(true);
loadBtn.setEnabled(false);
resetBtn.setEnabled(false);
defaultBtn.setEnabled(false);
localizeLapsBtn.setEnabled(false);
writeDomainBtn.setEnabled(false);
readSpinners();
GenericToolsResourceData<LapsToolLayer> rd = new GenericToolsResourceData<LapsToolLayer>(
LapsToolLayer.DEFAULT_NAME, LapsToolLayer.class);
@ -999,13 +1053,13 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
}
private void localizeLapsAction() {
private void writeXmlfileAction() {
if (MessageDialog.openQuestion(getShell(), "Confirmation",
LapsToolsIO.getLocalizationQuestion())) {
LapsToolsIO.getWriteXmlQuestion())) {
try {
LapsToolsIO.localize(data);
statusHandler.handle(Priority.SIGNIFICANT,
"Initiated LAPS Localization");
LapsToolsIO.writeXmlFile(data);
statusHandler.handle(Priority.INFO, //SIGNIFICANT
"Write EDEX domain.xml file. This action will initiated a LAPS Localization process.");
close();
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
@ -1013,4 +1067,9 @@ public class LAPSToolsDlg extends CaveSWTDialog {
}
}
}
public boolean isLapsInstalled() {
return isLapsInstalled;
}
}

View file

@ -25,12 +25,16 @@ import java.util.Arrays;
import org.eclipse.jface.action.IMenuManager;
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.DrawableString;
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
//import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment;
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
//import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle;
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
@ -56,6 +60,8 @@ import com.vividsolutions.jts.geom.Envelope;
* bsteffen Intial creation.
* 07-21-14 #3412 mapeters Updated deprecated drawCircle call.
* 07-29-14 #3465 mapeters Updated deprecated drawString() calls.
* Nov 2013 # mccaslin Draw more graphical boxes: for CWA, previous domain, etc
* </pre>
*
* @author bsteffen
@ -72,10 +78,16 @@ public class LapsToolLayer extends AbstractMovableToolLayer<Coordinate>
private final AbstractRightClickAction moveElementAction;
private IWireframeShape validShapeOrig;
private IWireframeShape validShape;
private IWireframeShape gridShape;
private RGB labelColor;
public static String centerLabel = "Center Point";
public LapsToolLayer(GenericToolsResourceData<LapsToolLayer> resourceData,
LoadProperties loadProperties) {
super(resourceData, loadProperties, false);
@ -129,31 +141,74 @@ public class LapsToolLayer extends AbstractMovableToolLayer<Coordinate>
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
super.paintInternal(target, paintProps);
Envelope shapeArea = data.getValidArea();
if (validShape == null) {
validShape = target.createWireframeShape(false, descriptor);
Coordinate[] coords = new Coordinate[5];
Envelope area = data.getValidArea();
coords[0] = new Coordinate(area.getMinX(), area.getMinY());
coords[1] = new Coordinate(area.getMinX(), area.getMaxY());
coords[2] = new Coordinate(area.getMaxX(), area.getMaxY());
coords[3] = new Coordinate(area.getMaxX(), area.getMinY());
coords[0] = new Coordinate(shapeArea.getMinX(), shapeArea.getMinY());
coords[1] = new Coordinate(shapeArea.getMinX(), shapeArea.getMaxY());
coords[2] = new Coordinate(shapeArea.getMaxX(), shapeArea.getMaxY());
coords[3] = new Coordinate(shapeArea.getMaxX(), shapeArea.getMinY());
coords[4] = coords[0];
validShape.addLineSegment(coords);
}
Envelope shapeArea2 = data.getValidAreaOrig();
if (validShapeOrig == null) {
validShapeOrig = target.createWireframeShape(false, descriptor);
Coordinate[] coords = new Coordinate[5];
coords[0] = new Coordinate(shapeArea2.getMinX(), shapeArea2.getMinY());
coords[1] = new Coordinate(shapeArea2.getMinX(), shapeArea2.getMaxY());
coords[2] = new Coordinate(shapeArea2.getMaxX(), shapeArea2.getMaxY());
coords[3] = new Coordinate(shapeArea2.getMaxX(), shapeArea2.getMinY());
coords[4] = coords[0];
validShapeOrig.addLineSegment(coords);
}
Envelope gridArea = data.getGridArea();
if (gridShape == null) {
gridShape = target.createWireframeShape(false, descriptor);
Coordinate[] coords = new Coordinate[5];
Envelope area = data.getGridArea();
coords[0] = new Coordinate(area.getMinX(), area.getMinY());
coords[1] = new Coordinate(area.getMinX(), area.getMaxY());
coords[2] = new Coordinate(area.getMaxX(), area.getMaxY());
coords[3] = new Coordinate(area.getMaxX(), area.getMinY());
coords[0] = new Coordinate(gridArea.getMinX(), gridArea.getMinY());
coords[1] = new Coordinate(gridArea.getMinX(), gridArea.getMaxY());
coords[2] = new Coordinate(gridArea.getMaxX(), gridArea.getMaxY());
coords[3] = new Coordinate(gridArea.getMaxX(), gridArea.getMinY());
coords[4] = coords[0];
gridShape.addLineSegment(coords);
}
//Test domain sizes
data.setLimits(false);
if (gridArea.getMinX() > shapeArea.getMinX()) {
data.setLimits(true);
} if (gridArea.getMaxX() < shapeArea.getMaxX()) {
data.setLimits(true);
} if (gridArea.getMinY() > shapeArea.getMinY()) {
data.setLimits(true);
} if (gridArea.getMaxY() < shapeArea.getMaxY()) {
data.setLimits(true);
}
RGB color = getCapability(ColorableCapability.class).getColor();
RGB color2 = color;
// Projected grid domain too small, below the limits of the CWA...
if (data.getLimits()) {
color2 = new RGB ( 250, 40, 40);
labelColor = color2;
centerLabel = "[Center point]\nFull CWA is NOT covered by domain";
} else {
labelColor = color;
centerLabel = "Center point";
}
target.drawWireframeShape(validShape, color, 1, LineStyle.DASHED_LARGE);
target.drawWireframeShape(gridShape, color, 1, LineStyle.SOLID);
target.drawWireframeShape(gridShape, color2, 1, LineStyle.SOLID);
RGB gray = new RGB ( 90, 90, 90);
target.drawWireframeShape(validShapeOrig, gray, 1, LineStyle.DASH_DOTTED);
}
@Override
@ -171,11 +226,15 @@ public class LapsToolLayer extends AbstractMovableToolLayer<Coordinate>
circle.radius = radius;
circle.basics.color = color;
target.drawCircle(circle);
//14.1.1 and earlier: target.drawCircle(center[0], center[1], 0, radius, color, 1);
double labelLoc[] = target.getPointOnCircle(center[0], center[1], 0.0,
radius, 0);
DrawableString string = new DrawableString("center point", color);
//DrawableString string = new DrawableString("center point", color);
DrawableString string = new DrawableString(centerLabel, labelColor);
string.setCoordinates(labelLoc[0], labelLoc[1]);
target.drawStrings(string);
//14.1.1 and earlier: target.drawString(null, centerLabel, labelLoc[0], labelLoc[1], 0.0,
// TextStyle.NORMAL, labelColor, HorizontalAlignment.LEFT, null);
}
@Override
@ -248,6 +307,10 @@ public class LapsToolLayer extends AbstractMovableToolLayer<Coordinate>
validShape.dispose();
validShape = null;
}
if (validShapeOrig != null) {
validShapeOrig.dispose();
validShapeOrig = null;
}
if (gridShape != null) {
gridShape.dispose();
gridShape = null;
@ -255,5 +318,54 @@ public class LapsToolLayer extends AbstractMovableToolLayer<Coordinate>
issueRefresh();
}
}
/*
@see
* com.raytheon.uf.viz.core.rsc.AbstractVizResource#project(org.opengis.
* referencing.crs.CoordinateReferenceSystem)
*/
public void project(CoordinateReferenceSystem crs) throws VizException {
if (validShape != null) {
validShape.dispose();
validShape = null;
}
if (validShapeOrig != null) {
validShapeOrig.dispose();
validShapeOrig = null;
}
if (gridShape != null) {
gridShape.dispose();
gridShape = null;
}
issueRefresh();
}
protected void drawUpperLeftCornerLabel(IGraphicsTarget target,
PaintProperties paintProps, String label) throws VizException {
// TODO this screen location code is borrowed from MPELegendResource...
// should it be put into a shared class, possibly a paint
// properties method?
IExtent screenExtent = paintProps.getView().getExtent();
double scale = (screenExtent.getHeight() / paintProps.getCanvasBounds().height);
DrawableString tmpDS = new DrawableString("0", new RGB(100, 100, 100));
tmpDS.font = null;
double textHeight = target.getStringsBounds(tmpDS).getHeight() * scale;
double padding = 3 * scale;
double textSpace = textHeight + padding;
double cmapHeight = textHeight * 1.25;
double legendHeight = cmapHeight + 2.0 * textSpace + 2.0 * padding;
double y1 = screenExtent.getMinY() + legendHeight * 2.5;
double x1 = screenExtent.getMinX() + padding * 10.0;
DrawableString string = new DrawableString(label, this.getCapability(
ColorableCapability.class).getColor());
string.basics.x = x1;
string.basics.y = y1;
string.font = null;
//string.textStyle = IGraphicsTarget.TextStyle.NORMAL;
//string.horizontalAlignment = HorizontalAlignment.LEFT;
target.drawStrings(string);
}
}