Search in sources :

Example 6 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class IdentifiedObjectFinder method find.

/**
 * Lookups objects which are approximatively equal to the specified object.
 * The default implementation tries to instantiate some {@linkplain AbstractIdentifiedObject identified objects}
 * from the authority factory specified at construction time, in the following order:
 *
 * <ul>
 *   <li>If the specified object contains {@linkplain AbstractIdentifiedObject#getIdentifiers() identifiers}
 *       associated to the same authority than the factory, then those identifiers are used for
 *       {@linkplain GeodeticAuthorityFactory#createObject(String) creating objects} to be tested.</li>
 *   <li>If the authority factory can create objects from their {@linkplain AbstractIdentifiedObject#getName() name}
 *       in addition of identifiers, then the name and {@linkplain AbstractIdentifiedObject#getAlias() aliases} are
 *       used for creating objects to be tested.</li>
 *   <li>If a full scan of the dataset is allowed, then full {@linkplain #getCodeCandidates set of candidate codes}
 *       is used for creating objects to be tested.</li>
 * </ul>
 *
 * The created objects which are equal to the specified object in the
 * the sense of {@link ComparisonMode#APPROXIMATIVE} are returned.
 *
 * @param  object  the object looked up.
 * @return the identified objects, or an empty set if not found.
 * @throws FactoryException if an error occurred while creating an object.
 */
public Set<IdentifiedObject> find(final IdentifiedObject object) throws FactoryException {
    ArgumentChecks.ensureNonNull("object", object);
    Set<IdentifiedObject> result = getFromCache(object);
    if (result == null) {
        final AuthorityFactoryProxy<?> previous = proxy;
        proxy = AuthorityFactoryProxy.getInstance(object.getClass());
        try {
            if (!ignoreIdentifiers && !ignoreAxes) {
                /*
                     * First check if one of the identifiers can be used to find directly an identified object.
                     * Verify that the object that we found is actually equal to given one; we do not blindly
                     * trust the identifiers in the user object.
                     */
                IdentifiedObject candidate = createFromIdentifiers(object);
                if (candidate != null) {
                    // Not worth to cache.
                    return Collections.singleton(candidate);
                }
                /*
                     * We are unable to find the object from its identifiers. Try a quick name lookup.
                     * Some implementations like the one backed by the EPSG database are capable to find
                     * an object from its name.
                     */
                candidate = createFromNames(object);
                if (candidate != null) {
                    // Not worth to cache.
                    return Collections.singleton(candidate);
                }
            }
            /*
                 * Here we exhausted the quick paths.
                 * Perform a full scan (costly) if we are allowed to, otherwise abandon.
                 */
            if (domain == Domain.DECLARATION) {
                // Do NOT cache.
                return Collections.emptySet();
            }
            result = createFromCodes(object);
        } finally {
            proxy = previous;
        }
        // Costly operation (even if the result is empty) worth to cache.
        result = cache(object, result);
    }
    return result;
}
Also used : IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject)

Example 7 with AbstractIdentifiedObject

use of org.apache.sis.referencing.AbstractIdentifiedObject in project sis by apache.

the class DefaultCoordinateOperationFactory method createConcatenatedOperation.

/**
 * Creates an ordered sequence of two or more single coordinate operations.
 * The sequence of operations is constrained by the requirement that the source coordinate reference system
 * of step (<var>n</var>+1) must be the same as the target coordinate reference system of step (<var>n</var>).
 * The source coordinate reference system of the first step and the target coordinate reference system of the
 * last step are the source and target coordinate reference system associated with the concatenated operation.
 *
 * <p>The properties given in argument follow the same rules than for any other
 * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
 * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) coordinate operation} constructor.
 * The following table is a reminder of main (not all) properties:</p>
 *
 * <table class="sis">
 *   <caption>Recognized properties (non exhaustive list)</caption>
 *   <tr>
 *     <th>Property name</th>
 *     <th>Value type</th>
 *     <th>Returned by</th>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
 *     <td>{@link AbstractCoordinateOperation#getName()}</td>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
 *     <td>{@link AbstractCoordinateOperation#getIdentifiers()}</td>
 *   </tr>
 * </table>
 *
 * @param  properties  the properties to be given to the identified object.
 * @param  operations  the sequence of operations. Shall contains at least two operations.
 * @return the concatenated operation created from the given arguments.
 * @throws FactoryException if the object creation failed.
 */
