Search in sources :

Example 6 with InvalidGeodeticParameterException

use of org.apache.sis.referencing.factory.InvalidGeodeticParameterException in project sis by apache.

the class DefaultProjectedCRSTest method testConstructor.

/**
 * Creates a projected CRS and verifies its parameters.
 * Verifies also that the constructor does not accept invalid base CRS.
 *
 * @throws FactoryException if the CRS creation failed.
 */
@Test
public void testConstructor() throws FactoryException {
    final ProjectedCRS crs = create(HardCodedCRS.NTF);
    verifyParameters(crs.getConversionFromBase().getParameterValues());
    try {
        create(HardCodedCRS.WGS84_3D);
        fail("Should not accept a three-dimensional base geodetic CRS.");
    } catch (InvalidGeodeticParameterException e) {
        final String message = e.getMessage();
        assertTrue(message, message.contains("Lambert Conic Conformal (1SP)"));
    }
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) Test(org.junit.Test)

Example 7 with InvalidGeodeticParameterException

use of org.apache.sis.referencing.factory.InvalidGeodeticParameterException in project sis by apache.

the class DefaultMathTransformFactory method createPassThroughTransform.

/**
 * Creates a transform which passes through a subset of ordinates to another transform.
 * This allows transforms to operate on a subset of ordinates.
 *
 * <div class="note"><b>Example:</b>
 * Giving (<var>latitude</var>, <var>longitude</var>, <var>height</var>) coordinates,
 * a pass through transform can convert the height values from meters to feet without
 * affecting the (<var>latitude</var>, <var>longitude</var>) values.</div>
 *
 * The resulting transform will have the following dimensions:
 *
 * {@preformat java
 *     Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
 *     Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates
 * }
 *
 * @param  firstAffectedOrdinate  the lowest index of the affected ordinates.
 * @param  subTransform           transform to use for affected ordinates.
 * @param  numTrailingOrdinates   number of trailing ordinates to pass through. Affected ordinates will range
 *         from {@code firstAffectedOrdinate} inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
 * @return a pass through transform.
 * @throws FactoryException if the object creation failed.
 */
@Override
public MathTransform createPassThroughTransform(final int firstAffectedOrdinate, final MathTransform subTransform, final int numTrailingOrdinates) throws FactoryException {
    lastMethod.remove();
    final MathTransform tr;
    try {
        tr = PassThroughTransform.create(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
    } catch (IllegalArgumentException exception) {
        throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
    }
    return unique(tr);
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) MathTransform(org.opengis.referencing.operation.MathTransform)

Example 8 with InvalidGeodeticParameterException

use of org.apache.sis.referencing.factory.InvalidGeodeticParameterException 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;
}
Also used : MathTransform(org.opengis.referencing.operation.MathTransform) FactoryException(org.opengis.util.FactoryException) ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) DefaultOperationMethod(org.apache.sis.referencing.operation.DefaultOperationMethod) OperationMethod(org.opengis.referencing.operation.OperationMethod) InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) NoSuchIdentifierException(org.opengis.util.NoSuchIdentifierException)

Example 9 with InvalidGeodeticParameterException

use of org.apache.sis.referencing.factory.InvalidGeodeticParameterException in project sis by apache.

the class DefaultMathTransformFactory method createConcatenatedTransform.

/**
 * Creates a transform by concatenating two existing transforms.
 * A concatenated transform acts in the same way as applying two transforms, one after the other.
 *
 * <p>The dimension of the output space of the first transform must match the dimension of the input space
 * in the second transform. In order to concatenate more than two transforms, use this constructor repeatedly.</p>
 *
 * @param  tr1  the first transform to apply to points.
 * @param  tr2  the second transform to apply to points.
 * @return the concatenated transform.
 * @throws FactoryException if the object creation failed.
 *
 * @see MathTransforms#concatenate(MathTransform, MathTransform)
 */
@Override
public MathTransform createConcatenatedTransform(final MathTransform tr1, final MathTransform tr2) throws FactoryException {
    lastMethod.remove();
    ArgumentChecks.ensureNonNull("tr1", tr1);
    ArgumentChecks.ensureNonNull("tr2", tr2);
    final MathTransform tr;
    try {
        tr = ConcatenatedTransform.create(tr1, tr2, this);
    } catch (IllegalArgumentException exception) {
        throw new InvalidGeodeticParameterException(exception.getLocalizedMessage(), exception);
    }
    assert MathTransforms.isValid(MathTransforms.getSteps(tr)) : tr;
    return unique(tr);
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) MathTransform(org.opengis.referencing.operation.MathTransform)

