Search in sources :

Example 36 with Identifier

use of org.opengis.metadata.Identifier in project sis by apache.

the class ModifiableIdentifierMap method setHRef.

/**
 * Sets the {@code xlink:href} value, which may be null. If an explicit {@code xlink:href} identifier exists,
 * then it will removed before to set the new {@code href} in the {@link XLink} object. The intent is to give
 * precedence to the {@link XLink#getHRef()} property in every cases where the {@code href} is parsable as a
 * {@link URI}, and use the value associated to the {@code HREF} key only as a fallback when the string can not
 * be parsed.
 *
 * @param  href  the new value, or {@code null} for removing the value.
 * @return the previous value, or {@code null} if none.
 *
 * @see #getHRef()
 */
private URI setHRef(final URI href) {
    URI old = store(IdentifierSpace.HREF, null);
    final Identifier identifier = getIdentifier(IdentifierSpace.XLINK);
    if (identifier instanceof SpecializedIdentifier<?>) {
        final Object link = ((SpecializedIdentifier<?>) identifier).value;
        if (link instanceof XLink) {
            if (old == null) {
                old = ((XLink) link).getHRef();
            }
            ((XLink) link).setHRef(href);
            return old;
        }
    }
    if (href != null) {
        final XLink link = new XLink();
        link.setHRef(href);
        store(IdentifierSpace.XLINK, link);
    }
    return old;
}
Also used : Identifier(org.opengis.metadata.Identifier) URI(java.net.URI) XLink(org.apache.sis.xml.XLink)

Example 37 with Identifier

use of org.opengis.metadata.Identifier in project sis by apache.

the class NonMarshalledAuthority method filterOnMarshalling.

/**
 * If marshalling, filters the given collection of identifiers in order to omit any identifiers
 * for which the authority is an instance of {@code NonMarshalledAuthority}. This should exclude
 * all {@link org.apache.sis.xml.IdentifierSpace} constants.
 *
 * <p>This method is used for implementation of {@code getIdentifiers()} methods (plural form)
 * in public metadata objects. Note that those methods override
 * {@link org.apache.sis.xml.IdentifiedObject#getIdentifiers()}, which is expected to return
 * all identifiers in normal (non-marshalling) usage.</p>
 *
 * @param  identifiers  the identifiers to filter, or {@code null}.
 * @return the identifiers to marshal, or {@code null} if none.
 */
public static Collection<Identifier> filterOnMarshalling(Collection<Identifier> identifiers) {
    if (identifiers != null && Context.isFlagSet(Context.current(), Context.MARSHALLING)) {
        int count = identifiers.size();
        if (count != 0) {
            final Identifier[] copy = identifiers.toArray(new Identifier[count]);
            for (int i = count; --i >= 0; ) {
                final Identifier id = copy[i];
                if (id == null || (id.getAuthority() instanceof NonMarshalledAuthority)) {
                    System.arraycopy(copy, i + 1, copy, i, --count - i);
                }
            }
            identifiers = (count != 0) ? UnmodifiableArrayList.wrap(copy, 0, count) : null;
        }
    }
    return identifiers;
}
Also used : Identifier(org.opengis.metadata.Identifier)

Example 38 with Identifier

use of org.opengis.metadata.Identifier in project sis by apache.

the class Formatter method setInvalidWKT.

/**
 * Marks the current WKT representation of the given object as not strictly compliant with the WKT specification.
 * This method can be invoked by implementations of {@link FormattableObject#formatTo(Formatter)} when the object
 * to format is more complex than what the WKT specification allows.
 * Applications can test {@link #isInvalidWKT()} later for checking WKT validity.
 *
 * @param  unformattable  the object that can not be formatted,
 * @param  cause  the cause for the failure to format, or {@code null} if the cause is not an exception.
 */
public void setInvalidWKT(final IdentifiedObject unformattable, final Exception cause) {
    ArgumentChecks.ensureNonNull("unformattable", unformattable);
    String name;
    final Identifier id = unformattable.getName();
    if (id == null || (name = id.getCode()) == null) {
        name = getName(unformattable.getClass());
    }
    setInvalidWKT(name, cause);
}
Also used : ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) Identifier(org.opengis.metadata.Identifier) InternationalString(org.opengis.util.InternationalString)

