Issue #2582 Fix decoding where OBS DTG are on separate lines, cleanup

VAA and remove dataURI

Change-Id: I984173a6e85eb7dc269fb98964af4915a9b5105e

Former-commit-id: 148e7113abefd684dcacb5ccc28bb77192ff45c8
This commit is contained in:
Nate Jensen 2013-11-26 17:33:52 -06:00
parent 212bbeb379
commit 6bf1fd8d3c
10 changed files with 145 additions and 333 deletions

View file

@ -0,0 +1,53 @@
#!/bin/bash
# DR #2582 - this update script will drop the dataURI column from the vaa table
PSQL="/awips2/psql/bin/psql"
# takes one arg: a table name
# drops the datauri constraint and column if they exist
function dropDatauri {
echo "INFO: Dropping DataURI column from $1"
${PSQL} -U awips -d metadata -c "ALTER TABLE $1 DROP CONSTRAINT IF EXISTS ${1}_datauri_key;"
${PSQL} -U awips -d metadata -c "ALTER TABLE $1 DROP COLUMN IF EXISTS datauri;"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to drop dataURI column for $table"
echo "FATAL: The update has failed."
exit 1
fi
}
function dropRecordType {
echo "INFO: Dropping recordType column from $1"
${PSQL} -U awips -d metadata -c "ALTER TABLE $1 DROP COLUMN IF EXISTS recordtype;"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to drop recordType column for $table"
echo "FATAL: The update has failed."
exit 1
fi
}
# takes three args: table, constraint name, unique columns
# will first drop the constraint if it exists and then adds it back, this is
# fairly inefficient if it does exist but operationally it won't exist and for
# testing this allows the script to be run easily as a noop.
function dropDatauriAndAddConstraint {
dropDatauri $1
${PSQL} -U awips -d metadata -c "ALTER TABLE $1 DROP CONSTRAINT IF EXISTS $2;"
dropRecordType $1
${PSQL} -U awips -d metadata -c "ALTER TABLE $1 ADD CONSTRAINT $2 UNIQUE $3;"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to add new unique constraint for $table"
echo "FATAL: The update has failed."
exit 1
fi
${PSQL} -U awips -d metadata -c "VACUUM FULL ANALYZE $1"
}
echo "INFO: Dropping dataURI columns."
dropDatauriAndAddConstraint vaa vaa_latitude_longitude_stationId_reftime_forecasttime_advisoryNumber_key "(latitude, longitude, stationId, reftime, forecasttime, advisoryNumber)"
echo "INFO: VAA dataURI column dropped successfully"

View file

