use of org.apache.sis.parameter.DefaultParameterDescriptor in project sis by apache.
the class CC_OperationParameterGroupTest method testMerge.
/**
* Tests the merge of unmarshalled descriptors with more complete descriptors.
* This operation is expected to create new descriptor instances as a result of the merges.
*
* @throws JAXBException if this method failed to create test data.
*/
@Test
@DependsOnMethod("testSubtitution")
public void testMerge() throws JAXBException {
final ParameterDescriptorGroup fromXML = unmarshal();
final ParameterDescriptor<?>[] fromValues = create(null);
final Map<GeneralParameterDescriptor, GeneralParameterDescriptor> replacements = new IdentityHashMap<>(4);
final GeneralParameterDescriptor[] merged = CC_OperationParameterGroup.merge(fromXML.descriptors(), fromValues.clone(), replacements);
assertNotSame(fromValues, merged);
/*
* "Longitude of natural origin" parameter should be the same.
*/
assertEquals("Number of parameters", 2, merged.length);
assertSame("Longitude of natural origin", fromValues[1], merged[1]);
/*
* "Latitude of natural origin" should be a new parameter, because we merged the remarks from the
* 'fromXML' descriptor with value class, unit and default value from the 'fromValue' descriptor.
*/
final GeneralParameterDescriptor incomplete = fromXML.descriptors().get(0);
final DefaultParameterDescriptor<?> fromValue = (DefaultParameterDescriptor<?>) fromValues[0];
final DefaultParameterDescriptor<?> complete = (DefaultParameterDescriptor<?>) merged[0];
assertNotSame("Latitude of natural origin", incomplete, complete);
assertNotSame("Latitude of natural origin", fromValue, complete);
assertSame("name", fromValue.getName(), complete.getName());
assertSame("remarks", incomplete.getRemarks(), complete.getRemarks());
assertEquals("valueClass", Double.class, complete.getValueClass());
assertSame("valueDomain", fromValue.getValueDomain(), complete.getValueDomain());
/*
* All references to 'fromValue' will need to be replaced by references to 'complete'.
*/
assertEquals("replacements", Collections.singletonMap(fromValue, complete), replacements);
}
use of org.apache.sis.parameter.DefaultParameterDescriptor 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