Example 39 with Identifier

use of org.opengis.metadata.Identifier in project sis by apache.

the class GeodeticObjectParser method parseMetadataAndClose.

/**
 * Parses an <strong>optional</strong> metadata elements and close.
 * This include elements like {@code "SCOPE"}, {@code "ID"} (WKT 2) or {@code "AUTHORITY"} (WKT 1).
 * This WKT 1 element has the following pattern:
 *
 * {@preformat wkt
 *     AUTHORITY["<name>", "<code>"]
 * }
 *
 * <div class="section">Fallback</div>
 * The name is a mandatory property, but some invalid WKT with an empty string exist. In such case,
 * we will use the name of the enclosed datum. Indeed, it is not uncommon to have the same name for
 * a geographic CRS and its geodetic datum.
 *
 * @param  parent    the parent element.
 * @param  name      the name of the parent object being parsed.
 * @param  fallback  the fallback to use if {@code name} is empty.
 * @return a properties map with the parent name and the optional authority code.
 * @throws ParseException if an element can not be parsed.
 */
@SuppressWarnings("ReturnOfCollectionOrArrayField")
private Map<String, Object> parseMetadataAndClose(final Element parent, final String name, final IdentifiedObject fallback) throws ParseException {
    properties.clear();
    properties.put(IdentifiedObject.NAME_KEY, (name.isEmpty() && fallback != null) ? fallback.getName() : name);
    Element element;
    while ((element = parent.pullElement(OPTIONAL, ID_KEYWORDS)) != null) {
        final String codeSpace = element.pullString("codeSpace");
        // Accepts Integer as well as String.
        final String code = element.pullObject("code").toString();
        // Accepts Number as well as String.
        final Object version = element.pullOptional(Object.class);
        final Element citation = element.pullElement(OPTIONAL, WKTKeywords.Citation);
        final String authority;
        if (citation != null) {
            authority = citation.pullString("authority");
            citation.close(ignoredElements);
        } else {
            authority = codeSpace;
        }
        final Element uri = element.pullElement(OPTIONAL, WKTKeywords.URI);
        if (uri != null) {
            // TODO: not yet stored, since often redundant with other informations.
            uri.pullString("URI");
            uri.close(ignoredElements);
        }
        element.close(ignoredElements);
        /*
             * Note: we could be tempted to assign the authority to the name as well, like below:
             *
             *     if (name instanceof String) {
             *         name = new NamedIdentifier(authority, (String) name);
             *     }
             *     properties.put(IdentifiedObject.NAME_KEY, name);
             *
             * However experience shows that it is often wrong in practice, because peoples often
             * declare EPSG codes but still use WKT names much shorter than the EPSG names
             * (for example "WGS84" for the datum instead than "World Geodetic System 1984"),
             * so the name in WKT is often not compliant with the name actually defined by the authority.
             */
        final ImmutableIdentifier id = new ImmutableIdentifier(Citations.fromName(authority), codeSpace, code, (version != null) ? version.toString() : null, null);
        final Object previous = properties.put(IdentifiedObject.IDENTIFIERS_KEY, id);
        if (previous != null) {
            Identifier[] identifiers;
            if (previous instanceof Identifier) {
                identifiers = new Identifier[] { (Identifier) previous, id };
            } else {
                identifiers = (Identifier[]) previous;
                final int n = identifiers.length;
                identifiers = Arrays.copyOf(identifiers, n + 1);
                identifiers[n] = id;
            }
            properties.put(IdentifiedObject.IDENTIFIERS_KEY, identifiers);
        // REMINDER: values associated to IDENTIFIERS_KEY shall be recognized by 'toIdentifier(Object)'.
        }
    }
    /*
         * Other metadata (SCOPE, AREA, etc.).  ISO 19162 said that at most one of each type shall be present,
         * but our parser accepts an arbitrary amount of some kinds of metadata. They can be recognized by the
         * 'while' loop.
         *
         * Most WKT do not contain any of those metadata, so we perform an 'isEmpty()' check as an optimization
         * for those common cases.
         */
    if (!parent.isEmpty()) {
        /*
             * Example: SCOPE["Large scale topographic mapping and cadastre."]
             */
        element = parent.pullElement(OPTIONAL, WKTKeywords.Scope);
        if (element != null) {
            // Other types like Datum use the same key.
            properties.put(ReferenceSystem.SCOPE_KEY, element.pullString("scope"));
            element.close(ignoredElements);
        }
        /*
             * Example: AREA["Netherlands offshore."]
             */
        DefaultExtent extent = null;
        while ((element = parent.pullElement(OPTIONAL, WKTKeywords.Area)) != null) {
            final String area = element.pullString("area");
            element.close(ignoredElements);
            if (extent == null) {
                extent = new DefaultExtent(area, null, null, null);
            } else {
                extent.getGeographicElements().add(new DefaultGeographicDescription(area));
            }
        }
        /*
             * Example: BBOX[51.43, 2.54, 55.77, 6.40]
             */
        while ((element = parent.pullElement(OPTIONAL, WKTKeywords.BBox)) != null) {
            final double southBoundLatitude = element.pullDouble("southBoundLatitude");
            final double westBoundLongitude = element.pullDouble("westBoundLongitude");
            final double northBoundLatitude = element.pullDouble("northBoundLatitude");
            final double eastBoundLongitude = element.pullDouble("eastBoundLongitude");
            element.close(ignoredElements);
            if (extent == null)
                extent = new DefaultExtent();
            extent.getGeographicElements().add(new DefaultGeographicBoundingBox(westBoundLongitude, eastBoundLongitude, southBoundLatitude, northBoundLatitude));
        }
        /*
             * Example: VERTICALEXTENT[-1000, 0, LENGTHUNIT[“metre”, 1]]
             *
             * Units are optional, default to metres (no "contextual units" here).
             */
        while ((element = parent.pullElement(OPTIONAL, WKTKeywords.VerticalExtent)) != null) {
            final double minimum = element.pullDouble("minimum");
            final double maximum = element.pullDouble("maximum");
            Unit<Length> unit = parseScaledUnit(element, WKTKeywords.LengthUnit, Units.METRE);
            element.close(ignoredElements);
            if (unit == null)
                unit = Units.METRE;
            if (extent == null)
                extent = new DefaultExtent();
            verticalElements = new VerticalInfo(verticalElements, extent, minimum, maximum, unit).resolve(verticalCRS);
        }
        /*
             * Example: TIMEEXTENT[2013-01-01, 2013-12-31]
             *
             * TODO: syntax like TIMEEXTENT[“Jurassic”, “Quaternary”] is not yet supported.
             * See https://issues.apache.org/jira/browse/SIS-163
             *
             * This operation requires the the sis-temporal module. If not available,
             * we will report a warning and leave the temporal extent missing.
             */
        while ((element = parent.pullElement(OPTIONAL, WKTKeywords.TimeExtent)) != null) {
            if (element.peekValue() instanceof String) {
                element.pullString("startTime");
                element.pullString("endTime");
                element.close(ignoredElements);
                warning(parent, element, Errors.formatInternational(Errors.Keys.UnsupportedType_1, "TimeExtent[String,String]"), null);
            } else {
                final Date startTime = element.pullDate("startTime");
                final Date endTime = element.pullDate("endTime");
                element.close(ignoredElements);
                try {
                    final DefaultTemporalExtent t = new DefaultTemporalExtent();
                    t.setBounds(startTime, endTime);
                    if (extent == null)
                        extent = new DefaultExtent();
                    extent.getTemporalElements().add(t);
                } catch (UnsupportedOperationException e) {
                    warning(parent, element, null, e);
                }
            }
        }
        if (extent != null) {
            properties.put(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY, extent);
        }
        /*
             * Example: REMARK["Замечание на русском языке"]
             */
        element = parent.pullElement(OPTIONAL, WKTKeywords.Remark);
        if (element != null) {
            properties.put(IdentifiedObject.REMARKS_KEY, element.pullString("remarks"));
            element.close(ignoredElements);
        }
    }
    parent.close(ignoredElements);
    return properties;
}
Also used : Date(java.util.Date) DefaultGeographicDescription(org.apache.sis.metadata.iso.extent.DefaultGeographicDescription) ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) Identifier(org.opengis.metadata.Identifier) DefaultGeographicBoundingBox(org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox) DefaultExtent(org.apache.sis.metadata.iso.extent.DefaultExtent) Length(javax.measure.quantity.Length) DefaultTemporalExtent(org.apache.sis.metadata.iso.extent.DefaultTemporalExtent) IdentifiedObject(org.opengis.referencing.IdentifiedObject) ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier)

