use of org.apache.sis.referencing.operation.transform.ContextualParameters in project sis by apache.
the class Equirectangular method createMathTransform.
/**
* Creates an Equirectangular projection from the specified group of parameter values. This method is an
* adaptation of {@link org.apache.sis.referencing.operation.projection.NormalizedProjection} constructor,
* reproduced in this method because we will create an affine transform instead than the usual projection
* classes.
*
* @param factory the factory to use if this constructor needs to create other math transforms.
* @param parameters the parameter values that define the transform to create.
* @return the map projection created from the given parameter values.
* @throws FactoryException if an error occurred while creating the math transform.
*/
@Override
public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup parameters) throws FactoryException {
final Parameters p = Parameters.castOrWrap(parameters);
final ContextualParameters context = new ContextualParameters(this);
double a = getAndStore(p, context, MapProjection.SEMI_MAJOR);
double b = getAndStore(p, context, MapProjection.SEMI_MINOR);
double λ0 = getAndStore(p, context, LONGITUDE_OF_ORIGIN);
double φ0 = getAndStore(p, context, LATITUDE_OF_ORIGIN);
double φ1 = getAndStore(p, context, STANDARD_PARALLEL);
double fe = getAndStore(p, context, FALSE_EASTING);
double fn = getAndStore(p, context, FALSE_NORTHING);
/*
* Perform following transformation, in that order. Note that following
* AffineTransform convention, the Java code appears in reverse order:
*
* 1) Subtract φ0 to the latitude.
* 2) Subtract λ0 to the longitude.
* 3) Convert degrees to radians.
* 4) Scale longitude by cos(φ1).
*/
φ1 = toRadians(φ1);
final MatrixSIS normalize = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
normalize.convertBefore(0, cos(φ1), null);
context.normalizeGeographicInputs(λ0).convertBefore(1, null, -φ0);
/*
* At this point, we usually invoke 'denormalize.convertAfter(…, a, …)' where 'a' (the semi-major axis length)
* is taken as the Earth radius (R). However quoting EPSG: "If the figure of the earth used is an ellipsoid
* rather than a sphere then R should be calculated as the radius of the conformal sphere at the projection
* origin at latitude φ1 using the formula for RC given in section 1.2, table 3".
*/
if (a != b) {
final double rs = b / a;
final double sinφ1 = sin(φ1);
a = b / (1 - (1 - rs * rs) * (sinφ1 * sinφ1));
}
final DoubleDouble k = new DoubleDouble(a);
final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
denormalize.convertAfter(0, k, new DoubleDouble(fe));
denormalize.convertAfter(1, k, new DoubleDouble(fn));
/*
* Creates the ConcatenatedTransform, letting the factory returns the cached instance
* if the caller already invoked this method previously (which usually do not happen).
*/
MathTransform mt = context.completeTransform(factory, MathTransforms.identity(2));
if (mt instanceof AffineTransform) {
// Always true in Apache SIS implementation.
mt = new ParameterizedAffine((AffineTransform) mt, context, true);
}
return mt;
}
Aggregations