use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class OperationMethodSetTest method testMixedCases.
/**
* Tests a non-empty set.
*/
@Test
@DependsOnMethod("testEmpty")
public void testMixedCases() {
final DefaultOperationMethod merA = createMethod(CylindricalProjection.class, "Mercator (variant A)");
final DefaultOperationMethod merB = createMethod(CylindricalProjection.class, "Mercator (variant B)");
final DefaultOperationMethod merC = createMethod(CylindricalProjection.class, "Mercator (variant C)");
final DefaultOperationMethod dup = createMethod(CylindricalProjection.class, "Mercator (variant B)");
final DefaultOperationMethod lamb = createMethod(ConicProjection.class, "Lambert");
final DefaultOperationMethod[] methods = new DefaultOperationMethod[] { merA, merB, merC, dup, lamb };
final OperationMethodSet mercators = create(CylindricalProjection.class, methods);
final OperationMethodSet lambert = create(ConicProjection.class, methods);
final OperationMethodSet all = create(Projection.class, methods);
/*
* Mercator case.
* - Intentionally start the iteration without checking 'hasNext()' - the iterator shall be robust to that.
* - Intentionally start an other iteration (indirectly) in the middle of the first one.
*/
final Iterator<OperationMethod> iterator = mercators.iterator();
assertSame(merA, iterator.next());
assertSame(merB, iterator.next());
assertArrayEquals("toArray", new DefaultOperationMethod[] { merA, merB, merC }, mercators.toArray());
assertSame(merC, iterator.next());
assertFalse(iterator.hasNext());
assertFalse("isEmpty", mercators.isEmpty());
assertEquals("size", 3, mercators.size());
/*
* Lambert case. Test twice since the two excecutions will take different code paths.
*/
assertEquals(Collections.singleton(lamb), lambert);
assertEquals(Collections.singleton(lamb), lambert);
/*
* Test filtering: the test should not contain any conic projection.
*/
assertEmpty(create(PlanarProjection.class, methods));
/*
* Opportunist tests.
*/
assertFalse(lambert.containsAll(all));
assertTrue(all.containsAll(lambert));
assertTrue(all.containsAll(mercators));
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class DefaultMathTransformFactory method getOperationMethod.
/**
* Returns the operation method for the specified name or identifier. 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"}).
*
* <p>The search is case-insensitive. Comparisons against method names can be
* {@linkplain DefaultOperationMethod#isHeuristicMatchForName(String) heuristic}.</p>
*
* <p>If more than one method match the given identifier, 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 identifier the name or identifier of the operation method to search.
* @return the coordinate operation method for the given name or identifier.
* @throws NoSuchIdentifierException if there is no operation method registered for the specified identifier.
*
* @see org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#getOperationMethod(String)
*/
public OperationMethod getOperationMethod(String identifier) throws NoSuchIdentifierException {
identifier = CharSequences.trimWhitespaces(identifier);
ArgumentChecks.ensureNonEmpty("identifier", identifier);
OperationMethod method = methodsByName.get(identifier);
if (method == null) {
final ReferencingServices services = ReferencingServices.getInstance();
synchronized (methods) {
method = services.getOperationMethod(methods, identifier);
}
if (method == null) {
throw new NoSuchIdentifierException(Resources.format(Resources.Keys.NoSuchOperationMethod_1, identifier), identifier);
}
/*
* Remember the method we just found, for faster check next time.
*/
final OperationMethod previous = methodsByName.putIfAbsent(identifier.intern(), method);
if (previous != null) {
method = previous;
}
}
return method;
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class Formatter method appendComplement.
/**
* Appends the optional complementary attributes common to many {@link IdentifiedObject} subtypes.
* Those attributes are {@code ANCHOR}, {@code SCOPE}, {@code AREA}, {@code BBOX}, {@code VERTICALEXTENT},
* {@code TIMEEXTENT}, {@code ID} (previously known as {@code AUTHORITY}) and {@code REMARKS},
* and have a special treatment: they are written by {@link #append(FormattableObject)}
* after the {@code formatTo(Formatter)} method returned.
*
* <p>The {@code ID[<name>,<code>,…]} element is normally written only for the root element
* (unless the convention is {@code INTERNAL}), but there is various exceptions to this rule.
* If formatted, the {@code ID} element will be by default on the same line than the enclosing
* element (e.g. {@code SPHEROID["Clarke 1866", …, ID["EPSG", 7008]]}). Other example:</p>
*
* {@preformat text
* PROJCS["NAD27 / Idaho Central",
* GEOGCS[...etc...],
* ...etc...
* ID["EPSG", 26769]]
* }
*
* For non-internal conventions, all elements other than {@code ID[…]} are formatted
* only for {@link CoordinateOperation} and root {@link ReferenceSystem} instances,
* with an exception for remarks of {@code ReferenceSystem} embedded inside {@code CoordinateOperation}.
* Those restrictions are our interpretation of the following ISO 19162 requirement:
*
* <blockquote>(…snip…) {@code <scope extent identifier remark>} is a collection of four optional attributes
* which may be applied to a coordinate reference system, a coordinate operation or a boundCRS. (…snip…)
* Identifier (…snip…) may also be utilised for components of these objects although this is not recommended
* except for coordinate operation methods (including map projections) and parameters. (…snip…)
* A {@code <remark>} can be included within the descriptions of source and target CRS embedded within
* a coordinate transformation as well as within the coordinate transformation itself.</blockquote>
*/
@SuppressWarnings("null")
private void appendComplement(final IdentifiedObject object, final FormattableObject parent, final FormattableObject gp) {
isComplement = true;
// Whether to format ID[…] elements.
final boolean showIDs;
// Whether we shall limit to a single ID[…] element.
final boolean filterID;
// Whether to format any element other than ID[…] and Remarks[…].
final boolean showOthers;
// Whether to format Remarks[…].
final boolean showRemarks;
if (convention == Convention.INTERNAL) {
showIDs = true;
filterID = false;
showOthers = true;
showRemarks = true;
} else {
/*
* Except for the special cases of OperationMethod and Parameters, ISO 19162 recommends to format the
* ID only for the root element. But Apache SIS adds an other exception to this rule by handling the
* components of CompoundCRS as if they were root elements. The reason is that users often create their
* own CompoundCRS from standard components, for example by adding a time axis to some standard CRS like
* "WGS84". The resulting CompoundCRS usually have no identifier. Then the users often need to extract a
* particular component of a CompoundCRS, most often the horizontal part, and will need its identifier
* for example in a Web Map Service (WMS). Those ID are lost if we do not format them here.
*/
if (parent == null || parent instanceof CompoundCRS) {
showIDs = true;
} else if (gp instanceof CoordinateOperation && !(parent instanceof IdentifiedObject)) {
// "SourceCRS[…]" and "TargetCRS[…]" sub-elements in CoordinateOperation.
showIDs = true;
} else if (convention == Convention.WKT2_SIMPLIFIED) {
showIDs = false;
} else {
showIDs = (object instanceof OperationMethod) || (object instanceof GeneralParameterDescriptor);
}
if (convention.majorVersion() == 1) {
filterID = true;
showOthers = false;
showRemarks = false;
} else {
filterID = (parent != null);
if (object instanceof CoordinateOperation) {
showOthers = !(parent instanceof ConcatenatedOperation);
showRemarks = showOthers;
} else if (object instanceof ReferenceSystem) {
showOthers = (parent == null);
showRemarks = (parent == null) || (gp instanceof CoordinateOperation);
} else {
// Mandated by ISO 19162.
showOthers = false;
showRemarks = false;
}
}
}
if (showOthers) {
appendForSubtypes(object);
}
if (showIDs) {
Collection<ReferenceIdentifier> identifiers = object.getIdentifiers();
if (identifiers != null) {
// Paranoiac check
if (filterID) {
for (final ReferenceIdentifier id : identifiers) {
if (Citations.identifierMatches(authority, id.getAuthority())) {
identifiers = Collections.singleton(id);
break;
}
}
}
for (ReferenceIdentifier id : identifiers) {
if (!(id instanceof FormattableObject)) {
id = ImmutableIdentifier.castOrCopy(id);
}
append((FormattableObject) id);
if (filterID)
break;
}
}
}
if (showRemarks) {
appendOnNewLine(WKTKeywords.Remark, object.getRemarks(), ElementKind.REMARKS);
}
isComplement = false;
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class CRSBuilder method verify.
/**
* Verifies if the user-defined conversion created from GeoTIFF values
* matches the given conversion created from the EPSG geodetic dataset.
* This method does not verify the EPSG code of the given conversion.
*
* @param projection the conversion created from the EPSG geodetic dataset.
*/
private void verify(final Conversion projection, final Unit<Angle> angularUnit, final Unit<Length> linearUnit) throws FactoryException {
final Unit<Angle> azimuthUnit = createUnit(GeoKeys.AzimuthUnits, (short) 0, Angle.class, Units.DEGREE);
final String type = getAsString(GeoKeys.CoordTrans);
if (type != null) {
/*
* Compare the name of the map projection declared in the GeoTIFF file with the name
* of the projection used by the EPSG geodetic dataset.
*/
final OperationMethod method = projection.getMethod();
if (!IdentifiedObjects.isHeuristicMatchForName(method, type)) {
Identifier expected = IdentifiedObjects.getIdentifier(method, Citations.GEOTIFF);
if (expected == null) {
expected = IdentifiedObjects.getIdentifier(method, null);
}
warning(Resources.Keys.NotTheEpsgValue_5, IdentifiedObjects.getIdentifierOrName(projection), expected.getCode(), GeoKeys.name(GeoKeys.CoordTrans), type, "");
}
/*
* Compare the parameter values with the ones declared in the EPSG geodetic dataset.
*/
final ParameterValueGroup parameters = projection.getParameterValues();
for (final short key : remainingKeys()) {
final Unit<?> unit;
switch(GeoKeys.unitOf(key)) {
case GeoKeys.RATIO:
unit = Units.UNITY;
break;
case GeoKeys.LINEAR:
unit = linearUnit;
break;
case GeoKeys.ANGULAR:
unit = angularUnit;
break;
case GeoKeys.AZIMUTH:
unit = azimuthUnit;
break;
default:
continue;
}
try {
verify(projection, parameters.parameter("GeoTIFF:" + key).doubleValue(unit), key, unit);
} catch (ParameterNotFoundException e) {
warning(Resources.Keys.UnexpectedParameter_2, type, GeoKeys.name(key));
}
}
}
}
use of org.opengis.referencing.operation.OperationMethod in project sis by apache.
the class GeoKeysTest method verifyProjectionNames.
/**
* Verifies that GeoTIFF projection aliases registered in the {@link org.apache.sis.internal.referencing.provider}
* package match the name of fields listed in {@link GeoIdentifiers} and that GeoTIFF numerical codes correspond.
* This method verifies only projection names and identifiers, not parameter names.
*/
@Test
@DependsOnMethod("testName")
public void verifyProjectionNames() {
final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
for (final OperationMethod method : factory.getAvailableMethods(SingleOperation.class)) {
final Identifier identifier = IdentifiedObjects.getIdentifier(method, Citations.GEOTIFF);
final Set<String> names = IdentifiedObjects.getNames(method, Citations.GEOTIFF);
/*
* If there is no GeoTIFF identifiers, we should have no GeoTIFF name neither.
* However we may have more than one name, since GeoTIFF defines also aliases.
*/
assertEquals(method.getName().getCode(), identifier == null, names.isEmpty());
if (identifier != null) {
final int code = Short.parseShort(identifier.getCode());
for (final String name : names) {
assertEquals(name, code, GeoIdentifiers.code(name));
}
}
}
}
Aggregations