Issue #2581 fix decoding of LSR freezing drizzle and latlon

Change-Id: Iec01ce82c1b3104e86a54cd9ec015d699d0703d5

Former-commit-id: c0c17822c2 [formerly 60d395b347] [formerly c0c17822c2 [formerly 60d395b347] [formerly 16b0650f67 [formerly f7324d1e9ab164c553f5c62920292fb0487bfcfb]]]
Former-commit-id: 16b0650f67
Former-commit-id: c96678bb3a [formerly 36845b1c1d]
Former-commit-id: 6b9ef6eddd
This commit is contained in:
Nate Jensen 2013-12-09 16:39:51 -06:00
parent 5283e7c725
commit 34319cc97e
5 changed files with 115 additions and 139 deletions

View file

@ -24,7 +24,7 @@ import java.util.Map;
/**
* TODO Add Description
* Local Storm Report event type
*
* <pre>
*
@ -33,6 +33,7 @@ import java.util.Map;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 14, 2009 jkorman Initial creation
* Dec 09, 2013 2581 njensen Added freezing drizzle
*
* </pre>
*
@ -81,7 +82,8 @@ public enum LSREventType {
TSTMWNDDMG("TSTM WND DMG",36,LSRUnits.NOUNITS),
TSTMWNDGST("TSTM WND GST",37,LSRUnits.MPH),
WATERSPOUT("WATER SPOUT",38,LSRUnits.NOUNITS),
WILDFIRE("WILDFIRE",39,LSRUnits.NOUNITS);
WILDFIRE("WILDFIRE",39,LSRUnits.NOUNITS),
FREEZINGDRIZZLE("FREEZING DRIZZLE", 40, LSRUnits.NOUNITS);
private final String eventName;

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Lsr Plug-in
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.lsr
Bundle-Version: 1.12.1174.qualifier
Bundle-Version: 1.13.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.raytheon.uf.common.dataplugin.lsr;bundle-version="1.0.0",
@ -19,5 +19,4 @@ Import-Package: com.raytheon.edex.esb,
com.raytheon.uf.common.datastorage.records,
com.raytheon.uf.common.status,
com.raytheon.uf.common.time,
com.raytheon.uf.edex.core,
org.apache.commons.logging
com.raytheon.uf.edex.core

View file

@ -22,17 +22,16 @@ package com.raytheon.uf.edex.plugin.lsr;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.lsr.LocalStormReport;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.plugin.lsr.decoder.LSRParser;
/**
*
* Decoder for Local Storm Reports
*
* <pre>
*
@ -40,6 +39,7 @@ import com.raytheon.uf.edex.plugin.lsr.decoder.LSRParser;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 21, 2009 1939 jkorman Initial creation
* Dec 09, 2013 2581 njensen Updated javadoc
*
* </pre>
*
@ -47,7 +47,7 @@ import com.raytheon.uf.edex.plugin.lsr.decoder.LSRParser;
* @version 1.0
*/
public class LSRDecoder {
private Log logger = LogFactory.getLog(getClass());
private IUFStatusHandler logger = UFStatus.getHandler(LSRDecoder.class);
private final String pluginName;
@ -107,7 +107,7 @@ public class LSRDecoder {
if (data != null && data.length > 0) {
List<LocalStormReport> obsList = new ArrayList<LocalStormReport>();
try {
LSRParser parser = new LSRParser(dao, pdd, pluginName);
LSRParser parser = new LSRParser(dao, pdd);
parser.setData(data, traceId, headers);
LocalStormReport report;

View file

@ -28,11 +28,11 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
/**
* TODO Add Description
* Internal structure for parsing Local Storm Reports
*
* <pre>
*
@ -42,6 +42,7 @@ import org.apache.commons.logging.LogFactory;
* ------------ ---------- ----------- --------------------------
* Oct 26, 2009 jkorman Initial creation
* Oct 23, 2013 DR 16674 D. Friedman Prevent infinite loop
* Dec 10, 2013 2581 njensen Use UFStatus for logging
*
* </pre>
*
@ -51,7 +52,8 @@ import org.apache.commons.logging.LogFactory;
public class InternalReport {
private static Log logger = LogFactory.getLog(InternalReport.class);
private static final IUFStatusHandler logger = UFStatus
.getHandler(InternalReport.class);
public static final String NWS_ID_LINE = "^(NATIONAL WEATHER SERVICE) +(.*)";
@ -59,13 +61,14 @@ public class InternalReport {
public static final String DATETIME = "^((\\d{3,4}) (AM|PM) (EDT|EST|CDT|CST|MDT|MST|PDT|PST|GMT)(.*))";
//
// 0953 AM NON-TSTM WND DMG FAIRHAVEN 41.65N 70.82W
// 0953 AM NON-TSTM WND DMG FAIRHAVEN 41.65N 70.82W
public static final String TIME_LINE = "^((0[1-9]|1[0-2]))([0-5]\\d) (AM|PM) (.*)";
// 10/18/2009 PLYMOUTH MA AMATEUR RADIO
// 10/18/2009 PLYMOUTH MA AMATEUR RADIO
public static final String DATE_LINE = "^((0[1-9])|(1[0-2]))/(\\d{2,2})/(\\d{4,4}) .*";
private final InternalType lineType;
private final String reportLine;
private List<InternalReport> subLines = null;
@ -99,12 +102,13 @@ public class InternalReport {
/**
*
* @param buffer Buffer to receive String formatted internal data. If this
* reference is null, a new StringBuilder instance is created.
* @param buffer
* Buffer to receive String formatted internal data. If this
* reference is null, a new StringBuilder instance is created.
* @return The populated StringBuilder instance.
*/
public StringBuilder toString(StringBuilder buffer) {
if(buffer == null) {
if (buffer == null) {
buffer = new StringBuilder();
}
buffer.append("[");
@ -117,13 +121,14 @@ public class InternalReport {
/**
* Create a string representation of this class instance.
*
* @return The string representation of this class instance.
*/
@Override
public String toString() {
StringBuilder sb = toString(null);
if(subLines != null) {
for(InternalReport r : subLines) {
if (subLines != null) {
for (InternalReport r : subLines) {
sb.append(" ");
r.toString(sb);
}
@ -131,41 +136,46 @@ public class InternalReport {
return sb.toString();
}
public static List<InternalReport> identifyMessage(byte [] message) {
public static List<InternalReport> identifyMessage(byte[] message) {
List<InternalReport> reports = new ArrayList<InternalReport>();
List<String> lines = separateLines(message);
if(lines != null) {
if (lines != null) {
Pattern p1 = Pattern.compile(NWS_ID_LINE);
Pattern p2 = Pattern.compile(DATETIME);
Pattern p3 = Pattern.compile(TIME_LINE);
Pattern p4 = Pattern.compile(DATE_LINE);
for(String s : lines) {
if((s.length() > 0)&&(s.startsWith("&&"))) {
for (String s : lines) {
if ((s.length() > 0) && (s.startsWith("&&"))) {
// We don't care about any aux. data past this point.
break;
}
Matcher m = p1.matcher(s);
if(m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.NWS_ID,m.group(2));
if (m.matches()) {
InternalReport rptLine = new InternalReport(
InternalType.NWS_ID, m.group(2));
reports.add(rptLine);
} else {
m = p2.matcher(s);
if(m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.DATETIME_ZONE,s);
if (m.matches()) {
InternalReport rptLine = new InternalReport(
InternalType.DATETIME_ZONE, s);
reports.add(rptLine);
} else {
m = p3.matcher(s);
if(m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.TIME,s);
if (m.matches()) {
InternalReport rptLine = new InternalReport(
InternalType.TIME, s);
reports.add(rptLine);
} else {
m = p4.matcher(s);
if(m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.DATE,s);
if (m.matches()) {
InternalReport rptLine = new InternalReport(
InternalType.DATE, s);
reports.add(rptLine);
} else if(s.startsWith(" ")) {
InternalReport rptLine = new InternalReport(InternalType.REMARK,s.trim());
} else if (s.startsWith(" ")) {
InternalReport rptLine = new InternalReport(
InternalType.REMARK, s.trim());
reports.add(rptLine);
} else {
logger.debug("not identified [" + s + "]");
@ -199,7 +209,7 @@ public class InternalReport {
}
}
} catch (Exception e) {
logger.error("Error reading from reader",e);
logger.error("Error reading from reader", e);
} finally {
if (reader != null) {
try {
@ -215,42 +225,44 @@ public class InternalReport {
/**
* Collect subordinate report lines "below" the report lead-in line.
* @param reports List of report lines to adjust.
*
* @param reports
* List of report lines to adjust.
* @return The adjusted report list.
*/
private static List<InternalReport> adjust(List<InternalReport> reports) {
if(reports != null) {
if (reports != null) {
InternalReport currRpt = null;
for(int i = 0;i < reports.size();) {
for (int i = 0; i < reports.size();) {
InternalReport r = reports.get(i);
switch(r.lineType) {
case DATETIME_ZONE : {
switch (r.lineType) {
case DATETIME_ZONE: {
i++;
break;
}
case TIME : {
case TIME: {
currRpt = r;
if(currRpt.subLines == null) {
if (currRpt.subLines == null) {
currRpt.subLines = new ArrayList<InternalReport>();
}
i++;
break;
}
case DATE : {
if(currRpt != null) {
case DATE: {
if (currRpt != null) {
currRpt.subLines.add(r);
}
reports.remove(r);
break;
}
case REMARK : {
if(currRpt != null) {
case REMARK: {
if (currRpt != null) {
currRpt.subLines.add(r);
}
reports.remove(r);
break;
}
default : {
default: {
logger.debug(r.reportLine);
reports.remove(r);
}
@ -260,12 +272,12 @@ public class InternalReport {
return reports;
}
public static final void main(String[] args) {
public static final void main(String [] args) {
Pattern p4 = Pattern
.compile("^((0[1-9])|(1[0-2]))/(\\d{2,2})/(\\d{4,4}) .*");
Pattern p4 = Pattern.compile("^((0[1-9])|(1[0-2]))/(\\d{2,2})/(\\d{4,4}) .*");
String [] test = {
String[] test = {
"00/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"01/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"02/25/2010 PROVIDENCE RI AMATEUR RADIO ",
@ -279,15 +291,13 @@ public class InternalReport {
"10/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"11/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"12/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"13/25/2010 PROVIDENCE RI AMATEUR RADIO ",
};
for(String s : test) {
"13/25/2010 PROVIDENCE RI AMATEUR RADIO ", };
for (String s : test) {
Matcher m = p4.matcher(s);
if(m.matches()) {
if (m.matches()) {
System.out.println(s);
}
}
}
}

View file

@ -28,24 +28,22 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.lsr.LSREventType;
import com.raytheon.uf.common.dataplugin.lsr.LocalStormReport;
import com.raytheon.uf.common.pointdata.PointDataContainer;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.common.pointdata.PointDataView;
import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.decodertools.time.TimeTools;
import com.raytheon.uf.edex.plugin.lsr.LocalStormReportDao;
import com.raytheon.uf.edex.wmo.message.WMOHeader;
/**
*
* Local Storm Report parser
*
* <pre>
*
@ -54,6 +52,8 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
* ------------ ---------- ----------- --------------------------
* Jan 21, 2009 1939 jkorman Initial creation
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Dec 09, 2013 2581 njensen Reuse patterns for efficiency
* Check entire time line looking for latlon
*
* </pre>
*
@ -64,10 +64,6 @@ public class LSRParser {
private static final int PDV_FILL_INT = -9999;
private static final float PDV_FILL_DBL = -9999.0f;
private static int MAX_LENGTH = 500; // LSR max length
private static int TIME = 0; // time
private static int TIME_LENGTH = 7; // time max length
@ -80,26 +76,12 @@ public class LSRParser {
private static int LOCATION_LENGTH = 23; // city location max length
private static int LATLON = 52; // lat/lon
private static int LATLON_LENGTH = 14; // lat/lon max length
private static int DATE = 0; // date
private static int DATE_LENGTH = 10; // date max length
private static int MAG = 12; // magnitude
private static int MAG_LENGTH = 3; // magnitude max length
private static int EMAG_LENGTH = 4; // magnitude max length
private static int UNIT = 16; // unit
private static int EUNIT = 17; // emag unit
private static int UNIT_LENGTH = 4; // unit length
private static int COUNTY = 29; // county
private static int COUNTY_LENGTH = 18; // county max length
@ -112,17 +94,17 @@ public class LSRParser {
private static int SOURCE_LENGTH = 16; // source max length
private static int REMARK = 12; // remark
private static final Pattern LATLON_PTRN = Pattern
.compile("((([0-8][0-9]|90).\\d{2,2}[NS]) ++(1?+\\d{2,2}.\\d{2,2}[EW])())");
private static int REMARK_LENGTH = 57; // remark length
private static final Pattern RPT_DT_PTRN = Pattern
.compile(InternalReport.DATETIME);
private static int REMARK_MAX_LENGTH = 500; // remark max length
private static final Pattern FATAL_INJ_PTRN = Pattern
.compile("\\*\\*\\*( (\\d*) (FATAL))?,?( (\\d*) (INJ))? \\*\\*\\*(.*)");
private static final String LATLON_PTRN = "((([0-8][0-9]|90).\\d{2,2}[NS]) ++(1?+\\d{2,2}.\\d{2,2}[EW])())";
private static final String RPT_DT_PTRN = InternalReport.DATETIME;
private static final String FATAL_INJ_PTRN = "\\*\\*\\*( (\\d*) (FATAL))?,?( (\\d*) (INJ))? \\*\\*\\*(.*)";
private static final Pattern OFFICE_ID_PTRN = Pattern
.compile("NWUS5[1-9]\\s([A-Z]{4})\\s\\d{6}");
private static final Map<String, Integer> TIMEZONE = new HashMap<String, Integer>();
static {
@ -137,11 +119,9 @@ public class LSRParser {
TIMEZONE.put("GMT", 0);
}
// private Pattern rptStartPtrn = Pattern.compile(TIME_PTRN);
private final Pattern latlanPtrn = Pattern.compile(LATLON_PTRN);
/** The logger */
private final Log logger = LogFactory.getLog(getClass());
private static final IUFStatusHandler logger = UFStatus
.getHandler(LSRParser.class);;
private final PointDataDescription pointDataDescription;
@ -149,8 +129,6 @@ public class LSRParser {
private final Map<File, PointDataContainer> containerMap;
private final String pluginName;
private WMOHeader wmoHeader;
private String officeid;
@ -177,11 +155,9 @@ public class LSRParser {
* @param wmoHeader
* @param pdd
*/
public LSRParser(LocalStormReportDao dao, PointDataDescription pdd,
String name) {
public LSRParser(LocalStormReportDao dao, PointDataDescription pdd) {
pointDataDescription = pdd;
lsrDao = dao;
pluginName = name;
containerMap = new HashMap<File, PointDataContainer>();
}
@ -198,9 +174,7 @@ public class LSRParser {
this.traceId = traceId;
wmoHeader = new WMOHeader(message, headers);
if (wmoHeader != null) {
Pattern officeidPtrn = Pattern
.compile("NWUS5[1-9]\\s([A-Z]{4})\\s\\d{6}");
Matcher m = officeidPtrn.matcher(wmoHeader.getWmoHeader());
Matcher m = OFFICE_ID_PTRN.matcher(wmoHeader.getWmoHeader());
if (m.matches()) {
officeid = m.group(1);
}
@ -248,18 +222,12 @@ public class LSRParser {
} else {
report = reports.get(currentReport++);
logger.debug("Getting report " + report);
try {
report.constructDataURI();
if (URI_MAP.containsKey(report.getDataURI())) {
report = null;
} else {
URI_MAP.put(report.getDataURI(), Boolean.TRUE);
}
} catch (PluginException e) {
logger.error(traceId + "- Unable to construct dataURI", e);
if (URI_MAP.containsKey(report.getDataURI())) {
report = null;
} else {
URI_MAP.put(report.getDataURI(), Boolean.TRUE);
}
if (report != null) {
PointDataContainer pdc = getContainer(report);
@ -323,8 +291,7 @@ public class LSRParser {
for (; currPos < parts.size(); currPos++) {
InternalReport r = parts.get(currPos);
if (InternalType.DATETIME_ZONE.equals(r.getLineType())) {
Pattern rptDatePtrn = Pattern.compile(RPT_DT_PTRN);
Matcher m = rptDatePtrn.matcher(r.getReportLine());
Matcher m = RPT_DT_PTRN.matcher(r.getReportLine());
if (m.find()) {
String tz = m.group(4);
if (TIMEZONE.containsKey(tz)) {
@ -406,8 +373,7 @@ public class LSRParser {
.trim();
rpt.setCityLoc(ss);
ss = timeLine.substring(LATLON).trim();
parseLatLon(ss, rpt);
parseLatLon(timeLine, rpt);
}
return timeOk;
}
@ -466,7 +432,7 @@ public class LSRParser {
private boolean parseLatLon(String latlon, LocalStormReport rpt) {
boolean locOk = false;
Matcher m = latlanPtrn.matcher(latlon);
Matcher m = LATLON_PTRN.matcher(latlon);
if (m.find()) {
String ss = m.group(2);
Double lat = Double.parseDouble(ss.substring(0, ss.length() - 1));
@ -587,7 +553,7 @@ public class LSRParser {
List<InternalReport> remarks = new ArrayList<InternalReport>();
for (InternalReport r : rptLines) {
logger.debug(r);
logger.debug(r.toString());
if (InternalType.REMARK.equals(r.getLineType())) {
logger.debug("Adding " + r);
remarks.add(r);
@ -601,8 +567,7 @@ public class LSRParser {
}
String rmk = r.getReportLine().trim();
// Check each line just in the event someone did it wrong.
Pattern p = Pattern.compile(FATAL_INJ_PTRN);
Matcher m = p.matcher(rmk);
Matcher m = FATAL_INJ_PTRN.matcher(rmk);
if (m.find()) {
int n;
if ("FATAL".equals(m.group(3))) {