VLab Issue #4001 - NCEP EDEX and EDEX Common delivery for 14.2.1-n
AWW and Upper Air updates. Revert some RTS xml files Change-Id: I4cc48defcea33b9008c9734c1c53a193d0ce94da Former-commit-id:75277cb034
[formerly 72fa8af848f1452a517a62c6a54eae265a9ec8a1] Former-commit-id:32dffe58c8
This commit is contained in:
parent
f604392bbc
commit
4abe38b3ac
9 changed files with 645 additions and 474 deletions
|
@ -12,10 +12,10 @@
|
|||
|
||||
<!-- SUBCENTER 0 -->
|
||||
<model>
|
||||
<name>ecens</name>
|
||||
<name>ecmwfP25</name>
|
||||
<center>98</center>
|
||||
<subcenter>0</subcenter>
|
||||
<grid>360181001</grid>
|
||||
<grid>144072101</grid>
|
||||
<process>
|
||||
<id>141</id>
|
||||
<id>142</id>
|
||||
|
@ -25,34 +25,6 @@
|
|||
</process>
|
||||
</model>
|
||||
|
||||
<model>
|
||||
<name>ecmwf0p25</name>
|
||||
<center>98</center>
|
||||
<subcenter>0</subcenter>
|
||||
<grid>193</grid>
|
||||
<process>
|
||||
<id>141</id>
|
||||
<id>142</id>
|
||||
<id>143</id>
|
||||
<id>144</id>
|
||||
<id>145</id>
|
||||
</process>
|
||||
</model>
|
||||
|
||||
<model>
|
||||
<name>ecmwf0p25wave</name>
|
||||
<center>98</center>
|
||||
<subcenter>0</subcenter>
|
||||
<grid>ECMWF-wave-0p25deg</grid>
|
||||
<process>
|
||||
<id>108</id>
|
||||
<id>109</id>
|
||||
<id>110</id>
|
||||
<id>111</id>
|
||||
<id>112</id>
|
||||
</process>
|
||||
</model>
|
||||
|
||||
<model>
|
||||
<name>ecmwf</name>
|
||||
<center>98</center>
|
||||
|
|
|
@ -19,17 +19,14 @@
|
|||
further_licensing_information.
|
||||
-->
|
||||
<requestPatterns xmlns:ns2="group">
|
||||
<regex>^S(HV|HXX|S[^X]).*</regex>
|
||||
<regex>^S[IMN]W[^KZ].*</regex>
|
||||
<regex>^SIV[A-FJX].*</regex>
|
||||
<regex>^SMUS.*</regex>
|
||||
<regex>^SMCN.*</regex>
|
||||
<regex>^SMMX.*</regex>
|
||||
<regex>^SMV[A-FJX].*</regex>
|
||||
<regex>^SNV[A-FXZ].*</regex>
|
||||
<regex>^SMV[DCE].*</regex>
|
||||
<regex>^SIV[DCE].*</regex>
|
||||
<regex>^SNV[DCE].*</regex>
|
||||
<regex>^SSV[DCE].*</regex>
|
||||
<regex>^SSVX.*</regex>
|
||||
<regex>^SXUS2[0123].*</regex>
|
||||
<regex>^SXUS2[0123] KWNB.*</regex>
|
||||
<regex>^VHVD2[89] KWNB.*</regex>
|
||||
<regex>^Y[HO]XX84.*</regex>
|
||||
</requestPatterns>
|
||||
|
|
|
@ -56,6 +56,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* PluginDataObject.
|
||||
* July 29, 2013 1028 ghull add AwwReportType enum
|
||||
* Feb 11, 2014 2784 rferrel Remove override of setIdentifier.
|
||||
* July 07, 2014 ??? D. Sushon add handling for TORNADO_WATCH in getReportType(..)
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -111,8 +112,12 @@ public class AwwRecord extends PluginDataObject {
|
|||
if (rtStr.equals("THUNDERSTORM_REPORT")) {
|
||||
return SEVERE_THUNDERSTORM_WATCH;
|
||||
}
|
||||
if (rtStr.endsWith("STATUS REPORT")) {
|
||||
if (rtStr.equals("TORNADO_REPORT")) {
|
||||
return TORNADO_WATCH;
|
||||
}
|
||||
if (rtStr.endsWith("STATUS_REPORT")) {
|
||||
// ??? return AwwReportType.SEVERE_WEATHER_STATUS_NOTIFICATION
|
||||
return AwwReportType.STATUS_REPORT;
|
||||
}
|
||||
// WSTM is looking for
|
||||
if (rtStr.equals("WINTER_STORM")) {
|
||||
|
|
|
@ -80,6 +80,8 @@ public class NcSoundingTools {
|
|||
public static float precip_water2(List<NcSoundingLayer2> sndlayers) {
|
||||
float pw = 0;
|
||||
float d1, p1, d2, p2, tot, w1, w2, wbar;
|
||||
if (sndlayers == null || sndlayers.size() <= 0)
|
||||
return 0;
|
||||
// ----- Start with interpolated bottom layer -----
|
||||
// find surface layer or first layer with valid dewpoint
|
||||
int sfcIndex = 0;
|
||||
|
|
|
@ -47,13 +47,15 @@ import java.util.regex.Pattern;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.raytheon.edex.exception.DecoderException;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
|
||||
public class AwwParser {
|
||||
|
||||
private static Logger logger = Logger.getLogger(AwwParser.class.getName());
|
||||
private static Logger logger = Logger.getLogger(AwwParser.class
|
||||
.getCanonicalName());
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -91,14 +93,17 @@ public class AwwParser {
|
|||
record = new AwwRecord();
|
||||
|
||||
String wmoHeader = theMatcher.group(1);
|
||||
if (wmoHeader == null)
|
||||
if (wmoHeader == null) {
|
||||
wmoHeader = "";
|
||||
}
|
||||
String issueOffice = theMatcher.group(2);
|
||||
if (issueOffice == null)
|
||||
if (issueOffice == null) {
|
||||
issueOffice = "";
|
||||
}
|
||||
String designatorBBB = theMatcher.group(5);
|
||||
if (designatorBBB == null)
|
||||
if (designatorBBB == null) {
|
||||
designatorBBB = "";
|
||||
}
|
||||
|
||||
record.setWmoHeader(wmoHeader);
|
||||
record.setIssueOffice(issueOffice);
|
||||
|
@ -112,17 +117,21 @@ public class AwwParser {
|
|||
DataTime dataTime = new DataTime(issueTime);
|
||||
record.setDataTime(dataTime);
|
||||
|
||||
/* set mndTime to record object, if mndTime is NULL, set
|
||||
* mndtimeString to an empty string */
|
||||
/*
|
||||
* set mndTime to record object, if mndTime is NULL, set
|
||||
* mndtimeString to an empty string
|
||||
*/
|
||||
String mndTimeString = "";
|
||||
if (mndTime != null)
|
||||
if (mndTime != null) {
|
||||
TimeUtil.formatCalendar(mndTime);
|
||||
}
|
||||
record.setMndTime(mndTimeString);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
public static String processSevereWeatherStatusEventTrackNumber(String wmoline) {
|
||||
public static String processSevereWeatherStatusEventTrackNumber(
|
||||
String wmoline) {
|
||||
// String severeWeatherStatusStringMatchPattern = "STATUS REPORT ON WW";
|
||||
// final String SEVERE_WEATHER_STATUS_EXP =
|
||||
// "STATUS REPORT ON WW ([0-9]{3})? *\\x0d\\x0d\\x0a";
|
||||
|
@ -138,14 +147,16 @@ public class AwwParser {
|
|||
|
||||
}
|
||||
|
||||
private static boolean isSevereWeatherStatusInfo(String stringInfo, String strPatternToBeSearched) {
|
||||
private static boolean isSevereWeatherStatusInfo(String stringInfo,
|
||||
String strPatternToBeSearched) {
|
||||
boolean isSereveWeatherStatus = false;
|
||||
if (stringInfo.indexOf(strPatternToBeSearched) >= 0)
|
||||
isSereveWeatherStatus = true;
|
||||
return isSereveWeatherStatus;
|
||||
}
|
||||
|
||||
private static String getSevereWeatherStatusEventTrackNumber(String wmoLine, String matchPatternString) {
|
||||
private static String getSevereWeatherStatusEventTrackNumber(
|
||||
String wmoLine, String matchPatternString) {
|
||||
Pattern matchPattern = Pattern.compile(matchPatternString);
|
||||
Matcher theMatcher = matchPattern.matcher(wmoLine);
|
||||
String severeWeatherStatusEventTrackNumber = theMatcher.group(1);
|
||||
|
@ -217,11 +228,13 @@ public class AwwParser {
|
|||
|
||||
if (attnMatcher.find()) {
|
||||
String attentionLine = attnMatcher.group();
|
||||
Scanner sc = new Scanner(attentionLine).useDelimiter("\\x2e\\x2e\\x2e|\\x0d\\x0d\\x0a");
|
||||
Scanner sc = new Scanner(attentionLine)
|
||||
.useDelimiter("\\x2e\\x2e\\x2e|\\x0d\\x0d\\x0a");
|
||||
|
||||
while (sc.hasNext()) {
|
||||
attnToken = sc.next();
|
||||
if (attnToken.length() == 3 && (attnToken.compareTo("WFO") != 0)) {
|
||||
if (attnToken.length() == 3
|
||||
&& (attnToken.compareTo("WFO") != 0)) {
|
||||
attnList.add(attnToken);
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +244,8 @@ public class AwwParser {
|
|||
if (idxAttn == 0) {
|
||||
collectAttn = attnList.get(idxAttn);
|
||||
} else {
|
||||
collectAttn = collectAttn.concat(";").concat(attnList.get(idxAttn));
|
||||
collectAttn = collectAttn.concat(";").concat(
|
||||
attnList.get(idxAttn));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +256,8 @@ public class AwwParser {
|
|||
return collectAttn;
|
||||
}
|
||||
|
||||
public static String processUgcToRetrieveWatchNumberForThunderstormOrTornado(String segment) {
|
||||
public static String processUgcToRetrieveWatchNumberForThunderstormOrTornado(
|
||||
String segment) {
|
||||
String watchNumber = "";
|
||||
// "WW\\s\\d{3}\\sTORNADO\\s([A-Z]{2}\\s)+CW\\s(\\d{6}Z)\\s\\-\\s(\\d{6}Z)"
|
||||
// Pattern used to extract Thunderstorm watch number for WATCH
|
||||
|
@ -254,8 +269,10 @@ public class AwwParser {
|
|||
// (\\d{3})
|
||||
// with
|
||||
// (\\d{1,4}
|
||||
Pattern thunderstormWatchNumberPattern = Pattern.compile(THUNDERSTORM_WATCH_NUMBER_EXP);
|
||||
Matcher thunderstormWatchNumberMatcher = thunderstormWatchNumberPattern.matcher(segment);
|
||||
Pattern thunderstormWatchNumberPattern = Pattern
|
||||
.compile(THUNDERSTORM_WATCH_NUMBER_EXP);
|
||||
Matcher thunderstormWatchNumberMatcher = thunderstormWatchNumberPattern
|
||||
.matcher(segment);
|
||||
|
||||
String THUNDERSTORM_WATCH_NUMBER_EXP2 = "WW\\s(\\d{1,4})\\sSEVERE\\sTSTM"; // T976
|
||||
// -
|
||||
|
@ -263,8 +280,10 @@ public class AwwParser {
|
|||
// (\\d{3})
|
||||
// with
|
||||
// (\\d{1,4}
|
||||
Pattern thunderstormWatchNumberPattern2 = Pattern.compile(THUNDERSTORM_WATCH_NUMBER_EXP2);
|
||||
Matcher thunderstormWatchNumberMatcher2 = thunderstormWatchNumberPattern2.matcher(segment);
|
||||
Pattern thunderstormWatchNumberPattern2 = Pattern
|
||||
.compile(THUNDERSTORM_WATCH_NUMBER_EXP2);
|
||||
Matcher thunderstormWatchNumberMatcher2 = thunderstormWatchNumberPattern2
|
||||
.matcher(segment);
|
||||
|
||||
if (thunderstormWatchNumberMatcher.find()) {
|
||||
watchNumber = thunderstormWatchNumberMatcher.group(1).trim();
|
||||
|
@ -281,8 +300,10 @@ public class AwwParser {
|
|||
// (\\d{3})
|
||||
// with
|
||||
// (\\d{1,4}
|
||||
Pattern tornadoWatchNumberPattern = Pattern.compile(TORNADO_WATCH_NUMBER_EXP);
|
||||
Matcher tornadoWatchNumberMatcher = tornadoWatchNumberPattern.matcher(segment);
|
||||
Pattern tornadoWatchNumberPattern = Pattern
|
||||
.compile(TORNADO_WATCH_NUMBER_EXP);
|
||||
Matcher tornadoWatchNumberMatcher = tornadoWatchNumberPattern
|
||||
.matcher(segment);
|
||||
if (tornadoWatchNumberMatcher.find()) {
|
||||
watchNumber = tornadoWatchNumberMatcher.group(1).trim();
|
||||
// System.out.println("in processUgcToRetrieveWatchNumber - find TORNADO_WATCH_NUMBER="
|
||||
|
@ -310,7 +331,8 @@ public class AwwParser {
|
|||
return watchNmbr;
|
||||
}
|
||||
|
||||
public static String processUgcToRetrieveWatchNumberForStatusReport(String segment) {
|
||||
public static String processUgcToRetrieveWatchNumberForStatusReport(
|
||||
String segment) {
|
||||
String watchNumber = "";
|
||||
String STATUS_REPORT_WATCH_NUMBER_EXP = "STATUS REPORT ON WW\\s(\\d{1,4})"; // T976
|
||||
// -
|
||||
|
@ -318,8 +340,10 @@ public class AwwParser {
|
|||
// (\\d{3})
|
||||
// with
|
||||
// (\\d{1,4}
|
||||
Pattern statusReportWatchNumberPattern = Pattern.compile(STATUS_REPORT_WATCH_NUMBER_EXP);
|
||||
Matcher statusReportWatchNumberMatcher = statusReportWatchNumberPattern.matcher(segment);
|
||||
Pattern statusReportWatchNumberPattern = Pattern
|
||||
.compile(STATUS_REPORT_WATCH_NUMBER_EXP);
|
||||
Matcher statusReportWatchNumberMatcher = statusReportWatchNumberPattern
|
||||
.matcher(segment);
|
||||
if (statusReportWatchNumberMatcher.find()) {
|
||||
watchNumber = statusReportWatchNumberMatcher.group(1).trim();
|
||||
// System.out.println("in processUgcToRetrieveWatchNumber - find STATUS_REPORT_WATCH_NUMBER="
|
||||
|
@ -336,8 +360,10 @@ public class AwwParser {
|
|||
// (\\d{3})
|
||||
// with
|
||||
// (\\d{1,4}
|
||||
Pattern statusReportWatchNumberPattern = Pattern.compile(STATUS_REPORT_WATCH_NUMBER_EXP);
|
||||
Matcher statusReportWatchNumberMatcher = statusReportWatchNumberPattern.matcher(segment);
|
||||
Pattern statusReportWatchNumberPattern = Pattern
|
||||
.compile(STATUS_REPORT_WATCH_NUMBER_EXP);
|
||||
Matcher statusReportWatchNumberMatcher = statusReportWatchNumberPattern
|
||||
.matcher(segment);
|
||||
if (statusReportWatchNumberMatcher.find()) {
|
||||
isSegmentValid = true;
|
||||
}
|
||||
|
@ -357,7 +383,8 @@ public class AwwParser {
|
|||
* The collection of watch numbers
|
||||
* @return a AwwUgc table
|
||||
*/
|
||||
public static AwwUgc processUgc(String ugcline, String segment, Calendar mndTime, ArrayList<String> watchList) {
|
||||
public static AwwUgc processUgc(String ugcline, String segment,
|
||||
Calendar mndTime, ArrayList<String> watchList) {
|
||||
|
||||
final String delim = "\n";
|
||||
String pvtecLine;
|
||||
|
@ -392,7 +419,8 @@ public class AwwParser {
|
|||
// System.out.println("in Ugc - ugcline=" + ugcline);
|
||||
|
||||
if (vtecMatcher.find()) {
|
||||
StringTokenizer vtecToken = new StringTokenizer(vtecMatcher.group(), delim);
|
||||
StringTokenizer vtecToken = new StringTokenizer(
|
||||
vtecMatcher.group(), delim);
|
||||
|
||||
// Each bulletin may have multiple VTEC lines
|
||||
while (vtecToken.hasMoreTokens()) {
|
||||
|
@ -406,8 +434,10 @@ public class AwwParser {
|
|||
}
|
||||
trackingNO.append(trackingNumber);
|
||||
|
||||
/* Store the event tracking number as a primary key in the AWW
|
||||
* record recognized as "watch number" */
|
||||
/*
|
||||
* Store the event tracking number as a primary key in the AWW
|
||||
* record recognized as "watch number"
|
||||
*/
|
||||
if (!watchList.contains(trackingNumber)) {
|
||||
watchList.add(trackingNumber);
|
||||
}
|
||||
|
@ -430,14 +460,18 @@ public class AwwParser {
|
|||
if (latlonMatcher.find()) {
|
||||
|
||||
// New AwwLatlons record to hold LAT/LON values
|
||||
AwwParser.processLatlons(latlonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlons(latlonMatcher.group(), currentUgc,
|
||||
latlonIndex);
|
||||
|
||||
Matcher conlatlonMatcher = conlatlonPattern.matcher(segment);
|
||||
|
||||
/* find the continuation of LAT/LON polygon pairs if any note that
|
||||
* LAT/LON may have more than one line */
|
||||
/*
|
||||
* find the continuation of LAT/LON polygon pairs if any note that
|
||||
* LAT/LON may have more than one line
|
||||
*/
|
||||
if (conlatlonMatcher.find()) {
|
||||
AwwParser.processLatlons(conlatlonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlons(conlatlonMatcher.group(), currentUgc,
|
||||
latlonIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,7 +481,9 @@ public class AwwParser {
|
|||
currentUgc.setEventTrackingNumber(trackingNO.toString());
|
||||
// Replace special characters with a blank; it is more readable and set
|
||||
// the segment
|
||||
currentUgc.setSegment(UtilN.removeLeadingWhiteSpaces(segment.replace('\r', ' ').replace('\003', ' ').replace('\000', ' ').replace('\001', ' ').replace('\036', ' ')));
|
||||
currentUgc.setSegment(UtilN.removeLeadingWhiteSpaces(segment
|
||||
.replace('\r', ' ').replace('\003', ' ').replace('\000', ' ')
|
||||
.replace('\001', ' ').replace('\036', ' ')));
|
||||
|
||||
return currentUgc;
|
||||
|
||||
|
@ -584,7 +620,8 @@ public class AwwParser {
|
|||
* The collection of watch numbers
|
||||
* @return a AwwUgc table
|
||||
*/
|
||||
public static AwwUgc processUgcForWtch(String ugcline, String segment, Calendar mndTime, String issueOfficeId, ArrayList<String> watchList) {
|
||||
public static AwwUgc processUgcForWtch(String ugcline, String segment,
|
||||
Calendar mndTime, String issueOfficeId, ArrayList<String> watchList) {
|
||||
|
||||
final String delim = "\n";
|
||||
String pvtecLine;
|
||||
|
@ -605,7 +642,8 @@ public class AwwParser {
|
|||
final String WTCH_LATLON_EXP = "LAT...LON( (\\d{5}|\\d{4})(\\d{5}|\\d{4}))+", WTCH_CON_LATLON_EXP = "(( )+( (\\d{5}|\\d{4})(\\d{5}|\\d{4}))+\\x0d\\x0d\\x0a)+";
|
||||
// Regular expression for the continuation of LAT/LON polygon
|
||||
final String CON_LATLON_EXP = "(( )+( (\\d{5}|\\d{4}) (\\d{5}|\\d{4}))+\\x0d\\x0d\\x0a)+";
|
||||
final Pattern wtchLatLonPattern = Pattern.compile(WTCH_LATLON_EXP), wtchConLatlonPattern = Pattern.compile(WTCH_CON_LATLON_EXP);
|
||||
final Pattern wtchLatLonPattern = Pattern.compile(WTCH_LATLON_EXP), wtchConLatlonPattern = Pattern
|
||||
.compile(WTCH_CON_LATLON_EXP);
|
||||
// Pattern used to extract LAT/LON line
|
||||
final Pattern latlonPattern = Pattern.compile(LATLON_EXP);
|
||||
|
||||
|
@ -623,10 +661,12 @@ public class AwwParser {
|
|||
Matcher wtchVtecMatcher = wtchVtecPattern.matcher(segment);
|
||||
// System.out.println("in Ugc - ugcline=" + ugcline);
|
||||
if (wtchVtecMatcher.find()) {
|
||||
AwwParser.processVtecWtch(wtchVtecMatcher, issueOfficeId, currentUgc);
|
||||
AwwParser.processVtecWtch(wtchVtecMatcher, issueOfficeId,
|
||||
currentUgc);
|
||||
}
|
||||
if (vtecMatcher.find()) {
|
||||
StringTokenizer vtecToken = new StringTokenizer(vtecMatcher.group(), delim);
|
||||
StringTokenizer vtecToken = new StringTokenizer(
|
||||
vtecMatcher.group(), delim);
|
||||
|
||||
// Each bulletin may have multiple VTEC lines
|
||||
while (vtecToken.hasMoreTokens()) {
|
||||
|
@ -640,8 +680,10 @@ public class AwwParser {
|
|||
}
|
||||
trackingNO.append(trackingNumber);
|
||||
|
||||
/* Store the event tracking number as a primary key in the AWW
|
||||
* record recognized as "watch number" */
|
||||
/*
|
||||
* Store the event tracking number as a primary key in the AWW
|
||||
* record recognized as "watch number"
|
||||
*/
|
||||
if (!watchList.contains(trackingNumber)) {
|
||||
watchList.add(trackingNumber);
|
||||
}
|
||||
|
@ -652,18 +694,14 @@ public class AwwParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (currentUgc.getAwwVtecLine() == null || currentUgc.getAwwVtecLine().size() == 0) // T976
|
||||
// -
|
||||
// If
|
||||
// the
|
||||
// UGC
|
||||
// has
|
||||
// no
|
||||
// VTEC/HVTEC
|
||||
// info,
|
||||
// return
|
||||
// null.
|
||||
if (currentUgc.getAwwVtecLine() == null
|
||||
|| currentUgc.getAwwVtecLine().size() == 0) { // T976 - If the
|
||||
// UGC has no
|
||||
// VTEC/HVTEC
|
||||
// info, return
|
||||
// null.
|
||||
return null;
|
||||
}
|
||||
|
||||
AwwParser.processFips(ugcline, currentUgc, mndTime);
|
||||
|
||||
|
@ -675,22 +713,28 @@ public class AwwParser {
|
|||
if (latlonMatcher.find()) {
|
||||
|
||||
// New AwwLatlons record to hold LAT/LON values
|
||||
AwwParser.processLatlons(latlonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlons(latlonMatcher.group(), currentUgc,
|
||||
latlonIndex);
|
||||
|
||||
Matcher conlatlonMatcher = wtchConLatlonPattern.matcher(segment);
|
||||
|
||||
/* find the continuation of LAT/LON polygon pairs if any note that
|
||||
* LAT/LON may have more than one line */
|
||||
/*
|
||||
* find the continuation of LAT/LON polygon pairs if any note that
|
||||
* LAT/LON may have more than one line
|
||||
*/
|
||||
if (conlatlonMatcher.find()) {
|
||||
AwwParser.processLatlons(conlatlonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlons(conlatlonMatcher.group(), currentUgc,
|
||||
latlonIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (wtchLatLonMatcher.find()) {
|
||||
AwwParser.processLatlonsWtch(wtchLatLonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlonsWtch(wtchLatLonMatcher.group(), currentUgc,
|
||||
latlonIndex);
|
||||
Matcher wtchConlatlonMatcher = conlatlonPattern.matcher(segment);
|
||||
if (wtchConlatlonMatcher.find()) {
|
||||
AwwParser.processLatlonsWtch(wtchConlatlonMatcher.group(), currentUgc, latlonIndex);
|
||||
AwwParser.processLatlonsWtch(wtchConlatlonMatcher.group(),
|
||||
currentUgc, latlonIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,7 +744,9 @@ public class AwwParser {
|
|||
currentUgc.setEventTrackingNumber(trackingNO.toString());
|
||||
// Replace special characters with a blank; it is more readable and set
|
||||
// the segment
|
||||
currentUgc.setSegment(UtilN.removeLeadingWhiteSpaces(segment.replace('\r', ' ').replace('\003', ' ').replace('\000', ' ').replace('\001', ' ').replace('\036', ' ')));
|
||||
currentUgc.setSegment(UtilN.removeLeadingWhiteSpaces(segment
|
||||
.replace('\r', ' ').replace('\003', ' ').replace('\000', ' ')
|
||||
.replace('\001', ' ').replace('\036', ' ')));
|
||||
|
||||
return currentUgc;
|
||||
|
||||
|
@ -777,14 +823,17 @@ public class AwwParser {
|
|||
// endTime = AwwParser.findEventTime(pvtokenMatcher.group(8));
|
||||
// currentVtec.setEventEndTime(endTime);
|
||||
|
||||
/* The follow logic is the modified way of setting the event
|
||||
/*
|
||||
* The follow logic is the modified way of setting the event
|
||||
* start/end times. Basically it tries to look at the previous
|
||||
* records of the same event in DB and fill the missed values */
|
||||
* records of the same event in DB and fill the missed values
|
||||
*/
|
||||
String eventStartTimeString = pvtokenMatcher.group(7);
|
||||
String eventEndTimeString = pvtokenMatcher.group(8);
|
||||
|
||||
AwwVtecDataInfo awwVtecEventTimeInfoObject = getEventTimeInfo(eventStartTimeString, eventEndTimeString, productClass, officeId, phenomena, significance,
|
||||
eventTrackingNumber);
|
||||
AwwVtecDataInfo awwVtecEventTimeInfoObject = getEventTimeInfo(
|
||||
eventStartTimeString, eventEndTimeString, productClass,
|
||||
officeId, phenomena, significance, eventTrackingNumber);
|
||||
|
||||
startTime = awwVtecEventTimeInfoObject.getEventStartTime();
|
||||
currentVtec.setEventStartTime(startTime);
|
||||
|
@ -792,17 +841,25 @@ public class AwwParser {
|
|||
endTime = awwVtecEventTimeInfoObject.getEventEndTime();
|
||||
currentVtec.setEventEndTime(endTime);
|
||||
|
||||
/* Now we add one more logic to try to fill the holes of
|
||||
* eventstarttime is null */
|
||||
if (isEventStartTimeValidToBeUsedToFillNullValues(action, NEW_ACTION_VALUE, awwVtecEventTimeInfoObject.getEventStartTime())) {
|
||||
fillNullEventStartTimeValues(awwVtecEventTimeInfoObject.getEventStartTime(), productClass, officeId, phenomena, significance, eventTrackingNumber);
|
||||
/*
|
||||
* Now we add one more logic to try to fill the holes of
|
||||
* eventstarttime is null
|
||||
*/
|
||||
if (isEventStartTimeValidToBeUsedToFillNullValues(action,
|
||||
NEW_ACTION_VALUE,
|
||||
awwVtecEventTimeInfoObject.getEventStartTime())) {
|
||||
fillNullEventStartTimeValues(
|
||||
awwVtecEventTimeInfoObject.getEventStartTime(),
|
||||
productClass, officeId, phenomena, significance,
|
||||
eventTrackingNumber);
|
||||
}
|
||||
|
||||
// Check if any H-VTEC line after the P-VTEC line
|
||||
Matcher hvtokenMatcher = hvtokenPattern.matcher(segment);
|
||||
|
||||
if (hvtokenMatcher.find()) {
|
||||
AwwHVtec currentHVtec = AwwParser.processHVtec(hvtokenMatcher.group());
|
||||
AwwHVtec currentHVtec = AwwParser.processHVtec(hvtokenMatcher
|
||||
.group());
|
||||
|
||||
// Add current H-VTEC message to set.
|
||||
currentVtec.addAwwHVtecLine(currentHVtec);
|
||||
|
@ -821,7 +878,8 @@ public class AwwParser {
|
|||
* @param eventStartTime
|
||||
* @return
|
||||
*/
|
||||
private static boolean isEventStartTimeValidToBeUsedToFillNullValues(String action, String newActionValue, Calendar eventStartTime) {
|
||||
private static boolean isEventStartTimeValidToBeUsedToFillNullValues(
|
||||
String action, String newActionValue, Calendar eventStartTime) {
|
||||
boolean isValid = false;
|
||||
if (newActionValue.equalsIgnoreCase(action) && eventStartTime != null) {
|
||||
isValid = true;
|
||||
|
@ -841,25 +899,36 @@ public class AwwParser {
|
|||
* @param eventTrackingNumber
|
||||
* @return
|
||||
*/
|
||||
private static AwwVtecDataInfo getEventTimeInfo(String eventStartTimeString, String eventEndTimeString, String productClass, String officeId, String phenomena,
|
||||
private static AwwVtecDataInfo getEventTimeInfo(
|
||||
String eventStartTimeString, String eventEndTimeString,
|
||||
String productClass, String officeId, String phenomena,
|
||||
String significance, String eventTrackingNumber) {
|
||||
AwwVtecDataInfo awwVtecDataInfo = new AwwVtecDataInfo();
|
||||
Calendar eventStartTime = AwwParser.findEventTime(eventStartTimeString);
|
||||
Calendar eventEndTime = AwwParser.findEventTime(eventEndTimeString);
|
||||
if (eventStartTime != null)
|
||||
if (eventStartTime != null) {
|
||||
awwVtecDataInfo.setEventStartTime(eventStartTime);
|
||||
if (eventEndTime != null)
|
||||
}
|
||||
if (eventEndTime != null) {
|
||||
awwVtecDataInfo.setEventEndTime(eventEndTime);
|
||||
awwVtecDataInfo = AwwVtecDataUtil.populateAwwVtecEventTimeInfo(awwVtecDataInfo, productClass, officeId, phenomena, significance, eventTrackingNumber);
|
||||
}
|
||||
awwVtecDataInfo = AwwVtecDataUtil.populateAwwVtecEventTimeInfo(
|
||||
awwVtecDataInfo, productClass, officeId, phenomena,
|
||||
significance, eventTrackingNumber);
|
||||
return awwVtecDataInfo;
|
||||
}
|
||||
|
||||
private static void fillNullEventStartTimeValues(Calendar eventStartTime, String productClass, String officeId, String phenomena, String significance,
|
||||
String eventTrackingNumber) {
|
||||
private static void fillNullEventStartTimeValues(Calendar eventStartTime,
|
||||
String productClass, String officeId, String phenomena,
|
||||
String significance, String eventTrackingNumber) {
|
||||
try {
|
||||
AwwVtecDataUtil.populateAwwVtecEventStartTimeWithValidValue(eventStartTime, productClass, officeId, phenomena, significance, eventTrackingNumber);
|
||||
AwwVtecDataUtil.populateAwwVtecEventStartTimeWithValidValue(
|
||||
eventStartTime, productClass, officeId, phenomena,
|
||||
significance, eventTrackingNumber);
|
||||
} catch (DataAccessLayerException dale) {
|
||||
System.out.println("======Caught DataAccessLayerException in method fillNullEventStartTimeValues(...), error=" + dale.getMessage());
|
||||
System.out
|
||||
.println("======Caught DataAccessLayerException in method fillNullEventStartTimeValues(...), error="
|
||||
+ dale.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,7 +966,8 @@ public class AwwParser {
|
|||
* The index of Lat/Long
|
||||
*
|
||||
*/
|
||||
public static void processLatlons(String latlons, AwwUgc UGC, int[] latlonIndex) {
|
||||
public static void processLatlons(String latlons, AwwUgc UGC,
|
||||
int[] latlonIndex) {
|
||||
|
||||
String currentToken = null;
|
||||
String latlon = "LAT...LON";
|
||||
|
@ -919,7 +989,9 @@ public class AwwParser {
|
|||
// New AwwLatlons record to hold LAT/LON values.
|
||||
flat = (float) (Integer.parseInt(latitude) / 100.0);
|
||||
flong = (float) ((Integer.parseInt(longitude) / 100.0) * (-1.0));
|
||||
AwwLatlons currentLatlons = AwwParser.setLatlon(flat, flong, latlonIndex[0]);
|
||||
|
||||
AwwLatlons currentLatlons = AwwParser.setLatlon(flat,
|
||||
flong, latlonIndex[0]);
|
||||
|
||||
// Add current LAT/LON and index to set.
|
||||
UGC.addAwwLatLon(currentLatlons);
|
||||
|
@ -950,7 +1022,8 @@ public class AwwParser {
|
|||
final String delim = "-,\n";
|
||||
final String inclusiveDelim = ">";
|
||||
|
||||
/* Here are many possible cases: 1. PAC055-057-140130- 2.
|
||||
/*
|
||||
* Here are many possible cases: 1. PAC055-057-140130- 2.
|
||||
* ILZ027>031-036>038-040>045-047>054-061-141015- 3.
|
||||
* LAC001-003-009-011-019-023-039-045-053-055-079-097-099-101-113-^M
|
||||
* 115-131500-^M 4. ILC129-221523- 5.
|
||||
|
@ -959,13 +1032,15 @@ public class AwwParser {
|
|||
* KYC001-003-005-009-015-017-021-023-027-029-031-037-041-045-049-^M
|
||||
* 053-057-061-067-073-077-079-081-085-087-093-097-099-103-111-113-^M
|
||||
* 117-123-137-141-151-155-161-163-167-169-171-179-181-185-187-191-^M
|
||||
* 201-207-209-211-213-215-217-223-227-229-239-190900-^M */
|
||||
* 201-207-209-211-213-215-217-223-227-229-239-190900-^M
|
||||
*/
|
||||
StringTokenizer fipsTokens = new StringTokenizer(ugc, delim);
|
||||
while (fipsTokens.hasMoreTokens()) {
|
||||
|
||||
fipsToken = fipsTokens.nextToken();
|
||||
|
||||
if (fipsToken.length() == 6 && Character.isLetter(fipsToken.toCharArray()[0])) {
|
||||
if (fipsToken.length() == 6
|
||||
&& Character.isLetter(fipsToken.toCharArray()[0])) {
|
||||
// A brand new county FIPS with format NAMDDD
|
||||
countyFips = fipsToken;
|
||||
county = fipsToken.substring(0, 3);
|
||||
|
@ -977,7 +1052,8 @@ public class AwwParser {
|
|||
county = fipsToken.substring(0, 3);
|
||||
|
||||
// Format in NAMDDD1>DDD2
|
||||
StringTokenizer twoTokens = new StringTokenizer(intervalToken, inclusiveDelim);
|
||||
StringTokenizer twoTokens = new StringTokenizer(intervalToken,
|
||||
inclusiveDelim);
|
||||
String firstToken = twoTokens.nextToken();
|
||||
String secondToken = twoTokens.nextToken();
|
||||
|
||||
|
@ -1002,15 +1078,18 @@ public class AwwParser {
|
|||
AwwFips currentFips = AwwFips.setFIPS(countyFips);
|
||||
UGC.addAwwFIPS(currentFips);
|
||||
}
|
||||
} else if (fipsToken.length() == 3 && Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
} else if (fipsToken.length() == 3
|
||||
&& Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
// A continuation of previous county FIPS with format DDD
|
||||
countyFips = county.concat(fipsToken);
|
||||
|
||||
AwwFips currentFips = AwwFips.setFIPS(countyFips);
|
||||
UGC.addAwwFIPS(currentFips);
|
||||
} else if (fipsToken.length() == 7 && Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
} else if (fipsToken.length() == 7
|
||||
&& Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
// A continuation of previous county FIPS with format DDD1>DDD2
|
||||
StringTokenizer twoTokens = new StringTokenizer(fipsToken, inclusiveDelim);
|
||||
StringTokenizer twoTokens = new StringTokenizer(fipsToken,
|
||||
inclusiveDelim);
|
||||
String firstToken = twoTokens.nextToken();
|
||||
String secondToken = twoTokens.nextToken();
|
||||
|
||||
|
@ -1035,7 +1114,8 @@ public class AwwParser {
|
|||
AwwFips currentFips = AwwFips.setFIPS(countyFips);
|
||||
UGC.addAwwFIPS(currentFips);
|
||||
}
|
||||
} else if (fipsToken.length() == 6 && Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
} else if (fipsToken.length() == 6
|
||||
&& Character.isDigit(fipsToken.toCharArray()[0])) {
|
||||
// The last item is the UGC product purge time
|
||||
try {
|
||||
Calendar purgeDate = UtilN.findDataTime(fipsToken, mndTime);
|
||||
|
@ -1118,7 +1198,8 @@ public class AwwParser {
|
|||
*/
|
||||
public static String getReportType(String bull) {
|
||||
|
||||
/* There are many report types as follows: 1. SEVERE THUNDERSTORM
|
||||
/*
|
||||
* There are many report types as follows: 1. SEVERE THUNDERSTORM
|
||||
* WARNING 2. SEVERE THUNDERSTORM WATCH 3. TORNADO WARNING 4. TORNADO
|
||||
* WATCH 5. SEVERE THUNDERSTORM OUTLINE UPDATE 6. TORNADO WATCH OUTLINE
|
||||
* UPDATE 7. FLASH FLOOD WARNING 8. FLASH FLOOD WATCH 9. FLOOD WARNING
|
||||
|
@ -1129,15 +1210,18 @@ public class AwwParser {
|
|||
* WEATHER ADVISORY 23. SIGNIGICANT WEATHER ADVISORY 24. SPECIAL WEATHER
|
||||
* STATEMENT 25. RED FLAG WARNING 26. TORNADO REPORT 27. HIGH WIND
|
||||
* WARNING 28. FREEZE WARNING 29. ADVERTENCIA DE INUNDACIONES 30.
|
||||
* HYDROLOGIC STATEMENT 31. URGENT WEATHER MESSAGE */
|
||||
* HYDROLOGIC STATEMENT 31. URGENT WEATHER MESSAGE
|
||||
*/
|
||||
|
||||
String reportType = null;
|
||||
|
||||
// Regular expression for report type
|
||||
// final String REPORT_EXP =
|
||||
// "(SEVERE THUNDERSTORM|TORNADO|FLOOD|WINTER STORM|WATCH COUNTY NOTIFICATION|ADVISORY|WEATHER STATEMENT|RED FLAG WARNING)";
|
||||
/* add the key words "STATUS REPORT" at the beginning of the regular
|
||||
* expression string pattern */
|
||||
/*
|
||||
* add the key words "STATUS REPORT" at the beginning of the regular
|
||||
* expression string pattern
|
||||
*/
|
||||
final String REPORT_EXP = "(STATUS REPORT|SEVERE THUNDERSTORM|SEVERE TSTM|TORNADO|FLOOD|WINTER STORM|WATCH COUNTY NOTIFICATION|ADVISORY|WEATHER STATEMENT|RED FLAG WARNING)";
|
||||
|
||||
// Pattern used for extracting data from the report type
|
||||
|
@ -1149,7 +1233,8 @@ public class AwwParser {
|
|||
String type = reportMatcher.group(1);
|
||||
if (type.compareTo("STATUS REPORT") == 0) {
|
||||
reportType = getStatusReportType(bull);
|
||||
} else if (type.compareTo("SEVERE THUNDERSTORM") == 0 || type.compareTo("SEVERE TSTM") == 0) {
|
||||
} else if (type.compareTo("SEVERE THUNDERSTORM") == 0
|
||||
|| type.compareTo("SEVERE TSTM") == 0) {
|
||||
reportType = getThunderstormType(bull);
|
||||
} else if (type.compareTo("TORNADO") == 0) {
|
||||
reportType = getTornadoType(bull);
|
||||
|
@ -1171,7 +1256,8 @@ public class AwwParser {
|
|||
}
|
||||
|
||||
if (AwwReportType.getReportType(reportType) == AwwReportType.UNKNOWN_AWW_REPORT_TYPE) {
|
||||
logger.warn("Warning: decoded aww report type, " + reportType + ", not recogized.");
|
||||
logger.warn("Warning: decoded aww report type, " + reportType
|
||||
+ ", not recogized.");
|
||||
}
|
||||
|
||||
return reportType;
|
||||
|
@ -1314,7 +1400,8 @@ public class AwwParser {
|
|||
Matcher reportMatcher = reportPattern.matcher(bull);
|
||||
|
||||
if (reportMatcher.find()) {
|
||||
weatherstatementType = reportMatcher.group(1).concat(weatherstatementType);
|
||||
weatherstatementType = reportMatcher.group(1).concat(
|
||||
weatherstatementType);
|
||||
}
|
||||
return weatherstatementType;
|
||||
}
|
||||
|
@ -1359,14 +1446,15 @@ public class AwwParser {
|
|||
// ---------------------------------Ticket 456:
|
||||
public static final String WTCH_BOX_UGC_LINE = "";
|
||||
|
||||
public static void processLatlonsWtch(String latlons, AwwUgc UGC, int[] latlonIndex) {
|
||||
public static void processLatlonsWtch(String latlons, AwwUgc UGC,
|
||||
int[] latlonIndex) {
|
||||
|
||||
String currentToken = null;
|
||||
String latlon = "LAT...LON";
|
||||
String latitude = null;
|
||||
String longitude = null;
|
||||
boolean pair = false;
|
||||
Float flat, flong;
|
||||
Float flat, flong, flongTmp;
|
||||
|
||||
StringTokenizer latlonTokens = new StringTokenizer(latlons);
|
||||
|
||||
|
@ -1378,13 +1466,43 @@ public class AwwParser {
|
|||
longitude = currentToken.substring(4);
|
||||
|
||||
flat = (float) (Integer.parseInt(latitude) / 100.0);
|
||||
flong = (float) ((Integer.parseInt(longitude) / 100.0) * (-1.0));
|
||||
flongTmp = (float) ((Integer.parseInt(longitude) / 100.0) * (-1.0));
|
||||
|
||||
if (-62.0f < flongTmp) { // now -40.0f W, was -62.0f W
|
||||
// this is one solution for WATCH
|
||||
// decoding, however it may be possible
|
||||
// that LAT's LSB is really hiding the
|
||||
// missing 100, an ATBD-type document
|
||||
// for WATCH should be investigated, or
|
||||
// deep-dive GEMPAK's wwdcod.f +
|
||||
// nwxp_wwcrnr.c
|
||||
flongTmp = flongTmp - (100.0f);
|
||||
|
||||
if (-180.00f > flongTmp) { // always false unless some
|
||||
// unforeseen critical JVM or
|
||||
// hardware-level error occurs &
|
||||
// processing does not halt..
|
||||
Float ferror = flongTmp;
|
||||
// flongTmp = -180.00f; // keep both ends checked & warn
|
||||
// flongTmp = flongTmp + (-62.0f);
|
||||
flongTmp = flongTmp + (0);
|
||||
logger.warn(ferror// TODO keep?
|
||||
+ " longitude beyond -180.00 maximum?",
|
||||
new DecoderException(ferror
|
||||
+ " longitude beyond -180.00 maximum"));
|
||||
}
|
||||
}
|
||||
|
||||
flong = flongTmp;
|
||||
|
||||
latlonIndex[0]++;
|
||||
|
||||
AwwLatlons currentLatlons = AwwParser.setLatlon(flat, flong, latlonIndex[0]);
|
||||
AwwLatlons currentLatlons = AwwParser.setLatlon(flat, flong,
|
||||
latlonIndex[0]);
|
||||
UGC.addAwwLatLon(currentLatlons);
|
||||
|
||||
/* if ( pair ) { longitude = currentToken; latlonIndex[0]++;
|
||||
/*
|
||||
* if ( pair ) { longitude = currentToken; latlonIndex[0]++;
|
||||
* pair = false;
|
||||
*
|
||||
* // New AwwLatlons record to hold LAT/LON values. flat =
|
||||
|
@ -1395,13 +1513,15 @@ public class AwwParser {
|
|||
*
|
||||
* // Add current LAT/LON and index to set.
|
||||
* UGC.addAwwLatLon(currentLatlons); } else { latitude =
|
||||
* currentToken; pair = true; } */
|
||||
* currentToken; pair = true; }
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static AwwVtec processVtectForSevereWeatherStatus(String wmoline, Calendar recordIssueTime, String issueOfficeId) {
|
||||
public static AwwVtec processVtectForSevereWeatherStatus(String wmoline,
|
||||
Calendar recordIssueTime, String issueOfficeId) {
|
||||
// STATUS REPORT ON WW 865^M
|
||||
//
|
||||
// SEVERE WEATHER THREAT CONTINUES RIGHT OF A LINE FROM 50 E JAX TO^M
|
||||
|
@ -1410,7 +1530,8 @@ public class AwwParser {
|
|||
AwwVtec awwVtec = new AwwVtec();
|
||||
final String TRACK_NUMBER_VTEC_EXP = "STATUS REPORT ON WW\\s(\\d{3}\\s)"; // (\\d{6}
|
||||
// Pattern used to extract track number for VTEC
|
||||
final Pattern trackNumberPattern = Pattern.compile(TRACK_NUMBER_VTEC_EXP);
|
||||
final Pattern trackNumberPattern = Pattern
|
||||
.compile(TRACK_NUMBER_VTEC_EXP);
|
||||
Matcher trackNumberMatcher = trackNumberPattern.matcher(wmoline);
|
||||
if (trackNumberMatcher.find()) {
|
||||
String eventTrackingNumber = trackNumberMatcher.group(1).trim();
|
||||
|
@ -1420,16 +1541,20 @@ public class AwwParser {
|
|||
}
|
||||
|
||||
String SEVERE_WEATHER_THREAT_LINE_EXP = "SEVERE WEATHER THREAT CONTINUES RIGHT OF A LINE FROM\\s((\\w|\\s)*).";
|
||||
Pattern severeWeatherThreatLinePattern = Pattern.compile(SEVERE_WEATHER_THREAT_LINE_EXP);
|
||||
Matcher severeWeatherThreatLineMatcher = severeWeatherThreatLinePattern.matcher(wmoline);
|
||||
Pattern severeWeatherThreatLinePattern = Pattern
|
||||
.compile(SEVERE_WEATHER_THREAT_LINE_EXP);
|
||||
Matcher severeWeatherThreatLineMatcher = severeWeatherThreatLinePattern
|
||||
.matcher(wmoline);
|
||||
if (severeWeatherThreatLineMatcher.find()) {
|
||||
// String group = severeWeatherThreatLineMatcher.group();
|
||||
String severeWeatherThreatLine = severeWeatherThreatLineMatcher.group(1);
|
||||
String severeWeatherThreatLine = severeWeatherThreatLineMatcher
|
||||
.group(1);
|
||||
// System.out.println("====, line info parser value group = " +
|
||||
// group);
|
||||
// System.out.println("====, line info parser value severeWeatherThreatLine = "
|
||||
// + severeWeatherThreatLine);
|
||||
String vtecLine = severeWeatherThreatLine.replace("\t", " ").replace("\r", " ").replace("\n", " ");
|
||||
String vtecLine = severeWeatherThreatLine.replace("\t", " ")
|
||||
.replace("\r", " ").replace("\n", " ");
|
||||
// System.out.println("====, vtecLine = " + vtecLine);
|
||||
awwVtec.setVtecLine(vtecLine);
|
||||
}
|
||||
|
@ -1439,11 +1564,14 @@ public class AwwParser {
|
|||
// awwVtec.setEventStartTime(recordIssueTime);
|
||||
|
||||
String SEVERE_WEATHER_THREAT_EVENT_END_TIME_EXP = "WW-[a-zA-Z]\\s(\\d{6})\\s";
|
||||
Pattern severeWeatherThreatEventEndTimePattern = Pattern.compile(SEVERE_WEATHER_THREAT_EVENT_END_TIME_EXP);
|
||||
Matcher severeWeatherThreatEventEndTimeMatcher = severeWeatherThreatEventEndTimePattern.matcher(wmoline);
|
||||
Pattern severeWeatherThreatEventEndTimePattern = Pattern
|
||||
.compile(SEVERE_WEATHER_THREAT_EVENT_END_TIME_EXP);
|
||||
Matcher severeWeatherThreatEventEndTimeMatcher = severeWeatherThreatEventEndTimePattern
|
||||
.matcher(wmoline);
|
||||
String severeWeatherThreatEventEndTimeString = null;
|
||||
if (severeWeatherThreatEventEndTimeMatcher.find()) {
|
||||
severeWeatherThreatEventEndTimeString = severeWeatherThreatEventEndTimeMatcher.group(1);
|
||||
severeWeatherThreatEventEndTimeString = severeWeatherThreatEventEndTimeMatcher
|
||||
.group(1);
|
||||
// Calendar severeWeatherThreatEventEndTime =
|
||||
// convertStringToCalendar(severeWeatherThreatEventEndTimeString);
|
||||
// if(severeWeatherThreatEventEndTime != null)
|
||||
|
@ -1451,29 +1579,36 @@ public class AwwParser {
|
|||
}
|
||||
|
||||
String SEVERE_WEATHER_THREAT_MONTH_DAY_YEAR_EXP = "..(\\d{2}/\\d{2}/\\d{2})\\s";
|
||||
Pattern severeWeatherThreatMonthDayYearPattern = Pattern.compile(SEVERE_WEATHER_THREAT_MONTH_DAY_YEAR_EXP);
|
||||
Matcher severeWeatherThreatMonthDayYearMatcher = severeWeatherThreatMonthDayYearPattern.matcher(wmoline);
|
||||
Pattern severeWeatherThreatMonthDayYearPattern = Pattern
|
||||
.compile(SEVERE_WEATHER_THREAT_MONTH_DAY_YEAR_EXP);
|
||||
Matcher severeWeatherThreatMonthDayYearMatcher = severeWeatherThreatMonthDayYearPattern
|
||||
.matcher(wmoline);
|
||||
String monthString = null;
|
||||
String yearString = null;
|
||||
if (severeWeatherThreatMonthDayYearMatcher.find()) {
|
||||
String monthDayYearString = severeWeatherThreatMonthDayYearMatcher.group(1);
|
||||
String monthDayYearString = severeWeatherThreatMonthDayYearMatcher
|
||||
.group(1);
|
||||
String[] monthDayYearStringArray = monthDayYearString.split("/");
|
||||
monthString = monthDayYearStringArray[0];
|
||||
// String dayString = monthDayYearStringArray[1];
|
||||
yearString = monthDayYearStringArray[2];
|
||||
}
|
||||
|
||||
Calendar severeWeatherThreatEventStartTime = addMonthAndYearValueToCalendar(recordIssueTime, monthString, yearString);
|
||||
Calendar severeWeatherThreatEventStartTime = addMonthAndYearValueToCalendar(
|
||||
recordIssueTime, monthString, yearString);
|
||||
awwVtec.setEventStartTime(severeWeatherThreatEventStartTime);
|
||||
|
||||
Calendar severeWeatherThreatEventEndTime = convertStringToCalendar(severeWeatherThreatEventEndTimeString, monthString, yearString);
|
||||
if (severeWeatherThreatEventEndTime != null)
|
||||
Calendar severeWeatherThreatEventEndTime = convertStringToCalendar(
|
||||
severeWeatherThreatEventEndTimeString, monthString, yearString);
|
||||
if (severeWeatherThreatEventEndTime != null) {
|
||||
awwVtec.setEventEndTime(severeWeatherThreatEventEndTime);
|
||||
}
|
||||
|
||||
return awwVtec;
|
||||
}
|
||||
|
||||
public static void processVtecWtch(Matcher wtchVtecMatcher, String issueOfficeId, AwwUgc awwugc) {
|
||||
public static void processVtecWtch(Matcher wtchVtecMatcher,
|
||||
String issueOfficeId, AwwUgc awwugc) {
|
||||
|
||||
// WW 865 TORNADO FL GA CW 100825Z - 101700Z
|
||||
// WW 893 SEVERE TSTM AR OK TX 202140Z - 210500Z
|
||||
|
@ -1502,7 +1637,8 @@ public class AwwParser {
|
|||
|
||||
}
|
||||
|
||||
public static void processVtecWtch2(String wtchLine, String issueOfficeId, AwwUgc awwugc) {
|
||||
public static void processVtecWtch2(String wtchLine, String issueOfficeId,
|
||||
AwwUgc awwugc) {
|
||||
|
||||
// WW 865 TORNADO FL GA CW 100825Z - 101700Z
|
||||
|
||||
|
@ -1531,9 +1667,12 @@ public class AwwParser {
|
|||
|
||||
}
|
||||
|
||||
/* timeString is in format: e.g. 101102, 10 - day in the month, 11 - Hour of
|
||||
* Day, 02 - minute */
|
||||
public static Calendar addMonthAndYearValueToCalendar(Calendar calendar, String monthString, String yearString) {
|
||||
/*
|
||||
* timeString is in format: e.g. 101102, 10 - day in the month, 11 - Hour of
|
||||
* Day, 02 - minute
|
||||
*/
|
||||
public static Calendar addMonthAndYearValueToCalendar(Calendar calendar,
|
||||
String monthString, String yearString) {
|
||||
|
||||
if (calendar != null) {
|
||||
/* set up the month value */
|
||||
|
@ -1555,9 +1694,12 @@ public class AwwParser {
|
|||
return calendar;
|
||||
}
|
||||
|
||||
/* timeString is in format: e.g. 101102, 10 - day in the month, 11 - Hour of
|
||||
* Day, 02 - minute */
|
||||
public static Calendar convertStringToCalendar(String timeString, String monthString, String yearString) {
|
||||
/*
|
||||
* timeString is in format: e.g. 101102, 10 - day in the month, 11 - Hour of
|
||||
* Day, 02 - minute
|
||||
*/
|
||||
public static Calendar convertStringToCalendar(String timeString,
|
||||
String monthString, String yearString) {
|
||||
|
||||
final String zeroTimePattern = "000000T0000";
|
||||
Calendar calendar = null;
|
||||
|
@ -1601,8 +1743,9 @@ public class AwwParser {
|
|||
if (!isStringEmpty(monthString)) {
|
||||
try {
|
||||
int monthInInteger = Integer.parseInt(monthString);
|
||||
if (monthInInteger > 0 && monthInInteger < 13)
|
||||
if (monthInInteger > 0 && monthInInteger < 13) {
|
||||
isMonthValueValid = true;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -1615,12 +1758,15 @@ public class AwwParser {
|
|||
if (!isStringEmpty(yearString)) {
|
||||
try {
|
||||
int yearInInteger = Integer.parseInt(yearString);
|
||||
/* The assumption is users may use either 4 digits or 2 dogits
|
||||
* to represent the value of the year */
|
||||
/*
|
||||
* The assumption is users may use either 4 digits or 2 dogits
|
||||
* to represent the value of the year
|
||||
*/
|
||||
// if((yearInInteger > 1900 && yearInInteger < 2150) ||
|
||||
// (yearInInteger >= 0 && yearInInteger < 100))
|
||||
if (yearInInteger >= 0 && yearInInteger < 100)
|
||||
// (yearInInteger >= 0 && yearInInteger < 100)){
|
||||
if (yearInInteger >= 0 && yearInInteger < 100) {
|
||||
isYearValueValid = true;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -1630,8 +1776,9 @@ public class AwwParser {
|
|||
|
||||
private static boolean isStringEmpty(String str) {
|
||||
boolean isStringEmpty = true;
|
||||
if (str != null && str.trim().length() != 0)
|
||||
if (str != null && str.trim().length() != 0) {
|
||||
isStringEmpty = false;
|
||||
}
|
||||
return isStringEmpty;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
|||
* 11/2011 Q. Zhou Handle multi-record for stationId, eliminate
|
||||
* number-id if there is a non-number-id.
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* 09/02/2014 Chin Chen fix surface height missing on some stations issue
|
||||
* </pre>
|
||||
*
|
||||
* This code has been developed by the SIB for use in the AWIPS2 system.
|
||||
|
@ -75,12 +76,12 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
* The wmo index
|
||||
* @return The obs station with the specified wmo index
|
||||
*/
|
||||
public ObStation getStationInfo(Integer wmoIndex) {
|
||||
private ObStation getStationInfo(Integer wmoIndex) {
|
||||
ObStation station = null;
|
||||
|
||||
List<?> obs = null;
|
||||
ObStationDao dao = new ObStationDao();
|
||||
if (dao != null) {
|
||||
List<?> obs = null;
|
||||
|
||||
try {
|
||||
obs = dao
|
||||
.queryBySingleCriteria("wmoIndex", wmoIndex.toString());
|
||||
|
@ -108,6 +109,23 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
}
|
||||
|
||||
}
|
||||
// Chin: sfcElevSolution
|
||||
if (station != null && station.getElevation() != null
|
||||
&& station.getElevation().intValue() < 0) {
|
||||
boolean uElev = false;
|
||||
for (int i = 0; i < obs.size(); i++) {
|
||||
ObStation stationTemp = ((ObStation) obs.get(i));
|
||||
if (stationTemp.getUpperAirElevation() != null
|
||||
&& stationTemp.getUpperAirElevation() >= 0) {
|
||||
station.setElevation(stationTemp.getUpperAirElevation());
|
||||
uElev = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uElev == false)
|
||||
station.setElevation(0);
|
||||
}
|
||||
// Chin: sfcElevSolution end
|
||||
return station;
|
||||
}
|
||||
|
||||
|
@ -200,9 +218,10 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
Double lon = station.getGeometry().getX();
|
||||
obsLoc.assignLocation(lat, lon);
|
||||
Integer elev = station.getElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
}
|
||||
// Chin: sfcElevSolution
|
||||
// if (elev == null) {
|
||||
// elev = -9999;
|
||||
// }
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
} else if (station.getUpperAirGeometry() != null) {
|
||||
|
@ -211,7 +230,7 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
obsLoc.assignLocation(lat, lon);
|
||||
Integer elev = station.getUpperAirElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
elev = 0; // Chin: sfcElevSolution-9999;
|
||||
}
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
|
@ -281,9 +300,10 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
obsLoc.assignLocation(NcUairShipMobile.getXlat(),
|
||||
NcUairShipMobile.getXlon());
|
||||
Integer elev = NcUairShipMobile.getElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
}
|
||||
// Chin: sfcElevSolution
|
||||
// if (elev == null) {
|
||||
// elev = -9999;
|
||||
// }
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
record.setStnum(NcUairShipMobile.getStationNumber());
|
||||
|
@ -433,9 +453,10 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
Double lon = station.getGeometry().getX();
|
||||
obsLoc.assignLocation(lat, lon);
|
||||
Integer elev = station.getElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
}
|
||||
// Chin: sfcElevSolution
|
||||
// if (elev == null) {
|
||||
// elev = -9999;
|
||||
// }
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
} else if (station.getUpperAirGeometry() != null) {
|
||||
|
@ -444,7 +465,7 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
obsLoc.assignLocation(lat, lon);
|
||||
Integer elev = station.getUpperAirElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
elev = 0; // Chin: sfcElevSolution
|
||||
}
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
|
@ -519,9 +540,10 @@ public class NcUairDecoder extends AbstractDecoder {
|
|||
obsLoc.assignLocation(NcUairShipMobile.getXlat(),
|
||||
NcUairShipMobile.getXlon());
|
||||
Integer elev = NcUairShipMobile.getElevation();
|
||||
if (elev == null) {
|
||||
elev = -9999;
|
||||
}
|
||||
// Chin: sfcElevSolution
|
||||
// if (elev == null) {
|
||||
// elev = -9999;
|
||||
// }
|
||||
obsLoc.setElevation(elev);
|
||||
record.setLocation(obsLoc);
|
||||
record.setStnum(NcUairShipMobile.getStationNumber());
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* 03/2010 210 L. Lin Initial coding
|
||||
* 09/2011 457 S. Gurung Renamed H5 to Nc and h5 to nc
|
||||
* 09/02/2014 Chin Chen fix surface height missing on some stations issue
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -19,328 +20,346 @@
|
|||
|
||||
package gov.noaa.nws.ncep.edex.plugin.ncuair.util;
|
||||
|
||||
import gov.noaa.nws.ncep.edex.util.UtilN;
|
||||
import gov.noaa.nws.ncep.common.tools.IDecoderConstantsN;
|
||||
import gov.noaa.nws.ncep.edex.util.UtilN;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class NcUairShipMobile {
|
||||
|
||||
private static float xlat;
|
||||
|
||||
private static float xlon;
|
||||
|
||||
private static String stnId;
|
||||
|
||||
private static String codeMessage;
|
||||
|
||||
private static String obsUTC;
|
||||
|
||||
private static String UTC;
|
||||
|
||||
private static int iutc;
|
||||
|
||||
private static String stationNumber;
|
||||
|
||||
private static int surfaceHeight;
|
||||
|
||||
private static int elevation;
|
||||
|
||||
private static Calendar obsTime;
|
||||
|
||||
private static Calendar synopticTime;
|
||||
|
||||
private static int topwind;
|
||||
|
||||
private static Boolean windKnot;
|
||||
|
||||
public static float getXlat() {
|
||||
return xlat;
|
||||
}
|
||||
private static float xlat;
|
||||
|
||||
public static void setXlat(float xlat) {
|
||||
NcUairShipMobile.xlat = xlat;
|
||||
}
|
||||
private static float xlon;
|
||||
|
||||
public static float getXlon() {
|
||||
return xlon;
|
||||
}
|
||||
private static String stnId;
|
||||
|
||||
public static void setXlon(float xlon) {
|
||||
NcUairShipMobile.xlon = xlon;
|
||||
}
|
||||
private static String codeMessage;
|
||||
|
||||
public static String getStnId() {
|
||||
return stnId;
|
||||
}
|
||||
private static String obsUTC;
|
||||
|
||||
public static void setStnId(String stnId) {
|
||||
NcUairShipMobile.stnId = stnId;
|
||||
}
|
||||
private static String UTC;
|
||||
|
||||
public static String getCodeMessage() {
|
||||
return codeMessage;
|
||||
}
|
||||
private static int iutc;
|
||||
|
||||
public static void setCodeMessage(String codeMessage) {
|
||||
NcUairShipMobile.codeMessage = codeMessage;
|
||||
}
|
||||
private static String stationNumber;
|
||||
|
||||
public static String getUTC() {
|
||||
return UTC;
|
||||
}
|
||||
private static int surfaceHeight;
|
||||
|
||||
public static void setUTC(String utc) {
|
||||
UTC = utc;
|
||||
}
|
||||
private static int elevation;
|
||||
|
||||
public static int getIutc() {
|
||||
return iutc;
|
||||
}
|
||||
private static Calendar obsTime;
|
||||
|
||||
public static void setIutc(int iutc) {
|
||||
NcUairShipMobile.iutc = iutc;
|
||||
}
|
||||
private static Calendar synopticTime;
|
||||
|
||||
public static String getStationNumber() {
|
||||
return stationNumber;
|
||||
}
|
||||
private static int topwind;
|
||||
|
||||
public static void setStationNumber(String stationNumber) {
|
||||
NcUairShipMobile.stationNumber = stationNumber;
|
||||
}
|
||||
private static Boolean windKnot;
|
||||
|
||||
public static int getSurfaceHeight() {
|
||||
return surfaceHeight;
|
||||
}
|
||||
public static float getXlat() {
|
||||
return xlat;
|
||||
}
|
||||
|
||||
public static void setSurfaceHeight(int surfaceHeight) {
|
||||
NcUairShipMobile.surfaceHeight = surfaceHeight;
|
||||
}
|
||||
public static void setXlat(float xlat) {
|
||||
NcUairShipMobile.xlat = xlat;
|
||||
}
|
||||
|
||||
public static int getElevation() {
|
||||
return elevation;
|
||||
}
|
||||
public static float getXlon() {
|
||||
return xlon;
|
||||
}
|
||||
|
||||
public static void setElevation(int elevation) {
|
||||
NcUairShipMobile.elevation = elevation;
|
||||
}
|
||||
public static void setXlon(float xlon) {
|
||||
NcUairShipMobile.xlon = xlon;
|
||||
}
|
||||
|
||||
public static String getObsUTC() {
|
||||
return obsUTC;
|
||||
}
|
||||
public static String getStnId() {
|
||||
return stnId;
|
||||
}
|
||||
|
||||
public static void setObsUTC(String obsUTC) {
|
||||
NcUairShipMobile.obsUTC = obsUTC;
|
||||
}
|
||||
public static void setStnId(String stnId) {
|
||||
NcUairShipMobile.stnId = stnId;
|
||||
}
|
||||
|
||||
public static Calendar getObsTime() {
|
||||
return obsTime;
|
||||
}
|
||||
public static String getCodeMessage() {
|
||||
return codeMessage;
|
||||
}
|
||||
|
||||
public static void setObsTime(Calendar obsTime) {
|
||||
NcUairShipMobile.obsTime = obsTime;
|
||||
}
|
||||
public static void setCodeMessage(String codeMessage) {
|
||||
NcUairShipMobile.codeMessage = codeMessage;
|
||||
}
|
||||
|
||||
public static Calendar getSynopticTime() {
|
||||
return synopticTime;
|
||||
}
|
||||
public static String getUTC() {
|
||||
return UTC;
|
||||
}
|
||||
|
||||
public static void setSynopticTime(Calendar synopticTime) {
|
||||
NcUairShipMobile.synopticTime = synopticTime;
|
||||
}
|
||||
public static void setUTC(String utc) {
|
||||
UTC = utc;
|
||||
}
|
||||
|
||||
public static int getTopwind() {
|
||||
return topwind;
|
||||
}
|
||||
public static int getIutc() {
|
||||
return iutc;
|
||||
}
|
||||
|
||||
public static void setTopwind(int topwind) {
|
||||
NcUairShipMobile.topwind = topwind;
|
||||
}
|
||||
public static void setIutc(int iutc) {
|
||||
NcUairShipMobile.iutc = iutc;
|
||||
}
|
||||
|
||||
public static Boolean getWindKnot() {
|
||||
return windKnot;
|
||||
}
|
||||
public static String getStationNumber() {
|
||||
return stationNumber;
|
||||
}
|
||||
|
||||
public static void setWindKnot(Boolean windKnot) {
|
||||
NcUairShipMobile.windKnot = windKnot;
|
||||
}
|
||||
public static void setStationNumber(String stationNumber) {
|
||||
NcUairShipMobile.stationNumber = stationNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes ship or dropsonde data
|
||||
*
|
||||
* @param report The input report
|
||||
* @param dataType The input dataType
|
||||
* @return
|
||||
*/
|
||||
public static void ShipMobileField(String report, String dataType) {
|
||||
|
||||
Boolean drop = false;
|
||||
Boolean ship = false;
|
||||
|
||||
xlat = IDecoderConstantsN.UAIR_FLOAT_MISSING;
|
||||
xlon = IDecoderConstantsN.UAIR_FLOAT_MISSING;
|
||||
stnId = null;
|
||||
codeMessage = null;
|
||||
obsUTC = null;
|
||||
UTC = null;
|
||||
iutc = -1;
|
||||
stationNumber = null;
|
||||
surfaceHeight = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
elevation = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
windKnot = false;
|
||||
|
||||
int day = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
|
||||
final String SHIP = "( )?([A-Z]{4}[0-9]{2}|[A-Z]{4}[0-9]{1}|[A-Z]{4}) (\\d{5}|\\d{4}/) (\\d{5}) (\\d{5}) (\\d{5}) (\\d{5})(.*)";
|
||||
Pattern shipPattern = Pattern.compile(SHIP, Pattern.DOTALL);
|
||||
Matcher shipMatcher = shipPattern.matcher(report);
|
||||
|
||||
final String MOBILE = "( )?(\\d{5}|\\d{4}/) (\\d{5}) (\\d{5}) (\\d{5})(.*)";
|
||||
Pattern mobilePattern = Pattern.compile(MOBILE, Pattern.DOTALL);
|
||||
Matcher mobileMatcher = mobilePattern.matcher(report);
|
||||
int quadrant=0;
|
||||
if ( shipMatcher.find()) {
|
||||
ship = true;
|
||||
stnId = shipMatcher.group(2);
|
||||
xlat = (float)Integer.parseInt(shipMatcher.group(4).substring(2,5)) / (float)10;
|
||||
xlon = (float)Integer.parseInt(shipMatcher.group(5).substring(1,5)) / (float)10;
|
||||
quadrant = Integer.parseInt(shipMatcher.group(5).substring(0,1));
|
||||
codeMessage = shipMatcher.group(7) + shipMatcher.group(8);
|
||||
obsUTC = shipMatcher.group(3).substring(2,4);
|
||||
day = Integer.parseInt(shipMatcher.group(3).substring(0,2));
|
||||
|
||||
//elevation = 0;
|
||||
String heightGroup = shipMatcher.group(7);
|
||||
if ( heightGroup.substring(0,3).equals("999")) {
|
||||
surfaceHeight = Integer.parseInt(heightGroup.substring(3,5));
|
||||
}
|
||||
|
||||
String topwindIndicator = shipMatcher.group(3).substring(4,5);
|
||||
if ( topwindIndicator.equals("/") ) {
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
} else {
|
||||
topwind = Integer.parseInt(topwindIndicator);
|
||||
}
|
||||
public static int getSurfaceHeight() {
|
||||
return surfaceHeight;
|
||||
}
|
||||
|
||||
} else if ( mobileMatcher.find()) {
|
||||
xlat = (float)Integer.parseInt(mobileMatcher.group(3).substring(2,5)) / (float)10;
|
||||
xlon = (float)Integer.parseInt(mobileMatcher.group(4).substring(1,5)) / (float)10;
|
||||
quadrant = Integer.parseInt(mobileMatcher.group(4).substring(0,1));
|
||||
codeMessage = mobileMatcher.group(6);
|
||||
obsUTC = mobileMatcher.group(2).substring(2,4);
|
||||
day = Integer.parseInt(mobileMatcher.group(2).substring(0,2));
|
||||
|
||||
String topwindIndicator = mobileMatcher.group(2).substring(4,5);
|
||||
if ( topwindIndicator.equals("/") ) {
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
} else {
|
||||
topwind = Integer.parseInt(topwindIndicator);
|
||||
}
|
||||
|
||||
drop = true;
|
||||
}
|
||||
|
||||
if ( quadrant == 7 ) {
|
||||
xlon = -xlon;
|
||||
} else if ( quadrant == 5 ) {
|
||||
xlon = -xlon;
|
||||
xlat = -xlat;
|
||||
} else if ( quadrant == 3 ) {
|
||||
xlat = -xlat;
|
||||
}
|
||||
|
||||
if ( day > 50 ) {
|
||||
windKnot = true;
|
||||
day = day -50;
|
||||
}
|
||||
|
||||
if ( ship ) {
|
||||
stnId = stnId + obsUTC;
|
||||
}
|
||||
// Adjusts the time to the nearest 3-hourly interval.
|
||||
int hour = Integer.parseInt(obsUTC);
|
||||
int idiff = hour % 3;
|
||||
if ( idiff == 1 ) {
|
||||
hour = hour - 1;
|
||||
} else if ( idiff == 2 ) {
|
||||
/*
|
||||
* If hour is one hour early, add hour and
|
||||
* change day if hour
|
||||
*/
|
||||
hour = hour + 1;
|
||||
if ( hour == 24 ) {
|
||||
hour = 0;
|
||||
}
|
||||
}
|
||||
iutc = hour;
|
||||
UTC = Integer.toString(hour);
|
||||
if ( hour < 10 ) {
|
||||
UTC = "0" + UTC;
|
||||
}
|
||||
|
||||
// Get observation time
|
||||
if ( obsUTC != null && day > 0 && day <= 31 ) {
|
||||
String oday = Integer.toString(day);
|
||||
if ( day < 10 ) {
|
||||
oday = "0" + oday;
|
||||
}
|
||||
String obsDate = oday + obsUTC + "00";
|
||||
Calendar cal = null;
|
||||
obsTime = UtilN.findDataTime(obsDate,cal);
|
||||
}
|
||||
public static void setSurfaceHeight(int surfaceHeight) {
|
||||
NcUairShipMobile.surfaceHeight = surfaceHeight;
|
||||
}
|
||||
|
||||
// Get synoptic time
|
||||
if ( UTC != null && day > 0 && day <= 31 ) {
|
||||
String sday = Integer.toString(day);
|
||||
if ( day < 10 ) {
|
||||
sday = "0" + sday;
|
||||
}
|
||||
String synopticDate = sday + UTC + "00";
|
||||
Calendar cal = null;
|
||||
synopticTime = UtilN.findDataTime(synopticDate,cal);
|
||||
|
||||
if ( obsUTC.equals("23") ) {
|
||||
// Adjust day to next day
|
||||
synopticTime.set(Calendar.DAY_OF_MONTH, day + 1 );
|
||||
}
|
||||
}
|
||||
public static int getElevation() {
|
||||
return elevation;
|
||||
}
|
||||
|
||||
if ( drop ) {
|
||||
// Decode 61616 and 62626 group
|
||||
Dropsonde(report);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes dropsonde data
|
||||
*
|
||||
* @param report The input report
|
||||
* @return
|
||||
*/
|
||||
public static void Dropsonde(String report) {
|
||||
|
||||
final String DROP = "61616 (AF|NOAA|NASA)(\\d{1,3}) (.*) OB (\\d{2}) 62626";
|
||||
Pattern dropPattern = Pattern.compile(DROP, Pattern.DOTALL);
|
||||
Matcher dropMatcher = dropPattern.matcher(report);
|
||||
public static void setElevation(int elevation) {
|
||||
NcUairShipMobile.elevation = elevation;
|
||||
}
|
||||
|
||||
//final String DROP2 = "62626 (.*) LST WND (\\d3) MBL WIND ";
|
||||
final String DROP2 = "62626 (.*) LST WND (\\d{3})";
|
||||
Pattern drop2Pattern = Pattern.compile(DROP2, Pattern.DOTALL);
|
||||
Matcher drop2Matcher = drop2Pattern.matcher(report);
|
||||
public static String getObsUTC() {
|
||||
return obsUTC;
|
||||
}
|
||||
|
||||
UTC = obsUTC;
|
||||
|
||||
if ( dropMatcher.find() ) {
|
||||
stationNumber = dropMatcher.group(4) + obsUTC + dropMatcher.group(2);
|
||||
stnId = dropMatcher.group(1) + dropMatcher.group(2) + dropMatcher.group(4);
|
||||
}
|
||||
public static void setObsUTC(String obsUTC) {
|
||||
NcUairShipMobile.obsUTC = obsUTC;
|
||||
}
|
||||
|
||||
public static Calendar getObsTime() {
|
||||
return obsTime;
|
||||
}
|
||||
|
||||
public static void setObsTime(Calendar obsTime) {
|
||||
NcUairShipMobile.obsTime = obsTime;
|
||||
}
|
||||
|
||||
public static Calendar getSynopticTime() {
|
||||
return synopticTime;
|
||||
}
|
||||
|
||||
public static void setSynopticTime(Calendar synopticTime) {
|
||||
NcUairShipMobile.synopticTime = synopticTime;
|
||||
}
|
||||
|
||||
public static int getTopwind() {
|
||||
return topwind;
|
||||
}
|
||||
|
||||
public static void setTopwind(int topwind) {
|
||||
NcUairShipMobile.topwind = topwind;
|
||||
}
|
||||
|
||||
public static Boolean getWindKnot() {
|
||||
return windKnot;
|
||||
}
|
||||
|
||||
public static void setWindKnot(Boolean windKnot) {
|
||||
NcUairShipMobile.windKnot = windKnot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes ship or dropsonde data
|
||||
*
|
||||
* @param report
|
||||
* The input report
|
||||
* @param dataType
|
||||
* The input dataType
|
||||
* @return
|
||||
*/
|
||||
public static void ShipMobileField(String report, String dataType) {
|
||||
|
||||
Boolean drop = false;
|
||||
Boolean ship = false;
|
||||
|
||||
xlat = IDecoderConstantsN.UAIR_FLOAT_MISSING;
|
||||
xlon = IDecoderConstantsN.UAIR_FLOAT_MISSING;
|
||||
stnId = null;
|
||||
codeMessage = null;
|
||||
obsUTC = null;
|
||||
UTC = null;
|
||||
iutc = -1;
|
||||
stationNumber = null;
|
||||
surfaceHeight = 0; // Chin: sfcElevSolution
|
||||
// IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
elevation = 0; // Chin: sfcElevSolution
|
||||
// IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
windKnot = false;
|
||||
|
||||
int day = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
|
||||
final String SHIP = "( )?([A-Z]{4}[0-9]{2}|[A-Z]{4}[0-9]{1}|[A-Z]{4}) (\\d{5}|\\d{4}/) (\\d{5}) (\\d{5}) (\\d{5}) (\\d{5})(.*)";
|
||||
Pattern shipPattern = Pattern.compile(SHIP, Pattern.DOTALL);
|
||||
Matcher shipMatcher = shipPattern.matcher(report);
|
||||
|
||||
final String MOBILE = "( )?(\\d{5}|\\d{4}/) (\\d{5}) (\\d{5}) (\\d{5})(.*)";
|
||||
Pattern mobilePattern = Pattern.compile(MOBILE, Pattern.DOTALL);
|
||||
Matcher mobileMatcher = mobilePattern.matcher(report);
|
||||
int quadrant = 0;
|
||||
if (shipMatcher.find()) {
|
||||
ship = true;
|
||||
stnId = shipMatcher.group(2);
|
||||
xlat = (float) Integer.parseInt(shipMatcher.group(4)
|
||||
.substring(2, 5)) / (float) 10;
|
||||
xlon = (float) Integer.parseInt(shipMatcher.group(5)
|
||||
.substring(1, 5)) / (float) 10;
|
||||
quadrant = Integer.parseInt(shipMatcher.group(5).substring(0, 1));
|
||||
codeMessage = shipMatcher.group(7) + shipMatcher.group(8);
|
||||
obsUTC = shipMatcher.group(3).substring(2, 4);
|
||||
day = Integer.parseInt(shipMatcher.group(3).substring(0, 2));
|
||||
|
||||
// elevation = 0;
|
||||
String heightGroup = shipMatcher.group(7);
|
||||
if (heightGroup.substring(0, 3).equals("999")) {
|
||||
surfaceHeight = Integer.parseInt(heightGroup.substring(3, 5));
|
||||
// Chin: sfcElevSolution
|
||||
elevation = surfaceHeight;
|
||||
}
|
||||
|
||||
String topwindIndicator = shipMatcher.group(3).substring(4, 5);
|
||||
if (topwindIndicator.equals("/")) {
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
} else {
|
||||
topwind = Integer.parseInt(topwindIndicator);
|
||||
}
|
||||
|
||||
} else if (mobileMatcher.find()) {
|
||||
xlat = (float) Integer.parseInt(mobileMatcher.group(3).substring(2,
|
||||
5))
|
||||
/ (float) 10;
|
||||
xlon = (float) Integer.parseInt(mobileMatcher.group(4).substring(1,
|
||||
5))
|
||||
/ (float) 10;
|
||||
quadrant = Integer.parseInt(mobileMatcher.group(4).substring(0, 1));
|
||||
codeMessage = mobileMatcher.group(6);
|
||||
obsUTC = mobileMatcher.group(2).substring(2, 4);
|
||||
day = Integer.parseInt(mobileMatcher.group(2).substring(0, 2));
|
||||
|
||||
String topwindIndicator = mobileMatcher.group(2).substring(4, 5);
|
||||
if (topwindIndicator.equals("/")) {
|
||||
topwind = IDecoderConstantsN.UAIR_INTEGER_MISSING;
|
||||
} else {
|
||||
topwind = Integer.parseInt(topwindIndicator);
|
||||
}
|
||||
|
||||
drop = true;
|
||||
}
|
||||
|
||||
if (quadrant == 7) {
|
||||
xlon = -xlon;
|
||||
} else if (quadrant == 5) {
|
||||
xlon = -xlon;
|
||||
xlat = -xlat;
|
||||
} else if (quadrant == 3) {
|
||||
xlat = -xlat;
|
||||
}
|
||||
|
||||
if (day > 50) {
|
||||
windKnot = true;
|
||||
day = day - 50;
|
||||
}
|
||||
|
||||
if (ship) {
|
||||
stnId = stnId + obsUTC;
|
||||
}
|
||||
// Adjusts the time to the nearest 3-hourly interval.
|
||||
int hour = Integer.parseInt(obsUTC);
|
||||
int idiff = hour % 3;
|
||||
if (idiff == 1) {
|
||||
hour = hour - 1;
|
||||
} else if (idiff == 2) {
|
||||
/*
|
||||
* If hour is one hour early, add hour and change day if hour
|
||||
*/
|
||||
hour = hour + 1;
|
||||
if (hour == 24) {
|
||||
hour = 0;
|
||||
}
|
||||
}
|
||||
iutc = hour;
|
||||
UTC = Integer.toString(hour);
|
||||
if (hour < 10) {
|
||||
UTC = "0" + UTC;
|
||||
}
|
||||
|
||||
// Get observation time
|
||||
if (obsUTC != null && day > 0 && day <= 31) {
|
||||
String oday = Integer.toString(day);
|
||||
if (day < 10) {
|
||||
oday = "0" + oday;
|
||||
}
|
||||
String obsDate = oday + obsUTC + "00";
|
||||
Calendar cal = null;
|
||||
obsTime = UtilN.findDataTime(obsDate, cal);
|
||||
}
|
||||
|
||||
// Get synoptic time
|
||||
if (UTC != null && day > 0 && day <= 31) {
|
||||
String sday = Integer.toString(day);
|
||||
if (day < 10) {
|
||||
sday = "0" + sday;
|
||||
}
|
||||
String synopticDate = sday + UTC + "00";
|
||||
Calendar cal = null;
|
||||
synopticTime = UtilN.findDataTime(synopticDate, cal);
|
||||
|
||||
if (obsUTC.equals("23")) {
|
||||
// Adjust day to next day
|
||||
synopticTime.set(Calendar.DAY_OF_MONTH, day + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (drop) {
|
||||
// Decode 61616 and 62626 group
|
||||
Dropsonde(report);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes dropsonde data
|
||||
*
|
||||
* @param report
|
||||
* The input report
|
||||
* @return
|
||||
*/
|
||||
public static void Dropsonde(String report) {
|
||||
|
||||
final String DROP = "61616 (AF|NOAA|NASA)(\\d{1,3}) (.*) OB (\\d{2}) 62626";
|
||||
Pattern dropPattern = Pattern.compile(DROP, Pattern.DOTALL);
|
||||
Matcher dropMatcher = dropPattern.matcher(report);
|
||||
|
||||
// Chin: sfcElevSolution start
|
||||
// Chin: the information is actually not provided
|
||||
// final String DROP2 = "62626 (.*) LST WND (\\d3) MBL WIND ";
|
||||
// final String DROP2 = "62626 (.*) LST WND (\\d{3})";
|
||||
// Pattern drop2Pattern = Pattern.compile(DROP2, Pattern.DOTALL);
|
||||
// Matcher drop2Matcher = drop2Pattern.matcher(report);
|
||||
// end sfcElevSolution
|
||||
UTC = obsUTC;
|
||||
|
||||
if (dropMatcher.find()) {
|
||||
stationNumber = dropMatcher.group(4) + obsUTC
|
||||
+ dropMatcher.group(2);
|
||||
stnId = dropMatcher.group(1) + dropMatcher.group(2)
|
||||
+ dropMatcher.group(4);
|
||||
}
|
||||
// Chin: sfcElevSolution start
|
||||
// if (drop2Matcher.find()) {
|
||||
// elevation = Integer.parseInt(drop2Matcher.group(2));
|
||||
// }
|
||||
// end sfcElevSolution
|
||||
}
|
||||
|
||||
if ( drop2Matcher.find() ) {
|
||||
elevation = Integer.parseInt(drop2Matcher.group(2));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* 8/2012 T. Lee/NCEP Removed missing wind interpolation
|
||||
* 8/2012 T. Lee/NCEP Fixed max wind merging; May fix NSHARP EL calculation
|
||||
* 5/2014 T. Lee/NCEP Fixed wind interpolation
|
||||
* 08/26/2014 Chin Chen index out of bound bug
|
||||
* </pre>
|
||||
*
|
||||
* @author T. Lee
|
||||
|
@ -2260,9 +2261,9 @@ public class MergeSounding2 implements ISerializableObject {
|
|||
|
||||
int sndataSize = sndata.size();
|
||||
if (sndata == null
|
||||
|| sndataSize <= 1
|
||||
|| (sndata.get(0).getPressure() != null && (!sndata.get(0)
|
||||
.getPressure().hasValidValue())) || man.size() < 1
|
||||
|| sndataSize <= 1) {
|
||||
.getPressure().hasValidValue())) || man.size() < 1) {
|
||||
return sndata;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile;
|
|||
* 03/28/2012 Chin Chen modify Grid data sounding query algorithms for better performance
|
||||
* 06/25/2014 Chin Chen support dropsonde
|
||||
* 07/23/2014 Chin Chen Support PW
|
||||
* 08/26/2014 Chin Chen index out of bound bug
|
||||
* </pre>
|
||||
* Python Script example to query multiple locations at one request:
|
||||
* The following 3 query examples, returns same results.
|
||||
|
@ -1216,7 +1217,7 @@ public class NcSoundingDrv {
|
|||
pf.setSoundingLyLst2(sls);
|
||||
// System.out.println("sls set to the sounding profile");
|
||||
} else if (ms.isNumber(level) >= 0) {
|
||||
if (sls.size() == 1) {
|
||||
if (sls != null && sls.size() == 1) {
|
||||
// System.out.println("NcUair get one layer using level = "+
|
||||
// level);
|
||||
pf.setSoundingLyLst2(sls);
|
||||
|
@ -1226,7 +1227,8 @@ public class NcSoundingDrv {
|
|||
// level);
|
||||
}
|
||||
} else {
|
||||
if (sls.isEmpty() || sls.size() <= 1) {
|
||||
if (sls != null
|
||||
&& (sls.isEmpty() || sls.size() <= 1)) {
|
||||
pf = null;
|
||||
// System.out.println("not MAN level & sls is empty or 1");
|
||||
} else {
|
||||
|
@ -1242,7 +1244,11 @@ public class NcSoundingDrv {
|
|||
ttcc, ttdd, ppaa, ppbb, ppcc, ppdd,
|
||||
trop_a, trop_c, wmax_a, wmax_c,
|
||||
pf.getStationElevation());
|
||||
pf.setPw(NcSoundingTools.precip_water2(sls2));
|
||||
if (sls2 != null && sls2.size() > 0)
|
||||
pf.setPw(NcSoundingTools
|
||||
.precip_water2(sls2));
|
||||
else
|
||||
pf.setPw(-1);
|
||||
|
||||
// System.out.println("2nd merge call: lat/lon="
|
||||
// + pf.getStationLatitude());
|
||||
|
@ -2042,8 +2048,8 @@ public class NcSoundingDrv {
|
|||
ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c,
|
||||
wmax_a, wmax_c, pf.getStationElevation());
|
||||
// PW Support test
|
||||
float pw = NcSoundingTools.precip_water(sls);
|
||||
pf.setPw(pw);
|
||||
// float pw = NcSoundingTools.precip_water(sls);
|
||||
// pf.setPw(pw);
|
||||
// end PW Support test
|
||||
// System.out.println("NCUAIR Number of Layers after merge:"+sls.size()
|
||||
// + " level="+level +
|
||||
|
|
Loading…
Add table
Reference in a new issue