Example 40 with Identifier

use of org.opengis.metadata.Identifier in project sis by apache.

the class Builder method reidentify.

/**
 * Replaces the identifiers associated to the given authority by the given new identifiers.
 * More specifically:
 *
 * <ul>
 *   <li>The first occurrence of an identifier associated to {@code authority} will be replaced by
 *       a new identifier with the same authority and the code defined by {@code replacements[0]}.</li>
 *   <li>The second occurrence of an identifier associated to {@code authority} will be replaced by a
 *       new identifier with the same authority and the local part defined by {@code replacements[1]}.</li>
 *   <li><i>etc.</i> until one of the following conditions is meet:
 *     <ul>
 *       <li>There is no more identifier associated to the given authority in this {@code Builder}, in which case
 *           new identifiers are inserted for all remaining elements in the {@code replacements} array.</li>
 *       <li>There is no more elements in the {@code replacements} array, in which case all remaining
 *           identifiers associated to the given authority in this {@code Builder} are removed.</li>
 *     </ul>
 *   </li>
 * </ul>
 *
 * This method could also be understood as a {@code setIdentifiers(Citation, ...)} method, except that it modifies
 * only the identifiers associated to the given authority and preserves the same order than previous identifiers.
 *
 * @param  authority     the authority of the names to replaces.
 * @param  replacements  the new local parts for the names to replace,
 *         or {@code null} or an empty array for removing all names associated to the given authority.
 * @return {@code this}, for method call chaining.
 *
 * @since 0.8
 */
