use of org.apache.sis.internal.referencing.EPSGParameterDomain in project sis by apache.
the class EPSGDataAccess method createParameterDescriptor.
/**
* Creates a definition of a single parameter used by an operation method.
*
* <div class="note"><b>Example:</b>
* some EPSG codes for parameters are:
*
* <table class="sis" summary="EPSG codes examples">
* <tr><th>Code</th> <th>Description</th></tr>
* <tr><td>8801</td> <td>Latitude of natural origin</td></tr>
* <tr><td>8802</td> <td>Longitude of natural origin</td></tr>
* <tr><td>8805</td> <td>Scale factor at natural origin</td></tr>
* <tr><td>8806</td> <td>False easting</td></tr>
* <tr><td>8807</td> <td>False northing</td></tr>
* </table></div>
*
* @param code value allocated by EPSG.
* @return the parameter descriptor for the given code.
* @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
* @throws FactoryException if the object creation failed for some other reason.
*
* @see org.apache.sis.parameter.DefaultParameterDescriptor
*/
@Override
public synchronized ParameterDescriptor<?> createParameterDescriptor(final String code) throws NoSuchAuthorityCodeException, FactoryException {
ArgumentChecks.ensureNonNull("code", code);
ParameterDescriptor<?> returnValue = null;
try (ResultSet result = executeQuery("Coordinate_Operation Parameter", "PARAMETER_CODE", "PARAMETER_NAME", "SELECT PARAMETER_CODE," + " PARAMETER_NAME," + " DESCRIPTION," + " DEPRECATED" + " FROM [Coordinate_Operation Parameter]" + " WHERE PARAMETER_CODE = ?", code)) {
while (result.next()) {
final Integer epsg = getInteger(code, result, 1);
final String name = getString(code, result, 2);
final String description = getOptionalString(result, 3);
final boolean deprecated = getOptionalBoolean(result, 4);
Class<?> type = Double.class;
/*
* If the parameter appears to have at least one non-null value in the "Parameter File Name" column,
* then the type is assumed to be URI as a string. Otherwise, the type is a floating point number.
*/
try (ResultSet r = executeQuery("ParameterType", "SELECT PARAM_VALUE_FILE_REF FROM [Coordinate_Operation Parameter Value]" + " WHERE (PARAMETER_CODE = ?) AND PARAM_VALUE_FILE_REF IS NOT NULL", epsg)) {
while (r.next()) {
String element = getOptionalString(r, 1);
if (element != null && !element.isEmpty()) {
type = String.class;
break;
}
}
}
/*
* Search for units. We typically have many different units but all of the same dimension
* (for example metres, kilometres, feet, etc.). In such case, the units Set will have only
* one element and that element will be the most frequently used unit. But some parameters
* accept units of different dimensions. For example the "Ordinate 1 of evaluation point"
* (EPSG:8617) parameter value may be in metres or in degrees. In such case the units Set
* will have two elements.
*/
final Set<Unit<?>> units = new LinkedHashSet<>();
try (ResultSet r = executeQuery("ParameterUnit", "SELECT UOM_CODE FROM [Coordinate_Operation Parameter Value]" + " WHERE (PARAMETER_CODE = ?)" + " GROUP BY UOM_CODE" + " ORDER BY COUNT(UOM_CODE) DESC", epsg)) {
next: while (r.next()) {
final String c = getOptionalString(r, 1);
if (c != null) {
final Unit<?> candidate = owner.createUnit(c);
for (final Unit<?> e : units) {
if (candidate.isCompatible(e)) {
continue next;
}
}
units.add(candidate);
}
}
}
/*
* Determines if the inverse operation can be performed by reversing the parameter sign.
* The EPSG dataset uses "Yes" or "No" value, but SIS scripts use boolean type. We have
* to accept both. Note that if we do not recognize the string as a boolean value, then
* we need a SQLException, not a null value. If the value is wrongly null, this method
* will succeed anyway and EPSGDataAccess will finish its work without apparent problem,
* but Apache SIS will fail later when it will try to compute the inverse operation, for
* example in a call to CRS.findOperation(…). The exception thrown at such later time is
* much more difficult to relate to the root cause than if we throw the exception here.
*/
InternationalString isReversible = null;
try (ResultSet r = executeQuery("ParameterSign", "SELECT DISTINCT PARAM_SIGN_REVERSAL FROM [Coordinate_Operation Parameter Usage]" + " WHERE (PARAMETER_CODE = ?)", epsg)) {
if (r.next()) {
Boolean b;
if (translator.useBoolean()) {
b = r.getBoolean(1);
if (r.wasNull())
b = null;
} else {
// May throw SQLException - see above comment.
b = SQLUtilities.toBoolean(r.getString(1));
}
if (b != null) {
isReversible = b ? SignReversalComment.OPPOSITE : SignReversalComment.SAME;
}
}
}
/*
* Now creates the parameter descriptor.
*/
final NumberRange<?> valueDomain;
switch(units.size()) {
case 0:
valueDomain = null;
break;
default:
valueDomain = new EPSGParameterDomain(units);
break;
case 1:
valueDomain = MeasurementRange.create(Double.NEGATIVE_INFINITY, false, Double.POSITIVE_INFINITY, false, CollectionsExt.first(units));
break;
}
final Map<String, Object> properties = createProperties("Coordinate_Operation Parameter", name, epsg, isReversible, deprecated);
properties.put(ImmutableIdentifier.DESCRIPTION_KEY, description);
final ParameterDescriptor<?> descriptor = new DefaultParameterDescriptor<>(properties, 1, 1, type, valueDomain, null, null);
returnValue = ensureSingleton(descriptor, returnValue, code);
}
} catch (SQLException exception) {
throw databaseFailure(OperationMethod.class, code, exception);
}
if (returnValue == null) {
throw noSuchAuthorityCode(OperationMethod.class, code);
}
return returnValue;
}
Aggregations