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 e0503ad983d9a9e733b7dc8aff2c95f4db5841d9
Merge: 0beabad754 8f4b197bc6
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu May 5 16:04:04 2022 +0200

    Merge branch 'geoapi-3.1'

 .../org/apache/sis/metadata/sql/Dispatcher.java    |   2 +-
 .../MultiResolutionCoverageLoaderTest.java         |   2 +-
 .../referencing/provider/AbstractMercator.java     |  12 +-
 .../referencing/provider/CassiniSoldner.java       |   9 +-
 ...Soldner.java => LambertAzimuthalEqualArea.java} | 108 ++++---
 .../LambertAzimuthalEqualAreaSpherical.java        |  77 +++++
 .../provider/LambertCylindricalEqualArea.java      |   9 +-
 .../internal/referencing/provider/Mercator1SP.java |   9 +-
 .../internal/referencing/provider/Mercator2SP.java |   9 +-
 .../provider/MercatorAuxiliarySphere.java          |  85 +++++
 .../referencing/provider/MillerCylindrical.java    |   2 +-
 .../referencing/provider/ObliqueMercator.java      |   6 +-
 .../referencing/provider/PseudoMercator.java       |   2 +-
 .../java/org/apache/sis/referencing/Builder.java   |  14 +-
 .../operation/projection/AlbersEqualArea.java      |  24 +-
 ...AreaProjection.java => AuthalicConversion.java} | 122 +++++---
 .../operation/projection/AuthalicMercator.java     | 115 +++++++
 .../operation/projection/AzimuthalEquidistant.java |   6 +-
 .../operation/projection/CassiniSoldner.java       |  87 ++++--
 .../operation/projection/ConformalProjection.java  |   8 +-
 .../operation/projection/CylindricalEqualArea.java |  79 +++--
 .../operation/projection/Initializer.java          |  42 ++-
 .../projection/LambertAzimuthalEqualArea.java      | 284 +++++++++++++++++
 .../projection/LambertConicConformal.java          |  95 +++---
 .../referencing/operation/projection/Mercator.java | 135 +++++---
 .../operation/projection/MeridianArcBased.java     |   4 +-
 .../projection/ModifiedAzimuthalEquidistant.java   |   6 +-
 .../operation/projection/Mollweide.java            |  31 +-
 .../operation/projection/NormalizedProjection.java |  95 +++---
 .../operation/projection/ObliqueMercator.java      |  80 +++--
 .../operation/projection/ObliqueStereographic.java |  10 +-
 .../operation/projection/Orthographic.java         |   4 +-
 .../operation/projection/PolarStereographic.java   |  83 +++--
 .../operation/projection/Polyconic.java            |   6 +-
 .../operation/projection/ProjectionVariant.java    |  58 ++++
 .../operation/projection/SatelliteTracking.java    |   4 +-
 .../operation/projection/Sinusoidal.java           |   6 +-
 .../operation/projection/TransverseMercator.java   |  44 ++-
 .../operation/projection/ZonedGridSystem.java      |   2 +-
 ...g.opengis.referencing.operation.OperationMethod |   3 +
 .../referencing/provider/ProvidersTest.java        |   3 +
 ...ectionTest.java => AuthalicConversionTest.java} |  24 +-
 .../operation/projection/InitializerTest.java      |   2 +-
 .../projection/LambertAzimuthalEqualAreaTest.java  | 344 +++++++++++++++++++++
 .../operation/projection/MercatorTest.java         |  72 ++++-
 .../sis/referencing/operation/projection/NoOp.java |   4 +-
 .../projection/ProjectionResultComparator.java     |   2 +-
 .../sis/test/suite/ReferencingTestSuite.java       |   3 +-
 .../org/apache/sis/storage/landsat/BandGroup.java  |   2 +-
 .../sis/internal/netcdf/DiscreteSampling.java      |   2 +-
 .../apache/sis/internal/netcdf/RasterResource.java |   2 +-
 .../org/apache/sis/internal/netcdf/TestCase.java   |   2 +-
 .../org/apache/sis/internal/sql/feature/Table.java |   4 +-
 .../sis/internal/storage/AggregatedFeatureSet.java |   2 +-
 .../sis/internal/storage/MemoryFeatureSet.java     |   4 +-
 .../sis/internal/storage/MemoryGridResource.java   |   2 +-
 .../sis/internal/storage/TiledGridResource.java    |   2 +-
 .../org/apache/sis/internal/storage/csv/Store.java |   6 +-
 .../sis/internal/storage/image/FormatFilter.java   |  23 +-
 .../sis/internal/storage/image/FormatFinder.java   | 288 +++++++++++++++++
 .../internal/storage/image/MultiImageStore.java    |  62 ++++
 .../internal/storage/image/SingleImageStore.java   | 191 ++++++++++++
 .../internal/storage/image/WorldFileResource.java  |  16 +-
 .../sis/internal/storage/image/WorldFileStore.java | 116 +++----
 .../storage/image/WorldFileStoreProvider.java      |  67 +++-
 .../sis/internal/storage/image/WritableStore.java  |  81 ++---
 .../sis/internal/storage/io/ChannelData.java       |   2 +
 .../storage/io/ChannelImageInputStream.java        |  31 +-
 .../org/apache/sis/storage/AbstractFeatureSet.java |  20 +-
 .../sis/storage/AbstractGridCoverageResource.java  |  20 +-
 .../org/apache/sis/storage/AbstractResource.java   |  24 +-
 .../org/apache/sis/storage/CoverageSubset.java     |   2 +-
 .../java/org/apache/sis/storage/DataStore.java     |   2 +-
 .../java/org/apache/sis/storage/FeatureNaming.java |   1 +
 .../java/org/apache/sis/storage/FeatureSubset.java |   2 +-
 .../apache/sis/storage/event/StoreListeners.java   |   2 +-
 .../sis/internal/storage/RangeArgumentTest.java    |   2 +-
 .../storage/image/SelfConsistencyTest.java         |   2 +-
 .../internal/storage/image/WorldFileStoreTest.java |  12 +-
 .../org/apache/sis/storage/GridResourceMock.java   |   2 +-
 80 files changed, 2578 insertions(+), 651 deletions(-)

