Added back in the ldad/mesonet plugins so that we can decode the RAWS mesonet data.

-Also updated the Surface Obs menu to have a few menu options to load the RAWS data
This commit is contained in:
ucar-tmeyer 2023-09-27 13:04:01 +00:00
parent 0f45a4b964
commit 4e7b1f7721
63 changed files with 5405 additions and 23 deletions

View file

@ -28,28 +28,6 @@
<displays xsi:type="d2DMapRenderableDisplay"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<descriptor xsi:type="mapDescriptor">
<resource>
<loadProperties>
<capabilities>
<capability xsi:type="outlineCapability"
lineStyle="SOLID" outlineOn="true"
outlineWidth="1" />
<capability xsi:type="colorableCapability"
colorAsString="#9b9b9b" />
</capabilities>
<resourceType>PLAN_VIEW</resourceType>
</loadProperties>
<properties isSystemResource="false"
isBlinking="false" isMapLayer="true" isHoverOn="false"
isVisible="true">
<pdProps maxDisplayWidth="100000000"
minDisplayWidth="0" />
</properties>
<resourceData xsi:type="spiResourceData">
<filename>basemaps/ldad15.spi</filename>
<mapName>LDAD Stations</mapName>
</resourceData>
</resource>
<resource>
<loadProperties>
<capabilities>

View file

@ -11,6 +11,46 @@
<contribute xsi:type="bundleItem" file="bundles/SurfacePlotMetar.xml"
menuText="METAR Station Plot" id="MetarPlot">
</contribute>
<contribute xsi:type="bundleItem" file="bundles/LDADMesoPlot.xml"
menuText="30 min RAWS Plot" id="local30minstnplot">
<substitute key="svg" value="ldadMesoDesign.svg" />
<substitute key="legend" value="30 min RAWS Data Plot" />
<substitute key="posOffset" value="900" />
<substitute key="negOffset" value="900" />
</contribute>
<contribute xsi:type="subMenu" menuText="Other RAWS Plots">
<contribute xsi:type="bundleItem" file="bundles/LDADMesoPlot.xml"
menuText="15 min stn plot" id="local15minstnplot">
<substitute key="svg" value="ldadMesoDesign.svg" />
<substitute key="legend" value="15 min RAWS Data Plot" />
<substitute key="posOffset" value="450" />
<substitute key="negOffset" value="450" />
</contribute>
<contribute xsi:type="bundleItem" file="bundles/LDADMesoPlot.xml"
menuText="5 min stn plot" id="local5minstnplot">
<substitute key="svg" value="ldadMesoDesign.svg" />
<substitute key="legend" value="5 min RAWS Data Plot" />
<substitute key="posOffset" value="150" />
<substitute key="negOffset" value="150" />
</contribute>
<contribute xsi:type="bundleItem" file="bundles/LDADMesoPlot.xml"
menuText="1 min stn plot" id="local1minstnplot">
<substitute key="svg" value="ldadMesoDesign.svg" />
<substitute key="legend" value="1 min RAWS Data Plot" />
<substitute key="posOffset" value="30" />
<substitute key="negOffset" value="30" />
</contribute>
<contribute xsi:type="bundleItem" file="bundles/LDADMesoPlot.xml"
menuText="WindCh/HeatIdx" id="localWindChHeatIdx">
<substitute key="svg" value="ldadMesoHiWcDesign.svg" />
<substitute key="legend" value="RAWS WindChill/HeatIndex Plot" />
<substitute key="posOffset" value="900" />
<substitute key="negOffset" value="900" />
</contribute>
</contribute>
<contribute xsi:type="bundleItem" file="bundles/SurfaceMSLP.xml"
menuText="METAR MSLP Plot" id="MetarPlot">
</contribute>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.edex.plugin.ldad</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,16 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ldad Plug-in
Bundle-SymbolicName: com.raytheon.edex.plugin.ldad
Bundle-Version: 1.18.1.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-11
Export-Package: com.raytheon.edex.plugin.ldad.common
Require-Bundle: com.raytheon.uf.common.dataplugin.ldad,
com.raytheon.uf.common.pointdata,
com.raytheon.edex.common,
com.raytheon.uf.common.localization,
javax.measure,
org.slf4j,
javax.xml.bind
Import-Package: com.raytheon.uf.common.status

View file

@ -0,0 +1,6 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
utility/,\
.,\
res/

View file

@ -0,0 +1,17 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ldadPluginName" class="java.lang.String">
<constructor-arg type="java.lang.String" value="ldad" />
</bean>
<bean id="ldadProperties" class="com.raytheon.uf.common.dataplugin.PluginProperties">
<property name="pluginName" value="ldad" />
</bean>
<bean factory-bean="pluginRegistry" factory-method="register">
<constructor-arg value="ldad" />
<constructor-arg ref="ldadProperties" />
</bean>
</beans>

View file

