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;
}
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;
}
Aggregations