Search in sources :

Example 1 with InternalDataStoreException

use of org.apache.sis.storage.InternalDataStoreException in project sis by apache.

the class Variable method getGridGeometry.

/**
 * Returns the grid geometry for this variable, or {@code null} if this variable is not a data cube.
 * Not all variables have a grid geometry. For example collections of features do not have such grid.
 * The same grid geometry may be shared by many variables.
 * The grid may have fewer {@linkplain Grid#getDimensions() dimensions} than this variable,
 * in which case the additional {@linkplain #getGridDimensions() variable dimensions} can be considered as bands.
 *
 * @return the grid geometry for this variable, or {@code null} if none.
 * @throws IOException if an error occurred while reading the data.
 * @throws DataStoreException if a logical error occurred.
 */
public final GridGeometry getGridGeometry() throws IOException, DataStoreException {
    if (!gridDetermined) {
        // Set first so we don't try twice in case of failure.
        gridDetermined = true;
        final GridMapping gridMapping = GridMapping.forVariable(this);
        final GridAdjustment adjustment = new GridAdjustment();
        final Grid info = getGrid(adjustment);
        if (info != null) {
            /*
                 * This variable may have more dimensions than the grid. We need to reduce the list to the same
                 * dimensions than the ones in the grid.  We can not take Grid.getDimensions() directly because
                 * those dimensions may not have the same length (this mismatch is handled in the next block).
                 */
            // In netCDF order.
            List<Dimension> dimensions = getGridDimensions();
            final int dataDimension = dimensions.size();
            if (dataDimension > info.getSourceDimensions()) {
                boolean copied = false;
                // Also in netCDF order.
                final List<Dimension> toKeep = info.getDimensions();
                final int numToKeep = toKeep.size();
                for (int i = 0; i < numToKeep; i++) {
                    Dimension expected = toKeep.get(i);
                    expected = adjustment.gridToVariable.getOrDefault(expected, expected);
                    /*
                         * At this point, `expected` is a dimension of the variable that we expect to find at
                         * current index `i`. If we do not find that dimension, then the unexpected dimension
                         * is assumed to be a band. We usually remove at most one element. If removal results
                         * in a list too short, it would be a bug in the way we computed `toKeep`.
                         */
                    while (!expected.equals(dimensions.get(i))) {
                        if (!copied) {
                            copied = true;
                            dimensions = new ArrayList<>(dimensions);
                        }
                        /*
                             * It is possible that we never reach this point if the unexpected dimension is last.
                             * However in such case the dimension to declare is the last one in netCDF order,
                             * which corresponds to the first dimension (i.e. dimension 0) in "natural" order.
                             * Since the `bandDimension` field is initialized to zero, its value is correct.
                             */
                        // Convert netCDF order to "natural" order.
                        bandDimension = dataDimension - 1 - i;
                        dimensions.remove(i);
                        for (int j = dimensions.size(); --j >= i; ) {
                            dimensions.set(j, dimensions.get(j).decrementIndex());
                        }
                        if (dimensions.size() < numToKeep) {
                            // Should not happen (see above comment).
                            throw new InternalDataStoreException();
                        }
                    }
                }
            /*
                     * At this point `dimensions` may still be longer than `toKeep` but it does not matter.
                     * We only need that for any index i < numToKeep, dimensions.get(i) corresponds to the
                     * dimension at the same index in the grid.
                     */
            }
            /*
                 * Compare the size of the variable with the size of the localization grid.
                 * If they do not match, then there is a scale factor between the two that
                 * needs to be applied.
                 */
            GridGeometry grid = info.getGridGeometry(decoder);
            if (grid != null) {
                if (grid.isDefined(GridGeometry.EXTENT)) {
                    GridExtent extent = grid.getExtent();
                    final long[] sizes = new long[extent.getDimension()];
                    boolean needsResize = false;
                    for (int i = sizes.length; --i >= 0; ) {
                        // Convert "natural order" index into netCDF index.
                        final int d = (sizes.length - 1) - i;
                        sizes[i] = dimensions.get(d).length();
                        if (!needsResize) {
                            needsResize = (sizes[i] != extent.getSize(i));
                        }
                    }
                    if (needsResize) {
                        final double[] dataToGridIndices = adjustment.dataToGridIndices();
                        if (dataToGridIndices == null || dataToGridIndices.length < sizes.length) {
                            warning(Variable.class, "getGridGeometry", Resources.Keys.ResamplingIntervalNotFound_2, getFilename(), getName());
                            return null;
                        }
                        extent = extent.resize(sizes);
                        grid = GridAdjustment.scale(grid, extent, info.getAnchor(), dataToGridIndices);
                    }
                }
                /*
                     * At this point we finished to build a grid geometry from the information provided by axes.
                     * If there is grid mapping attributes (e.g. "EPSG_code", "ESRI_pe_string", "GeoTransform",
                     * "spatial_ref", etc.), substitute some parts of the grid geometry by the parts built from
                     * those attributes.
                     */
                if (gridMapping != null) {
                    grid = gridMapping.adaptGridCRS(this, grid, info.getAnchor());
                }
            }
            gridGeometry = grid;
        } else if (gridMapping != null) {
            gridGeometry = gridMapping.createGridCRS(this);
        }
    }
    return gridGeometry;
}
Also used : InternalDataStoreException(org.apache.sis.storage.InternalDataStoreException) GridGeometry(org.apache.sis.coverage.grid.GridGeometry) GridExtent(org.apache.sis.coverage.grid.GridExtent)

