use of org.apache.sis.storage.netcdf.AttributeNames in project sis by apache.
the class GridGeometryWrapper method getAxes.
/**
* Returns all axes of the netCDF coordinate system, together with the grid dimension to which the axis
* is associated.
*
* <p>In this method, the words "domain" and "range" are used in the netCDF sense: they are the input
* (domain) and output (range) of the function that convert grid indices to geodetic coordinates.</p>
*
* <p>The domain of all axes (or the {@linkplain CoordinateSystem#getDomain() coordinate system domain})
* is often the same than the domain of the variable, but not necessarily.
* In particular, the relationship is not straightforward when the coordinate system contains instances
* of {@link CoordinateAxis2D}.</p>
*
* @return the CRS axes, in netCDF order (reverse of "natural" order).
* @throws IOException if an I/O operation was necessary but failed.
* @throws DataStoreException if a logical error occurred.
*/
@Override
public Axis[] getAxes() throws IOException, DataStoreException {
final List<Dimension> domain = netcdfCS.getDomain();
final List<CoordinateAxis> range = netcdfCS.getCoordinateAxes();
/*
* In this method, 'sourceDim' and 'targetDim' are relative to "grid to CRS" conversion.
* So 'sourceDim' is the grid (domain) dimension and 'targetDim' is the CRS (range) dimension.
*/
int targetDim = range.size();
final Axis[] axes = new Axis[targetDim];
while (--targetDim >= 0) {
final CoordinateAxis axis = range.get(targetDim);
/*
* The AttributeNames are for ISO 19115 metadata. They are not used for locating grid cells
* on Earth, but we nevertheless get them now for making MetadataReader work easier.
*/
AttributeNames.Dimension attributeNames = null;
final AxisType type = axis.getAxisType();
if (type != null)
switch(type) {
case Lon:
attributeNames = AttributeNames.LONGITUDE;
break;
case Lat:
attributeNames = AttributeNames.LATITUDE;
break;
// Fallthrough: consider as Height
case Pressure:
case Height:
attributeNames = AttributeNames.VERTICAL;
break;
// Fallthrough: consider as Time
case RunTime:
case Time:
attributeNames = AttributeNames.TIME;
break;
}
/*
* Get the grid dimensions (part of the "domain" in UCAR terminology) used for computing
* the ordinate values along the current axis. There is exactly 1 such grid dimension in
* straightforward netCDF files. However some more complex files may have 2 dimensions.
*/
int i = 0;
final List<Dimension> axisDomain = axis.getDimensions();
final int[] indices = new int[axisDomain.size()];
final int[] sizes = new int[indices.length];
for (final Dimension dimension : axisDomain) {
final int sourceDim = domain.lastIndexOf(dimension);
if (sourceDim >= 0) {
indices[i] = sourceDim;
sizes[i++] = dimension.getLength();
}
/*
* If the axis dimension has not been found in the coordinate system (sourceDim < 0),
* then there is maybe a problem with the netCDF file. However for the purpose of this
* package, we can proceed as if the dimension does not exist ('i' not incremented).
*/
}
axes[targetDim] = new Axis(this, axis, attributeNames, ArraysExt.resize(indices, i), ArraysExt.resize(sizes, i));
}
return axes;
}
use of org.apache.sis.storage.netcdf.AttributeNames in project sis by apache.
the class MetadataReader method addSpatialRepresentationInfo.
/**
* Adds information about axes and cell geometry.
* This is the {@code <gmd:spatialRepresentationInfo>} element in XML.
*
* @param cs the grid geometry (related to the netCDF coordinate system).
*/
private void addSpatialRepresentationInfo(final GridGeometry cs) throws IOException, DataStoreException {
final Axis[] axes = cs.getAxes();
for (int i = axes.length; i > 0; ) {
final int dim = axes.length - i;
final Axis axis = axes[--i];
/*
* Axes usually have exactly one dimension. However some netCDF axes are backed by a two-dimensional
* conversion grid. In such case, our Axis constructor should have ensured that the first element in
* the 'sourceDimensions' and 'sourceSizes' arrays are for the grid dimension which is most closely
* oriented toward the axis direction.
*/
if (axis.sourceSizes.length >= 1) {
setAxisLength(dim, axis.sourceSizes[0]);
}
final AttributeNames.Dimension attributeNames = axis.attributeNames;
if (attributeNames != null) {
setAxisName(dim, attributeNames.DEFAULT_NAME_TYPE);
final Number value = decoder.numericValue(attributeNames.RESOLUTION);
if (value != null) {
setAxisResolution(dim, value.doubleValue());
}
}
}
setCellGeometry(CellGeometry.AREA);
}
use of org.apache.sis.storage.netcdf.AttributeNames in project sis by apache.
the class GridGeometryInfo method getAxes.
/**
* Returns all axes of the netCDF coordinate system, together with the grid dimension to which the axis
* is associated. See {@code org.apache.sis.internal.netcdf.ucar.GridGeometryWrapper.getAxes()} for a
* closer look on the relationship between this algorithm and the UCAR library.
*
* <p>In this method, the words "domain" and "range" are used in the netCDF sense: they are the input
* (domain) and output (range) of the function that convert grid indices to geodetic coordinates.</p>
*
* <p>The domain of all axes is often the same than the domain of the variable, but not necessarily.
* In particular, the relationship is not straightforward when the coordinate system contains
* "two-dimensional axes" (in {@link ucar.nc2.dataset.CoordinateAxis2D} sense).</p>
*
* @return the CRS axes, in netCDF order (reverse of "natural" order).
* @throws IOException if an I/O operation was necessary but failed.
* @throws DataStoreException if a logical error occurred.
*/
@Override
public Axis[] getAxes() throws IOException, DataStoreException {
/*
* Process the variables in the order the appear in the sequence of bytes that make the netCDF files.
* This is often the same order than the indices, but not necessarily. The intent is to reduce the
* amount of disk seek operations.
*/
final SortedMap<VariableInfo, Integer> variables = new TreeMap<>();
for (int i = 0; i < range.length; i++) {
final VariableInfo v = range[i];
if (variables.put(v, i) != null) {
throw new DataStoreException(Errors.format(Errors.Keys.DuplicatedElement_1, v.getName()));
}
}
/*
* In this method, 'sourceDim' and 'targetDim' are relative to "grid to CRS" conversion.
* So 'sourceDim' is the grid (domain) dimension and 'targetDim' is the CRS (range) dimension.
*/
final Axis[] axes = new Axis[range.length];
for (final SortedMap.Entry<VariableInfo, Integer> entry : variables.entrySet()) {
final int targetDim = entry.getValue();
final VariableInfo axis = entry.getKey();
/*
* The AttributeNames are for ISO 19115 metadata. They are not used for locating grid cells
* on Earth, but we nevertheless get them now for making MetadataReader work easier.
*/
AttributeNames.Dimension attributeNames = null;
final String type = axis.getAxisType();
if (type != null) {
for (int i = 0; i < AXIS_TYPES.length; i += 2) {
if (type.equalsIgnoreCase((String) AXIS_TYPES[i])) {
attributeNames = (AttributeNames.Dimension) AXIS_TYPES[i + 1];
break;
}
}
}
/*
* Get the grid dimensions (part of the "domain" in UCAR terminology) used for computing
* the ordinate values along the current axis. There is exactly 1 such grid dimension in
* straightforward netCDF files. However some more complex files may have 2 dimensions.
*/
int i = 0;
final Dimension[] axisDomain = axis.dimensions;
final int[] indices = new int[axisDomain.length];
final int[] sizes = new int[axisDomain.length];
for (final Dimension dimension : axisDomain) {
for (int sourceDim = domain.length; --sourceDim >= 0; ) {
if (domain[sourceDim] == dimension) {
indices[i] = sourceDim;
sizes[i++] = dimension.length;
break;
}
}
}
axes[targetDim] = new Axis(this, axis, attributeNames, ArraysExt.resize(indices, i), ArraysExt.resize(sizes, i));
}
return axes;
}
Aggregations