diff --cc 
core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
index b3e1bbb1e1,2fc5829ec5..335a4a4763
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
@@@ -21,8 -21,10 +21,9 @@@ import java.util.List
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Objects;
+ import java.util.regex.Pattern;
  import java.io.Serializable;
  import java.lang.reflect.Modifier;
 -import org.opengis.metadata.Identifier;
  import org.opengis.parameter.ParameterValueGroup;
  import org.opengis.parameter.ParameterDescriptor;
  import org.opengis.parameter.ParameterDescriptorGroup;
@@@ -457,26 -455,22 +457,22 @@@ public abstract class NormalizedProject
      }
  
      /**
-      * Returns {@code true} if the projection specified by the given method 
has the given keyword or identifier.
-      * If non-null, the given identifier is presumed in the EPSG namespace 
and has precedence over the keyword.
+      * Returns the variant of the map projection described by the given 
operation method.
+      * Identifiers are tested first because they have precedence over 
operation names.
       *
-      * <div class="note"><b>Implementation note:</b>
-      * Since callers usually give a constant string for the {@code regex} 
argument, it would be more efficient to
-      * compile the {@link java.util.regex.Pattern} once for all. However the 
regular expression is used only as a
-      * fallback if the descriptor does not contain EPSG identifier, which 
should be rare. Usually, the regular
-      * expression will never be compiled.</div>
-      *
-      * @param  method      the user-specified projection method.
-      * @param  regex       the regular expression to use when using the 
operation name as the criterion.
-      * @param  identifier  the identifier to compare against the operation 
method name.
-      * @return {@code true} if the name of the given operation method 
contains the given keyword
-      *         or has an EPSG identifier equals to the given identifier.
+      * @param  method        the user-specified projection method.
+      * @param  variants      possible variants for the map projection.
+      * @param  defaultValue  value to return if no match is found.
+      * @return the variant of the given operation method, or {@code 
defaultValue} if none.
       */
-     static boolean identMatch(final OperationMethod method, final String 
regex, final String identifier) {
-         if (identifier != null) {
-             for (final ReferenceIdentifier id : method.getIdentifiers()) {
-                 if (Constants.EPSG.equals(id.getCodeSpace())) {
-                     return identifier.equals(id.getCode());
+     static <V extends ProjectionVariant> V variant(final OperationMethod 
method, final V[] variants, final V defaultValue) {
+         for (final V variant : variants) {
+             final String identifier = variant.getIdentifier();
+             if (identifier != null) {
 -                for (final Identifier id : method.getIdentifiers()) {
++                for (final ReferenceIdentifier id : method.getIdentifiers()) {
+                     if (Constants.EPSG.equals(id.getCodeSpace()) && 
identifier.equals(id.getCode())) {
+                         return variant;
+                     }
                  }
              }
          }
diff --cc 
core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertAzimuthalEqualAreaTest.java
index 0000000000,72427c2dac..3c46896b6b
mode 000000,100644..100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertAzimuthalEqualAreaTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertAzimuthalEqualAreaTest.java
@@@ -1,0 -1,357 +1,344 @@@
+ /*
+  * 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.projection;
+ 
+ import org.opengis.util.FactoryException;
+ import org.opengis.referencing.operation.TransformException;
+ import org.apache.sis.referencing.operation.transform.CoordinateDomain;
+ import 
org.apache.sis.referencing.operation.transform.MathTransformFactoryMock;
+ import org.apache.sis.internal.referencing.provider.MapProjection;
+ import org.apache.sis.internal.metadata.ReferencingServices;
+ import org.apache.sis.parameter.Parameters;
+ import org.junit.Test;
+ 
+ import static java.lang.Double.NaN;
+ import static java.lang.StrictMath.*;
+ import static org.apache.sis.math.MathFunctions.SQRT_2;
+ import static org.apache.sis.internal.referencing.Formulas.LINEAR_TOLERANCE;
+ import static org.apache.sis.internal.referencing.Formulas.ANGULAR_TOLERANCE;
+ import static org.junit.Assert.*;
+ 
+ 
+ /**
+  * Tests the {@link LambertAzimuthalEqualArea} class. We test using various 
values
+  * of the latitude of origin, which is the only parameter impacting the 
internal
+  * coefficients of that class (except for the eccentricity).
+  *
+  * @author  Martin Desruisseaux (Geomatys)
+  * @author  Rémi Maréchal (Geomatys)
+  * @version 1.2
+  * @since   1.2
+  * @module
+  */
+ public final strictfp class LambertAzimuthalEqualAreaTest extends 
MapProjectionTestCase {
+     /**
+      * The radius of the sphere used in sphere test cases.
+      */
+     private static final double SPHERE_RADIUS = 
ReferencingServices.AUTHALIC_RADIUS;
+ 
+     /**
+      * Returns the provider for the map projection to tesT.
+      */
+     private static MapProjection provider(final boolean elliptical) {
+         return elliptical ? new 
org.apache.sis.internal.referencing.provider.LambertAzimuthalEqualArea()
+                           : new 
org.apache.sis.internal.referencing.provider.LambertAzimuthalEqualAreaSpherical();
+     }
+ 
+     /**
+      * Creates and validates a new instance of {@link 
LambertAzimuthalEqualArea}.
+      *
+      * @param  elliptical        {@code false} for a sphere, or {@code true} 
for WGS84 ellipsoid.
+      * @param  latitudeOfOrigin  the latitude of origin.
+      * @param  complete          whether to create the full projection, 
working on degrees instead of radians.
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      */
+     private void createProjection(final boolean elliptical, final double 
latitudeOfOrigin, final boolean complete)
+             throws FactoryException
+     {
+         final MapProjection provider = provider(elliptical);
+         final Parameters parameters = parameters(provider, elliptical);
+         parameters.parameter("latitude_of_origin").setValue(latitudeOfOrigin);
+         LambertAzimuthalEqualArea projection = new 
LambertAzimuthalEqualArea(provider, parameters);
+         if (complete) {
+             transform = projection.createMapProjection(new 
MathTransformFactoryMock(provider));
+         } else {
+             transform = projection;
+         }
+         validate();
+     }
+ 
+     /**
+      * Tests oblique case with a point computed with PROJ.
+      * Command line was:
+      *
+      * <pre>cs2cs "EPSG:4326" +to +type=crs +proj=laea +no_defs +lat_0=90 
+lon_0=0 +datum=WGS84 &lt;&lt;&lt; "72 50"</pre>
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testPolar() throws FactoryException, TransformException {
+         tolerance = LINEAR_TOLERANCE;
+         createProjection(true, 90, true);
+         final double[] point    = new double[] {50, 72};
+         final double[] expected = new double[] {1533302.80, -1286593.82};
+         verifyTransform(point, expected);
+     }
+ 
+     /**
+      * Tests oblique case with a point computed with PROJ.
+      * Command line was:
+      *
+      * <pre>cs2cs "EPSG:4326" +to +type=crs +proj=laea +no_defs +lat_0=37 
+lon_0=0 +datum=WGS84 &lt;&lt;&lt; "25 -9"</pre>
+      *
+      * Note that {@link #runGeoapiTest()} performs a similar test.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testOblique() throws FactoryException, TransformException {
+         tolerance = LINEAR_TOLERANCE;
+         createProjection(true, 37, true);
+         final double[] point    = new double[] {-9, 25};
+         final double[] expected = new double[] {-911656.53, -1288191.92};
+         verifyTransform(point, expected);
+     }
+ 
+     /**
+      * Tests self-consistency of the unitary projection on a sphere.
+      * The projection works with radians on a sphere of radius 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testConsistencyOfUnitaryOnSphere() throws FactoryException, 
TransformException {
+         final double delta = toRadians(100.0 / 60) / 1852;              // 
Approximatively 100 metres.
+         derivativeDeltas = new double[] {delta, delta};
+         tolerance = ANGULAR_TOLERANCE;
+         for (int φ = -90; φ <= 90; φ += 15) {
+             createProjection(false, φ, false);
+             verifyInDomain(CoordinateDomain.GEOGRAPHIC_RADIANS, 862247543);
+         }
+     }
+ 
+     /**
+      * Tests self-consistency of the unitary projection on an ellipse.
+      * The projection works with radians on an ellipsoid of semi-major axis 
length 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testConsistencyOfUnitaryOnEllipse() throws FactoryException, 
TransformException {
+         final double delta = toRadians(100.0 / 60) / 1852;              // 
Approximatively 100 metres.
+         derivativeDeltas = new double[] {delta, delta};
+         tolerance = ANGULAR_TOLERANCE;
+         for (int φ = -90; φ <= 90; φ += 15) {
+             createProjection(true, φ, false);
+             verifyInDomain(CoordinateDomain.GEOGRAPHIC_RADIANS, 484117986);
+         }
+     }
+ 
+     /**
+      * Tests the projection at a few particular points in the oblique case.
+      * The particular points are the origin and the (almost) antipodal points.
+      * The projection works with radians on a sphere of radius 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testParticularPointsWithObliqueOnSphere() throws 
FactoryException, TransformException {
+         testParticularPointsWithOblique(false);
+     }
+ 
+     /**
+      * Tests the projection at a few particular points in the oblique case.
+      * The particular points are the origin and the (almost) antipodal points.
+      * The projection works with degrees on an ellipsoid of semi-major axis 
length 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testParticularPointsWithObliqueOnEllipse() throws 
FactoryException, TransformException {
+         testParticularPointsWithOblique(true);
+     }
+ 
+     /**
+      * Implementation of {@link #testParticularPointsWithObliqueOnSphere()}
+      * and {@link #testParticularPointsWithObliqueOnEllipse()}.
+      */
+     private void testParticularPointsWithOblique(final boolean elliptical) 
throws FactoryException, TransformException {
+         tolerance = LINEAR_TOLERANCE;
+         createProjection(elliptical, 45, true);
+ 
+         // Projects the origin.
+         final double[] point    = new double[] {0, 45};
+         final double[] expected = new double[] {0, 0};
+         verifyTransform(point, expected);
+ 
+         // Project the antipode.
+         point[0] = 180;
+         point[1] = -45;
+         transform.transform(point, 0, point, 0, 1);
+         assertEquals("E", NaN, point[0], tolerance);
+         assertEquals("N", NaN, point[1], tolerance);
+ 
+         // Project the almost-antipode.
+         point[0] = 180;
+         point[1] = -44.999;
+         transform.transform(point, 0, point, 0, 1);
+         assertEquals("E", 0, point[0], tolerance);
+         assertEquals("N", 2*SPHERE_RADIUS, point[1], 0.002*SPHERE_RADIUS);
+     }
+ 
+     /**
+      * Tests the projection at a few extreme points in the polar case.
+      * The projection works with radians on a sphere of radius 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testParticularPointsWithPolarOnSphere() throws 
FactoryException, TransformException {
+         testParticularPointsWithPolar(false);
+     }
+ 
+     /**
+      * Tests the projection at a few extreme points in the polar case.
+      * The projection works with radians on an ellipsoid of semi-major axis 
length 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testParticularPointsWithPolarOnEllipse() throws 
FactoryException, TransformException {
+         testParticularPointsWithPolar(true);
+     }
+ 
+     /**
+      * Implementation of {@link #testParticularPointsWithPolarOnSphere()}
+      * and {@link #testParticularPointsWithPolarOnEllipse()}.
+      */
+     private void testParticularPointsWithPolar(final boolean elliptical) 
throws FactoryException, TransformException {
+         tolerance = LINEAR_TOLERANCE;
+         createProjection(elliptical, 90, true);
+         /*
+          * Project the origin. Result should be (0,0). Do not test the 
inverse projection
+          * because the longitude could be anything and still be the North 
pole. We test that
+          * by projecting again with an other longitude, set to 45°, and 
expect the same result.
+          */
+         final double[] point    = new double[] {0, 90};
+         final double[] expected = new double[] {0,  0};
+         isInverseTransformSupported = false;
+         verifyTransform(point, expected);
+         transform.inverse().transform(expected, 0, point, 0, 1);
+         assertEquals("λ",  0, point[0], 180);
+         assertEquals("φ", 90, point[1], ANGULAR_TOLERANCE);
+         /*
+          * Same point as above (i.e. projection origin), but using a 
different longitude value.
+          * Same expected result because longitude should have no effect at a 
pole.
+          */
+         point[0] = 45;
+         point[1] = 90;
+         verifyTransform(point, expected);
+         transform.inverse().transform(expected, 0, point, 0, 1);
+         assertEquals("λ", 45, point[0], 180);
+         assertEquals("φ", 90, point[1], ANGULAR_TOLERANCE);
+         /*
+          * Project a point on the equator, at 0° and at 180° longitude.
+          * Result should be (0, √2) positive or negative depending on the 
longitude.
+          */
+         point[0] = 0; expected[0] = 0;
+         point[1] = 0; expected[1] = -SQRT_2*SPHERE_RADIUS;
+         isInverseTransformSupported = true;
+         if (elliptical) tolerance = 0.5;        // Because the use of 
`SPHERE_RADIUS` is approximate.
+         verifyTransform(point, expected);
+ 
+         point[0] = 180; expected[0] = 0;
+         point[1] =   0; expected[1] = SQRT_2*SPHERE_RADIUS;
+         verifyTransform(point, expected);
+         /*
+          * Project the antipode. Result would be (0, -2) if this operation 
was allowed.
+          * Actually the formulas would work, but every points on a circle or 
radius 2
+          * would be the pole so returning a single value may not be 
appropriate.
+          */
+         point[0] =   0;
+         point[1] = -90;
+         transform.transform(point, 0, point, 0, 1);
+         assertEquals("E", NaN, point[0], tolerance);
+         assertEquals("N", NaN, point[1], tolerance);
+     }
+ 
+     /**
+      * Tests consistency when converting a point forward then backward.
+      * The projection works with radians on a sphere of radius 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testRoundtrip() throws FactoryException, TransformException {
+         tolerance = ANGULAR_TOLERANCE;
+         createProjection(false, -75, false);
+         final double[] point = new double[] {toRadians(-90), toRadians(-8)};
+         transform.transform(point, 0, point, 0, 1);
+         transform.inverse().transform(point, 0, point, 0, 1);
+         assertEquals(-90, toDegrees(point[0]), tolerance);
+         assertEquals( -8, toDegrees(point[1]), tolerance);
+     }
+ 
+     /**
+      * Creates a projection and tests the derivatives at a few points.
+      * The projection works with radians on an ellipsoid of semi-major axis 
length 1.
+      *
+      * @throws FactoryException if an error occurred while creating the map 
projection.
+      * @throws TransformException if an error occurred while projecting a 
coordinate.
+      */
+     @Test
+     public void testDerivative() throws FactoryException, TransformException {
+         tolerance = 1E-9;
+         final double delta = toRadians(100.0 / 60) / 1852;              // 
Approximatively 100 metres.
+         derivativeDeltas = new double[] {delta, delta};
+ 
+         // Polar projection.
+         createProjection(true, 90, false);
+         verifyDerivative(toRadians(-6), toRadians(80));
+ 
+         // Intentionally above the pole.
+         verifyDerivative(toRadians(-6), toRadians(100));
+ 
+         // Polar projection, spherical formulas.
+         createProjection(false, 90, false);
+         verifyDerivative(toRadians(-6), toRadians(85));
+ 
+         // Equatorial projection, spherical formulas.
+         createProjection(false, 0, false);
+         verifyDerivative(toRadians(3), toRadians(4));
+ 
+         // Oblique projection, ellipsoidal formulas.
+         createProjection(true, 8, false);
+         verifyDerivative(toRadians(-6), toRadians(2));
+ 
+         // Oblique projection, spherical formulas.
+         createProjection(false, 8, false);
+         verifyDerivative(toRadians(-6), toRadians(2));
+     }
 -
 -    /**
 -     * Runs the test defined in the GeoAPI-conformance module.
 -     *
 -     * @throws FactoryException if an error occurred while creating the map 
projection.
 -     * @throws TransformException if an error occurred while projecting a 
coordinate.
 -     *
 -     * @see 
org.opengis.test.referencing.ParameterizedTransformTest#testLambertAzimuthalEqualArea()
 -     */
 -    @Test
 -    public void runGeoapiTest() throws FactoryException, TransformException {
 -        createGeoApiTest(provider(true)).testLambertAzimuthalEqualArea();
 -    }
+ }
diff --cc 
core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
index f3e2b3c167,aa93ec41fd..b4de8e0248
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
@@@ -22,9 -23,14 +23,12 @@@ import org.apache.sis.internal.util.Con
  import org.apache.sis.internal.referencing.Formulas;
  import org.apache.sis.internal.referencing.provider.Mercator1SP;
  import org.apache.sis.internal.referencing.provider.Mercator2SP;
 -import org.apache.sis.internal.referencing.provider.MercatorSpherical;
+ import org.apache.sis.internal.referencing.provider.MercatorAuxiliarySphere;
  import org.apache.sis.internal.referencing.provider.PseudoMercator;
  import org.apache.sis.internal.referencing.provider.MillerCylindrical;
 -import org.apache.sis.internal.referencing.provider.RegionalMercator;
  import org.apache.sis.referencing.operation.transform.CoordinateDomain;
+ import 
org.apache.sis.referencing.operation.transform.MathTransformFactoryMock;
+ import org.apache.sis.parameter.Parameters;
  import org.apache.sis.test.DependsOnMethod;
  import org.apache.sis.test.DependsOn;
  import org.junit.Test;
diff --cc 
storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Table.java
index b8079a82ce,6e5b40c17e..82d237c4af
--- 
a/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Table.java
+++ 
b/storage/sis-sqlstore/src/main/java/org/apache/sis/internal/sql/feature/Table.java
@@@ -190,10 -191,10 +190,10 @@@ final class Table extends AbstractFeatu
       *
       * @todo This constructor is not yet used because it is an unfinished 
work.
       *       We need to invent some mechanism for using a subset of the 
columns.
 -     *       A starting point is {@link 
org.apache.sis.storage.FeatureQuery#expectedType(FeatureType)}.
 +     *       A starting point is {@link 
org.apache.sis.storage.FeatureQuery#expectedType(DefaultFeatureType)}.
       */
      Table(final Table parent) {
-         super(parent.listeners);
+         super(parent.listeners, false);
          database = parent.database;
          query    = parent.query;
          name     = parent.name;
diff --cc 
storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MemoryFeatureSet.java
index f03d334266,7249bbbb6c..2ae3383eed
--- 
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
@@@ -59,10 -59,8 +59,10 @@@ public class MemoryFeatureSet extends A
       * @param type       the type of all features in the given collection.
       * @param features   collection of stored features. This collection will 
not be copied.
       */
 -    public MemoryFeatureSet(final StoreListeners parent, final FeatureType 
type, final Collection<Feature> features) {
 +    public MemoryFeatureSet(final StoreListeners parent,
 +                            final DefaultFeatureType type, final 
Collection<AbstractFeature> features)
- {
-         super(parent);
++    {
+         super(parent, false);
          ArgumentChecks.ensureNonNull("type",     type);
          ArgumentChecks.ensureNonNull("features", features);
          this.type     = type;
diff --cc 
storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
index 84416bb946,50fd6de7b7..d3a4e61bfc
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
@@@ -576,13 -578,9 +576,9 @@@ final class Store extends URIDataStore 
              }
              properties.add(createProperty(name, type, minOccurrence, 
maxOccurrence, characteristics));
          }
-         String name = super.getDisplayName();
-         final int s = name.lastIndexOf('.');
-         if (s > 0) {                            // Exclude 0 because shall 
not be the first character.
-             name = name.substring(0, s);
-         }
+         final String name = 
IOUtilities.filenameWithoutExtension(super.getDisplayName());
          return new 
DefaultFeatureType(Collections.singletonMap(DefaultFeatureType.NAME_KEY, name),
 -                false, null, properties.toArray(new 
PropertyType[properties.size()]));
 +                false, null, properties.toArray(new 
AbstractIdentifiedType[properties.size()]));
      }
  
      /**
diff --cc 
storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/WorldFileStoreTest.java
index 7ff00be156,9c174d5241..7e68d48a6e
--- 
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/WorldFileStoreTest.java
+++ 
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/WorldFileStoreTest.java
@@@ -76,10 -76,20 +76,18 @@@ public final strictfp class WorldFileSt
      public void testMetadata() throws DataStoreException {
          final WorldFileStoreProvider provider = new WorldFileStoreProvider();
          try (WorldFileStore store = provider.open(testData())) {
+             /*
+              * Opportunistic check of store type. Should be read-only,
+              * and should have been simplified to the "single image" case.
+              */
              assertFalse(store instanceof WritableStore);
+             assertTrue(store instanceof SingleImageStore);
+             /*
+              * Verify metadata content.
+              */
              assertEquals("gradient", store.getIdentifier().get().toString());
              final Metadata metadata = store.getMetadata();
 -            final Identification id = 
getSingleton(metadata.getIdentificationInfo());
 -            final String format = 
getSingleton(id.getResourceFormats()).getFormatSpecificationCitation().getTitle().toString();
 -            assertTrue(format, format.contains("PNG"));
 +            final DataIdentification id = (DataIdentification) 
getSingleton(metadata.getIdentificationInfo());
              assertEquals("WGS 84", 
getSingleton(metadata.getReferenceSystemInfo()).getName().getCode());
              final GeographicBoundingBox bbox = (GeographicBoundingBox)
                      
getSingleton(getSingleton(id.getExtents()).getGeographicElements());

Reply via email to