public B reidentify(final Citation authority, final String... replacements) {
    ensureNonNull("authority", authority);
    final int length = (replacements != null) ? replacements.length : 0;
    int next = 0;
    int insertAt = identifiers.size();
    for (int i = 0; i < identifiers.size(); i++) {
        final Identifier old = identifiers.get(i);
        if (authority.equals(old.getAuthority())) {
            if (next < length) {
                final String code;
                ensureNonNullElement("replacements", next, code = replacements[next++]);
                if (!code.equals(old.getCode())) {
                    identifiers.set(i, createIdentifier(authority, code));
                    insertAt = i + 1;
                }
            } else {
                identifiers.remove(i--);
            }
        }
    }
    while (next < length) {
        final String code;
        ensureNonNullElement("replacements", next, code = replacements[next++]);
        identifiers.add(insertAt++, createIdentifier(authority, code));
    }
    return self();
}
Also used : ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier) Identifier(org.opengis.metadata.Identifier) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) InternationalString(org.opengis.util.InternationalString)

Aggregations

Identifier (org.opengis.metadata.Identifier)60 ReferenceIdentifier (org.opengis.referencing.ReferenceIdentifier)21 Test (org.junit.Test)14 ImmutableIdentifier (org.apache.sis.metadata.iso.ImmutableIdentifier)11 Citation (org.opengis.metadata.citation.Citation)10 IdentifiedObject (org.opengis.referencing.IdentifiedObject)10 InternationalString (org.opengis.util.InternationalString)10 ArrayList (java.util.ArrayList)8 HashMap (java.util.HashMap)6 DefaultIdentifier (org.apache.sis.metadata.iso.DefaultIdentifier)6 IdentifierMap (org.apache.sis.xml.IdentifierMap)6 GeneralParameterDescriptor (org.opengis.parameter.GeneralParameterDescriptor)5 OperationMethod (org.opengis.referencing.operation.OperationMethod)5 NameToIdentifier (org.apache.sis.internal.metadata.NameToIdentifier)4 NamedIdentifier (org.apache.sis.referencing.NamedIdentifier)4 GenericName (org.opengis.util.GenericName)4 URI (java.net.URI)3 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)3 IdentityHashMap (java.util.IdentityHashMap)2 LinkedHashMap (java.util.LinkedHashMap)2