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: 32dffe58c8 [formerly 32dffe58c8 [formerly 72fa8af848f1452a517a62c6a54eae265a9ec8a1]]
Former-commit-id: 75277cb034
Former-commit-id: 3da185fa1a
This commit is contained in:
Stephen Gilbert 2014-09-03 14:33:37 -04:00
parent f846921a9f
commit a0f6386a90
9 changed files with 645 additions and 474 deletions

View file

@ -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>

View file

@ -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>

View file

@ -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")) {

View file

@ -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;

View file

@ -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;
}

View file

@ -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());

View file

@ -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));
}
}
}

View file

@ -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;
}

View file

@ -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 +