Issue #2582 Fix decoding where OBS DTG are on separate lines, cleanup
VAA and remove dataURI Change-Id: I984173a6e85eb7dc269fb98964af4915a9b5105e Former-commit-id:77c23c6d0e
[formerly9b3f871c21
] [formerly6bf1fd8d3c
] [formerly77c23c6d0e
[formerly9b3f871c21
] [formerly6bf1fd8d3c
] [formerly72c322c667
[formerly6bf1fd8d3c
[formerly 148e7113abefd684dcacb5ccc28bb77192ff45c8]]]] Former-commit-id:72c322c667
Former-commit-id:a25621ae6d
[formerly476f9da5ad
] [formerly 58b83a2d53b306277cdc9a0820852147a2519f74 [formerly2831ceb356
]] Former-commit-id: f8fdfa9a908f980ca803296046b6496e1b85e6e3 [formerlycbd12d4cc7
] Former-commit-id:da9d1b2447
This commit is contained in:
parent
aaf5dfbd62
commit
74c0067901
10 changed files with 145 additions and 333 deletions
53
deltaScripts/14.2.1/dropVAAdataURI.sh
Normal file
53
deltaScripts/14.2.1/dropVAAdataURI.sh
Normal 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"
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 =
|
||||
|
|
|
@ -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 ::= ' ' .
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue