Search in sources :

Example 16 with GeneralParameterDescriptor

use of org.opengis.parameter.GeneralParameterDescriptor 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;
}
Also used : ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) CompoundCRS(org.opengis.referencing.crs.CompoundCRS) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) CoordinateOperation(org.opengis.referencing.operation.CoordinateOperation) ConcatenatedOperation(org.opengis.referencing.operation.ConcatenatedOperation) IdentifiedObject(org.opengis.referencing.IdentifiedObject) ReferenceSystem(org.opengis.referencing.ReferenceSystem) OperationMethod(org.opengis.referencing.operation.OperationMethod)

Example 17 with GeneralParameterDescriptor

use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.

the class InverseOperationMethod method create.

/**
 * Returns or create the inverse of the given operation method. If the same operation method can be used
 * for the inverse operation either with the exact same parameter values or with the sign of some values
 * reversed, then the given method is returned as-is. Otherwise a synthetic method is created.
 */
static OperationMethod create(final OperationMethod method) {
    if (method instanceof InverseOperationMethod) {
        return ((InverseOperationMethod) method).inverse;
    }
    if (!isInvertible(method)) {
        boolean useSameParameters = false;
        for (final GeneralParameterDescriptor descriptor : method.getParameters().descriptors()) {
            useSameParameters = (descriptor.getRemarks() instanceof SignReversalComment);
            if (!useSameParameters)
                break;
        }
        if (!useSameParameters) {
            Identifier name = method.getName();
            name = new ImmutableIdentifier(null, null, "Inverse of " + name.getCode());
            final Map<String, Object> properties = new HashMap<>(6);
            properties.put(NAME_KEY, name);
            properties.put(FORMULA_KEY, method.getFormula());
            properties.put(REMARKS_KEY, method.getRemarks());
            if (method instanceof Deprecable) {
                properties.put(DEPRECATED_KEY, ((Deprecable) method).isDeprecated());
            }
            return new InverseOperationMethod(properties, method);
        }
    }
    return method;
}
Also used : ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier) Identifier(org.opengis.metadata.Identifier) HashMap(java.util.HashMap) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) SignReversalComment(org.apache.sis.internal.referencing.SignReversalComment) InternationalString(org.opengis.util.InternationalString) ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier) Deprecable(org.apache.sis.util.Deprecable)

Example 18 with GeneralParameterDescriptor

use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.

the class CC_GeneralOperationParameter method merge.

/**
 * Returns a descriptor with the given properties, completed with information not found in GML.
 * Those extra information are given by the {@code complete} descriptor.
 *
 * @param  caller         the public source class to report if a log message need to be emitted.
 * @param  properties     properties as declared in the GML document, to be used if {@code complete} is incompatible.
 * @param  merged         more complete properties, to be used if {@code complete} is compatible.
 * @param  minimumOccurs  value to assign to {@link DefaultParameterDescriptorGroup#getMinimumOccurs()}.
 * @param  maximumOccurs  value to assign to {@link DefaultParameterDescriptorGroup#getMaximumOccurs()}.
 * @param  provided       parameter descriptors declared in the GML document. This array will be overwritten.
 * @param  complete       more complete parameter descriptors.
 * @param  canSubstitute  {@code true} if this method is allowed to return {@code complete}.
 * @return the parameter descriptor group to use (may be the {@code complete} instance).
 *
 * @see <a href="http://issues.apache.org/jira/browse/SIS-290">SIS-290</a>
 */
static ParameterDescriptorGroup merge(final Class<?> caller, final Map<String, ?> properties, final Map<String, ?> merged, final int minimumOccurs, final int maximumOccurs, final GeneralParameterDescriptor[] provided, final ParameterDescriptorGroup complete, boolean canSubstitute) {
    boolean isCompatible = true;
    final Set<GeneralParameterDescriptor> included = new HashSet<>(Containers.hashMapCapacity(provided.length));
    for (int i = 0; i < provided.length; i++) {
        final GeneralParameterDescriptor p = provided[i];
        try {
            /*
                 * Replace the descriptors provided in the GML document by descriptors from the 'complete' instance,
                 * if possible. Keep trace of the complete descriptors that we found in this process.
                 */
            GeneralParameterDescriptor predefined = complete.descriptor(p.getName().getCode());
            if (predefined != null) {
                // Safety in case 'complete' is a user's implementation.
                canSubstitute &= (provided[i] = merge(p, predefined)) == predefined;
                if (!included.add(predefined)) {
                    // Broken hashCode/equals, or object mutated.
                    throw new CorruptedObjectException(predefined);
                }
                continue;
            }
        } catch (ParameterNotFoundException e) {
            /*
                 * Log at Level.WARNING for the first parameter (canSubstitute == true) and at Level.FINE
                 * for all other (canSubstitute == false).  We do not use CC_GeneralOperationParameter as
                 * the source class because this is an internal class. We rather use the first public class
                 * in the caller hierarchy, which is either DefaultParameterValueGroup or DefaultOperationMethod.
                 */
            Context.warningOccured(Context.current(), caller, (caller == DefaultParameterValueGroup.class) ? "setValues" : "setDescriptors", e, canSubstitute);
        }
        /*
             * If a parameter was not found in the 'complete' descriptor, we will not be able to use that descriptor.
             * But we may still be able to use its properties (name, alias, identifier) provided that the parameter
             * not found was optional.
             */
        isCompatible &= p.getMinimumOccurs() == 0;
        canSubstitute = false;
    }
    if (isCompatible) {
        /*
             * At this point, we determined that all mandatory parameters in the GML document exist in the 'complete'
             * descriptor. However the converse is not necessarily true. Verify that all parameters missing in the GML
             * document were optional.
             */
        for (final GeneralParameterDescriptor descriptor : complete.descriptors()) {
            if (!included.contains(descriptor) && descriptor.getMinimumOccurs() != 0 && !CC_OperationMethod.isImplicitParameter(descriptor)) {
                canSubstitute = false;
                isCompatible = false;
                break;
            }
        }
    }
    if (canSubstitute) {
        return complete;
    } else {
        return new DefaultParameterDescriptorGroup(isCompatible ? merged : properties, minimumOccurs, maximumOccurs, provided);
    }
}
Also used : DefaultParameterDescriptorGroup(org.apache.sis.parameter.DefaultParameterDescriptorGroup) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) CorruptedObjectException(org.apache.sis.util.CorruptedObjectException) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException) HashSet(java.util.HashSet)

Example 19 with GeneralParameterDescriptor

use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.

the class ParameterValueList method ensureDescriptorExists.

/**
 * Verifies the given descriptor exists in the {@link DefaultParameterDescriptorGroup#descriptors()} list.
 */
final void ensureDescriptorExists(final GeneralParameterDescriptor desc) {
    final List<GeneralParameterDescriptor> descriptors = descriptor.descriptors();
    if (!descriptors.contains(desc)) {
        /*
             * For a more accurate error message, check if the operation failed because the
             * parameter name was not found, or the parameter descriptor does not matches.
             */
        final Identifier name = desc.getName();
        final String code = name.getCode();
        for (final GeneralParameterDescriptor descriptor : descriptors) {
            if (IdentifiedObjects.isHeuristicMatchForName(descriptor, code)) {
                throw new IllegalArgumentException(Resources.format(Resources.Keys.MismatchedParameterDescriptor_1, name));
            }
        }
        throw new InvalidParameterNameException(Resources.format(Resources.Keys.ParameterNotFound_2, Verifier.getDisplayName(descriptor), name), code);
    }
}
Also used : Identifier(org.opengis.metadata.Identifier) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) InvalidParameterNameException(org.opengis.parameter.InvalidParameterNameException)

Example 20 with GeneralParameterDescriptor

use of org.opengis.parameter.GeneralParameterDescriptor in project sis by apache.

the class DefaultParameterValueGroup method groups.

/**
 * Returns all subgroups with the specified name.
 *
 * <p>This method do not create new groups: if the requested group is optional (i.e.
 * <code>{@linkplain DefaultParameterDescriptor#getMinimumOccurs() minimumOccurs} == 0</code>)
 * and no value were defined previously, then this method returns an empty set.</p>
 *
 * @param  name  the name of the parameter to search for.
 * @return the set of all parameter group for the given name.
 * @throws ParameterNotFoundException if no descriptor was found for the given name.
 */
@Override
public List<ParameterValueGroup> groups(final String name) throws ParameterNotFoundException {
    ArgumentChecks.ensureNonNull("name", name);
    // Protect against accidental changes.
    final ParameterValueList values = this.values;
    final List<ParameterValueGroup> groups = new ArrayList<>(4);
    final int size = values.size();
    for (int i = 0; i < size; i++) {
        final GeneralParameterDescriptor descriptor = values.descriptor(i);
        if (descriptor instanceof ParameterDescriptorGroup) {
            if (IdentifiedObjects.isHeuristicMatchForName(descriptor, name)) {
                groups.add((ParameterValueGroup) values.get(i));
            }
        }
    }
    /*
         * No groups were found. Check if the group actually exists (i.e. is declared in the
         * descriptor). If it doesn't exists, then an exception is thrown. If it exists (i.e.
         * it is simply an optional group not yet defined), then returns an empty list.
         */
    if (groups.isEmpty()) {
        final ParameterDescriptorGroup descriptor = values.descriptor;
        if (!(descriptor.descriptor(name) instanceof ParameterDescriptorGroup)) {
            throw new ParameterNotFoundException(Resources.format(Resources.Keys.ParameterNotFound_2, Verifier.getDisplayName(descriptor), name), name);
        }
    }
    return groups;
}
Also used : ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) ParameterDescriptorGroup(org.opengis.parameter.ParameterDescriptorGroup) ArrayList(java.util.ArrayList) GeneralParameterDescriptor(org.opengis.parameter.GeneralParameterDescriptor) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException)

Aggregations

GeneralParameterDescriptor (org.opengis.parameter.GeneralParameterDescriptor)30 ParameterDescriptorGroup (org.opengis.parameter.ParameterDescriptorGroup)12 Test (org.junit.Test)10 DefaultParameterDescriptorGroup (org.apache.sis.parameter.DefaultParameterDescriptorGroup)8 DependsOnMethod (org.apache.sis.test.DependsOnMethod)8 ParameterNotFoundException (org.opengis.parameter.ParameterNotFoundException)6 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)6 HashMap (java.util.HashMap)5 Identifier (org.opengis.metadata.Identifier)5 GeneralParameterValue (org.opengis.parameter.GeneralParameterValue)5 ParameterDescriptor (org.opengis.parameter.ParameterDescriptor)4 IdentityHashMap (java.util.IdentityHashMap)3 OperationMethod (org.opengis.referencing.operation.OperationMethod)3 ArrayList (java.util.ArrayList)2 DefaultParameterValueGroup (org.apache.sis.parameter.DefaultParameterValueGroup)2 CorruptedObjectException (org.apache.sis.util.CorruptedObjectException)2 InvalidParameterNameException (org.opengis.parameter.InvalidParameterNameException)2 ParameterValue (org.opengis.parameter.ParameterValue)2 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1