Search in sources :

Example 56 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class ReferencingFunctions method getIdentifiedObject.

/**
 * Gets the CRS or other kind of object from the given code.
 * If the code is a URN, then it can be any kind of object.
 * Otherwise a Coordinate Reference System is assumed.
 * This method caches the result.
 *
 * @param  codeOrPath  the code allocated by an authority, or the path to a file.
 * @param  type        how to interpret {@code codeOrPath}, or {@code null} for guessing.
 * @return the identified object for the given code.
 * @throws FactoryException if an error occurred while creating the object.
 * @throws DataStoreException if an error occurred while reading a data file.
 */
private IdentifiedObject getIdentifiedObject(final String codeOrPath, CodeType type) throws FactoryException, DataStoreException {
    final CacheKey<IdentifiedObject> key = new CacheKey<>(IdentifiedObject.class, codeOrPath, null, null);
    IdentifiedObject object = key.peek();
    if (object == null) {
        final Cache.Handler<IdentifiedObject> handler = key.lock();
        try {
            object = handler.peek();
            if (object == null) {
                if (type == null) {
                    type = CodeType.guess(codeOrPath);
                }
                if (type.equals(CodeType.URN)) {
                    object = CRS.getAuthorityFactory(null).createObject(codeOrPath);
                } else if (type.isCRS) {
                    object = CRS.forCode(codeOrPath);
                } else {
                    /*
                         * Apparently not an AUTHORITY:CODE string.
                         * Try to read a dataset from a file or URL, then get its CRS.
                         */
                    final Metadata metadata;
                    try (DataStore store = DataStores.open(codeOrPath)) {
                        metadata = store.getMetadata();
                    }
                    if (metadata != null) {
                        for (final ReferenceSystem rs : metadata.getReferenceSystemInfo()) {
                            if (rs instanceof CoordinateReferenceSystem) {
                                return rs;
                            } else if (object == null) {
                                // Will be used as a fallback if we find no CRS.
                                object = rs;
                            }
                        }
                    }
                    if (object == null) {
                        throw new FactoryException(Errors.getResources(getJavaLocale()).getString(Errors.Keys.UnspecifiedCRS));
                    }
                }
            }
        } finally {
            handler.putAndUnlock(object);
        }
    }
    return object;
}
Also used : FactoryException(org.opengis.util.FactoryException) DataStore(org.apache.sis.storage.DataStore) Metadata(org.opengis.metadata.Metadata) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) ReferenceSystem(org.opengis.referencing.ReferenceSystem) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) Cache(org.apache.sis.util.collection.Cache)

Example 57 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class CoordinateOperationFinder method createOperations.

/**
 * Infers operations for conversions or transformations between two coordinate reference systems.
 * If a non-null authority factory – the <cite>registry</cite> – has been specified at construction time,
 * then this method will first query that factory (<cite>late-binding</cite> approach – see class javadoc).
 * If no operation has been found in the registry or if no registry has been specified to the constructor,
 * this method inspects the given CRS and delegates the work to one or many {@code createOperationStep(…)}
 * methods (<cite>early-binding</cite> approach).
 *
 * <p>At first, this method is invoked with the {@code sourceCRS} and {@code targetCRS} arguments given to the
 * {@link DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem,
 * CoordinateOperationContext) CoordinateOperationFactory.createOperation(…)} method. But then, this method may
 * be invoked recursively by some {@code createOperationStep(…)} methods with different source or target CRS,
 * for example in order to process the {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS#getBaseCRS()
 * base geographic CRS} of a projected CRS.</p>
 *
 * <p>Coordinate operations are returned in preference order: best operations for the area of interest should be first.
 * The returned list is modifiable: callers can add, remove or set elements without impact on this
 * {@code CoordinateOperationFinder} instance.</p>
 *
 * @param  sourceCRS  input coordinate reference system.
 * @param  targetCRS  output coordinate reference system.
 * @return coordinate operations from {@code sourceCRS} to {@code targetCRS}.
 * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
 * @throws FactoryException if the operation creation failed for some other reason.
 *
 * @since 1.0
 */