Example 10 with InvalidGeodeticParameterException

use of org.apache.sis.referencing.factory.InvalidGeodeticParameterException in project sis by apache.

the class DefaultMathTransformFactory method createFromWKT.

/**
 * Creates a math transform object from a
 * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
 * Known Text</cite> (WKT)</a>.
 * If the given text contains non-fatal anomalies (unknown or unsupported WKT elements,
 * inconsistent unit definitions, <i>etc.</i>), warnings may be reported in a
 * {@linkplain java.util.logging.Logger logger} named {@code "org.apache.sis.io.wkt"}.
 *
 * @param  text  math transform encoded in Well-Known Text format.
 * @return the math transform (never {@code null}).
 * @throws FactoryException if the Well-Known Text can not be parsed,
 *         or if the math transform creation failed from some other reason.
 */
@Override
public MathTransform createFromWKT(final String text) throws FactoryException {
    lastMethod.remove();
    Parser p = parser.getAndSet(null);
    if (p == null)
        try {
            Constructor<? extends Parser> c = parserConstructor;
            if (c == null) {
                c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(Parser.class).getConstructor(MathTransformFactory.class);
                // For allowing use in inner class or lambda expression.
                final Constructor<?> cp = c;
                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                    cp.setAccessible(true);
                    return null;
                });
                parserConstructor = c;
            }
            p = c.newInstance(this);
        } catch (ReflectiveOperationException e) {
            throw new FactoryException(e);
        }
    /*
         * No need to check the type of the parsed object, because MathTransformParser
         * should return only instance of MathTransform.
         */
    final Object object;
    try {
        object = p.createFromWKT(text);
    } catch (FactoryException e) {
        /*
             * The parsing may fail because a operation parameter is not known to SIS. If this happen, replace
             * the generic exception thrown be the parser (which is FactoryException) by a more specific one.
             * Note that InvalidGeodeticParameterException is defined only in this sis-referencing module,
             * so we could not throw it from the sis-metadata module that contain the parser.
             */
        Throwable cause = e.getCause();
        while (cause != null) {
            if (cause instanceof ParameterNotFoundException) {
                throw new InvalidGeodeticParameterException(e.getLocalizedMessage(), cause);
            }
            cause = cause.getCause();
        }
        throw e;
    }
    parser.set(p);
    return (MathTransform) object;
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) MathTransform(org.opengis.referencing.operation.MathTransform) PrivilegedAction(java.security.PrivilegedAction) FactoryException(org.opengis.util.FactoryException) Constructor(java.lang.reflect.Constructor) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException) Parser(org.apache.sis.io.wkt.Parser)

Aggregations

InvalidGeodeticParameterException (org.apache.sis.referencing.factory.InvalidGeodeticParameterException)12 MathTransform (org.opengis.referencing.operation.MathTransform)5 FactoryException (org.opengis.util.FactoryException)3 ParserException (javax.measure.format.ParserException)2 UnavailableFactoryException (org.apache.sis.referencing.factory.UnavailableFactoryException)2 Test (org.junit.Test)2 OperationMethod (org.opengis.referencing.operation.OperationMethod)2 NoSuchIdentifierException (org.opengis.util.NoSuchIdentifierException)2 Constructor (java.lang.reflect.Constructor)1 PrivilegedAction (java.security.PrivilegedAction)1 HashMap (java.util.HashMap)1 DeferredCoordinateOperation (org.apache.sis.internal.referencing.DeferredCoordinateOperation)1 Parser (org.apache.sis.io.wkt.Parser)1 Line (org.apache.sis.math.Line)1 Plane (org.apache.sis.math.Plane)1 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)1 DefaultProjectedCRS (org.apache.sis.referencing.crs.DefaultProjectedCRS)1 DefaultConversion (org.apache.sis.referencing.operation.DefaultConversion)1 DefaultOperationMethod (org.apache.sis.referencing.operation.DefaultOperationMethod)1 MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)1