001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2004-2024 Open Geospatial Consortium, Inc.
004 *    http://www.geoapi.org
005 *
006 *    Licensed under the Apache License, Version 2.0 (the "License");
007 *    you may not use this file except in compliance with the License.
008 *    You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *    Unless required by applicable law or agreed to in writing, software
013 *    distributed under the License is distributed on an "AS IS" BASIS,
014 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 *    See the License for the specific language governing permissions and
016 *    limitations under the License.
017 */
018package org.opengis.metadata.quality;
019
020import java.util.Date;
021import java.util.Iterator;
022import java.util.Collection;
023import java.util.Collections;
024import java.util.AbstractCollection;
025import java.time.temporal.Temporal;
026import org.opengis.metadata.Identifier;
027import org.opengis.metadata.citation.Citation;
028import org.opengis.util.InternationalString;
029import org.opengis.geoapi.internal.Legacy;
030import org.opengis.annotation.Classifier;
031import org.opengis.annotation.Stereotype;
032import org.opengis.annotation.UML;
033
034import static org.opengis.annotation.Obligation.*;
035import static org.opengis.annotation.Specification.*;
036
037
038/**
039 * Aspect of quantitative quality information.
040 * A data quality element is a component describing a certain aspect of the quality of geographic data.
041 * An evaluation of a data quality element is described by the following:
042 * <ul>
043 *   <li>{@linkplain #getMeasureReference() Measure}: the type of evaluation;</li>
044 *   <li>{@linkplain #getEvaluationMethod() Evaluation method}: the procedure used to evaluate the measure;</li>
045 *   <li>{@linkplain #getResults() Result:} the output of the evaluation.</li>
046 * </ul>
047 *
048 * Elements are organized into different categories, which are identified by the following subtypes:
049 * {@link Completeness}, {@link LogicalConsistency}, {@link PositionalAccuracy}, {@link TemporalQuality},
050 * {@link ThematicAccuracy}, or {@link Metaquality}.
051 *
052 * @author  Martin Desruisseaux (IRD)
053 * @author  Cory Horner (Refractions Research)
054 * @author  Alexis Gaillard (Geomatys)
055 * @version 3.1
056 * @since   2.0
057 *
058 * @todo Renamed in 19157:2022: {@code QualityElement}.
059 */
060@Classifier(Stereotype.ABSTRACT)
061@UML(identifier="DQ_Element", specification=ISO_19157)
062public interface Element {
063    /**
064     * Clause in the standalone quality report where this data quality element is described.
065     * May apply to any related data quality element (original results in case of derivation or aggregation).
066     *
067     * @return clause where this data quality element is described, or {@code null} if none.
068     *
069     * @since 3.1
070     *
071     * @todo Renamed in 19157:2022: {@code QualityEvaluationReportDetails}.
072     */
073    @UML(identifier="standaloneQualityReportDetails", obligation=OPTIONAL, specification=ISO_19157)
074    default InternationalString getStandaloneQualityReportDetails() {
075        return null;
076    }
077
078    /**
079     * Full description of a data quality measure.
080     *
081     * @departure easeOfUse
082     *   This method is not part of ISO 19157 specification.
083     *   Instead, the standard provides only a {@link MeasureReference}
084     *   that clients can use for finding the full measure description in a measure register or catalogue.
085     *   Because Java interfaces can execute code (as opposed to static data encoded in XML or JSON documents),
086     *   implementers are free to do themselves the work of fetching this information from an external source
087     *   when {@code getMeasure()} is invoked. This method is added in the {@link Element} interface for making
088     *   that feature possible. This is an optional feature; implementers can ignore this method and implement
089     *   only the {@link #getMeasureReference()} method.
090     *
091     * @return a measure of data quality, or {@code null} if none.
092     *
093     * @since 3.1
094     */
095    default Measure getMeasure() {
096        return null;
097    }
098
099    /**
100     * Identifier of a measure fully described elsewhere.
101     * The full description is given by {@link #getMeasure()},
102     * but that description may not be available to this {@code Element}.
103     * Instead, the whole description may be found within a measure register or catalogue,
104     * in which case this reference can be used for finding the whole description.
105     *
106     * <p>If a full measure is {@linkplain #getMeasure() contained in this element},
107     * then by default this method returns the {@linkplain Measure#getName() name},
108     * {@linkplain Measure#getMeasureIdentifier() identifier} and
109     * {@linkplain Measure#getDefinition() definition} of that measure.</p>
110     *
111     * @departure rename
112     *   The ISO 19157 property name is {@code measure}.
113     *   This is renamed {@code measureReference} in GeoAPI for reflecting the return type
114     *   and for making room for a {@code measure} property for the full {@link Measure} description.
115     *
116     * @return reference to the measure used, or {@code null} if none.
117     *
118     * @since 3.1
119     */
120    @UML(identifier="measure", obligation=OPTIONAL, specification=ISO_19157)
121    default MeasureReference getMeasureReference() {
122        final Measure measure = getMeasure();
123        return (measure == null) ? null : new MeasureInstanceReference(measure);
124    }
125
126    /**
127     * Name of the test applied to the data.
128     *
129     * @return name of the test applied to the data.
130     *
131     * @deprecated Replaced by {@link MeasureReference#getNamesOfMeasure()}.
132     */
133    @Deprecated(since="3.1")
134    @UML(identifier="nameOfMeasure", obligation=OPTIONAL, specification=ISO_19115, version=2003)
135    default Collection<? extends InternationalString> getNamesOfMeasure() {
136        final MeasureReference ref = getMeasureReference();
137        return (ref != null) ? ref.getNamesOfMeasure() : Collections.emptyList();
138    }
139
140    /**
141     * Code identifying a registered standard procedure, or {@code null} if none.
142     *
143     * @return code identifying a registered standard procedure, or {@code null}.
144     *
145     * @deprecated Replaced by {@link MeasureReference#getMeasureIdentification()}.
146     */
147    @Deprecated(since="3.1")
148    @UML(identifier="measureIdentification", obligation=OPTIONAL, specification=ISO_19115, version=2003)
149    default Identifier getMeasureIdentification() {
150        final MeasureReference ref = getMeasureReference();
151        return (ref != null) ? ref.getMeasureIdentification() : null;
152    }
153
154    /**
155     * Description of the measure being determined.
156     *
157     * @return description of the measure being determined, or {@code null}.
158     *
159     * @deprecated Replaced by {@link MeasureReference#getMeasureDescription()}.
160     */
161    @Deprecated(since="3.1")
162    @UML(identifier="measureDescription", obligation=OPTIONAL, specification=ISO_19115, version=2003)
163    default InternationalString getMeasureDescription() {
164        final MeasureReference ref = getMeasureReference();
165        return (ref != null) ? ref.getMeasureDescription() : null;
166    }
167
168    /**
169     * Evaluation information.
170     *
171     * @return information about the evaluation method, or {@code null} if none.
172     *
173     * @since 3.1
174     */
175    @UML(identifier="evaluationMethod", obligation=OPTIONAL, specification=ISO_19157)
176    default EvaluationMethod getEvaluationMethod() {
177        return null;
178    }
179
180    /**
181     * Type of method used to evaluate quality of the dataset.
182     *
183     * @return type of method used to evaluate quality, or {@code null}.
184     *
185     * @deprecated Replaced by {@link EvaluationMethod#getEvaluationMethodType()}.
186     */
187    @Deprecated(since="3.1")
188    @UML(identifier="evaluationMethodType", obligation=OPTIONAL, specification=ISO_19115, version=2003)
189    default EvaluationMethodType getEvaluationMethodType() {
190        final EvaluationMethod ref = getEvaluationMethod();
191        return (ref != null) ? ref.getEvaluationMethodType() : null;
192    }
193
194    /**
195     * Description of the evaluation method.
196     *
197     * @return description of the evaluation method, or {@code null}.
198     *
199     * @deprecated Replaced by {@link EvaluationMethod#getEvaluationMethodDescription()}.
200     */
201    @Deprecated(since="3.1")
202    @UML(identifier="evaluationMethodDescription", obligation=OPTIONAL, specification=ISO_19115, version=2003)
203    default InternationalString getEvaluationMethodDescription() {
204        final EvaluationMethod ref = getEvaluationMethod();
205        return (ref != null) ? ref.getEvaluationMethodDescription() : null;
206    }
207
208    /**
209     * Reference to the procedure information, or {@code null} if none.
210     *
211     * @return reference to the procedure information, or {@code null}.
212     *
213     * @deprecated Replaced by {@link EvaluationMethod#getEvaluationProcedure()}.
214     */
215    @Deprecated(since="3.1")
216    @UML(identifier="evaluationProcedure", obligation=OPTIONAL, specification=ISO_19115, version=2003)
217    default Citation getEvaluationProcedure() {
218        final EvaluationMethod ref = getEvaluationMethod();
219        return (ref != null) ? ref.getEvaluationProcedure() : null;
220    }
221
222    /**
223     * Date or range of dates on which a data quality measure was applied.
224     * The collection size is 1 for a single date, or 2 for a range.
225     * Returns an empty collection if this information is not available.
226     *
227     * <p>The default implementation returns a wrapper around @link EvaluationMethod#getDates()} collection.
228     * Calls to {@link Iterator#next()} may throw {@link java.time.DateTimeException} if the temporal object
229     * cannot be converted to a date.</p>
230     *
231     * @return date or range of dates on which a data quality measure was applied.
232     *
233     * @deprecated Replaced by {@link EvaluationMethod#getDates()}.
234     */
235    @Deprecated(since="3.1")
236    @UML(identifier="dateTime", obligation=OPTIONAL, specification=ISO_19115, version=2003)
237    default Collection<? extends Date> getDates() {
238        return new AbstractCollection<Date>() {
239            @Override public int size() {
240                final EvaluationMethod ref = getEvaluationMethod();
241                return (ref != null) ? ref.getDates().size() : 0;
242            }
243
244            @Override public Iterator<Date> iterator() {
245                final EvaluationMethod ref = getEvaluationMethod();
246                if (ref == null) {
247                    return Collections.emptyIterator();
248                }
249                final Iterator<? extends Temporal> it = ref.getDates().iterator();
250                return new Iterator<Date>() {
251                    @Override public void    remove()  {it.remove();}
252                    @Override public boolean hasNext() {return it.hasNext();}
253                    @Override public Date    next()    {return Legacy.toDate(it.next());}
254                };
255            }
256        };
257    }
258
259    /**
260     * Value (or set of values) obtained from applying a data quality measure.
261     * May be an outcome of evaluating the obtained value (or set of values)
262     * against a specified acceptable conformance quality level.
263     *
264     * @return set of values obtained from applying a data quality measure.
265     */
266    @UML(identifier="result", obligation=MANDATORY, specification=ISO_19157)
267    Collection<? extends Result> getResults();
268
269    /**
270     * In case of aggregation or derivation, indicates the original elements.
271     *
272     * @return original element(s) when there is an aggregation or derivation.
273     *
274     * @since 3.1
275     */
276    @UML(identifier="derivedElement", obligation=OPTIONAL, specification=ISO_19157)
277    default Collection<? extends Element> getDerivedElements() {
278        return Collections.emptyList();
279    }
280}