@ -0,0 +1,575 @@
/**
* 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.edex.plugin.ldad;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.DateTimeException;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import javax.measure.IncommensurableException;
import javax.measure.UnconvertibleException;
import javax.measure.Unit;
import javax.xml.bind.JAXBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.raytheon.edex.plugin.ldad.common.DecodedData;
import com.raytheon.edex.plugin.ldad.common.LdadField;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.ldad.LdadRecord;
import com.raytheon.uf.common.localization.ILocalizationFile;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationUtil;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation;
import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.time.DataTime;
import net.sf.cglib.beans.BeanMap;
import tec.uom.se.format.SimpleUnitFormat;
/**
* Decoder implementation for ldadmesonet plugin.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------------------------
* Sep 04, 2009 vkorolev Initial creation
* May 15, 2013 1869 bsteffen Remove DataURI column from ldadmesonet.
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Jul 23, 2014 3410 bclement location changed to floats
* Aug 15, 2014 3530 bclement no longer extends AbstractDecoder
* Jul 08, 2016 5744 mapeters Config file moved from edex_static to
* common_static
* Dec 18, 2017 6897 tgurney Handle date value in a Double field
* Mar 06, 2018 6851 randerso Added lookup table for time zones. Lots of
* code cleanup.
* May 09, 2018 7288 randerso Use stationId if available
* Apr 15, 2019 7596 lsingh Updated units framework to JSR-363.
* Handled unit conversion.
*
* </pre>
*
* @author vkorolev
*/
public class LdadDecoder {
private static final Logger logger = LoggerFactory
.getLogger(LdadDecoder.class);
private static final String DATE_TIME_STRING_UNITS = "DATE_TIME_STRING";
private static final String OBSERVATION_TIME_KEY = "observationTime";
private static final String TIMEZONE_KEY = "_tz";
private static final String PROVIDER_ID_KEY = "providerId";
private static final String STATION_ID_KEY = "stationId";
private static final String LATITUDE_KEY = "_lat";
private static final String LONGITUDE_KEY = "_lon";
private static final String ELEVATION_KEY = "_elev";
private static final String BAD_PROPERTY_FMT = "NumberFormatException setting property %s.%s(%s %s)";
private static final String DATE_FORMAT = "yy/MM/dd HH:mm:ss";
private static final ThreadLocal<SimpleDateFormat> DateFormatter = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
private static JAXBManager jaxb;
private static Properties ldadUnitsMap = new Properties();
private static Date ldadUnitsDate = new Date(0);
private static String ldadUnitsChecksum = ILocalizationFile.NON_EXISTENT_CHECKSUM;
private static Properties ldadTimeZoneMap = new Properties();
private static Date ldadTimeZoneDate = new Date(0);
private static String ldadTimeZoneChecksum = ILocalizationFile.NON_EXISTENT_CHECKSUM;
private final Class<? extends LdadRecord> recordClass;
private final String storageType;
/**
* Constructor
*
* @param recordClass
* LdadRecord subclass to be decoded
* @param storageType
* storageType of LDAD files to accept. All others are ignored.
* @throws JAXBException
*/
public LdadDecoder(Class<? extends LdadRecord> recordClass,
String storageType) throws JAXBException {
this.recordClass = recordClass;
this.storageType = storageType;
synchronized (LdadDecoder.class) {
if (jaxb == null) {
jaxb = new JAXBManager(DecodedData.class);
}
}
}
/**
* Decode the raw data in to PluginDataObjects
*
* @param data
* the raw data
* @return the decoded records
*/
public PluginDataObject[] decode(byte[] data) {
PluginDataObject[] retVal = new PluginDataObject[0];
if (data != null) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
String filePath = LocalizationUtil.join("ldad", "ldadUnitsMap.txt");
ILocalizationFile lf = pathMgr.getStaticLocalizationFile(filePath);
if (lf != null) {
synchronized (ldadUnitsMap) {
// update the units map if necessary
if (loadPropertiesFile(ldadUnitsMap, lf, ldadUnitsDate,
ldadUnitsChecksum)) {
// update properties file info
ldadUnitsDate = lf.getTimeStamp();
ldadUnitsChecksum = lf.getCheckSum();
}
}
}
filePath = LocalizationUtil.join("ldad", "ldadTimeZoneMap.txt");
lf = pathMgr.getStaticLocalizationFile(filePath);
if (lf != null) {
synchronized (ldadTimeZoneMap) {
// update the time zone map if necessary
if (loadPropertiesFile(ldadTimeZoneMap, lf,
ldadTimeZoneDate, ldadTimeZoneChecksum)) {
// update properties file info
ldadTimeZoneDate = lf.getTimeStamp();
ldadTimeZoneChecksum = lf.getCheckSum();
}
}
}
try {
DecodedData dd = (DecodedData) jaxb.unmarshalFromInputStream(
new ByteArrayInputStream(data));
// Storage type separator
String currentFile = dd.fileName;
if (!this.storageType.equals(dd.storageType)) {
logger.warn(String.format(
"LDAD decoder for %s received file %s of type %s. File ignored.",
this.storageType, currentFile, dd.storageType));
return retVal;
}
// Header
String missingValue = dd.missingValue;
// Number of records
int numRecs = dd.fields.get(0).values.size();
if (numRecs == 0) {
logger.info("No data in file.");
return retVal;
}
// Create a map of fields
Map<String, LdadField> fieldMap = new HashMap<>(
dd.fields.size(), 1.0f);
for (LdadField field : dd.fields) {
fieldMap.put(field.variableName, field);
}
Set<String> keySet = new HashSet<>(fieldMap.keySet());
// Check for observation time
if (!fieldMap.containsKey(OBSERVATION_TIME_KEY)) {
logger.error(String.format(
"No observation times present in file %s",
currentFile));
return retVal;
}
// Check for lat/lon
if (!fieldMap.containsKey(LATITUDE_KEY)
|| !fieldMap.containsKey(LONGITUDE_KEY)) {
logger.error(String.format("No location present in file %s",
currentFile));
return retVal;
}
// Assume UTC if no time zone specified in file
if (!fieldMap.containsKey(TIMEZONE_KEY)) {
logger.warn(String.format(
"No time zone specified in file %s, assuming UTC",
currentFile));
}
// Loop through records
BeanMap beanMap = BeanMap.create(recordClass.newInstance());
List<PluginDataObject> records = new ArrayList<>(numRecs);
for (int i = 0; i < numRecs; i++) {
LdadRecord record = recordClass.newInstance();
SurfaceObsLocation location = new SurfaceObsLocation();
record.setDataProvider(dd.provider);
record.setStationType(dd.type);
record.setReportTime(dd.reportTime);
// Set of all known keys remaining to be processed
keySet.addAll(fieldMap.keySet());
// Get time zone if present
TimeZone timeZone = UTC;
if (keySet.contains(TIMEZONE_KEY)) {
String tz = fieldMap.get(TIMEZONE_KEY).values.get(i);
keySet.remove(TIMEZONE_KEY);
synchronized (ldadTimeZoneMap) {
tz = ldadTimeZoneMap.getProperty(tz, tz);
}
try {
ZoneId zoneId = ZoneId.of(tz);
timeZone = TimeZone.getTimeZone(zoneId);
} catch (DateTimeException e) {
logger.error(String.format(
"Unrecognized time zone: %s in record %d of file %s, assuming UTC",
tz, i, currentFile), e);
}
}
// Get observation time
LdadField field = fieldMap.get(OBSERVATION_TIME_KEY);
keySet.remove(OBSERVATION_TIME_KEY);
String value = field.values.get(i);
if (missingValue.equals(value)) {
logMissingValue(field, i, currentFile);
continue;
}
try {
record.setObservationTime(parseDate(value, timeZone));
} catch (ParseException e) {
logValueError(field, i, currentFile, e);
continue;
}
// Get location
field = fieldMap.get(LATITUDE_KEY);
keySet.remove(LATITUDE_KEY);
value = field.values.get(i);
if (missingValue.equals(value)) {
logMissingValue(field, i, currentFile);
continue;
}
float latitude;
try {
latitude = Float.parseFloat(value);
} catch (NumberFormatException e) {
logValueError(field, i, currentFile, e);
continue;
}
field = fieldMap.get(LONGITUDE_KEY);
keySet.remove(LONGITUDE_KEY);
value = field.values.get(i);
if (missingValue.equals(value)) {
logMissingValue(field, i, currentFile);
continue;
}
float longitude;
try {
longitude = Float.parseFloat(value);
} catch (NumberFormatException e) {
logValueError(field, i, currentFile, e);
continue;
}
location.assignLocation(latitude, longitude);
if (keySet.contains(ELEVATION_KEY)) {
field = fieldMap.get(ELEVATION_KEY);
keySet.remove(ELEVATION_KEY);
value = field.values.get(i);
if (!missingValue.equals(value)) {
try {
// elevation in meter - integer in location
double elevation = Double.parseDouble(value);
location.setElevation(
(int) Math.round(elevation));
} catch (NumberFormatException e) {
logValueError(field, i, currentFile, e);
}
}
}
// set station ID to provider ID in case station ID is not
// present
if (keySet.contains(PROVIDER_ID_KEY)) {
field = fieldMap.get(PROVIDER_ID_KEY);
// leave provider id in key set so providerId field is
// populated in the record
value = field.values.get(i);
location.setStationId(value);
}
if (keySet.contains(STATION_ID_KEY)) {
field = fieldMap.get(STATION_ID_KEY);
keySet.remove(STATION_ID_KEY);
value = field.values.get(i);
location.setStationId(value);
}
// Loop through remaining fields
beanMap.setBean(record);
for (String key : keySet) {
field = fieldMap.get(key);
String name = field.variableName;
if (beanMap.containsKey(name)) {
String units = field.units;
value = field.values.get(i);
if (!missingValue.equals(value)) {
try {
// try setting field via reflection
setProperty(name, beanMap, value, units,
timeZone);
} catch (Throwable e) {
logPropertyError(field, i, currentFile, e);
}
}
} else {
/*
* Some fields are not supported. Perfectly valid
* data can cause this exception so we log it as
* debug
*/
logger.debug(String.format(
"Unrecognized field: %s, will be ignored.",
name));
}
}
record = (LdadRecord) beanMap.getBean();
// DataTime = Observation time
Date ot = record.getObservationTime();
if (ot != null) {
DataTime dt = new DataTime(ot);
record.setDataTime(dt);
record.setLocation(location);
record.setRawMessage(record.toMessage());
records.add(record);
}
}
retVal = records.toArray(new PluginDataObject[records.size()]);
} catch (SerializationException e) {
logger.error("Unable to unmarshall xml:", e);
} catch (RuntimeException e) {
logger.error("Error decoding ldad mesonet data:" + e);
} catch (InstantiationException | IllegalAccessException e) {
logger.error("Unable to instantiate class: "
+ this.recordClass.getName(), e);
}
}
return retVal;
}
/**
* Loads properties from a localization file
*
* @param props
* properties instance to be updated
* @param lf
* localization file from which to load properties
* @return true if properties were successfully loaded
*/
private boolean loadPropertiesFile(Properties props, ILocalizationFile lf,
Date lastTimeStamp, String lastChecksum) {
boolean status = false;
if (lf.exists() && (!lastChecksum.equals(lf.getCheckSum())
|| !lastTimeStamp.equals(lf.getTimeStamp()))) {
try (InputStream is = lf.openInputStream()) {
Properties newProps = new Properties();
newProps.load(is);
props.clear();
props.putAll(newProps);
status = true;
} catch (LocalizationException | IOException e) {
logger.error("Error loading properites from: " + lf, e);
}
}
return status;
}
private void logMissingValue(LdadField field, int index, String file) {
logger.error(String.format(
"Missing value in field: %s value: %s with units: %s for file: %s",
field.variableName, field.values.get(index), field.units,
file));
}
private void logValueError(LdadField field, int index, String file,
Throwable e) {
logger.error(String.format(
"Invalid value in field: %s value: %s with units: %s for file: %s",
field.variableName, field.values.get(index), field.units, file),
e);
}
private void logPropertyError(LdadField field, int index, String file,
Throwable e) {
logger.error(String.format(
"Unable to set property %s to value: %s with units: %s for file: %s",
field.variableName, field.values.get(index), field.units, file),
e);
}
private void setProperty(String name, BeanMap beanMap, String value,
String units, TimeZone timeZone) throws ParseException {
Object val = null;
boolean abort = false;
Class<?> clazz = beanMap.getPropertyType(name);
// Type filter
if (String.class == clazz) {
val = value.trim();
} else if (Calendar.class == clazz) {
val = parseDate(value, timeZone);
} else if (DATE_TIME_STRING_UNITS.equals(units)) {
// String date/time in a Double field, convert to epoch seconds
Date date = parseDate(value, timeZone);
val = date.getTime() / 1000.0;
} else {
// Get rid of some troublesome data
// TODO: find out what should be done with these values
abort = "B".equals(value);
abort |= "R".equals(value);
abort |= "V".equals(value);
abort |= "NAN0".equals(value);
if (!abort) {
Double tval = null;
try {
tval = Double.parseDouble(value);
} catch (NumberFormatException nfe) {
String msg = String.format(BAD_PROPERTY_FMT,
beanMap.getBean().getClass().getSimpleName(), name,
clazz.getSimpleName(), value);
logger.error(msg, nfe);
return;
}
synchronized (ldadUnitsMap) {
if (ldadUnitsMap.containsKey(units)) {
String translatedUnit = ldadUnitsMap.getProperty(units,
units);
Unit<?> inUnit = (Unit<?>) SimpleUnitFormat.getInstance(SimpleUnitFormat.Flavor.ASCII)
.parseObject(translatedUnit, new ParsePosition(0));
String propUnit = ldadUnitsMap.getProperty(name);
if (propUnit == null) {
logger.error(String.format(
"No units defined in ldadUnitsMap.txt for property: %s",
name));
} else {
Unit<?> outUnit = (Unit<?>) SimpleUnitFormat.getInstance(SimpleUnitFormat.Flavor.ASCII)
.parseObject(propUnit, new ParsePosition(0));
try {
tval = inUnit.getConverterToAny(outUnit)
.convert((tval).doubleValue());
} catch (IncommensurableException | UnconvertibleException e) {
logger.error(String.format(
"Property[%s] Input unit %s not compatible with Output unit %s",
name, units, outUnit), e);
return;
}
}
}
}
if (clazz == Integer.class) {
val = tval.intValue();
} else if (clazz == Short.class) {
val = tval.shortValue();
} else if (clazz == Float.class) {
val = tval.floatValue();
} else {
val = tval;
}
}
}
if (!abort) {
beanMap.put(name, val);
}
}
private Date parseDate(String dateTime, TimeZone timeZone)
throws ParseException {
SimpleDateFormat sdf = DateFormatter.get();
sdf.setTimeZone(timeZone);
Date date = sdf.parse(dateTime);
return date;
}
}

View file

@ -0,0 +1,67 @@
/**
* 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.edex.plugin.ldad.common;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Decoded LDAD XML data structure.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 08/17/09 dfriedman Initial creation
*
* </pre>
*
* @author dfriedman
* @version 1.0
*/
@XmlRootElement
public class DecodedData {
@XmlAttribute
public String fileName; // original file name
@XmlAttribute
public String storageType; // "mesonet", "hydro", etc.
@XmlAttribute
public String type; // data type name or "msas_qc.<derived name>"
@XmlAttribute
public String root; // original data type name
@XmlAttribute
public String source; // same as type?
@XmlAttribute
public String provider; // data type name? or "MSAS_QC"
@XmlAttribute
public String missingValue;
@XmlAttribute
public long reportTime; // Report time in seconds since 1/1/1970
@XmlElement(name="field")
public List<LdadField> fields = new ArrayList<LdadField>();
}

View file

@ -0,0 +1,59 @@
/**
* 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.edex.plugin.ldad.common;
/**
* Decoded LDAD data types.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 08/17/09 dfriedman Initial creation
*
* </pre>
*
* @author dfriedman
* @version 1.0
*/
public enum LdadDataType {
STRING(0),
DATE_TIME(1),
SHORT(2), INT(3), LONG(4),
FLOAT(5), DOUBLE(6);
private int id;
private LdadDataType(int id) {
this.id = id;
}
public boolean isNumeric() {
return this != STRING && this != DATE_TIME;
}
public static LdadDataType fromId(int id) {
for (LdadDataType t : LdadDataType.values())
if (t.getId() == id)
return t;
return null;
}
private int getId() {
return id;
}
}

View file

@ -0,0 +1,56 @@
/**
* 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.edex.plugin.ldad.common;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* Decoded LDAD XML data structure.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 08/17/09 dfriedman Initial creation
*
* </pre>
*
* @author dfriedman
* @version 1.0
*/
@XmlType(name="field")
public class LdadField {
@XmlAttribute
public String variableName;
@XmlAttribute
public String units;
@XmlAttribute
public LdadDataType type;
@XmlElement(name="v")
//@XmlList
public List<String> values = new ArrayList<String>();
}

View file

@ -0,0 +1,36 @@
##
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------- -------- --------- --------------------------------------------
# Mar 05, 2018 6851 randerso Initial creation
#
##
##
# This is an absolute override file, indicating that a higher priority version
# of the file will completely replace a lower priority version of the file.
##
##
# This file contains a mapping of time zone strings used by LDAD data
# to valid time zones recognized by java.time.ZoneId
##
EST GMT-0500
EST5 GMT-0500
CST GMT-0600
CST6 GMT-0600
MST GMT-0700
MST7 GMT-0700
PST GMT-0800
PST8 GMT-0800
AKST GMT-0900
AKST9 GMT-0900
AST10 GMT-1000
HST GMT-1000
HST10 GMT-1000
HAST GMT-1000
HAST10 GMT-1000
ChST GMT+1000
CHST GMT+1000

View file

