use of org.opengis.referencing.ReferenceIdentifier 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.ReferenceIdentifier in project sis by apache.
the class GeodeticObjectParser method parseMethod.
/**
* Parses a {@code "Method"} (WKT 2) element, without the parameters.
*
* @param parent the parent element.
* @param keywords the element keywords.
* @return the operation method.
* @throws ParseException if the {@code "Method"} element can not be parsed.
*/
private OperationMethod parseMethod(final Element parent, final String... keywords) throws ParseException {
final Element element = parent.pullElement(MANDATORY, keywords);
final String name = element.pullString("method");
Map<String, ?> properties = parseMetadataAndClose(element, name, null);
// See NOTE 2 in parseDerivingConversion.
final Identifier id = toIdentifier(properties.remove(IdentifiedObject.IDENTIFIERS_KEY));
/*
* The map projection method may be specified by an EPSG identifier (or any other authority),
* which is preferred to the method name since the later is potentially ambiguous. However not
* all CoordinateOperationFactory may accept identifier as an argument to 'getOperationMethod'.
* So if an identifier is present, we will try to use it but fallback on the name if we can
* not use the identifier.
*/
FactoryException suppressed = null;
if (id instanceof ReferenceIdentifier)
try {
// CodeSpace is a mandatory attribute in ID[…] elements, so we do not test for null values.
return referencing.getOperationMethod(opFactory, mtFactory, ((ReferenceIdentifier) id).getCodeSpace() + DefaultNameSpace.DEFAULT_SEPARATOR + id.getCode());
} catch (FactoryException e) {
suppressed = e;
}
try {
return referencing.getOperationMethod(opFactory, mtFactory, name);
} catch (FactoryException e) {
if (suppressed != null) {
e.addSuppressed(suppressed);
}
throw element.parseFailed(e);
}
}
use of org.opengis.referencing.ReferenceIdentifier in project sis by apache.
the class AbstractIdentifiedObjectTest method testWithSingleIdentifier.
/**
* Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor
* with only one identifier. The methods of interest for this test are:
*
* <ul>
* <li>{@link AbstractIdentifiedObject#getIdentifiers()}</li>
* <li>{@link AbstractIdentifiedObject#getIdentifier()}</li>
* <li>{@link AbstractIdentifiedObject#getID()}</li>
* </ul>
*/
@Test
@DependsOnMethod("testWithoutIdentifier")
public void testWithSingleIdentifier() {
final ReferenceIdentifier identifier = new ImmutableIdentifier(null, "EPSG", "7019");
final Set<ReferenceIdentifier> identifiers = Collections.singleton(identifier);
final AbstractIdentifiedObject object = new AbstractIdentifiedObject(properties(identifiers));
final ReferenceIdentifier gmlId = validate(object, identifiers, "epsg-7019");
assertNotNull("gmlId", gmlId);
assertEquals("gmlId.codespace", "EPSG", gmlId.getCodeSpace());
assertEquals("gmlId.code", "7019", gmlId.getCode());
}
use of org.opengis.referencing.ReferenceIdentifier in project sis by apache.
the class CodeTest method testForIdentifiedObject.
/**
* Tests {@link Code#forIdentifiedObject(Class, Iterable)}.
*/
@Test
@DependsOnMethod("testWithVersion")
public void testForIdentifiedObject() {
final ReferenceIdentifier id = new ImmutableIdentifier(Citations.EPSG, "EPSG", "4326", "8.2", null);
final Code value = Code.forIdentifiedObject(GeographicCRS.class, Collections.singleton(id));
assertNotNull(value);
assertEquals("codeSpace", Constants.IOGP, value.codeSpace);
assertEquals("code", "urn:ogc:def:crs:EPSG:8.2:4326", value.code);
}
use of org.opengis.referencing.ReferenceIdentifier in project sis by apache.
the class CodeTest method testSimple.
/**
* Tests the {@link Code#Code(ReferenceIdentifier)} constructor with {@code "EPSG:4326"} identifier.
* This test intentionally uses an identifier with the {@code IOGP} authority instead than
* EPSG in order to make sure that the {@code codeSpace} attribute is set from
* {@code Identifier.getCodeSpace()}, not from {@code Identifier.getAuthority()}.
*/
@Test
public void testSimple() {
final SimpleCitation IOGP = new SimpleCitation("IOGP");
// See above javadoc.
final ReferenceIdentifier id = new ImmutableIdentifier(IOGP, "EPSG", "4326");
final Code value = new Code(id);
assertEquals("codeSpace", "EPSG", value.codeSpace);
assertEquals("code", "4326", value.code);
/*
* Reverse operation. Note that the authority is lost since there is no room for that in a
* <gml:identifier> element. Current implementation sets the authority to the code space.
*/
final ReferenceIdentifier actual = value.getIdentifier();
assertSame("authority", Citations.EPSG, actual.getAuthority());
assertEquals("codeSpace", "EPSG", actual.getCodeSpace());
assertNull("version", actual.getVersion());
assertEquals("code", "4326", actual.getCode());
}
Aggregations