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> * <pre>
* *
@ -33,6 +33,7 @@ import java.util.Map;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 14, 2009 jkorman Initial creation * Oct 14, 2009 jkorman Initial creation
* Dec 09, 2013 2581 njensen Added freezing drizzle
* *
* </pre> * </pre>
* *
@ -81,7 +82,8 @@ public enum LSREventType {
TSTMWNDDMG("TSTM WND DMG",36,LSRUnits.NOUNITS), TSTMWNDDMG("TSTM WND DMG",36,LSRUnits.NOUNITS),
TSTMWNDGST("TSTM WND GST",37,LSRUnits.MPH), TSTMWNDGST("TSTM WND GST",37,LSRUnits.MPH),
WATERSPOUT("WATER SPOUT",38,LSRUnits.NOUNITS), 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; private final String eventName;

View file

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

View file

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

View file

@ -28,11 +28,11 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.logging.Log; import com.raytheon.uf.common.status.IUFStatusHandler;
import org.apache.commons.logging.LogFactory; import com.raytheon.uf.common.status.UFStatus;
/** /**
* TODO Add Description * Internal structure for parsing Local Storm Reports
* *
* <pre> * <pre>
* *
@ -42,6 +42,7 @@ import org.apache.commons.logging.LogFactory;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 26, 2009 jkorman Initial creation * Oct 26, 2009 jkorman Initial creation
* Oct 23, 2013 DR 16674 D. Friedman Prevent infinite loop * Oct 23, 2013 DR 16674 D. Friedman Prevent infinite loop
* Dec 10, 2013 2581 njensen Use UFStatus for logging
* *
* </pre> * </pre>
* *
@ -51,7 +52,8 @@ import org.apache.commons.logging.LogFactory;
public class InternalReport { 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) +(.*)"; public static final String NWS_ID_LINE = "^(NATIONAL WEATHER SERVICE) +(.*)";
@ -66,6 +68,7 @@ public class InternalReport {
public static final String DATE_LINE = "^((0[1-9])|(1[0-2]))/(\\d{2,2})/(\\d{4,4}) .*"; public static final String DATE_LINE = "^((0[1-9])|(1[0-2]))/(\\d{2,2})/(\\d{4,4}) .*";
private final InternalType lineType; private final InternalType lineType;
private final String reportLine; private final String reportLine;
private List<InternalReport> subLines = null; private List<InternalReport> subLines = null;
@ -99,7 +102,8 @@ public class InternalReport {
/** /**
* *
* @param buffer Buffer to receive String formatted internal data. If this * @param buffer
* Buffer to receive String formatted internal data. If this
* reference is null, a new StringBuilder instance is created. * reference is null, a new StringBuilder instance is created.
* @return The populated StringBuilder instance. * @return The populated StringBuilder instance.
*/ */
@ -117,6 +121,7 @@ public class InternalReport {
/** /**
* Create a string representation of this class instance. * Create a string representation of this class instance.
*
* @return The string representation of this class instance. * @return The string representation of this class instance.
*/ */
@Override @Override
@ -147,25 +152,30 @@ public class InternalReport {
} }
Matcher m = p1.matcher(s); Matcher m = p1.matcher(s);
if (m.matches()) { if (m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.NWS_ID,m.group(2)); InternalReport rptLine = new InternalReport(
InternalType.NWS_ID, m.group(2));
reports.add(rptLine); reports.add(rptLine);
} else { } else {
m = p2.matcher(s); m = p2.matcher(s);
if (m.matches()) { if (m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.DATETIME_ZONE,s); InternalReport rptLine = new InternalReport(
InternalType.DATETIME_ZONE, s);
reports.add(rptLine); reports.add(rptLine);
} else { } else {
m = p3.matcher(s); m = p3.matcher(s);
if (m.matches()) { if (m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.TIME,s); InternalReport rptLine = new InternalReport(
InternalType.TIME, s);
reports.add(rptLine); reports.add(rptLine);
} else { } else {
m = p4.matcher(s); m = p4.matcher(s);
if (m.matches()) { if (m.matches()) {
InternalReport rptLine = new InternalReport(InternalType.DATE,s); InternalReport rptLine = new InternalReport(
InternalType.DATE, s);
reports.add(rptLine); reports.add(rptLine);
} else if (s.startsWith(" ")) { } else if (s.startsWith(" ")) {
InternalReport rptLine = new InternalReport(InternalType.REMARK,s.trim()); InternalReport rptLine = new InternalReport(
InternalType.REMARK, s.trim());
reports.add(rptLine); reports.add(rptLine);
} else { } else {
logger.debug("not identified [" + s + "]"); logger.debug("not identified [" + s + "]");
@ -215,7 +225,9 @@ public class InternalReport {
/** /**
* Collect subordinate report lines "below" the report lead-in line. * 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. * @return The adjusted report list.
*/ */
private static List<InternalReport> adjust(List<InternalReport> reports) { private static List<InternalReport> adjust(List<InternalReport> reports) {
@ -260,10 +272,10 @@ public class InternalReport {
return reports; 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 ", "00/25/2010 PROVIDENCE RI AMATEUR RADIO ",
@ -279,8 +291,7 @@ public class InternalReport {
"10/25/2010 PROVIDENCE RI AMATEUR RADIO ", "10/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"11/25/2010 PROVIDENCE RI AMATEUR RADIO ", "11/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"12/25/2010 PROVIDENCE RI AMATEUR RADIO ", "12/25/2010 PROVIDENCE RI AMATEUR RADIO ",
"13/25/2010 PROVIDENCE RI AMATEUR RADIO ", "13/25/2010 PROVIDENCE RI AMATEUR RADIO ", };
};
for (String s : test) { for (String s : test) {
Matcher m = p4.matcher(s); Matcher m = p4.matcher(s);
if (m.matches()) { if (m.matches()) {
@ -289,5 +300,4 @@ public class InternalReport {
} }
} }
} }

View file

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