use of org.opengis.util.NoSuchIdentifierException in project sis by apache.
the class EPSGDataAccess method fillParameterValues.
/**
* Sets the values of all parameters in the given group.
*
* @param method the EPSG code for the operation method.
* @param operation the EPSG code for the operation (conversion or transformation).
* @param parameters the parameter values to fill.
* @throws SQLException if a SQL statement failed.
*/
private void fillParameterValues(final Integer method, final Integer operation, final ParameterValueGroup parameters) throws FactoryException, SQLException {
try (ResultSet result = executeQuery("Coordinate_Operation Parameter Value", "SELECT CP.PARAMETER_NAME," + " CV.PARAMETER_VALUE," + " CV.PARAM_VALUE_FILE_REF," + " CV.UOM_CODE" + " FROM ([Coordinate_Operation Parameter Value] AS CV" + " INNER JOIN [Coordinate_Operation Parameter] AS CP" + " ON CV.PARAMETER_CODE = CP.PARAMETER_CODE)" + " INNER JOIN [Coordinate_Operation Parameter Usage] AS CU" + " ON (CP.PARAMETER_CODE = CU.PARAMETER_CODE)" + " AND (CV.COORD_OP_METHOD_CODE = CU.COORD_OP_METHOD_CODE)" + " WHERE CV.COORD_OP_METHOD_CODE = ?" + " AND CV.COORD_OP_CODE = ?" + " ORDER BY CU.SORT_ORDER", method, operation)) {
while (result.next()) {
final String name = getString(operation, result, 1);
final double value = getOptionalDouble(result, 2);
final Unit<?> unit;
String reference;
if (Double.isNaN(value)) {
/*
* If no numeric values were provided in the database, then the values should be
* in some external file. It may be a file in the $SIS_DATA/DatumChanges directory.
*/
reference = getString(operation, result, 3);
unit = null;
} else {
reference = null;
final String unitCode = getOptionalString(result, 4);
unit = (unitCode != null) ? owner.createUnit(unitCode) : null;
}
final ParameterValue<?> param;
try {
param = parameters.parameter(name);
} catch (ParameterNotFoundException exception) {
/*
* Wrap the unchecked ParameterNotFoundException into the checked NoSuchIdentifierException,
* which is a FactoryException subclass. Note that in principle, NoSuchIdentifierException is for
* MathTransforms rather than parameters. However we are close in spirit here since we are setting
* up MathTransform's parameters. Using NoSuchIdentifierException allows CoordinateOperationSet to
* know that the failure is probably caused by a MathTransform not yet supported in Apache SIS
* (or only partially supported) rather than some more serious failure in the database side.
* Callers can use this information in order to determine if they should try the next coordinate
* operation or propagate the exception.
*/
throw (NoSuchIdentifierException) new NoSuchIdentifierException(error().getString(Errors.Keys.CanNotSetParameterValue_1, name), name).initCause(exception);
}
try {
if (reference != null) {
param.setValue(reference);
} else if (unit != null) {
param.setValue(value, unit);
} else {
param.setValue(value);
}
} catch (RuntimeException exception) {
// Catch InvalidParameterValueException, ArithmeticException and others.
throw new FactoryDataException(error().getString(Errors.Keys.CanNotSetParameterValue_1, name), exception);
}
}
}
}
use of org.opengis.util.NoSuchIdentifierException in project sis by apache.
the class DefaultCoordinateOperationFactory method getOperationMethod.
/**
* Returns the operation method of the given name. The given argument shall be either a method
* {@linkplain DefaultOperationMethod#getName() name} (e.g. <cite>"Transverse Mercator"</cite>)
* or one of its {@linkplain DefaultOperationMethod#getIdentifiers() identifiers} (e.g. {@code "EPSG:9807"}).
* The search is case-insensitive and comparisons against method names can be
* {@linkplain DefaultOperationMethod#isHeuristicMatchForName(String) heuristic}.
*
* <p>If more than one method match the given name, then the first (according iteration order)
* non-{@linkplain org.apache.sis.util.Deprecable#isDeprecated() deprecated} matching method is returned.
* If all matching methods are deprecated, the first one is returned.</p>
*
* @param name the name of the operation method to fetch.
* @return the operation method of the given name.
* @throws FactoryException if the requested operation method can not be fetched.
*
* @see DefaultMathTransformFactory#getOperationMethod(String)
*/
public OperationMethod getOperationMethod(String name) throws FactoryException {
name = CharSequences.trimWhitespaces(name);
ArgumentChecks.ensureNonEmpty("name", name);
final MathTransformFactory mtFactory = getMathTransformFactory();
if (mtFactory instanceof DefaultMathTransformFactory) {
return ((DefaultMathTransformFactory) mtFactory).getOperationMethod(name);
}
final OperationMethod method = ReferencingServices.getInstance().getOperationMethod(mtFactory.getAvailableMethods(SingleOperation.class), name);
if (method != null) {
return method;
}
throw new NoSuchIdentifierException(Resources.forProperties(defaultProperties).getString(Resources.Keys.NoSuchOperationMethod_1, name), name);
}
use of org.opengis.util.NoSuchIdentifierException in project sis by apache.
the class StandardDefinitions method createUniversal.
/**
* Creates a Universal Transverse Mercator (UTM) or a Universal Polar Stereographic (UPS) projected CRS
* using the Apache SIS factory implementation. This method restricts the factory to SIS implementation
* instead than arbitrary factory in order to meet the contract saying that {@link CommonCRS} methods
* should never fail.
*
* @param code the EPSG code, or 0 if none.
* @param baseCRS the geographic CRS on which the projected CRS is based.
* @param isUTM {@code true} for UTM or {@code false} for UPS. Note: redundant with the given latitude.
* @param latitude a latitude in the zone of the desired projection, to be snapped to 0°, 90°S or 90°N.
* @param longitude a longitude in the zone of the desired projection, to be snapped to UTM central meridian.
* @param derivedCS the projected coordinate system.
*/
static ProjectedCRS createUniversal(final int code, final GeographicCRS baseCRS, final boolean isUTM, final double latitude, final double longitude, final CartesianCS derivedCS) {
final OperationMethod method;
try {
method = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class).getOperationMethod(isUTM ? TransverseMercator.NAME : PolarStereographicA.NAME);
} catch (NoSuchIdentifierException e) {
// Should not happen with SIS implementation.
throw new IllegalStateException(e);
}
final ParameterValueGroup parameters = method.getParameters().createValue();
String name = isUTM ? TransverseMercator.Zoner.UTM.setParameters(parameters, latitude, longitude) : PolarStereographicA.setParameters(parameters, latitude >= 0);
final DefaultConversion conversion = new DefaultConversion(properties(0, name, null, false), method, null, parameters);
name = baseCRS.getName().getCode() + " / " + name;
return new DefaultProjectedCRS(properties(code, name, null, false), baseCRS, conversion, derivedCS);
}
use of org.opengis.util.NoSuchIdentifierException 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