@Override
public List<CoordinateOperation> createOperations(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws FactoryException {
    ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
    ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    if (equalsIgnoreMetadata(sourceCRS, targetCRS))
        try {
            return asList(createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(), targetCRS.getCoordinateSystem())));
        } catch (IllegalArgumentException | IncommensurableException e) {
            throw new FactoryException(Resources.format(Resources.Keys.CanNotInstantiateGeodeticObject_1, new CRSPair(sourceCRS, targetCRS)), e);
        }
    /*
         * If this method is invoked recursively, verify if the requested operation is already in the cache.
         * We do not perform this verification on the first invocation because it was already verified by
         * DefaultCoordinateOperationFactory.createOperation(…). We do not block if the operation is in
         * process of being computed in another thread because of the risk of deadlock. If the operation
         * is not in the cache, store the key in our internal map for preventing infinite recursivity.
         */
    final CRSPair key = new CRSPair(sourceCRS, targetCRS);
    if (useCache && stopAtFirst && !previousSearches.isEmpty()) {
        final CoordinateOperation op = factorySIS.cache.peek(key);
        // Must be a modifiable list as per this method contract.
        if (op != null)
            return asList(op);
    }
    if (previousSearches.put(key, Boolean.TRUE) != null) {
        throw new FactoryException(Resources.format(Resources.Keys.RecursiveCreateCallForCode_2, CoordinateOperation.class, key));
    }
    /*
         * If the user did not specified an area of interest, use the domain of validity of the CRS.
         */
    GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(areaOfInterest);
    if (bbox == null) {
        bbox = Extents.intersection(CRS.getGeographicBoundingBox(sourceCRS), CRS.getGeographicBoundingBox(targetCRS));
        areaOfInterest = CoordinateOperationContext.setGeographicBoundingBox(areaOfInterest, bbox);
    }
    /*
         * Verify if some extension module handles this pair of CRS in a special way. For example it may
         * be the "sis-gdal" module checking if the given CRS are wrappers around Proj.4 data structure.
         */
    {
        // For keeping 'operations' list locale.
        final List<CoordinateOperation> operations = new ArrayList<>();
        for (final SpecializedOperationFactory sp : factorySIS.getSpecializedFactories()) {
            for (final CoordinateOperation op : sp.findOperations(sourceCRS, targetCRS)) {
                if (filter(op)) {
                    operations.add(op);
                }
            }
        }
        if (!operations.isEmpty()) {
            CoordinateOperationSorter.sort(operations, bbox);
            return operations;
        }
    }
    /*
         * Verify in the EPSG dataset if the operation is explicitely defined by an authority.
         */
    if (registry != null) {
        final List<CoordinateOperation> authoritatives = super.createOperations(sourceCRS, targetCRS);
        if (!authoritatives.isEmpty())
            return authoritatives;
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (sourceCRS instanceof GeneralDerivedCRS) {
        final GeneralDerivedCRS source = (GeneralDerivedCRS) sourceCRS;
        if (targetCRS instanceof GeneralDerivedCRS) {
            return createOperationStep(source, (GeneralDerivedCRS) targetCRS);
        }
        if (targetCRS instanceof SingleCRS) {
            return createOperationStep(source, (SingleCRS) targetCRS);
        }
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (targetCRS instanceof GeneralDerivedCRS) {
        final GeneralDerivedCRS target = (GeneralDerivedCRS) targetCRS;
        if (sourceCRS instanceof SingleCRS) {
            return createOperationStep((SingleCRS) sourceCRS, target);
        }
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (sourceCRS instanceof GeodeticCRS) {
        final GeodeticCRS source = (GeodeticCRS) sourceCRS;
        if (targetCRS instanceof GeodeticCRS) {
            return createOperationStep(source, (GeodeticCRS) targetCRS);
        }
        if (targetCRS instanceof VerticalCRS) {
            return createOperationStep(source, (VerticalCRS) targetCRS);
        }
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (sourceCRS instanceof VerticalCRS) {
        final VerticalCRS source = (VerticalCRS) sourceCRS;
        if (targetCRS instanceof VerticalCRS) {
            return createOperationStep(source, (VerticalCRS) targetCRS);
        }
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (sourceCRS instanceof TemporalCRS) {
        final TemporalCRS source = (TemporalCRS) sourceCRS;
        if (targetCRS instanceof TemporalCRS) {
            return createOperationStep(source, (TemporalCRS) targetCRS);
        }
    }
    // //////////////////////////////////////////////////////////////////////////////
    if (sourceCRS instanceof CompoundCRS || targetCRS instanceof CompoundCRS) {
        return createOperationStep(sourceCRS, CRS.getSingleComponents(sourceCRS), targetCRS, CRS.getSingleComponents(targetCRS));
    }
    throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS));
}
Also used : FactoryException(org.opengis.util.FactoryException) SpecializedOperationFactory(org.apache.sis.internal.referencing.SpecializedOperationFactory) GeographicBoundingBox(org.opengis.metadata.extent.GeographicBoundingBox) ArrayList(java.util.ArrayList) List(java.util.List)

Example 58 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class CoordinateOperationRegistry method createOperations.

/**
 * Finds or infers operations for conversions or transformations between two coordinate reference systems.
 * {@code CoordinateOperationRegistry} implements the <cite>late-binding</cite> approach (see definition
 * of terms in class javadoc) by extracting the authority codes from the supplied {@code sourceCRS} and
 * {@code targetCRS}, then by submitting those codes to the
 * <code>{@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
 * createFromCoordinateReferenceSystemCodes}(sourceCode, targetCode)</code> method.
 *
 * <p>Operations in the returned list are ordered in preference order (preferred operation first).
 * If no operation is found for those codes, then this method returns an empty list.
 * Note that it does not mean that no path exist;
 * it only means that it was not defined explicitely in the registry.</p>
 *
 * @param  sourceCRS  input coordinate reference system.
 * @param  targetCRS  output coordinate reference system.
 * @return coordinate operations from {@code sourceCRS} to {@code targetCRS},
 *         or an empty list if no such operation is explicitly defined in the underlying database.
 * @throws FactoryException if the operation creation failed.
 */
public List<CoordinateOperation> createOperations(final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws FactoryException {
    CoordinateReferenceSystem source = sourceCRS;
    CoordinateReferenceSystem target = targetCRS;
    for (int combine = 0; ; combine++) {
        /*
             * First, try directly the provided (sourceCRS, targetCRS) pair. If that pair does not work,
             * try to use different combinations of user-provided CRS and two-dimensional components of
             * those CRS. The code below assumes that the user-provided CRS are three-dimensional, but
             * actually it works for other kind of CRS too without testing twice the same combinations.
             */
        switch(combine) {
            // 3D → 3D
            case 0:
                break;
            case // 3D → 2D
            1:
                // 3D → 2D
                target = CRS.getHorizontalComponent(targetCRS);
                if (target == targetCRS)
                    continue;
                break;
            case // 2D → 2D
            2:
                // 2D → 2D
                source = CRS.getHorizontalComponent(sourceCRS);
                if (source == sourceCRS)
                    continue;
                break;
            case 3:
                if (source == sourceCRS || target == targetCRS)
                    continue;
                // 2D → 3D
                target = targetCRS;
                break;
            default:
                return Collections.emptyList();
        }
        if (source != null && target != null)
            try {
                final List<CoordinateOperation> operations = search(source, target);
                if (operations != null) {
                    /*
                     * Found an operation. If we had to extract the horizontal part of some 3D CRS, then we
                     * need to modify the coordinate operation in order to match the new number of dimensions.
                     */
                    if (combine != 0) {
                        for (int i = operations.size(); --i >= 0; ) {
                            CoordinateOperation operation = operations.get(i);
                            operation = propagateVertical(sourceCRS, source != sourceCRS, targetCRS, target != targetCRS, operation);
                            if (operation != null) {
                                operation = complete(operation, sourceCRS, targetCRS);
                                operations.set(i, operation);
                            } else {
                                operations.remove(i);
                            }
                        }
                    }
                    if (!operations.isEmpty()) {
                        return operations;
                    }
                }
            } catch (IllegalArgumentException | IncommensurableException e) {
                String message = Resources.format(Resources.Keys.CanNotInstantiateGeodeticObject_1, new CRSPair(sourceCRS, targetCRS));
                String details = e.getLocalizedMessage();
                if (details != null) {
                    message = message + ' ' + details;
                }
                throw new FactoryException(message, e);
            }
    }
}
Also used : FactoryException(org.opengis.util.FactoryException) NoSuchAuthorityFactoryException(org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException) List(java.util.List) ArrayList(java.util.ArrayList) DeferredCoordinateOperation(org.apache.sis.internal.referencing.DeferredCoordinateOperation) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 59 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class EPSGFactory method newDataAccess.

/**
 * Creates the factory which will perform the actual geodetic object creation work.
 * This method is invoked automatically when a new worker is required, either because the previous
 * one has been disposed after its timeout or because a new one is required for concurrency.
 *
 * <p>The default implementation performs the following steps:</p>
 * <ol>
 *   <li>Gets a new connection from the {@link #dataSource}.</li>
 *   <li>If this method is invoked for the first time, verifies if the EPSG tables exists.
 *       If the tables are not found, invokes {@link #install(Connection)}.</li>
 *   <li>Delegates to {@link #newDataAccess(Connection, SQLTranslator)}, which provides an easier
 *       overriding point for subclasses wanting to return a custom {@link EPSGDataAccess} instance.</li>
 * </ol>
 *
 * @return Data Access Object (DAO) to use in {@code createFoo(String)} methods.
 * @throws FactoryException if the constructor failed to connect to the EPSG database.
 *         This exception usually has a {@link SQLException} as its cause.
 */
@Override
protected EPSGDataAccess newDataAccess() throws FactoryException {
    UnavailableFactoryException exception;
    Connection connection = null;
    try {
        connection = dataSource.getConnection();
        Logging.log(EPSGFactory.class, "newDataAccess", Initializer.connected(connection.getMetaData()));
        SQLTranslator tr = translator;
        if (tr == null) {
            synchronized (this) {
                tr = translator;
                if (tr == null) {
                    tr = new SQLTranslator(connection.getMetaData(), catalog, schema);
                    try {
                        if (!tr.isTableFound()) {
                            install(connection);
                            // Set only on success.
                            tr.setup(connection.getMetaData());
                        }
                    } finally {
                        // Set only after installation in order to block other threads.
                        translator = tr;
                    }
                }
            }
        }
        if (tr.isTableFound()) {
            return newDataAccess(connection, tr);
        } else {
            connection.close();
            exception = new UnavailableFactoryException(canNotUse(SQLTranslator.tableNotFound(locale)));
        }
    } catch (Exception e) {
        // Really want to catch all exceptions here.
        if (connection != null)
            try {
                connection.close();
            } catch (SQLException e2) {
                e.addSuppressed(e2);
            }
        if (e instanceof FactoryException) {
            throw (FactoryException) e;
        }
        /*
             * Derby sometime wraps SQLException into another SQLException.  For making the stack strace a
             * little bit simpler, keep only the root cause provided that the exception type is compatible.
             */
        exception = new UnavailableFactoryException(canNotUse(e), Exceptions.unwrap(e));
    }
    exception.setUnavailableFactory(this);
    throw exception;
}
Also used : SQLException(java.sql.SQLException) UnavailableFactoryException(org.apache.sis.referencing.factory.UnavailableFactoryException) FactoryException(org.opengis.util.FactoryException) Connection(java.sql.Connection) UnavailableFactoryException(org.apache.sis.referencing.factory.UnavailableFactoryException) UnavailableFactoryException(org.apache.sis.referencing.factory.UnavailableFactoryException) SQLException(java.sql.SQLException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) FactoryException(org.opengis.util.FactoryException)

Example 60 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class ConcurrentAuthorityFactory method getAuthority.

/**
 * Returns the database or specification that defines the codes recognized by this factory.
 * The default implementation performs the following steps:
 * <ul>
 *   <li>Returns the cached value if it exists.</li>
 *   <li>Otherwise:
 *     <ol>
 *       <li>get an instance of the Data Access Object,</li>
 *       <li>delegate to its {@link GeodeticAuthorityFactory#getAuthority()} method,</li>
 *       <li>release the Data Access Object,</li>
 *       <li>cache the result.</li>
 *     </ol>
 *   </li>
 * </ul>
 *
 * If this method can not get a Data Access Object (for example because no database connection is available),
 * then this method returns {@code null}.
 *
 * @return the organization responsible for definition of the database, or {@code null} if unavailable.
 */
@Override
public Citation getAuthority() {
    Citation c = authority;
    if (c == null || c == UNAVAILABLE)
        try {
            final DAO factory = getDataAccess();
            try {
                /*
                 * Cache only in case of success. If we failed, we
                 * will try again next time this method is invoked.
                 */
                authority = c = factory.getAuthority();
            } finally {
                release("getAuthority", Citation.class, null);
            }
        } catch (FactoryException e) {
            authority = UNAVAILABLE;
            /*
             * Use the warning level only on the first failure, then the fine level on all subsequent failures.
             * Do not log the stack trace if we failed because of UnavailableFactoryException since it may be
             * normal (the EPSG geodetic dataset is optional, even if strongly recommended).
             */
            final LogRecord record = new LogRecord(c == null ? Level.WARNING : Level.FINE, e.getLocalizedMessage());
            if (!(e instanceof UnavailableFactoryException)) {
                record.setThrown(e);
            }
            record.setLoggerName(Loggers.CRS_FACTORY);
            Logging.log(ConcurrentAuthorityFactory.class, "getAuthority", record);
            c = null;
        }
    return c;
}
Also used : FactoryException(org.opengis.util.FactoryException) LogRecord(java.util.logging.LogRecord) SimpleCitation(org.apache.sis.internal.simple.SimpleCitation) Citation(org.opengis.metadata.citation.Citation)

Aggregations

FactoryException (org.opengis.util.FactoryException)84 TransformException (org.opengis.referencing.operation.TransformException)27 GeometryWrapper (org.apache.jena.geosparql.implementation.GeometryWrapper)21 MismatchedDimensionException (org.opengis.geometry.MismatchedDimensionException)19 ExprEvalException (org.apache.jena.sparql.expr.ExprEvalException)17 MathTransform (org.opengis.referencing.operation.MathTransform)15 DatatypeFormatException (org.apache.jena.datatypes.DatatypeFormatException)12 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)10 IdentifiedObject (org.opengis.referencing.IdentifiedObject)8 Envelope (org.locationtech.jts.geom.Envelope)7 ArrayList (java.util.ArrayList)6 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)6 NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)6 Literal (org.apache.jena.rdf.model.Literal)5 UnavailableFactoryException (org.apache.sis.referencing.factory.UnavailableFactoryException)5 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)5 ParseException (java.text.ParseException)4 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)4 BackingStoreException (org.apache.sis.util.collection.BackingStoreException)4 Test (org.junit.Test)4