@ -0,0 +1,305 @@
#$Id: ldatUnitsMap.txt 2009-09-28 slav Exp $
##
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------- -------- --------- --------------------------------------------
# Sep 28, 2009 slav Initial Creation.
# Mar 05, 2018 6851 randerso Added description of override behavior
#
##
##
# This is an absolute override file, indicating that a higher priority version
# of the file will completely replace a lower priority version of the file.
##
#====================================================================================
# LDAD FIELD UNITS
#--------------------------------------------------
# dataProvider # Typical data providers: CDoT, KDoT, UDFCD, etc.
# homeWFO
# observationTime # observationTime
# SurfaceObsLocation location # latitude, longitude, elevation, stationId "RALC2"
# providerId # "110" "FA6026DA" Data Provider station Id
# stationName # "Ralston_Res" "BEN CREEK AIRSTRIP" ?????????????????
# handbook5Id # "" ????????????????
# stationType # "STO" "RAWS" ????????????
# reportTime # 1.247436157E9 time data was processed by the provider
# receivedTime # time data was received - seconds since 1-1-1970
# numericWMOid # numeric WMO identification
# dataPlatformType # short -32767 moving (e.g. floating buoy or ship)
# tempChangeTime # time of temperature last change - seconds since 1970-1-1 00:00:00.0
# rhChangeTime # time of last relative humidity change
# stationPressChangeTime # time of last station press change
# pressChangeChar # long_name = "character of pressure change"
# windDirChangeTime # seconds since 1970-1-1 00:00:00.0
# windSpeedChangeTime
# windGustChangeTime
# skyCover # char ref FMH-1
# visibilityStatus
# totalCloudCover # tenths
# presWeather # present weather ref FMH-1
# lowLevelCloudType # lowLevelCloudType:long_name = "low level cloud type"
# midLevelCloudType # midLevelCloudType:long_name = "middle level cloud type"
# highLevelCloudType # highLevelCloudType:long_name = "high level cloud type"
# maxTempRecordPeriod # maxTempRecordPeriod:long_name = "maximum temperature recording period"
# minTempRecordPeriod # minTempRecordPeriod:long_name = "minimum temperature recording period"
# precipType # precipType:long_name = "precipitation type"
# timeSinceLastPcp # seconds
# solarRadChangeTime # seconds since 1970-1-1 00:00:00.0
# rawMessage
# cloudBaseHeight # cloudBaseHeight:long_name = "height of the lowest cloud layer"
# precipIntensity # precipIntensity:long_name = "precipitation intensity"
#----------------------------------------------------
# ldad_mesonet VarName stored units
#--------------------------------------------------
latitude degree_angle
longitude degree_angle
elevation m
platformTrueDirection degree_angle
platformTrueSpeed m/s
wetBulbTemperature K
stationPressure Pa
pressChange3Hour Pa
windDirMin degree_angle
windDirMax degree_angle
skyLayerBase m
visibility m
maximumTemperature K
minimumTemperature K
precipAccum mm
solarRadiation W/m^2
seaSurfaceTemp K
wavePeriod s
waveHeight m
temperature K
dewpoint K
relHumidity %
windDir degree_angle
windSpeed m/s
windGust m/s
pressure Pa
seaLevelPressure Pa
altimeter Pa
precipRate m/s
fuelTemperature K
fuelMoisture %
soilTemperature K
soilMoisture %
#--------------------------------------------------
# ldad_hydro VarName stored units
#--------------------------------------------------
# voltageBattery volt
# waterConductance microS/cm
# waterOxygen mg/l
# waterPH pH
# riverReportChangeTime
belowSurface m
riverStage m
poolElevation m
tailwaterStage m
riverVelocity km/h
riverInflow m^3/s
riverFlow m^3/s
computedOutflow m^3/s
waterTemperature K
windSpeedPeak m/s
precip5min mm
precip1hr mm
precip3hr mm
precip6hr mm
precip12hr mm
precip18hr mm
precip24hr mm
# ====================================================
# UNITS OF THERMODYNAMIC TEMPERATURE
#
# KELVIN KELVIN
# CELSIUS KELVIN @ 273.15
# RANKINE KELVIN/1.8
# FAHRENHEIT RANKINE @ 459.67
# C CELSIUS # `C' means `coulomb'
Celsius Celsius
celsius Celsius
degree_centigrade Celsius
degC Celsius
degreeC Celsius
degree_C Celsius
degree_c Celsius
deg_C Celsius
deg_c Celsius
degK K
degreeK K
degree_K K
degree_k K
deg_K K
deg_k K
K K
degF degree_fahrenheit
degreeF degree_fahrenheit
degree_F degree_fahrenheit
degree_f degree_fahrenheit
deg_F degree_fahrenheit
deg_f degree_fahrenheit
F degree_fahrenheit
Fahrenheit degree_fahrenheit
fahrenheit degree_fahrenheit
# R RANKINE # `R' means `roentgen'
degR degree_rankine
degreeR degree_rankine
degree_R degree_rankine
degree_r degree_rankine
deg_R degree_rankine
deg_r degree_rankine
Rankine degree_rankine
rankine degree_rankine
# -----------------------------------------
# Relative humidity
% %
# -----------------------------------------
# UNITS OF LENGTH
#
m m
meter m
meters m
metre m
metres m
mm mm
# God help us! There's an international foot and a US survey foot and
# they're not the same!
# International foot stuff:
international_inch in
international_foot ft
international_feet ft
international_yard yd
international_mile mi
# Alias unspecified units to the international units:
inch in
foot ft
yard yd
mile mi
# The following should hold regardless:
inches in
in in
ft ft
feet ft
yd yd
yards yd
nmile nmi
nmi nmi
# -----------------------------------------
# UNITS OF TIME
#
day d
hour h
minute min
s s
sec s
common_year year
d day
min min
hr h
h h
week week
year year
yr year
a year
month month
# -----------------------------------------
# UNITS OF PLANE ANGLE
#
# rad rad
# circle rev
degree_angle degree_angle
angular_degree degree_angle
# turn rev
degree degree_angle
degree_true degree_angle
arcdeg degree_angle
angular_minute degree_angle/60
angular_second degree_angle/3600
degree_north degree_angle
degreeN degree_angle
degree_N degree_angle
degrees_north degree_angle
degreesN degree_angle
degrees_N degree_angle
degree_east degree_angle
degreeE degree_angle
degree_E degree_angle
degrees_east degree_angle
degreesE degree_angle
degrees_E degree_angle
degree_west degree_angle*-1
degreeW degree_angle*-1
degree_W degree_angle*-1
degrees_west degree_angle*-1
degreesW degree_angle*-1
degrees_W degree_angle*-1
degrees_true degree_angle
degreeT degree_angle
degree_T degree_angle
degreesT degree_angle
degrees_T degree_angle
# -----------------------------------------
# PRESSURE OR STRESS
#
bar bar
mB bar/1000
standard_atmosphere atm
technical_atmosphere kgf/cm^2
Pa Pa
inch_Hg inHg
inch_hg inHg
inHg inHg
in_Hg inHg
in_hg inHg
millimeter_Hg mmHg
mmHg mmHg
mm_Hg mmHg
mm_hg mmHg
torr mmHg
# at kgf/cm^2
atmosphere atm
atm atm
# -----------------------------------------
# VELOCITY (INCLUDES SPEED)
#
# c m/s*299792458
knot kn
knot_international kn
international_knot kn
kt kn
m/s m/s
mph mph
kph km/h
mps m/s
iph in/h
mmph mm/h
# -----------------------------------------
# SOLAR RADIATION
W/meter2 W/m^2

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.common.dataplugin.ldad</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,13 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: LDAD Common
Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.ldad
Bundle-Version: 1.18.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: com.raytheon.uf.common.dataplugin.ldad
Require-Bundle: javax.persistence,
com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.pointdata
Import-Package: com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.serialization.annotations

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,126 @@
/**
* 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.common.dataplugin.ldad;
import java.util.Date;
import javax.persistence.MappedSuperclass;
import javax.persistence.SequenceGenerator;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Abstract base class for LDAD records
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- -----------------
* Mar 06, 2018 6851 randerso Initial creation
* Apr 24, 2019 6140 tgurney Remove Inheritance annotation
* (Hibernate 5.4 fix)
*
* </pre>
*
* @author randerso
*/
@MappedSuperclass
@SequenceGenerator(name = PluginDataObject.ID_GEN)
@DynamicSerialize
public abstract class LdadRecord extends PersistablePluginDataObject {
private static final long serialVersionUID = 1L;
/*
* TODO: move common fields from MesonetLdadRecord and HydroLdadRecord up to
* LdadRecord. Unfortunately this changes the dataURI so would require
* additional changes.
*/
/**
* Default Constructor
*/
public LdadRecord() {
super();
}
/**
* Constructor for DataURI construction through base class. This is used by
* the notification service.
*
* @param uri
* A data uri applicable to this class.
*/
public LdadRecord(String uri) {
super(uri);
}
/**
* @param dataProvider
* the dataProvider to set
*/
public abstract void setDataProvider(String dataProvider);
/**
* @param stationType
* the stationType to set
*/
public abstract void setStationType(String stationType);
/**
* @param reportTime
* the reportTime to set
*/
public abstract void setReportTime(long reportTime);
/**
* @return the observationTime
*/
public abstract Date getObservationTime();
/**
* @param observationTime
* the observationTime to set
*/
public abstract void setObservationTime(Date observationTime);
/**
* @param location
* the location to set
*/
public abstract void setLocation(SurfaceObsLocation location);
/**
* @param rawMessage
* the rawMessage to set
*/
public abstract void setRawMessage(String rawMessage);
/**
* @return record as rawMessage
*/
public abstract String toMessage();
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.common.dataplugin.ldadmesonet</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,16 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ldadmesonet Plug-in
Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.ldadmesonet
Bundle-Version: 1.18.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.serialization.annotations,
org.locationtech.jts.geom
Export-Package: com.raytheon.uf.common.dataplugin.ldadmesonet
Require-Bundle: javax.persistence,
com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.pointdata,
com.raytheon.uf.common.dataaccess,
com.raytheon.uf.common.dataplugin.ldad

View file

@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
res/

View file

@ -0,0 +1,13 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ldadmesonetDataAccessFactory" class="com.raytheon.uf.common.pointdata.dataaccess.PointDataAccessFactory" />
<bean factory-bean="dataAccessRegistry" factory-method="register">
<constructor-arg value="ldadmesonet"/>
<constructor-arg ref="ldadmesonetDataAccessFactory"/>
</bean>
</beans>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.common.dataplugin.qc</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,15 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Qc Plug-in
Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.qc
Bundle-Version: 1.18.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.pointdata
Export-Package: com.raytheon.uf.common.dataplugin.qc
Import-Package: com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.pointdata.spatial,
com.raytheon.uf.common.serialization.annotations,
com.raytheon.uf.common.status,
javax.persistence

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,197 @@
/**
* 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.common.dataplugin.qc;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.annotations.NullString;
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.pointdata.IPointData;
import com.raytheon.uf.common.pointdata.PointDataView;
import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Record class for QC data
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 07, 2009 3408 bphillip Initial creation
* Apr 04, 2013 1846 bkowal Added an index on refTime and
* forecastTime
* Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation.
* May 07, 2013 1869 bsteffen Remove dataURI column from
* PluginDataObject.
* May 16, 2013 1869 bsteffen Remove DataURI column from qc.
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Feb 27, 2014 2852 rferrel Add getter/setter to FakePointDataView.
* Jul 21, 2015 4360 rferrel Named unique constraint.
* Jan 04, 2018 6861 njensen Removed unnecessary fields, use PointDataView
* Aug 08, 2022 8892 tjensen Update indexes for Hibernate 5
*
*
* </pre>
*
* @author bphillip
*/
@Entity
@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "qcseq")
/*
* Both refTime and forecastTime are included in the refTimeIndex since
* forecastTime is unlikely to be used.
*/
@Table(name = "qc", uniqueConstraints = {
@UniqueConstraint(name = "uk_qc_datauri_fields", columnNames = {
"stationid", "reftime", "qcType", "latitude",
"longitude" }) }, indexes = {
@Index(name = "%TABLE%_refTimeIndex", columnList = "refTime, forecastTime"),
@Index(name = "%TABLE%_stationIndex", columnList = "stationId") })
@DynamicSerialize
public class QCRecord extends PersistablePluginDataObject
implements ISpatialEnabled, IPointData {
private static final long serialVersionUID = -8836262244188895665L;
@Embedded
@DataURI(position = 2, embedded = true)
@DynamicSerializeElement
private SurfaceObsLocation location;
@Column(nullable = false, length = 20)
@DataURI(position = 1)
@NullString
@DynamicSerializeElement
private String qcType;
@Column(length = 15)
private String ncSet;
private PointDataView pointDataView;
public QCRecord() {
}
public QCRecord(String uri) {
super(uri);
}
public String getStationId() {
return location.getStationId();
}
/**
* @return the location
*/
public SurfaceObsLocation getLocation() {
return location;
}
/**
* @param location
* the location to set
*/
public void setLocation(SurfaceObsLocation location) {
this.location = location;
}
public float getLatitude() {
return location.getLatitude().floatValue();
}
public float getLongitude() {
return location.getLongitude().floatValue();
}
public float getElevation() {
return location.getElevation();
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
/**
* @return the ncSet
*/
public String getNcSet() {
return ncSet;
}
/**
* @param ncSet
* the ncSet to set
*/
public void setNcSet(String ncSet) {
this.ncSet = ncSet;
}
@Override
public ISpatialObject getSpatialObject() {
return location;
}
/**
* @return the qcType
*/
public String getQcType() {
return qcType;
}
/**
* @param qcType
* the qcType to set
*/
public void setQcType(String qcType) {
this.qcType = qcType;
}
@Override
public PointDataView getPointDataView() {
return pointDataView;
}
@Override
public void setPointDataView(PointDataView pointDataView) {
this.pointDataView = pointDataView;
}
@Override
public String getPluginName() {
return "qc";
}
}

View file

@ -45,6 +45,19 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.dataplugin.ldad"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.dataplugin.ldadmesonet"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.dataplugin.lsr"
download-size="0"
@ -52,6 +65,13 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.dataplugin.qc"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.common.dataplugin.sfcobs"
download-size="0"
@ -94,6 +114,13 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.edex.plugin.ldad"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.edex.plugin.obs"
download-size="0"
@ -143,6 +170,13 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.plugin.ldadmesonet"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.plugin.lsr"
download-size="0"
@ -150,6 +184,13 @@
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.plugin.qc"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.plugin.svrwx"
download-size="0"

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.edex.plugin.ldadmesonet</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ldadmesonet Plug-in
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.ldadmesonet
Bundle-Version: 1.18.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.raytheon.uf.common.dataplugin.ldad,
com.raytheon.uf.common.dataplugin.ldadmesonet,
com.raytheon.edex.common,
com.raytheon.uf.edex.pointdata
Import-Package: com.raytheon.uf.common.status

View file

@ -0,0 +1,6 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
utility/,\
.,\
res/

View file

@ -0,0 +1,91 @@
<?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.
-->
<pointDataDescription>
<!--parameter name = "dataProvider" numDims="1" type="STRING" size="256"/-->
<!--parameter name = "homeWFO" numDims="1" type="STRING" size="4"/-->
<parameter name = "observationTime" numDims="1" type="LONG"/>
<!--parameter name = "providerId" numDims="1" type="STRING" size="12"/-->
<!--parameter name = "stationName" numDims="1" type="STRING" size="51"/-->
<!--parameter name = "handbook5Id" numDims="1" type="STRING" size="256"/-->
<!--parameter name = "stationType" numDims="1" type="STRING" size="256"/-->
<!--parameter name = "latitude" numDims="1" type="FLOAT" unit="degree_N" /-->
<!--parameter name = "longitude" numDims="1" type="FLOAT" unit="degree_E" /-->
<!--parameter name = "elevation" numDims="1" type="FLOAT" unit="m" /-->
<!--parameter name = "stationId" numDims="1" type="STRING" size="6"/-->
<parameter name = "reportTime" numDims="1" type="LONG"/>
<parameter name = "receivedTime" numDims="1" type="LONG"/>
<parameter name = "numericWMOid" numDims="1" type="LONG"/>
<parameter name = "dataPlatformType" numDims="1" type="INT"/>
<parameter name = "platformTrueDirection" numDims="1" unit="degree" type="FLOAT"/>
<parameter name = "platformTrueSpeed" numDims="1" unit="m/s" type="FLOAT"/>
<parameter name = "tempChangeTime" numDims="1" type="LONG"/>
<parameter name = "wetBulbTemperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "rhChangeTime" numDims="1" type="LONG"/>
<parameter name = "stationPressure" numDims="1" unit="Pa" type="FLOAT"/>
<parameter name = "stationPressChangeTime" numDims="1" type="LONG"/>
<parameter name = "pressChangeChar" numDims="1" type="INT"/>
<parameter name = "pressChange3Hour" numDims="1" unit="Pa" type="FLOAT"/>
<parameter name = "windDir" numDims="1" unit="degree" type="FLOAT"/>
<parameter name = "windDirChangeTime" numDims="1" type="LONG"/>
<parameter name = "windSpeedChangeTime" numDims="1" type="LONG"/>
<parameter name = "windGustChangeTime" numDims="1" type="LONG"/>
<parameter name = "windDirMin" numDims="1" unit="degree" type="FLOAT"/>
<parameter name = "windDirMax" numDims="1" unit="degree" type="INT"/>
<parameter name = "skyCover" numDims="1" type="STRING" size="6"/>
<parameter name = "skyLayerBase" numDims="1" type="FLOAT"/>
<parameter name = "visibility" numDims="1" unit="m" type="FLOAT"/>
<parameter name = "visibilityStatus" numDims="1" type="STRING" size="256"/>
<parameter name = "totalCloudCover" numDims="1" type="FLOAT"/>
<parameter name = "cloudBaseHeight" numDims="1" type="INT"/>
<parameter name = "presWeather" numDims="1" type="STRING" size="25"/>
<parameter name = "lowLevelCloud" numDims="1" type="INT"/>
<parameter name = "midLevelCloud" numDims="1" type="INT"/>
<parameter name = "highLevelCloud" numDims="1" type="INT"/>
<parameter name = "maxTempRecordPeriod" numDims="1" type="INT"/>
<parameter name = "maximumTemperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "minTempRecordPeriod" numDims="1" type="INT"/>
<parameter name = "minimumTemperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "precipAccum" numDims="1" unit="mm" type="FLOAT"/>
<parameter name = "precip" numDims="1" type="INT"/>
<parameter name = "precipIntensity" numDims="1" type="INT"/>
<parameter name = "precipType" numDims="1" type="INT"/>
<parameter name = "timeSinceLastPcp" numDims="1" unit="s" type="LONG"/>
<parameter name = "solarRadiation" numDims="1" unit="W*m^-2" type="FLOAT"/>
<parameter name = "solarRadChangeTime" numDims="1" unit="s" type="LONG"/>
<parameter name = "seaSurfaceTemp" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "wavePeriod" numDims="1" unit="s" type="FLOAT"/>
<parameter name = "waveHeight" numDims="1" unit="m" type="FLOAT"/>
<parameter name = "rawMessage" numDims="1" type="STRING" size="512"/>
<parameter name = "temperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "dewpoint" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "relHumidity" numDims="1" unit="%" type="FLOAT"/>
<parameter name = "windSpeed" numDims="1" unit="m/s" type="FLOAT"/>
<parameter name = "windGust" numDims="1" unit="m/s" type="FLOAT"/>
<parameter name = "pressure" numDims="1" unit="Pa" type="FLOAT"/>
<parameter name = "seaLevelPressure" numDims="1" unit="Pa" type="FLOAT"/>
<parameter name = "altimeter" numDims="1" unit="Pa" type="FLOAT"/>
<parameter name = "precipRate" numDims="1" unit="m/s" type="FLOAT"/>
<parameter name = "fuelTemperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "fuelMoisture" numDims="1" unit="%" type="FLOAT"/>
<parameter name = "soilTemperature" numDims="1" unit="K" type="FLOAT"/>
<parameter name = "soilMoisture" numDims="1" unit="%" type="FLOAT"/>
<!-- parameter name = "dataURI" numDims="1" type="STRING" size="128"/-->
</pointDataDescription>

View file

@ -0,0 +1,30 @@
<?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.
-->
<pointDataDbDescription>
<parameter name="latitude" queryName="location.latitude" type="FLOAT" unit="°" />
<parameter name="longitude" queryName="location.longitude" type="FLOAT" unit="°" />
<parameter name="elevation" queryName="location.elevation" type="FLOAT" fillValue="-9999" unit="m" />
<parameter name="stationId" queryName="location.stationId" type="STRING" />
<parameter name="reportType" queryName="reportType" type="STRING" />
<parameter name="dataProvider" queryName="dataProvider" type="STRING" />
<parameter name="refTime" queryName="dataTime.refTime" numDims="1" type="LONG" unit="ms"/>
<parameter name="forecastHr" queryName="dataTime.fcstTime" numDims="1" type="INT" unit="h" dbunit="s"/>
</pointDataDbDescription>

View file

@ -0,0 +1,21 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mesonetPluginName" class="java.lang.String">
<constructor-arg type="java.lang.String" value="ldadmesonet" />
</bean>
<bean id="mesonetProperties" class="com.raytheon.uf.common.dataplugin.PluginProperties">
<property name="pluginName" value="ldadmesonet" />
<property name="pluginFQN" value="com.raytheon.uf.common.dataplugin.ldadmesonet" />
<property name="dao" value="com.raytheon.uf.edex.plugin.ldadmesonet.dao.LdadMesonetDao" />
<property name="record" value="com.raytheon.uf.common.dataplugin.ldadmesonet.MesonetLdadRecord" />
</bean>
<bean factory-bean="pluginRegistry" factory-method="register">
<constructor-arg ref="mesonetPluginName" />
<constructor-arg ref="mesonetProperties" />
</bean>
</beans>

View file

@ -0,0 +1,45 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="mesonetDecoder" class="com.raytheon.edex.plugin.ldad.LdadDecoder">
<constructor-arg value="com.raytheon.uf.common.dataplugin.ldadmesonet.MesonetLdadRecord" />
<constructor-arg value="mesonet" />
</bean>
<bean id="mesonetDatabase" class="java.lang.String">
<constructor-arg type="java.lang.String" value="metadata" />
</bean>
<bean id="ldadmesonetDistRegistry" factory-bean="distributionSrv"
factory-method="register">
<constructor-arg value="ldadmesonet" />
<constructor-arg value="jms-durable:queue:Ingest.ldadmesonet"/>
</bean>
<bean id="ldadmesonetPointData" class="com.raytheon.uf.edex.plugin.ldadmesonet.LdadmesonetPointDataTransform"/>
<camelContext id="ldadmesonet-camel"
xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<route id="ldadmesonetIngestRoute">
<from uri="jms-durable:queue:Ingest.ldadmesonet"/>
<doTry>
<pipeline>
<bean ref="stringToFile" />
<bean ref="mesonetDecoder" method="decode" />
<bean ref="dupElim" />
<bean ref="ldadmesonetPointData" method="toPointData" />
<to uri="direct-vm:persistIndexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="log:ldadmesonet?level=ERROR"/>
</doCatch>
</doTry>
</route>
</camelContext>
</beans>

View file

@ -0,0 +1,557 @@
/**
* 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.ldadmesonet;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.ldadmesonet.MesonetLdadRecord;
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.edex.plugin.ldadmesonet.dao.LdadMesonetDao;
/**
* Transform LDAD MESONET records into Point Data Model.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 09, 2009 DR2814 vkorolev Initial creation
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Jul 23, 2014 3410 bclement location changed to floats
* Aug 15, 2014 3530 bclement moved from common to edex
*
* </pre>
*
* @author vkorolev
* @version 1
*/
public class LdadmesonetPointDataTransform {
private LdadMesonetDao dao;
private PointDataDescription description;
// ------------------Common params (From OBS
// plugin)----------------------------
private static final String PRESS_CHANGE3_HOUR = "pressChange3Hour";
private static final String PRESS_CHANGE_CHAR = "pressChangeChar";
private static final String ALTIMETER = "altimeter";
private static final String WIND_GUST = "windGust";
private static final String WIND_SPEED = "windSpeed";
private static final String DEWPOINT = "dewpoint";
private static final String TEMPERATURE = "temperature";
private static final String PRES_WEATHER = "presWeather";
private static final String VISIBILITY = "visibility";
private static final String LONGITUDE = "longitude";
private static final String LATITUDE = "latitude";
private static final String ELEVATION = "elevation";
private static final String STATION_NAME = "stationName";
private static final String DATAURI = "dataURI";
// ------------------From LDAD mesonet netCDF------------------------
private static final String STORAGE_TYPE = "storageType";
private static final String STATION_ID = "stationId";
private static final String DATA_PROVIDER = "dataProvider";
private static final String HOME_WFO = "homeWFO";
private static final String OBSERVATION_TIME = "observationTime";
private static final String PROVIDER_ID = "providerId";
private static final String HANDBOOK5_ID = "handbook5Id";
private static final String STATION_TYPE = "stationType";
private static final String REPORT_TIME = "reportTime";
private static final String RECEIVED_TIME = "receivedTime";
private static final String NUMERICAL_WMO_ID = "numericWMOid";
private static final String DATA_PLATFORM_TYPE = "dataPlatformType";
private static final String PLATFORM_TRUE_DIRECTION = "platformTrueDirection";
private static final String PLARFORM_TRUE_SPEED = "platformTrueSpeed";
private static final String TEMP_CHANGE_TIME = "tempChangeTime";
private static final String WET_BULB_TEMPERATURE = "wetBulbTemperature";
private static final String RH_CHANGE_TIME = "rhChangeTime";
private static final String STATION_PRESSURE = "stationPressure";
private static final String STATION_PRESS_CHANGE_TIME = "stationPressChangeTime";
private static final String WIND_DIR_CHANGE_TIME = "windDirChangeTime";
private static final String WIND_SPEED_CHANGE_TIME = "windSpeedChangeTime";
private static final String WIND_GUST_CHANGE_TIME = "windGustChangeTime";
private static final String WIND_DIR_MIN = "windDirMin";
private static final String WIND_DIR_MAX = "windDirMax";
private static final String VISIBILITY_STATUS = "visibilityStatus";
private static final String TOTAL_CLOUD_COVER = "totalCloudCover";
private static final String CLOUD_BASE_HEIGHT = "cloudBaseHeight";
private static final String LOW_LEVEL_CLOUD_TYPE = "lowLevelCloudType";
private static final String MID_LEVEL_CLOUD_TYPE = "midLevelCloudType";
private static final String HIGH_LEVEL_CLOUD_TYPE = "highLevelCloudType";
private static final String MAX_TEMP_RECORD_PERIOD = "maxTempRecordPeriod";
private static final String MAXIMUM_TEMPERATURE = "maximumTemperature";
private static final String MIN_TEMP_RECORD_PERIOD = "minTempRecordPeriod";
private static final String MINIMUM_TEMPERATURE = "minimumTemperature";
private static final String PRECIP_ACCUM = "precipAccum";
private static final String PRECIP_TYPE = "precipType";
private static final String PRECIP_INTENSITY = "precipIntensity";
private static final String TIME_SINCE_LAST_PCP = "timeSinceLastPcp";
private static final String SOLAR_RADIATION = "solarRadiation";
private static final String SOLAR_RAD_CHANGE_TIME = "solarRadChangeTime";
private static final String SEA_SURFACE_TEMP = "seaSurfaceTemp";
private static final String WAVE_PERIOD = "wavePeriod";
private static final String WAVE_HEIGHT = "waveHeight";
private static final String RAW_MESONET = "rawMessage";
private static final String REL_HUMIDITY = "relHumidity";
private static final String WIND_DIR = "windDir";
private static final String PRESSURE = "pressure";
private static final String SEA_LEVEL_PRESSURE = "seaLevelPressure";
private static final String PRECIP_RATE = "precipRate";
private static final String FUEL_TEMPERATURE = "fuelTemperature";
private static final String FUEL_MOISTURE = "fuelMoisture";
private static final String SOIL_TEMPERATURE = "soilTemperature";
private static final String SOIL_MOISTURE = "soilMoisture";
/**
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! It is important to
* keep this up to date or risk breaking backwards compatibility
*
*/
private static final String[] ALL_PARAMS = { PRESS_CHANGE3_HOUR,
PRESS_CHANGE_CHAR, ALTIMETER, WIND_GUST, WIND_SPEED, DEWPOINT,
TEMPERATURE, PRES_WEATHER, VISIBILITY, LONGITUDE, LATITUDE,
SEA_LEVEL_PRESSURE, STATION_NAME, DATAURI, STORAGE_TYPE, ELEVATION,
STATION_ID, DATA_PROVIDER, HOME_WFO, OBSERVATION_TIME, PROVIDER_ID,
HANDBOOK5_ID, STATION_TYPE, REPORT_TIME, RECEIVED_TIME,
NUMERICAL_WMO_ID, DATA_PLATFORM_TYPE, PLATFORM_TRUE_DIRECTION,
PLARFORM_TRUE_SPEED, TEMP_CHANGE_TIME, WET_BULB_TEMPERATURE,
RH_CHANGE_TIME, STATION_PRESSURE, STATION_PRESS_CHANGE_TIME,
WIND_DIR_CHANGE_TIME, WIND_SPEED_CHANGE_TIME,
WIND_GUST_CHANGE_TIME, WIND_DIR_MIN, WIND_DIR_MAX,
VISIBILITY_STATUS, TOTAL_CLOUD_COVER, CLOUD_BASE_HEIGHT,
LOW_LEVEL_CLOUD_TYPE, MID_LEVEL_CLOUD_TYPE, HIGH_LEVEL_CLOUD_TYPE,
MAX_TEMP_RECORD_PERIOD, MAXIMUM_TEMPERATURE,
MIN_TEMP_RECORD_PERIOD, MINIMUM_TEMPERATURE, PRECIP_ACCUM,
PRECIP_TYPE, PRECIP_INTENSITY, TIME_SINCE_LAST_PCP,
SOLAR_RADIATION, SOLAR_RAD_CHANGE_TIME, SEA_SURFACE_TEMP,
WAVE_PERIOD, WAVE_HEIGHT, RAW_MESONET, REL_HUMIDITY, WIND_DIR,
PRESSURE, SEA_LEVEL_PRESSURE, PRECIP_RATE, FUEL_TEMPERATURE,
FUEL_MOISTURE, SOIL_TEMPERATURE, SOIL_MOISTURE };
public static final String ALL_PARAMS_LIST;
static {
StringBuffer sb = new StringBuffer();
boolean first = true;
for (String s : ALL_PARAMS) {
if (!first) {
sb.append(", ");
} else {
first = false;
}
sb.append(s);
}
ALL_PARAMS_LIST = sb.toString();
}
// public LdadmesonetPointDataTransform() throws JAXBException,
// PluginException {
// this.description = getDescription("ldadmesonet");
// logger.info("=============PointDataDescription loaded==============");
// this.dao = new LdadMesonetDao("ldadmesonet");
// }
public LdadmesonetPointDataTransform() {
try {
this.dao = new LdadMesonetDao("ldadmesonet");
this.description = dao.getPointDataDescription(null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PluginDataObject[] toPointData(PluginDataObject[] pdo) {
if (pdo.length > 0) {
Map<File, PointDataContainer> pointMap = new HashMap<File, PointDataContainer>();
for (PluginDataObject p : pdo) {
if (!(p instanceof MesonetLdadRecord)) {
continue;
}
File f = this.dao.getFullFilePath(p);
PointDataContainer pdc = pointMap.get(f);
if (pdc == null) {
pdc = PointDataContainer.build(this.description);
pointMap.put(f, pdc);
}
MesonetLdadRecord mesor = (MesonetLdadRecord) p;
PointDataView pdv = buildView(pdc, mesor);
mesor.setPointDataView(pdv);
}
}
return pdo;
}
private PointDataView buildView(PointDataContainer container,
MesonetLdadRecord record) {
PointDataView pdv = container.append();
if (record.getRawMessage() != null) {
pdv.setString(RAW_MESONET, record.getRawMessage());
}
if (record.getSeaLevelPressure() != null) {
pdv.setFloat(SEA_LEVEL_PRESSURE, record.getSeaLevelPressure());
}
if (record.getObservationTime() != null) {
pdv.setLong(OBSERVATION_TIME, record.getDataTime().getRefTime()
.getTime());
}
if (record.getVisibility() != null) {
pdv.setFloat(VISIBILITY, record.getVisibility());
}
if (record.getTemperature() != null) {
pdv.setFloat(TEMPERATURE, record.getTemperature());
}
if (record.getDewpoint() != null) {
pdv.setFloat(DEWPOINT, record.getDewpoint());
}
if (record.getWindSpeed() != null) {
pdv.setFloat(WIND_SPEED, record.getWindSpeed());
}
if (record.getWindGust() != null) {
pdv.setFloat(WIND_GUST, record.getWindGust());
}
if (record.getAltimeter() != null) {
pdv.setFloat(ALTIMETER, record.getAltimeter());
}
if (record.getPressChangeChar() != null) {
pdv.setInt(PRESS_CHANGE_CHAR, record.getPressChangeChar()
.intValue());
}
if (record.getPressChange3Hour() != null) {
pdv.setFloat(PRESS_CHANGE3_HOUR, record.getPressChange3Hour());
}
// --------------------------------------LDAD mesonet
// specific------------------------
if (record.getReportTime() != null) {
pdv.setLong(REPORT_TIME, record.getReportTime());
}
if (record.getReceivedTime() != null) {
pdv.setLong(RECEIVED_TIME, record.getReceivedTime().longValue());
}
if (record.getNumericWMOid() != null) {
pdv.setLong(NUMERICAL_WMO_ID, record.getNumericWMOid());
}
if (record.getDataPlatformType() != null) {
pdv.setInt(DATA_PLATFORM_TYPE, record.getDataPlatformType()
.intValue());
}
if (record.getPlatformTrueDirection() != null) {
pdv.setFloat(PLATFORM_TRUE_DIRECTION,
record.getPlatformTrueDirection());
}
if (record.getPlatformTrueSpeed() != null) {
pdv.setFloat(PLARFORM_TRUE_SPEED, record.getPlatformTrueSpeed());
}
if (record.getTempChangeTime() != null) {
pdv.setLong(TEMP_CHANGE_TIME, record.getTempChangeTime()
.longValue());
}
if (record.getWetBulbTemperature() != null) {
pdv.setFloat(WET_BULB_TEMPERATURE, record.getWetBulbTemperature());
}
if (record.getRhChangeTime() != null) {
pdv.setLong(RH_CHANGE_TIME, record.getRhChangeTime().longValue());
}
if (record.getStationPressure() != null) {
pdv.setFloat(STATION_PRESSURE, record.getStationPressure());
}
if (record.getStationPressChangeTime() != null) {
pdv.setLong(STATION_PRESS_CHANGE_TIME, record
.getStationPressChangeTime().longValue());
}
if (record.getWindDirChangeTime() != null) {
pdv.setLong(WIND_DIR_CHANGE_TIME, record.getWindDirChangeTime()
.longValue());
}
if (record.getWindSpeedChangeTime() != null) {
pdv.setLong(WIND_SPEED_CHANGE_TIME, record.getWindSpeedChangeTime()
.longValue());
}
if (record.getWindGustChangeTime() != null) {
pdv.setLong(WIND_GUST_CHANGE_TIME, record.getWindGustChangeTime()
.longValue());
}
if (record.getWindDirMin() != null) {
pdv.setFloat(WIND_DIR_MIN, record.getWindDirMin());
}
if (record.getWindDirMax() != null) {
pdv.setFloat(WIND_DIR_MAX, record.getWindDirMax());
}
if (record.getVisibilityStatus() != null) {
pdv.setString(VISIBILITY_STATUS, record.getVisibilityStatus());
}
if (record.getTotalCloudCover() != null) {
pdv.setFloat(TOTAL_CLOUD_COVER, record.getTotalCloudCover());
}
if (record.getCloudBaseHeight() != null) {
pdv.setInt(CLOUD_BASE_HEIGHT, record.getCloudBaseHeight()
.intValue());
}
if (record.getLowLevelCloudType() != null) {
pdv.setInt(LOW_LEVEL_CLOUD_TYPE, record.getLowLevelCloudType()
.intValue());
}
if (record.getMidLevelCloudType() != null) {
pdv.setInt(MID_LEVEL_CLOUD_TYPE, record.getMidLevelCloudType()
.intValue());
}
if (record.getHighLevelCloudType() != null) {
pdv.setInt(HIGH_LEVEL_CLOUD_TYPE, record.getHighLevelCloudType()
.intValue());
}
if (record.getMinTempRecordPeriod() != null) {
pdv.setInt(MAX_TEMP_RECORD_PERIOD, record.getMinTempRecordPeriod()
.intValue());
}
if (record.getMaximumTemperature() != null) {
pdv.setFloat(MAXIMUM_TEMPERATURE, record.getMaximumTemperature());
}
if (record.getMinTempRecordPeriod() != null) {
pdv.setInt(MIN_TEMP_RECORD_PERIOD, record.getMinTempRecordPeriod()
.intValue());
}
if (record.getMinimumTemperature() != null) {
pdv.setFloat(MINIMUM_TEMPERATURE, record.getMinimumTemperature());
}
if (record.getPrecipAccum() != null) {
pdv.setFloat(PRECIP_ACCUM, record.getPrecipAccum());
}
if (record.getPrecipType() != null) {
pdv.setInt(PRECIP_TYPE, record.getPrecipType().intValue());
}
if (record.getPrecipIntensity() != null) {
pdv.setInt(PRECIP_INTENSITY, record.getPrecipIntensity().intValue());
}
if (record.getTimeSinceLastPcp() != null) {
pdv.setLong(TIME_SINCE_LAST_PCP, record.getTimeSinceLastPcp()
.longValue());
}
if (record.getSolarRadiation() != null) {
pdv.setFloat(SOLAR_RADIATION, record.getSolarRadiation());
}
if (record.getSolarRadChangeTime() != null) {
pdv.setLong(SOLAR_RAD_CHANGE_TIME, record.getSolarRadChangeTime()
.longValue());
}
if (record.getSeaSurfaceTemp() != null) {
pdv.setFloat(SEA_SURFACE_TEMP, record.getSeaSurfaceTemp());
}
if (record.getWavePeriod() != null) {
pdv.setFloat(WAVE_PERIOD, record.getWavePeriod());
}
if (record.getWaveHeight() != null) {
pdv.setFloat(WAVE_HEIGHT, record.getWaveHeight());
}
if (record.getRelHumidity() != null) {
pdv.setFloat(REL_HUMIDITY, record.getRelHumidity());
}
if (record.getWindDir() != null) {
pdv.setFloat(WIND_DIR, record.getWindDir());
}
if (record.getPressure() != null) {
pdv.setFloat(PRESSURE, record.getPressure());
}
if (record.getSeaLevelPressure() != null) {
pdv.setFloat(SEA_LEVEL_PRESSURE, record.getSeaLevelPressure());
}
if (record.getPrecipRate() != null) {
pdv.setFloat(PRECIP_RATE, record.getPrecipRate());
}
if (record.getFuelTemperature() != null) {
pdv.setFloat(FUEL_TEMPERATURE, record.getFuelTemperature());
}
if (record.getFuelMoisture() != null) {
pdv.setFloat(FUEL_MOISTURE, record.getFuelMoisture());
}
if (record.getSoilTemperature() != null) {
pdv.setFloat(SOIL_TEMPERATURE, record.getSoilTemperature());
}
if (record.getSoilMoisture() != null) {
pdv.setFloat(SOIL_MOISTURE, record.getSoilMoisture());
}
return pdv;
}
public static MesonetLdadRecord toMesonetLdadRecord(PointDataView pdv) {
MesonetLdadRecord mr = new MesonetLdadRecord();
mr.setAltimeter(pdv.getNumber(ALTIMETER).floatValue());
mr.setDewpoint(pdv.getNumber(DEWPOINT).floatValue());
SurfaceObsLocation loc = new SurfaceObsLocation(
pdv.getString(STATION_ID));
float lat = pdv.getNumber(LATITUDE).floatValue();
float lon = pdv.getNumber(LONGITUDE).floatValue();
loc.assignLocation(lat, lon);
loc.setElevation(pdv.getNumber(ELEVATION).intValue());
mr.setLocation(loc);
mr.setReportType(pdv.getString(STORAGE_TYPE));
mr.setProviderId(pdv.getString(PROVIDER_ID));
mr.setPressChange3Hour(pdv.getNumber(PRESS_CHANGE3_HOUR).floatValue());
mr.setPressChangeChar((short) pdv.getInt(PRESS_CHANGE_CHAR));
mr.setSeaLevelPressure(pdv.getNumber(SEA_LEVEL_PRESSURE).floatValue());
mr.setTemperature(pdv.getNumber(TEMPERATURE).floatValue());
mr.setVisibility(pdv.getNumber(VISIBILITY).floatValue());
mr.setWindDir(pdv.getFloat(WIND_DIR));
mr.setWindGust(pdv.getFloat(WIND_GUST));
mr.setWindSpeed(pdv.getFloat(WIND_SPEED));
mr.setDataURI(pdv.getString(DATAURI));
mr.setReceivedTime(pdv.getNumber(RECEIVED_TIME).doubleValue());
// ----------------------------------------------------------------------------------
mr.setTempChangeTime(pdv.getNumber(TEMP_CHANGE_TIME).doubleValue());
mr.setWetBulbTemperature(pdv.getFloat(WET_BULB_TEMPERATURE));
mr.setRhChangeTime((Double) pdv.getNumber(RH_CHANGE_TIME));
mr.setStationPressure(pdv.getFloat(STATION_PRESSURE));
mr.setStationPressChangeTime((Double) pdv
.getNumber(STATION_PRESS_CHANGE_TIME));
mr.setWindDirChangeTime((Double) pdv.getNumber(WIND_DIR_CHANGE_TIME));
mr.setWindSpeedChangeTime((Double) pdv
.getNumber(WIND_SPEED_CHANGE_TIME));
mr.setWindGustChangeTime((Double) pdv.getNumber(WIND_GUST_CHANGE_TIME));
mr.setWindDirMin(pdv.getFloat(WIND_DIR_MIN));
mr.setWindDirMax(pdv.getFloat(WIND_DIR_MAX));
mr.setVisibilityStatus(pdv.getString(VISIBILITY_STATUS));
mr.setTotalCloudCover(pdv.getFloat(TOTAL_CLOUD_COVER));
mr.setCloudBaseHeight((Short) pdv.getNumber(CLOUD_BASE_HEIGHT));
mr.setLowLevelCloudType((Short) pdv.getNumber(LOW_LEVEL_CLOUD_TYPE));
mr.setMidLevelCloudType((Short) pdv.getNumber(MID_LEVEL_CLOUD_TYPE));
mr.setHighLevelCloudType((Short) pdv.getNumber(HIGH_LEVEL_CLOUD_TYPE));
mr.setMaxTempRecordPeriod((Short) pdv.getNumber(MAX_TEMP_RECORD_PERIOD));
mr.setMaximumTemperature(pdv.getFloat(MAXIMUM_TEMPERATURE));
mr.setMinTempRecordPeriod((Short) pdv.getNumber(MIN_TEMP_RECORD_PERIOD));
mr.setMaximumTemperature(pdv.getFloat(MINIMUM_TEMPERATURE));
mr.setPrecipAccum(pdv.getFloat(PRECIP_ACCUM));
mr.setPrecipType((Short) pdv.getNumber(PRECIP_TYPE));
mr.setPrecipIntensity((Short) pdv.getNumber(PRECIP_INTENSITY));
mr.setTimeSinceLastPcp((Double) pdv.getNumber(TIME_SINCE_LAST_PCP));
mr.setSolarRadiation(pdv.getFloat(SOLAR_RADIATION));
mr.setSolarRadChangeTime((Double) pdv.getNumber(SOLAR_RAD_CHANGE_TIME));
mr.setSeaSurfaceTemp(pdv.getFloat(SEA_SURFACE_TEMP));
mr.setWavePeriod(pdv.getFloat(WAVE_PERIOD));
mr.setWaveHeight(pdv.getFloat(WAVE_HEIGHT));
mr.setRawMessage(pdv.getString(RAW_MESONET));
mr.setRelHumidity(pdv.getFloat(REL_HUMIDITY));
mr.setWindDir(pdv.getFloat(WIND_DIR));
mr.setPressure(pdv.getFloat(PRESSURE));
mr.setSeaLevelPressure(pdv.getFloat(SEA_LEVEL_PRESSURE));
mr.setPrecipRate(pdv.getFloat(PRECIP_RATE));
mr.setFuelTemperature(pdv.getFloat(FUEL_TEMPERATURE));
mr.setFuelMoisture(pdv.getFloat(FUEL_MOISTURE));
mr.setSoilTemperature(pdv.getFloat(SOIL_TEMPERATURE));
mr.setSoilMoisture(pdv.getFloat(SOIL_MOISTURE));
return mr;
}
public static MesonetLdadRecord[] toMesonetLdadRecords(
PointDataContainer container) {
List<MesonetLdadRecord> records = new ArrayList<MesonetLdadRecord>();
container.setCurrentSz(container.getAllocatedSz());
for (int i = 0; i < container.getCurrentSz(); i++) {
PointDataView pdv = container.readRandom(i);
records.add(toMesonetLdadRecord(pdv));
}
return records.toArray(new MesonetLdadRecord[records.size()]);
}
}

View file

@ -0,0 +1,163 @@
/**
* 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.ldadmesonet.dao;
import java.util.ArrayList;
import java.util.List;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.ldadmesonet.MesonetLdadRecord;
import com.raytheon.uf.common.dataquery.db.QueryParam;
import com.raytheon.uf.common.pointdata.spatial.ObStation;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.query.DatabaseQuery;
import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
import com.raytheon.uf.edex.pointdata.spatial.ObStationDao;
/**
* Data access object for accessing LDAD MESONET records in the database.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 9/04/09 vkorolev Initial creation
* 10/09/09 DR2814 vkorolev Refactor to Point Data Model
* Feb 27, 2013 1638 mschenke Moved ObStationDao to edex pointdata plugin
* Aug 15, 2014 3530 bclement moved from common to edex
* Feb 16, 2022 8608 mapeters Remove populateDataStore override that matched super
*
* </pre>
*
* @author vkorolev
*/
public class LdadMesonetDao extends PointDataPluginDao<MesonetLdadRecord> {
/** The station dao */
private ObStationDao obDao = new ObStationDao();
public LdadMesonetDao(String pluginName) throws PluginException {
super(pluginName);
}
public LdadMesonetDao() throws PluginException {
this("ldadmesonet");
}
public List<?> queryBySpatialBox(double upperLeftLat, double upperLeftLon,
double lowerRightLat, double lowerRightLon)
throws DataAccessLayerException {
List<ObStation> stationList = obDao.queryBySpatialBox(upperLeftLat,
upperLeftLon, lowerRightLat, lowerRightLon);
List<String> stationNames = new ArrayList<>();
for (ObStation station : stationList) {
stationNames.add(station.getIdentifier());
}
stationList.clear();
DatabaseQuery query = new DatabaseQuery(MesonetLdadRecord.class);
query.addQueryParam("location.stationId", stationNames,
QueryParam.QueryOperand.IN);
return queryByCriteria(query);
}
public List<?> queryByState(String state, Integer count)
throws DataAccessLayerException {
List<ObStation> results = obDao.queryByState(state);
List<String> icaos = new ArrayList<>();
for (ObStation station : results) {
icaos.add(station.getIdentifier());
}
DatabaseQuery query = new DatabaseQuery(MesonetLdadRecord.class, count);
query.addQueryParam("location.stationId", icaos,
QueryParam.QueryOperand.IN);
return queryByCriteria(query);
}
/**
* Retrieves an ldadMesonet report using the datauri .
*
* @param dataURI
* The dataURI to match against.
* @return The report record if it exists.
*/
public MesonetLdadRecord queryByDataURI(String dataURI) {
MesonetLdadRecord report = null;
List<?> obs = null;
try {
obs = queryBySingleCriteria("dataURI", dataURI);
} catch (DataAccessLayerException e) {
logger.error("Error querying LDAD Mesonet data by URI: " + dataURI,
e);
}
if (obs != null && !obs.isEmpty()) {
report = (MesonetLdadRecord) obs.get(0);
}
return report;
}
/**
* Queries for to determine if a given data uri exists on the redbook 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.ldadmesonet where datauri='"
+ dataUri + "';";
Object[] results = executeSQLQuery(sql);
return results;
}
public ObStationDao getObDao() {
return obDao;
}
public void setObDao(ObStationDao obDao) {
this.obDao = obDao;
}
@Override
public String[] getKeysRequiredForFileName() {
return new String[] { "dataTime.refTime" };
}
@Override
public String getPointDataFileName(MesonetLdadRecord p) {
return "ldadmesonet.h5";
}
@Override
public MesonetLdadRecord newObject() {
return new MesonetLdadRecord();
}
}

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<requestPatterns xmlns:ns2="group">
<regex>LDAD\.mesonet\.*</regex>
</requestPatterns>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
Incremental overrides can also be achieved by creating a new file with
a suffix inserted between the original filename and extension.
-->
<purgeRuleSet>
<defaultRule>
<versionsToKeep>24</versionsToKeep>
<delta>=00-01:00:00</delta>
<round>00-01:00:00</round>
</defaultRule>
</purgeRuleSet>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.edex.plugin.qc</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>

View file

@ -0,0 +1,13 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Qc Plug-in
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.qc
Bundle-Version: 1.18.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.raytheon.edex.common,
com.raytheon.uf.edex.pointdata,
com.raytheon.uf.common.dataplugin.qc,
com.raytheon.uf.common.localization,
ucar.nc2
Import-Package: com.raytheon.uf.common.status

View file

@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
utility/,\
.,\
res/,\
resources/

View file

@ -0,0 +1,58 @@
<?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.
-->
<pointDataDescription>
<parameter name="reportTime" numDims="1" type="FLOAT" unit="seconds since 1-1-1970"
fillValue="3.40282346e+38" />
<parameter name="observationTime" numDims="1" type="FLOAT" unit="seconds since 1-1-1970"
fillValue="3.40282346e+38" />
<parameter name="providerId" numDims="2" type="STRING" size="12" />
<parameter name="dataProvider" numDims="2" type="STRING" size="12" />
<parameter name="elevation" numDims="1" type="FLOAT" unit="m" fillValue="3.40282346639e+38" />
<parameter name="seaLevelPressure" numDims="1" type="FLOAT" unit="Pa"
fillValue="3.40282346639e+38" />
<parameter name="seaLevelPressureDD" numDims="1" type="STRING" size="1" />
<parameter name="seaLevelPressureQCA" numDims="1" type="INT" />
<parameter name="seaLevelPressureQCR" numDims="1" type="INT" />
<parameter name="precipAccum" numDims="1" type="FLOAT" unit="mm" fillValue="3.40282346639e+38" />
<parameter name="precipAccumDD" numDims="1" type="STRING" size="1" />
<parameter name="precipAccumQCA" numDims="1" type="INT" />
<parameter name="precipAccumQCR" numDims="1" type="INT" />
<parameter name="temperature" numDims="1" type="FLOAT" unit="K" fillValue="3.40282346639e+38" />
<parameter name="temperatureDD" numDims="1" type="STRING" size="1" />
<parameter name="temperatureQCA" numDims="1" type="INT" />
<parameter name="temperatureQCR" numDims="1" type="INT" />
<parameter name="windSpeed" numDims="1" type="FLOAT" unit="m/s" fillValue="3.40282346639e+38" />
<parameter name="windSpeedDD" numDims="1" type="STRING" size="1" />
<parameter name="windSpeedQCA" numDims="1" type="INT" />
<parameter name="windSpeedQCR" numDims="1" type="INT" />
<parameter name="dewpoint" numDims="1" type="FLOAT" unit="K" fillValue="3.40282346639e+38" />
<parameter name="dewpointDD" numDims="1" type="STRING" size="1" />
<parameter name="dewpointQCA" numDims="1" type="INT" />
<parameter name="dewpointQCR" numDims="1" type="INT" />
<parameter name="windGust" numDims="1" type="FLOAT" unit="m/s" fillValue="3.40282346639e+38" />
<parameter name="windGustDD" numDims="1" type="STRING" size="1" />
<parameter name="windGustQCA" numDims="1" type="INT" />
<parameter name="windGustQCR" numDims="1" type="INT" />
<parameter name="windDir" numDims="1" type="FLOAT" unit="degree" fillValue="3.40282346639e+38" />
<parameter name="windDirDD" numDims="1" type="STRING" size="1" />
<parameter name="windDirQCA" numDims="1" type="INT" />
<parameter name="windDirQCR" numDims="1" type="INT" />
</pointDataDescription>

View file

@ -0,0 +1,61 @@
<?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.
-->
<pointDataDescription>
<parameter name="timeObs" numDims="1" type="FLOAT" unit="seconds since 1-1-1970" fillValue="1.7976931348623157e+308" />
<parameter name="timeObsTrue" numDims="1" type="FLOAT" unit="seconds since 1-1-1970" fillValue="1.7976931348623157e+308" />
<parameter name="stationName" numDims="2" type="STRING" size="5" />
<parameter name="MAPSseaLevelPress" numDims="1" type="FLOAT" unit="Pa" fillValue="3.4028235e+38" />
<parameter name="MAPSseaLevelPressDD" numDims="1" type="STRING" />
<parameter name="MAPSseaLevelPressQCA" numDims="1" type="INT" />
<parameter name="MAPSseaLevelPressQCR" numDims="1" type="INT" />
<parameter name="dewpoint" numDims="1" type="FLOAT" unit="K" fillValue="3.4028235e+38" />
<parameter name="dewpointDD" numDims="1" type="STRING" />
<parameter name="dewpointQCA" numDims="1" type="INT" />
<parameter name="dewpointQCR" numDims="1" type="INT" />
<parameter name="potentialTemp" numDims="1" type="FLOAT" unit="K" fillValue="3.4028235e+38" />
<parameter name="potentialTempDD" numDims="1" type="STRING" />
<parameter name="potentialTempQCA" numDims="1" type="INT" />
<parameter name="potentialTempQCR" numDims="1" type="INT" />
<parameter name="dewpointDepression" numDims="1" type="FLOAT" unit="K" fillValue="3.4028235e+38" />
<parameter name="dewpointDepressionDD" numDims="1" type="STRING" />
<parameter name="dewpointDepressionQCA" numDims="1" type="INT" />
<parameter name="dewpointDepressionQCR" numDims="1" type="INT" />
<parameter name="uw" numDims="1" type="FLOAT" unit="m/s" fillValue="3.4028235e+38" />
<parameter name="uwDD" numDims="1" type="STRING" />
<parameter name="uwQCA" numDims="1" type="INT" />
<parameter name="uwQCR" numDims="1" type="INT" />
<parameter name="vw" numDims="1" type="FLOAT" unit="m/s" fillValue="3.4028235e+38" />
<parameter name="vwDD" numDims="1" type="STRING" />
<parameter name="vwQCA" numDims="1" type="INT" />
<parameter name="vwQCR" numDims="1" type="INT" />
<parameter name="pressChange3Hour" numDims="1" type="FLOAT" unit="Pa/s" fillValue="3.4028235e+38" />
<parameter name="pressChange3HourDD" numDims="1" type="STRING" />
<parameter name="pressChange3HourQCA" numDims="1" type="INT" />
<parameter name="pressChange3HourQCR" numDims="1" type="INT" />
<parameter name="seaLevelPress" numDims="1" type="FLOAT" unit="Pa" fillValue="3.4028235e+38" />
<parameter name="seaLevelPressDD" numDims="1" type="STRING" />
<parameter name="seaLevelPressQCA" numDims="1" type="INT" />
<parameter name="seaLevelPressQCR" numDims="1" type="INT" />
<parameter name="altimeter" numDims="1" type="FLOAT" unit="Pa" fillValue="3.4028235e+38" />
<parameter name="altimeterDD" numDims="1" type="STRING" />
<parameter name="altimeterQCA" numDims="1" type="INT" />
<parameter name="altimeterQCR" numDims="1" type="INT" />
</pointDataDescription>

View file

@ -0,0 +1,29 @@
<?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.
-->
<pointDataDbDescription>
<parameter name="latitude" queryName="location.latitude" type="FLOAT" unit="°" />
<parameter name="longitude" queryName="location.longitude" type="FLOAT" unit="°" />
<parameter name="elevation" queryName="location.elevation" type="FLOAT" unit="m" />
<parameter name="stationName" queryName="location.stationId" type="STRING" />
<parameter name="stationId" queryName="location.stationId" type="STRING" />
<parameter name="refTime" queryName="dataTime.refTime" numDims="1" type="LONG" unit="ms"/>
<parameter name="qcType" queryName="qcType" type="STRING" />
</pointDataDbDescription>

View file

@ -0,0 +1,29 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="qcProperties" class="com.raytheon.uf.common.dataplugin.PluginProperties">
<property name="pluginName" value="qc" />
<property name="pluginFQN" value="com.raytheon.uf.common.dataplugin.qc" />
<property name="dao" value="com.raytheon.uf.edex.plugin.qc.dao.QCDao" />
<property name="record" value="com.raytheon.uf.common.dataplugin.qc.QCRecord" />
<property name="compression" value="LZF"/>
</bean>
<bean id="qcPluginRegistered" factory-bean="pluginRegistry" factory-method="register">
<constructor-arg value="qc"/>
<constructor-arg ref="qcProperties"/>
</bean>
<!-- Disable ignite for qc since qc files are too large to pull an entire
file into ignite's cache when appending to it. depends-on is to ensure
qc gets registered to the point data cache first and then we overwrite
that mapping. -->
<bean factory-bean="ignitePluginRegistry" factory-method="registerPluginCacheName"
depends-on="qcPluginRegistered,ignitePointDataCacheConfigurator">
<constructor-arg value="qc" />
<constructor-arg value="none" />
</bean>
</beans>

View file

@ -0,0 +1,61 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="qcScanner" class="com.raytheon.uf.edex.plugin.qc.QCScanner" depends-on="qcProperties">
<property name="maxRecordsInChunk" value="1000" />
</bean>
<camelContext id="qcScan-camel"
xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<endpoint id="scheduledQCCron" uri="quartz://qc/scanQC/?cron=${qc.cron}"/>
<route id="scheduledQCScan">
<from uri="scheduledQCCron" />
<setHeader name="pluginName">
<constant>qc</constant>
</setHeader>
<split streaming="true">
<method ref="qcScanner" method="split" />
<doTry>
<to uri="jms-generic:queue:qcDecodeQueue" />
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="log:qc?level=ERROR" />
</doCatch>
</doTry>
</split>
</route>
</camelContext>
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
<constructor-arg ref="qcScan-camel"/>
</bean>
<camelContext id="qcDecode-camel"
xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<route id="qcDecodeRoute">
<from uri="jms-generic:queue:qcDecodeQueue" />
<doTry>
<pipeline>
<bean ref="qcScanner" method="scanFile" />
<to uri="direct-vm:persistIndexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="log:qc?level=ERROR" />
</doCatch>
</doTry>
</route>
</camelContext>
</beans>

View file

@ -0,0 +1,2 @@
# period to scan the QC file drop point for new QC data
qc.cron=0+2,7,12,17,22,27,32,37,42,47,52,57+*+*+*+?

View file

@ -0,0 +1,370 @@
/**
* 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.qc;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.qc.QCRecord;
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.database.plugin.PluginFactory;
import com.raytheon.uf.edex.plugin.qc.dao.QCDao;
import com.raytheon.uf.edex.plugin.qc.internal.QCPaths;
import ucar.ma2.Array;
import ucar.ma2.ArrayChar;
import ucar.ma2.DataType;
import ucar.ma2.Section;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
/**
* Scans NetCDF files generated by A1 legacy applications and generates QCRecord
* instances that refer to their records. The scan should only occur on one JVM
* in a cluster while the decode can occur on multiple JVMs in a cluster.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 03, 2010 4775 D. Friedman Initial version
* Mar 07, 2013 15842 D. Friedman Use Java NetCDF library instead of
* pupynere
* May 16, 2013 1869 bsteffen Remove DataURI column from qc.
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Feb 20, 2014 DR 17098 D. Friedman Filter out invalid lat/lon values.
* Jul 23, 2014 3410 bclement location changed to floats
* Jan 03, 2018 6861 njensen Split on files, decode and store results
* as PointDataView on PluginDataObject[]
*
* </pre>
*
* @author dfriedma
*/
public class QCScanner {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(QCScanner.class);
private static final Pattern FILE_PATTERN = Pattern.compile("^\\d+_\\d+$");
private Integer maxRecordsInChunk;
/**
* Map of qcType to filename to last mod time. Used to ensure we don't scan
* a file again if it hasn't changed.
*/
private Map<String, Map<String, Long>> fileLastScannedMap = new HashMap<>();
/**
* @return the maxRecordsInChunk
*/
public Integer getMaxRecordsInChunk() {
return maxRecordsInChunk;
}
/**
* @param maxRecordsInChunk
* the maxRecordsInChunk to set
*/
public void setMaxRecordsInChunk(Integer maxRecordsInChunk) {
this.maxRecordsInChunk = maxRecordsInChunk;
}
/**
* Information necessary to start a decode. Serialized after the split to
* take advantage of clustering the decodes.
*/
public static class QCFile implements Serializable {
private static final long serialVersionUID = 1L;
protected String qcType;
protected File file;
protected QCFile(String qcType, File file) {
this.qcType = qcType;
this.file = file;
}
}
public class QCDirectoryScanner {
private final String qcType;
private final File directory;
public QCDirectoryScanner(String qcType, File directory) {
this.qcType = qcType;
this.directory = directory;
}
/**
* Scan all files in the directory that match the pattern and have been
* modified since we last scanned them. If we did not previously scan
* them, then scan those too.
*
* @return the list of QCFiles that match the pattern and have been
* modified since we last scanned them
*/
public List<QCFile> getFiles() {
List<QCFile> results = new ArrayList<>();
Map<String, Long> updatedScanMap = new HashMap<>();
Map<String, Long> innerMap = fileLastScannedMap.get(qcType);
if (innerMap == null) {
innerMap = new HashMap<>();
}
for (String fn : directory.list()) {
if (FILE_PATTERN.matcher(fn).matches()) {
try {
File f = new File(directory, fn);
String path = f.getPath();
Long lastScanned = innerMap.get(path);
if (lastScanned == null
|| f.lastModified() > lastScanned) {
QCFile qcf = new QCFile(qcType, f);
results.add(qcf);
lastScanned = f.lastModified();
}
updatedScanMap.put(path, lastScanned);
} catch (Exception e) {
statusHandler
.error(String.format("error reading %s/%s: %s",
directory, fn, e.getMessage()), e);
}
}
}
fileLastScannedMap.put(qcType, updatedScanMap);
return results;
}
}
/**
* Gets an iterator of QC files to process/decode.
*
* @return an iterator of QC files
* @throws FileNotFoundException
*/
public Iterator<QCFile> split() throws FileNotFoundException {
List<QCFile> files = new ArrayList<>();
Map<String, File> paths = QCPaths.getPaths();
for (Map.Entry<String, File> entry : paths.entrySet()) {
String type = entry.getKey();
File directory = entry.getValue();
QCDirectoryScanner scanner = new QCDirectoryScanner(type,
directory);
files.addAll(scanner.getFiles());
}
return files.iterator();
}
/**
* Scans or "decodes" the QC netcdf file into QCRecords
*
* @param qcFile
* the QC file to scan for records
* @return the PluginDataObjects that were "decoded"
* @throws Exception
*/
public PluginDataObject[] scanFile(QCFile qcFile) throws Exception {
try (NetcdfFile nc = NetcdfFile.open(qcFile.file.getPath())) {
int index = 0;
int totalRecordCount = nc.getUnlimitedDimension().getLength();
int batchSize = Math.min(getMaxRecordsInChunk(), totalRecordCount);
String[] idVariablesNames = nc.findGlobalAttribute("idVariables")
.getStringValue().split(",");
String[] timeVariableNames = nc.findGlobalAttribute("timeVariables")
.getStringValue().split(",");
Variable[] idVariables = new Variable[idVariablesNames.length];
for (int i = 0; i < idVariables.length; ++i) {
idVariables[i] = nc.findVariable(idVariablesNames[i]);
}
Variable vObsTime = nc.findVariable(timeVariableNames[0]);
double vObsTimeFillValue = vObsTime.findAttribute("_FillValue")
.getNumericValue().doubleValue();
Double vObsTimeMissingValue = null;
Attribute a = vObsTime.findAttribute("missing_value");
if (a != null) {
vObsTimeMissingValue = a.getNumericValue().doubleValue();
}
Variable vLat = nc.findVariable("latitude");
Variable vLon = nc.findVariable("longitude");
Variable vElev = nc.findVariable("elevation");
/*
* There's so many variables in the file that we don't need so we
* pick the ones we do need from the point data description.
*/
QCDao qcDao = (QCDao) PluginFactory.getInstance()
.getPluginDao("qc");
Map<String, Object> map = new HashMap<>();
map.put("qcType", qcFile.qcType);
PointDataDescription pdd = qcDao.getPointDataDescription(map);
PointDataContainer pdc = PointDataContainer.build(pdd);
Map<String, Variable> variableMap = new HashMap<>();
for (String name : pdd.getParameterNames()) {
/*
* do not include id variables, we will read those separately
* below because they are 2-dimensional chars (aka Strings)
*/
boolean foundId = false;
for (String idName : idVariablesNames) {
if (idName.equals(name)) {
foundId = true;
break;
}
}
if (!foundId) {
Variable v = nc.findVariable(name);
if (v != null) {
variableMap.put(name, v);
}
}
}
Map<String, PluginDataObject> recordMap = new HashMap<>();
while (index < totalRecordCount) {
batchSize = Math.min(batchSize, totalRecordCount - index);
int[] ofs = new int[] { index };
int[] len = new int[] { batchSize };
Array dObsTime = vObsTime.read(ofs, len);
Array dLat = vLat.read(ofs, len);
Array dLon = vLon.read(ofs, len);
Array dElev = vElev.read(ofs, len);
// get IDs which will become the unique station name
Section sec = new Section();
sec.appendRange(index, (index + batchSize) - 1);
sec.appendRange();
ArrayChar[] dIDs = new ArrayChar[idVariables.length];
for (int i = 0; i < dIDs.length; ++i) {
dIDs[i] = (ArrayChar) idVariables[i].read(sec);
}
Map<String, Array> nameToArrayMap = new HashMap<>();
for (Variable v : variableMap.values()) {
Array arr = v.read(ofs, len);
nameToArrayMap.put(v.getName(), arr);
}
int ri = 0;
while (ri < batchSize) {
PointDataView pdv = pdc.append();
QCRecord pdo = new QCRecord();
pdo.setOverwriteAllowed(true);
double obsTime = dObsTime.getDouble(ri);
float lat = dLat.getFloat(ri);
float lon = dLon.getFloat(ri);
if ((obsTime != vObsTimeFillValue)
&& ((vObsTimeMissingValue == null)
|| (vObsTimeMissingValue != obsTime))
&& Math.abs(lon) <= 180 && Math.abs(lat) <= 90) {
pdo.setDataTime(new DataTime(
new Date((long) (obsTime * 1000))));
SurfaceObsLocation loc = new SurfaceObsLocation();
loc.assignLocation(lat, lon);
loc.setElevation(dElev.getInt(ri));
/*
* Set up a unique stationId while also setting the id
* variable names with point data values
*/
StringBuilder stationId = new StringBuilder();
for (ArrayChar idArray : dIDs) {
stationId.append(idArray.getString(ri));
}
loc.setStationId(stationId.toString());
for (int i = 0; i < idVariablesNames.length; i++) {
pdv.setString(idVariablesNames[i],
dIDs[i].getString(ri));
}
pdo.setLocation(loc);
pdo.setNcSet(qcFile.file.getName());
pdo.setQcType(qcFile.qcType);
for (String name : nameToArrayMap.keySet()) {
Array arr = nameToArrayMap.get(name);
DataType dtype = arr.getDataType();
switch (dtype) {
case CHAR:
pdv.setString(name,
String.valueOf(arr.getChar(ri)));
break;
case INT:
case SHORT:
pdv.setInt(name, arr.getInt(ri));
break;
case LONG:
pdv.setLong(name, arr.getLong(ri));
break;
case FLOAT:
case DOUBLE:
pdv.setFloat(name, arr.getFloat(ri));
break;
default:
throw new IllegalArgumentException(
"QCScanner does not support reading values of type "
+ dtype);
}
}
pdo.setPointDataView(pdv);
recordMap.put(pdo.getDataURI(), pdo);
}
++index;
++ri;
}
} // end of outer while
Collection<PluginDataObject> results = recordMap.values();
int size = results.size();
statusHandler.info("Decoded " + size + " QC records from "
+ qcFile.file.getPath() + ", now storing");
return results.toArray(new PluginDataObject[size]);
}
}
}

View file

@ -0,0 +1,92 @@
/**
* 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.qc.dao;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.qc.QCRecord;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.edex.plugin.qc.internal.QCPaths;
import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
/**
* Data access object for retrieving QC mesonet data.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 12/04/2009 3408 bphillip Initial creation
* Aug 15, 2014 3530 bclement removed commons logging
* Apr 16, 2015 4259 njensen Removed unreachable catch
* Jan 04, 2018 6861 njensen Removed python usage, removed method overrides
* so it mostly resembles a normal pointdata plugin
*
* </pre>
*
* @author bphillip
*/
public class QCDao extends PointDataPluginDao<QCRecord> {
/** Map of plugin names to point data descriptions */
private static Map<String, PointDataDescription> pdds = new HashMap<>();
static {
pdds = QCPaths.getPointDataDescriptions();
}
/**
* Constructs a new QC data access object
*
* @param pluginName
* "qc"
* @throws PluginException
* If errors occur while constructing the data access object
*/
public QCDao(String pluginName) throws PluginException {
super(pluginName);
}
@Override
public String[] getKeysRequiredForFileName() {
return new String[] { "qcType", "dataTime.refTime" };
}
@Override
public String getPointDataFileName(QCRecord p) {
return "qc.h5";
}
@Override
public QCRecord newObject() {
return new QCRecord();
}
@Override
public PointDataDescription getPointDataDescription(
Map<String, Object> obj) {
return pdds.get(obj.get("qcType").toString());
}
}

View file

@ -0,0 +1,123 @@
/**
* 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.qc.internal;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.edex.core.EDEXUtil;
/**
* This class should only be used by the QC plug-ins.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------------------------
* ??? ??? ??? Initial creation
* Aug 15, 2014 3530 bclement moved from common to edex
* Jul 15, 2016 5744 mapeters Use common_static instead of edex_static
* in getPythonScriptPath()
* Jan 05, 2018 6861 njensen Removed python support
* Simplified getPointDataDescriptions()
*
* </pre>
*
*/
public class QCPaths {
/** The directory containing the raw QC mesonet data */
private static final String QC_RAW_DIR;
static {
QC_RAW_DIR = EDEXUtil.getEdexData() + File.separator
+ System.getProperty("HDF5_PATH");
}
public static Map<String, File> getPaths() throws FileNotFoundException {
Map<String, File> paths = new HashMap<>();
File baseDir = new File(QC_RAW_DIR);
if (baseDir.exists()) {
File[] files = baseDir.listFiles();
if (files == null) {
throw new FileNotFoundException(
"Unable to read files in directory: " + baseDir);
}
for (File f : files) {
paths.put(f.getName(), f);
}
} else {
throw new FileNotFoundException(
"Unable to open directory: " + baseDir);
}
return paths;
}
public static Map<String, PointDataDescription> getPointDataDescriptions() {
Map<String, PointDataDescription> pdds = new HashMap<>();
String mesonetPath = "/res/pointdata/pdd/ldadmesonet.xml";
String msasPath = "/res/pointdata/pdd/msas.xml";
try (InputStream is = QCPaths.class.getResourceAsStream(mesonetPath)) {
PointDataDescription desc;
try {
desc = PointDataDescription.fromStream(is);
pdds.put("ldadmesonet", desc);
} catch (SerializationException e) {
throw new RuntimeException(
"Error reading pointdata description from "
+ mesonetPath,
e);
}
} catch (IOException e) {
// ignore
}
try (InputStream is = QCPaths.class.getResourceAsStream(msasPath)) {
PointDataDescription desc;
try {
desc = PointDataDescription.fromStream(is);
pdds.put("msas", desc);
} catch (SerializationException e) {
throw new RuntimeException(
"Error reading pointdata description from " + msasPath,
e);
}
} catch (IOException e) {
// ignore
}
return pdds;
}
public static String getBaseDir() {
return QC_RAW_DIR;
}
}

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
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.
-->
<!--
This is an absolute override file, indicating that a higher priority
version of the file will completely replace a lower priority version
of the file.
-->
<pathKeySet>
<pathKey>
<key>qcType</key>
<order>0</order>
</pathKey>
</pathKeySet>