You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/06/11 16:04:55 UTC
svn commit: r1798377 - in
/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis:
internal/netcdf/ internal/netcdf/impl/ internal/netcdf/ucar/ storage/netcdf/
Author: desruisseaux
Date: Sun Jun 11 16:04:55 2017
New Revision: 1798377
URL: http://svn.apache.org/viewvc?rev=1798377&view=rev
Log:
Mostly documentation clarification for remembering the relationship between "source" and "target" dimensions versus NetCDF "domain" and "range".
Modified:
sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java
sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridGeometry.java
sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfo.java
sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java
sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java?rev=1798377&r1=1798376&r2=1798377&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java [UTF-8] Sun Jun 11 16:04:55 2017
@@ -27,7 +27,7 @@ import org.apache.sis.storage.netcdf.Att
* {@link ucar.nc2.dataset.CoordinateAxis1D} or {@link ucar.nc2.dataset.CoordinateAxis2D} respectively.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
*
* @see GridGeometry#getAxes()
*
@@ -41,14 +41,13 @@ public final class Axis {
public final AttributeNames.Dimension attributeNames;
/**
- * The indices of the grid dimension associated to this axis. Values in this array are sorted with more
- * "significant" (defined below) dimensions first - this is not necessarily increasing order.
- *
- * <div class="section">Elements order</div>
- * The length of this array is often 1. But if more than one grid dimension is associated to this axis
- * (i.e. if the wrapped NetCDF axis is an instance of {@link ucar.nc2.dataset.CoordinateAxis2D}), then
- * the first index is what seems the most significant grid dimension (i.e. the dimension which seems
- * to be varying fastest along this axis).
+ * The indices of the grid dimension associated to this axis. The length of this array is often 1.
+ * But if more than one grid dimension is associated to this axis (i.e. if the wrapped NetCDF axis
+ * is an instance of {@link ucar.nc2.dataset.CoordinateAxis2D}), then the first value is the grid
+ * dimension which seems most closely oriented toward this axis direction. We do that for allowing
+ * {@code MetadataReader.addSpatialRepresentationInfo(…)} method to get the most appropriate value
+ * for ISO 19115 {@code metadata/spatialRepresentationInfo/axisDimensionProperties/dimensionSize}
+ * metadata property.
*/
public final int[] sourceDimensions;
@@ -61,15 +60,17 @@ public final class Axis {
/**
* Constructs a new axis associated to an arbitrary number of grid dimension.
- * In the particular case where the number of dimensions is equals to 2, this
- * constructor will detects by itself which grid dimension varies fastest.
+ * In the particular case where the number of dimensions is equals to 2, this constructor will detect
+ * by itself which grid dimension varies fastest and reorder in-place the elements in the given arrays
+ * (those array are modified, not cloned).
*
* @param owner provides callback for the conversion from grid coordinates to geodetic coordinates.
+ * @param axis an implementation-dependent object representing the two-dimensional axis, or {@code null} if none.
* @param attributeNames the attributes to use for fetching dimension information, or {@code null} if unknown.
* @param sourceDimensions the index of the grid dimension associated to this axis.
* @param sourceSizes the number of cell elements along that axis.
*/
- public Axis(final GridGeometry owner, final AttributeNames.Dimension attributeNames,
+ public Axis(final GridGeometry owner, final Object axis, final AttributeNames.Dimension attributeNames,
final int[] sourceDimensions, final int[] sourceSizes)
{
this.attributeNames = attributeNames;
@@ -80,9 +81,11 @@ public final class Axis {
final int up1 = sourceSizes[1];
final int mid0 = up0 / 2;
final int mid1 = up1 / 2;
- final double d1 = (owner.coordinateForCurrentAxis(0, mid1) - owner.coordinateForCurrentAxis(up0-1, mid1)) / up0;
- final double d2 = (owner.coordinateForCurrentAxis(mid0, 0) - owner.coordinateForCurrentAxis(mid0, up1-1)) / up1;
- if (Math.abs(d2) > Math.abs(d1)) {
+ final double inc0 = (owner.coordinateForAxis(axis, 0, mid1) -
+ owner.coordinateForAxis(axis, up0-1, mid1)) / up0;
+ final double inc1 = (owner.coordinateForAxis(axis, mid0, 0) -
+ owner.coordinateForAxis(axis, mid0, up1-1)) / up1;
+ if (Math.abs(inc1) > Math.abs(inc0)) {
sourceSizes[0] = up1;
sourceSizes[1] = up0;
ArraysExt.swap(sourceDimensions, 0, 1);
Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridGeometry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridGeometry.java?rev=1798377&r1=1798376&r2=1798377&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridGeometry.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/GridGeometry.java [UTF-8] Sun Jun 11 16:04:55 2017
@@ -21,7 +21,7 @@ package org.apache.sis.internal.netcdf;
* Information about the grid geometry and the conversion from grid coordinates to geodetic coordinates.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
* @since 0.3
* @module
*/
@@ -33,38 +33,41 @@ public abstract class GridGeometry {
}
/**
- * Returns the number of dimensions in the grid.
- * This is the number of dimensions of source coordinates in the <cite>"grid to CRS"</cite> transform.
+ * Returns the number of dimensions of source coordinates in the <cite>"grid to CRS"</cite> conversion.
+ * This is the number of dimensions of the <em>grid</em>.
*
* @return number of grid dimensions.
*/
public abstract int getSourceDimensions();
/**
- * Returns the number of dimensions in the coordinate reference system.
- * This is the number of dimensions of target coordinates in the <cite>"grid to CRS"</cite> transform.
- * It should also be equal to the size of the list returned by {@link #getAxes()}.
+ * Returns the number of dimensions of target coordinates in the <cite>"grid to CRS"</cite> conversion.
+ * This is the number of dimensions of the <em>coordinate reference system</em>.
+ * It should be equal to the size of the array returned by {@link #getAxes()},
+ * but caller should be robust to inconsistencies.
*
* @return number of CRS dimensions.
*/
public abstract int getTargetDimensions();
/**
- * Returns the axes of the coordinate reference system. The size of this list is expected equals to the
- * value returned by {@link #getTargetDimensions()}, however the caller should be robust to inconsistencies.
+ * Returns the axes of the coordinate reference system. The size of this array is expected equals to the
+ * value returned by {@link #getTargetDimensions()}, but the caller should be robust to inconsistencies.
+ * This array may not be a clone, so callers shall not modify it.
*
* @return the CRS axes, in NetCDF order (reverse of "natural" order).
*/
public abstract Axis[] getAxes();
/**
- * Returns the coordinate for the given grid coordinate of an axis in the process of being constructed.
- * This is a callback method for {@link #getAxes()}. In the NetCDF UCAR API, this method maps directly
+ * Returns a coordinate for the given two-dimensional grid coordinate axis. This is (indirectly)
+ * a callback method for {@link #getAxes()}. In the NetCDF UCAR API, this method maps directly
* to {@link ucar.nc2.dataset.CoordinateAxis2D#getCoordValue(int, int)}.
*
- * @param j the fastest varying (right-most) index.
- * @param i the slowest varying (left-most) index.
+ * @param axis an implementation-dependent object representing the two-dimensional axis, or {@code null} if none.
+ * @param j the fastest varying (right-most) index.
+ * @param i the slowest varying (left-most) index.
* @return the coordinate at the given index, or {@link Double#NaN} if it can not be computed.
*/
- protected abstract double coordinateForCurrentAxis(final int j, final int i);
+ protected abstract double coordinateForAxis(Object axis, int j, int i);
}
Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfo.java?rev=1798377&r1=1798376&r2=1798377&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfo.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfo.java [UTF-8] Sun Jun 11 16:04:55 2017
@@ -29,7 +29,7 @@ import org.apache.sis.storage.netcdf.Att
* (domain) and output (range) of the function that convert grid indices to geodetic coordinates.</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
* @since 0.3
* @module
*/
@@ -82,6 +82,8 @@ final class GridGeometryInfo extends Gri
/**
* Returns the number of dimensions of target coordinates in the <cite>"grid to CRS"</cite> conversion.
* This is the number of dimensions of the <em>coordinate reference system</em>.
+ * It should be equal to the size of the array returned by {@link #getAxes()},
+ * but caller should be robust to inconsistencies.
*/
@Override
public int getTargetDimensions() {
@@ -90,16 +92,32 @@ final class GridGeometryInfo extends Gri
/**
* 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 more
- * information on the algorithm applied here, and relationship with the UCAR library.
+ * 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).
*/
@Override
public Axis[] getAxes() {
+ /*
+ * 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.length;
final Axis[] axes = new Axis[targetDim];
while (--targetDim >= 0) {
final VariableInfo axis = range[targetDim];
- final Dimension[] axisDomain = axis.dimensions;
+ /*
+ * 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) {
@@ -110,7 +128,13 @@ final class GridGeometryInfo extends Gri
}
}
}
+ /*
+ * 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) {
@@ -122,15 +146,15 @@ final class GridGeometryInfo extends Gri
}
}
}
- axes[targetDim] = new Axis(this, attributeNames,
- ArraysExt.resize(indices, i),
- ArraysExt.resize(sizes, i));
+ axes[targetDim] = new Axis(this, null, attributeNames,
+ ArraysExt.resize(indices, i),
+ ArraysExt.resize(sizes, i));
}
return axes;
}
@Override
- protected double coordinateForCurrentAxis(final int j, final int i) {
+ protected double coordinateForAxis(final Object axis, final int j, final int i) {
throw new UnsupportedOperationException();
}
}
Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java?rev=1798377&r1=1798376&r2=1798377&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridGeometryWrapper.java [UTF-8] Sun Jun 11 16:04:55 2017
@@ -35,7 +35,7 @@ import org.apache.sis.util.ArraysExt;
* of the grid geometry information.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
* @since 0.3
* @module
*/
@@ -46,11 +46,6 @@ final class GridGeometryWrapper extends
private final CoordinateSystem netcdfCS;
/**
- * A temporary variable for {@link #coordinateForCurrentAxis(int, int)}.
- */
- private transient CoordinateAxis2D axis2D;
-
- /**
* Creates a new grid geometry for the given NetCDF coordinate system.
*
* @param cs the NetCDF coordinate system, or {@code null} if none.
@@ -60,7 +55,8 @@ final class GridGeometryWrapper extends
}
/**
- * Returns the number of dimensions in the grid.
+ * Returns the number of dimensions of source coordinates in the <cite>"grid to CRS"</cite> conversion.
+ * This is the number of dimensions of the <em>grid</em>.
*/
@Override
public int getSourceDimensions() {
@@ -68,7 +64,10 @@ final class GridGeometryWrapper extends
}
/**
- * Returns the number of dimensions in the coordinate reference system.
+ * Returns the number of dimensions of target coordinates in the <cite>"grid to CRS"</cite> conversion.
+ * This is the number of dimensions of the <em>coordinate reference system</em>.
+ * It should be equal to the size of the array returned by {@link #getAxes()},
+ * but caller should be robust to inconsistencies.
*/
@Override
public int getTargetDimensions() {
@@ -86,20 +85,25 @@ final class GridGeometryWrapper extends
* 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).
*/
@Override
public Axis[] getAxes() {
final List<Dimension> domain = netcdfCS.getDomain();
final List<CoordinateAxis> range = netcdfCS.getCoordinateAxes();
- int targetDim = range.size();
- final Axis[] axes = new Axis[targetDim];
/*
- * NetCDF files declare axes in reverse order, so we iterate in the 'netcdfAxes'
- * list in reverse order for adding to the 'axes' list in "natural" order.
+ * 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);
- final List<Dimension> axisDomain = axis.getDimensions();
+ 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) {
@@ -116,6 +120,7 @@ final class GridGeometryWrapper extends
* 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) {
@@ -127,24 +132,22 @@ final class GridGeometryWrapper extends
/*
* 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.
+ * package, we can proceed as if the dimension does not exist ('i' not incremented).
*/
}
- axis2D = (axis instanceof CoordinateAxis2D) ? (CoordinateAxis2D) axis : null;
- axes[targetDim] = new Axis(this, attributeNames,
- ArraysExt.resize(indices, i),
- ArraysExt.resize(sizes, i));
+ axes[targetDim] = new Axis(this, axis, attributeNames,
+ ArraysExt.resize(indices, i),
+ ArraysExt.resize(sizes, i));
}
- axis2D = null;
return axes;
}
/**
- * Returns the coordinate for the given grid coordinate of an axis in the process of being constructed.
+ * Returns a coordinate for the given two-dimensional grid coordinate axis.
* This is a callback method for {@link #getAxes()}.
*/
@Override
- protected double coordinateForCurrentAxis(final int j, final int i) {
- return (axis2D != null) ? axis2D.getCoordValue(j, i) : Double.NaN;
+ protected double coordinateForAxis(final Object axis, final int j, final int i) {
+ return (axis instanceof CoordinateAxis2D) ? ((CoordinateAxis2D) axis).getCoordValue(j, i) : Double.NaN;
}
}
Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java?rev=1798377&r1=1798376&r2=1798377&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java [UTF-8] Sun Jun 11 16:04:55 2017
@@ -634,7 +634,13 @@ split: while ((start = CharSequences.sk
for (int i=axes.length; i>0;) {
final int dim = axes.length - i;
final Axis axis = axes[--i];
- if (axis.sourceSizes.length == 1) {
+ /*
+ * 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;