sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/01: Merge branch 'geoapi-3.1'.
Date Mon, 15 Oct 2018 08:48:36 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 28a9f6452a368743aee0a2a36988869ecdd515f0
Merge: 6717af9 eaaec69
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Oct 15 10:47:59 2018 +0200

    Merge branch 'geoapi-3.1'.

 .gitignore                                         |  18 +-
 .../org/apache/sis/openoffice/Registration.java    |   4 +-
 .../org/apache/sis/feature/AbstractAttribute.java  |  10 +-
 .../org/apache/sis/feature/AbstractFeature.java    |   4 +-
 .../org/apache/sis/feature/DefaultFeatureType.java |  12 +-
 .../java/org/apache/sis/feature/FeatureFormat.java |  28 +-
 .../java/org/apache/sis/feature/FieldType.java     |   2 +-
 .../org/apache/sis/feature/PropertySingleton.java  |   4 +-
 .../java/org/apache/sis/feature/Validator.java     |   2 +-
 .../sis/feature/builder/AttributeTypeBuilder.java  |   2 +-
 .../sis/feature/builder/FeatureTypeBuilder.java    |  33 +-
 .../sis/feature/builder/OperationWrapper.java      |   2 +-
 .../apache/sis/feature/builder/package-info.java   |  14 +-
 .../java/org/apache/sis/feature/package-info.java  |   2 +-
 .../sis/feature/DefaultAttributeTypeTest.java      |   2 +-
 .../apache/sis/feature/DefaultFeatureTypeTest.java |   4 +-
 .../org/apache/sis/feature/FeatureFormatTest.java  |  52 +--
 .../org/apache/sis/feature/FeatureTestCase.java    |  14 +-
 .../sis/feature/MultiValuedAttributeTest.java      |   2 +-
 .../builder/AssociationRoleBuilderTest.java        |   2 +-
 .../apache/sis/internal/jaxb/TypeRegistration.java | 133 +++++---
 .../internal/jaxb/metadata/RS_ReferenceSystem.java |   5 +-
 .../sis/internal/metadata/AxisDirections.java      |  41 +--
 .../sis/internal/metadata/MetadataTypes.java       |  13 +-
 .../apache/sis/internal/xml/LegacyNamespaces.java  |   6 +
 .../org/apache/sis/metadata/KeyNamePolicy.java     |   2 +-
 .../apache/sis/metadata/PropertyComparator.java    |   2 +-
 .../org/apache/sis/metadata/TitleProperty.java     |   2 +-
 .../org/apache/sis/metadata/iso/ISOMetadata.java   |   4 +-
 .../org/apache/sis/util/iso/DefaultRecord.java     |   2 +-
 .../main/java/org/apache/sis/util/iso/Names.java   |   4 +-
 .../java/org/apache/sis/xml/MarshallerPool.java    |   2 +-
 .../src/main/java/org/apache/sis/xml/Pooled.java   |  10 +-
 .../java/org/apache/sis/xml/PooledMarshaller.java  |  10 +-
 .../main/java/org/apache/sis/xml/Transformer.java  | 176 ++++++----
 .../org/apache/sis/xml/TransformingNamespaces.java |   2 -
 .../org/apache/sis/xml/TransformingReader.java     |  55 ++--
 .../org/apache/sis/xml/TransformingWriter.java     |   9 +-
 .../src/main/java/org/apache/sis/xml/readme.html   |  79 +++++
 .../org/apache/sis/xml/RenameOnExport.lst          |  15 +-
 .../org/apache/sis/xml/RenameOnImport.lst          | 363 ++++-----------------
 .../apache/sis/metadata/TreeTableFormatTest.java   |   4 +-
 .../apache/sis/test/suite/MetadataTestSuite.java   |   1 +
 .../java/org/apache/sis/xml/TransformerTest.java   |  63 ++++
 .../apache/sis/xml/TransformingNamespacesTest.java |   1 -
 .../org/apache/sis/coverage/grid/GridExtent.java   | 102 ++++++
 .../org/apache/sis/coverage/grid/GridGeometry.java | 137 ++++++--
 .../apache/sis/coverage/grid/GridExtentTest.java   |  80 +++++
 .../apache/sis/coverage/grid/GridGeometryTest.java |  21 ++
 .../org/apache/sis/test/suite/RasterTestSuite.java |   1 +
 .../org/apache/sis/geometry/ArrayEnvelope.java     |   2 +-
 .../org/apache/sis/geometry/DirectPosition2D.java  |   2 +-
 .../java/org/apache/sis/geometry/Envelopes.java    |  67 +++-
 .../org/apache/sis/geometry/GeneralEnvelope.java   |  26 +-
 .../java/org/apache/sis/geometry/Shapes2D.java     |   2 +-
 .../sis/internal/referencing/ReferencingTypes.java |  16 +-
 .../internal/referencing/j2d/ShapeUtilities.java   |   2 +-
 .../provider/DatumShiftGridCompressed.java         |   4 +-
 .../referencing/provider/DatumShiftGridFile.java   |  12 +-
 .../provider/FranceGeocentricInterpolation.java    |   2 +-
 .../sis/internal/referencing/provider/NTv2.java    |  33 +-
 .../sis/parameter/DefaultParameterValueGroup.java  |   2 +-
 .../org/apache/sis/parameter/ParameterBuilder.java |  14 +-
 .../apache/sis/parameter/ParameterValueList.java   |   2 +-
 .../java/org/apache/sis/parameter/Verifier.java    |  49 +--
 .../java/org/apache/sis/referencing/Builder.java   |   4 +-
 .../main/java/org/apache/sis/referencing/CRS.java  |   3 +
 .../sis/referencing/StandardDefinitions.java       |   2 +-
 .../apache/sis/referencing/crs/AbstractCRS.java    |   2 +-
 .../sis/referencing/crs/DefaultDerivedCRS.java     |   2 +-
 .../sis/referencing/datum/BursaWolfParameters.java |   2 +-
 .../sis/referencing/datum/DatumShiftGrid.java      |   6 +-
 .../factory/LazySynchronizedIterator.java          |   2 +-
 .../factory/MultiAuthoritiesFactory.java           |   4 +-
 .../sis/referencing/factory/sql/package-info.java  |   2 +-
 .../operation/builder/LinearTransformBuilder.java  | 343 ++++++++++++++++++-
 .../operation/builder/LocalizationGridBuilder.java | 110 ++++++-
 .../operation/builder/ResidualGrid.java            |   4 +-
 .../sis/referencing/operation/matrix/Matrices.java |   2 +-
 .../referencing/operation/matrix/MatrixSIS.java    |   2 +-
 .../sis/referencing/operation/matrix/Solver.java   |   2 +-
 .../transform/AbstractLinearTransform.java         |   2 +-
 .../operation/transform/AbstractMathTransform.java |   2 +-
 .../operation/transform/MathTransforms.java        |  25 +-
 .../operation/transform/TransformSeparator.java    |   4 +-
 .../org/apache/sis/geometry/EnvelopesTest.java     |  38 ++-
 .../apache/sis/geometry/GeneralEnvelopeTest.java   |  20 +-
 .../sis/internal/metadata/AxisDirectionsTest.java  |  10 +-
 .../parameter/DefaultParameterValueGroupTest.java  |  16 +-
 .../referencing/factory/sql/EPSGInstallerTest.java |  27 ++
 .../builder/LinearTransformBuilderTest.java        |  81 ++++-
 .../builder/LocalizationGridBuilderTest.java       |  41 ++-
 .../operation/builder/ResidualGridTest.java        | 152 +++++++++
 .../projection/ConformalProjectionTest.java        |   2 +-
 .../projection/LambertConicConformalTest.java      |  36 +-
 .../operation/projection/MercatorTest.java         |   8 +-
 .../sis/test/suite/ReferencingTestSuite.java       |   1 +
 .../sis/internal/converter/FallbackConverter.java  |   2 +-
 .../sis/internal/system/DelayedExecutor.java       |   2 +-
 .../sis/internal/system/DelayedRunnable.java       |  14 +-
 .../org/apache/sis/internal/util/Citations.java    |   2 +-
 .../org/apache/sis/internal/util/Numerics.java     |  21 ++
 .../java/org/apache/sis/io/CompoundFormat.java     |  52 +--
 .../main/java/org/apache/sis/io/DefaultFormat.java |  13 +-
 .../java/org/apache/sis/math/DecimalFunctions.java |   6 +-
 .../org/apache/sis/measure/ConventionalUnit.java   | 113 +++++--
 .../java/org/apache/sis/measure/NumberRange.java   |  15 +-
 .../main/java/org/apache/sis/measure/Range.java    |   2 +-
 .../java/org/apache/sis/measure/SystemUnit.java    |  98 ++++--
 .../java/org/apache/sis/measure/UnitFormat.java    |  72 ++--
 .../main/java/org/apache/sis/measure/Units.java    |   2 +-
 .../main/java/org/apache/sis/util/Characters.java  |  16 +-
 .../java/org/apache/sis/util/ObjectConverter.java  |   2 +-
 .../util/UnsupportedImplementationException.java   |   2 +-
 .../java/org/apache/sis/util/collection/Cache.java |   2 +-
 .../org/apache/sis/util/collection/Containers.java |  14 +-
 .../sis/util/collection/TreeTableFormat.java       |  80 ++++-
 .../apache/sis/util/logging/MonolineFormatter.java |  73 ++++-
 .../java/org/apache/sis/util/resources/Errors.java |   7 +-
 .../apache/sis/util/resources/Errors.properties    |   3 +-
 .../apache/sis/util/resources/Errors_fr.properties |   1 +
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../org/apache/sis/internal/util/NumericsTest.java |  11 +
 .../org/apache/sis/measure/UnitFormatTest.java     |  79 ++++-
 .../java/org/apache/sis/test/TestUtilities.java    |   2 +-
 .../sis/util/logging/MonolineFormatterTest.java    |  13 +-
 ide-project/NetBeans/build.xml                     |  10 +
 ide-project/NetBeans/nbproject/project.properties  |  15 +-
 pom.xml                                            |  25 +-
 .../sis/internal/profile/fra/ProfileTypes.java     |  14 +-
 .../sis/internal/profile/fra/package-info.java     |   2 +-
 .../sis/internal/profile/fra/RenameOnImport.lst    |  13 +
 .../profile/fra/DataIdentificationTest.java        |   2 -
 src/main/config/logging.properties                 |  21 +-
 .../sis/storage/earthobservation/LandsatStore.java |  69 ++--
 .../apache/sis/storage/geotiff/GeoTiffStore.java   | 105 +++++-
 .../sis/storage/geotiff/ImageFileDirectory.java    |  24 +-
 .../apache/sis/storage/geotiff/Localization.java   |   2 +-
 .../org/apache/sis/storage/geotiff/Reader.java     |  20 +-
 .../org/apache/sis/internal/netcdf/Decoder.java    |  27 +-
 .../sis/internal/netcdf/impl/ChannelDecoder.java   |   4 +-
 .../sis/internal/netcdf/impl/FeaturesInfo.java     |  36 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |   4 +-
 .../sis/internal/netcdf/ucar/FeaturesWrapper.java  |   8 +-
 .../apache/sis/storage/netcdf/MetadataReader.java  |  18 +-
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |  29 ++
 .../apache/sis/internal/sql/feature/Database.java  |   6 +-
 .../org/apache/sis/internal/sql/feature/Table.java |  10 +-
 .../java/org/apache/sis/storage/sql/SQLStore.java  |  44 ++-
 .../org/apache/sis/index/tree/QuadTreeWriter.java  |  17 +-
 .../sis/internal/storage/AbstractResource.java     |  78 ++++-
 .../sis/internal/storage/MemoryFeatureSet.java     |  13 +-
 .../sis/internal/storage/StoreUtilities.java       |  46 ++-
 .../org/apache/sis/internal/storage/csv/Store.java |  12 +
 .../apache/sis/internal/storage/folder/Store.java  |  62 +++-
 .../sis/internal/storage/folder/WritableStore.java |   8 +-
 .../sis/internal/storage/query/FeatureSubset.java  |   9 +
 .../sis/internal/storage/xml/StoreProvider.java    |   1 +
 .../java/org/apache/sis/storage/DataStore.java     | 190 +++++++----
 .../java/org/apache/sis/storage/FeatureSet.java    |   2 +-
 .../apache/sis/storage/IllegalNameException.java   |   3 +
 .../main/java/org/apache/sis/storage/Resource.java |  28 +-
 .../java/org/apache/sis/storage/DataStoreMock.java |   4 +-
 .../storage/gpx/GroupAsPolylineOperation.java      |   8 +-
 .../org/apache/sis/internal/storage/gpx/Types.java | 144 ++++----
 167 files changed, 3367 insertions(+), 1242 deletions(-)

diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
index c8cde2e,04a7cb4..e017104
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
@@@ -702,20 -715,17 +702,20 @@@ public class DefaultFeatureType extend
              /*
               * If the base property is an attribute, then the overriding property shall
be either an attribute
               * or a parameterless operation producing an attribute.  The parameterless operation
is considered
-              * has having a [1…1] cardinality.
+              * has having a [1…1] multiplicity.
 +             *
 +             * Note: other SIS branches use AttributeType and FeatureAssociationRole
 +             *       instead than DefaultAttributeType and DefaultAssociationRole.
               */
 -            if (base instanceof AttributeType<?>) {
 -                final AttributeType<?> p0 = (AttributeType<?>) base;
 -                final AttributeType<?> p1;
 -                if (other instanceof AttributeType<?>) {
 -                    p1 = (AttributeType<?>) other;
 +            if (base instanceof DefaultAttributeType<?>) {
 +                final DefaultAttributeType<?> p0 = (DefaultAttributeType<?>)
base;
 +                final DefaultAttributeType<?> p1;
 +                if (other instanceof DefaultAttributeType<?>) {
 +                    p1 = (DefaultAttributeType<?>) other;
                  } else if (isParameterlessOperation(other)) {
 -                    final IdentifiedType result = ((Operation) other).getResult();
 -                    if (result instanceof AttributeType<?>) {
 -                        p1 = (AttributeType<?>) result;
 +                    final AbstractIdentifiedType result = ((AbstractOperation) other).getResult();
 +                    if (result instanceof DefaultAttributeType<?>) {
 +                        p1 = (DefaultAttributeType<?>) result;
                      } else {
                          return false;
                      }
diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
index ea54a85,c3c9fb7..90ffcd0
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
@@@ -49,8 -49,18 +49,6 @@@ import org.apache.sis.internal.system.M
  import org.apache.sis.referencing.IdentifiedObjects;
  import org.apache.sis.math.MathFunctions;
  
--// Branch-dependent imports
 -import org.opengis.feature.IdentifiedType;
 -import org.opengis.feature.Property;
 -import org.opengis.feature.PropertyType;
 -import org.opengis.feature.Attribute;
 -import org.opengis.feature.AttributeType;
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureType;
 -import org.opengis.feature.FeatureAssociation;
 -import org.opengis.feature.FeatureAssociationRole;
 -import org.opengis.feature.Operation;
--
  
  /**
   * Formats {@linkplain AbstractFeature features} or {@linkplain DefaultFeatureType feature
types} in a tabular format.
@@@ -233,8 -243,11 +231,11 @@@ public class FeatureFormat extends Tabu
          TYPE(Vocabulary.Keys.Type),
  
          /**
-          * The minimum and maximum occurrences of attribute values. This is made from the
numbers returned
-          * by {@link DefaultAttributeType#getMinimumOccurs()} and {@link DefaultAttributeType#getMaximumOccurs()}.
+          * Cardinality (for attributes) or multiplicity (for attribute types).
+          * The cardinality is the actual number of attribute values.
+          * The multiplicity is the minimum and maximum occurrences of attribute values.
 -         * The multiplicity is made from the numbers returned by {@link AttributeType#getMinimumOccurs()}
 -         * and {@link AttributeType#getMaximumOccurs()}.
++         * The multiplicity is made from the numbers returned by {@link DefaultAttributeType#getMinimumOccurs()}
++         * and {@link DefaultAttributeType#getMaximumOccurs()}.
           */
          CARDINALITY(Vocabulary.Keys.Cardinality),
  
diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
index ca89ef2,022a8bd..68adf1e
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
@@@ -21,9 -21,12 +21,9 @@@ import java.util.Iterator
  import org.opengis.util.GenericName;
  import org.apache.sis.util.resources.Errors;
  
 -// Branch-dependent imports
 -import org.opengis.feature.PropertyType;
 -
  
  /**
-  * Base class of property types having a value and a cardinality.
+  * Base class of property types having a value and a multiplicity.
   * This include {@code AttributeType} and {@code AssociationRole}, but not {@code Operation}.
   *
   * <div class="note"><b>Analogy:</b> if we compare {@code FeatureType}
to a class in the Java language,
diff --cc core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
index cc456e5,166adb6..fc5c6d7
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
@@@ -63,8 -65,8 +63,8 @@@ import org.apache.sis.feature.DefaultAt
   *   <li>Methods for optionally specifying the feature type hierarchy: its {@linkplain
#setSuperTypes super types}
   *       and whether the feature type is {@linkplain #setAbstract abstract}.</li>
   *   <li>Convenience methods for setting the {@linkplain #setNameSpace name space}
and the
-  *       {@linkplain #setDefaultCardinality default cardinality} of properties to be added
to the feature type.</li>
+  *       {@linkplain #setDefaultMultiplicity default multiplicity} of properties to be added
to the feature type.</li>
 - *   <li>Methods for {@linkplain #addAttribute(Class) adding an attribute}, {@linkplain
#addAssociation(FeatureType)
 + *   <li>Methods for {@linkplain #addAttribute(Class) adding an attribute}, {@linkplain
#addAssociation(DefaultFeatureType)
   *       an association} or {@linkplain #addProperty an operation}.</li>
   *   <li>Method for listing the previously added {@linkplain #properties() properties}.</li>
   *   <li>A {@link #build()} method for creating the {@code FeatureType} instance from
all previous information.</li>
diff --cc core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index c30c444,aeefa6e..e4efea7
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@@ -252,8 -353,10 +350,10 @@@ public class GridExtent implements Seri
       * @param  extent  the grid envelope to copy.
       * @throws IllegalArgumentException if a coordinate value in the low part is
       *         greater than the corresponding coordinate value in the high part.
+      *
+      * @see #castOrCopy(GridEnvelope)
       */
 -    protected GridExtent(final GridEnvelope extent) {
 +    protected GridExtent(final GridExtent extent) {
          ArgumentChecks.ensureNonNull("extent", extent);
          final int dimension = extent.getDimension();
          ordinates = allocate(dimension);
diff --cc core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/ResidualGridTest.java
index 0000000,b15d4f0..720dccd
mode 000000,100644..100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/ResidualGridTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/ResidualGridTest.java
@@@ -1,0 -1,152 +1,152 @@@
+ /*
+  * 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.operation.builder;
+ 
+ import org.apache.sis.referencing.operation.matrix.Matrix2;
+ import org.opengis.referencing.operation.Matrix;
+ import org.opengis.referencing.operation.TransformException;
+ import org.apache.sis.referencing.operation.transform.MathTransforms;
+ import org.apache.sis.test.DependsOnMethod;
+ import org.apache.sis.test.TestCase;
+ import org.junit.Test;
+ 
 -import static org.opengis.test.Assert.*;
++import static org.apache.sis.test.Assert.*;
+ 
+ 
+ /**
+  * Tests {@link ResidualGrid}.
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @version 1.0
+  * @since   1.0
+  * @module
+  */
+ public final strictfp class ResidualGridTest extends TestCase {
+     /**
+      * The grid to test.
+      */
+     private final ResidualGrid grid;
+ 
+     /**
+      * Creates a new test case with a 3×4 grid with 2 values in each cells.
+      * Those two values are typically the horizontal components of translation vectors.
+      * The grid has no "source to grid" or "grid to CRS" transformations.
+      */
+     public ResidualGridTest() {
+         grid = new ResidualGrid(MathTransforms.identity(2), MathTransforms.identity(2),
3, 4, 2, new double[] {
+                 0,2  ,  1,2  ,  2,1,
+                 1,3  ,  2,2  ,  1,1,
+                 0,4  ,  2,3  ,  3,2,
+                 1,4  ,  3,3  ,  3,2}, 0.1);
+     }
+ 
+     /**
+      * Verifies some global properties.
+      */
+     @Test
+     public void verifyGlobalProperties() {
+         assertEquals("translationDimensions", 2,  grid.getTranslationDimensions());
+         assertTrue("coordinateToGrid.isIdentity", grid.getCoordinateToGrid().isIdentity());
+         assertTrue("gridToTarget.isIdentity",     grid.gridToTarget().isIdentity());
+     }
+ 
+     /**
+      * Tests {@link ResidualGrid#getCellValue(int, int, int)}.
+      * That method fetches values directly, without interpolations.
+      */
+     @Test
+     public void testGetCellValue() {
+         assertEquals(0, grid.getCellValue(0, 0, 0), STRICT);
+         assertEquals(2, grid.getCellValue(1, 0, 0), STRICT);
+         assertEquals(1, grid.getCellValue(0, 1, 0), STRICT);
+         assertEquals(2, grid.getCellValue(1, 1, 0), STRICT);
+         assertEquals(2, grid.getCellValue(0, 2, 0), STRICT);
+         assertEquals(1, grid.getCellValue(1, 2, 0), STRICT);
+         assertEquals(1, grid.getCellValue(0, 0, 3), STRICT);
+         assertEquals(4, grid.getCellValue(1, 0, 3), STRICT);
+         assertEquals(3, grid.getCellValue(0, 2, 3), STRICT);
+         assertEquals(2, grid.getCellValue(1, 2, 3), STRICT);
+     }
+ 
+     /**
+      * Tests {@link ResidualGrid#interpolateAt(double...)} without interpolation.
+      * This test checks the same values than {@link #testGetCellValue()}.
+      *
+      * @throws TransformException if an error occurred while transforming a coordinate.
+      */
+     @Test
+     @DependsOnMethod("testGetCellValue")
+     public void testInterpolateAtExactLocation() throws TransformException {
+         assertArrayEquals(new double[] {0, 2}, grid.interpolateAt(0, 0), STRICT);
+         assertArrayEquals(new double[] {1, 2}, grid.interpolateAt(1, 0), STRICT);
+         assertArrayEquals(new double[] {2, 1}, grid.interpolateAt(2, 0), STRICT);
+         assertArrayEquals(new double[] {1, 4}, grid.interpolateAt(0, 3), STRICT);
+         assertArrayEquals(new double[] {3, 2}, grid.interpolateAt(2, 3), STRICT);
+     }
+ 
+     /**
+      * Tests {@link ResidualGrid#interpolateAt(double...)} at the median point between cells.
+      * The result in this special case is equivalent to the average of all 4 surrounding
cells.
+      *
+      * @throws TransformException if an error occurred while transforming a coordinate.
+      */
+     @Test
+     @DependsOnMethod("testInterpolateAtExactLocation")
+     public void testInterpolateAtIntersection() throws TransformException {
+         assertArrayEquals(new double[] {1,    2.25}, grid.interpolateAt(0.5, 0.5), STRICT);
+         assertArrayEquals(new double[] {1.5,  1.5 }, grid.interpolateAt(1.5, 0.5), STRICT);
+         assertArrayEquals(new double[] {1.25, 3   }, grid.interpolateAt(0.5, 1.5), STRICT);
+         assertArrayEquals(new double[] {2,    2   }, grid.interpolateAt(1.5, 1.5), STRICT);
+         assertArrayEquals(new double[] {1.5,  3.5 }, grid.interpolateAt(0.5, 2.5), STRICT);
+         assertArrayEquals(new double[] {2.75, 2.5 }, grid.interpolateAt(1.5, 2.5), STRICT);
+     }
+ 
+     /**
+      * Tests {@link ResidualGrid#interpolateAt(double...)} at other locations.
+      *
+      * @throws TransformException if an error occurred while transforming a coordinate.
+      */
+     @Test
+     @DependsOnMethod("testInterpolateAtIntersection")
+     public void testInterpolateAt() throws TransformException {
+         assertArrayEquals(new double[] {0.25,  2   }, grid.interpolateAt(0.25, 0   ), STRICT);
+         assertArrayEquals(new double[] {1.75,  1.25}, grid.interpolateAt(1.75, 0   ), STRICT);
+         assertArrayEquals(new double[] {1.25,  2   }, grid.interpolateAt(1,    0.25), STRICT);
+         assertArrayEquals(new double[] {1.625, 1.25}, grid.interpolateAt(1.75, 0.25), STRICT);
+     }
+ 
+     /**
+      * Tests {@link ResidualGrid#derivativeInCell(double, double)}.
+      * The Jacobian is computed with those values:
+      *
+      * {@preformat text
+      *   (0,4)   (2,3)
+      *   (1,4)   (3,3)
+      * }
+      *
+      * So this mean for example that when moving from 1 cell to the right, the residual
change from (0,4) to (2,3).
+      * Consequently the <var>x</var> position is increased from (2-0) = 2 cells
in addition to the move to the right
+      * (so the total increase is 3), and the <var>y</var> position is increased
from (3-4) = -1.
+      */
+     @Test
+     @DependsOnMethod("testGetCellValue")
+     public void testDerivativeInCell() {
+         final Matrix expected = new Matrix2(3, 1, -1, 1);
+         final Matrix actual = grid.derivativeInCell(0.5, 2.5);
+         assertMatrixEquals("derivativeInCell", expected, actual, STRICT);
+     }
+ }
diff --cc storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
index 45dd2ae,7256bc3..60a5da1
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Decoder.java
@@@ -25,7 -27,8 +27,11 @@@ import org.apache.sis.setup.GeometryLib
  import org.apache.sis.storage.DataStore;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.util.logging.WarningListeners;
+ import org.apache.sis.internal.system.DefaultFactories;
+ 
++// Branch-dependent imports
++import org.apache.sis.util.iso.DefaultNameFactory;
 +
  
  /**
   * The API used internally by Apache SIS for fetching variables and attribute values from
a netCDF file.
@@@ -40,6 -43,18 +46,18 @@@
   */
  public abstract class Decoder implements Closeable {
      /**
+      * The data store identifier created from the global attributes, or {@code null} if
none.
+      * Defined as a namespace for use as the scope of children resources (the variables).
+      * This is set by netCDF store constructor and shall not be modified afterward.
+      */
+     public NameSpace namespace;
+ 
+     /**
+      * The factory to use for creating variable identifiers.
+      */
 -    public final NameFactory nameFactory;
++    public final DefaultNameFactory nameFactory;
+ 
+     /**
       * The library for geometric objects, or {@code null} for the default.
       * This will be used only if there is geometric objects to create.
       * If the netCDF file contains only raster data, this value is ignored.
@@@ -65,8 -80,9 +83,9 @@@
       */
      protected Decoder(final GeometryLibrary geomlib, final WarningListeners<DataStore>
listeners) {
          Objects.requireNonNull(listeners);
-         this.geomlib   = geomlib;
-         this.listeners = listeners;
+         this.geomlib     = geomlib;
+         this.listeners   = listeners;
 -        this.nameFactory = DefaultFactories.forBuildin(NameFactory.class);
++        this.nameFactory = DefaultFactories.forBuildin(NameFactory.class, DefaultNameFactory.class);
      }
  
      /**
diff --cc storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
index f1aac19,d3b9fa2..5ef53bf
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
@@@ -33,11 -34,10 +34,8 @@@ import org.apache.sis.internal.netcdf.D
  import org.apache.sis.internal.netcdf.DiscreteSampling;
  import org.apache.sis.internal.netcdf.Resources;
  import org.apache.sis.internal.feature.MovingFeature;
- import org.apache.sis.storage.DataStore;
  import org.apache.sis.storage.DataStoreException;
 -import org.apache.sis.feature.DefaultFeatureType;
 -import org.apache.sis.feature.DefaultAttributeType;
  import org.apache.sis.util.collection.BackingStoreException;
- import org.apache.sis.util.logging.WarningListeners;
- import org.apache.sis.setup.GeometryLibrary;
  import ucar.nc2.constants.CF;
  
  // Branch-dependent imports
diff --cc storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
index b6aeb29,226c977..2615bbe
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/FeaturesWrapper.java
@@@ -55,7 -56,12 +56,12 @@@ final class FeaturesWrapper extends Dis
      }
  
      @Override
+     public GenericName getIdentifier() {
+         throw new UnsupportedOperationException();      // TODO
+     }
+ 
+     @Override
 -    public FeatureType getType() {
 +    public DefaultFeatureType getType() {
          throw new UnsupportedOperationException();      // TODO
      }
  
diff --cc storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index 77481ca,1512ed6..be1ee25
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@@ -35,7 -35,7 +35,6 @@@ import javax.measure.IncommensurableExc
  import javax.measure.format.ParserException;
  
  import org.opengis.util.CodeList;
--import org.opengis.util.NameFactory;
  import org.opengis.util.InternationalString;
  import org.opengis.metadata.Metadata;
  import org.opengis.metadata.Identifier;
@@@ -930,12 -927,8 +920,8 @@@ split:  while ((start = CharSequences.s
          newSampleDimension();
          final String name = trim(variable.getName());
          if (name != null) {
-             if (nameFactory == null) {
-                 nameFactory = DefaultFactories.forBuildin(NameFactory.class, DefaultNameFactory.class);
-                 // Real dependency injection to be used in a future version.
-             }
-             setBandIdentifier(nameFactory.createMemberName(null, name,
-                     nameFactory.createTypeName(null, variable.getDataTypeName())));
 -            final NameFactory f = decoder.nameFactory;
++            final DefaultNameFactory f = decoder.nameFactory;
+             setBandIdentifier(f.createMemberName(null, name, f.createTypeName(null, variable.getDataTypeName())));
          }
          Object[] v = variable.getAttributeValues(CF.STANDARD_NAME, false);
          final String id = (v.length == 1) ? trim((String) v[0]) : null;
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
index da2d5a2,511d86a..f195e93
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
@@@ -32,9 -36,6 +36,10 @@@ import org.apache.sis.storage.DataStore
  import org.apache.sis.storage.event.ChangeEvent;
  import org.apache.sis.storage.event.ChangeListener;
  
 +// Branch-dependent imports
++import org.opengis.referencing.ReferenceIdentifier;
 +import org.opengis.metadata.identification.DataIdentification;
 +
  
  /**
   * Base implementation of resources contained in data stores.
@@@ -93,6 -97,58 +101,58 @@@ public abstract class AbstractResource 
      }
  
      /**
+      * Returns an identifier for this resource. The default implementation returns the first
identifier
+      * of {@code Metadata/​identificationInfo/​citation}, provided that exactly one
such citation is found.
+      * If more than one citation is found, then this method returns {@code null} since the
identification
+      * is considered ambiguous. This is the same default implementation than {@link DataStore#getIdentifier()}.
+      *
+      * @return the resource identifier inferred from metadata, or {@code null} if none or
ambiguous.
+      * @throws DataStoreException if an error occurred while fetching the identifier.
+      *
+      * @see DataStore#getIdentifier()
+      */
+     @Override
+     public GenericName getIdentifier() throws DataStoreException {
+         return identifier(getMetadata());
+     }
+ 
+     /**
+      * Implementation of {@link #getIdentifier()}, provided as a separated method for implementations
+      * that do not extend {@code AbstractResource}.
+      *
+      * @param  metadata  the metadata from which to infer the identifier, or {@code null}.
+      * @return the resource identifier inferred from metadata, or {@code null} if none or
ambiguous.
+      *
+      * @see StoreUtilities#getAnyIdentifier(Metadata, boolean)
+      */
+     public static GenericName identifier(final Metadata metadata) {
+         if (metadata != null) {
+             Citation citation = null;
+             for (final Identification id : metadata.getIdentificationInfo()) {
+                 final Citation c = id.getCitation();
+                 if (c != null) {
+                     if (citation != null && citation != c) return null;        
        // Ambiguity.
+                     citation = c;
+                 }
+             }
+             if (citation != null) {
 -                Identifier first = null;
++                ReferenceIdentifier first = null;
+                 for (final Identifier c : citation.getIdentifiers()) {
+                     if (c instanceof GenericName) {
+                         return (GenericName) c;
 -                    } else if (first == null) {
 -                        first = c;
++                    } else if (first == null && c instanceof ReferenceIdentifier)
{
++                        first = (ReferenceIdentifier) c;
+                     }
+                 }
+                 if (first != null) {
+                     return new NamedIdentifier(first);
+                 }
+             }
+         }
+         return null;
+     }
+ 
+     /**
       * Returns the spatio-temporal envelope of this resource.
       * The default implementation computes the union of all {@link GeographicBoundingBox}
in the resource metadata,
       * assuming the {@linkplain org.apache.sis.referencing.CommonCRS#defaultGeographic()
default geographic CRS}
@@@ -116,18 -174,14 +178,16 @@@
          GeneralEnvelope bounds = null;
          if (metadata != null) {
              for (final Identification identification : metadata.getIdentificationInfo())
{
 -                for (final Extent extent : identification.getExtents()) {
 -                    for (final GeographicExtent ge : extent.getGeographicElements()) {
 -                        if (ge instanceof GeographicBoundingBox) {
 -                            final GeneralEnvelope env = new GeneralEnvelope((GeographicBoundingBox)
ge);
 -                            if (bounds == null) {
 -                                bounds = env;
 -                            } else {
 -                                bounds.add(env);
 +                if (identification instanceof DataIdentification) {
 +                    for (final Extent extent : ((DataIdentification) identification).getExtents())
{
-                         if (extent != null) {                                          
    // Paranoiac check.
-                             for (final GeographicExtent ge : extent.getGeographicElements())
{
-                                 if (ge instanceof GeographicBoundingBox) {
-                                     final GeneralEnvelope env = new GeneralEnvelope((GeographicBoundingBox)
ge);
-                                     if (bounds == null) {
-                                         bounds = env;
-                                     } else {
-                                         bounds.add(env);
-                                     }
++                        for (final GeographicExtent ge : extent.getGeographicElements())
{
++                            if (ge instanceof GeographicBoundingBox) {
++                                final GeneralEnvelope env = new GeneralEnvelope((GeographicBoundingBox)
ge);
++                                if (bounds == null) {
++                                    bounds = env;
++                                } else {
++                                    bounds.add(env);
 +                                }
                              }
                          }
                      }
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryFeatureSet.java
index c3bcf5a,6757d43..b9b1c82
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryFeatureSet.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryFeatureSet.java
@@@ -21,11 -23,10 +23,10 @@@ import org.opengis.metadata.Metadata
  import org.apache.sis.storage.DataStore;
  import org.apache.sis.util.ArgumentChecks;
  import org.apache.sis.util.logging.WarningListeners;
- import org.opengis.metadata.Metadata;
  
  // Branch-dependent imports
 -import org.opengis.feature.Feature;
 -import org.opengis.feature.FeatureType;
 +import org.apache.sis.feature.AbstractFeature;
 +import org.apache.sis.feature.DefaultFeatureType;
  
  
  /**
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
index ec525e8,61e1842..4b4b753
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/folder/Store.java
@@@ -222,11 -263,10 +263,10 @@@ class Store extends DataStore implement
      public synchronized Metadata getMetadata() {
          if (metadata == null) {
              final MetadataBuilder mb = new MetadataBuilder();
-             final String name = getDisplayName();
-             mb.addResourceScope(ScopeCode.valueOf("COLLECTION"), Resources.formatInternational(Resources.Keys.DirectoryContent_1,
name));
 -            mb.addResourceScope(ScopeCode.COLLECTION, Resources.formatInternational(Resources.Keys.DirectoryContent_1,
getDisplayName()));
++            mb.addResourceScope(ScopeCode.valueOf("COLLECTION"), Resources.formatInternational(Resources.Keys.DirectoryContent_1,
getDisplayName()));
              mb.addLanguage(locale,   MetadataBuilder.Scope.RESOURCE);
              mb.addEncoding(encoding, MetadataBuilder.Scope.RESOURCE);
-             mb.addTitleOrIdentifier(name, MetadataBuilder.Scope.ALL);
+             mb.addTitleOrIdentifier(identifier.toString(), MetadataBuilder.Scope.RESOURCE);
              metadata = mb.build(true);
          }
          return metadata;
diff --cc storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/FeatureSubset.java
index 3836a80,cc65820..fa6db66
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/FeatureSubset.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/query/FeatureSubset.java
@@@ -16,8 -16,11 +16,9 @@@
   */
  package org.apache.sis.internal.storage.query;
  
 -import java.util.List;
  import java.util.stream.Stream;
+ import org.opengis.util.GenericName;
  import org.opengis.geometry.Envelope;
 -import org.apache.sis.internal.feature.FeatureUtilities;
  import org.apache.sis.internal.storage.AbstractFeatureSet;
  import org.apache.sis.storage.DataStoreException;
  import org.apache.sis.storage.FeatureSet;
diff --cc storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
index 7d0f7df,4d80617..9ce5d48
--- a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
+++ b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
@@@ -207,23 -207,23 +207,23 @@@ final class Types 
          wayPoint = create(builder, resources);
          /*
           * Route ⇾ GPXEntity
-          * ┌────────────────┬────────────────┬───────────────────────┬─────────────┐
-          * │ Name           │ Type           │ XML type              │ Cardinality
│
-          * ├────────────────┼────────────────┼───────────────────────┼─────────────┤
-          * │ sis:identifier │ Integer        │                       │   [1 …
1]   │
-          * │ sis:envelope   │ Envelope       │                       │   [1 …
1]   │
-          * │ sis:geometry   │ Polyline       │                       │   [1 …
1]   │
-          * │ name           │ String         │ xs:string             │   [0 …
1]   │
-          * │ cmt            │ String         │ xs:string             │   [0 …
1]   │
-          * │ desc           │ String         │ xs:string             │   [0 …
1]   │
-          * │ src            │ String         │ xs:string             │   [0 …
1]   │
-          * │ link           │ OnlineResource │ gpx:linkType          │   [0 …
∞]   │
-          * │ number         │ Integer        │ xs:nonNegativeInteger │   [0 …
1]   │
-          * │ type           │ String         │ xs:string             │   [0 …
1]   │
-          * │ rtept          │ WayPoint       │ gpx:wptType           │   [0 …
∞]   │
-          * └────────────────┴────────────────┴───────────────────────┴─────────────┘
+          * ┌────────────────┬────────────────┬───────────────────────┬──────────────┐
+          * │ Name           │ Type           │ XML type              │ Multiplicity
│
+          * ├────────────────┼────────────────┼───────────────────────┼──────────────┤
+          * │ sis:identifier │ Integer        │                       │   [1 …
1]    │
+          * │ sis:envelope   │ Envelope       │                       │   [1 …
1]    │
+          * │ sis:geometry   │ Polyline       │                       │   [1 …
1]    │
+          * │ name           │ String         │ xs:string             │   [0 …
1]    │
+          * │ cmt            │ String         │ xs:string             │   [0 …
1]    │
+          * │ desc           │ String         │ xs:string             │   [0 …
1]    │
+          * │ src            │ String         │ xs:string             │   [0 …
1]    │
+          * │ link           │ OnlineResource │ gpx:linkType          │   [0 …
∞]    │
+          * │ number         │ Integer        │ xs:nonNegativeInteger │   [0 …
1]    │
+          * │ type           │ String         │ xs:string             │   [0 …
1]    │
+          * │ rtept          │ WayPoint       │ gpx:wptType           │   [0 …
∞]    │
+          * └────────────────┴────────────────┴───────────────────────┴──────────────┘
           */
 -        final AttributeType<?> groupResult = GroupAsPolylineOperation.getResult(geometries);
 +        final DefaultAttributeType<?> groupResult = GroupAsPolylineOperation.getResult(geometries);
          GroupAsPolylineOperation groupOp = new GroupAsPolylineOperation(geomInfo, Tags.ROUTE_POINTS,
groupResult);
          builder.clear().setSuperTypes(parent).setNameSpace(Tags.PREFIX).setName("Route");
          builder.addProperty(groupOp);


Mime
View raw message