From 0b569fcba85dda2b21149bbc1e2dce24950716ad Mon Sep 17 00:00:00 2001 From: Paula McCaslin Date: Wed, 12 Nov 2014 13:58:24 -0700 Subject: [PATCH] VLab Issue #5061. LAPS Tools; fixes #5061 Change-Id: I447e7e94b931ad2efad687efa90e16cebb2e7bf9 Former-commit-id: 1375bc38f3c5592ef12446991e2eeefd354f7ba1 [formerly e2e8faf273666e74eaffd8e4c3b61e7020f1cee3] [formerly a5c805cf4d1f6dcafea8ac3b52ce9c1dc3596887 [formerly e05f01c705953d0c9528cfea6604f88455a5f5ac]] Former-commit-id: a5c805cf4d1f6dcafea8ac3b52ce9c1dc3596887 Former-commit-id: 1038498ced97ecd385312b4c5fdba080722116b2 --- .../awipstools/ui/action/LapsToolsAction.java | 65 ++- .../awipstools/ui/action/LapsToolsData.java | 191 +++++-- .../viz/awipstools/ui/action/LapsToolsIO.java | 475 ++++++------------ .../awipstools/ui/dialog/LAPSToolsDlg.java | 407 ++++++++------- .../awipstools/ui/layer/LapsToolLayer.java | 136 ++++- 5 files changed, 712 insertions(+), 562 deletions(-) diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsAction.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsAction.java index b0e42fb41f..d2d1b68db1 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsAction.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsAction.java @@ -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 * * * @@ -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; } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsData.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsData.java index d17bbaef5e..0e679eee19 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsData.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsData.java @@ -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 tags and 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; + } + } } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsIO.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsIO.java index 8ce724e831..a892d530d9 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsIO.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/LapsToolsIO.java @@ -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. * *
  * 
  * 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
  * 
  * 
* @@ -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 whatgotinFiles; + private static List dataChoices; - - private static List 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 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()); } - } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/dialog/LAPSToolsDlg.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/dialog/LAPSToolsDlg.java index 6347d2ed5b..495e2c668c 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/dialog/LAPSToolsDlg.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/dialog/LAPSToolsDlg.java @@ -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 * * * @@ -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 rd = new GenericToolsResourceData( 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; + } + } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/LapsToolLayer.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/LapsToolLayer.java index 2519b35db1..38f103d076 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/LapsToolLayer.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/LapsToolLayer.java @@ -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 + * * * @author bsteffen @@ -72,10 +78,16 @@ public class LapsToolLayer extends AbstractMovableToolLayer 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 resourceData, LoadProperties loadProperties) { super(resourceData, loadProperties, false); @@ -129,31 +141,74 @@ public class LapsToolLayer extends AbstractMovableToolLayer 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 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 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 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); + } + }