diff --git a/cave/com.raytheon.viz.aviation/config.xml b/cave/com.raytheon.viz.aviation/config.xml index 4599a2c9c8..ca28235848 100644 --- a/cave/com.raytheon.viz.aviation/config.xml +++ b/cave/com.raytheon.viz.aviation/config.xml @@ -2,19 +2,19 @@ @@ -59,6 +59,7 @@ disabled disabled None + 10 true error latest diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java index 8d3edda713..a1c016edcc 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java @@ -247,6 +247,7 @@ import com.raytheon.viz.ui.simulatedtime.SimulatedTimeOperations; * Sep 28, 2015 4898 rferrel Disable sending of TAF when CAVE not in real time. * Oct 05, 2015 4855 skorolev Fixed an unhandled event loop exception in createErrorStyleRange. * Oct 16, 2015 4645 skorolev Added updateWordWrap. + * 10/23/2015 18061 zhao Fixed a bug in checkBaiscSyntaxError() * * * @@ -2035,7 +2036,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, tafStartIndex += taf.length() + 2; } - if (doLogMessage) { + if (doLogMessage && errorFound) { msgStatComp.setMessageText(msg, qcColors[3].getRGB()); } diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/NotifyAudioManager.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/NotifyAudioManager.java index c2324f0afb..b9eb23036b 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/NotifyAudioManager.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/monitor/NotifyAudioManager.java @@ -24,6 +24,9 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import com.raytheon.viz.aviation.resource.ResourceConfigMgr; +import com.raytheon.viz.aviation.resource.ResourceConfigMgr.ResourceTag; + import sun.audio.AudioData; import sun.audio.AudioDataStream; import sun.audio.AudioPlayer; @@ -35,9 +38,10 @@ import sun.audio.AudioStream; *
  * 
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
+ * Date         Ticket#   Engineer    Description
+ * ------------ --------- ----------- --------------------------
  * Dec 2, 2009            avarani     Initial creation
+ * Oct 20,2015  17445     yteng       Set alert interval
  * 
  * 
* @@ -46,6 +50,9 @@ import sun.audio.AudioStream; */ public class NotifyAudioManager { + + private static long lastAlertTime = 0; + private static NotifyAudioManager nam; private String filename; @@ -69,15 +76,27 @@ public class NotifyAudioManager { } public void playFile(String filename) throws IOException { - if (!filename.equals(this.filename)) { - File soundFile = new File(filename); - InputStream in = new FileInputStream(soundFile); - AudioStream as = new AudioStream(in); - AudioData data = as.getData(); - ads = new AudioDataStream(data); - } - AudioPlayer.player.stop(ads); - AudioPlayer.player.start(ads); + ResourceConfigMgr configMgr = ResourceConfigMgr.getInstance(); + int alertIntervalMinutes = configMgr.getResourceAsInt(ResourceTag.AlertIntervalMinutes); + + long currentTime = System.currentTimeMillis(); + if (currentTime >= (lastAlertTime + alertIntervalMinutes*60*1000)) { + lastAlertTime = currentTime; + + if (!filename.equals(this.filename)) { + File soundFile = new File(filename); + InputStream in = new FileInputStream(soundFile); + AudioStream as = new AudioStream(in); + AudioData data = as.getData(); + ads = new AudioDataStream(data); + } + AudioPlayer.player.stop(ads); + AudioPlayer.player.start(ads); + } + } + + public static void resetAlertTime() { + lastAlertTime = 0; } } diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/observer/TafMonitorDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/observer/TafMonitorDlg.java index 2250ba1112..8ba4b8b8f9 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/observer/TafMonitorDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/observer/TafMonitorDlg.java @@ -70,6 +70,7 @@ import com.raytheon.viz.aviation.monitor.GfsMonitorObserver; import com.raytheon.viz.aviation.monitor.IGridDataRetrieveListener; import com.raytheon.viz.aviation.monitor.LtgMonitorObserver; import com.raytheon.viz.aviation.monitor.MetarMonitorObserver; +import com.raytheon.viz.aviation.monitor.NotifyAudioManager; import com.raytheon.viz.aviation.monitor.PythonMonitorJob; import com.raytheon.viz.aviation.monitor.RltgMonitorObserver; import com.raytheon.viz.aviation.monitor.ScheduledMonitorTask; @@ -95,11 +96,11 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; /** * TafMonitorDlg (Terminal Aerodome Forecast Monitor Dialog) class. - * + * *
- * 
+ *
  * SOFTWARE HISTORY
- * 
+ *
  * Date         Ticket#     Engineer    Description
  * ------------ ----------  ----------- --------------------------
  * 1/24/2008    817         grichard    Initial creation.
@@ -147,9 +148,10 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
  * 03/07/2013   1735        rferrel     Performance speed up for retrieving grid data.
  * 08/09/2013   2033        mschenke    Switched File.separator to IPathManager.SEPARATOR
  * Sep 15, 2015 4880        njensen     Removed reference to ForecastModel
- * 
+ * 10/20/2015   17445       yteng       Reset alert time for audio alert.
+ *
  * 
- * + * * @author grichard * @version 1.0 */ @@ -331,6 +333,7 @@ public class TafMonitorDlg extends CaveSWTDialog implements initializeData(); initializeComponents(); setupMonitoring(); + NotifyAudioManager.resetAlertTime(); shell.addShellListener(new ShellAdapter() { @Override diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceConfigMgr.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceConfigMgr.java index f9af3c9a2b..232806c858 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceConfigMgr.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceConfigMgr.java @@ -52,6 +52,7 @@ import com.raytheon.viz.aviation.activator.Activator; * methods and method to reset data values. * Dec 9, 2010 7380 rferrel Changed spinner values for text fields. * Dec 14, 2010 5782 rferrel Fixed numTafs combo string array. + * Oct 20, 2015 17445 yteng Add audio alert interval field. * * * @@ -90,7 +91,8 @@ public class ResourceConfigMgr implements IResourceAction { "alertLevel3"), AlertLevel4("alertLevel4"), AlertLevel5( "alertLevel5"), AlertLevel6("alertLevel6"), NotifyDeiconify( "notifyDeiconify"), NotifyRaise("notifyRaise"), NotifyPlay( - "notifyPlay"), PlayFile("playFile"), Blink("blink"), DisallowSend( + "notifyPlay"), PlayFile("playFile"), AlertIntervalMinutes( + "alertIntervalMinutes"), Blink("blink"), DisallowSend( "disallowSend"), LoadOrder("loadOrder"), AutoSave("autoSave"), UpdateTimes( "updateTimes"), AutoPrint("autoPrint"), Insert("insert"), Wrap( "wrap"), AmdButtons("amdbuttons"), NumTafs("numTafs"), NumHours( @@ -228,6 +230,8 @@ public class ResourceConfigMgr implements IResourceAction { ResourceType.COMBO, "Alert level to play file")); resourceTypeMap.put(ResourceTag.PlayFile, new ResourceInfo( ResourceType.FILE, "Sound to play on TAF alert")); + resourceTypeMap.put(ResourceTag.AlertIntervalMinutes, new ResourceInfo( + ResourceType.SPINNER, "TAF alert interval in minutes")); resourceTypeMap.put(ResourceTag.Blink, new ResourceInfo( ResourceType.CHECK, "Blink on new notification")); resourceTypeMap.put(ResourceTag.DisallowSend, new ResourceInfo( @@ -297,6 +301,9 @@ public class ResourceConfigMgr implements IResourceAction { final int htMin = 50; final int htMax = 1200; final int inc = 50; + final int aiMin = 1; + final int aiMax = 60; + final int aiInc = 1; if (resourceTag == ResourceTag.TextWidth) { return new SpinnerData(wdMin, wdMax, inc); @@ -312,6 +319,8 @@ public class ResourceConfigMgr implements IResourceAction { return new SpinnerData(wdMin, wdMax, inc); } else if (resourceTag == ResourceTag.TextViewerHeight) { return new SpinnerData(htMin, htMax, inc); + } else if (resourceTag == ResourceTag.AlertIntervalMinutes) { + return new SpinnerData(aiMin, aiMax, aiInc); } return new SpinnerData(0, 100, 10); diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceDataManager.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceDataManager.java index 22e291e24f..05c45ade6f 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceDataManager.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/resource/ResourceDataManager.java @@ -59,6 +59,7 @@ import com.raytheon.viz.aviation.resource.ResourceConfigMgr.ResourceTag; * 30 Aug 2013 #2164 bkowal Add default case statement for MSFT Windows * Java. Replaced platform-dependent code with * code that is not platform-dependent. + * Oct 20, 2015 17445 yteng Add audio alert interval. * * * @@ -526,6 +527,9 @@ public class ResourceDataManager { resourceMap.put(ResourceTag.NotifyPlay, notifyPlay); String playFile = resourceCB.getResourceAsString(ResourceTag.PlayFile); resourceMap.put(ResourceTag.PlayFile, playFile); + int alertIntervalMinutes = resourceCB + .getResourceAsInt(ResourceTag.TextEditorInsWidth); + resourceMap.put(ResourceTag.AlertIntervalMinutes, alertIntervalMinutes); boolean blink = resourceCB.getResourceAsBoolean(ResourceTag.Blink); resourceMap.put(ResourceTag.Blink, Boolean.valueOf(blink)); String disalowSend = resourceCB diff --git a/cave/com.raytheon.viz.avnconfig/localization/aviation/python/TafGen.py b/cave/com.raytheon.viz.avnconfig/localization/aviation/python/TafGen.py index 667c1a95b3..4f0968fb7f 100644 --- a/cave/com.raytheon.viz.avnconfig/localization/aviation/python/TafGen.py +++ b/cave/com.raytheon.viz.avnconfig/localization/aviation/python/TafGen.py @@ -31,6 +31,11 @@ # Change Document History: # %PIRC% # +# +# Date Ticket# Engineer Description +# ---------- ---------- ----------- -------------------------- +# 10/28/2015 15464 zhao Modified mkTempo & mkProb30 to handle case of "TS"+"SKC" +# import sys,os,copy,cPickle,math,ConfigParser,time,logging import AvnLib, AvnParser, Avn @@ -325,10 +330,11 @@ class LampProjection(Projection): visStr = self.vis['str'] if 'TS' in tmpStr: #make sure cig is below threshold - cig = int(skyStr[3:]) - if cig > self.grpTaf['cbhight']: - cig = self.grpTaf['cbhight'] - skyStr = "%s%03d%s" %('BKN',cig,'CB') + if skyStr != 'SKC': + cig = int(skyStr[3:]) + if cig > self.grpTaf['cbhight']: + cig = self.grpTaf['cbhight'] + skyStr = "%s%03d%s" %('BKN',cig,'CB') return {'wxStr':fixPcp(tmpStr),'visStr':visStr,\ 'skyStr':skyStr} @@ -360,10 +366,11 @@ class LampProjection(Projection): visStr = self.vis['str'] if 'TS' in tmpStr: #make sure cig is below threshold - cig = int(skyStr[3:]) - if cig > self.grpTaf['cbhight']: - cig = self.grpTaf['cbhight'] - skyStr = "%s%03d%s" %('BKN',cig,'CB') + if skyStr != 'SKC': + cig = int(skyStr[3:]) + if cig > self.grpTaf['cbhight']: + cig = self.grpTaf['cbhight'] + skyStr = "%s%03d%s" %('BKN',cig,'CB') return {'wxStr':fixPcp(tmpStr),'visStr':visStr,\ 'skyStr':skyStr} diff --git a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/smartTools/LimitValues.py b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/smartTools/LimitValues.py index 61397b9ebd..12ea1a82b2 100644 --- a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/smartTools/LimitValues.py +++ b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/smartTools/LimitValues.py @@ -99,7 +99,7 @@ class Tool (SmartScript.SmartScript): # you could get this from GridInfo, but you can't # resolution=1 - if (WEname=="QPF"): + if (WEname=="QPF" or WEname=="IceAccum"): resolution=0.01 if (WEname=="SnowAmt"): resolution=0.1 diff --git a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/textUtilities/headline/HazardsTable.py b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/textUtilities/headline/HazardsTable.py index d2f7d3a576..f7f56f9583 100644 --- a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/textUtilities/headline/HazardsTable.py +++ b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/textUtilities/headline/HazardsTable.py @@ -41,6 +41,7 @@ # 05/07/2015 4027 randerso Fixed error handling, # added NOTE about false postives for duplicate ETNs # 10/16/2015 17771 dgilling Remove __sitesIgnoreNatlEtn. +# 10/29/2015 17701 yteng Correct parm selection for Hazards to exclude Hazardsnc # @@ -1036,10 +1037,8 @@ class HazardsTable(VTECTableUtil.VTECTableUtil): # pid = filter(lambda x: str(x).find("Hazards") != -1, # self.__ifpClient.getParmList(self.__databaseID))[0] parmList = self.__ifpClient.getParmList(dbid) - size = parmList.size() - for x in range(size): - p = parmList.get(x) - if str(p).find("Hazards") != -1: + for p in parmList: + if p.getParmName() == "Hazards": pid = p break diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java index 2db3538bf6..dc1d33fb43 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductAreaComp.java @@ -75,6 +75,8 @@ import com.raytheon.viz.ui.simulatedtime.SimulatedTimeProhibitedOpException; * 24 AUG 2015 4749 dgilling Ensure TextProductFinishListener callbacks execute on UI thread, * override dispose to aid perspective shutdown. * 15 SEP 2015 4858 dgilling Handle exception from runFormatterScript. + * 03 NOV 2015 14813 ryu Fix missing VTEC code in generated product. VTEC mode is set + * based on the pil of the product rather than the disply name. * * * @@ -392,24 +394,11 @@ public class ProductAreaComp extends Composite implements if (formattingCbo.isVisible()) { vtecMode = formattingCbo.getText(); } else { - // TODO: part of fix for SS RM DR #14813 - // String pil = (String) textProductMgr - // .getDefinitionValue(productName, "pil"); - // if (pil != null) { - // pil = pil.substring(0, 3); - // vtecMode = textProductMgr - // .getVtecMessageType(pil); - // } - - int hazIndex = productName.indexOf("Hazard_"); - if (hazIndex > -1) { - String category = productName.substring( - hazIndex + 7, hazIndex + 10); - vtecMode = textProductMgr - .getVtecMessageType(category); - if (vtecMode == null) { - vtecMode = ""; - } + String pil = (String) textProductMgr + .getDefinitionValue(productName, "pil"); + if (pil != null) { + pil = pil.substring(0, 3); + vtecMode = textProductMgr.getVtecMessageType(pil); } } diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayCanvas.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayCanvas.java index db009a60c5..1fc1d5beaa 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayCanvas.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayCanvas.java @@ -140,7 +140,8 @@ import com.raytheon.viz.hydrocommon.util.DbUtils; * 06 May 2013 1976 mpduff Refactored Hydro time series data access. * 29 May 2013 2016 mpduff Fix TS Toggle Traces. * 05 Sep 2013 #2332 lvenable Fixed memory leaks. - * 24 Jan 2013 15959 lbousaidi Swap the corner points of the bounding box when zooming. + * 24 Jan 2013 15959 lbousaidi Swap the corner points of the bounding box when zooming. + * 22 Oct 2015 13736 xwei Fixed missing data after zoom, edit, & reset problem * @author lvenable * @version 1.0 * @@ -1135,26 +1136,42 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements td = gd.getTraceData(i); if (td != null && td.isTraceOn()) { TimeSeriesPoint[] points = null; + TimeSeriesPoint[] pointsZoomed = null; + if (zoomed) { - points = td.getZoomedTsData(); + points = td.getTsData(); + pointsZoomed = td.getZoomedTsData(); } else { points = td.getTsData(); } - if (points != null) { - List pointList = new ArrayList(); + if ( points != null) { + + List pointListZoomed = new ArrayList(); + List pointList = new ArrayList(); + /* Delete the specified point */ if ((deleteList.size() > 0) && (i == selectedTraceId)) { - for (int j = 0; j < points.length; j++) { + + for (int j = 0; j < points.length; j++) { if (!deleteList.contains(j)) { - pointList.add(points[j]); - } - + pointList.add(points[j]); + } } - td.setTsData(pointList - .toArray(new TimeSeriesPoint[pointList.size()])); + td.setTsData(pointList.toArray(new TimeSeriesPoint[pointList.size()])); + + if ( zoomed && pointsZoomed != null ) { + + for (int j = 0; j < pointsZoomed.length; j++) { + if (!deleteList.contains(j)) { + pointListZoomed.add(pointsZoomed[j]); + } + } + td.setZoomedTsData(pointListZoomed.toArray(new TimeSeriesPoint[pointListZoomed.size()])); + } + deleteIndex = HydroConstants.MISSING_VALUE; - deleteList.clear(); + deleteList.clear(); } /* Set missing */ @@ -1164,8 +1181,8 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements pointList.add(points[j]); } } - td.setTsData(pointList - .toArray(new TimeSeriesPoint[pointList.size()])); + td.setTsData(pointList.toArray(new TimeSeriesPoint[pointList.size()])); + setMissingIndex = HydroConstants.MISSING_VALUE; setMissingList.clear(); } @@ -1202,9 +1219,15 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements .toArray(new TimeSeriesPoint[pointList.size()])); insertedPoint = null; } - if (!zoomed) { - TimeSeriesPoint[] pointArray = td.getTsData(); - if (pointArray != null) { + + TimeSeriesPoint[] pointArray = null; + if (zoomed) { + pointArray = td.getZoomedTsData(); + }else{ + pointArray = td.getTsData(); + } + + if (pointArray != null) { for (int j = 0; j < pointArray.length; j++) { if (pointArray[j] != null) { if (pointArray[j].getY() < yLowest) { @@ -1227,9 +1250,9 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements } } } // end for - } - } - + } + + } } } // end for @@ -1466,7 +1489,7 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements statusHandler.handle(Priority.ERROR, "Error retrieving graph data", e); } - + td.setTsData(points.toArray(new TimeSeriesPoint[points.size()])); td.setPreviousTsData(pointsbak.toArray(new TimeSeriesPoint[pointsbak @@ -1932,13 +1955,12 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements } } } else if (traceSelected && dialog.isDelete()) { - if (precipPE) { + if (precipPE) { List ppl = precipPointList.get(selectedTraceId); for (int i = 0; i < ppl.size(); i++) { if (ppl.get(i).contains(e.x, e.y)) { deleteIndex = i; - deleteList.add(deleteIndex); - break; + deleteList.add( getZoomOffset(selectedTraceId) + deleteIndex ); } } } else { @@ -1946,13 +1968,20 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements for (int i = 0; i < prl.size(); i++) { if (prl.get(i).contains(e.x, e.y)) { deleteIndex = i; - deleteList.add(deleteIndex); + deleteList.add( getZoomOffset(selectedTraceId) + deleteIndex ); break; } } } TraceData td = graphData.getTraceData(selectedTraceId); - TimeSeriesPoint[] points = td.getTsData(); + + TimeSeriesPoint[] points = null; + if (zoomed) { + points = td.getZoomedTsData(); + } else { + points = td.getTsData(); + } + for (int j = 0; j < points.length; j++) { if (j == deleteIndex) { @@ -1969,7 +1998,7 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements for (int i = 0; i < ppl.size(); i++) { if (ppl.get(i).contains(e.x, e.y)) { setMissingIndex = i; - setMissingList.add(setMissingIndex); + setMissingList.add(getZoomOffset(selectedTraceId) + setMissingIndex); break; } } @@ -1978,7 +2007,7 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements for (int i = 0; i < prl.size(); i++) { if (prl.get(i).contains(e.x, e.y)) { setMissingIndex = i; - setMissingList.add(setMissingIndex); + setMissingList.add(getZoomOffset(selectedTraceId) + setMissingIndex); break; } } @@ -2030,7 +2059,7 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements * Mouse Event */ private void handleMouseUpEvent(MouseEvent e) { - mouseDown = false; + mouseDown = false; /* Null the point string or the last location stays displayed */ pointString = null; @@ -2051,7 +2080,7 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements dataPts[selectionIndex * 2 + 1] = e.y; graphData.getTraceData(selectedTraceId).setLineData(dataPts); - + setEditData(e.y); pointSelected = false; getAgain = false; @@ -2094,33 +2123,32 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements } dialog.addDeletePoint(data); - deleteList.add(i); } } deleteRect = null; - } else if (traceSelected && dialog.isSetMissing() - && (setMissingRect != null)) { + } else if (traceSelected && dialog.isSetMissing() && (setMissingRect != null) ) { + TraceData td = graphData.getTraces().get(selectedTraceId); TimeSeriesPoint[] pointArray = td.getTsData(); - + for (int i = 0; i < pointArray.length; i++) { if (setMissingRect.contains(pointArray[i].getPixelX(), pointArray[i].getPixelY())) { ForecastData data = createPoint(td, pointArray[i]); data.setValue(new Double(HydroConstants.MISSING_VALUE)); dialog.addEditPoint(data); - setMissingList.add(i); + setMissingList.add( getZoomOffset(selectedTraceId) + i ); } } setMissingRect = null; } - + /* Get the data traces */ traceArray = graphData.getTraces(); - + // Set true so new regions will be created createRegions = true; @@ -2136,13 +2164,13 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements setZoomed(false); dialog.setZoomAction(false); traceArray = graphData.getTraces(); - + // Set true so new regions will be created createRegions = true; setCursor(null); redraw(); - + return; } @@ -2168,14 +2196,18 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements graphData.getTraceData(selectedTraceId).setTsData(pa); } - + // set the value back into the list pa[selectionIndex] = tsp; ForecastData data = createPoint(td, tsp); dialog.addEditPoint(data); - graphData.getTraceData(selectedTraceId).setTsData(pa); - } + if (zoomed) { + graphData.getTraceData(selectedTraceId).setZoomedTsData(pa); + } else { + graphData.getTraceData(selectedTraceId).setTsData(pa); + } + } /** * Make the regions around the lines and points @@ -2815,5 +2847,14 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements public void setZoomed(boolean zoomed) { this.zoomed = zoomed; } - + + private int getZoomOffset(int pSelectedTraceId) { + + if (zoomed){ + TraceData td = graphData.getTraceData(pSelectedTraceId); + return td.getZoomIndexOffset(); + } + + return 0; + } } diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/util/TraceData.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/util/TraceData.java index 57a931296f..5bf8cc1435 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/util/TraceData.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/util/TraceData.java @@ -38,6 +38,7 @@ import com.raytheon.viz.hydrocommon.HydroConstants; * pop up menu * Apr 05, 2011 8732 jpiatt Added product_id. * June,1, 2011 9499 djingtao change setDur() + * 22 Oct 2015 13736 xwei Added getZoomIndexOffset() method * * * @@ -606,4 +607,24 @@ public class TraceData implements Serializable { public void setProductTime(Date productTime) { this.productTime = productTime; } + + /** + * @return zoom index offset + */ + public int getZoomIndexOffset() { + + if (this.zoomedTsData != null && this.zoomedTsData.length > 0 ){ + for (int i = 0; i < this.tsData.length; i++) { + if ( tsData[i].getX().equals(zoomedTsData[0].getX()) && + tsData[i].getY() == zoomedTsData[0].getY() + ){ + return i; + } + } + + } + + return 0; + } + } diff --git a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDataManager.java b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDataManager.java index c48493aa23..22778a5eed 100644 --- a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDataManager.java +++ b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDataManager.java @@ -43,6 +43,7 @@ import com.raytheon.viz.hydrocommon.datamanager.HydroDataManager; * 15 Dec 2009 2422 mpduff Added query for rating date and * USGS rating number. * Jul 21, 2015 4500 rjpeter Use Number in blind cast. + * 23 Oct 2015 14375 xwei Fixed rating curve saving error. Fixed import rating curve format error. * * * @version 1.0 @@ -334,4 +335,23 @@ public class RatingCurveDataManager extends HydroDataManager { return label; } + + /** + * delete All Rating Curves for a lid + * + * @param lid + */ + public void clearAllRatingCurveData(RatingCurveData rcd, String lid) { + if (lid != null) { + String query = "DELETE from rating WHERE lid='" + lid + "' ;" ; + try { + DirectDbQuery.executeStatement(query, HydroConstants.IHFS, + QueryLanguage.SQL); + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + } diff --git a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDlg.java b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDlg.java index feee4c17f8..d58ae5eb48 100644 --- a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDlg.java +++ b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/ratingcurve/RatingCurveDlg.java @@ -77,6 +77,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * 22 Jan 2013 15682 lbousaidi fix openfile problem and changed the path to * whfs_import_dir for "Import Curve" button. * 15 Jul 2013 2088 rferrel Make dialog non-blocking. + * 23 Oct 2015 14375 xwei Fixed rating curve saving error. Fixed import rating curve format error. * * * @author lvenable @@ -290,6 +291,8 @@ public class RatingCurveDlg extends CaveSWTDialog { * Shift amount */ private double shiftAmount = 0; + + private boolean deleteAllRatingCurve = false; /** * Constructor. @@ -366,6 +369,7 @@ public class RatingCurveDlg extends CaveSWTDialog { addSeparator(); createBottomButtons(); populateControls(); + curveImportBtnSetEnabled(); } /** @@ -426,6 +430,23 @@ public class RatingCurveDlg extends CaveSWTDialog { recordDataLbl.setLayoutData(gd); } + + /** + * Create the rating curve canvas. + * + */ + private void curveImportBtnSetEnabled() { + + if ( noShiftCurveDataList.getItemCount() == 0 && shiftCurveDataList.getItemCount() == 0 ) { + curveImportBtn.setEnabled(true); + } else { + curveImportBtn.setEnabled(false); + } + + + } + + /** * Create the rating curve canvas. * @@ -577,8 +598,14 @@ public class RatingCurveDlg extends CaveSWTDialog { int response = messageDialog.open(); if (response == SWT.OK) { - // get rid of every point - removedPoints = noShiftCurveArray; + + + deleteAllRatingCurve = true; + // Add all rating curve points to the array. + for (RatingCurveData d : noShiftCurveArray) { + removedPoints.add(d); + } + noShiftCurveArray.clear(); noShiftCurveDataList.removeAll(); noShiftCurveDataList.redraw(); @@ -1093,7 +1120,7 @@ public class RatingCurveDlg extends CaveSWTDialog { // Read File Line By Line while ((strLine = br.readLine()) != null) { - String[] line = strLine.split(" "); + String[] line = strLine.trim().split(" "); // should be ordered stage, flow separated by a space if (line.length == 2) { rci.add(new Double(line[0]), new Double(line[1])); @@ -1121,6 +1148,15 @@ public class RatingCurveDlg extends CaveSWTDialog { newRatingCurve = false; } + if (removedPoints.size() != 0 && deleteAllRatingCurve) { + for (RatingCurveData rcd : removedPoints) { + rcdm.clearAllRatingCurveData(rcd,lid); + } + deleteAllRatingCurve=false; + removedPoints = new ArrayList(); + + } + if (removedPoints.size() != 0) { for (RatingCurveData rcd : removedPoints) { rcdm.deleteRatingCurveData(rcd, lid); @@ -1145,6 +1181,8 @@ public class RatingCurveDlg extends CaveSWTDialog { } addedCurveShifts = new ArrayList(); } + + curveImportBtnSetEnabled(); } /** diff --git a/cave/com.raytheon.viz.warngen/META-INF/MANIFEST.MF b/cave/com.raytheon.viz.warngen/META-INF/MANIFEST.MF index 7b79a016f8..6748871094 100644 --- a/cave/com.raytheon.viz.warngen/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.viz.warngen/META-INF/MANIFEST.MF @@ -25,7 +25,8 @@ Require-Bundle: org.eclipse.ui, com.raytheon.viz.alerts, com.raytheon.uf.common.site, com.raytheon.viz.core.contours, - com.raytheon.uf.viz.core.rsc + com.raytheon.uf.viz.core.rsc, + com.raytheon.uf.viz.d2d.ui Bundle-ActivationPolicy: lazy Export-Package: com.raytheon.viz.warngen, com.raytheon.viz.warngen.gis, diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java index d1c4876187..d1e5396be1 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java @@ -81,6 +81,7 @@ import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.core.maps.MapManager; +import com.raytheon.uf.viz.d2d.ui.map.SideView; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.DisplayType; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.Mode; import com.raytheon.viz.texteditor.msgs.IWarngenObserver; @@ -170,6 +171,9 @@ import com.vividsolutions.jts.geom.Polygon; * May 7, 2015 ASM #17438 D. Friedman Clean up debug and performance logging. * Jun 05, 2015 DR 17428 D. Friedman Fixed duration-related user interface issues. Added duration logging. * Sep 22, 2015 4859 dgilling Prevent product generation in DRT mode. + * Nov 9, 2015 DR 14905 Qinglu Lin Updated backupSiteSelected(), disposed(), initializeComponents(), populateBackupGroup(), and + * createProductTypeGroup, and moved existing code to newly created setBackupCboColors() and setBackupSite(). + * Nov 25, 2015 DR 17464 Qinglu Lin Updated changeTemplate(). * * * @author chammack @@ -351,6 +355,10 @@ public class WarngenDialog extends CaveSWTDialog implements timer.cancel(); updateTimeTask.cancel(); CurrentWarnings.removeListener(this); + IDisplayPaneContainer container = warngenLayer.getResourceContainer(); + if (container != null && ! (container instanceof SideView)) { + WarngenLayer.setLastSelectedBackupSite(warngenLayer.getBackupSite()); + } warngenLayer = null; } @@ -384,6 +392,7 @@ public class WarngenDialog extends CaveSWTDialog implements createTimeRangeGroup(mainComposite); createBulletListAndLabel(mainComposite); createBottomButtons(mainComposite); + setBackupSite(); setInstructions(); } @@ -501,9 +510,6 @@ public class WarngenDialog extends CaveSWTDialog implements productType.setLayout(gl); productType.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - - createMainProductButtons(productType); - createOtherProductsList(productType); } /** @@ -766,14 +772,21 @@ public class WarngenDialog extends CaveSWTDialog implements backupSiteCbo.add(NO_BACKUP_SELECTED); String[] CWAs = warngenLayer.getDialogConfig().getBackupCWAs() .split(","); + int index = 0, selectedIndex = 0; for (String cwa : CWAs) { if (cwa.length() > 0) { + index += 1; BackupData data = new BackupData(cwa); backupSiteCbo.setData(data.site, data); backupSiteCbo.add(data.site); + if (data.site.equals(warngenLayer.getBackupSite())) { + selectedIndex = index; + warngenLayer.setBackupSite(data.site); + } } } - backupSiteCbo.select(0); + backupSiteCbo.select(selectedIndex); + setBackupCboColors(); } private void createTrackGroup(Composite backupTrackEditComp) { @@ -1406,15 +1419,16 @@ public class WarngenDialog extends CaveSWTDialog implements hide(); } - /** - * Action for when something is selected from the backup site combo - */ - private void backupSiteSelected() { + private boolean setBackupSite() { if ((backupSiteCbo.getSelectionIndex() >= 0) && (backupSiteCbo.getItemCount() > 0)) { int index = backupSiteCbo.getSelectionIndex(); String backupSite = backupSiteCbo.getItem(index); warngenLayer.setBackupSite(backupSite); + IDisplayPaneContainer container = warngenLayer.getResourceContainer(); + if (container != null && ! (container instanceof SideView)) { + WarngenLayer.setLastSelectedBackupSite(backupSite); + } if (backupSite.equalsIgnoreCase("none")) { new TemplateRunnerInitJob().schedule(); } else { @@ -1439,11 +1453,24 @@ public class WarngenDialog extends CaveSWTDialog implements .error("Error occurred while switching to the default template.", e); } + return true; + } else { + return false; + } + } + /** + * Action for when something is selected from the backup site combo + */ + private void backupSiteSelected() { + if (setBackupSite()) { productType.layout(true, true); getShell().pack(true); } + setBackupCboColors(); + } + private void setBackupCboColors() { if (backupSiteCbo.getSelectionIndex() == 0) { backupSiteCbo.setBackground(null); backupSiteCbo.setForeground(null); @@ -1706,21 +1733,11 @@ public class WarngenDialog extends CaveSWTDialog implements boolean isDifferentAreaSources = !warngenLayer.getConfiguration() .getHatchedAreaSource().getAreaSource() .equalsIgnoreCase(lastAreaSource); - boolean snapHatchedAreaToPolygon = isDifferentAreaSources; boolean preservedSelection = !isDifferentAreaSources; - if (isDifferentAreaSources - || !warngenLayer.getConfiguration().getHatchedAreaSource() - .getAreaSource().toLowerCase().equals("marinezones")) { - // If template has a different hatched area source from the previous - // template, then the warned area would be based on the polygon and - // not - // preserved. - try { - warngenLayer.updateWarnedAreas(snapHatchedAreaToPolygon, - preservedSelection); - } catch (VizException e1) { - statusHandler.handle(Priority.PROBLEM, "WarnGen Error", e1); - } + try { + warngenLayer.updateWarnedAreas(preservedSelection); + } catch (VizException e1) { + statusHandler.handle(Priority.PROBLEM, "WarnGen Error", e1); } // Properly sets the "Create Text" button. setInstructions(); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java index b7c3ca7dd7..6e0832eb29 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java @@ -240,6 +240,9 @@ import com.vividsolutions.jts.io.WKTReader; * 04/24/2015 ASM #17394 D. Friedman Fix geometries that become invalid in local coordinate space. * 05/07/2015 ASM #17438 D. Friedman Clean up debug and performance logging. * 05/08/2015 ASM #17310 D. Friedman Log input polygon when output of AreaHatcher is invalid. + * 11/09/2015 DR 14905 Qinglu Lin Added lastSelectedBackupSite and its accessors, and updated constructor. + * 11/25/2015 DR 17464 Qinglu Lin Updated two updateWarnedAreas(), updateWarnedAreaState(), createSquare(),redrawBoxFromTrack(), + * redrawBoxFromHatched(), createDamThreatArea(), createPolygonFromRecord(), addOrRemoveCounty(). * * * @author mschenke @@ -253,6 +256,8 @@ public class WarngenLayer extends AbstractStormTrackResource { private static final IPerformanceStatusHandler perfLog = PerformanceStatus .getHandler("WG:"); + static String lastSelectedBackupSite; + String uniqueFip = null; String backupOfficeShort = null; @@ -814,6 +819,9 @@ public class WarngenLayer extends AbstractStormTrackResource { statusHandler.handle(Priority.SIGNIFICANT, "Error loading config.xml", e); } + + setBackupSite(WarngenLayer.getLastSelectedBackupSite()); + // Load default template String defaultTemplate = dialogConfig.getDefaultTemplate(); if (defaultTemplate.equals("")) { @@ -1536,7 +1544,7 @@ public class WarngenLayer extends AbstractStormTrackResource { } public void setBackupSite(String site) { - if (site.equalsIgnoreCase("none")) { + if (site == null || site.equalsIgnoreCase("none")) { backupSite = null; } else { backupSite = site; @@ -1947,20 +1955,14 @@ public class WarngenLayer extends AbstractStormTrackResource { } } - public void updateWarnedAreas(boolean snapHatchedAreaToPolygon) - throws VizException { - updateWarnedAreas(snapHatchedAreaToPolygon, false); + public void updateWarnedAreas() throws VizException { + updateWarnedAreas(false); } /** - * - * @param snapHatchedAreaToPolygon - * If True, any hatched area outside the polygon will be - * eliminated. * @throws VizException */ - public void updateWarnedAreas(boolean snapHatchedAreaToPolygon, - boolean preservedSelection) throws VizException { + public void updateWarnedAreas(boolean preservedSelection) throws VizException { if (getPolygon() == null) { return; } @@ -1970,11 +1972,10 @@ public class WarngenLayer extends AbstractStormTrackResource { Geometry warningArea = state.getWarningArea(); Geometry warningPolygon = state.getWarningPolygon(); Geometry newWarningArea = createWarnedArea( - latLonToLocal((snapHatchedAreaToPolygon || (warningArea == null)) ? warningPolygon - : warningArea), preservedSelection + latLonToLocal(warningPolygon), preservedSelection && (warningArea != null) ? latLonToLocal(warningArea) : null); - updateWarnedAreaState(newWarningArea, snapHatchedAreaToPolygon); + updateWarnedAreaState(newWarningArea); perfLog.logDuration("Determining hatchedArea", System.currentTimeMillis() - t0); @@ -2127,8 +2128,7 @@ public class WarngenLayer extends AbstractStormTrackResource { } } - private void updateWarnedAreaState(Geometry newHatchedArea, - boolean snapToHatchedArea) throws VizException { + private void updateWarnedAreaState(Geometry newHatchedArea) throws VizException { try { // Ensure all geometries in local coords Geometry warningPolygon = latLonToLocal(state.getWarningPolygon()); @@ -2251,7 +2251,7 @@ public class WarngenLayer extends AbstractStormTrackResource { state.setWarningPolygon((Polygon) state .getMarkedWarningPolygon().clone()); state.resetMarked(); - updateWarnedAreas(snapToHatchedArea); + updateWarnedAreas(); } } else { state.setWarningArea(localToLatLon(newHatchedArea)); @@ -2447,7 +2447,7 @@ public class WarngenLayer extends AbstractStormTrackResource { LinearRing lr = gf.createLinearRing(c); state.setWarningPolygon(gf.createPolygon(lr, null)); - updateWarnedAreas(true); + updateWarnedAreas(); } public void redrawBoxFromTrack() throws VizException { @@ -2619,7 +2619,7 @@ public class WarngenLayer extends AbstractStormTrackResource { LinearRing lr = gf.createLinearRing(c); state.setWarningPolygon(gf.createPolygon(lr, null)); - updateWarnedAreas(true); + updateWarnedAreas(); /* * NOT LINE OF STORMS @@ -2664,7 +2664,7 @@ public class WarngenLayer extends AbstractStormTrackResource { LinearRing lr = gf.createLinearRing(c); state.setWarningPolygon(gf.createPolygon(lr, null)); - updateWarnedAreas(true); + updateWarnedAreas(); } if (dialog.box.getSelection()) { displayState.editable = false; @@ -2704,7 +2704,7 @@ public class WarngenLayer extends AbstractStormTrackResource { if (hatched != null) { state.setWarningPolygon(hatched); - updateWarnedAreaState(hatchedArea, true); + updateWarnedAreaState(hatchedArea); issueRefresh(); // End of DR 15559 state.snappedToArea = true; @@ -2752,7 +2752,7 @@ public class WarngenLayer extends AbstractStormTrackResource { try { state.setWarningPolygon(gf.createPolygon(lr, null)); state.rightClickSelected = false; - updateWarnedAreas(true); + updateWarnedAreas(); displayState.dragMeGeom = gf.createPoint(pt); displayState.dragMePoint = gf.createPoint(pt); displayState.mode = Mode.TRACK; @@ -2868,7 +2868,7 @@ public class WarngenLayer extends AbstractStormTrackResource { state.setWarningPolygon(warnPolygon); state.setWarningArea(getWarningAreaFromPolygon( state.getWarningPolygon(), record)); - updateWarnedAreas(true, true); + updateWarnedAreas(true); } private DataTime recordFrameTime(AbstractWarningRecord warnRecord) { @@ -3254,7 +3254,7 @@ public class WarngenLayer extends AbstractStormTrackResource { String fip = getFips(f); if ((fip != null) && (uniqueFip != null) && fip.equals(uniqueFip)) { - updateWarnedAreas(true); + updateWarnedAreas(); } break; } @@ -3844,4 +3844,15 @@ public class WarngenLayer extends AbstractStormTrackResource { return backupOfficeLoc; } + public String getBackupSite() { + return backupSite; + } + + public static String getLastSelectedBackupSite() { + return lastSelectedBackupSite; + } + + public static void setLastSelectedBackupSite(String backupSite) { + lastSelectedBackupSite = backupSite; + } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java index 2b9e8af8e2..449cc4778f 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java @@ -67,6 +67,7 @@ import com.vividsolutions.jts.geom.Polygon; * Jun 25, 2013 DR 16013 Qinglu Lin Called setUniqueFip() in handleMouseUp(). * Aug 15, 2013 DR 16418 D. Friedman Only raise dialog if editable. Don't call featureEdit if not editable. * Sep 24, 2013 #2403 lvenable Fixed cursor memory leak. + * Nov 25, 2015 DR 17464 Qinglu Lin Updated handleMouseUp(), DeleteVertexAction(), and AddVertexAction class. * * * @@ -260,7 +261,7 @@ public class WarngenUIManager extends InputAdapter { LinearRing lr = gf.createLinearRing(coordinates); state.setWarningPolygon(gf.createPolygon(lr, null)); } - warngenLayer.updateWarnedAreas(true); + warngenLayer.updateWarnedAreas(); } catch (VizException e) { e.printStackTrace(); } @@ -457,7 +458,7 @@ public class WarngenUIManager extends InputAdapter { warngenLayer.getWarngenState().setWarningPolygon(newPoly); try { - warngenLayer.updateWarnedAreas(true); + warngenLayer.updateWarnedAreas(); } catch (VizException e) { Status s = new Status(Status.ERROR, Activator.PLUGIN_ID, "Error updating warned area", e); @@ -597,7 +598,7 @@ public class WarngenUIManager extends InputAdapter { Polygon newPoly = gf.createPolygon(newLs, null); warngenLayer.getWarngenState().setWarningPolygon(newPoly); try { - warngenLayer.updateWarnedAreas(true); + warngenLayer.updateWarnedAreas(); } catch (VizException e) { Status s = new Status(Status.ERROR, Activator.PLUGIN_ID, diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/src/com/raytheon/edex/plugin/obs/metar/MetarDecoder.java b/edexOsgi/com.raytheon.edex.plugin.obs/src/com/raytheon/edex/plugin/obs/metar/MetarDecoder.java index 569d2bc855..8db285746b 100644 --- a/edexOsgi/com.raytheon.edex.plugin.obs/src/com/raytheon/edex/plugin/obs/metar/MetarDecoder.java +++ b/edexOsgi/com.raytheon.edex.plugin.obs/src/com/raytheon/edex/plugin/obs/metar/MetarDecoder.java @@ -88,6 +88,8 @@ import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; * Oct 02, 2014 3693 mapeters Added Pattern constants. * Apr 22, 2015 DR 16923 MPorricelli Modified cleanMessage to eliminate extra spaces * Jul 13, 2015 4389 skorolev Added correction of invalid (NUL) characters in the message. + * Nov 01, 2015 DR 14741 MPorricelli Modified WIND_VAR_DIR_EXP pattern to prevent its matching + * some RVR strings * * * @@ -116,9 +118,11 @@ public class MetarDecoder { private static final Pattern WIND_GROUP_EXP_MPS = Pattern .compile("(\\d{3}|VRB)(\\d{2,3})((G)(\\d{2,3}))?MPS"); - // Variable wind direction + // Variable wind direction: e.g. 050V120 + // Exclude case where RVR has similar construct: + // e.g R13R/0600V1200FT so it will not be read as var wind dir private static final Pattern WIND_VAR_DIR_EXP = Pattern - .compile("\\d{3}V\\d{3}"); + .compile("\\d{3}V\\d{3}(?!\\d{1}FT)"); /** Regular expression for the visibility */ // private final Pattern VISIBILITY_EXP = Pattern diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py index a5b8087bd6..8b71a743f0 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py +++ b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py @@ -48,6 +48,8 @@ # when decoding product not from a file. # Mar 26, 2015 4324 dgilling Improve handling of all 0s time values in HVTEC strings. # Sep 23, 2015 4848 nabowle Handle UGC-like lines in the text segment. +# Nov 10, 2015 17068 ryu Improve handling of lines starting with a UGC code +# but do not really begin new segments # # # @author rferrel @@ -173,6 +175,8 @@ class StdWarningDecoder(): self._endSegmentRE = r'^\$\$' self._dlineRE = r"^1?[0-9]{3} [AP]M [A-Z][A-Z]?[DS]T.*[A-Z][A-Z,a-z]{2} " + \ r"[0123]?[0-9] 2[0-9]{3}.*$" + self._ugcRE = r'^[A-Z][A-Z][CZ][0-9]{3}[->]' + self._endTimeRE = r'-[0-3][0-9][0-2][0-9][0-5][0-9]-$' #maximum future time (used for until further notice) self._maxFutureTime = float(2**31 - 1) #max signed int @@ -353,7 +357,7 @@ usage: VTECDecoder -f productfilename -d -a activeTableName count = startLine dlineFlag = 0 while count < 12 and count < len(self._lines): - if re.search(r'^[A-Z][A-Z][CZ][0-9][0-9][0-9].*', + if re.search(self._ugcRE, self._lines[count]): if dlineFlag == 0: return 0 @@ -386,10 +390,8 @@ usage: VTECDecoder -f productfilename -d -a activeTableName startOverviewLine = count #next line after MND date line #search for the 1st UGC line - ugcRE = r'^[A-Z][A-Z][CZ][0-9][0-9][0-9].*' while 1: - ugc_search = re.search(ugcRE, self._lines[count]) - if ugc_search: + if self.checkForBeginSegment(count): stopOverviewLine = count - 1 break count = count + 1 @@ -490,8 +492,7 @@ usage: VTECDecoder -f productfilename -d -a activeTableName count = lineStart #start on line following PIL while 1: #look for the first UGC line - if re.search(r'^[A-Z][A-Z][CZ][0-9][0-9][0-9].*', - self._lines[count]): + if self.checkForBeginSegment(count): LogStream.logDebug("First line of UGC found on line: ", count, '[' + self._lines[count] + ']') @@ -503,16 +504,15 @@ usage: VTECDecoder -f productfilename -d -a activeTableName nxt = 0 #number of lines from the first UGC line ugc = "" #final UGC codes while count+nxt < len(self._lines): - if not re.search(r'.*[0-9][0-9][0-9][0-9][0-9][0-9]-', - self._lines[count+nxt]): - nxt = nxt + 1 - else: + if re.search(self._endTimeRE, self._lines[count+nxt]): LogStream.logDebug("Last line of UGC found on line: ", count+nxt, '[' + self._lines[count+nxt] + ']') ugc = string.join(self._lines[count:count+nxt+1], sep="") break + nxt = nxt + 1 + # if we hit the end, break out and let the len(ugc) check fail if count+nxt == len(self._lines): break; @@ -584,16 +584,11 @@ usage: VTECDecoder -f productfilename -d -a activeTableName # found a probable UGC line, terminate the segment # if a DDMMHH or VTEC can be found - elif re.search(r'^[A-Z][A-Z][CZ][0-9][0-9][0-9].*', - self._lines[count+nxt]): - toCheck = count+nxt - falsePositive = self.checkForFalseUGCLine(toCheck) - - if not falsePositive: - segmentText = self._prepSegmentText(\ - self._lines[textFirst:count+nxt]) - nxt = nxt - 1 #back up one line to redo UGC outer loop - break + elif self.checkForBeginSegment(count+nxt): + segmentText = self._prepSegmentText(\ + self._lines[textFirst:count+nxt]) + nxt = nxt - 1 #back up one line to redo UGC outer loop + break # end of file, terminate the segment elif count+nxt+1 == len(self._lines): @@ -625,10 +620,17 @@ usage: VTECDecoder -f productfilename -d -a activeTableName count = count + 1 if count >= len(self._lines): break + for e in ugcList: LogStream.logVerbose("UGC/VTEC found: ", e[0], e[1]) return ugcList + def checkForBeginSegment(self, start): + if re.search(self._ugcRE, self._lines[start]) and \ + not self.checkForFalseUGCLine(start): + return True + return False + def checkForFalseUGCLine(self, toCheck): # tries to determine if an apparent UGC line encountered in a text # segment is an actual UGC line, or is a UGC-like line in the free-text @@ -641,12 +643,16 @@ usage: VTECDecoder -f productfilename -d -a activeTableName while toCheck < len(self._lines): # look for the end date or vtec line before "$$" or the end of the # file - if re.search(r'.*[0-9][0-9][0-9][0-9][0-9][0-9]-', + if re.search(self._endTimeRE, self._lines[toCheck]) or \ re.search(self._vtecRE, self._lines[toCheck]): falsePositive = False break; + # blank line + if not self._lines[toCheck]: + break + if re.search(self._endSegmentRE, self._lines[toCheck]): break; diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/area.suppress b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/area.suppress new file mode 100644 index 0000000000..ddedce01e4 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/area.suppress @@ -0,0 +1,13 @@ +# NOTE: both number sign, # and the space ahead of UGC code need to be removed +# in the following examples to make it work. Each site should copy this file +# to SITE-LEVEL area.suppress and append appropriate UGC code and direction to it +# if there's a need to suppress direction in the first bullet for certain counties. + +# The following example suppresses east west direction for MTC087 at BYZ +# MTC087 ew + +# The following example suppresses north south direction for ORC051 at PQR +# ORC051 ns + +# The following example suppresses all directions for ORC051 at PQR +# ORC051 diff --git a/edexOsgi/com.raytheon.uf.edex.site/src/com/raytheon/uf/edex/site/SiteAwareRegistry.java b/edexOsgi/com.raytheon.uf.edex.site/src/com/raytheon/uf/edex/site/SiteAwareRegistry.java index e67d48c74f..d41a770c01 100644 --- a/edexOsgi/com.raytheon.uf.edex.site/src/com/raytheon/uf/edex/site/SiteAwareRegistry.java +++ b/edexOsgi/com.raytheon.uf.edex.site/src/com/raytheon/uf/edex/site/SiteAwareRegistry.java @@ -43,6 +43,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.util.registry.RegistryException; import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.EdexException; +import com.raytheon.uf.edex.database.cluster.ClusterLockUtils; +import com.raytheon.uf.edex.database.cluster.ClusterTask; +import com.raytheon.uf.edex.database.cluster.ClusterLockUtils.LockState; import com.raytheon.uf.edex.site.SiteActivationMessage.Action; /** @@ -63,6 +66,8 @@ import com.raytheon.uf.edex.site.SiteActivationMessage.Action; * Dec 11, 2012 14360 ryu No printing stack trace on activation exception * Mar 10, 2014 2721 randerso Fix error when activeSites.txt contains blank lines. * Jul 10, 2014 2914 garmendariz Remove EnvProperties + * Nov 9, 2015 14734 yteng Remove activeSites and add lock to synchronize access + * to activeSites.txt to eliminate race conditions * * * @@ -77,8 +82,6 @@ public class SiteAwareRegistry { private static SiteAwareRegistry instance = new SiteAwareRegistry(); - private Set activeSites = new CopyOnWriteArraySet(); - private Set activationListeners = new CopyOnWriteArraySet(); private String routeId; @@ -88,13 +91,11 @@ public class SiteAwareRegistry { } private SiteAwareRegistry() { - // read in the current activeSites - loadActiveSites(); - // initialize default site + Set activeSites = getActiveSitesFromFile(true); String defaultSite = EDEXUtil.getEdexSite(); if (!activeSites.contains(defaultSite)) { - activeSites.add(defaultSite); + updateActiveSites(Action.ACTIVATE, defaultSite); } } @@ -111,7 +112,7 @@ public class SiteAwareRegistry { + sa.toString()); } // inform of the current active sites - for (String siteID : activeSites) { + for (String siteID : getActiveSitesFromFile(true)) { try { sa.activateSite(siteID); } catch (Exception e) { @@ -190,8 +191,7 @@ public class SiteAwareRegistry { mess.setSiteId(siteID); mess.setAction(Action.ACTIVATE); routeMessage(mess); - activeSites.add(siteID); - saveActiveSites(); + updateActiveSites(Action.ACTIVATE, siteID); } catch (Exception e) { statusHandler .handle(Priority.PROBLEM, @@ -211,8 +211,7 @@ public class SiteAwareRegistry { mess.setSiteId(siteID); mess.setAction(Action.DEACTIVATE); routeMessage(mess); - activeSites.remove(siteID); - saveActiveSites(); + updateActiveSites(Action.DEACTIVATE, siteID); } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Failed to send site de-activation message for site " @@ -226,6 +225,7 @@ public class SiteAwareRegistry { * @param siteID */ public void cycleSite(String siteID) { + Set activeSites = getActiveSitesFromFile(true); if (activeSites.contains(siteID)) { try { SiteActivationMessage mess = new SiteActivationMessage(); @@ -253,8 +253,7 @@ public class SiteAwareRegistry { statusHandler.handle(Priority.PROBLEM, "Failed to process site " + action + " for site " + siteID, e); - activeSites.add(siteID); - saveActiveSites(); + updateActiveSites(Action.ACTIVATE, siteID); } } if (!Action.DEACTIVATE.equals(action)) { @@ -264,8 +263,7 @@ public class SiteAwareRegistry { statusHandler.handle(Priority.PROBLEM, "Failed to process site " + action + " for site " + siteID, e); - activeSites.remove(siteID); - saveActiveSites(); + updateActiveSites(Action.DEACTIVATE, siteID); } } @@ -281,9 +279,17 @@ public class SiteAwareRegistry { /** * load the active site list */ - private void loadActiveSites() { + private Set getActiveSitesFromFile(boolean useFileLock) { // add cluster locking - activeSites.clear(); + ClusterTask ct = null; + if (useFileLock) { + do { + ct = ClusterLockUtils.lock("siteActivation", "readwrite", + 120000, true); + } while (!LockState.SUCCESSFUL.equals(ct.getLockState())); + } + + Set activeSites = new LinkedHashSet(); BufferedReader in = null; try { IPathManager pathMgr = PathManagerFactory.getPathManager(); @@ -313,13 +319,20 @@ public class SiteAwareRegistry { statusHandler.handle(Priority.PROBLEM, "Error loading active sites", e); } + + if (useFileLock) { + ClusterLockUtils.deleteLock(ct.getId().getName(), ct + .getId().getDetails()); + } } + + return activeSites; } /** * save the active site list */ - private void saveActiveSites() { + private void saveActiveSites(Set activeSites) { BufferedWriter out = null; IPathManager pathMgr = PathManagerFactory.getPathManager(); LocalizationFile lf = pathMgr.getLocalizationFile(pathMgr.getContext( @@ -353,6 +366,34 @@ public class SiteAwareRegistry { e); } } + + /** + * update the active site list + * + * @param action + * @param siteID + */ + private synchronized void updateActiveSites(Action action, String siteID) { + ClusterTask ct = null; + do { + ct = ClusterLockUtils.lock("siteActivation", "readwrite", + 120000, true); + } while (!LockState.SUCCESSFUL.equals(ct.getLockState())); + + Set activeSites = getActiveSitesFromFile(false); + if (Action.ACTIVATE.equals(action)) { + if (activeSites.add(siteID)) + saveActiveSites(activeSites); + } else if (Action.DEACTIVATE.equals(action)) { + if (activeSites.remove(siteID)) + saveActiveSites(activeSites); + } else { + statusHandler.handle(Priority.PROBLEM, "Error updating active sites"); + } + + ClusterLockUtils.deleteLock(ct.getId().getName(), ct + .getId().getDetails()); + } } /** diff --git a/rpms/awips2.core/Installer.ldm/component.spec b/rpms/awips2.core/Installer.ldm/component.spec index e4c9f1d839..14811714c2 100644 --- a/rpms/awips2.core/Installer.ldm/component.spec +++ b/rpms/awips2.core/Installer.ldm/component.spec @@ -1,4 +1,4 @@ -%define _ldm_version 6.12.9 +%define _ldm_version 6.12.14 %define _ldm_src_tar ldm-%{_ldm_version}.tar.gz # ldm-%{_ldm_version}.tar.gz is tarred up ldm-%{_ldm_version}/src dir after # ISG makes retrans changes @@ -199,6 +199,8 @@ if [ $? -ne 0 ]; then exit 1 fi export _current_dir=`pwd` +# Localize configure based on the auto tools that are installed +cd ${_current_dir}; autoreconf -if su ldm -lc "cd ${_current_dir}; ./configure --disable-max-size --with-noaaport --with-retrans --disable-root-actions --prefix=${_ldm_root_dir} CFLAGS='-g -O0'" \ > configure.log 2>&1 if [ $? -ne 0 ]; then diff --git a/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tar.gz b/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tar.gz new file mode 100755 index 0000000000..b25ced05c0 Binary files /dev/null and b/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tar.gz differ diff --git a/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tgz b/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tgz new file mode 100644 index 0000000000..02b0e64a68 Binary files /dev/null and b/rpms/awips2.core/Installer.ldm/src/ldm-6.12.14.tgz differ