@Override
public CoordinateOperation createConcatenatedOperation(final Map<String, ?> properties, final CoordinateOperation... operations) throws FactoryException {
    /*
         * If the user specified a single operation, there is no need to create a ConcatenatedOperation;
         * the operation to return will be the specified one. The metadata given in argument are ignored
         * on the assumption that the single operation has more complete metadata (in particular an EPSG
         * code, in which case we do not want to modify any other metadata in order to stay compliant
         * with EPSG definition).
         */
    if (operations != null && operations.length == 1) {
        return operations[0];
    }
    final ConcatenatedOperation op;
    try {
        op = new DefaultConcatenatedOperation(properties, operations, getMathTransformFactory());
    } catch (IllegalArgumentException exception) {
        throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
    }
    /*
         * Verifies again the number of single operations.  We may have a singleton if some operations
         * were omitted because their associated math transform were identity. This happen for example
         * if a "Geographic 3D to 2D conversion" has been redimensioned to a "3D to 3D" operation.
         */
    final List<? extends CoordinateOperation> co = op.getOperations();
    if (co.size() != 1) {
        return pool.unique(op);
    }
    final CoordinateOperation single = co.get(0);
    assert op.getMathTransform().equals(single.getMathTransform()) : op;
    if (!Objects.equals(single.getSourceCRS(), op.getSourceCRS()) || !Objects.equals(single.getTargetCRS(), op.getTargetCRS())) {
        /*
             * The CRS of the single operation may be different than the CRS of the concatenated operation
             * if the first or the last operation was an identity operation. It happens for example if the
             * sole purpose of an operation step was to change the longitude range from [-180 … +180]° to
             * [0 … 360]°: the MathTransform is identity (because Apache SIS does not handle those changes
             * in MathTransform; we handle that elsewhere, for example in the Envelopes utility class),
             * but omitting the transform should not cause the lost of the CRS with desired longitude range.
             */
        if (single instanceof SingleOperation) {
            final Map<String, Object> merge = new HashMap<>(IdentifiedObjects.getProperties(single, CoordinateOperation.IDENTIFIERS_KEY));
            merge.put(ReferencingServices.PARAMETERS_KEY, ((SingleOperation) single).getParameterValues());
            if (single instanceof AbstractIdentifiedObject) {
                merge.put(ReferencingServices.OPERATION_TYPE_KEY, ((AbstractIdentifiedObject) single).getInterface());
            }
            merge.putAll(properties);
            return createSingleOperation(merge, op.getSourceCRS(), op.getTargetCRS(), AbstractCoordinateOperation.getInterpolationCRS(op), ((SingleOperation) single).getMethod(), single.getMathTransform());
        }
    }
    return single;
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) HashMap(java.util.HashMap) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject)

Aggregations

AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)7 IdentifiedObject (org.opengis.referencing.IdentifiedObject)6 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)3 HashMap (java.util.HashMap)2 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)2 FactoryException (org.opengis.util.FactoryException)2 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)1 InvalidGeodeticParameterException (org.apache.sis.referencing.factory.InvalidGeodeticParameterException)1 DataStoreException (org.apache.sis.storage.DataStoreException)1 Cache (org.apache.sis.util.collection.Cache)1 Identifier (org.opengis.metadata.Identifier)1 Citation (org.opengis.metadata.citation.Citation)1 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)1 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)1 GenericName (org.opengis.util.GenericName)1 InternationalString (org.opengis.util.InternationalString)1