Example 2 with InternalDataStoreException

use of org.apache.sis.storage.InternalDataStoreException in project sis by apache.

the class NetcdfStoreProvider method createByReflection.

/**
 * Creates a new netCDF decoder as a wrapper around the UCAR library. This decoder is used only when we can
 * not create our embedded netCDF decoder. This method uses reflection for creating the wrapper, in order
 * to keep the UCAR dependency optional.
 *
 * @param  input      the netCDF file object of filename string from which to read data.
 * @param  isUCAR     {@code true} if {@code input} is an instance of the UCAR {@link ucar.nc2.NetcdfFile} object,
 *                    or {@code false} if it is the filename as a {@code String}.
 * @param  geomlib    the library for geometric objects, or {@code null} for the default.
 * @param  listeners  where to send the warnings.
 * @return the {@link DecoderWrapper} instance for the given input, or {@code null} if the input type is not recognized.
 * @throws IOException if an error occurred while opening the netCDF file.
 * @throws DataStoreException if a logical error (other than I/O) occurred.
 */
private static Decoder createByReflection(final Object input, final boolean isUCAR, final GeometryLibrary geomlib, final StoreListeners listeners) throws IOException, DataStoreException {
    ensureInitialized(true);
    /*
         * Get the appropriate constructor for the isUCAR argument. This constructor will be null
         * if the above code failed to load the UCAR library. Otherwise, instantiate the wrapper.
         */
    final Constructor<? extends Decoder> constructor;
    final Class<?> expectedType;
    if (isUCAR) {
        constructor = createFromUCAR;
        expectedType = netcdfFileClass;
    } else {
        constructor = createFromPath;
        expectedType = String.class;
    }
    if (constructor == null || !expectedType.isInstance(input)) {
        return null;
    }
    try {
        return constructor.newInstance(input, geomlib, listeners);
    } catch (InvocationTargetException e) {
        final Throwable cause = e.getCause();
        if (cause instanceof IOException)
            throw (IOException) cause;
        if (cause instanceof DataStoreException)
            throw (DataStoreException) cause;
        if (cause instanceof RuntimeException)
            throw (RuntimeException) cause;
        if (cause instanceof Error)
            throw (Error) cause;
        // Should never happen actually.
        throw new UndeclaredThrowableException(cause);
    } catch (ReflectiveOperationException e) {
        // Should never happen (shall be verified by the JUnit tests).
        throw new InternalDataStoreException(e);
    }
}
Also used : InternalDataStoreException(org.apache.sis.storage.InternalDataStoreException) DataStoreException(org.apache.sis.storage.DataStoreException) InternalDataStoreException(org.apache.sis.storage.InternalDataStoreException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 3 with InternalDataStoreException

use of org.apache.sis.storage.InternalDataStoreException in project sis by apache.

the class Table method setDeferredSearchTables.

/**
 * Sets the search tables on all {@link Relation} instances for which this operation has been deferred.
 * This happen when a table could not be obtained because of circular dependency.
 * This method is invoked after all tables have been created in order to fill such holes.
 *
 * @param  tables  all tables created.
 */
final void setDeferredSearchTables(final Analyzer analyzer, final Map<GenericName, Table> tables) throws DataStoreException {
    for (final Relation.Direction direction : Relation.Direction.values()) {
        final Relation[] relations;
        switch(direction) {
            case IMPORT:
                relations = importedKeys;
                break;
            case EXPORT:
                relations = exportedKeys;
                break;
            default:
                continue;
        }
        for (final Relation relation : relations) {
            if (relation.isSearchTableDeferred()) {
                /*
                     * `ClassCastException` should never occur below because `relation.propertyName` fields
                     * have been set to association names. If `ClassCastException` occurs here, it is a bug
                     * in our object constructions.
                     */
                final DefaultAssociationRole association = (DefaultAssociationRole) featureType.getProperty(relation.propertyName);
                final Table table = tables.get(association.getValueType().getName());
                if (table == null) {
                    throw new InternalDataStoreException(association.toString());
                }
                final PrimaryKey referenced;
                switch(direction) {
                    case IMPORT:
                        referenced = table.primaryKey;
                        break;
                    case EXPORT:
                        referenced = this.primaryKey;
                        break;
                    default:
                        throw new AssertionError(direction);
                }
                if (referenced != null) {
                    relation.setSearchTable(analyzer, table, referenced, direction);
                }
            }
        }
    }
}
Also used : InternalDataStoreException(org.apache.sis.storage.InternalDataStoreException) DefaultAssociationRole(org.apache.sis.feature.DefaultAssociationRole) TreeTable(org.apache.sis.util.collection.TreeTable)

Aggregations

InternalDataStoreException (org.apache.sis.storage.InternalDataStoreException)3 IOException (java.io.IOException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)1 GridExtent (org.apache.sis.coverage.grid.GridExtent)1 GridGeometry (org.apache.sis.coverage.grid.GridGeometry)1 DefaultAssociationRole (org.apache.sis.feature.DefaultAssociationRole)1 DataStoreException (org.apache.sis.storage.DataStoreException)1 TreeTable (org.apache.sis.util.collection.TreeTable)1