@ -22,8 +22,6 @@ package com.raytheon.uf.common.dataplugin.vaa;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
@ -62,6 +60,7 @@ import com.vividsolutions.jts.geom.Geometry;
*
* PluginDataObject.
* Oct 22, 2013 2361 njensen Remove XML annotations
* Nov 26, 2013 2582 njensen Remove dataURI and recordType columns
*
* </pre>
*
@ -71,7 +70,9 @@ import com.vividsolutions.jts.geom.Geometry;
@Entity
@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "vaaseq")
@Table(name = "vaa", uniqueConstraints = { @UniqueConstraint(columnNames = { "dataURI" }) })
@Table(name = "vaa", uniqueConstraints = { @UniqueConstraint(columnNames = {
"latitude", "longitude", "stationId", "refTime", "forecastTime",
"advisoryNumber" }) })
/*
* Both refTime and forecastTime are included in the refTimeIndex since
* forecastTime is unlikely to be used.
@ -88,24 +89,15 @@ public class VAARecord extends PluginDataObject implements ISpatialEnabled {
@DynamicSerializeElement
private SurfaceObsLocation location;
/**
*
*/
@Column(length = 8)
@DataURI(position = 2)
@DynamicSerializeElement
private String recordType;
/**
*
*/
@Column(length = 16)
@DataURI(position = 3)
@DataURI(position = 2)
@DynamicSerializeElement
private String advisoryNumber;
// Correction indicator from wmo header
@DataURI(position = 4)
@Column(length = 8)
@DynamicSerializeElement
private String corIndicator;
@ -285,21 +277,6 @@ public class VAARecord extends PluginDataObject implements ISpatialEnabled {
return location.getLocationDefined();
}
/**
* @return the recordType
*/
public String getRecordType() {
return recordType;
}
/**
* @param recordType
* the recordType to set
*/
public void setRecordType(String recordType) {
this.recordType = recordType;
}
/**
* @return the advisoryNumber
*/
@ -459,13 +436,6 @@ public class VAARecord extends PluginDataObject implements ISpatialEnabled {
// "\r\r\nANTICIPATED DURING THE NEXT 12 HOURS. ...BALDWIN" +
// "\r\r\nNXT ADVISORY: WILL BE ISSUED BY 20091104/2315Z" +
@Override
@Column
@Access(AccessType.PROPERTY)
public String getDataURI() {
return super.getDataURI();
}
@Override
public String getPluginName() {
return "vaa";

View file

@ -2,21 +2,15 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Vaa Plug-in
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.vaa
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.edex.decodertools,
com.raytheon.uf.common.pointdata,
com.raytheon.uf.edex.pointdata,
org.geotools,
javax.persistence,
javax.measure,
com.raytheon.uf.common.dataplugin,
com.raytheon.uf.edex.database,
com.raytheon.uf.common.dataplugin.vaa
Import-Package: com.raytheon.edex.db.dao,
com.raytheon.edex.esb,
com.raytheon.uf.common.datastorage,
com.raytheon.uf.common.time,
com.raytheon.uf.edex.core,
org.apache.commons.logging
Import-Package: com.raytheon.edex.esb,
com.raytheon.uf.common.pointdata.spatial,
com.raytheon.uf.common.status,
com.raytheon.uf.common.time

View file

@ -1,30 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
This_software_product_contains_export-restricted_data_whose
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
an_export_license_or_other_authorization.
Contractor_Name:________Raytheon_Company
Contractor_Address:_____6825_Pine_Street,_Suite_340
________________________Mail_Stop_B8
________________________Omaha,_NE_68106
________________________402.291.0100
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information.
-->
<!--
Volcanic Ash Advisories
-->
<pointDataDescription>
<parameter name="timeObs" numDims="1" type="LONG" />
<parameter name="latitude" numDims="1" type="FLOAT" unit="degree_N" />
<parameter name="longitude" numDims="1" type="FLOAT" unit="degree_E" />
<parameter name="wmoHeader" numDims="1" type="STRING" />
<parameter name="dataURI" numDims="1" type="STRING" />
</pointDataDescription>

View file

@ -9,7 +9,7 @@
<bean id="vaaProperties" class="com.raytheon.uf.common.dataplugin.PluginProperties">
<property name="pluginName" ref="vaaPluginName" />
<property name="pluginFQN" value="com.raytheon.uf.common.dataplugin.vaa" />
<property name="dao" value="com.raytheon.uf.edex.plugin.vaa.VAARecordDao" />
<property name="dao" value="com.raytheon.edex.db.dao.DefaultPluginDao" />
<property name="record" value="com.raytheon.uf.common.dataplugin.vaa.VAARecord" />
</bean>

View file

@ -3,9 +3,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="vaaDecoder" class="com.raytheon.uf.edex.plugin.vaa.VAADecoder">
<constructor-arg ref="vaaPluginName" />
</bean>
<bean id="vaaDecoder" class="com.raytheon.uf.edex.plugin.vaa.VAADecoder"/>
<bean id="vaaDistRegistry" factory-bean="distributionSrv"
factory-method="register">
@ -46,7 +44,7 @@
<pipeline>
<bean ref="stringToFile" />
<bean ref="vaaDecoder" method="decode" />
<to uri="direct-vm:persistIndexAlert" />
<to uri="direct-vm:indexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>

View file

@ -22,17 +22,15 @@ package com.raytheon.uf.edex.plugin.vaa;
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.PluginException;
import com.raytheon.uf.common.dataplugin.vaa.VAARecord;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.plugin.vaa.decoder.VAAParser;
/**
*
* Decoder for Volcanic Ash Advisory
*
* <pre>
*
@ -40,6 +38,7 @@ import com.raytheon.uf.edex.plugin.vaa.decoder.VAAParser;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 04, 2009 3267 jkorman Initial creation
* Nov 26, 2013 2582 njensen Cleanup
*
* </pre>
*
@ -47,18 +46,15 @@ import com.raytheon.uf.edex.plugin.vaa.decoder.VAAParser;
* @version 1.0
*/
public class VAADecoder {
private Log logger = LogFactory.getLog(getClass());
private final String pluginName;
private boolean failSafe = false;
private IUFStatusHandler logger = UFStatus.getHandler(VAADecoder.class);
/**
*
* @param name
*/
public VAADecoder(String name) {
pluginName = name;
public VAADecoder() {
}
/**
@ -76,29 +72,19 @@ public class VAADecoder {
if (headers != null) {
traceId = (String) headers.get("traceId");
}
if (isFailSafe()) {
return new PluginDataObject[0];
}
logger.debug(traceId + " - Decoding data");
if (data != null && data.length > 0) {
List<PluginDataObject> obsList = new ArrayList<PluginDataObject>();
try {
VAAParser parser = new VAAParser(pluginName, data, traceId,
headers);
VAAParser parser = new VAAParser(data, traceId, headers);
for (VAARecord record : parser) {
if (record != null) {
try {
record.constructDataURI();
if (!checkForDup(record)) {
obsList.add(record);
}
} catch (PluginException e) {
logger.error(traceId
+ "- Unable to construct dataURI", e);
record = null;
}
// overwrite will only happen if a correction is issued
// within the same minute as the original
record.setOverwriteAllowed(true);
obsList.add(record);
}
}
} catch (Exception e) {
@ -119,37 +105,4 @@ public class VAADecoder {
return decodedData;
}
/**
*
* @return
*/
public boolean isFailSafe() {
return failSafe;
}
/**
*
* @param value
*/
public void setFailSafe(boolean value) {
failSafe = value;
}
/**
*
* @param vaa
* @return
*/
private boolean checkForDup(VAARecord vaa) {
boolean isDup = false;
try {
VAARecordDao dao = new VAARecordDao(pluginName);
Object[] res = dao.queryDataUriColumn(vaa.getDataURI());
isDup = (res != null) && (res.length > 0);
} catch (Exception e) {
logger.error("Unable to create VAARecordDao", e);
}
return isDup;
}
}

View file

@ -1,93 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.vaa;
import java.util.List;
import com.raytheon.edex.db.dao.DefaultPluginDao;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.vaa.VAARecord;
import com.raytheon.uf.edex.database.DataAccessLayerException;
/**
*
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 04, 2009 jkorman Initial creation
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class VAARecordDao extends DefaultPluginDao {
/**
* Creates a new ObsStationDao
* @throws PluginException
*/
public VAARecordDao(String pluginName) throws PluginException {
super(pluginName);
}
/**
* Retrieves an Volcanic Ash report using the datauri .
*
* @param dataURI
* The dataURI to match against.
* @return The report record if it exists.
*/
public VAARecord queryByDataURI(String dataURI) {
VAARecord report = null;
List<?> obs = null;
try {
obs = queryBySingleCriteria("dataURI", dataURI);
} catch (DataAccessLayerException e) {
e.printStackTrace();
}
if ((obs != null) && (obs.size() > 0)) {
report = (VAARecord) obs.get(0);
}
return report;
}
/**
* Queries for to determine if a given data uri exists on the sfcobs table.
*
* @param dataUri
* The DataURI to find.
* @return An array of objects. If not null, there should only be a single
* element.
*/
public Object[] queryDataUriColumn(final String dataUri) {
String sql = "select datauri from awips.vaa where datauri='"
+ dataUri + "';";
Object[] results = executeSQLQuery(sql);
return results;
}
}

View file

@ -32,7 +32,7 @@ import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.edex.wmo.message.WMOHeader;
/**
* TODO Add Description
* Data structure for a Volcanic Ash Advisory
*
* <pre>
*
@ -41,6 +41,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 19, 2009 jkorman Initial creation
* Nov 26, 2013 2582 njensen Fix where OBS DTG is on separate lines
*
* </pre>
*
@ -49,22 +50,26 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
*/
public class InternalReport {
// private static Log logger = LogFactory.getLog(InternalReport.class);
public static final String VAAC_CNTR_P = "^((VAAC)(?:\\:) +(.*))";
public static final Pattern VAAC_CNTR_P = Pattern
.compile("^((VAAC)(?:\\:) +(.*))");
// PSN: N1642 W06210
// LOCATION: N1642 W06210
public static final String VOL_PSN_P = "(^(LOCATION|PSN)(?:\\:) +(.*))";
public static final Pattern VOL_PSN_P = Pattern
.compile("(^(LOCATION|PSN)(?:\\:) +(.*))");
public static final String LAT_LON_P = "([NS])(\\d{2,2})(\\d{2,2}) +([EW])(\\d{3,3})(\\d{2,2})";
public static final Pattern LAT_LON_P = Pattern
.compile("([NS])(\\d{2,2})(\\d{2,2}) +([EW])(\\d{3,3})(\\d{2,2})");
public static final String DTG_P = "^(OBS) +(VA|ASH) +DTG: +(.*)";
public static final Pattern DTG_P = Pattern
.compile("^(OBS) +(VA|ASH) +DTG: +(.*)");
public static final String ANAL_P = "^(OBS) +(VA|ASH) +(CLD|CLOUD): +(.*)";
public static final Pattern ANAL_P = Pattern
.compile("^(OBS) +(VA|ASH) +(CLD|CLOUD): +(.*)");
//
public static final String FCST_P = "^(FCST) +(VA|ASH) +(CLD|CLOUD) \\+(\\d{1,2})HR: +(.*)";
public static final Pattern FCST_P = Pattern
.compile("^(FCST) +(VA|ASH) +(CLD|CLOUD) \\+(\\d{1,2})HR: +(.*)");
//
// public static final String DATE_LINE =
@ -167,26 +172,21 @@ public class InternalReport {
}
List<String> lines = separateLines(message);
if (lines != null) {
Pattern p1 = Pattern.compile(VAAC_CNTR_P);
Pattern p2 = Pattern.compile(VOL_PSN_P);
Pattern p3 = Pattern.compile(FCST_P);
Pattern p4 = Pattern.compile(ANAL_P);
Pattern p5 = Pattern.compile(DTG_P);
Matcher m;
String previousLine = null;
for (String s : lines) {
if (s.length() > 0) {
m = p1.matcher(s);
m = VAAC_CNTR_P.matcher(s);
if (m.find()) {
reports.add(new InternalReport(InternalType.VAAC_CNTR,
m.group(3)));
} else {
m = p2.matcher(s);
m = VOL_PSN_P.matcher(s);
if (m.find()) {
reports.add(new InternalReport(
InternalType.VOLCANO_PSN, s));
} else {
m = p3.matcher(s);
m = FCST_P.matcher(s);
if (m.find()) {
reports.add(new InternalReport(
InternalType.FCST, s));
@ -196,9 +196,15 @@ public class InternalReport {
reports.add(new InternalReport(
InternalType.ADVISORY_LEAD, s));
} else if (s.startsWith("DTG:")) {
reports.add(new InternalReport(
InternalType.MESSAGE_DTG, s
.substring(5)));
if (previousLine != null
&& previousLine.startsWith("OBS")) {
reports.add(new InternalReport(
InternalType.OBS_DTG, s));
} else {
reports.add(new InternalReport(
InternalType.MESSAGE_DTG, s
.substring(5)));
}
} else if (s.startsWith("VOLCANO:")) {
reports.add(new InternalReport(
InternalType.VOLCANO_ID, s.substring(9)));
@ -222,12 +228,12 @@ public class InternalReport {
InternalType.ERUPTION_DETAIL, s
.substring(18)));
} else if (s.startsWith("OBS")) {
m = p4.matcher(s);
m = ANAL_P.matcher(s);
if (m.find()) {
reports.add(new InternalReport(
InternalType.OBS, s));
} else {
m = p5.matcher(s);
m = DTG_P.matcher(s);
if (m.find()) {
reports.add(new InternalReport(
InternalType.OBS_DTG, s));
@ -253,7 +259,7 @@ public class InternalReport {
}
}
}
previousLine = s;
} // for
}
return adjust(reports);
@ -302,7 +308,6 @@ public class InternalReport {
* @return The adjusted report list.
*/
private static List<InternalReport> adjust(List<InternalReport> reports) {
boolean advisoryLead = false;
if (reports != null) {
InternalReport currRpt = null;
for (int i = 0; i < reports.size();) {
@ -314,7 +319,6 @@ public class InternalReport {
break;
}
case ADVISORY_LEAD: {
advisoryLead = true;
// fall through
}
case MESSAGE_DTG:
@ -360,11 +364,9 @@ public class InternalReport {
}
public static final void main(String[] args) {
Pattern p = Pattern.compile(VOL_PSN_P);
Matcher m;
m = p.matcher("PSN: N1642 W06210");
m = VOL_PSN_P.matcher("PSN: N1642 W06210");
if (m.find()) {
for (int i = 1; i <= m.groupCount(); i++) {
System.out.println(String.format(" %3d %s", i, m.group(i)));
@ -372,7 +374,7 @@ public class InternalReport {
}
System.out
.println("--------------------------------------------------------");
m = p.matcher("LOCATION: N1642 W06210");
m = VOL_PSN_P.matcher("LOCATION: N1642 W06210");
if (m.find()) {
for (int i = 1; i <= m.groupCount(); i++) {
System.out.println(String.format(" %3d %s", i, m.group(i)));
@ -380,8 +382,7 @@ public class InternalReport {
}
System.out
.println("--------------------------------------------------------");
p = Pattern.compile(VAAC_CNTR_P);
m = p.matcher("VAAC: WASHINGTON");
m = VAAC_CNTR_P.matcher("VAAC: WASHINGTON");
if (m.find()) {
for (int i = 1; i <= m.groupCount(); i++) {
System.out.println(String.format(" %3d %s", i, m.group(i)));
@ -389,8 +390,7 @@ public class InternalReport {
}
System.out
.println("--------------------------------------------------------");
p = Pattern.compile(LAT_LON_P);
m = p.matcher("N1642 W06210");
m = LAT_LON_P.matcher("N1642 W06210");
if (m.find()) {
for (int i = 1; i <= m.groupCount(); i++) {
System.out.println(String.format(" %3d %s", i, m.group(i)));
@ -403,7 +403,7 @@ public class InternalReport {
String FCST_1_P = "(\\d{2}/\\d{4}Z +)";
p = Pattern.compile(FCST_P);
Pattern p = Pattern.compile(FCST_P);
// m =
// p.matcher("FCST VA CLD +6HR: 05/0130Z SFC/FL220 5NM WIDE LINE N1638 W06614 - N1643 W06214");
// m =

View file

@ -36,7 +36,7 @@ import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.wmo.message.WMOHeader;
/**
*
* Parser for Volcanic Ash Advisories
*
* <pre>
*
@ -45,6 +45,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
* ------------ ---------- ----------- --------------------------
* Nov 05, 2009 3267 jkorman Initial creation
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Nov 26, 2013 2582 njensen Cleanup
*
* </pre>
*
@ -53,6 +54,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
*/
public class VAAParser implements Iterable<VAARecord> {
// TODO should use JTS coordinate
private static class LatLon {
public Double lat;
@ -70,7 +72,21 @@ public class VAAParser implements Iterable<VAARecord> {
public String shapeType;
}
private final String pluginName;
private static final Pattern COR_P = Pattern.compile("(C[A-Z]{2})( +.*)?");
private static final Pattern SUMMIT_ELEV_P = Pattern
.compile("(\\d+) +FT +\\((\\d+) +[Mm]\\)");
private static final Pattern LINE_P = Pattern.compile("WID +LINE +BTN");
private static final Pattern DTG_P = Pattern.compile("(\\d{8}/\\d{4})(Z)");
private static final ThreadLocal<SimpleDateFormat> SDF = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd/HHmmZ");
}
};
private final WMOHeader wmoHeader;
@ -78,17 +94,13 @@ public class VAAParser implements Iterable<VAARecord> {
private final List<VAARecord> records = new ArrayList<VAARecord>();
private List<InternalReport> reports;
/**
*
* @param message
* @param wmoHeader
* @param pdd
*/
public VAAParser(String name, byte[] message, String traceId,
Headers headers) {
pluginName = name;
public VAAParser(byte[] message, String traceId, Headers headers) {
this.traceId = traceId;
wmoHeader = new WMOHeader(message, headers);
setData(message, headers);
@ -112,14 +124,15 @@ public class VAAParser implements Iterable<VAARecord> {
*/
private void setData(byte[] message, Headers headers) {
reports = InternalReport.identifyMessage(message, headers);
List<InternalReport> reports = InternalReport.identifyMessage(message,
headers);
VAARecord vaa = new VAARecord();
vaa.setTraceId(traceId);
vaa.setWmoHeader(wmoHeader.getWmoHeader());
String cor = wmoHeader.getBBBIndicator();
if (cor != null) {
Matcher m = Pattern.compile("(C[A-Z]{2})( +.*)?").matcher(cor);
Matcher m = COR_P.matcher(cor);
if (m.find()) {
vaa.setCorIndicator(m.group(1));
}
@ -208,8 +221,7 @@ public class VAAParser implements Iterable<VAARecord> {
*/
private LatLon parseLatLon(String latLon) {
LatLon latlon = null;
Pattern p = Pattern.compile(InternalReport.LAT_LON_P);
Matcher m = p.matcher(latLon);
Matcher m = InternalReport.LAT_LON_P.matcher(latLon);
if (m.find()) {
latlon = new LatLon();
latlon.lat = Double.parseDouble(m.group(2));
@ -230,8 +242,7 @@ public class VAAParser implements Iterable<VAARecord> {
*/
private int parseSummitElev(String summitElev) {
int elevation = -9999;
Matcher m = Pattern.compile("(\\d+) +FT +\\((\\d+) +[Mm]\\)").matcher(
summitElev);
Matcher m = SUMMIT_ELEV_P.matcher(summitElev);
if (m.find()) {
elevation = Integer.parseInt(m.group(2));
}
@ -245,17 +256,15 @@ public class VAAParser implements Iterable<VAARecord> {
DataTime dt = null;
// 20091104/1708Z
SimpleDateFormat dtFmt = new SimpleDateFormat("yyyyMMdd/HHmmZ");
if (dtg != null) {
Pattern p = Pattern.compile("(\\d{8}/\\d{4})(Z)");
Matcher m = p.matcher(dtg);
Matcher m = DTG_P.matcher(dtg);
if (m.find()) {
if ("Z".equals(m.group(2))) {
dtg = m.group(1) + "GMT";
}
}
ParsePosition pos = new ParsePosition(0);
Date d = dtFmt.parse(dtg, pos);
Date d = SDF.get().parse(dtg, pos);
if (pos.getErrorIndex() < 0) {
dt = new DataTime(d);
}
@ -271,9 +280,7 @@ public class VAAParser implements Iterable<VAARecord> {
*/
private void parseAnalData(InternalReport rpt, VAARecord vaa) {
String rptData = unPack(rpt, false);
Pattern p = Pattern.compile(InternalReport.ANAL_P);
Matcher m = p.matcher(rptData);
Matcher m = InternalReport.ANAL_P.matcher(rptData);
if (m.find()) {
if ("OBS".equals(m.group(1))) {
vaa.setAnal00Hr(unPack(rpt, true));
@ -315,11 +322,9 @@ public class VAAParser implements Iterable<VAARecord> {
*/
private void parseFcstData(InternalReport rpt, VAARecord vaa) {
String rptData = unPack(rpt, false);
String fcstPd = null;
Pattern p = Pattern.compile(InternalReport.FCST_P);
Matcher m = p.matcher(rptData);
Matcher m = InternalReport.FCST_P.matcher(rptData);
if (m.find()) {
if ("FCST".equals(m.group(1))) {
if ("6".equals(m.group(4))) {
@ -368,19 +373,15 @@ public class VAAParser implements Iterable<VAARecord> {
* @return
*/
private List<VAAShape> parseFeature(String rptData) {
Pattern latLonP = Pattern.compile(InternalReport.LAT_LON_P);
Pattern lineP = Pattern.compile("WID +LINE +BTN");
Pattern areaP = Pattern.compile(" ");
List<VAAShape> features = new ArrayList<VAAShape>();
String[] descriptions = rptData.split("SFC/");
if ((descriptions != null) && (descriptions.length > 1)) {
for (String description : descriptions) {
Matcher m = lineP.matcher(description);
Matcher m = LINE_P.matcher(description);
if (m.find()) {
// parse as a line
m = latLonP.matcher(description);
m = InternalReport.LAT_LON_P.matcher(description);
int pos = 0;
List<LatLon> points = new ArrayList<LatLon>();
while (m.find(pos)) {
@ -398,7 +399,7 @@ public class VAAParser implements Iterable<VAARecord> {
}
} else {
// handle as an area
m = latLonP.matcher(description);
m = InternalReport.LAT_LON_P.matcher(description);
int pos = 0;
List<LatLon> points = new ArrayList<LatLon>();
while (m.find(pos)) {
@ -473,7 +474,7 @@ public class VAAParser implements Iterable<VAARecord> {
+ "\r\r\n\u0003";
Headers headers = new Headers();
headers.put("ingestFileName", "FVXX20.20110106");
VAAParser p = new VAAParser("vaa", msg1.getBytes(), "TEST01", headers);
VAAParser p = new VAAParser(msg1.getBytes(), "TEST01", headers);
Iterator<VAARecord> it = p.iterator();
while (it.hasNext()) {
VAARecord r = it.next();
@ -481,39 +482,5 @@ public class VAAParser implements Iterable<VAARecord> {
System.out.println(r.getMessage());
}
// Matcher m =
// Pattern.compile("(\\d+) +FT +\\((\\d+) +[Mm]\\)").matcher("3002 FT (915 M)");
// if(m.find()) {
// for(int i = 0;i <= m.groupCount();i++) {
// System.out.println(m.group(i));
// }
// }
}
// ashdescription ::= 'SFC' '/' 'FL' digit digit digit ( line | area ) (
// movement ) .
//
// area ::= segments .
//
// line ::= digits 'NM' 'WID' 'LINE' 'BTN' segment '.' .
//
// movement ::=
//
// segments ::= segment ( spaces - spaces latlon ) .
//
// segment ::= latlon spaces - spaces latlon.
//
// latlon ::= lat spaces lon.
//
// lat ::= ['N' | 'S'] digit digit minutes .
// lon ::= ['E' | 'W'] digit digit digit minutes . // 1(([0-7]\d)|(80))
//
// minutes ::= ( '0' | '1' | '2' | '3' | '4' | '5' ) digit .
//
// digits ::= digit ( digits ) .
//
// digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
//
// spaces ::= space ( spaces ) .
//
// space ::= ' ' .
}