use of org.opengis.referencing.crs.CoordinateReferenceSystem in project sis by apache.
the class ServicesForMetadata method setBounds.
/**
* Sets a temporal extent with the value inferred from the given envelope.
* Only the vertical ordinates are extracted; all other ordinates are ignored.
*
* @param envelope the source envelope.
* @param target the target temporal extent where to store envelope information.
* @throws TransformException if no temporal component can be extracted from the given envelope.
*/
@Override
public void setBounds(final Envelope envelope, final DefaultTemporalExtent target) throws TransformException {
final CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
final TemporalCRS temporalCRS = CRS.getTemporalComponent(crs);
if (temporalCRS == null) {
// Mandatory for the conversion from numbers to dates.
throw new TransformException(dimensionNotFound(Resources.Keys.MissingTemporalDimension_1, crs));
}
setTemporalExtent(envelope, target, crs, temporalCRS);
}
use of org.opengis.referencing.crs.CoordinateReferenceSystem in project sis by apache.
the class CoordinateOperationSet method createObject.
/**
* Creates a coordinate operation for the specified EPSG code.
*/
@Override
protected CoordinateOperation createObject(final String code) throws FactoryException {
final Integer base = projections.get(code);
if (base != null) {
/*
* First case documented in class Javadoc:
*
* SELECT PROJECTION_CONV_CODE FROM "Coordinate Reference System" …
*
* The result is usually a ProjectedCRS, but not always.
*/
CoordinateReferenceSystem crs;
crs = ((CRSAuthorityFactory) factory).createCoordinateReferenceSystem(String.valueOf(base));
if (crs instanceof GeneralDerivedCRS) {
return ((GeneralDerivedCRS) crs).getConversionFromBase();
}
}
/*
* Following line is either for the second case documented in class Javadoc, or the first case
* when the result is not a derived CRS. Note that we could create a derived CRS here as below:
*
* CoordinateOperation op = …,
* if (crs != null && op instanceof Conversion) {
* return DefaultDerivedCRS.create(IdentifiedObjects.getProperties(crs), baseCRS,
* (Conversion) op, crs.getCoordinateSystem()).getConversionFromBase();
* }
*
* We don't do that for now because because EPSGDataAccess.createCoordinateReferenceSystem(String)
* would be a better place, by generalizing the work done for ProjectedCRS.
*
* https://issues.apache.org/jira/browse/SIS-357
*/
return ((CoordinateOperationAuthorityFactory) factory).createCoordinateOperation(code);
}
use of org.opengis.referencing.crs.CoordinateReferenceSystem in project sis by apache.
the class AbstractSingleOperation method afterUnmarshal.
/**
* Invoked by JAXB after unmarshalling. This method needs information provided by:
*
* <ul>
* <li>{@link #setSource(CoordinateReferenceSystem)}</li>
* <li>{@link #setTarget(CoordinateReferenceSystem)}</li>
* <li>{@link #setParameters(GeneralParameterValue[])}</li>
* </ul>
*
* @see <a href="http://issues.apache.org/jira/browse/SIS-291">SIS-291</a>
*/
@Override
final void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
super.afterUnmarshal(unmarshaller, parent);
final CoordinateReferenceSystem sourceCRS = super.getSourceCRS();
final CoordinateReferenceSystem targetCRS = super.getTargetCRS();
if (transform == null && sourceCRS != null && targetCRS != null && parameters != null)
try {
transform = DefaultFactories.forBuildin(MathTransformFactory.class).createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());
} catch (FactoryException e) {
Context.warningOccured(Context.current(), AbstractSingleOperation.class, "afterUnmarshal", e, true);
}
}
use of org.opengis.referencing.crs.CoordinateReferenceSystem in project sis by apache.
the class CoordinateOperationRegistry method recreate.
/**
* Creates a new coordinate operation with the same method than the given operation, but different CRS.
* The CRS may differ either in the number of dimensions (i.e. let the vertical coordinate pass through),
* or in axis order (i.e. axis order in user CRS were not compliant with authority definition).
*
* @param operation the operation specified by the authority.
* @param sourceCRS the source CRS specified by the user.
* @param targetCRS the target CRS specified by the user
* @param transform the math transform to use in replacement to the one in {@code operation}.
* @param method the operation method, or {@code null} for attempting an automatic detection.
* @return a new operation from the given source CRS to target CRS using the given transform.
* @throws IllegalArgumentException if the operation method can not have the desired number of dimensions.
* @throws FactoryException if an error occurred while creating the new operation.
*/
private CoordinateOperation recreate(final CoordinateOperation operation, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, final MathTransform transform, OperationMethod method) throws IllegalArgumentException, FactoryException {
/*
* If the user-provided CRS are approximatively equal to the coordinate operation CRS, keep the later.
* The reason is that coordinate operation CRS are built from the definitions provided by the authority,
* while the user-provided CRS can be anything (e.g. parsed from a quite approximative WKT).
*/
CoordinateReferenceSystem crs;
if (Utilities.equalsApproximatively(sourceCRS, crs = operation.getSourceCRS()))
sourceCRS = crs;
if (Utilities.equalsApproximatively(targetCRS, crs = operation.getTargetCRS()))
targetCRS = crs;
final Map<String, Object> properties = new HashMap<>(derivedFrom(operation));
/*
* Determine whether the operation to create is a Conversion or a Transformation
* (could also be a Conversion subtype like Projection, but this is less important).
* We want the GeoAPI interface, not the implementation class.
* The most reliable way is to ask to the 'AbstractOperation.getInterface()' method,
* but this is SIS-specific. The fallback uses reflection.
*/
final Class<? extends IdentifiedObject> type;
if (operation instanceof AbstractIdentifiedObject) {
type = ((AbstractIdentifiedObject) operation).getInterface();
} else {
type = Classes.getLeafInterfaces(operation.getClass(), CoordinateOperation.class)[0];
}
properties.put(ReferencingServices.OPERATION_TYPE_KEY, type);
/*
* Reuse the same operation method, but we may need to change its number of dimension.
* The capability to resize an OperationMethod is specific to Apache SIS, so we must
* be prepared to see the 'redimension' call fails. In such case, we will try to get
* the SIS implementation of the operation method and try again.
*/
if (SubTypes.isSingleOperation(operation)) {
final SingleOperation single = (SingleOperation) operation;
properties.put(ReferencingServices.PARAMETERS_KEY, single.getParameterValues());
if (method == null) {
final int sourceDimensions = transform.getSourceDimensions();
final int targetDimensions = transform.getTargetDimensions();
method = single.getMethod();
try {
method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
} catch (IllegalArgumentException ex) {
try {
method = factorySIS.getOperationMethod(method.getName().getCode());
method = DefaultOperationMethod.redimension(method, sourceDimensions, targetDimensions);
} catch (NoSuchIdentifierException | IllegalArgumentException se) {
ex.addSuppressed(se);
throw ex;
}
}
}
}
return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS, AbstractCoordinateOperation.getInterpolationCRS(operation), method, transform);
}
use of org.opengis.referencing.crs.CoordinateReferenceSystem in project sis by apache.
the class CoordinateOperationRegistry method inverse.
/**
* Creates the inverse of the given single operation.
* If this operation succeed, then the returned coordinate operations has the following properties:
*
* <ul>
* <li>Its {@code sourceCRS} is the {@code targetCRS} of the given operation.</li>
* <li>Its {@code targetCRS} is the {@code sourceCRS} of the given operation.</li>
* <li>Its {@code interpolationCRS} is {@code null}.</li>
* <li>Its {@code MathTransform} is the
* {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#inverse() inverse}
* of the {@code MathTransform} of this operation.</li>
* <li>Its domain of validity and accuracy is the same.</li>
* </ul>
*
* <div class="note"><b>Note:</b>
* in many cases, the inverse operation is numerically less accurate than the direct operation because it
* uses approximations like series expansions or iterative methods. However the numerical errors caused by
* those approximations are not of interest here, because they are usually much smaller than the inaccuracy
* due to the stochastic nature of coordinate transformations (not to be confused with coordinate conversions;
* see ISO 19111 for more information).</div>
*/
final CoordinateOperation inverse(final SingleOperation op) throws NoninvertibleTransformException, FactoryException {
final CoordinateReferenceSystem sourceCRS = op.getSourceCRS();
final CoordinateReferenceSystem targetCRS = op.getTargetCRS();
final MathTransform transform = op.getMathTransform().inverse();
final OperationMethod method = InverseOperationMethod.create(op.getMethod());
final Map<String, Object> properties = properties(INVERSE_OPERATION);
InverseOperationMethod.properties(op, properties);
/*
* Find a hint about whether the coordinate operation is a transformation or a conversion,
* but do not set any conversion subtype. In particular, do not specify a Projection type,
* because the inverse of a Projection does not implement the Projection interface.
*/
Class<? extends CoordinateOperation> type = null;
if (op instanceof Transformation)
type = Transformation.class;
else if (op instanceof Conversion)
type = Conversion.class;
return createFromMathTransform(properties, targetCRS, sourceCRS, transform, method, null, type);
}
Aggregations