Omaha #4696 Moved everything to grid.netcdf plugin. NOS is all configs. Rename viz.grib.feature to uf.viz.grid.feature.

Change-Id: Ib2590c2c8d1df8c087c28d8adea3fce21e6135d4

Former-commit-id: 3ed99a6aea1602cf26fe7ed0fe7f2d1d306f4948
This commit is contained in:
Nathan Bowler 2015-09-14 16:05:32 -04:00
parent d2988e7f0d
commit b7d04e85b3
55 changed files with 1571 additions and 642 deletions

View file

@ -182,7 +182,7 @@
<param name="feature" value="com.raytheon.viz.warngen.feature" />
</antcall>
<antcall target="p2.build.repo">
<param name="feature" value="com.raytheon.viz.grib.feature" />
<param name="feature" value="com.raytheon.uf.viz.grid.feature" />
</antcall>
<antcall target="p2.build.repo">
<param name="feature" value="com.raytheon.uf.viz.kml.export.feature" />

View file

@ -23,7 +23,7 @@
<import feature="com.raytheon.uf.viz.d2d.xy.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.volumebrowser.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
</requires>
<plugin

View file

@ -23,7 +23,7 @@
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugins.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.sounding.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.displays.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.satellite.feature" version="1.0.0.qualifier"/>

View file

@ -19,7 +19,7 @@
<requires>
<import feature="com.raytheon.uf.viz.d2d.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.displays.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.text.feature" version="1.0.0.qualifier"/>

View file

@ -26,7 +26,7 @@
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.d2d.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.displays.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
</requires>

View file

@ -22,7 +22,7 @@
<import feature="com.raytheon.uf.viz.common.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.radar.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugins.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugin.obs.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.text.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.hydro.feature" version="1.0.0.qualifier"/>

View file

@ -23,7 +23,7 @@
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugins.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.sounding.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
</requires>
<plugin

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.viz.grib.feature</name>
<name>com.raytheon.uf.viz.grid.feature</name>
<comment></comment>
<projects>
</projects>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="com.raytheon.viz.grib.feature"
label="Grib Feature"
id="com.raytheon.uf.viz.grid.feature"
label="Grid Feature"
version="1.0.0.qualifier"
provider-name="RAYTHEON">

View file

@ -70,7 +70,7 @@
version="0.0.0"/>
<includes
id="com.raytheon.viz.grib.feature"
id="com.raytheon.uf.viz.grid.feature"
version="0.0.0"/>
<includes

View file

@ -21,7 +21,7 @@
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.common.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugin.obs.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.core.maps.feature" version="1.0.0.qualifier"/>
</requires>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>
<product name="CAVE" id="com.raytheon.viz.product.awips.CAVE" application="com.raytheon.uf.viz.application.application" useFeatures="true" includeLaunchers="true">
<product name="CAVE" id="com.raytheon.viz.product.awips.CAVE" application="com.raytheon.uf.viz.application.application" useFeatures="true" includeLaunchers="false">
<aboutInfo>
<image path="/com.raytheon.viz.product.awips/icons/ipr.gif"/>
@ -81,7 +81,7 @@
<feature id="com.raytheon.uf.viz.d2d.core.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.viz.radar.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.viz.text.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.uf.viz.kml.export.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.uf.viz.nwsauth.feature" version="1.0.0.qualifier"/>
<feature id="com.raytheon.viz.gfe.feature" version="1.0.0.qualifier"/>

View file

@ -22,7 +22,7 @@
<import feature="com.raytheon.uf.viz.common.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.d2d.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.grib.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.grid.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.uf.viz.dataplugin.obs.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.radar.feature" version="1.0.0.qualifier"/>
<import feature="com.raytheon.viz.satellite.feature" version="1.0.0.qualifier"/>

View file

@ -163,5 +163,6 @@
<vbSource key="WNAwave10" category="SfcGrid" views="PLANVIEW TIMESERIES" />
<vbSource key="WNAwave4" category="SfcGrid" views="PLANVIEW TIMESERIES" />
<vbSource key="WPHwave10" category="SfcGrid" views="PLANVIEW TIMESERIES" />
<vbSource key="PGBlended" category="SfcGrid" views="PLANVIEW TIMESERIES" />
<vbSource key="PGBlended" category="SfcGrid/NOS" views="PLANVIEW TIMESERIES" />
<vbSource key="PGBlended-Night" category="SfcGrid/NOS" views="PLANVIEW TIMESERIES" />
</vbSourceList>

View file

@ -93,5 +93,9 @@
<vbSource key="UKMET-NorthernHemisphere" category="Volume" />
<vbSource key="radar" name="Radar" category="Volume" />
<vbSource key="GEFS" category="Volume" />
<vbSource key="NCOM" category="Volume" views="PLANVIEW TIMESERIES" />
<vbSource key="NCOM-ALASKA" category="Volume/NCOM" views="PLANVIEW TIMESERIES" />
<vbSource key="NCOM-AMSEAS" category="Volume/NCOM" views="PLANVIEW TIMESERIES" />
<vbSource key="NCOM-HAWAII" category="Volume/NCOM" views="PLANVIEW TIMESERIES" />
<vbSource key="NCOM-SOCAL" category="Volume/NCOM" views="PLANVIEW TIMESERIES" />
<vbSource key="NCOM-USEAST" category="Volume/NCOM" views="PLANVIEW TIMESERIES" />
</vbSourceList>

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Grid Coverage
Bundle-SymbolicName: com.raytheon.uf.common.gridcoverage
Bundle-Version: 1.14.0.qualifier
Bundle-Version: 1.15.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy

View file

@ -84,6 +84,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Apr 11, 2014 2947 bsteffen Implement IGridGeometryProvider.
* Oct 16, 2014 3454 bphillip Upgrading to Hibernate 4
* Mar 04, 2015 3959 rjpeter Update for grid based subgridding.
* Sep 16, 2015 4696 nabowle Implement cloneable and add clone().
* </pre>
*
* @author bphillip
@ -99,7 +100,7 @@ import com.vividsolutions.jts.geom.Geometry;
StereographicGridCoverage.class })
@DynamicSerialize
public abstract class GridCoverage extends PersistableDataObject<Integer>
implements ISpatialObject, IGridGeometryProvider {
implements ISpatialObject, IGridGeometryProvider, Cloneable {
private static final long serialVersionUID = -1355232934065074837L;
@ -955,4 +956,17 @@ public abstract class GridCoverage extends PersistableDataObject<Integer>
this.includePole = coverage.includePole;
}
/**
* Clone this GridCoverage.
*/
public GridCoverage clone() throws CloneNotSupportedException {
GridCoverage clone = (GridCoverage) super.clone();
if (this.geometry != null) {
clone.setGeometry((Geometry) this.geometry.clone());
}
return clone;
}
}

View file

@ -20,6 +20,8 @@
package com.raytheon.uf.common.gridcoverage;
import java.util.Arrays;
import javax.persistence.Entity;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlAccessType;
@ -46,6 +48,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* 09/10/2012 DR 15270 D. Friedman Fix subgrid model name handling.
* Jan 17, 2014 2125 rjpeter Removed invalid @Table annotation.
* Mar 04, 2015 3959 rjpeter Update for grid based subgridding.
* Sep 17, 2015 4696 nabowle Add clone().
* </pre>
*
* @author bphillip
@ -209,4 +212,15 @@ public class LatLonGridCoverage extends GridCoverage {
this.isThin = coverage.isThin;
this.parallels = coverage.parallels;
}
public LatLonGridCoverage clone() throws CloneNotSupportedException {
LatLonGridCoverage clone = (LatLonGridCoverage) super.clone();
if (this.parallels != null) {
clone.setParallels(Arrays.copyOf(this.parallels,
this.parallels.length));
}
return clone;
}
}

View file

@ -53,7 +53,7 @@
unpack="false"/>
<plugin
id="com.raytheon.uf.edex.plugin.nos"
id="com.raytheon.uf.edex.plugin.grid.netcdf"
download-size="0"
install-size="0"
version="0.0.0"

View file

@ -38,6 +38,8 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 26, 2015 4699 nabowle Initial creation
* Sep 09, 2015 4696 nabowle Add retrieval at different indices and
* getLength().
*
* </pre>
*
@ -60,10 +62,37 @@ public abstract class AbstractFieldDescription {
this.name = name;
}
/**
* Gets a String from a scalar field.
*/
public abstract String getString(NetcdfFile file)
throws InvalidDescriptionException;
/**
* Gets the String at the supplied index from an n-dimensional field viewed
* as a 1 dimensional array. Scalar fields will always return the same
* String for any index.
*/
public abstract String getString(NetcdfFile file, int index)
throws InvalidDescriptionException;
/**
* Gets a Number value, if possible, from a scalar field.
*/
public abstract Number getNumber(NetcdfFile file)
throws InvalidDescriptionException;
/**
* Gets the Number at the supplied index from an n-dimensional field viewed
* as a 1 dimensional array. Scalar fields will always return the same
* Number for any index.
*/
public abstract Number getNumber(NetcdfFile file, int n)
throws InvalidDescriptionException;
/**
* Get the total number of elements for a field.
*/
public abstract long getLength(NetcdfFile file);
}

