This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 3ce6fb642bb95199cd8e785487cf37648bd2cccd Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Jul 18 18:51:11 2024 +0200 Determine the accuracy of a coordinate operation through datum ensemble. The method added in this commit still need to be used by `CoordinateOperationFinder`. --- endorsed/build.gradle.kts | 3 + .../iso/quality/DefaultEvaluationMethod.java | 16 ++- .../iso/quality/DefaultMeasureReference.java | 14 +- .../{internal => privy}/RecordSchemaSIS.java | 5 +- .../sis/metadata/privy/TransformationAccuracy.java | 90 ------------- .../org/apache/sis/util/iso/DefaultRecord.java | 2 +- .../org/apache/sis/util/iso/DefaultRecordType.java | 2 +- .../iso/quality/DefaultQuantitativeResultTest.java | 2 +- .../sis/openoffice/ReferencingFunctionsTest.java | 2 +- .../apache/sis/io/wkt/GeodeticObjectParser.java | 4 +- .../main/org/apache/sis/referencing/CRS.java | 2 +- .../main/org/apache/sis/referencing/CommonCRS.java | 10 +- .../sis/referencing/MultiRegisterOperations.java | 10 +- .../referencing/datum/DefaultDatumEnsemble.java | 4 +- .../apache/sis/referencing/datum/PseudoDatum.java | 132 ++++++++++++++++--- .../referencing/factory/sql/EPSGDataAccess.java | 42 +++--- .../sis/referencing/internal/AnnotatedMatrix.java | 1 - .../PositionalAccuracyConstant.java | 144 +++++++++++++++------ .../apache/sis/referencing/internal/Resources.java | 10 ++ .../sis/referencing/internal/Resources.properties | 4 +- .../referencing/internal/Resources_fr.properties | 4 +- .../operation/AbstractCoordinateOperation.java | 2 +- .../operation/CoordinateOperationContext.java | 2 +- .../operation/CoordinateOperationRegistry.java | 6 +- .../operation/DefaultConcatenatedOperation.java | 2 +- .../referencing/privy/ReferencingUtilities.java | 24 ---- .../datum/DefaultGeodeticDatumTest.java | 2 +- .../internal/PositionalAccuracyConstantTest.java | 111 ++++++++++++++++ .../operation/CoordinateOperationFinderTest.java | 4 +- .../DefaultCoordinateOperationFactoryTest.java | 2 +- .../privy/PositionalAccuracyConstantTest.java | 68 ---------- .../sis/util/collection/WeakValueHashMap.java | 24 ++++ netbeans-project/nbproject/project.properties | 1 + 33 files changed, 456 insertions(+), 295 deletions(-) diff --git a/endorsed/build.gradle.kts b/endorsed/build.gradle.kts index 0872b955bd..c4252f8581 100644 --- a/endorsed/build.gradle.kts +++ b/endorsed/build.gradle.kts @@ -175,6 +175,9 @@ fun addExportForTests(args : MutableList<String>) { addExport(args, "org.apache.sis.metadata", "org.apache.sis.xml.bind.gcx", "org.apache.sis.referencing") + addExport(args, "org.apache.sis.referencing", "org.apache.sis.referencing.internal", + "org.apache.sis.openoffice") + addExport(args, "org.apache.sis.feature", "org.apache.sis.feature.privy", "org.apache.sis.storage.sql") diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultEvaluationMethod.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultEvaluationMethod.java index 2d5f6c2e8f..256a17165b 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultEvaluationMethod.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultEvaluationMethod.java @@ -30,6 +30,7 @@ import org.opengis.util.InternationalString; import org.opengis.metadata.citation.Citation; import org.opengis.metadata.quality.EvaluationMethodType; import org.apache.sis.system.Semaphores; +import org.apache.sis.util.iso.Types; import org.apache.sis.util.privy.CloneAccess; import org.apache.sis.util.collection.CheckedContainer; import org.apache.sis.util.resources.Errors; @@ -57,7 +58,7 @@ import org.opengis.metadata.quality.AggregationDerivation; * * @author Alexis Gaillard (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.4 + * @version 1.5 * @since 1.3 */ @XmlType(name = "DQ_EvaluationMethod_Type", propOrder = { @@ -274,6 +275,19 @@ public class DefaultEvaluationMethod extends ISOMetadata implements EvaluationMe public DefaultEvaluationMethod() { } + /** + * Constructs an evaluation method initialized to the given description. + * + * @param type the method type, or {@code null} if none. + * @param name the method description as a {@link String} or an {@link InternationalString} object, + * or {@code null} if none. + * @since 1.5 + */ + public DefaultEvaluationMethod(final EvaluationMethodType type, final CharSequence description) { + evaluationMethodType = type; + evaluationMethodDescription = Types.toInternationalString(description); + } + /** * Constructs a new instance initialized with the values from the specified metadata object. * This is a <em>shallow</em> copy constructor, because the other metadata contained in the diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultMeasureReference.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultMeasureReference.java index f540568839..cfd4a3e88c 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultMeasureReference.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/quality/DefaultMeasureReference.java @@ -24,6 +24,7 @@ import org.opengis.util.InternationalString; import org.opengis.metadata.Identifier; import org.opengis.metadata.quality.Element; import org.apache.sis.util.privy.CollectionsExt; +import org.apache.sis.util.iso.Types; // Specific to the geoapi-3.1 and geoapi-4.0 branches: import org.opengis.metadata.quality.MeasureReference; @@ -44,7 +45,7 @@ import org.opengis.metadata.quality.MeasureReference; * * @author Alexis Gaillard (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.4 + * @version 1.5 * @since 1.3 */ @XmlType(name = "DQ_MeasureReference_Type", propOrder = { @@ -83,6 +84,17 @@ public class DefaultMeasureReference extends ISOMetadata implements MeasureRefer public DefaultMeasureReference() { } + /** + * Constructs a measure reference initialized with the given name. + * + * @param name the name of the measure as a {@link String} or an {@link InternationalString} object, + * or {@code null} if none. + * @since 1.5 + */ + public DefaultMeasureReference(final CharSequence name) { + namesOfMeasure = singleton(Types.toInternationalString(name), InternationalString.class); + } + /** * Constructs a new instance initialized with the values from the specified metadata object. * This is a <em>shallow</em> copy constructor, because the other metadata contained in the diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/RecordSchemaSIS.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/RecordSchemaSIS.java similarity index 95% rename from endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/RecordSchemaSIS.java rename to endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/RecordSchemaSIS.java index 6a7180f314..dba0d52b2e 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/RecordSchemaSIS.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/RecordSchemaSIS.java @@ -14,11 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sis.metadata.internal; +package org.apache.sis.metadata.privy; import java.util.Map; import java.io.Serializable; import java.io.ObjectStreamException; +import org.apache.sis.metadata.internal.Resources; import org.opengis.util.TypeName; import org.opengis.util.InternationalString; import org.apache.sis.util.privy.Constants; @@ -32,7 +33,7 @@ import org.apache.sis.util.resources.Vocabulary; * * @author Martin Desruisseaux (Geomatys) */ -@SuppressWarnings("serial") // serialVersionUID not needed because of writeReplace(). +@SuppressWarnings({"serial", "removal"}) // serialVersionUID not needed because of writeReplace(). public final class RecordSchemaSIS extends DefaultRecordSchema implements Serializable { /** * The schema used in SIS for creating records. diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/TransformationAccuracy.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/TransformationAccuracy.java deleted file mode 100644 index 99743b8aa8..0000000000 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/privy/TransformationAccuracy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sis.metadata.privy; - -import java.util.List; -import org.opengis.util.RecordType; -import org.opengis.util.InternationalString; -import org.opengis.metadata.quality.PositionalAccuracy; -import org.opengis.metadata.quality.EvaluationMethodType; -import org.apache.sis.measure.Units; -import org.apache.sis.metadata.internal.RecordSchemaSIS; -import org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult; -import org.apache.sis.metadata.iso.quality.DefaultAbsoluteExternalPositionalAccuracy; -import org.apache.sis.util.Static; -import org.apache.sis.util.collection.WeakValueHashMap; -import org.apache.sis.util.iso.DefaultRecord; -import org.apache.sis.util.resources.Vocabulary; - - -/** - * Creates a record reporting coordinate transformation accuracy. - * - * @author Martin Desruisseaux (Geomatys) - */ -public final class TransformationAccuracy extends Static { - /** - * The name for the transformation accuracy metadata. - */ - private static final InternationalString TRANSFORMATION_ACCURACY = - Vocabulary.formatInternational(Vocabulary.Keys.TransformationAccuracy); - - /** - * Cache the positional accuracies. Most coordinate operation use a small set of accuracy values. - */ - private static final WeakValueHashMap<Double,PositionalAccuracy> CACHE = new WeakValueHashMap<>(Double.class); - - /** - * Do not allow instantiation of this class. - */ - private TransformationAccuracy() { - } - - /** - * Creates a positional accuracy for the given value, in metres. - * This method may return a cached value. - * - * @param accuracy the accuracy in metres. - * @return a positional accuracy with the given value. - */ - @SuppressWarnings("deprecation") - public static PositionalAccuracy create(final Double accuracy) { - PositionalAccuracy p = CACHE.get(accuracy); - if (p == null) { - final RecordType type = RecordSchemaSIS.REAL; - final DefaultRecord record = new DefaultRecord(type); - record.setAll(accuracy); - - final DefaultQuantitativeResult result = new DefaultQuantitativeResult(); - result.setValues(List.of(record)); - result.setValueUnit(Units.METRE); // In metres by definition in the EPSG database. - result.setValueType(type); - - final DefaultAbsoluteExternalPositionalAccuracy element = - new DefaultAbsoluteExternalPositionalAccuracy(result); - element.setNamesOfMeasure(List.of(TRANSFORMATION_ACCURACY)); - element.setEvaluationMethodType(EvaluationMethodType.DIRECT_EXTERNAL); - element.transitionTo(DefaultAbsoluteExternalPositionalAccuracy.State.FINAL); - - p = CACHE.putIfAbsent(accuracy, element); - if (p == null) { - p = element; - } - } - return p; - } -} diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecord.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecord.java index e9a51afd11..a7ef38bd9b 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecord.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecord.java @@ -33,7 +33,7 @@ import org.apache.sis.util.Utilities; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.privy.Strings; import org.apache.sis.util.privy.AbstractMapEntry; -import org.apache.sis.metadata.internal.RecordSchemaSIS; +import org.apache.sis.metadata.privy.RecordSchemaSIS; /** diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecordType.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecordType.java index 69646b3a26..55bb94d6ef 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecordType.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/DefaultRecordType.java @@ -42,7 +42,7 @@ import org.apache.sis.util.CharSequences; import org.apache.sis.util.ObjectConverters; import org.apache.sis.util.resources.Errors; import org.apache.sis.converter.SurjectiveConverter; -import org.apache.sis.metadata.internal.RecordSchemaSIS; +import org.apache.sis.metadata.privy.RecordSchemaSIS; // Specific to the geoapi-3.1 and geoapi-4.0 branches: import org.opengis.util.NameFactory; diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/DefaultQuantitativeResultTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/DefaultQuantitativeResultTest.java index dc180f7a72..84cc4bff45 100644 --- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/DefaultQuantitativeResultTest.java +++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/metadata/iso/quality/DefaultQuantitativeResultTest.java @@ -26,7 +26,7 @@ import org.opengis.util.RecordType; import org.opengis.util.MemberName; import org.opengis.metadata.quality.Element; import org.opengis.metadata.quality.QuantitativeResult; -import org.apache.sis.metadata.internal.RecordSchemaSIS; +import org.apache.sis.metadata.privy.RecordSchemaSIS; import org.apache.sis.xml.XML; import org.apache.sis.xml.privy.LegacyNamespaces; import org.apache.sis.util.SimpleInternationalString; diff --git a/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java b/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java index df72e680be..0e78793851 100644 --- a/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java +++ b/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java @@ -18,7 +18,7 @@ package org.apache.sis.openoffice; import com.sun.star.lang.IllegalArgumentException; import org.apache.sis.referencing.privy.Formulas; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; // Test dependencies import org.junit.jupiter.api.Test; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java index 7c1d29de28..ecdfa88305 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java @@ -68,6 +68,7 @@ import org.apache.sis.referencing.privy.WKTUtilities; import org.apache.sis.referencing.privy.WKTKeywords; import org.apache.sis.referencing.internal.Legacy; import org.apache.sis.referencing.internal.VerticalDatumTypes; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.metadata.iso.extent.DefaultExtent; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; @@ -75,7 +76,6 @@ import org.apache.sis.metadata.iso.extent.DefaultGeographicDescription; import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent; import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent; import org.apache.sis.metadata.privy.AxisNames; -import org.apache.sis.metadata.privy.TransformationAccuracy; import org.apache.sis.referencing.operation.provider.AbstractProvider; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.privy.Constants; @@ -2309,7 +2309,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo final Map<String,Object> properties = parseParametersAndClose(element, name, method); if (accuracy != null) { properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, - TransformationAccuracy.create(accuracy.pullDouble("accuracy"))); + PositionalAccuracyConstant.create(accuracy.pullDouble("accuracy"))); accuracy.close(ignoredElements); } try { diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java index 6174b51d20..98c9574f51 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CRS.java @@ -61,10 +61,10 @@ import org.apache.sis.xml.bind.Context; import org.apache.sis.xml.bind.ScopedIdentifier; import org.apache.sis.referencing.privy.AxisDirections; import org.apache.sis.referencing.privy.EllipsoidalHeightCombiner; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; import org.apache.sis.referencing.privy.ReferencingUtilities; import org.apache.sis.referencing.privy.DefinitionVerifier; import org.apache.sis.referencing.internal.Resources; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.cs.AxisFilter; import org.apache.sis.referencing.cs.CoordinateSystems; import org.apache.sis.referencing.cs.DefaultVerticalCS; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java index 6d4457e1bd..cb5394aeac 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java @@ -2084,9 +2084,17 @@ public enum CommonCRS { */ public boolean datumUsedBy(final CoordinateReferenceSystem crs) { for (final SingleCRS component : CRS.getSingleComponents(crs)) { - if (ReferencingUtilities.uses(component, datum)) { + if (Utilities.equalsIgnoreMetadata(datum, component.getDatum())) { return true; } + final var ensemble = component.getDatumEnsemble(); + if (ensemble != null) { + for (final Datum member : ensemble.getMembers()) { + if (Utilities.equalsIgnoreMetadata(datum, member)) { + return true; + } + } + } } return false; } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java index 9b8ebfef7e..8eed014ccc 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java @@ -44,7 +44,6 @@ import org.apache.sis.referencing.factory.MultiAuthoritiesFactory; import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException; import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; -import org.apache.sis.util.Utilities; import org.apache.sis.util.logging.Logging; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.iso.AbstractFactory; @@ -52,7 +51,6 @@ import org.apache.sis.util.iso.AbstractFactory; // Specific to the geoapi-3.1 and geoapi-4.0 branches: import org.opengis.referencing.RegisterOperations; import org.opengis.referencing.crs.SingleCRS; -import org.apache.sis.referencing.privy.ReferencingUtilities; /** @@ -350,13 +348,7 @@ public class MultiRegisterOperations extends AbstractFactory implements Register return false; } for (int i=0; i<n; i++) { - final var crs1 = sources.get(i); - final var crs2 = targets.get(i); - if (!(Utilities.equalsIgnoreMetadata(PseudoDatum.getDatumOrEnsemble(crs1), - PseudoDatum.getDatumOrEnsemble(crs2)) - || ReferencingUtilities.uses(crs1, crs2.getDatum()) - || ReferencingUtilities.uses(crs2, crs1.getDatum()))) - { + if (PseudoDatum.getOperationAccuracy(sources.get(i), targets.get(i)).isEmpty()) { return false; } } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultDatumEnsemble.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultDatumEnsemble.java index 0b03e1ba43..0da60eed88 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultDatumEnsemble.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultDatumEnsemble.java @@ -24,7 +24,6 @@ import org.apache.sis.io.wkt.Formatter; import org.apache.sis.io.wkt.Convention; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.datum.Datum; -import org.opengis.referencing.datum.DatumEnsemble; import org.opengis.metadata.quality.PositionalAccuracy; import org.apache.sis.referencing.AbstractIdentifiedObject; import org.apache.sis.referencing.internal.Resources; @@ -34,6 +33,9 @@ import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Utilities; import org.apache.sis.util.resources.Errors; +// Specific to the geoapi-3.1 and geoapi-4.0 branches: +import org.opengis.referencing.datum.DatumEnsemble; + /** * Collection of datums which for low accuracy requirements may be considered diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/PseudoDatum.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/PseudoDatum.java index f905c6c4f6..87c9fe4f43 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/PseudoDatum.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/PseudoDatum.java @@ -28,6 +28,7 @@ import java.io.Serializable; import org.opengis.util.GenericName; import org.opengis.util.InternationalString; import org.opengis.metadata.Identifier; +import org.opengis.metadata.quality.PositionalAccuracy; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.ObjectDomain; import org.opengis.referencing.datum.*; @@ -38,6 +39,7 @@ import org.apache.sis.util.LenientComparable; import org.apache.sis.util.resources.Errors; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.referencing.GeodeticException; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; /** @@ -96,26 +98,6 @@ public abstract class PseudoDatum<D extends Datum> implements Datum, LenientComp this.ensemble = Objects.requireNonNull(ensemble); } - /** - * Returns the datum of the given <abbr>CRS</abbr> if presents, or the datum ensemble otherwise. - * This is an alternative to the {@code of(…)} methods when the caller does not need to view the - * object as a datum. - * - * @param crs the <abbr>CRS</abbr> from which to get the datum or ensemble, or {@code null}. - * @return the datum if present, or the datum ensemble otherwise, or {@code null}. - */ - public static IdentifiedObject getDatumOrEnsemble(final SingleCRS crs) { - if (crs == null) return null; - final Datum datum = crs.getDatum(); - if (datum != null) { - if (datum instanceof PseudoDatum<?>) { - return ((PseudoDatum) datum).ensemble; - } - return datum; - } - return crs.getDatumEnsemble(); - } - /** * Returns the datum or pseudo-datum of the given geodetic <abbr>CRS</abbr>. * If the given <abbr>CRS</abbr> is associated to a non-null datum, then this method returns that datum. @@ -215,6 +197,116 @@ public abstract class PseudoDatum<D extends Datum> implements Datum, LenientComp return datum; } + /** + * Returns the datum of the given <abbr>CRS</abbr> if presents, or the datum ensemble otherwise. + * This is an alternative to the {@code of(…)} methods when the caller does not need to view the + * object as a datum. + * + * @param crs the <abbr>CRS</abbr> from which to get the datum or ensemble, or {@code null}. + * @return the datum if present, or the datum ensemble otherwise, or {@code null}. + */ + public static IdentifiedObject getDatumOrEnsemble(final SingleCRS crs) { + if (crs == null) return null; + final Datum datum = crs.getDatum(); + if (datum != null) { + if (datum instanceof PseudoDatum<?>) { + return ((PseudoDatum) datum).ensemble; + } + return datum; + } + return crs.getDatumEnsemble(); + } + + /** + * Returns the inaccuracy that would have an operation using datum ensembles. + * This method makes the following choice: + * + * <ul> + * <li>If the two reference systems are associated to the same datum, returns an arbitrary value.</li> + * <li>Otherwise, if the datum of one <abbr>CRS</abbr> is a member of the datum ensemble of the other + * <abbr>CRS</abbr>, returns the ensemble accuracy.</li> + * <li>OTherwise, if the datum ensemble of one <abbr>CRS</abbr> is fully contained in the datum ensemble + * of the other <abbr>CRS</abbr>, returns the accuracy of the larger ensemble.</li> + * <li>Otherwise, returns an empty value.</li> + * </ul> + * + * An empty value means that the two <abbr>CRS</abbr> are not compatible according the datum and datum ensemble + * properties. However, a transformation path may exist in a geodetic registry such as <abbr>EPSG</abbr>. + * + * @param source the first <abbr>CRS</abbr> for which to compare the datum. + * @param target the second <abbr>CRS</abbr> for which to compare the datum. + * @return a non-null value if it is okay, for low accuracy requirements, to ignore the datum shift. + */ + public static Optional<PositionalAccuracy> getOperationAccuracy(final SingleCRS source, final SingleCRS target) { + final Datum sourceDatum = source.getDatum(); + final Datum targetDatum = target.getDatum(); + if (sourceDatum != null && targetDatum != null && Utilities.equalsIgnoreMetadata(sourceDatum, targetDatum)) { + return Optional.of(PositionalAccuracyConstant.SAME_DATUM_ENSEMBLE); + } + DatumEnsemble<?> sourceEnsemble; + DatumEnsemble<?> targetEnsemble; + PositionalAccuracy accuracy; + if ((accuracy = accuracyIfMember(sourceDatum, targetEnsemble = target.getDatumEnsemble())) != null || + (accuracy = accuracyIfMember(targetDatum, sourceEnsemble = source.getDatumEnsemble())) != null || + (sourceEnsemble == null || targetEnsemble == null)) + { + return Optional.of(accuracy); + } + var sources = sourceEnsemble.getMembers(); + var targets = targetEnsemble.getMembers(); + if (sources.size() > targets.size()) { + var tmp = targets; // Want as if transforming from smaller ensemble to larger ensemble. + targets = sources; + sources = tmp; + + var te = targetEnsemble; + targetEnsemble = sourceEnsemble; + sourceEnsemble = te; + } + final Datum[] remaining = sources.toArray(Datum[]::new); + int count = remaining.length; + for (final Datum member : targets) { + for (int i=0; i<count; i++) { + if (Utilities.equalsIgnoreMetadata(member, remaining[i])) { + System.arraycopy(remaining, i+1, remaining, i, --count - i); + if (count == 0) { + /* + * Found all members of the smaller ensemble. Take the accuracy + * of the larger ensemble, as it contains the smaller ensemble. + */ + if ((accuracy = targetEnsemble.getEnsembleAccuracy()) == null && + (accuracy = sourceEnsemble.getEnsembleAccuracy()) == null) { + accuracy = PositionalAccuracyConstant.SAME_DATUM_ENSEMBLE; + } + return Optional.of(accuracy); + } + break; // For removing only the first match. + } + } + } + return Optional.empty(); + } + + /** + * If the given datum is a member of the given ensemble, returns the ensemble accuracy. + * Otherwise, returns {@code null}. + * + * @param datum the datum to test, or {@code null}. + * @param ensemble the ensemble to test, or {@code null}. + * @return a non-null value if the datum is a member of the given ensemble. + */ + private static PositionalAccuracy accuracyIfMember(final Datum datum, final DatumEnsemble<?> ensemble) { + if (ensemble != null) { + for (final Datum member : ensemble.getMembers()) { + if (Utilities.equalsIgnoreMetadata(datum, member)) { + PositionalAccuracy accuracy = ensemble.getEnsembleAccuracy(); + return (accuracy != null) ? accuracy : PositionalAccuracyConstant.SAME_DATUM_ENSEMBLE; + } + } + } + return null; + } + /** * Returns the GeoAPI interface of the ensemble members. * It should also be the interface implemented by this class. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java index 1036dd57c1..21cf4bec22 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java @@ -66,21 +66,31 @@ import org.opengis.referencing.cs.*; import org.opengis.referencing.crs.*; import org.opengis.referencing.datum.*; import org.opengis.referencing.operation.*; -import org.apache.sis.metadata.privy.TransformationAccuracy; import org.apache.sis.referencing.NamedIdentifier; import org.apache.sis.referencing.ImmutableIdentifier; import org.apache.sis.referencing.AbstractIdentifiedObject; +import org.apache.sis.referencing.cs.CoordinateSystems; +import org.apache.sis.referencing.datum.BursaWolfParameters; +import org.apache.sis.referencing.datum.DefaultGeodeticDatum; +import org.apache.sis.referencing.operation.DefaultOperationMethod; +import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; +import org.apache.sis.referencing.factory.FactoryDataException; +import org.apache.sis.referencing.factory.GeodeticAuthorityFactory; +import org.apache.sis.referencing.factory.IdentifiedObjectFinder; import org.apache.sis.referencing.privy.WKTKeywords; import org.apache.sis.referencing.privy.CoordinateOperations; import org.apache.sis.referencing.privy.ReferencingFactoryContainer; import org.apache.sis.referencing.privy.Formulas; -import org.apache.sis.metadata.sql.privy.SQLUtilities; import org.apache.sis.referencing.internal.DeferredCoordinateOperation; import org.apache.sis.referencing.internal.DeprecatedCode; import org.apache.sis.referencing.internal.EPSGParameterDomain; +import org.apache.sis.referencing.internal.ParameterizedTransformBuilder; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.internal.SignReversalComment; import org.apache.sis.referencing.internal.Resources; -import org.apache.sis.referencing.internal.ParameterizedTransformBuilder; +import static org.apache.sis.referencing.internal.ServicesForMetadata.CONNECTION; +import org.apache.sis.parameter.DefaultParameterDescriptor; +import org.apache.sis.parameter.DefaultParameterDescriptorGroup; import org.apache.sis.system.Loggers; import org.apache.sis.system.Semaphores; import org.apache.sis.util.SimpleInternationalString; @@ -90,36 +100,26 @@ import org.apache.sis.util.Localized; import org.apache.sis.util.Version; import org.apache.sis.util.Workaround; import org.apache.sis.util.ArraysExt; +import org.apache.sis.util.collection.BackingStoreException; +import org.apache.sis.util.resources.Vocabulary; +import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.logging.Logging; import org.apache.sis.util.privy.Constants; import org.apache.sis.util.privy.CollectionsExt; import org.apache.sis.util.privy.Strings; import org.apache.sis.util.privy.URLs; +import static org.apache.sis.util.privy.Constants.UTC; +import static org.apache.sis.util.Utilities.equalsIgnoreMetadata; import org.apache.sis.temporal.LenientDateFormat; import org.apache.sis.metadata.iso.citation.DefaultCitation; import org.apache.sis.metadata.iso.citation.DefaultOnlineResource; import org.apache.sis.metadata.iso.extent.DefaultExtent; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; -import org.apache.sis.parameter.DefaultParameterDescriptor; -import org.apache.sis.parameter.DefaultParameterDescriptorGroup; -import org.apache.sis.referencing.cs.CoordinateSystems; -import org.apache.sis.referencing.datum.BursaWolfParameters; -import org.apache.sis.referencing.datum.DefaultGeodeticDatum; -import org.apache.sis.referencing.operation.DefaultOperationMethod; -import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory; -import org.apache.sis.referencing.factory.FactoryDataException; -import org.apache.sis.referencing.factory.GeodeticAuthorityFactory; -import org.apache.sis.referencing.factory.IdentifiedObjectFinder; -import org.apache.sis.util.collection.BackingStoreException; -import org.apache.sis.util.resources.Vocabulary; -import org.apache.sis.util.resources.Errors; -import org.apache.sis.util.logging.Logging; +import org.apache.sis.metadata.sql.privy.SQLUtilities; import org.apache.sis.measure.MeasurementRange; import org.apache.sis.measure.NumberRange; import org.apache.sis.measure.Units; import org.apache.sis.pending.jdk.JDK16; -import static org.apache.sis.util.privy.Constants.UTC; -import static org.apache.sis.util.Utilities.equalsIgnoreMetadata; -import static org.apache.sis.referencing.internal.ServicesForMetadata.CONNECTION; // Specific to the geoapi-3.1 and geoapi-4.0 branches: import org.opengis.metadata.Identifier; @@ -2896,7 +2896,7 @@ next: while (r.next()) { opProperties.put(CoordinateOperation.OPERATION_VERSION_KEY, version); if (!Double.isNaN(accuracy)) { opProperties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, - TransformationAccuracy.create(accuracy)); + PositionalAccuracyConstant.create(accuracy)); } /* * Creates the operation. Conversions should be the only operations allowed to have diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/AnnotatedMatrix.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/AnnotatedMatrix.java index 5b0140f59f..0732b42805 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/AnnotatedMatrix.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/AnnotatedMatrix.java @@ -19,7 +19,6 @@ package org.apache.sis.referencing.internal; import org.opengis.referencing.operation.Matrix; import org.opengis.metadata.quality.PositionalAccuracy; import org.apache.sis.util.privy.CloneAccess; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; /** diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/PositionalAccuracyConstant.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/PositionalAccuracyConstant.java similarity index 66% rename from endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/PositionalAccuracyConstant.java rename to endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/PositionalAccuracyConstant.java index 7370c6c5e6..123aea11c2 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/PositionalAccuracyConstant.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/PositionalAccuracyConstant.java @@ -14,16 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sis.referencing.privy; +package org.apache.sis.referencing.internal; -import java.util.Set; +import java.util.List; +import java.util.ArrayList; import java.util.Collection; import java.io.ObjectStreamException; import jakarta.xml.bind.annotation.XmlTransient; import javax.measure.Unit; import javax.measure.quantity.Length; import org.opengis.util.Record; -import org.opengis.util.InternationalString; +import org.opengis.util.RecordType; import org.opengis.metadata.quality.PositionalAccuracy; import org.opengis.metadata.quality.EvaluationMethodType; import org.opengis.metadata.quality.QuantitativeResult; @@ -34,11 +35,16 @@ import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.Transformation; import org.apache.sis.measure.Units; import org.apache.sis.metadata.iso.citation.Citations; +import org.apache.sis.metadata.iso.quality.DefaultMeasureReference; +import org.apache.sis.metadata.iso.quality.DefaultEvaluationMethod; import org.apache.sis.metadata.iso.quality.DefaultConformanceResult; import org.apache.sis.metadata.iso.quality.DefaultAbsoluteExternalPositionalAccuracy; -import org.apache.sis.system.Configuration; -import org.apache.sis.referencing.internal.Resources; +import org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult; +import org.apache.sis.metadata.privy.RecordSchemaSIS; +import org.apache.sis.util.collection.WeakValueHashMap; import org.apache.sis.util.resources.Vocabulary; +import org.apache.sis.util.iso.DefaultRecord; +import org.apache.sis.system.Configuration; /** @@ -77,7 +83,7 @@ public final class PositionalAccuracyConstant extends DefaultAbsoluteExternalPos * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy() */ @Configuration - private static final double DATUM_SHIFT_ACCURACY = 25; + public static final double DATUM_SHIFT_ACCURACY = 25; /** * Default accuracy of datum shifts when using an intermediate datum (typically WGS 84). @@ -92,7 +98,9 @@ public final class PositionalAccuracyConstant extends DefaultAbsoluteExternalPos * Indicates that a {@linkplain org.opengis.referencing.operation.Transformation transformation} * requires a datum shift and some method has been applied. Datum shift methods often use * {@linkplain org.apache.sis.referencing.datum.BursaWolfParameters Bursa Wolf parameters}, - * but other kind of method may have been applied as well. + * but other kinds of method may have been applied as well. + * + * @todo Should use the accuracy defined in {@code BoundCRS} instead. */ public static final PositionalAccuracy DATUM_SHIFT_APPLIED; @@ -110,29 +118,106 @@ public final class PositionalAccuracyConstant extends DefaultAbsoluteExternalPos * an intermediate datum, typically WGS 84. */ public static final PositionalAccuracy INDIRECT_SHIFT_APPLIED; + + /** + * Coordinate operation between reference frames in the same datum ensemble. + * Should be used only with coordinate operations that are conversion, + * but may also be used as a fallback if a datum ensemble didn't specified its accuracy. + */ + public static final PositionalAccuracy SAME_DATUM_ENSEMBLE; + + /** + * Name for accuracy metadata of coordinate transformations. + */ + private static final DefaultMeasureReference TRANSFORMATION_REFERENCE = + new DefaultMeasureReference(Vocabulary.formatInternational(Vocabulary.Keys.TransformationAccuracy)); + + /** + * The evaluation method for coordinate transformations when the accuracy is specified in the EPSG database. + * Those evaluation method are considered "external" on the assumption that the operation results have been + * compared by the database maintainers against some results taken as true. By contrast, the accuracies that + * we have set to conservative values are considered "direct internal". + */ + private static final DefaultEvaluationMethod TRANSFORMATION_METHOD = + new DefaultEvaluationMethod(EvaluationMethodType.DIRECT_EXTERNAL, + Resources.formatInternational(Resources.Keys.AccuracyFromGeodeticDatase)); + static { - final InternationalString desc = Vocabulary.formatInternational(Vocabulary.Keys.TransformationAccuracy); - final InternationalString eval = Resources .formatInternational(Resources.Keys.ConformanceMeansDatumShift); - DATUM_SHIFT_APPLIED = new PositionalAccuracyConstant(desc, eval, true); - DATUM_SHIFT_OMITTED = new PositionalAccuracyConstant(desc, eval, false); - INDIRECT_SHIFT_APPLIED = new PositionalAccuracyConstant(desc, eval, true); + TRANSFORMATION_REFERENCE.transitionTo(DefaultMeasureReference.State.FINAL); + TRANSFORMATION_METHOD .transitionTo(DefaultEvaluationMethod.State.FINAL); + final var desc = Resources.formatInternational(Resources.Keys.ConformanceMeansDatumShift); + final var method = new DefaultEvaluationMethod(EvaluationMethodType.DIRECT_INTERNAL, desc); + final var pass = new DefaultConformanceResult(Citations.SIS, desc, true); + final var fail = new DefaultConformanceResult(Citations.SIS, desc, false); + + DATUM_SHIFT_APPLIED = new PositionalAccuracyConstant(TRANSFORMATION_REFERENCE, method, pass, DATUM_SHIFT_ACCURACY); + DATUM_SHIFT_OMITTED = new PositionalAccuracyConstant(TRANSFORMATION_REFERENCE, method, fail, UNKNOWN_ACCURACY); + INDIRECT_SHIFT_APPLIED = new PositionalAccuracyConstant(TRANSFORMATION_REFERENCE, method, pass, INDIRECT_SHIFT_ACCURACY); + + final var reference = new DefaultMeasureReference(Resources.formatInternational(Resources.Keys.OperationSameDatumEnsemble)); + SAME_DATUM_ENSEMBLE = new PositionalAccuracyConstant(reference, null, null, null); } /** - * Creates an positional accuracy initialized to the given result. + * Creates a positional accuracy initialized to the given result. + * + * @param reference description of the positional accuracy. + * @param method method used for accuracy measurement, or {@code null}. + * @param result qualitative result, or {@code null} if none. + * @param accuracy the linear accuracy in metres, or {@code null} if none. */ - @SuppressWarnings("deprecation") - private PositionalAccuracyConstant(final InternationalString measureDescription, - final InternationalString evaluationMethodDescription, final boolean pass) + private PositionalAccuracyConstant(final DefaultMeasureReference reference, + final DefaultEvaluationMethod method, + final DefaultConformanceResult result, + final Double accuracy) { - DefaultConformanceResult result = new DefaultConformanceResult(Citations.SIS, evaluationMethodDescription, pass); - setResults(Set.of(result)); - setMeasureDescription(measureDescription); - setEvaluationMethodDescription(evaluationMethodDescription); - setEvaluationMethodType(EvaluationMethodType.DIRECT_INTERNAL); + setMeasureReference(reference); + setEvaluationMethod(method); + final var results = new ArrayList<Result>(2); + if (result != null) { + results.add(result); + } + if (accuracy != null) { + final RecordType type = RecordSchemaSIS.REAL; + final var record = new DefaultRecord(type); + record.setAll(accuracy); + + final var r = new DefaultQuantitativeResult(); + r.setValues(List.of(record)); + r.setValueUnit(Units.METRE); // In metres by definition in the EPSG database. + r.setValueType(type); + results.add(r); + } + setResults(results); transitionTo(State.FINAL); } + /** + * Creates a positional accuracy for a value specified in the EPSG database. + * + * @param accuracy the linear accuracy in metres. + */ + private PositionalAccuracyConstant(final Double accuracy) { + this(TRANSFORMATION_REFERENCE, TRANSFORMATION_METHOD, null, accuracy); + } + + /** + * Creates a positional accuracy for the given value, in metres. + * This method may return a cached value. + * + * @param accuracy the accuracy in metres. + * @return a positional accuracy with the given value. + */ + public static PositionalAccuracy create(final Double accuracy) { + return CACHE.computeIfAbsent(accuracy, PositionalAccuracyConstant::new); + } + + /** + * Cache the positional accuracies of coordinate transformations. + * Most coordinate operations use a small set of accuracy values. + */ + private static final WeakValueHashMap<Double,PositionalAccuracy> CACHE = new WeakValueHashMap<>(Double.class); + /** * Invoked on deserialization. Replace this instance by one of the constants, if applicable. * @@ -143,6 +228,7 @@ public final class PositionalAccuracyConstant extends DefaultAbsoluteExternalPos if (equals(DATUM_SHIFT_APPLIED)) return DATUM_SHIFT_APPLIED; if (equals(DATUM_SHIFT_OMITTED)) return DATUM_SHIFT_OMITTED; if (equals(INDIRECT_SHIFT_APPLIED)) return INDIRECT_SHIFT_APPLIED; + if (equals(SAME_DATUM_ENSEMBLE)) return SAME_DATUM_ENSEMBLE; return this; } @@ -207,22 +293,6 @@ public final class PositionalAccuracyConstant extends DefaultAbsoluteExternalPos if (operation instanceof Conversion) { return 0; } - /* - * If the coordinate operation is actually a transformation, checks if Bursa-Wolf parameters - * were available for the datum shift. This is SIS-specific. See field javadoc for a rational - * about the return values chosen. - */ - if (operation instanceof Transformation) { - for (final PositionalAccuracy element : accuracies) { - /* - * Really need identity comparisons, not Object.equals(Object), because the latter - * does not distinguish between DATUM_SHIFT_APPLIED and INDIRECT_SHIFT_APPLIED. - */ - if (element == DATUM_SHIFT_APPLIED) return DATUM_SHIFT_ACCURACY; - if (element == DATUM_SHIFT_OMITTED) return UNKNOWN_ACCURACY; - if (element == INDIRECT_SHIFT_APPLIED) return INDIRECT_SHIFT_ACCURACY; - } - } /* * If the coordinate operation is a compound of other coordinate operations, returns the sum of their accuracy, * skipping unknown ones. Making the sum is a conservative approach (not exactly the "worst case" scenario, diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java index 11a8ad71a4..0af68e9f8f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.java @@ -54,6 +54,11 @@ public class Resources extends IndexedResourceBundle { private Keys() { } + /** + * Accuracy declared in a geodetic dataset. + */ + public static final short AccuracyFromGeodeticDatase = 105; + /** * Ambiguity between inverse flattening and semi minor axis length for “{0}”. Using inverse * flattening. @@ -503,6 +508,11 @@ public class Resources extends IndexedResourceBundle { */ public static final short OperationHasNoTransform_2 = 43; + /** + * Coordinate operation between reference frames in the same datum ensemble. + */ + public static final short OperationSameDatumEnsemble = 106; + /** * No parameter named “{1}” has been found in “{0}”. */ diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.properties b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.properties index a79a91f56e..e7eef826ce 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.properties +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources.properties @@ -21,8 +21,8 @@ # # Information messages or non-fatal warnings # +AccuracyFromGeodeticDatase = Accuracy declared in a geodetic dataset. AmbiguousEllipsoid_1 = Ambiguity between inverse flattening and semi minor axis length for \u201c{0}\u201d. Using inverse flattening. -CannotParseElement_1 = Cannot parse the \u201c{0}\u201d element: ConformanceMeansDatumShift = This result indicates if a datum shift method has been applied. ConstantProjParameterValue_1 = This parameter is shown for completeness, but should never have a value different than {0} for this projection. DeprecatedCode_3 = Code \u201c{0}\u201d is deprecated and replaced by code {1}. Reason is: {2} @@ -43,6 +43,7 @@ NotFormalProjectionParameter_1 = This parameter borrowed from the \u201c{0}\u NonConformAxes_2 = The coordinate system axes in the given \u201c{0}\u201d description do not conform to the expected axes according \u201c{1}\u201d authoritative description. NonConformCRS_3 = The given \u201c{0}\u201d description does not conform to the \u201c{1}\u201d authoritative description. \ Differences are found in {2,choice,0#conversion method|1#conversion description|2#coordinate system|3#datum|4#prime meridian|5#ellipsoid|6#CRS}. +OperationSameDatumEnsemble = Coordinate operation between reference frames in the same datum ensemble. RestrictedToPoleLatitudes = The only valid entries are \u00b190\u00b0 or equivalent in alternative angle units. # @@ -61,6 +62,7 @@ CanNotInstantiateGeodeticObject_1 = Cannot instantiate geodetic object for \u201 CanNotLinearizeLocalizationGrid = Cannot linearize the localization grid. CanNotMapAxisToDirection_1 = Cannot map an axis from the specified coordinate system to the \u201c{0}\u201d direction. CanNotParseCombinedReference_2 = Cannot parse component {1} in the combined {0,choice,0#URN|1#URL}. +CannotParseElement_1 = Cannot parse the \u201c{0}\u201d element: CanNotSeparateCRS_1 = Cannot separate the \u201c{0}\u201d coordinate reference system into sub-components. CanNotSeparateTransform_3 = Cannot separate the transform because result would have {2} {0,choice,0#source|1#target} dimension{2,choice,1#|2#s} instead of {1}. CanNotSeparateTargetDimension_1 = Target dimension {0} depends on excluded source dimensions. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources_fr.properties b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources_fr.properties index 245a08e502..9a58be876f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources_fr.properties +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/Resources_fr.properties @@ -26,8 +26,8 @@ # # Information messages or non-fatal warnings # +AccuracyFromGeodeticDatase = Pr\u00e9cision d\u00e9clar\u00e9e dans une base de donn\u00e9es g\u00e9od\u00e9siques. AmbiguousEllipsoid_1 = Ambigu\u00eft\u00e9 entre l\u2019aplatissement et la longueur du semi-axe mineur pour \u00ab\u202f{0}\u202f\u00bb. Utilise l\u2019aplatissement. -CannotParseElement_1 = Ne peut pas d\u00e9coder l\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb\u00a0: ConformanceMeansDatumShift = Ce r\u00e9sultat indique si un changement de r\u00e9f\u00e9rentiel a \u00e9t\u00e9 appliqu\u00e9. ConstantProjParameterValue_1 = Ce param\u00e8tre est montr\u00e9 pour \u00eatre plus complet, mais sa valeur ne devrait jamais \u00eatre diff\u00e9rente de {0} pour cette projection. DeprecatedCode_3 = Le code \u00ab\u202f{0}\u202f\u00bb est d\u00e9pr\u00e9ci\u00e9 et remplac\u00e9 par le code {1}. La raison est\u00a0: {2} @@ -48,6 +48,7 @@ NotFormalProjectionParameter_1 = Ce param\u00e8tre emprunt\u00e9 \u00e0 la pr NonConformAxes_2 = Les axes du syst\u00e8me de coordonn\u00e9es d\u00e9finis dans \u00ab\u202f{0}\u202f\u00bb ne sont pas conformes aux axes attendus d\u2019apr\u00e8s la description officielle de \u00ab\u202f{1}\u202f\u00bb. NonConformCRS_3 = La description donn\u00e9e pour \u00ab\u202f{0}\u202f\u00bb n\u2019est pas conforme \u00e0 la description officielle de \u00ab\u202f{1}\u202f\u00bb. \ Des diff\u00e9rences ont \u00e9t\u00e9 trouv\u00e9es dans {2,choice,0#la m\u00e9thode de conversion|1#la description de la conversion|2#le syst\u00e8me de coordonn\u00e9es|3#le r\u00e9f\u00e9rentiel|4#le m\u00e9ridien d\u2019origine|5#l\u2019ellipso\u00efde|6#le CRS}. +OperationSameDatumEnsemble = Op\u00e9ration sur les coordonn\u00e9es entre des r\u00e9f\u00e9rentiels qui sont dans le m\u00eame ensemble de r\u00e9f\u00e9rentiels. RestrictedToPoleLatitudes = Les seules valeurs valides sont \u00b190\u00b0 ou \u00e9quivalent dans d\u2019autres unit\u00e9s. # @@ -69,6 +70,7 @@ CanNotSeparateCRS_1 = Ne peut pas s\u00e9parer le syst\u00e8me de CanNotSeparateTransform_3 = Ne peut pas s\u00e9parer la transformation parce-que le r\u00e9sultat aurait {2} dimension{2,choice,1#|2#s} en {0,choice,0#entr\u00e9|1#sortie} au lieu de {1}. CanNotSeparateTargetDimension_1 = La dimension de destination {0} d\u00e9pend de dimensions sources qui ont \u00e9t\u00e9 exclues. CanNotParseCombinedReference_2 = Ne peut pas d\u00e9coder la composante {1} dans l\u2019{0,choice,0#URN|1#URL} combin\u00e9. +CannotParseElement_1 = Ne peut pas d\u00e9coder l\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb\u00a0: CanNotParseWKT_2 = Ne peut pas lire le \u00ab\u202fWell-Known Text\u202f\u00bb \u00e0 la ligne {0}. La cause est\u202f: {1} CanNotTransformCoordinates_2 = Ne peut pas transformer les coordonn\u00e9es ({0,number}; {1,number}). CanNotTransformEnvelopeToGeodetic = Ne peut pas transformer l\u2019enveloppe vers un r\u00e9f\u00e9rentiel g\u00e9od\u00e9sique. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java index 038e256a13..5724153a01 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java @@ -60,11 +60,11 @@ import org.apache.sis.referencing.AbstractIdentifiedObject; import org.apache.sis.referencing.cs.CoordinateSystems; import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.referencing.operation.transform.PassThroughTransform; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; import org.apache.sis.referencing.privy.CoordinateOperations; import org.apache.sis.referencing.privy.ReferencingUtilities; import org.apache.sis.referencing.privy.WKTUtilities; import org.apache.sis.referencing.privy.WKTKeywords; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.internal.Resources; import org.apache.sis.metadata.privy.ImplementationHelper; import org.apache.sis.util.privy.Constants; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationContext.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationContext.java index 37a4593bc0..22936847f6 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationContext.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationContext.java @@ -126,7 +126,7 @@ public class CoordinateOperationContext implements Serializable { areaOfInterest.getWestBoundLongitude() > Longitude.MIN_VALUE || areaOfInterest.getEastBoundLongitude() < Longitude.MAX_VALUE) { - final CoordinateOperationContext context = new CoordinateOperationContext(); + final var context = new CoordinateOperationContext(); context.setAreaOfInterest(areaOfInterest); return context; } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java index 136f8b010b..c8bf82dacf 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java @@ -65,9 +65,9 @@ import org.apache.sis.referencing.factory.InvalidGeodeticParameterException; import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException; import org.apache.sis.referencing.privy.CoordinateOperations; import org.apache.sis.referencing.privy.EllipsoidalHeightCombiner; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; import org.apache.sis.referencing.privy.ReferencingUtilities; import org.apache.sis.referencing.internal.ParameterizedTransformBuilder; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.internal.DeferredCoordinateOperation; import org.apache.sis.referencing.internal.Resources; import org.apache.sis.metadata.iso.citation.Citations; @@ -131,14 +131,14 @@ class CoordinateOperationRegistry { * Such "ellipsoid shifts" are approximations and may have 1 kilometre error. * * @see org.apache.sis.referencing.datum.BursaWolfParameters - * @see org.apache.sis.referencing.privy.PositionalAccuracyConstant#DATUM_SHIFT_OMITTED + * @see PositionalAccuracyConstant#DATUM_SHIFT_OMITTED */ static final Identifier ELLIPSOID_CHANGE = createIdentifier(Vocabulary.Keys.EllipsoidChange); /** * The identifier for a transformation which is a datum shift. * - * @see org.apache.sis.referencing.privy.PositionalAccuracyConstant#DATUM_SHIFT_APPLIED + * @see PositionalAccuracyConstant#DATUM_SHIFT_APPLIED */ static final Identifier DATUM_SHIFT = createIdentifier(Vocabulary.Keys.DatumShift); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java index 9ee0d7ed63..669701949a 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java @@ -36,9 +36,9 @@ import org.opengis.referencing.operation.NoninvertibleTransformException; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory; import org.apache.sis.referencing.factory.InvalidGeodeticParameterException; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; import org.apache.sis.referencing.privy.CoordinateOperations; import org.apache.sis.referencing.privy.ReferencingUtilities; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.internal.Resources; import org.apache.sis.util.Utilities; import org.apache.sis.util.ComparisonMode; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java index 6cb1e5cbb8..933df84dd8 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/privy/ReferencingUtilities.java @@ -206,30 +206,6 @@ public final class ReferencingUtilities extends Static { return (types.length != 0) ? types[0] : type; } - /** - * Returns whether the given <abbr>CRS</abbr> uses the given datum. - * - * @param crs the <abbr>CRS</abbr>, or {@code null}. - * @param datum the datum to compare with the <abbr>CRS</abbr> datum or datum ensemble. - * @return whether the given CRS <abbr>CRS</abbr> uses the specified datum. - */ - public static boolean uses(final SingleCRS crs, final Datum datum) { - if (crs != null && datum != null) { - if (Utilities.equalsIgnoreMetadata(crs.getDatum(), datum)) { - return true; - } - final var ensemble = crs.getDatumEnsemble(); - if (ensemble != null) { - for (final Datum member : ensemble.getMembers()) { - if (Utilities.equalsIgnoreMetadata(member, datum)) { - return true; - } - } - } - } - return false; - } - /** * Returns {@code true} if the type of the given datum is ellipsoidal. A vertical datum is not allowed * to be ellipsoidal according ISO 19111, but Apache SIS relaxes this restriction in some limited cases, diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java index 15c196a909..0618af7057 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java @@ -30,7 +30,7 @@ import org.apache.sis.xml.Namespaces; import org.apache.sis.io.wkt.Convention; import org.apache.sis.referencing.operation.matrix.Matrix4; import org.apache.sis.referencing.internal.AnnotatedMatrix; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.metadata.iso.extent.DefaultExtent; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; import static org.apache.sis.referencing.GeodeticObjectVerifier.*; diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/PositionalAccuracyConstantTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/PositionalAccuracyConstantTest.java new file mode 100644 index 0000000000..0202bf8af5 --- /dev/null +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/internal/PositionalAccuracyConstantTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.referencing.internal; + +import java.util.Map; +import java.util.Iterator; +import org.opengis.metadata.quality.Result; +import org.opengis.metadata.quality.ConformanceResult; +import org.opengis.metadata.quality.QuantitativeResult; +import org.opengis.metadata.quality.PositionalAccuracy; +import org.opengis.referencing.operation.CoordinateOperation; +import org.apache.sis.referencing.operation.AbstractCoordinateOperation; + +// Test dependencies +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import org.apache.sis.test.TestCase; + + +/** + * Tests the {@link PositionalAccuracyConstant} class. + * + * @author Martin Desruisseaux (IRD, Geomatys) + */ +public final class PositionalAccuracyConstantTest extends TestCase { + /** + * Creates a new test case. + */ + public PositionalAccuracyConstantTest() { + } + + /** + * Tests {@link PositionalAccuracyConstant#equals(Object)}. + */ + @Test + public void testEquals() { + assertEquals(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, + PositionalAccuracyConstant.DATUM_SHIFT_APPLIED); + + assertEquals(PositionalAccuracyConstant.DATUM_SHIFT_OMITTED, + PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); + + assertNotSame(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, + PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); + + assertNotEquals(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, + PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); + } + + /** + * Verifies the property values of some {@link PositionalAccuracyConstant} constants. + */ + @Test + public void testQualitativeResults() { + final Iterator<? extends Result> appliedResults = PositionalAccuracyConstant.DATUM_SHIFT_APPLIED.getResults().iterator(); + final Iterator<? extends Result> omittedResults = PositionalAccuracyConstant.DATUM_SHIFT_OMITTED.getResults().iterator(); + final var applied = assertInstanceOf(ConformanceResult.class, appliedResults.next()); + final var omitted = assertInstanceOf(ConformanceResult.class, omittedResults.next()); + assertNotSame(applied, omitted); + assertTrue (applied.pass(), "DATUM_SHIFT_APPLIED"); + assertFalse(omitted.pass(), "DATUM_SHIFT_OMITTED"); + assertNotEquals(applied, omitted); + assertNotEquals(appliedResults, omittedResults); + + assertNotEquals(assertInstanceOf(QuantitativeResult.class, appliedResults.next()), + assertInstanceOf(QuantitativeResult.class, omittedResults.next())); + + assertFalse(appliedResults.hasNext()); + assertFalse(omittedResults.hasNext()); + } + + /** + * tests {@link PositionalAccuracyConstant#getLinearAccuracy(CoordinateOperation)}. + */ + @Test + public void testQuantitativeResults() { + assertLinearAccuracyEquals(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, + PositionalAccuracyConstant.DATUM_SHIFT_ACCURACY); + assertLinearAccuracyEquals(PositionalAccuracyConstant.DATUM_SHIFT_OMITTED, + PositionalAccuracyConstant.UNKNOWN_ACCURACY); + assertLinearAccuracyEquals(PositionalAccuracyConstant.INDIRECT_SHIFT_APPLIED, + PositionalAccuracyConstant.INDIRECT_SHIFT_ACCURACY); + } + + /** + * Asserts that the numerical accuracy associated to the given metadata is the expected value. + * + * @param metadata the metadata to test. + * @param expected the expected accuracy value. + */ + private static void assertLinearAccuracyEquals(final PositionalAccuracy metadata, final double expected) { + var properties = Map.of(CoordinateOperation.NAME_KEY, "Dummy", + CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, metadata); + var operation = new AbstractCoordinateOperation(properties, null, null, null, null); + assertEquals(expected, PositionalAccuracyConstant.getLinearAccuracy(operation)); + } +} diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java index 5d0bdc63f8..46fd3b62cf 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java @@ -40,7 +40,7 @@ import org.opengis.referencing.operation.OperationNotFoundException; import org.opengis.referencing.operation.Matrix; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.CRS; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.referencing.operation.transform.LinearTransform; import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.referencing.operation.matrix.Matrices; @@ -55,7 +55,7 @@ import org.apache.sis.measure.Units; import static org.apache.sis.util.privy.Constants.SECONDS_PER_DAY; import static org.apache.sis.referencing.privy.Formulas.LINEAR_TOLERANCE; import static org.apache.sis.referencing.privy.Formulas.ANGULAR_TOLERANCE; -import static org.apache.sis.referencing.privy.PositionalAccuracyConstant.DATUM_SHIFT_APPLIED; +import static org.apache.sis.referencing.internal.PositionalAccuracyConstant.DATUM_SHIFT_APPLIED; // Test dependencies import org.junit.jupiter.api.BeforeEach; diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java index 8decba736b..8422c98203 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java @@ -30,7 +30,7 @@ import org.opengis.referencing.operation.TransformException; import org.apache.sis.referencing.CRS; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.privy.Formulas; -import org.apache.sis.referencing.privy.PositionalAccuracyConstant; +import org.apache.sis.referencing.internal.PositionalAccuracyConstant; import org.apache.sis.util.privy.Constants; import org.apache.sis.geometry.DirectPosition2D; import org.apache.sis.io.wkt.WKTFormat; diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/PositionalAccuracyConstantTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/PositionalAccuracyConstantTest.java deleted file mode 100644 index ecbf216563..0000000000 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/privy/PositionalAccuracyConstantTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.sis.referencing.privy; - -import java.util.Collection; -import org.opengis.metadata.quality.ConformanceResult; -import org.opengis.metadata.quality.Result; - -// Test dependencies -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; -import org.apache.sis.test.TestUtilities; -import org.apache.sis.test.TestCase; - - -/** - * Tests the {@link PositionalAccuracyConstant} class. - * - * @author Martin Desruisseaux (IRD, Geomatys) - */ -public final class PositionalAccuracyConstantTest extends TestCase { - /** - * Creates a new test case. - */ - public PositionalAccuracyConstantTest() { - } - - /** - * Tests {@link PositionalAccuracyConstant} constants. - */ - @Test - public void testPositionalAccuracy() { - assertEquals(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, - PositionalAccuracyConstant.DATUM_SHIFT_APPLIED); - - assertEquals(PositionalAccuracyConstant.DATUM_SHIFT_OMITTED, - PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); - - assertNotSame(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, - PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); - - final Collection<? extends Result> appliedResults = PositionalAccuracyConstant.DATUM_SHIFT_APPLIED.getResults(); - final Collection<? extends Result> omittedResults = PositionalAccuracyConstant.DATUM_SHIFT_OMITTED.getResults(); - final ConformanceResult applied = (ConformanceResult) TestUtilities.getSingleton(appliedResults); - final ConformanceResult omitted = (ConformanceResult) TestUtilities.getSingleton(omittedResults); - assertNotSame(applied, omitted); - assertTrue (applied.pass(), "DATUM_SHIFT_APPLIED"); - assertFalse(omitted.pass(), "DATUM_SHIFT_OMITTED"); - assertNotEquals(applied, omitted); - assertNotEquals(appliedResults, omittedResults); - assertNotEquals(PositionalAccuracyConstant.DATUM_SHIFT_APPLIED, - PositionalAccuracyConstant.DATUM_SHIFT_OMITTED); - } -} diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/WeakValueHashMap.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/WeakValueHashMap.java index c340b0bf34..da842d5b1c 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/WeakValueHashMap.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/collection/WeakValueHashMap.java @@ -569,6 +569,30 @@ public class WeakValueHashMap<K,V> extends AbstractMap<K,V> { return intern(key, value, Wildcard.NO_VALUE); } + /** + * Returns the value associated to the given key, computing the value if it does not exist. + * This implementation is thread-safe. + * + * @param key key of the value to get. + * @param creator function to invoke for creating the value if it does not already exist. + * @return value (potentially newly created) for the given key. + * @since 1.5 + */ + @Override + public V computeIfAbsent(final K key, final Function<? super K, ? extends V> creator) { + V value = get(key); + if (value == null) { + V newValue = creator.apply(key); + if (newValue != null) { + value = putIfAbsent(key, newValue); // A value may have been created concurrently. + if (value == null) { + return newValue; + } + } + } + return value; + } + /** * Replaces the entry for the specified key only if it is currently mapped to some value. * diff --git a/netbeans-project/nbproject/project.properties b/netbeans-project/nbproject/project.properties index 49c7f7a4a4..46801fed4b 100644 --- a/netbeans-project/nbproject/project.properties +++ b/netbeans-project/nbproject/project.properties @@ -110,6 +110,7 @@ test.options = --add-modules jama,GeographicLib.Java,\ --add-exports org.apache.sis.metadata/org.apache.sis.xml.privy=org.apache.sis.storage.geotiff \ --add-exports org.apache.sis.metadata/org.apache.sis.xml.bind.gcx=org.apache.sis.referencing \ --add-exports org.apache.sis.metadata/org.apache.sis.metadata.privy=org.apache.sis.referencing.gazetteer \ + --add-exports org.apache.sis.referencing/org.apache.sis.referencing.internal=org.apache.sis.openoffice \ --add-exports org.apache.sis.feature/org.apache.sis.feature.privy=org.apache.sis.storage.sql \ --add-exports org.apache.sis.feature/org.apache.sis.geometry.wrapper.jts=org.apache.sis.storage.sql,org.apache.sis.portrayal.map \ --add-exports org.apache.sis.storage/org.apache.sis.storage.base=org.apache.sis.portrayal.map \