use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class SingleOperationMarshallingTest method testConversionUnmarshalling.
/**
* Tests unmarshalling of a defining conversion.
*
* @throws JAXBException if an error occurred during marshalling or unmarshalling.
*/
@Test
@DependsOnMethod("testOperationMethod")
public void testConversionUnmarshalling() throws JAXBException {
final DefaultConversion c = unmarshalFile(DefaultConversion.class, "Conversion.xml");
assertEquals("name", "World Mercator", c.getName().getCode());
assertEquals("identifier", "3395", getSingleton(c.getIdentifiers()).getCode());
assertEquals("scope", "Very small scale mapping.", String.valueOf(c.getScope()));
assertNull("operationVersion", c.getOperationVersion());
final GeographicBoundingBox e = (GeographicBoundingBox) getSingleton(c.getDomainOfValidity().getGeographicElements());
assertEquals("eastBoundLongitude", +180, e.getEastBoundLongitude(), STRICT);
assertEquals("westBoundLongitude", -180, e.getWestBoundLongitude(), STRICT);
assertEquals("northBoundLatitude", 84, e.getNorthBoundLatitude(), STRICT);
assertEquals("southBoundLatitude", -80, e.getSouthBoundLatitude(), STRICT);
// This is a defining conversion, so we do not expect CRS.
assertNull("sourceCRS", c.getSourceCRS());
assertNull("targetCRS", c.getTargetCRS());
assertNull("interpolationCRS", c.getInterpolationCRS());
assertNull("mathTransform", c.getMathTransform());
// The most difficult part.
final OperationMethod method = c.getMethod();
assertNotNull("method", method);
verifyMethod(method);
final ParameterValueGroup parameters = c.getParameterValues();
assertNotNull("parameters", parameters);
final Iterator<GeneralParameterValue> it = parameters.values().iterator();
verifyParameter(method, parameters, -0.0, (ParameterValue<?>) it.next());
verifyParameter(method, parameters, -90.0, (ParameterValue<?>) it.next());
assertFalse("Unexpected parameter.", it.hasNext());
Validators.validate(c);
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class InitializerTest method testRadiusOfConformalSphere.
/**
* Tests the {@link Initializer#radiusOfConformalSphere(double)} method.
* This test computes the Radius of Conformal Sphere using the values given
* by the <a href="http://www.iogp.org/pubs/373-07-2.pdf">EPSG guide</a> for
* the <cite>Amersfoort / RD New</cite> projection (a Stereographic one).
*/
@Test
public void testRadiusOfConformalSphere() {
final OperationMethod op = new ObliqueStereographic();
final ParameterValueGroup p = op.getParameters().createValue();
/*
* Following parameters are not given explicitely by EPSG definitions since they are
* usually inferred from the datum. However in the particular case of this test, we
* need to provide them. The names used below are either OGC names or SIS extensions.
*/
p.parameter("semi_major").setValue(6377397.155);
p.parameter("inverse_flattening").setValue(299.15281);
/*
* Following parameters are reproduced verbatim from EPSG registry and EPSG guide.
*/
p.parameter("Latitude of natural origin").setValue(52.156160556);
p.parameter("Longitude of natural origin").setValue(5.387638889);
p.parameter("Scale factor at natural origin").setValue(0.9999079);
p.parameter("False easting").setValue(155000.00);
p.parameter("False northing").setValue(463000.00);
/*
* The following lines are a typical way to create an Initializer instance.
* The EnumMap tells to the Initializer constructor which parameters to look for.
* We construct this map here for testing purpose, but users normally do not have
* to do that since this map is provided by the ObliqueStereographic class itself.
*/
final EnumMap<NormalizedProjection.ParameterRole, ParameterDescriptor<Double>> roles = new EnumMap<>(NormalizedProjection.ParameterRole.class);
roles.put(NormalizedProjection.ParameterRole.CENTRAL_MERIDIAN, ObliqueStereographic.LONGITUDE_OF_ORIGIN);
roles.put(NormalizedProjection.ParameterRole.SCALE_FACTOR, ObliqueStereographic.SCALE_FACTOR);
roles.put(NormalizedProjection.ParameterRole.FALSE_EASTING, ObliqueStereographic.FALSE_EASTING);
roles.put(NormalizedProjection.ParameterRole.FALSE_NORTHING, ObliqueStereographic.FALSE_NORTHING);
final Initializer initializer = new Initializer(op, (Parameters) p, roles, (byte) 0);
/*
* The following lines give an example of how Apache SIS projection constructors
* use the Initializer class.
*/
final double φ0 = toRadians(initializer.getAndStore(ObliqueStereographic.LATITUDE_OF_ORIGIN));
assertTrue(φ0 > 0);
assertEquals("Conformal Sphere Radius", 6382644.571, 6377397.155 * initializer.radiusOfConformalSphere(sin(φ0)), Formulas.LINEAR_TOLERANCE);
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class ObliqueStereographicTest method testPolarStereographic.
/**
* Tests the delegation to {@link PolarStereographic} implementation when the latitude of origin is ±90°.
*
* @throws FactoryException if an error occurred while creating the map projection.
* @throws TransformException if an error occurred while projecting a coordinate.
*/
@Test
public void testPolarStereographic() throws FactoryException, TransformException {
final OperationMethod op = new org.apache.sis.internal.referencing.provider.ObliqueStereographic();
final ParameterValueGroup p = op.getParameters().createValue();
p.parameter("semi_major").setValue(6378137);
p.parameter("inverse_flattening").setValue(298.2572236);
p.parameter("Latitude of natural origin").setValue(90);
p.parameter("Scale factor at natural origin").setValue(0.994);
p.parameter("False easting").setValue(2000000);
p.parameter("False northing").setValue(2000000);
transform = new ObliqueStereographic(op, (Parameters) p).createMapProjection(DefaultFactories.forBuildin(MathTransformFactory.class));
tolerance = 0.01;
verifyTransform(new double[] { 44, 73 }, new double[] { 3320416.75, 632668.43 });
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class DefaultMathTransformFactory method createParameterizedTransform.
/**
* Creates a transform from a group of parameters.
* The set of expected parameters varies for each operation.
* The easiest way to provide parameter values is to get an initially empty group for the desired
* operation by calling {@link #getDefaultParameters(String)}, then to fill the parameter values.
* Example:
*
* {@preformat java
* ParameterValueGroup group = factory.getDefaultParameters("Transverse_Mercator");
* group.parameter("semi_major").setValue(6378137.000);
* group.parameter("semi_minor").setValue(6356752.314);
* MathTransform mt = factory.createParameterizedTransform(group, null);
* }
*
* Sometime the {@code "semi_major"} and {@code "semi_minor"} parameter values are not explicitly provided,
* but rather inferred from the {@linkplain org.apache.sis.referencing.datum.DefaultGeodeticDatum geodetic
* datum} of the source Coordinate Reference System. If the given {@code context} argument is non-null,
* then this method will use those contextual information for:
*
* <ol>
* <li>Inferring the {@code "semi_major"}, {@code "semi_minor"}, {@code "src_semi_major"},
* {@code "src_semi_minor"}, {@code "tgt_semi_major"} or {@code "tgt_semi_minor"} parameters values
* from the {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid ellipsoids} associated to
* the source or target CRS, if those parameters are not explicitly given and if they are relevant
* for the coordinate operation method.</li>
* <li>{@linkplain #createConcatenatedTransform Concatenating} the parameterized transform
* with any other transforms required for performing units changes and ordinates swapping.</li>
* </ol>
*
* The complete group of parameters, including {@code "semi_major"}, {@code "semi_minor"} or other calculated values,
* can be obtained by a call to {@link Context#getCompletedParameters()} after {@code createParameterizedTransform(…)}
* returned. Note that the completed parameters may only have additional parameters compared to the given parameter
* group; existing parameter values should not be modified.
*
* <p>The {@code OperationMethod} instance used by this constructor can be obtained by a call to
* {@link #getLastMethodUsed()}.</p>
*
* @param parameters the parameter values. The {@linkplain ParameterDescriptorGroup#getName() parameter group name}
* shall be the name of the desired {@linkplain DefaultOperationMethod operation method}.
* @param context information about the context (for example source and target coordinate systems)
* in which the new transform is going to be used, or {@code null} if none.
* @return the transform created from the given parameters.
* @throws NoSuchIdentifierException if there is no method for the given parameter group name.
* @throws FactoryException if the object creation failed. This exception is thrown
* if some required parameter has not been supplied, or has illegal value.
*
* @see #getDefaultParameters(String)
* @see #getAvailableMethods(Class)
* @see #getLastMethodUsed()
* @see org.apache.sis.parameter.ParameterBuilder#createGroupForMapProjection(ParameterDescriptor...)
*/
public MathTransform createParameterizedTransform(ParameterValueGroup parameters, final Context context) throws NoSuchIdentifierException, FactoryException {
OperationMethod method = null;
RuntimeException failure = null;
MathTransform transform;
try {
ArgumentChecks.ensureNonNull("parameters", parameters);
final ParameterDescriptorGroup descriptor = parameters.getDescriptor();
final String methodName = descriptor.getName().getCode();
String methodIdentifier = IdentifiedObjects.toString(IdentifiedObjects.getIdentifier(descriptor, Citations.EPSG));
if (methodIdentifier == null) {
methodIdentifier = methodName;
}
/*
* Get the MathTransformProvider of the same name or identifier than the given parameter group.
* We give precedence to EPSG identifier because operation method names are sometime ambiguous
* (e.g. "Lambert Azimuthal Equal Area (Spherical)"). If we fail to find the method by its EPSG code,
* we will try searching by method name. As a side effect, this second attempt will produce a better
* error message if the method is really not found.
*/
try {
method = getOperationMethod(methodIdentifier);
} catch (NoSuchIdentifierException exception) {
if (methodIdentifier.equals(methodName)) {
throw exception;
}
method = getOperationMethod(methodName);
Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION), DefaultMathTransformFactory.class, "createParameterizedTransform", exception);
}
if (!(method instanceof MathTransformProvider)) {
throw new NoSuchIdentifierException(// For now, handle like an unknown operation.
Errors.format(Errors.Keys.UnsupportedImplementation_1, Classes.getClass(method)), methodName);
}
/*
* Will catch only exceptions that may be the result of improper parameter usage (e.g. a value out
* of range). Do not catch exceptions caused by programming errors (e.g. null pointer exception).
*/
try {
/*
* If the user's parameters do not contain semi-major and semi-minor axis lengths, infer
* them from the ellipsoid. We have to do that because those parameters are often omitted,
* since the standard place where to provide this information is in the ellipsoid object.
*/
if (context != null) {
failure = context.completeParameters(this, method, parameters);
parameters = context.parameters;
method = context.provider;
}
transform = ((MathTransformProvider) method).createMathTransform(this, parameters);
} catch (IllegalArgumentException | IllegalStateException exception) {
throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
}
/*
* Cache the transform that we just created and make sure that the number of dimensions
* is compatible with the OperationMethod instance. Then make final adjustment for axis
* directions and units of measurement.
*/
transform = unique(transform);
method = DefaultOperationMethod.redimension(method, transform.getSourceDimensions(), transform.getTargetDimensions());
if (context != null) {
transform = swapAndScaleAxes(transform, context);
}
} catch (FactoryException e) {
if (failure != null) {
e.addSuppressed(failure);
}
throw e;
} finally {
// May be null in case of failure, which is intended.
lastMethod.set(method);
if (context != null) {
context.provider = null;
/*
* For now we conservatively reset the provider information to null. But if we choose to
* make that information public in a future SIS version, then we would remove this code.
*/
}
}
return transform;
}
Aggregations