View file

@ -44,6 +44,7 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Aug 11, 2015 4709 bsteffen Initial creation
* Aug 25, 2015 4699 nabowle Extracted from Pointset netcdf plugin,
* renamed, and refactored.
* Sep 09, 2015 4696 nabowle Override new methods.
*
* </pre>
*
@ -53,8 +54,7 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
public class AttributeDescription extends AbstractFieldDescription {
@Override
public String getString(NetcdfFile file)
throws InvalidDescriptionException {
public String getString(NetcdfFile file) throws InvalidDescriptionException {
if (name != null) {
Attribute attribute = file.findGlobalAttribute(this.name);
if (attribute == null) {
@ -67,8 +67,23 @@ public class AttributeDescription extends AbstractFieldDescription {
}
@Override
public Number getNumber(NetcdfFile file)
public String getString(NetcdfFile file, int index)
throws InvalidDescriptionException {
if (name != null) {
Attribute attribute = file.findGlobalAttribute(this.name);
if (attribute == null) {
return null;
} else if (attribute.isArray()) {
return attribute.getStringValue(index);
} else {
return attribute.getStringValue();
}
}
return null;
}
@Override
public Number getNumber(NetcdfFile file) throws InvalidDescriptionException {
if (name != null) {
Attribute attribute = file.findGlobalAttribute(this.name);
if (attribute == null) {
@ -80,4 +95,32 @@ public class AttributeDescription extends AbstractFieldDescription {
return null;
}
@Override
public Number getNumber(NetcdfFile file, int index)
throws InvalidDescriptionException {
if (name != null) {
Attribute attribute = file.findGlobalAttribute(this.name);
if (attribute == null) {
return null;
} else if (attribute.isArray()) {
return attribute.getNumericValue(index);
} else {
return attribute.getNumericValue();
}
}
return null;
}
@Override
public long getLength(NetcdfFile file) {
if (name != null) {
Attribute attribute = file.findGlobalAttribute(this.name);
if (attribute == null) {
return 0;
} else {
return attribute.getLength();
}
}
return 0;
}
}

View file

@ -96,18 +96,44 @@ public class LevelDescription {
public Level getLevel(NetcdfFile file, LevelFactory factory)
throws InvalidDescriptionException {
String masterLevel = this.masterLevel.getString(file);
return getLevel(file, factory, 0);
}
/**
*
*
* @param file
* @param factory
* @param levelIndex
* The index for each level component (master level,level one,
* level two), it is expected that each component at this index
* is associated, or the component is scalar and valid for all
* indices of every other non-scalar component.
* @return
* @throws InvalidDescriptionException
*/
public Level getLevel(NetcdfFile file, LevelFactory factory, int levelIndex)
throws InvalidDescriptionException {
if (levelIndex < 0) {
throw new InvalidDescriptionException(
new ArrayIndexOutOfBoundsException(levelIndex));
}
String masterLevel = this.masterLevel.getString(file, levelIndex);
if (masterLevel == null) {
return null;
}
Number levelOneValue = this.levelOneValue.getNumber(file);
Number levelOneValue = this.levelOneValue.getNumber(file, levelIndex);
if (levelOneValue == null) {
return null;
}
if (this.levelTwoValue == null) {
return factory.getLevel(masterLevel, levelOneValue.doubleValue());
}
Number levelTwoValue = this.levelTwoValue.getNumber(file);
Number levelTwoValue = this.levelTwoValue.getNumber(file, levelIndex);
if (levelTwoValue == null) {
return null;
}

View file

@ -42,6 +42,7 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------
* Aug 26, 2015 4699 nabowle Initial creation
* Sep 09, 2015 4696 nabowle Add indexed retrieval and getLength().
*
* </pre>
*
@ -69,6 +70,11 @@ public class ValueDescription extends AbstractFieldDescription {
return null;
}
public String getString(NetcdfFile file, int index)
throws InvalidDescriptionException {
return getString(file);
}
public Number getNumber(NetcdfFile file)
throws InvalidDescriptionException {
if (value != null) {
@ -76,4 +82,14 @@ public class ValueDescription extends AbstractFieldDescription {
}
return null;
}
public Number getNumber(NetcdfFile file, int index)
throws InvalidDescriptionException {
return getNumber(file);
}
@Override
public long getLength(NetcdfFile file) {
return value == null ? 0 : 1;
}
}

View file

@ -24,6 +24,7 @@ import java.io.IOException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import ucar.ma2.Array;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
@ -42,6 +43,7 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Aug 11, 2015 4709 bsteffen Initial creation
* Aug 25, 2015 4699 nabowle Extracted from Pointset netcdf plugin and
* refactored.
* Sep 09, 2015 4696 nabowle Add indexed retrieval and getLength().
*
* </pre>
*
@ -69,6 +71,30 @@ public class VariableDescription extends AbstractFieldDescription {
return null;
}
@Override
public String getString(NetcdfFile file, int index)
throws InvalidDescriptionException {
if (name != null) {
Variable var = file.findVariable(name);
if (var == null) {
return null;
}
if (var.getSize() == 1) {
index = 0;
}
try {
return var.read().getObject(index).toString();
} catch (IOException e) {
throw new InvalidDescriptionException(
"Cannot read a string at index " + index + " from "
+ name, e);
}
}
return null;
}
@Override
public Number getNumber(NetcdfFile file)
throws InvalidDescriptionException {
@ -94,8 +120,7 @@ public class VariableDescription extends AbstractFieldDescription {
default:
throw new InvalidDescriptionException(
"Cannot read a scalar number from " + name
+ " with of data type "
+ var.getDataType());
+ " of data type " + var.getDataType());
}
} catch (IOException e) {
throw new InvalidDescriptionException(
@ -106,4 +131,57 @@ public class VariableDescription extends AbstractFieldDescription {
return null;
}
@Override
public Number getNumber(NetcdfFile file, int index)
throws InvalidDescriptionException {
if (name != null) {
Variable var = file.findVariable(name);
if (var == null) {
return null;
}
if (var.getSize() == 1) {
index = 0;
}
try {
Array array = var.read();
switch (var.getDataType()) {
case BYTE:
return array.getByte(index);
case SHORT:
return array.getShort(index);
case INT:
return array.getInt(index);
case LONG:
return array.getLong(index);
case FLOAT:
return array.getFloat(index);
case DOUBLE:
return array.getDouble(index);
default:
throw new InvalidDescriptionException(
"Cannot read a number at index " + index + " from "
+ name + " of data type "
+ var.getDataType());
}
} catch (IOException e) {
throw new InvalidDescriptionException(
"Error reading a number at index " + index + " from "
+ name, e);
}
}
return null;
}
@Override
public long getLength(NetcdfFile file) {
if (name != null) {
Variable var = file.findVariable(name);
if (var == null) {
return 0;
}
return var.getSize();
}
return 0;
}
}

View file

@ -61,11 +61,6 @@ public class DataTimeDescription {
@XmlElement
private ForecastDescription forecast;
/*
* Eventually this should include the information necessary to pull out
* forecast information and/or time ranges.
*/
public AbstractDateValue getRefTime() {
return refTime;
}

View file

@ -23,6 +23,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -45,6 +46,8 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------
* Aug 25, 2015 4699 nabowle Initial creation
* Sep 09, 2015 4696 nabowle Switch TimeUnits. Rename offsetType for
* consistency.
*
* </pre>
*
@ -57,7 +60,7 @@ public class EpochOffsetDateValue extends AbstractDateValue{
private String epoch;
@XmlAttribute(required = true)
private TimeUnit offsetType;
private TimeUnit units;
private transient SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
@ -72,12 +75,12 @@ public class EpochOffsetDateValue extends AbstractDateValue{
this.epoch = epoch;
}
public TimeUnit getOffsetType() {
return offsetType;
public TimeUnit getUnits() {
return units;
}
public void setOffsetType(TimeUnit offsetType) {
this.offsetType = offsetType;
public void setUnits(TimeUnit units) {
this.units = units;
}
@Override
@ -101,7 +104,7 @@ public class EpochOffsetDateValue extends AbstractDateValue{
Calendar cal = (Calendar) epochCal.clone();
int field;
switch (this.offsetType) {
switch (this.units) {
case DAYS:
field = Calendar.DAY_OF_YEAR;
break;
@ -116,7 +119,7 @@ public class EpochOffsetDateValue extends AbstractDateValue{
break;
default:
throw new InvalidDescriptionException("Unsupported offset type: "
+ offsetType);
+ units);
}
cal.add(field, offsetN.intValue());
return cal.getTime();

View file

@ -19,6 +19,8 @@
**/
package com.raytheon.uf.edex.netcdf.description.date;
import java.util.concurrent.TimeUnit;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@ -27,7 +29,6 @@ import javax.xml.bind.annotation.XmlElements;
import ucar.nc2.NetcdfFile;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.edex.netcdf.description.AbstractFieldDescription;
import com.raytheon.uf.edex.netcdf.description.AttributeDescription;
import com.raytheon.uf.edex.netcdf.description.ValueDescription;
@ -44,6 +45,7 @@ import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionExcep
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 8, 2015 4469 nabowle Initial creation
* Sep 9, 2015 4469 nabowle Switch TimeUnits.
*
* </pre>
*
@ -78,23 +80,7 @@ public class ForecastDescription {
*/
public int getForecast(NetcdfFile file) throws InvalidDescriptionException {
int forecast = this.forecastField.getNumber(file).intValue();
switch (this.units) {
case DAYS:
forecast *= TimeUtil.SECONDS_PER_DAY;
break;
case HOURS:
forecast *= TimeUtil.SECONDS_PER_HOUR;
break;
case SECONDS:
// No-op.
break;
case MILLISECONDS:
forecast = (int) (forecast / (double) TimeUtil.MILLIS_PER_SECOND);
break;
default:
throw new InvalidDescriptionException("Unsupported units: " + units);
}
forecast = Long.valueOf(this.units.toSeconds(forecast)).intValue();
return forecast;
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.raytheon.uf.edex.plugin.nos</name>
<name>com.raytheon.uf.edex.plugin.grid.netcdf</name>
<comment></comment>
<projects>
</projects>

View file

@ -1,10 +1,13 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NOS
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.nos
Bundle-Name: Netcdf Grid
Bundle-SymbolicName: com.raytheon.uf.edex.plugin.grid.netcdf
Bundle-Version: 1.15.0.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: com.raytheon.uf.edex.plugin.grid.netcdf,
com.raytheon.uf.edex.plugin.grid.netcdf.description.coverage,
com.raytheon.uf.edex.plugin.grid.netcdf.description.product
Require-Bundle: ucar.nc2;bundle-version="4.2.0",
com.raytheon.uf.common.dataplugin;bundle-version="1.14.0",
org.slf4j;bundle-version="1.7.5",
@ -12,8 +15,5 @@ Require-Bundle: ucar.nc2;bundle-version="4.2.0",
javax.measure;bundle-version="1.0.0",
com.raytheon.uf.edex.netcdf;bundle-version="1.15.0",
com.raytheon.uf.common.localization;bundle-version="1.14.1",
com.raytheon.uf.common.geospatial;bundle-version="1.15.0"
Export-Package: com.raytheon.uf.edex.plugin.nos.description,
com.raytheon.uf.edex.plugin.nos.ncom.netcdf,
com.raytheon.uf.edex.plugin.nos.netcdf,
com.raytheon.uf.edex.plugin.nos.pgblended.hdf4
com.raytheon.uf.common.geospatial;bundle-version="1.15.0",
com.raytheon.uf.common.serialization;bundle-version="1.15.1"

View file

@ -0,0 +1,48 @@
<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-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="pathManager" class="com.raytheon.uf.common.localization.PathManagerFactory"
factory-method="getPathManager" />
<bean id="netcdfGridDecoder" class="com.raytheon.uf.edex.plugin.grid.netcdf.NetcdfGridDecoder">
<property name="pathManager" ref="pathManager" />
</bean>
<bean id="netcdfGridDistRegistry" factory-bean="distributionSrv"
factory-method="register">
<constructor-arg value="netcdfGrid" />
<constructor-arg value="jms-durable:queue:Ingest.NetcdfGrid" />
</bean>
<camelContext id="netcdfGrid-camel" xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<route id="netcdfGridIngestRoute">
<from uri="jms-durable:queue:Ingest.NetcdfGrid" />
<doTry>
<pipeline>
<bean ref="stringToFile" />
<split streaming="true">
<method bean="netcdfGridDecoder" method="split"/>
<doTry>
<pipeline>
<bean ref="netcdfGridDecoder" method="decode" />
<to uri="direct-vm:persistIndexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="direct-vm:logFailedData" />
</doCatch>
</doTry>
</split>
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="direct-vm:logFailedData" />
</doCatch>
</doTry>
</route>
</camelContext>
</beans>

View file

@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.netcdf;
package com.raytheon.uf.edex.plugin.grid.netcdf;
import java.io.File;
import java.io.IOException;
@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,20 +42,25 @@ import ucar.nc2.Variable;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.dataplugin.level.LevelFactory;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.gridcoverage.exception.GridCoverageException;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.parameter.Parameter;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.netcdf.decoder.exception.NetcdfDecoderException;
import com.raytheon.uf.edex.netcdf.decoder.util.NetcdfDecoderUtils;
import com.raytheon.uf.edex.netcdf.description.AbstractFieldDescription;
import com.raytheon.uf.edex.netcdf.description.LevelDescription;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
import com.raytheon.uf.edex.plugin.nos.description.NosProductDescription;
import com.raytheon.uf.edex.plugin.nos.description.NosProductDescriptions;
import com.raytheon.uf.edex.plugin.grid.netcdf.description.coverage.CoverageCoordinatesDescription;
import com.raytheon.uf.edex.plugin.grid.netcdf.description.product.NetcdfGridProductDescription;
import com.raytheon.uf.edex.plugin.grid.netcdf.description.product.NetcdfGridProductDescriptions;
/**
* Base class for decoding NetCDF files.
* Base class for decoding NetCDF Grid files.
*
* <pre>
*
@ -62,36 +68,28 @@ import com.raytheon.uf.edex.plugin.nos.description.NosProductDescriptions;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 3, 2015 4696 nabowle Initial creation
* Sep 03, 2015 4696 nabowle Initial creation
* Sep 10, 2015 4696 nabowle Refactored. Renamed. No longer abstract.
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public abstract class AbstractNosNetcdfDecoder {
public static final String LON_VAR = "lon";
public static final String LAT_VAR = "lat";
public class NetcdfGridDecoder {
protected static final Logger logger = LoggerFactory
.getLogger(AbstractNosNetcdfDecoder.class);
.getLogger(NetcdfGridDecoder.class);
protected static final GridRecord[] EMPTY_RECORDS = new GridRecord[0];
private NosProductDescriptions descriptions;
private String descriptionFile;
private List<NetcdfGridProductDescriptions> descriptionsList = new ArrayList<>();
/**
* @param descriptionFile
*
* Constructor.
*/
public AbstractNosNetcdfDecoder(String descriptionFile) {
public NetcdfGridDecoder() {
super();
this.descriptionFile = descriptionFile;
}
/**
@ -109,7 +107,7 @@ public abstract class AbstractNosNetcdfDecoder {
*/
public GridRecord[] decode(File f) {
Iterator<NosRecordInfo> iter = split(f);
Iterator<NetcdfGridRecordInfo> iter = split(f);
List<GridRecord> records = new ArrayList<>();
@ -127,11 +125,25 @@ public abstract class AbstractNosNetcdfDecoder {
return records.toArray(EMPTY_RECORDS);
}
public GridRecord[] decode(NosRecordInfo recordInfo) {
NosProductDescription product = recordInfo.getDescription();
public GridRecord[] decode(NetcdfGridRecordInfo recordInfo) {
NetcdfGridProductDescription product = recordInfo.getDescription();
File f = recordInfo.getFile();
int levelIndex = recordInfo.getLevelIdx();
NetcdfFile file = null;
NetcdfGridProductDescriptions descriptions = null;
for (NetcdfGridProductDescriptions descriptionFile : this.descriptionsList) {
if (descriptionFile.matches(f.getName())) {
descriptions = descriptionFile;
break;
}
}
if (descriptions == null) {
logger.warn("No matching descriptions for file: {}", f.getName());
return EMPTY_RECORDS;
}
try {
file = NetcdfFile.open(f.getAbsolutePath());
@ -143,7 +155,8 @@ public abstract class AbstractNosNetcdfDecoder {
return EMPTY_RECORDS;
}
Level level = getLevel(recordInfo, file);
Level level = descriptions.getLevel().getLevel(file,
LevelFactory.getInstance(), recordInfo.getLevelIdx());
if (level == null) {
logger.error("Cannot decode level data in file: {}",
f.getName());
@ -163,7 +176,7 @@ public abstract class AbstractNosNetcdfDecoder {
record.setParameter(param);
List<Dimension> dimensions = dataVar.getDimensions();
List<Range> ranges = dataVar.getRanges();
final String levelOneName = getDescriptions().getLevel()
final String levelOneName = descriptions.getLevel()
.getLevelOneValue().getName();
/*
@ -181,9 +194,9 @@ public abstract class AbstractNosNetcdfDecoder {
// start and end range values are inclusive.
sect.appendRange(new Range(levelIndex, levelIndex));
} else {
if (LAT_VAR.equals(dim.getName())) {
if (recordInfo.getLatField().equals(dim.getName())) {
latDimIdx = i;
} else if (LON_VAR.equals(dim.getName())) {
} else if (recordInfo.getLonField().equals(dim.getName())) {
lonDimIdx = i;
}
sect.appendRange(ranges.get(i));
@ -214,6 +227,7 @@ public abstract class AbstractNosNetcdfDecoder {
// No-op
}
boolean dataPresent = false;
float[] data = (float[]) dataArr.get1DJavaArray(float.class);
float val;
for (int i = 0; i < data.length; i++) {
@ -224,10 +238,15 @@ public abstract class AbstractNosNetcdfDecoder {
val = val * scaleFactor + addOffset;
}
data[i] = val;
dataPresent |= !Float.isNaN(val);
}
record.setMessageData(data);
return new GridRecord[] { record };
if (dataPresent) {
return new GridRecord[] { record };
} else {
return EMPTY_RECORDS;
}
} catch (IOException | InvalidRangeException
| InvalidDescriptionException e) {
logger.error("Unable to decode {} {} from file: {}",
@ -254,37 +273,76 @@ public abstract class AbstractNosNetcdfDecoder {
* The file to split.
* @return An iterator over the record descriptions.
*/
public Iterator<NosRecordInfo> split(File f) {
List<NosRecordInfo> infos = new ArrayList<>();
public Iterator<NetcdfGridRecordInfo> split(File f) {
List<NetcdfGridRecordInfo> infos = new ArrayList<>();
NetcdfFile file = null;
try {
file = NetcdfFile.open(f.getAbsolutePath());
NosProductDescriptions descriptions = this.getDescriptions();
int numLevels = getNumLevels(file);
NetcdfGridProductDescriptions descriptions = null;
for (NetcdfGridProductDescriptions descriptionFile : this.descriptionsList) {
if (descriptionFile.matches(f.getName())) {
descriptions = descriptionFile;
break;
}
}
if (descriptions == null) {
throw new NetcdfDecoderException("No matching descriptions.");
}
long numLevels = getNumLevels(file, descriptions);
if (numLevels == 0) {
throw new NetcdfDecoderException(
"Cannot determine the number of levels.");
}
DataTime dataTime = descriptions.getDataTime().getDataTime(file);
if (dataTime == null) {
throw new InvalidDescriptionException(
throw new NetcdfDecoderException(
"Cannot decode the data time.");
}
GridCoverage location = getCoverage(file);
GridCoverage location = getCoverage(file, descriptions);
NosRecordInfo info;
for (NosProductDescription prod : descriptions.getDescriptions()) {
String latField = null;
String lonField = null;
CoverageCoordinatesDescription coordDesc = descriptions
.getCoverage().getCoordinatesDescription();
if (coordDesc != null) {
AbstractFieldDescription coordField = coordDesc.getLatitude();
if (coordField != null) {
latField = coordField.getName();
}
coordField = coordDesc.getLongitude();
if (coordField != null) {
lonField = coordField.getName();
}
}
NetcdfGridRecordInfo info;
for (NetcdfGridProductDescription prod : descriptions.getDescriptions()) {
for (int i = 0; i < numLevels; i++) {
info = new NosRecordInfo();
info = new NetcdfGridRecordInfo();
info.setDataTime(dataTime);
info.setLevelIdx(i);
info.setFile(f);
info.setDescription(prod);
info.setLocation(location);
if (latField != null) {
info.setLatField(latField);
}
if (lonField != null) {
info.setLonField(lonField);
}
infos.add(info);
}
}
} catch (IOException | InvalidDescriptionException
| GridCoverageException e) {
| NetcdfDecoderException e) {
logger.error("Unable split file: {}", f.getName(), e);
} finally {
if (file != null) {
@ -300,60 +358,75 @@ public abstract class AbstractNosNetcdfDecoder {
}
/**
* The {@link IPathManager} is used to look up the configured description
* file.
* @param file
* @return
* @throws NetcdfDecoderException
*/
public void setPathManager(IPathManager pathManager) {
LocalizationFile file = pathManager
.getStaticLocalizationFile(this.descriptionFile);
if (file == null) {
logger.error("Unable to load product descriptions");
return;
}
logger.info("Loading NOS description from " + file.getName());
try (InputStream inputStream = file.openInputStream()) {
this.descriptions = JAXB.unmarshal(inputStream,
NosProductDescriptions.class);
} catch (LocalizationException | IOException e) {
logger.error("Unable to load product descriptions from {}",
file.getName(), e);
}
}
protected long getNumLevels(NetcdfFile file,
NetcdfGridProductDescriptions descriptions)
throws NetcdfDecoderException {
LevelDescription levelDesc = descriptions.getLevel();
public NosProductDescriptions getDescriptions() {
return this.descriptions;
long numLevels = 0;
AbstractFieldDescription afd = levelDesc.getMasterLevel();
if (afd != null) {
numLevels = afd.getLength(file);
}
afd = levelDesc.getLevelOneValue();
if (afd != null) {
numLevels = Math.max(numLevels, afd.getLength(file));
}
afd = levelDesc.getLevelTwoValue();
if (afd != null) {
numLevels = Math.max(numLevels, afd.getLength(file));
}
return numLevels;
}
/**
* Get the number of levels in the file.
*
* @param file
* @return
*/
protected abstract int getNumLevels(NetcdfFile file)
throws InvalidDescriptionException;
/**
* Get the grid coverage for the file.
*
* @param file
* @return
* @throws GridCoverageException
* @throws IOException
*/
protected abstract GridCoverage getCoverage(NetcdfFile file)
throws GridCoverageException, IOException;
/**
* Get the Level for a specific record.
*
* @param recordInfo
* @param file
* @return
* @throws InvalidDescriptionException
* @throws IOException
*/
protected abstract Level getLevel(NosRecordInfo recordInfo, NetcdfFile file)
throws IOException, InvalidDescriptionException;
protected GridCoverage getCoverage(NetcdfFile file,
NetcdfGridProductDescriptions descriptions)
throws InvalidDescriptionException, NetcdfDecoderException {
return descriptions.getCoverage().getInitializedCoverage(file);
}
/**
* The {@link IPathManager} is used to look up the configured description
* file.
*
* @throws JAXBException
* @throws SerializationException
*/
public void setPathManager(IPathManager pathManager) {
LocalizationFile[] files = pathManager.listStaticFiles("grid/netcdf",
new String[] { ".xml" }, true, true);
NetcdfGridProductDescriptions descriptions;
for (LocalizationFile file : files) {
logger.info("Loading Netcdf Grid description from "
+ file.getName());
try (InputStream inputStream = file.openInputStream()) {
descriptions = JAXB.unmarshal(inputStream,
NetcdfGridProductDescriptions.class);
this.descriptionsList.add(descriptions);
} catch (LocalizationException | IOException e) {
logger.error("Unable to load product descriptions from {}",
file.getName(), e);
}
}
if (this.descriptionsList.isEmpty()) {
logger.error("No descriptions were loaded. Nothing will be decoded.");
}
}
public List<NetcdfGridProductDescriptions> getDescriptionsList() {
return this.descriptionsList;
}
}

View file

@ -17,18 +17,18 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.netcdf;
package com.raytheon.uf.edex.plugin.grid.netcdf;
import java.io.File;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.plugin.nos.description.NosProductDescription;
import com.raytheon.uf.edex.plugin.grid.netcdf.description.product.NetcdfGridProductDescription;
/**
* Holds the information needed to be able to decode a NOS grid record, allowing
* an NOS file to be split and decoded without having to keep more in memory
* than is necessary.
* Holds the information needed to be able to decode a Netcdf grid record,
* allowing an netcdf file to be split and decoded without having to keep more
* in memory than is necessary.
*
* <pre>
*
@ -37,13 +37,14 @@ import com.raytheon.uf.edex.plugin.nos.description.NosProductDescription;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 28, 2015 4696 nabowle Initial creation
* Sep 14, 2015 4696 nabowle Renamed. Added lat/lon field names.
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public class NosRecordInfo {
public class NetcdfGridRecordInfo {
/** The file on disk that is to be decoded. */
private File file;
@ -57,14 +58,18 @@ public class NosRecordInfo {
/** The index into the level data for this record. */
private int levelIdx;
private String latField = "lat";
private String lonField = "lon";
/** The description of this product. */
private NosProductDescription description;
private NetcdfGridProductDescription description;
/**
* Constructor.
*/
public NosRecordInfo() {
public NetcdfGridRecordInfo() {
super();
}
@ -128,10 +133,40 @@ public class NosRecordInfo {
this.levelIdx = levelIdx;
}
/**
* @return the latField
*/
public String getLatField() {
return latField;
}
/**
* @param latField
* the latField to set
*/
public void setLatField(String latField) {
this.latField = latField;
}
/**
* @return the lonField
*/
public String getLonField() {
return lonField;
}
/**
* @param lonField
* the lonField to set
*/
public void setLonField(String lonField) {
this.lonField = lonField;
}
/**
* @return the description
*/
public NosProductDescription getDescription() {
public NetcdfGridProductDescription getDescription() {
return description;
}
@ -139,13 +174,13 @@ public class NosRecordInfo {
* @param description
* the description to set
*/
public void setDescription(NosProductDescription description) {
public void setDescription(NetcdfGridProductDescription description) {
this.description = description;
}
@Override
public String toString() {
return "NosRecordInfo [file=" + file + ", dataTime=" + dataTime
return "NetcdfGridRecordInfo [file=" + file + ", dataTime=" + dataTime
+ ", levelIdx=" + levelIdx + ", description=" + description
+ "]";
}

View file

@ -0,0 +1,162 @@
/**
* 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.grid.netcdf.description.coverage;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import ucar.nc2.NetcdfFile;
import com.raytheon.uf.common.gridcoverage.Corner;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.edex.netcdf.decoder.exception.NetcdfDecoderException;
import com.raytheon.uf.edex.netcdf.description.AbstractFieldDescription;
import com.raytheon.uf.edex.netcdf.description.ValueDescription;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
/**
* Describes the coordinates for a Grid Coverage where the latitude and
* longitude coordinates are stored in separate fields as lists.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 11, 2015 4698 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class CoordinateListsDescription extends
CoverageCoordinatesDescription {
/**
* Constructor.
*/
public CoordinateListsDescription() {
super();
}
@Override
public void updateCoverage(GridCoverage coverage, NetcdfFile file)
throws InvalidDescriptionException {
validateRequirements(coverage);
double[] latRange = getCoordRange(file, this.latitude);
double dy = Math.abs(latRange[1] - latRange[0]);
int ny = (int) this.latitude.getLength(file);
dy /= ny - 1;
double[] lonRange = getCoordRange(file, this.longitude);
double dx = Math.abs(lonRange[1] - lonRange[0]);
int nx = (int) this.longitude.getLength(file);
dx /= nx - 1;
Corner corner;
double laCenterOffset = dy * .5;
double loCenterOffset = dx * .5;
if (latRange[0] >= latRange[1]) {
laCenterOffset = -laCenterOffset;
if (lonRange[0] <= lonRange[1]) {
corner = Corner.UpperLeft;
} else {
corner = Corner.UpperRight;
loCenterOffset = -loCenterOffset;
}
} else {
if (lonRange[0] <= lonRange[1]) {
corner = Corner.LowerLeft;
} else {
corner = Corner.LowerRight;
loCenterOffset = -loCenterOffset;
}
}
double lo1 = lonRange[0];
if (lo1 > 180) {
lo1 -= 360;
} else if (lo1 < -180) {
lo1 += 360;
}
coverage.setDx(dx);
coverage.setDy(dy);
coverage.setNx(nx);
coverage.setNy(ny);
coverage.setLa1(latRange[0] + laCenterOffset);
coverage.setLo1(lo1 + loCenterOffset);
coverage.setFirstGridPointCorner(corner);
coverage.setSpacingUnit("degree");
}
/**
* @param coverage
* @throws InvalidDescriptionException
*/
private void validateRequirements(GridCoverage coverage)
throws InvalidDescriptionException {
if (coverage == null) {
throw new InvalidDescriptionException(
"A base coverage specifying the projection is required.");
}
if (this.latitude == null) {
throw new InvalidDescriptionException(
"Latitude field is not configured.");
}
if (this.longitude == null) {
throw new InvalidDescriptionException(
"Longitude field is not configured.");
}
// Cannot support value descriptions because they're scalar
if (this.latitude instanceof ValueDescription
|| this.longitude instanceof ValueDescription) {
throw new InvalidDescriptionException(
"Value descriptions are unsupported for latitude and longitude of "
+ getClass().getName());
}
}
/**
* Returns the first and last values for a coordinate.
*
* @param coordVar
* The coordinate variable.
* @return The first and last values for a coordinate.
* @throws NetcdfDecoderException
*/
private double[] getCoordRange(NetcdfFile file,
AbstractFieldDescription field) throws InvalidDescriptionException {
int len = (int) field.getLength(file);
if (len < 2) {
throw new InvalidDescriptionException(field.getName()
+ " does not have at least two coordinates.");
}
return new double[] { field.getNumber(file, 0).doubleValue(),
field.getNumber(file, len - 1).doubleValue() };
}
}

View file

@ -0,0 +1,97 @@
/**
* 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.grid.netcdf.description.coverage;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import com.raytheon.uf.edex.netcdf.description.AbstractFieldDescription;
import com.raytheon.uf.edex.netcdf.description.AttributeDescription;
import com.raytheon.uf.edex.netcdf.description.ValueDescription;
import com.raytheon.uf.edex.netcdf.description.VariableDescription;
/**
* Base class for describing the coordinate information of a GridCoverage.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 14, 2015 4696 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public abstract class CoverageCoordinatesDescription implements
CoverageFieldDescription {
@XmlElements({
@XmlElement(name = "latitudeValue", type = ValueDescription.class),
@XmlElement(name = "latitudeVariable", type = VariableDescription.class),
@XmlElement(name = "latitudeAttribute", type = AttributeDescription.class) })
protected AbstractFieldDescription latitude;
@XmlElements({
@XmlElement(name = "longitudeValue", type = ValueDescription.class),
@XmlElement(name = "longitudeVariable", type = VariableDescription.class),
@XmlElement(name = "longitudeAttribute", type = AttributeDescription.class) })
protected AbstractFieldDescription longitude;
public CoverageCoordinatesDescription() {
super();
}
/**
* @return the latitude
*/
public AbstractFieldDescription getLatitude() {
return latitude;
}
/**
* @param latitude
* the latitude to set
*/
public void setLatitude(AbstractFieldDescription latitude) {
this.latitude = latitude;
}
/**
* @return the longitude
*/
public AbstractFieldDescription getLongitude() {
return longitude;
}
/**
* @param longitude
* the longitude to set
*/
public void setLongitude(AbstractFieldDescription longitude) {
this.longitude = longitude;
}
}

View file

@ -17,10 +17,16 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.netcdf.description.date;
package com.raytheon.uf.edex.plugin.grid.netcdf.description.coverage;
import ucar.nc2.NetcdfFile;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
/**
* Enum for specifying the time unit of a field.
* Describes a coverage field and provides a means to update a given
* GridCoverage from a NetcdfFile.
*
* <pre>
*
@ -28,13 +34,15 @@ package com.raytheon.uf.edex.netcdf.description.date;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 8, 2015 4496 nabowle Initial creation
* Sep 14, 2015 4469 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public enum TimeUnit {
DAYS, HOURS, SECONDS, MILLISECONDS;
public interface CoverageFieldDescription {
void updateCoverage(GridCoverage coverage, NetcdfFile file)
throws InvalidDescriptionException;
}

View file

@ -0,0 +1,222 @@
/**
* 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.grid.netcdf.description.coverage;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlSeeAlso;
import ucar.nc2.NetcdfFile;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.gridcoverage.LambertConformalGridCoverage;
import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage;
import com.raytheon.uf.common.gridcoverage.MercatorGridCoverage;
import com.raytheon.uf.common.gridcoverage.PolarStereoGridCoverage;
import com.raytheon.uf.common.gridcoverage.exception.GridCoverageException;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationException;
import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
/**
* Describes a Grid Coverage.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 9, 2015 4469 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
@XmlSeeAlso(CoordinateListsDescription.class)
public class GridCoverageDescription {
@XmlAttribute
private String coverageFile;
@XmlElements({
@XmlElement(name = "latLonGridCoverage", type = LatLonGridCoverage.class),
@XmlElement(name = "mercatorGridCoverage", type = MercatorGridCoverage.class),
@XmlElement(name = "lambertConformalGridCoverage", type = LambertConformalGridCoverage.class),
@XmlElement(name = "polarStereoGridCoverage", type = PolarStereoGridCoverage.class)/*,
@XmlElement(name = "stereographicGridCoverage", type = StereographicGridCoverage.class)*/ })
private GridCoverage coverage;
@XmlElements({ @XmlElement(name = "coordinateLists", type = CoordinateListsDescription.class) })
private CoverageCoordinatesDescription coordinatesDescription;
/*
* TODO: Eventually this could have a list of CoverageFieldDescriptions that
* specify how to extract various parts of the coverage that are
* indeterminate from the coordinate description.
*/
public GridCoverageDescription() {
super();
}
/**
* Returns a copy of the coverage, which may not be fully initialized, but
* is safe to modify. If a coverage is not specified, either by
* {@link #coverage} by {@link #coverageFile}, null is returned.
*
* @return the coverage
* @throws InvalidDescriptionException
* If the described coverage is non-null and invalid.
*/
public synchronized GridCoverage getCoverage()
throws InvalidDescriptionException {
if (this.coverage == null) {
loadFromLocalizationFile();
if (this.coverage == null) {
return null;
}
}
GridCoverage retCoverage;
try {
retCoverage = (GridCoverage) this.coverage.clone();
} catch (CloneNotSupportedException e) {
throw new InvalidDescriptionException(
"Unsupported GridCoverage type "
+ this.coverage.getClass().getName(), e);
}
return retCoverage;
}
/**
* @param coverage
* the coverage to set
*/
public synchronized void setCoverage(GridCoverage coverage) {
this.coverage = coverage;
}
/**
* @return the coverageFile
*/
public String getCoverageFile() {
return coverageFile;
}
/**
* @param coverageFile
* the coverageFile to set
*/
public void setCoverageFile(String coverageFile) {
this.coverageFile = coverageFile;
}
/**
* @return the coordinatesDescription
*/
public CoverageCoordinatesDescription getCoordinatesDescription() {
return coordinatesDescription;
}
/**
* @param coordinatesDescription
* the coordinatesDescription to set
*/
public void setCoordinatesDescription(
CoverageCoordinatesDescription coordinatesDescription) {
this.coordinatesDescription = coordinatesDescription;
}
/**
*
* @param file
* @return
* @throws InvalidDescriptionException
*/
public synchronized GridCoverage getInitializedCoverage(NetcdfFile file)
throws InvalidDescriptionException {
GridCoverage retCoverage = getCoverage();
initializeFromFields(retCoverage, file);
if (retCoverage == null) {
throw new InvalidDescriptionException(
"Could not initialize the coverage.");
}
try {
retCoverage.initialize();
} catch (GridCoverageException e) {
throw new InvalidDescriptionException(
"Could not initialize the coverage.", e);
}
return retCoverage;
}
private void initializeFromFields(GridCoverage coverage, NetcdfFile file)
throws InvalidDescriptionException {
if (this.coordinatesDescription != null) {
this.coordinatesDescription.updateCoverage(coverage, file);
}
}
/**
* Loads the grid coverage from the specified localization file.
*
* @throws InvalidDescriptionException
*/
private void loadFromLocalizationFile() throws InvalidDescriptionException {
if (this.coverageFile == null) {
return;
}
LocalizationFile locFile = PathManagerFactory.getPathManager()
.getStaticLocalizationFile(LocalizationType.EDEX_STATIC,
this.coverageFile);
if (locFile == null) {
throw new InvalidDescriptionException(
"Cannot find grid coverage file " + this.coverageFile);
}
try (InputStream inputStream = locFile.openInputStream()) {
// JAXBManager unmarshal works fine, JAXB.unmarshal does not.
JAXBManager jaxb = new JAXBManager(GridCoverage.class);
this.coverage = (GridCoverage) jaxb
.unmarshalFromInputStream(inputStream);
} catch (LocalizationException | IOException | SerializationException
| JAXBException e) {
throw new InvalidDescriptionException(
"Unable to load grid coverage from " + this.coverageFile);
}
}
}

View file

@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.description;
package com.raytheon.uf.edex.plugin.grid.netcdf.description.product;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -43,7 +43,7 @@ import com.raytheon.uf.edex.netcdf.description.VariableDescription;
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class NosProductDescription {
public class NetcdfGridProductDescription {
@XmlElement(required = true)
private VariableDescription data;
@ -61,7 +61,7 @@ public class NosProductDescription {
/**
* Constructor.
*/
public NosProductDescription() {
public NetcdfGridProductDescription() {
super();
}
@ -127,7 +127,7 @@ public class NosProductDescription {
@Override
public String toString() {
return "NosProductDescription [data="
return "NetcdfGridProductDescription [data="
+ data.getName() + ", parameter=" + parameter + "]";
}

View file

@ -17,22 +17,28 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.description;
package com.raytheon.uf.edex.plugin.grid.netcdf.description.product;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.edex.netcdf.description.LevelDescription;
import com.raytheon.uf.edex.netcdf.description.date.DataTimeDescription;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
import com.raytheon.uf.edex.plugin.grid.netcdf.description.coverage.GridCoverageDescription;
/**
* Contains a list of individual {@link NosProductDescription}s as well as
* information that pertains to all listed products.
* Contains a list of individual {@link NetcdfGridProductDescription}s as well
* as information that pertains to all listed products.
*
* <pre>
*
@ -49,10 +55,10 @@ import com.raytheon.uf.edex.netcdf.description.date.DataTimeDescription;
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class NosProductDescriptions {
public class NetcdfGridProductDescriptions {
@XmlElement(name = "description")
private List<NosProductDescription> descriptions;
private List<NetcdfGridProductDescription> descriptions;
@XmlElement(required = true)
private LevelDescription level;
@ -60,32 +66,39 @@ public class NosProductDescriptions {
@XmlElement(required = true)
private DataTimeDescription dataTime;
@XmlElement(required = true)
private GridCoverageDescription coverage;
@XmlElement(required = true)
private String datasetId;
@XmlElement(required = true)
@XmlJavaTypeAdapter(PatternTypeAdapter.class)
private Pattern pattern;
/**
* Constructor.
*/
public NosProductDescriptions() {
public NetcdfGridProductDescriptions() {
super();
}
public List<NosProductDescription> getDescriptions() {
public List<NetcdfGridProductDescription> getDescriptions() {
return descriptions;
}
public void setDescriptions(List<NosProductDescription> descriptions) {
public void setDescriptions(List<NetcdfGridProductDescription> descriptions) {
this.descriptions = descriptions;
}
public void addDescription(NosProductDescription description) {
public void addDescription(NetcdfGridProductDescription description) {
if (this.descriptions == null) {
this.descriptions = new ArrayList<>();
}
this.descriptions.add(description);
}
public void addDescriptions(NosProductDescriptions descriptions) {
public void addDescriptions(NetcdfGridProductDescriptions descriptions) {
if (this.descriptions == null) {
this.descriptions = new ArrayList<>();
}
@ -122,6 +135,26 @@ public class NosProductDescriptions {
this.dataTime = datatime;
}
/**
* @return the coverage
* @throws InvalidDescriptionException
*/
public GridCoverageDescription getCoverage()
throws InvalidDescriptionException {
if (coverage == null) {
throw new InvalidDescriptionException("Coverage not specified.");
}
return coverage;
}
/**
* @param coverage
* the coverage to set
*/
public void setCoverage(GridCoverageDescription coverage) {
this.coverage = coverage;
}
/**
* @return the datasetId
*/
@ -136,4 +169,55 @@ public class NosProductDescriptions {
public void setDatasetId(String datasetId) {
this.datasetId = datasetId;
}
public Pattern getPattern() {
return this.pattern;
}
/**
* @param patternString
* the pattern to set
*/
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
/**
* Convenience method to determine if the pattern matches a given String.
*
* @param input
* The String to test for matching.
* @return True if the String matches the pattern, false otherwise.
*/
public boolean matches(String input) {
if (this.pattern == null) {
return false;
}
Matcher m = this.pattern.matcher(input);
return m.matches();
}
private static class PatternTypeAdapter extends XmlAdapter<String, Pattern> {
@Override
public Pattern unmarshal(String patternStr) throws Exception {
if (patternStr == null) {
return null;
}
return Pattern.compile(patternStr);
}
@Override
public String marshal(Pattern pattern) throws Exception {
if (pattern == null) {
return null;
}
return pattern.pattern();
}
}
}

View file

@ -0,0 +1,75 @@
<?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.
-->
<netcdfGridProductDescriptions>
<dataTime>
<formattedRefTime dateFormat="yyyy-MM-dd HH:mm:ss">
<attribute name="time_origin" />
</formattedRefTime>
<forecast units="HOURS">
<variable name="tau" />
</forecast>
</dataTime>
<level>
<masterLevelValue value="BSS" />
<levelOneValueVariable name="depth" />
</level>
<datasetId>NCOM-ALASKA</datasetId>
<pattern>^ncom_relo_alaska.*</pattern>
<coverage>
<latLonGridCoverage />
<coordinateLists>
<latitudeVariable name="lat" />
<longitudeVariable name="lon" />
</coordinateLists>
</coverage>
<description>
<data name="water_u" /> <!-- Eastward -->
<parameter>UOGRD</parameter>
<parameterName>u-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_v" /> <!-- Northward -->
<parameter>VOGRD</parameter>
<parameterName>v-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_temp" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
<description>
<data name="salinity" />
<parameter>SALIN</parameter>
<parameterName>Practical Salinity</parameterName>
<units>PSU</units>
</description>
</netcdfGridProductDescriptions>

View file

@ -0,0 +1,75 @@
<?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.
-->
<netcdfGridProductDescriptions>
<dataTime>
<formattedRefTime dateFormat="yyyy-MM-dd HH:mm:ss">
<attribute name="time_origin" />
</formattedRefTime>
<forecast units="HOURS">
<variable name="tau" />
</forecast>
</dataTime>
<level>
<masterLevelValue value="BSS" />
<levelOneValueVariable name="depth" />
</level>
<datasetId>NCOM-AMSEAS</datasetId>
<pattern>^ncom_relo_amseas.*</pattern>
<coverage>
<latLonGridCoverage />
<coordinateLists>
<latitudeVariable name="lat" />
<longitudeVariable name="lon" />
</coordinateLists>
</coverage>
<description>
<data name="water_u" /> <!-- Eastward -->
<parameter>UOGRD</parameter>
<parameterName>u-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_v" /> <!-- Northward -->
<parameter>VOGRD</parameter>
<parameterName>v-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_temp" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
<description>
<data name="salinity" />
<parameter>SALIN</parameter>
<parameterName>Practical Salinity</parameterName>
<units>PSU</units>
</description>
</netcdfGridProductDescriptions>

View file

@ -18,7 +18,7 @@
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information.
-->
<nosProductDescriptions>
<netcdfGridProductDescriptions>
<dataTime>
<formattedRefTime dateFormat="yyyy-MM-dd HH:mm:ss">
<attribute name="time_origin" />
@ -33,7 +33,17 @@
<levelOneValueVariable name="depth" />
</level>
<datasetId>NCOM</datasetId>
<datasetId>NCOM-HAWAII</datasetId>
<pattern>^ncom_relo_haw.*</pattern>
<coverage>
<latLonGridCoverage />
<coordinateLists>
<latitudeVariable name="lat" />
<longitudeVariable name="lon" />
</coordinateLists>
</coverage>
<description>
<data name="water_u" /> <!-- Eastward -->
@ -62,4 +72,4 @@
<parameterName>Practical Salinity</parameterName>
<units>PSU</units>
</description>
</nosProductDescriptions>
</netcdfGridProductDescriptions>

View file

@ -0,0 +1,75 @@
<?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.
-->
<netcdfGridProductDescriptions>
<dataTime>
<formattedRefTime dateFormat="yyyy-MM-dd HH:mm:ss">
<attribute name="time_origin" />
</formattedRefTime>
<forecast units="HOURS">
<variable name="tau" />
</forecast>
</dataTime>
<level>
<masterLevelValue value="BSS" />
<levelOneValueVariable name="depth" />
</level>
<datasetId>NCOM-SOCAL</datasetId>
<pattern>^ncom_relo_socal.*</pattern>
<coverage>
<latLonGridCoverage />
<coordinateLists>
<latitudeVariable name="lat" />
<longitudeVariable name="lon" />
</coordinateLists>
</coverage>
<description>
<data name="water_u" /> <!-- Eastward -->
<parameter>UOGRD</parameter>
<parameterName>u-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_v" /> <!-- Northward -->
<parameter>VOGRD</parameter>
<parameterName>v-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_temp" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
<description>
<data name="salinity" />
<parameter>SALIN</parameter>
<parameterName>Practical Salinity</parameterName>
<units>PSU</units>
</description>
</netcdfGridProductDescriptions>

View file

@ -0,0 +1,75 @@
<?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.
-->
<netcdfGridProductDescriptions>
<dataTime>
<formattedRefTime dateFormat="yyyy-MM-dd HH:mm:ss">
<attribute name="time_origin" />
</formattedRefTime>
<forecast units="HOURS">
<variable name="tau" />
</forecast>
</dataTime>
<level>
<masterLevelValue value="BSS" />
<levelOneValueVariable name="depth" />
</level>
<datasetId>NCOM-USEAST</datasetId>
<pattern>^ncom_relo_useast.*</pattern>
<coverage>
<latLonGridCoverage />
<coordinateLists>
<latitudeVariable name="lat" />
<longitudeVariable name="lon" />
</coordinateLists>
</coverage>
<description>
<data name="water_u" /> <!-- Eastward -->
<parameter>UOGRD</parameter>
<parameterName>u-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_v" /> <!-- Northward -->
<parameter>VOGRD</parameter>
<parameterName>v-component of current</parameterName>
<units>m/s</units>
</description>
<description>
<data name="water_temp" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
<description>
<data name="salinity" />
<parameter>SALIN</parameter>
<parameterName>Practical Salinity</parameterName>
<units>PSU</units>
</description>
</netcdfGridProductDescriptions>

View file

@ -0,0 +1,45 @@
<?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.
-->
<netcdfGridProductDescriptions>
<dataTime>
<epochOffsetRefTime epoch="1970-01-01 00:00:00" units="DAYS">
<attribute name="pass_date" />
</epochOffsetRefTime>
</dataTime>
<level>
<masterLevelValue value="SFC" />
<levelOneValue value="0.0" />
</level>
<datasetId>PGBlended-Night</datasetId>
<pattern>^sst_geo-polar-blended_night_5km.*</pattern>
<coverage coverageFile="netcdf/grids/5km_world.xml" />
<description>
<data name="sst_analysis" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
</netcdfGridProductDescriptions>

View file

@ -18,24 +18,28 @@
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information.
-->
<nosProductDescriptions>
<netcdfGridProductDescriptions>
<dataTime>
<epochOffsetRefTime epoch="1970-01-01 00:00:00" offsetType="DAYS">
<epochOffsetRefTime epoch="1970-01-01 00:00:00" units="DAYS">
<attribute name="pass_date" />
</epochOffsetRefTime>
</dataTime>
<level>
<masterLevelValue value="SFC" />
<levelOneValue value="0.0" name="levelOneValue" />
<levelOneValue value="0.0" />
</level>
<datasetId>PGBlended</datasetId>
<pattern>^sst_geo-polar-blended_5km.*</pattern>
<coverage coverageFile="netcdf/grids/5km_world.xml" />
<description>
<data name="sst_analysis" />
<parameter>T</parameter>
<parameterName>Temperature</parameterName>
<units>C</units>
</description>
</nosProductDescriptions>
</netcdfGridProductDescriptions>

View file

@ -19,6 +19,7 @@
further_licensing_information.
-->
<requestPatterns xmlns:ns2="group">
<!-- NOS -->
<regex>^sst_geo-polar-blended.*</regex>
<regex>^ncom_relo.*</regex>
</requestPatterns>

View file

@ -0,0 +1,30 @@
<?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.
-->
<latLonGridCoverage>
<la1>89.975</la1>
<lo1>-179.975</lo1>
<nx>7200</nx>
<ny>3600</ny>
<dx>0.05</dx>
<dy>0.05</dy>
<firstGridPointCorner>UpperLeft</firstGridPointCorner>
<spacingUnit>degree</spacingUnit>
</latLonGridCoverage>

View file

@ -1,64 +0,0 @@
<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-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="nosPathManager" class="com.raytheon.uf.common.localization.PathManagerFactory"
factory-method="getPathManager" />
<bean id="pgblendedHdf4Decoder" class="com.raytheon.uf.edex.plugin.nos.pgblended.hdf4.PGBlendedHdf4Decoder">
<constructor-arg value="nos/netcdf/pgblended.xml" />
<property name="pathManager" ref="nosPathManager" />
</bean>
<bean id="ncomNetcdfDecoder" class="com.raytheon.uf.edex.plugin.nos.ncom.netcdf.NcomNetcdfDecoder">
<constructor-arg value="nos/netcdf/ncom.xml" />
<property name="pathManager" ref="nosPathManager" />
</bean>
<bean id="nosDistRegistry" factory-bean="distributionSrv"
factory-method="register">
<constructor-arg value="nos" />
<constructor-arg value="jms-durable:queue:Ingest.NOS" />
</bean>
<camelContext id="nos-camel" xmlns="http://camel.apache.org/schema/spring"
errorHandlerRef="errorHandler">
<route id="NOSIngestRoute">
<from uri="jms-durable:queue:Ingest.NOS" />
<doTry>
<pipeline>
<bean ref="stringToFile" />
<choice>
<when>
<simple>${in.header.header} regex '^sst_geo-polar-blended.*'</simple>
<bean ref="pgblendedHdf4Decoder" method="decode" />
<to uri="direct-vm:persistIndexAlert" />
</when>
<otherwise>
<split streaming="true">
<method bean="ncomNetcdfDecoder" method="split"/>
<doTry>
<pipeline>
<bean ref="ncomNetcdfDecoder" method="decode" />
<to uri="direct-vm:persistIndexAlert" />
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="direct-vm:logFailedData" />
</doCatch>
</doTry>
</split>
</otherwise>
</choice>
</pipeline>
<doCatch>
<exception>java.lang.Throwable</exception>
<to uri="direct-vm:logFailedData" />
</doCatch>
</doTry>
</route>
</camelContext>
</beans>

View file

@ -1,219 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.ncom.netcdf;
import java.io.IOException;
import ucar.ma2.Array;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.dataplugin.level.LevelFactory;
import com.raytheon.uf.common.gridcoverage.Corner;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage;
import com.raytheon.uf.common.gridcoverage.exception.GridCoverageException;
import com.raytheon.uf.edex.netcdf.description.LevelDescription;
import com.raytheon.uf.edex.netcdf.description.VariableDescription;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
import com.raytheon.uf.edex.plugin.nos.netcdf.AbstractNosNetcdfDecoder;
import com.raytheon.uf.edex.plugin.nos.netcdf.NosRecordInfo;
/**
* Decoder for Navy Coastal Ocean Model (NCOM) data in netcdf files.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 27, 2015 4698 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public class NcomNetcdfDecoder extends AbstractNosNetcdfDecoder {
private static final String VALID_RANGE_ATTR = "valid_range";
/**
* Constructor.
*/
public NcomNetcdfDecoder(String descriptionFile) {
super(descriptionFile);
}
/**
* @param file
* @param descriptions
* @return
* @throws InvalidDescriptionException
*/
@Override
protected int getNumLevels(NetcdfFile file)
throws InvalidDescriptionException {
LevelDescription levelDesc = getDescriptions().getLevel();
VariableDescription levelOneDesc = (VariableDescription) levelDesc
.getLevelOneValue();
Variable levelVar = file.findVariable(levelOneDesc.getName());
if (levelVar == null) {
throw new InvalidDescriptionException(
"Cannot find required level variable "
+ levelOneDesc.getName());
}
int numLevels = levelVar.getDimension(0).getLength();
return numLevels;
}
/**
* @param recordInfo
* @param file
* @return
* @throws IOException
* @throws InvalidDescriptionException
*/
@Override
protected Level getLevel(NosRecordInfo recordInfo, NetcdfFile file)
throws IOException, InvalidDescriptionException {
LevelDescription levelDesc = getDescriptions().getLevel();
String levelOneName = ((VariableDescription) levelDesc
.getLevelOneValue()).getName();
Variable levelOneVar = file.findVariable(levelOneName);
if (levelOneVar == null) {
return null;
}
Array arr = levelOneVar.read();
double levelOneVal = arr.getDouble(recordInfo.getLevelIdx());
Level level = LevelFactory.getInstance().getLevel(
levelDesc.getMasterLevel().getString(file), levelOneVal);
return level;
}
/**
* Extracts the necessary values from the file and creates a GridCoverage.
*
* @param file
* The NetcdfFile.
* @throws GridCoverageException
* @throws IOException
*/
@Override
protected GridCoverage getCoverage(NetcdfFile file)
throws GridCoverageException, IOException {
Variable latVar = file.findVariable(LAT_VAR);
Variable lonVar = file.findVariable(LON_VAR);
if (latVar == null || lonVar == null) {
return null;
}
double[] latRange = getCoordRange(latVar);
double dy = Math.abs(latRange[1] - latRange[0]);
int ny = latVar.getDimension(0).getLength();
dy /= ny - 1;
double[] lonRange = getCoordRange(lonVar);
double dx = Math.abs(lonRange[1] - lonRange[0]);
int nx = lonVar.getDimension(0).getLength();
dx /= nx - 1;
Corner corner;
double laCenterOffset = dy * .5;
double loCenterOffset = dx * .5;
if (latRange[0] >= latRange[1]) {
laCenterOffset = -laCenterOffset;
if (lonRange[0] <= lonRange[1]) {
corner = Corner.UpperLeft;
} else {
corner = Corner.UpperRight;
loCenterOffset = -loCenterOffset;
}
} else {
if (lonRange[0] <= lonRange[1]) {
corner = Corner.LowerLeft;
} else {
corner = Corner.LowerRight;
loCenterOffset = -loCenterOffset;
}
}
double lo1 = lonRange[0];
if (lo1 > 180) {
lo1 -= 360;
} else if (lo1 < -180) {
lo1 += 360;
}
double lo2 = lonRange[1];
if (lo2 > 180) {
lo2 -= 360;
} else if (lo2 < -180) {
lo2 += 360;
}
LatLonGridCoverage location = new LatLonGridCoverage();
location.setDx(dx);
location.setDy(dy);
location.setNx(nx);
location.setNy(ny);
location.setLa1(latRange[0] + laCenterOffset);
location.setLo1(lo1 + loCenterOffset);
location.setLa2(latRange[1] + laCenterOffset);
location.setLo2(lo2 + loCenterOffset);
location.setFirstGridPointCorner(corner);
location.setSpacingUnit("degree");
location.initialize();
return location;
}
/**
* Returns the first and last values for a coordinate.
*
* @param coordVar
* The coordinate variable.
* @return The first and last values for a coordinate.
* @throws IOException
*/
private double[] getCoordRange(Variable coordVar) throws IOException {
Attribute validRangeAttr = coordVar.findAttribute(VALID_RANGE_ATTR);
double[] coordRange;
if (validRangeAttr == null) {
Array latArr = coordVar.read();
coordRange = new double[] { latArr.getDouble(0),
latArr.getDouble((int) (latArr.getSize() - 1)) };
} else {
coordRange = (double[]) validRangeAttr.getValues()
.copyTo1DJavaArray();
}
return coordRange;
}
}

View file

@ -1,116 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.nos.pgblended.hdf4;
import java.io.IOException;
import ucar.nc2.Attribute;
import ucar.nc2.NetcdfFile;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.dataplugin.level.LevelFactory;
import com.raytheon.uf.common.gridcoverage.Corner;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
import com.raytheon.uf.common.gridcoverage.LatLonGridCoverage;
import com.raytheon.uf.common.gridcoverage.exception.GridCoverageException;
import com.raytheon.uf.edex.netcdf.description.exception.InvalidDescriptionException;
import com.raytheon.uf.edex.plugin.nos.netcdf.AbstractNosNetcdfDecoder;
import com.raytheon.uf.edex.plugin.nos.netcdf.NosRecordInfo;
/**
* Decoder for POES/GOES Blended data in HDF4 files.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 19, 2015 4699 nabowle Initial creation
*
* </pre>
*
* @author nabowle
* @version 1.0
*/
public class PGBlendedHdf4Decoder extends AbstractNosNetcdfDecoder {
private static final String COLS_ATTR = "cols";
private static final String ROWS_ATTR = "rows";
/**
* Constructor.
*/
public PGBlendedHdf4Decoder(String descriptionFile) {
super(descriptionFile);
}
/**
* Extracts the necessary values from the file and creates a GridCoverage.
*
* @param file
* The NetcdfFile.
* @throws GridCoverageException
*/
@Override
protected GridCoverage getCoverage(NetcdfFile file) throws IOException,
GridCoverageException {
Attribute rowsAttr = file.findGlobalAttribute(ROWS_ATTR);
Attribute colsAttr = file.findGlobalAttribute(COLS_ATTR);
if (rowsAttr == null || colsAttr == null) {
return null;
}
int ny = (Integer) rowsAttr.getNumericValue();
int nx = (Integer) colsAttr.getNumericValue();
double dx = 360.0 / nx;
double dy = 180.0 / ny;
double la1 = 90 - .5 * dy;
double lo1 = -180 + .5 * dx;
LatLonGridCoverage location = new LatLonGridCoverage();
location.setDx(dx);
location.setDy(dy);
location.setNx(nx);
location.setNy(ny);
location.setLa1(la1);
location.setLo1(lo1);
location.setFirstGridPointCorner(Corner.UpperLeft);
location.setSpacingUnit("degree");
location.initialize();
return location;
}
@Override
protected Level getLevel(NosRecordInfo recordInfo, NetcdfFile file)
throws IOException, InvalidDescriptionException {
return getDescriptions().getLevel().getLevel(file,
LevelFactory.getInstance());
}
@Override
protected int getNumLevels(NetcdfFile file)
throws InvalidDescriptionException {
return 1;
}
}