You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2021/09/17 13:32:16 UTC

[sis] branch geoapi-4.0 updated (9d36a8d -> 32936ed)

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git.


    from 9d36a8d  Move `InternationalString` implementations to `org.apache.sis.util` package. This is in anticipation for Jigsaw modularization.
     new 97fcad5  Remove the sis-gdal module. It is replaced by the https://github.com/OSGeo/PROJ-JNI project.
     new 32936ed  Following removal of "sis-gdal" module in previous commit, remove (for now) the `SpecializedOperationFactory` interface. Remove also the code for loading a native library (not used anymore).

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 application/sis-console/pom.xml                    |   6 -
 .../referencing/SpecializedOperationFactory.java   |  55 --
 .../main/java/org/apache/sis/referencing/CRS.java  |   1 -
 .../operation/CoordinateOperationFinder.java       |  19 -
 .../operation/CoordinateOperationRegistry.java     |   9 +-
 .../DefaultCoordinateOperationFactory.java         |  28 -
 .../org/apache/sis/internal/system/Modules.java    |   5 -
 .../java/org/apache/sis/internal/system/OS.java    | 196 -----
 .../apache/sis/util/logging/MonolineFormatter.java |   3 +-
 ide-project/NetBeans/build.xml                     |  11 -
 ide-project/NetBeans/nbproject/build-impl.xml      |  56 +-
 ide-project/NetBeans/nbproject/genfiles.properties |   4 +-
 ide-project/NetBeans/nbproject/project.properties  |   3 -
 ide-project/NetBeans/nbproject/project.xml         |   3 -
 storage/pom.xml                                    |   1 -
 storage/sis-gdal/pom.xml                           | 120 ---
 storage/sis-gdal/src/main/c/Makefile               |  77 --
 .../src/main/c/org_apache_sis_storage_gdal_PJ.c    | 321 --------
 .../src/main/c/org_apache_sis_storage_gdal_PJ.h    |  85 --
 .../internal/storage/gdal/OperationFactory.java    |  57 --
 .../sis/internal/storage/gdal/package-info.java    |  26 -
 .../main/java/org/apache/sis/storage/gdal/PJ.java  | 361 ---------
 .../java/org/apache/sis/storage/gdal/Proj4.java    | 401 ----------
 .../org/apache/sis/storage/gdal/Proj4Factory.java  | 886 ---------------------
 .../org/apache/sis/storage/gdal/Proj4Parser.java   | 185 -----
 .../org/apache/sis/storage/gdal/Transform.java     | 247 ------
 .../org/apache/sis/storage/gdal/package-info.java  |  90 ---
 ...nternal.referencing.SpecializedOperationFactory |   1 -
 ...org.opengis.referencing.crs.CRSAuthorityFactory |   1 -
 .../resources/native/darwin/libproj-binding.so     | Bin 14016 -> 0 bytes
 .../main/resources/native/linux/libproj-binding.so | Bin 13504 -> 0 bytes
 .../apache/sis/storage/gdal/IntegrationTest.java   |  63 --
 .../org/apache/sis/storage/gdal/MTFactory.java     | 201 -----
 .../java/org/apache/sis/storage/gdal/PJTest.java   | 181 -----
 .../apache/sis/storage/gdal/Proj4FactoryTest.java  | 148 ----
 .../apache/sis/storage/gdal/Proj4ParserTest.java   |  83 --
 .../org/apache/sis/storage/gdal/Proj4Test.java     |  46 --
 .../org/apache/sis/storage/gdal/TransformTest.java | 102 ---
 .../org/apache/sis/test/suite/GDALTestSuite.java   |  50 --
 39 files changed, 18 insertions(+), 4114 deletions(-)
 delete mode 100644 core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
 delete mode 100644 core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
 delete mode 100644 storage/sis-gdal/pom.xml
 delete mode 100644 storage/sis-gdal/src/main/c/Makefile
 delete mode 100644 storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.c
 delete mode 100644 storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.h
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/PJ.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java
 delete mode 100644 storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java
 delete mode 100644 storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
 delete mode 100644 storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
 delete mode 100755 storage/sis-gdal/src/main/resources/native/darwin/libproj-binding.so
 delete mode 100755 storage/sis-gdal/src/main/resources/native/linux/libproj-binding.so
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4ParserTest.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4Test.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/TransformTest.java
 delete mode 100644 storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java

[sis] 02/02: Following removal of "sis-gdal" module in previous commit, remove (for now) the `SpecializedOperationFactory` interface. Remove also the code for loading a native library (not used anymore).

Posted by de...@apache.org.
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 32936ed8d4bcec29f82d0c302b0a3bcf031127f0
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Sep 17 15:15:49 2021 +0200

    Following removal of "sis-gdal" module in previous commit,
    remove (for now) the `SpecializedOperationFactory` interface.
    Remove also the code for loading a native library (not used anymore).
---
 .../referencing/SpecializedOperationFactory.java   |  55 ------
 .../operation/CoordinateOperationFinder.java       |  19 --
 .../operation/CoordinateOperationRegistry.java     |   9 +-
 .../DefaultCoordinateOperationFactory.java         |  28 ---
 .../java/org/apache/sis/internal/system/OS.java    | 196 ---------------------
 .../apache/sis/util/logging/MonolineFormatter.java |   3 +-
 ide-project/NetBeans/build.xml                     |   7 -
 7 files changed, 2 insertions(+), 315 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
deleted file mode 100644
index a036ce9..0000000
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SpecializedOperationFactory.java
+++ /dev/null
@@ -1,55 +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.internal.referencing;
-
-import java.util.Set;
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.CoordinateOperation;
-
-
-/**
- * Implemented by extension modules capable to provide coordinate operations for some particular pairs of CRS.
- * Implementations of this interface are not general-purpose factories;
- * they should not process any pair of CRS other than the one for which they are designed.
- *
- * <div class="note"><b>Example:</b>
- * a module doing the bindings between Apache SIS and another map projection library may create wrappers
- * around the transformation method of that other library when {@code findOperations(…)} recognizes the
- * given CRS as wrappers around their data structures.</div>
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public interface SpecializedOperationFactory {
-    /**
-     * Returns operations between the given pair of CRS, or an empty set if this factory does not recognize them.
-     * Non-empty sets have precedence over EPSG geodetic dataset or other mechanism used by Apache SIS, so should
-     * be used sparsely.
-     *
-     * @param  sourceCRS  the coordinate reference system of source points (before transformation).
-     * @param  targetCRS  the coordinate reference system of target points (after transformation).
-     * @return the coordinate operations from source to target CRS, or an empty set if this factory
-     *         does not recognize the given pair of CRSs.
-     * @throws FactoryException if this factory recognizes the CRSs given in arguments,
-     *         but an error occurred while creating the coordinate operation.
-     */
-    Set<CoordinateOperation> findOperations(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)
-            throws FactoryException;
-}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
index a3ab4b1..94f9495 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
@@ -48,7 +48,6 @@ import org.apache.sis.internal.referencing.provider.Geographic3Dto2D;
 import org.apache.sis.internal.referencing.provider.GeographicToGeocentric;
 import org.apache.sis.internal.referencing.provider.GeocentricToGeographic;
 import org.apache.sis.internal.referencing.provider.GeocentricAffine;
-import org.apache.sis.internal.referencing.SpecializedOperationFactory;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.measure.Units;
@@ -266,24 +265,6 @@ public class CoordinateOperationFinder extends CoordinateOperationRegistry {
             areaOfInterest = CoordinateOperationContext.setGeographicBoundingBox(areaOfInterest, bbox);
         }
         /*
-         * Verify if some extension module handles this pair of CRS in a special way. For example it may
-         * be the "sis-gdal" module checking if the given CRS are wrappers around Proj.4 data structure.
-         */
-        {   // For keeping `operations` list locale.
-            final List<CoordinateOperation> operations = new ArrayList<>();
-            for (final SpecializedOperationFactory sp : factorySIS.getSpecializedFactories()) {
-                for (final CoordinateOperation op : sp.findOperations(sourceCRS, targetCRS)) {
-                    if (filter(op)) {
-                        operations.add(op);
-                    }
-                }
-            }
-            if (!operations.isEmpty()) {
-                CoordinateOperationSorter.sort(operations, bbox);
-                return operations;
-            }
-        }
-        /*
          * Verify in the EPSG dataset if the operation is explicitly defined by an authority.
          */
         if (registry != null) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index 299f63e..f81df93 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@ -626,7 +626,7 @@ class CoordinateOperationRegistry {
              * FactoryException propagate.
              */
             operation = complete(operation, sourceCRS, targetCRS);
-            if (filter(operation)) {
+            if (filter == null || filter.test(operation)) {
                 if (stopAtFirst) {
                     operations.clear();
                     operations.add(operation);
@@ -641,13 +641,6 @@ class CoordinateOperationRegistry {
     }
 
     /**
-     * Returns {@code true} if the given operation can be accepted.
-     */
-    final boolean filter(final CoordinateOperation op) {
-        return filter == null || filter.test(op);
-    }
-
-    /**
      * Creates the inverse of the given single operation.
      * If this operation succeed, then the returned coordinate operations has the following properties:
      *
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
index 45efa18..7b9484c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
@@ -21,7 +21,6 @@ import java.util.HashMap;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
-import java.util.ServiceLoader;
 import org.opengis.util.FactoryException;
 import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.parameter.ParameterValueGroup;
@@ -36,11 +35,9 @@ import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.CRSFactory;
 import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.datum.Datum;
-import org.apache.sis.internal.referencing.LazySet;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.referencing.MergedProperties;
 import org.apache.sis.internal.referencing.CoordinateOperations;
-import org.apache.sis.internal.referencing.SpecializedOperationFactory;
 import org.apache.sis.internal.referencing.ReferencingFactoryContainer;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.system.DefaultFactories;
@@ -130,17 +127,6 @@ public class DefaultCoordinateOperationFactory extends AbstractFactory implement
     private volatile MathTransformFactory mtFactory;
 
     /**
-     * Factories specialized to some particular pair of CRS. For example a module doing the bindings between
-     * Apache SIS and another map projection library may create wrappers around the transformation method of
-     * that other library when {@code SpecializedOperationFactory.tryCreateOperation(…)} recognizes the given
-     * CRS as wrappers around their data structures.
-     *
-     * <p>This array is created when first needed. After creation, the array shall not be modified anymore.</p>
-     */
-    @SuppressWarnings("VolatileArrayField")
-    private volatile SpecializedOperationFactory[] specializedFactories;
-
-    /**
      * Weak references to existing objects.
      * This set is used in order to return a pre-existing object instead of creating a new one.
      * This applies to objects created explicitly, not to coordinate operations inferred by a
@@ -277,20 +263,6 @@ public class DefaultCoordinateOperationFactory extends AbstractFactory implement
     }
 
     /**
-     * Returns all known factories specialized in the creation of coordinate operations between some particular
-     * pairs of CRS.
-     */
-    final SpecializedOperationFactory[] getSpecializedFactories() {
-        SpecializedOperationFactory[] factories = specializedFactories;
-        if (factories == null) {
-            final LazySet<SpecializedOperationFactory> set =
-                    new LazySet<>(ServiceLoader.load(SpecializedOperationFactory.class).iterator());
-            specializedFactories = factories = set.toArray(new SpecializedOperationFactory[set.size()]);
-        }
-        return factories;
-    }
-
-    /**
      * Returns the operation method of the given name. The given argument shall be either a method
      * {@linkplain DefaultOperationMethod#getName() name} (e.g. <cite>"Transverse Mercator"</cite>)
      * or one of its {@linkplain DefaultOperationMethod#getIdentifiers() identifiers} (e.g. {@code "EPSG:9807"}).
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
deleted file mode 100644
index 2a53697..0000000
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
+++ /dev/null
@@ -1,196 +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.internal.system;
-
-import java.net.URL;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.resources.Errors;
-
-
-/**
- * The operation system on which SIS is running.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.3
- * @module
- */
-public enum OS {
-    /**
-     * Unknown system.
-     */
-    UNKNOWN(null, false),
-
-    /**
-     * Windows.
-     */
-    WINDOWS("windows", false),
-
-    /**
-     * Mac OS.
-     */
-    MAC_OS("darwin", true),
-
-    /**
-     * Linux.
-     */
-    LINUX("linux", true);
-
-    /**
-     * The sub-directory where to look for native files ({@code .so} or {@code .dll}).
-     * Those subdirectories are not standard (as far as we know) and could change in
-     * any future Apache SIS version. The directory is {@code null} for unknown OS.
-     */
-    private final String libdir;
-
-    /**
-     * {@code true} if this OS is a kind of Unix.
-     */
-    public final boolean unix;
-
-    /**
-     * Creates a new enumeration.
-     */
-    private OS(final String libdir, final boolean unix) {
-        this.libdir = libdir;
-        this.unix   = unix;
-    }
-
-    /**
-     * Returns the name value of {@code "os.name"} property, or {@code null} if the security manager
-     * does not allow us to access this information.
-     *
-     * <div class="note"><b>Note:</b> {@code uname} is an Unix command providing the same information.</div>
-     *
-     * @return the operation system name, or {@code null} if this information is not available.
-     */
-    public static String uname() {
-        try {
-            return System.getProperty("os.name");
-        } catch (SecurityException e) {
-            Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class, "uname", e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns the operating system SIS is currently on.
-     *
-     * @return the operation system.
-     */
-    public static OS current() {
-        final String name = uname();
-        if (name != null) {
-            if (name.contains("Windows")) return WINDOWS;
-            if (name.contains("Mac OS"))  return MAC_OS;
-            if (name.contains("Linux"))   return LINUX;
-        }
-        return UNKNOWN;
-    }
-
-    /**
-     * Loads the native library of the given name from the JAR file of the given class.
-     * This method searches for a resource in the {@code /native/<os>} directory where
-     * {@code <os>} is {@code windows}, {@code darwin} or {@code linux}.
-     *
-     * @param  caller  a class in the JAR file where to look for native resources.
-     * @param  name    the native library name without {@code ".so"} or {@code ".dll"} extension.
-     * @throws UnsatisfiedLinkError if the native library can not be loaded for the current OS.
-     *
-     * @see System#load(String)
-     */
-    public static void load(final Class<?> caller, final String name) {
-        try {
-            System.load(current().nativeLibrary(caller, name));
-        } catch (IOException | SecurityException e) {
-            throw (UnsatisfiedLinkError) new UnsatisfiedLinkError(e.getMessage()).initCause(e);
-        }
-    }
-
-    /**
-     * Returns an absolute path to the library of the given name in the JAR file.
-     * If the resources can not be accessed by an absolute path, then this method
-     * copies the resource in a temporary file.
-     *
-     * @param  caller  a class in the JAR file where to look for native resources.
-     * @param  name    the native library name without {@code ".so"} or {@code ".dll"} extension.
-     * @return absolute path to the library (may be a temporary file).
-     * @throws IOException if an error occurred while copying the library to a temporary file.
-     * @throws SecurityException if the security manager denies loading resource, creating absolute path, <i>etc</i>.
-     * @throws UnsatisfiedLinkError if no native resource has been found for the current OS.
-     *
-     * @see System#load(String)
-     */
-    private String nativeLibrary(final Class<?> caller, final String name) throws IOException {
-        if (libdir != null) {
-            final String ext = unix ? ".so" : ".dll";
-            final String path = libdir + '/' + name + ext;
-            final ClassLoader loader = caller.getClassLoader();
-            /*
-             * First, verify if the "linux", "darwin" or "windows" directory exists at the same level
-             * than the JAR file containing the caller class. If it exists, then we will use it. This
-             * check avoid the need to copy the ".so" or ".dll" file in a temporary location.  If the
-             * directory does not exist, then we do NOT create it in order to reduce the risk to mess
-             * with user's installation.
-             *
-             * Example of URL for a JAR entry: jar:file:/home/…/sis-gdal.jar!/org/apache/…/PJ.class
-             */
-            URL res = loader.getResource(caller.getName().replace('.', '/').concat(".class"));
-            if (res != null && "jar".equals(res.getProtocol())) {
-                String file = res.getPath();
-                final int s = file.indexOf('!');
-                if (s >= 0) try {
-                    File location = new File(new URI(file.substring(0, s)));
-                    location = new File(location.getParentFile(), path);
-                    if (location.canExecute()) {
-                        return location.getAbsolutePath();
-                    }
-                } catch (IllegalArgumentException | URISyntaxException e) {
-                    Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class, "nativeLibrary", e);
-                }
-            }
-            /*
-             * If we didn't found an existing "linux", "darwin" or "windows" directory with native library,
-             * copy the library in a temporary file. That file will be deleted on JVM exists, so a new file
-             * will be copied each time the application is executed.
-             */
-            res = loader.getResource("native/".concat(path));
-            if (res != null) {
-                try {
-                    return new File(res.toURI()).getAbsolutePath();
-                } catch (IllegalArgumentException | URISyntaxException e) {
-                    Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class, "nativeLibrary", e);
-                }
-                final Path tmp = Files.createTempFile(name, ext).toAbsolutePath();
-                tmp.toFile().deleteOnExit();
-                try (InputStream in = res.openStream()) {
-                    Files.copy(in, tmp, StandardCopyOption.REPLACE_EXISTING);
-                }
-                return tmp.toString();
-            }
-        }
-        throw new UnsatisfiedLinkError(Errors.format(Errors.Keys.NativeInterfacesNotFound_2, uname(), name));
-    }
-}
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java b/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
index ec6ffd4..c8b352d 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
@@ -33,7 +33,6 @@ import java.util.Comparator;
 import java.util.ResourceBundle;
 import java.util.logging.*;
 import org.apache.sis.internal.system.Modules;
-import org.apache.sis.internal.system.OS;
 import org.apache.sis.internal.util.X364;
 import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.util.AutoMessageFormat;
@@ -345,7 +344,7 @@ public class MonolineFormatter extends Formatter {
         if (handler instanceof ConsoleHandler && X364.isAnsiSupported()) {
             resetLevelColors();
         }
-        faintSupported = OS.current() != OS.MAC_OS;
+        faintSupported = System.getProperty("os.name", "").contains("Mac OS");
         /*
          * Creates the buffer and the printer. We will expand the tabulations with 4 characters.
          * This apply to the stack trace formatted by Throwable.printStackTrace(PrintWriter);
diff --git a/ide-project/NetBeans/build.xml b/ide-project/NetBeans/build.xml
index 746e465..b76f00a 100644
--- a/ide-project/NetBeans/build.xml
+++ b/ide-project/NetBeans/build.xml
@@ -229,13 +229,6 @@
       </fileset>
     </concat>
 
-    <!-- SpecializedOperationFactory implementations to be loaded by ServiceLoader. -->
-    <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory" encoding="UTF-8" fixlastline="yes">
-      <fileset dir="${project.root}">
-        <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory"/>
-      </fileset>
-    </concat>
-
     <!-- DataStoreProvider implementations to be loaded by ServiceLoader. -->
     <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.storage.DataStoreProvider" encoding="UTF-8" fixlastline="yes">
       <fileset dir="${project.root}">

[sis] 01/02: Remove the sis-gdal module. It is replaced by the https://github.com/OSGeo/PROJ-JNI project.

Posted by de...@apache.org.
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 97fcad5dc0fe393da7e8ef315498164609e5a8e7
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Sep 17 14:47:37 2021 +0200

    Remove the sis-gdal module. It is replaced by the https://github.com/OSGeo/PROJ-JNI project.
    
    https://issues.apache.org/jira/browse/SIS-510
---
 application/sis-console/pom.xml                    |   6 -
 .../main/java/org/apache/sis/referencing/CRS.java  |   1 -
 .../org/apache/sis/internal/system/Modules.java    |   5 -
 ide-project/NetBeans/build.xml                     |   4 -
 ide-project/NetBeans/nbproject/build-impl.xml      |  56 +-
 ide-project/NetBeans/nbproject/genfiles.properties |   4 +-
 ide-project/NetBeans/nbproject/project.properties  |   3 -
 ide-project/NetBeans/nbproject/project.xml         |   3 -
 storage/pom.xml                                    |   1 -
 storage/sis-gdal/pom.xml                           | 120 ---
 storage/sis-gdal/src/main/c/Makefile               |  77 --
 .../src/main/c/org_apache_sis_storage_gdal_PJ.c    | 321 --------
 .../src/main/c/org_apache_sis_storage_gdal_PJ.h    |  85 --
 .../internal/storage/gdal/OperationFactory.java    |  57 --
 .../sis/internal/storage/gdal/package-info.java    |  26 -
 .../main/java/org/apache/sis/storage/gdal/PJ.java  | 361 ---------
 .../java/org/apache/sis/storage/gdal/Proj4.java    | 401 ----------
 .../org/apache/sis/storage/gdal/Proj4Factory.java  | 886 ---------------------
 .../org/apache/sis/storage/gdal/Proj4Parser.java   | 185 -----
 .../org/apache/sis/storage/gdal/Transform.java     | 247 ------
 .../org/apache/sis/storage/gdal/package-info.java  |  90 ---
 ...nternal.referencing.SpecializedOperationFactory |   1 -
 ...org.opengis.referencing.crs.CRSAuthorityFactory |   1 -
 .../resources/native/darwin/libproj-binding.so     | Bin 14016 -> 0 bytes
 .../main/resources/native/linux/libproj-binding.so | Bin 13504 -> 0 bytes
 .../apache/sis/storage/gdal/IntegrationTest.java   |  63 --
 .../org/apache/sis/storage/gdal/MTFactory.java     | 201 -----
 .../java/org/apache/sis/storage/gdal/PJTest.java   | 181 -----
 .../apache/sis/storage/gdal/Proj4FactoryTest.java  | 148 ----
 .../apache/sis/storage/gdal/Proj4ParserTest.java   |  83 --
 .../org/apache/sis/storage/gdal/Proj4Test.java     |  46 --
 .../org/apache/sis/storage/gdal/TransformTest.java | 102 ---
 .../org/apache/sis/test/suite/GDALTestSuite.java   |  50 --
 33 files changed, 16 insertions(+), 3799 deletions(-)

diff --git a/application/sis-console/pom.xml b/application/sis-console/pom.xml
index 2cc1076..7b12425 100644
--- a/application/sis-console/pom.xml
+++ b/application/sis-console/pom.xml
@@ -140,12 +140,6 @@
       <scope>runtime</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.sis.storage</groupId>
-      <artifactId>sis-gdal</artifactId>
-      <version>${project.version}</version>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
       <groupId>jakarta.xml.bind</groupId>
       <artifactId>jakarta.xml.bind-api</artifactId>
     </dependency>
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 207303e..1669ab6 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -221,7 +221,6 @@ public final class CRS extends Static {
      * The {@link IdentifiedObjects#lookupURN(IdentifiedObject, Citation)} method can be seen
      * as a converse of this method: from a CRS object, it tries to find a URN that describes it.
      * More codes may also be supported depending on which extension modules are available.
-     * See for example the {@linkplain org.apache.sis.storage.gdal bindings to PROJ library}.
      * </div>
      *
      * @param  code  the authority code.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
index 9d0b0d0..5b90bf3 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
@@ -90,11 +90,6 @@ public final class Modules {
     /**
      * The {@value} module name.
      */
-    public static final String GDAL = "org.apache.sis.storage.gdal";
-
-    /**
-     * The {@value} module name.
-     */
     public static final String SQL = "org.apache.sis.sql";
 
     /**
diff --git a/ide-project/NetBeans/build.xml b/ide-project/NetBeans/build.xml
index ad05d83..746e465 100644
--- a/ide-project/NetBeans/build.xml
+++ b/ide-project/NetBeans/build.xml
@@ -106,10 +106,6 @@
       <fileset dir="${project.root}/storage/sis-xmlstore/src/main/resources">
         <include name="**/*.properties"/>
       </fileset>
-      <fileset dir="${project.root}/storage/sis-gdal/src/main/resources">
-        <include name="**/*.dll"/>
-        <include name="**/*.so"/>
-      </fileset>
       <fileset dir="${project.root}/application/sis-javafx/src/main/resources">
         <include name="**/*.fxml"/>
         <include name="**/*.png"/>
diff --git a/ide-project/NetBeans/nbproject/build-impl.xml b/ide-project/NetBeans/nbproject/build-impl.xml
index 6797e6b..a00a7f6 100644
--- a/ide-project/NetBeans/nbproject/build-impl.xml
+++ b/ide-project/NetBeans/nbproject/build-impl.xml
@@ -90,7 +90,7 @@ is divided into following sections:
                 </not>
             </condition>
         </fail>
-        <j2seproject3:modulename property="module.name" sourcepath="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}"/>
+        <j2seproject3:modulename property="module.name" sourcepath="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}"/>
         <condition property="named.module.internal">
             <and>
                 <isset property="module.name"/>
@@ -197,7 +197,6 @@ is divided into following sections:
                 <available file="${test.utility.dir}"/>
                 <available file="${test.fra-profile.dir}"/>
                 <available file="${test.jpn-profile.dir}"/>
-                <available file="${test.gdal.dir}"/>
             </or>
         </condition>
         <condition property="have.sources">
@@ -221,8 +220,6 @@ is divided into following sections:
                 <available file="${src.utility.dir}"/>
                 <available file="${src.fra-profile.dir}"/>
                 <available file="${src.jpn-profile.dir}"/>
-                <available file="${src.gdal.dir}"/>
-                <available file="${src.c.gdal.dir}"/>
             </or>
         </condition>
         <condition property="netbeans.home+have.tests">
@@ -344,8 +341,6 @@ is divided into following sections:
         <fail unless="src.utility.dir">Must set src.utility.dir</fail>
         <fail unless="src.fra-profile.dir">Must set src.fra-profile.dir</fail>
         <fail unless="src.jpn-profile.dir">Must set src.jpn-profile.dir</fail>
-        <fail unless="src.gdal.dir">Must set src.gdal.dir</fail>
-        <fail unless="src.c.gdal.dir">Must set src.c.gdal.dir</fail>
         <fail unless="test.javafx.dir">Must set test.javafx.dir</fail>
         <fail unless="test.console.dir">Must set test.console.dir</fail>
         <fail unless="test.portrayal.dir">Must set test.portrayal.dir</fail>
@@ -363,7 +358,6 @@ is divided into following sections:
         <fail unless="test.utility.dir">Must set test.utility.dir</fail>
         <fail unless="test.fra-profile.dir">Must set test.fra-profile.dir</fail>
         <fail unless="test.jpn-profile.dir">Must set test.jpn-profile.dir</fail>
-        <fail unless="test.gdal.dir">Must set test.gdal.dir</fail>
         <fail unless="build.dir">Must set build.dir</fail>
         <fail unless="dist.dir">Must set dist.dir</fail>
         <fail unless="build.classes.dir">Must set build.classes.dir</fail>
@@ -384,7 +378,7 @@ is divided into following sections:
     </target>
     <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="modules.supported.internal" name="-init-macrodef-javac-with-module">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
+            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <attribute default="${javac.modulepath}" name="modulepath"/>
@@ -396,7 +390,7 @@ is divided into following sections:
             <attribute default="${excludes}" name="excludes"/>
             <attribute default="${javac.debug}" name="debug"/>
             <attribute default="${empty.dir}" name="sourcepath" unless:set="named.module.internal"/>
-            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" if:set="named.module.internal" name="sourcepath"/>
+            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}" if:set="named.module.internal" name="sourcepath"/>
             <attribute default="${empty.dir}" name="gensrcdir"/>
             <element name="customize" optional="true"/>
             <sequential>
@@ -451,7 +445,7 @@ is divided into following sections:
     </target>
     <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors" unless="modules.supported.internal">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
+            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <attribute default="${javac.modulepath}" name="modulepath"/>
@@ -494,7 +488,7 @@ is divided into following sections:
     </target>
     <target depends="-init-ap-cmdline-properties,-init-source-module-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
+            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <attribute default="${javac.modulepath}" name="modulepath"/>
@@ -529,7 +523,7 @@ is divided into following sections:
     </target>
     <target depends="-init-macrodef-javac-with-module,-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
         <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}" name="srcdir"/>
+            <attribute default="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <sequential>
@@ -713,9 +707,6 @@ is divided into following sections:
                             <fileset dir="${test.jpn-profile.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
                                 <filename name="@{testincludes}"/>
                             </fileset>
-                            <fileset dir="${test.gdal.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                                <filename name="@{testincludes}"/>
-                            </fileset>
                             <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
                                 <filename name="${test.binarytestincludes}"/>
                             </fileset>
@@ -790,9 +781,6 @@ is divided into following sections:
                     <fileset dir="${test.jpn-profile.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
                         <filename name="@{testincludes}"/>
                     </fileset>
-                    <fileset dir="${test.gdal.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
-                        <filename name="@{testincludes}"/>
-                    </fileset>
                 </union>
                 <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
                 <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="Apache_SIS_on_GeoAPI_4.0" testname="TestNG tests" workingDir="${work.dir}">
@@ -1275,7 +1263,7 @@ is divided into following sections:
                 <include name="*"/>
             </dirset>
         </pathconvert>
-        <j2seproject3:depend srcdir="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${src.gdal.dir}:${src.c.gdal.dir}:${build.generated.subdirs}"/>
+        <j2seproject3:depend srcdir="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile.dir}:${src.jpn-profile.dir}:${build.generated.subdirs}"/>
     </target>
     <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
         <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
@@ -1299,8 +1287,6 @@ is divided into following sections:
             <fileset dir="${src.utility.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${src.fra-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${src.jpn-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-            <fileset dir="${src.gdal.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-            <fileset dir="${src.c.gdal.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
         </copy>
     </target>
     <target if="has.persistence.xml" name="-copy-persistence-xml">
@@ -1321,7 +1307,7 @@ is divided into following sections:
     <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile/>
-        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}, module-info.java" sourcepath="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile. [...]
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}, module-info.java" sourcepath="${src.local-src.dir}:${src.javafx.dir}:${src.webapp.dir}:${src.console.dir}:${src.portrayal.dir}:${src.earth-obs.dir}:${src.geotiff.dir}:${src.netcdf.dir}:${src.shapefile.dir}:${src.sql.dir}:${src.xmlstore.dir}:${src.storage.dir}:${src.feature.dir}:${src.referencing.dir}:${src.ref-by-id.dir}:${src.metadata.dir}:${src.utility.dir}:${src.fra-profile. [...]
     </target>
     <target name="-post-compile-single">
         <!-- Empty placeholder for easier customization. -->
@@ -1770,12 +1756,6 @@ is divided into following sections:
             <fileset dir="${src.jpn-profile.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
                 <filename name="**/*.java"/>
             </fileset>
-            <fileset dir="${src.gdal.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
-                <filename name="**/*.java"/>
-            </fileset>
-            <fileset dir="${src.c.gdal.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
-                <filename name="**/*.java"/>
-            </fileset>
             <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                 <include name="**/*.java"/>
                 <exclude name="*.java"/>
@@ -1841,12 +1821,6 @@ is divided into following sections:
             <fileset dir="${src.jpn-profile.dir}" excludes="${excludes}" includes="${includes}">
                 <filename name="**/doc-files/**"/>
             </fileset>
-            <fileset dir="${src.gdal.dir}" excludes="${excludes}" includes="${includes}">
-                <filename name="**/doc-files/**"/>
-            </fileset>
-            <fileset dir="${src.c.gdal.dir}" excludes="${excludes}" includes="${includes}">
-                <filename name="**/doc-files/**"/>
-            </fileset>
             <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                 <include name="**/doc-files/**"/>
             </fileset>
@@ -1869,14 +1843,14 @@ is divided into following sections:
         <!-- You can override this target in the ../build.xml file. -->
     </target>
     <target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-javac-module-properties-with-module">
-        <j2seproject3:modulename property="test.module.name" sourcepath="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}:${test.gdal.dir}"/>
-        <condition else="${empty.dir}" property="javac.test.sourcepath" value="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}:${test.gdal.dir}">
+        <j2seproject3:modulename property="test.module.name" sourcepath="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}"/>
+        <condition else="${empty.dir}" property="javac.test.sourcepath" value="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}">
             <and>
                 <isset property="test.module.name"/>
                 <length length="0" string="${test.module.name}" when="greater"/>
             </and>
         </condition>
-        <condition else="--patch-module ${module.name}=${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}:${test.gdal.dir} --add-reads ${module.name}=ALL-UNNAMED" property="javac.test.com [...]
+        <condition else="--patch-module ${module.name}=${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir} --add-reads ${module.name}=ALL-UNNAMED" property="javac.test.compilerargs" value= [...]
             <and>
                 <isset property="test.module.name"/>
                 <length length="0" string="${test.module.name}" when="greater"/>
@@ -1917,10 +1891,10 @@ is divided into following sections:
     </target>
     <target depends="-init-test-javac-module-properties-with-module,-init-test-module-properties-without-module" name="-init-test-module-properties"/>
     <target if="do.depend.true" name="-compile-test-depend">
-        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}:${test.gdal.dir}"/>
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${test.feature.dir}:${test.referencing.dir}:${test.ref-by-id.dir}:${test.metadata.dir}:${test.utility.dir}:${test.fra-profile.dir}:${test.jpn-profile.dir}"/>
     </target>
     <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${te [...]
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir}:${test.storage.dir}:${te [...]
             <customize>
                 <compilerarg line="${javac.test.compilerargs}"/>
             </customize>
@@ -1943,7 +1917,6 @@ is divided into following sections:
             <fileset dir="${test.utility.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.fra-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.jpn-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-            <fileset dir="${test.gdal.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
         </copy>
     </target>
     <target name="-post-compile-test">
@@ -1958,7 +1931,7 @@ is divided into following sections:
     <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
-        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir} [...]
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${test.javafx.dir}:${test.console.dir}:${test.portrayal.dir}:${test.earth-obs.dir}:${test.geotiff.dir}:${test.netcdf.dir}:${test.shapefile.dir}:${test.sql.dir}:${test.xmlstore.dir} [...]
             <customize>
                 <compilerarg line="${javac.test.compilerargs}"/>
             </customize>
@@ -1981,7 +1954,6 @@ is divided into following sections:
             <fileset dir="${test.utility.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.fra-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${test.jpn-profile.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-            <fileset dir="${test.gdal.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
         </copy>
     </target>
     <target name="-post-compile-test-single">
diff --git a/ide-project/NetBeans/nbproject/genfiles.properties b/ide-project/NetBeans/nbproject/genfiles.properties
index 59fe61f..8278bf2 100644
--- a/ide-project/NetBeans/nbproject/genfiles.properties
+++ b/ide-project/NetBeans/nbproject/genfiles.properties
@@ -3,6 +3,6 @@
 build.xml.data.CRC32=58e6b21c
 build.xml.script.CRC32=462eaba0
 build.xml.stylesheet.CRC32=28e38971@1.53.1.46
-nbproject/build-impl.xml.data.CRC32=a9ed19c4
-nbproject/build-impl.xml.script.CRC32=532e10e3
+nbproject/build-impl.xml.data.CRC32=7361a050
+nbproject/build-impl.xml.script.CRC32=ec6b192e
 nbproject/build-impl.xml.stylesheet.CRC32=d549e5cc@1.99.0.48
diff --git a/ide-project/NetBeans/nbproject/project.properties b/ide-project/NetBeans/nbproject/project.properties
index b246187..2187e55 100644
--- a/ide-project/NetBeans/nbproject/project.properties
+++ b/ide-project/NetBeans/nbproject/project.properties
@@ -70,9 +70,6 @@ src.sql.dir          = ${project.root}/storage/sis-sqlstore/src/main/java
 test.sql.dir         = ${project.root}/storage/sis-sqlstore/src/test/java
 src.xmlstore.dir     = ${project.root}/storage/sis-xmlstore/src/main/java
 test.xmlstore.dir    = ${project.root}/storage/sis-xmlstore/src/test/java
-src.gdal.dir         = ${project.root}/storage/sis-gdal/src/main/java
-src.c.gdal.dir       = ${project.root}/storage/sis-gdal/src/main/c
-test.gdal.dir        = ${project.root}/storage/sis-gdal/src/test/java
 src.storage.dir      = ${project.root}/storage/sis-storage/src/main/java
 test.storage.dir     = ${project.root}/storage/sis-storage/src/test/java
 src.feature.dir      = ${project.root}/core/sis-feature/src/main/java
diff --git a/ide-project/NetBeans/nbproject/project.xml b/ide-project/NetBeans/nbproject/project.xml
index 4b802c3..1fa69a1 100644
--- a/ide-project/NetBeans/nbproject/project.xml
+++ b/ide-project/NetBeans/nbproject/project.xml
@@ -42,8 +42,6 @@
                 <root id="src.utility.dir" name="Utility"/>
                 <root id="src.fra-profile.dir" name="French profile"/>
                 <root id="src.jpn-profile.dir" name="Japanese profile"/>
-                <root id="src.gdal.dir" name="GDAL/Proj4"/>
-                <root id="src.c.gdal.dir" name="GDAL/Proj4 JNI"/>
             </source-roots>
             <test-roots>
                 <root id="test.javafx.dir" name="Test JavaFX application"/>
@@ -63,7 +61,6 @@
                 <root id="test.utility.dir" name="Test Utility"/>
                 <root id="test.fra-profile.dir" name="Test French profile"/>
                 <root id="test.jpn-profile.dir" name="Test Japanese profile"/>
-                <root id="test.gdal.dir" name="Test GDAL/Proj4"/>
             </test-roots>
         </data>
         <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
diff --git a/storage/pom.xml b/storage/pom.xml
index 0c76247..1172482 100644
--- a/storage/pom.xml
+++ b/storage/pom.xml
@@ -170,7 +170,6 @@
     <module>sis-netcdf</module>
     <module>sis-geotiff</module>
     <module>sis-earth-observation</module>
-    <module>sis-gdal</module>
   </modules>
 
 </project>
diff --git a/storage/sis-gdal/pom.xml b/storage/sis-gdal/pom.xml
deleted file mode 100644
index a482392..0000000
--- a/storage/sis-gdal/pom.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  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.
--->
-
-<project xmlns              = "http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi          = "http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
-                               http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.apache.sis</groupId>
-    <artifactId>storage</artifactId>
-    <version>2.0-SNAPSHOT</version>
-  </parent>
-
-
-  <!-- ===========================================================
-           Module Description
-       =========================================================== -->
-  <groupId>org.apache.sis.storage</groupId>
-  <artifactId>sis-gdal</artifactId>
-  <name>Apache SIS bindings for Proj4</name>
-  <description>
-    Referencing services from Proj4 through GeoAPI interfaces.
-  </description>
-
-
-  <!-- ===========================================================
-           Developers and Contributors
-       =========================================================== -->
-  <developers>
-    <developer>
-      <name>Martin Desruisseaux</name>
-      <id>desruisseaux</id>
-      <email>desruisseaux@apache.org</email>
-      <organization>Geomatys</organization>
-      <organizationUrl>https://www.geomatys.com</organizationUrl>
-      <timezone>+1</timezone>
-      <roles>
-        <role>developer</role>
-      </roles>
-    </developer>
-    <developer>
-      <name>Jean-Loup Amiot</name>
-      <organization>Geomatys</organization>
-      <organizationUrl>https://www.geomatys.com</organizationUrl>
-      <timezone>+1</timezone>
-      <roles>
-        <role>developer</role>
-      </roles>
-    </developer>
-  </developers>
-
-
-  <!-- ===========================================================
-           Build configuration
-       =========================================================== -->
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <configuration>
-          <archive>
-            <manifestEntries>
-              <Automatic-Module-Name>
-                org.apache.sis.storage.gdal
-              </Automatic-Module-Name>
-            </manifestEntries>
-          </archive>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-
-  <!-- ===========================================================
-           Dependencies
-       =========================================================== -->
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.sis.core</groupId>
-      <artifactId>sis-referencing</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sis.core</groupId>
-      <artifactId>sis-metadata</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sis.core</groupId>
-      <artifactId>sis-referencing</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/storage/sis-gdal/src/main/c/Makefile b/storage/sis-gdal/src/main/c/Makefile
deleted file mode 100644
index 85267d9..0000000
--- a/storage/sis-gdal/src/main/c/Makefile
+++ /dev/null
@@ -1,77 +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.
-#
-
-#
-# Compile the native part of the bindings to Proj.4.  This build process requires the Proj.4 library to be installed
-# on the current platform, preferably by the platform packaging mechanism (e.g. synaptic packages on Ubuntu, macport
-# on MacOS, etc). The Proj.4 header files are expected to be found either in the "/usr/local/include" directory (for
-# example on Linux distributions), or "/opt/local/include" on some other platforms.
-#
-# HOW TO BUILD:
-# C/C++ compilation is currently not part of Maven build. Compilation shall be done manually like below:
-#
-#     cd storage/sis-gdal/src/main/c
-#     make
-#
-# The executable will be created in the "storage/sis-gdal/src/resources/native/<platform>/" directory for inclusion
-# in the JAR file. Only the executable for the current platform will be updated. If the JNI have been updated, then
-# 'make' will need to be executed on all supported platforms.
-#
-# GCC options reminder:
-#    -shared		Produce a shared object which can then be linked with other objects to form an executable.
-#    -shared-libgcc	Use the shared version of libgcc. Recommended for JNI when exceptions may be thrown from gcc.
-#    -fpic		Generate position-independent code suitable for use in a shared library.
-#    -O2		Performs nearly all supported optimizations that do not involve a space-speed tradeoff.
-#
-FLAG   = -shared -shared-libgcc -fpic -O2
-LIB    = -lm -ldl -lproj
-SRC    = org_apache_sis_storage_gdal_PJ.c
-OUT    = libproj-binding.so
-
-ifndef JAVA_HOME
-    $(error JAVA_HOME is not set.)
-endif
-
-INCLUDE_DIR = -I$(JAVA_HOME)/include -I/usr/local/include -I/opt/local/include
-
-ifndef OS
-    OS = $(shell uname)
-endif
-
-ifeq ($(OS),Windows_NT)
-    OUTDIR = window
-endif
-
-ifeq ($(OS),Linux)
-    INCLUDE_DIR += -I$(JAVA_HOME)/include/linux
-    OUTDIR = linux
-endif
-
-ifeq ($(OS),Darwin)
-    INCLUDE_DIR += -I$(JAVA_HOME)/include/darwin
-    LIB += -L/opt/local/lib
-    OUTDIR = darwin
-endif
-
-ifndef OUTDIR
-    $(error The $(OS) platform is not supported by this makefile.)
-endif
-
-# The $(LIB) parameter should be last (it way work anywhere,
-# but putting it last allows more predictable results).
-all:
-	gcc $(FLAG) $(INCLUDE_DIR) -o ../resources/native/$(OUTDIR)/$(OUT) $(SRC) $(LIB)
diff --git a/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.c b/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.c
deleted file mode 100644
index 329dc4c..0000000
--- a/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.c
+++ /dev/null
@@ -1,321 +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.
- */
-#include <math.h>
-#include <string.h>
-#include <proj_api.h>
-#include "org_apache_sis_storage_gdal_PJ.h"
-
-
-#define PJ_FIELD_NAME "ptr"
-#define PJ_FIELD_TYPE "J"
-
-
-/*!
- * \brief
- * Internal method returning the address of the PJ structure wrapped by the given Java object.
- * This function looks for a field named "ptr" and of type "long" (Java signature "J") in the
- * given object.
- *
- * \param  env    - The JNI environment.
- * \param  object - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \return The address of the PJ structure, or NULL if the operation fails (for example
- *         because the "ptr" field was not found).
- */
-projPJ getPJ(JNIEnv *env, jobject object)
-{
-    jfieldID id = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, object), PJ_FIELD_NAME, PJ_FIELD_TYPE);
-    return (id) ? (projPJ) (*env)->GetLongField(env, object, id) : NULL;
-}
-
-/*!
- * \brief
- * Returns the Proj4 release number.
- *
- * \param  env   - The JNI environment.
- * \param  class - The class from which this method has been invoked.
- * \return The Proj4 release number, or NULL.
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getRelease
-  (JNIEnv *env, jclass class)
-{
-    const char *desc = pj_get_release();
-    return (desc) ? (*env)->NewStringUTF(env, desc) : NULL;
-}
-
-/*!
- * \brief
- * Allocates a new PJ structure from a definition string.
- *
- * \param  env        - The JNI environment.
- * \param  class      - The class from which this method has been invoked.
- * \param  definition - The string definition to be given to Proj4.
- * \return The address of the new PJ structure, or 0 in case of failure.
- */
-JNIEXPORT jlong JNICALL Java_org_apache_sis_storage_gdal_PJ_allocatePJ
-  (JNIEnv *env, jclass class, jstring definition)
-{
-    const char *def_utf = (*env)->GetStringUTFChars(env, definition, NULL);
-    if (!def_utf) return 0;             // OutOfMemoryError already thrown.
-    projPJ pj = pj_init_plus(def_utf);
-    (*env)->ReleaseStringUTFChars(env, definition, def_utf);
-    return (jlong) pj;
-}
-
-/*!
- * \brief
- * Allocates a new geographic PJ structure from an existing one.
- *
- * \param  env       - The JNI environment.
- * \param  class     - The class from which this method has been invoked.
- * \param  projected - The PJ object from which to derive a new one.
- * \return The address of the new PJ structure, or 0 in case of failure.
- */
-JNIEXPORT jlong JNICALL Java_org_apache_sis_storage_gdal_PJ_allocateGeoPJ
-  (JNIEnv *env, jclass class, jobject projected)
-{
-    projPJ pj = getPJ(env, projected);
-    return (pj) ? (jlong) pj_latlong_from_proj(pj) : 0;
-}
-
-/*!
- * \brief
- * Returns the definition string.
- *
- * \param  env    - The JNI environment.
- * \param  object - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \return The definition string.
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getCode
-  (JNIEnv *env, jobject object)
-{
-    projPJ pj = getPJ(env, object);
-    if (pj) {
-        const char *desc = pj_get_def(pj, 0);
-        if (desc) {
-            const char *trim = desc;
-            if (*trim == ' ') trim++;
-            jstring str = (*env)->NewStringUTF(env, trim);
-            pj_dalloc((char*) desc);
-            return str;
-        }
-    }
-    return NULL;
-}
-
-/*!
- * \brief
- * Returns the CRS type as one of the PJ.Type enum: GEOGRAPHIC, GEOCENTRIC or PROJECTED.
- * This function should never return NULL, unless class or fields have been renamed in
- * such a way that we can not find anymore the expected enum values.
- *
- * \param  env    - The JNI environment.
- * \param  object - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \return The CRS type as one of the PJ.Type enum.
- */
-JNIEXPORT jobject JNICALL Java_org_apache_sis_storage_gdal_PJ_getType
-  (JNIEnv *env, jobject object)
-{
-    projPJ pj = getPJ(env, object);
-    if (pj) {
-        const char *type;
-        if (pj_is_latlong(pj)) {
-            type = "GEOGRAPHIC";
-        } else if (pj_is_geocent(pj)) {
-            type = "GEOCENTRIC";
-        } else {
-            type = "PROJECTED";
-        }
-        jclass c = (*env)->FindClass(env, "org/apache/sis/storage/gdal/PJ$Type");
-        if (c) {
-            jfieldID id = (*env)->GetStaticFieldID(env, c, type, "Lorg/apache/sis/storage/gdal/PJ$Type;");
-            if (id) {
-                return (*env)->GetStaticObjectField(env, c, id);
-            }
-        }
-    }
-    return NULL;
-}
-
-/*!
- * \brief
- * Returns the semi-major axis length and eccentricity squared in an array of length 2.
- *
- * \param  env    - The JNI environment.
- * \param  object - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \return The semi-major axis length and eccentricity squared in an array of length 2.
- */
-JNIEXPORT jdoubleArray JNICALL Java_org_apache_sis_storage_gdal_PJ_getEllipsoidDefinition
-  (JNIEnv *env, jobject object)
-{
-    projPJ pj = getPJ(env, object);
-    if (pj) {
-        double major_axis;
-        double eccentricity_squared;
-        pj_get_spheroid_defn(pj, &major_axis, &eccentricity_squared);
-        jdoubleArray array = (*env)->NewDoubleArray(env, 2);
-        if (array) {
-            jdouble* def = (*env)->GetDoubleArrayElements(env, array, NULL);
-            if (def) {
-                def[0] = major_axis;
-                def[1] = eccentricity_squared;
-                (*env)->ReleaseDoubleArrayElements(env, array, def, 0);
-            }
-            return array;
-        }
-    }
-    return NULL;
-}
-
-/*!
- * \brief
- * Converts input values from degrees to radians before coordinate operation, or the output
- * values from radians to degrees after the coordinate operation.
- *
- * \param pj        - The Proj.4 PJ structure.
- * \param data      - The coordinate array to transform.
- * \param numPts    - Number of points to transform.
- * \param dimension - Dimension of points in the coordinate array.
- * \param factor    - The scale factor to apply: M_PI/180 for inputs or 180/M_PI for outputs.
- */
-void convertAngularOrdinates(projPJ pj, double* data, jint numPts, int dimension, double factor) {
-    int dimToSkip;
-    if (pj_is_latlong(pj)) {
-        // Convert only the 2 first coordinates and skip all the other dimensions.
-        dimToSkip = dimension - 2;
-    } else if (pj_is_geocent(pj)) {
-        // Convert only the 3 first coordinates and skip all the other dimensions.
-        dimToSkip = dimension - 3;
-    } else {
-        // Not a geographic or geocentric CRS: nothing to convert.
-        return;
-    }
-    double *stop = data + dimension*numPts;
-    if (dimToSkip > 0) {
-        while (data != stop) {
-            (*data++) *= factor;
-            (*data++) *= factor;
-            data += dimToSkip;
-        }
-    } else {
-        while (data != stop) {
-            (*data++) *= factor;
-        }
-    }
-}
-
-/*!
- * \brief
- * Transforms in-place the coordinates in the given array.
- *
- * \param env         - The JNI environment.
- * \param object      - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \param target      - The target CRS.
- * \param dimension   - The dimension of each coordinate value. Must be equals or greater than 2.
- * \param coordinates - The coordinates to transform, as a sequence of (x,y,<z>,...) tuples.
- * \param offset      - Offset of the first coordinate in the given array.
- * \param numPts      - Number of points to transform.
- */
-JNIEXPORT void JNICALL Java_org_apache_sis_storage_gdal_PJ_transform
-  (JNIEnv *env, jobject object, jobject target, jint dimension, jdoubleArray coordinates, jint offset, jint numPts)
-{
-    if (!target || !coordinates) {
-        jclass c = (*env)->FindClass(env, "java/lang/NullPointerException");
-        if (c) (*env)->ThrowNew(env, c, "The target CRS and the coordinates array can not be null.");
-        return;
-    }
-    if (dimension < 2 || dimension > 100) {     // Arbitrary upper value for catching potential misuse.
-        jclass c = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
-        if (c) (*env)->ThrowNew(env, c, "Illegal dimension. Must be in the [2-100] range.");
-        return;
-    }
-    if ((offset < 0) || (numPts < 0) || (offset + dimension*numPts) > (*env)->GetArrayLength(env, coordinates)) {
-        jclass c = (*env)->FindClass(env, "java/lang/ArrayIndexOutOfBoundsException");
-        if (c) (*env)->ThrowNew(env, c, "Illegal offset or illegal number of points.");
-        return;
-    }
-    projPJ src_pj = getPJ(env, object);
-    projPJ dst_pj = getPJ(env, target);
-    if (src_pj && dst_pj) {
-        // Using GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical rather than
-        // GetDoubleArrayElements/ReleaseDoubleArrayElements increase the chances that
-        // the JVM returns direct reference to its internal array without copying data.
-        // However we must promise to run the "critical" code fast, to not make any
-        // system call that may wait for the JVM and to not invoke any other JNI method.
-        double *data = (*env)->GetPrimitiveArrayCritical(env, coordinates, NULL);
-        if (data) {
-            double *x = data + offset;
-            double *y = x + 1;
-            double *z = (dimension >= 3) ? y+1 : NULL;
-            convertAngularOrdinates(src_pj, x, numPts, dimension, M_PI/180);
-            int err = pj_transform(src_pj, dst_pj, numPts, dimension, x, y, z);
-            convertAngularOrdinates(dst_pj, x, numPts, dimension, 180/M_PI);
-            (*env)->ReleasePrimitiveArrayCritical(env, coordinates, data, 0);
-            if (err) {
-                jclass c = (*env)->FindClass(env, "org/opengis/referencing/operation/TransformException");
-                if (c) (*env)->ThrowNew(env, c, pj_strerrno(err));
-            }
-        }
-    }
-}
-
-/*!
- * \brief
- * Returns a description of the last error that occurred, or NULL if none.
- *
- * \param  env    - The JNI environment.
- * \param  object - The Java object wrapping the PJ structure (not allowed to be NULL).
- * \return The last error, or NULL.
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getLastError
-  (JNIEnv *env, jobject object)
-{
-    /*
-     * For now we ignore the object reference, but a future version may use it if
-     * we make this method thread-safe with the use of a Proj.4 context parameter.
-     * Note that this method needs to work even if getPJ(env, object) returns NULL.
-     */
-    int err = *pj_get_errno_ref();
-    if (err) {
-        return (*env)->NewStringUTF(env, pj_strerrno(err));
-    }
-    return NULL;
-}
-
-/*!
- * \brief
- * Deallocate the PJ structure. This method is invoked by the garbage collector exactly once.
- * This method will also set the Java "ptr" final field to 0 as a safety. In theory we are not
- * supposed to change the value of a final field. But no Java code should use this field, and
- * the PJ object is being garbage collected anyway. We set the field to 0 as a safety in case
- * some user invoked the finalize() method explicitly despite our warning in the Javadoc to
- * never do such thing.
- *
- * \param env    - The JNI environment.
- * \param object - The Java object wrapping the PJ structure (not allowed to be NULL).
- */
-JNIEXPORT void JNICALL Java_org_apache_sis_storage_gdal_PJ_finalize
-  (JNIEnv *env, jobject object)
-{
-    jfieldID id = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, object), PJ_FIELD_NAME, PJ_FIELD_TYPE);
-    if (id) {
-        projPJ pj = (projPJ) (*env)->GetLongField(env, object, id);
-        if (pj) {
-            (*env)->SetLongField(env, object, id, (jlong) 0);
-            pj_free(pj);
-        }
-    }
-}
diff --git a/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.h b/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.h
deleted file mode 100644
index ae745e8..0000000
--- a/storage/sis-gdal/src/main/c/org_apache_sis_storage_gdal_PJ.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_apache_sis_storage_gdal_PJ */
-
-#ifndef _Included_org_apache_sis_storage_gdal_PJ
-#define _Included_org_apache_sis_storage_gdal_PJ
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    allocatePJ
- * Signature: (Ljava/lang/String;)J
- */
-JNIEXPORT jlong JNICALL Java_org_apache_sis_storage_gdal_PJ_allocatePJ
-  (JNIEnv *, jclass, jstring);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    allocateGeoPJ
- * Signature: (Lorg/apache/sis/storage/gdal/PJ;)J
- */
-JNIEXPORT jlong JNICALL Java_org_apache_sis_storage_gdal_PJ_allocateGeoPJ
-  (JNIEnv *, jclass, jobject);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    getRelease
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getRelease
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    getCode
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getCode
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    getType
- * Signature: ()Lorg/apache/sis/storage/gdal/PJ/Type;
- */
-JNIEXPORT jobject JNICALL Java_org_apache_sis_storage_gdal_PJ_getType
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    getEllipsoidDefinition
- * Signature: ()[D
- */
-JNIEXPORT jdoubleArray JNICALL Java_org_apache_sis_storage_gdal_PJ_getEllipsoidDefinition
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    transform
- * Signature: (Lorg/apache/sis/storage/gdal/PJ;I[DII)V
- */
-JNIEXPORT void JNICALL Java_org_apache_sis_storage_gdal_PJ_transform
-  (JNIEnv *, jobject, jobject, jint, jdoubleArray, jint, jint);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    getLastError
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_apache_sis_storage_gdal_PJ_getLastError
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_apache_sis_storage_gdal_PJ
- * Method:    finalize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_apache_sis_storage_gdal_PJ_finalize
-  (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java b/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
deleted file mode 100644
index d191186..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/OperationFactory.java
+++ /dev/null
@@ -1,57 +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.internal.storage.gdal;
-
-import java.util.Set;
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.apache.sis.internal.referencing.SpecializedOperationFactory;
-import org.apache.sis.internal.util.CollectionsExt;
-import org.apache.sis.storage.gdal.Proj4;
-
-
-/**
- * The factory for operations between pair of {@literal Proj.4} wrappers.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final class OperationFactory implements SpecializedOperationFactory {
-    /**
-     * Creates a new factory.
-     */
-    public OperationFactory() {
-    }
-
-    /**
-     * Returns an operation between the given pair of CRS, or an empty set if this factory does not recognize
-     * the given CRSs.
-     *
-     * @return the coordinate operation, or an empty set if the given CRSs are not Proj.4 wrappers.
-     * @throws FactoryException if the given CRSs are Proj.4 wrappers and an error occurred while
-     *         creating the coordinate operation.
-     */
-    @Override
-    public Set<CoordinateOperation> findOperations(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS)
-            throws FactoryException
-    {
-        return CollectionsExt.singletonOrEmpty(Proj4.createOperation(sourceCRS, targetCRS, false));
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java b/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
deleted file mode 100644
index 5db19e8..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/internal/storage/gdal/package-info.java
+++ /dev/null
@@ -1,26 +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.
- */
-
-/**
- * Service providers for {@code sis-gdal} module.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-package org.apache.sis.internal.storage.gdal;
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/PJ.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/PJ.java
deleted file mode 100644
index 7939ecc..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/PJ.java
+++ /dev/null
@@ -1,361 +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.storage.gdal;
-
-import java.util.Objects;
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.io.InvalidObjectException;
-import org.opengis.metadata.Identifier;
-import org.opengis.util.FactoryException;
-import org.opengis.metadata.citation.Citation;
-import org.opengis.referencing.datum.Ellipsoid;
-import org.opengis.referencing.datum.GeodeticDatum;
-import org.opengis.referencing.datum.PrimeMeridian;
-import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
-import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.system.OS;
-
-
-/**
- * Wraps the <a href="http://proj.osgeo.org/">{@literal Proj.4}</a> {@code PJ} native data structure.
- * Many methods defined in this class are native methods delegating their work to the Proj.4 library.
- * This class is the only place where such native methods are defined for Proj.4 support.
- *
- * <p>In the Proj.4 library, the {@code PJ} structure is an aggregation of {@link GeodeticDatum},
- * {@link Ellipsoid}, {@link PrimeMeridian}, {@link org.opengis.referencing.cs.CoordinateSystem},
- * {@link org.opengis.referencing.crs.CoordinateReferenceSystem} and their sub-interfaces.
- * The relationship with the GeoAPI methods is indicated in the "See" tags when appropriate.</p>
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-@SuppressWarnings("serial")     // serialVersionUID not needed since writeReplace() gives another kind of object.
-final class PJ implements Identifier, Serializable {
-    /**
-     * Loads the {@literal Proj.4} library.
-     * This static initializer may throw a {@link UnsatisfiedLinkError} if the static library can not be loaded.
-     * In such case, any future attempt to use this {@code PJ} class will cause a {@link NoClassDefFoundError}
-     * as per Java language specification.
-     */
-    static {
-        OS.load(PJ.class, "libproj-binding");
-    }
-
-    /**
-     * The pointer to {@code PJ} structure allocated in the C/C++ heap. This value has no meaning in Java code,
-     * except 0 which means no native object. <strong>Do not modify</strong>, since this value is used by Proj.4.
-     * Do not rename neither, unless you update accordingly the C code in JNI wrappers.
-     */
-    private final long ptr;
-
-    /**
-     * Creates a new {@code PJ} structure from the given {@literal Proj.4} definition string.
-     *
-     * @param  definition  the Proj.4 definition string.
-     * @throws InvalidGeodeticParameterException if the PJ structure can not be created from the given string.
-     */
-    public PJ(final String definition) throws InvalidGeodeticParameterException {
-        Objects.requireNonNull(definition);
-        ptr = allocatePJ(definition);
-        if (ptr == 0) {
-            // Note: our getLastError() implementation is safe even if pts == 0.
-            throw new InvalidGeodeticParameterException(getLastError());
-        }
-    }
-
-    /**
-     * Creates a new {@code PJ} structure for the geographic part of the given {@code PJ} object.
-     * This constructor is usually for getting the
-     * {@linkplain org.opengis.referencing.crs.ProjectedCRS#getBaseCRS() base geographic CRS}
-     * from a {@linkplain org.opengis.referencing.crs.ProjectedCRS projected CRS}.
-     *
-     * @param  crs   the CRS (usually projected) from which to derive a new CRS.
-     * @throws FactoryException if the PJ structure can not be created.
-     */
-    public PJ(final PJ crs) throws FactoryException {
-        Objects.requireNonNull(crs);
-        ptr = allocateGeoPJ(crs);
-        if (ptr == 0) {
-            throw new FactoryException(crs.getLastError());
-        }
-    }
-
-    /**
-     * Allocates a PJ native data structure and returns the pointer to it. This method should be invoked by
-     * the constructor only, and the return value <strong>must</strong> be assigned to the {@link #ptr} field.
-     * The allocated structure is released by the {@link #finalize()} method.
-     *
-     * @param  definition  the Proj.4 definition string.
-     * @return a pointer to the PJ native data structure, or 0 if the operation failed.
-     */
-    private static native long allocatePJ(String definition);
-
-    /**
-     * Allocates a PJ native data structure for the base geographic CRS of the given CRS, and returns the pointer to it.
-     * This method should be invoked by the constructor only, and the return value <strong>must</strong> be assigned to
-     * the {@link #ptr} field. The allocated structure is released by the {@link #finalize()} method.
-     *
-     * @param  projected  the CRS from which to derive the base geographic CRS.
-     * @return a pointer to the PJ native data structure, or 0 if the operation failed.
-     */
-    private static native long allocateGeoPJ(PJ projected);
-
-    /**
-     * Returns the project responsible for maintenance of the namespace.
-     *
-     * @see #getCodeSpace()
-     */
-    @Override
-    public Citation getAuthority() {
-        return Citations.PROJ4;
-    }
-
-    /**
-     * Returns the version identifier for the namespace, as specified by the code authority.
-     * This method* parses the Proj.4 release string (for example <cite>"Rel. 4.9.3, 15 August 2016"</cite>)
-     * for extracting the version number ("4.9.3" in above example).
-     *
-     * @see Proj4#version()
-     */
-    @Override
-    public String getVersion() {
-        String rel = getRelease();
-        if (rel != null) {
-            int start = -1;
-            final int length = rel.length();
-            for (int c, i=0; i < length; i += Character.charCount(c)) {
-                c = rel.codePointAt(i);
-                if (Character.isDigit(c)) {
-                    if (start < 0) start = i;
-                } else if (c != '.' && start >= 0) {
-                    return rel.substring(start, i);
-                }
-            }
-        }
-        return rel;
-    }
-
-    /**
-     * Returns the version number of the {@literal Proj.4} library.
-     *
-     * @return the Proj.4 release string.
-     *
-     * @see #getVersion()
-     * @see Proj4#version()
-     */
-    static native String getRelease();
-
-    /**
-     * Returns the namespace in which the code is valid.
-     *
-     * @see #getAuthority()
-     * @see #getCode()
-     */
-    @Override
-    public String getCodeSpace() {
-        return Constants.PROJ4;
-    }
-
-    /**
-     * Returns the {@literal Proj.4} definition string. This is the string given to the constructor,
-     * expanded with as much information as possible.
-     *
-     * <div class="note"><b>Example:</b> "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"</div>
-     *
-     * @return the Proj.4 definition string.
-     */
-    @Override
-    public native String getCode();
-
-    /**
-     * Returns the Coordinate Reference System type.
-     *
-     * @return the CRS type.
-     */
-    public native Type getType();
-
-    /**
-     * The coordinate reference system (CRS) type returned by {@link PJ#getType()}.
-     * In the Proj.4 library, a CRS can only be geographic, geocentric or projected,
-     * without distinction between 2D and 3D CRS.
-     */
-    enum Type {
-        /*
-         * IMPLEMENTATION NOTE: Do not rename those fields, unless you update the
-         * native C code accordingly.
-         */
-
-        /**
-         * The CRS is of type {@link org.opengis.referencing.crs.GeographicCRS}.
-         * The CRS can be two-dimensional or three-dimensional.
-         */
-        GEOGRAPHIC,
-
-        /**
-         * The CRS is of type {@link org.opengis.referencing.crs.GeocentricCRS}.
-         * The CRS can only be three-dimensional.
-         */
-        GEOCENTRIC,
-
-        /**
-         * The CRS is of type {@link org.opengis.referencing.crs.ProjectedCRS}.
-         * The CRS can be two-dimensional or three-dimensional.
-         */
-        PROJECTED
-    }
-
-    /**
-     * Returns the semi-major axis length and the square of the ellipsoid eccentricity (ε²).
-     * The eccentricity is related to axis length by ε=√(1-(<var>b</var>/<var>a</var>)²).
-     * The eccentricity of a sphere is zero. Other related quantities are:
-     *
-     * <ul>
-     *   <li>semi-minor axis length: b = a × √(1 - ε²)</li>
-     *   <li>inverse flattening: invf = 1 / (1 - √(1 - ε²))</li>
-     * </ul>
-     *
-     * @return the semi-major axis length and the eccentricity squared in an array of length 2.
-     *
-     * @see Ellipsoid#isSphere()
-     * @see Ellipsoid#getInverseFlattening()
-     */
-    public native double[] getEllipsoidDefinition();
-
-    /**
-     * Transforms in-place the coordinates in the given array.
-     * The coordinates array shall contain (<var>x</var>,<var>y</var>,<var>z</var>,…) tuples,
-     * where the <var>z</var> and any additional dimensions are optional.
-     * Note that any dimension after the <var>z</var> value are ignored.
-     *
-     * <p>Input and output units:</p>
-     * <ul>
-     *   <li>Angular units (as in longitude and latitudes) are decimal degrees.</li>
-     *   <li>Linear units are usually metres, but this is actually projection-dependent.</li>
-     * </ul>
-     *
-     * @param  target       the target CRS.
-     * @param  dimension    the dimension of each coordinate value. Typically 2, 3 or 4.
-     * @param  coordinates  the coordinates to transform, as a sequence of (<var>x</var>,<var>y</var>,&lt;<var>z</var>&gt;,…) tuples.
-     * @param  offset       offset of the first coordinate in the given array.
-     * @param  numPts       number of points to transform.
-     * @throws NullPointerException if the {@code target} or {@code coordinates} argument is null.
-     * @throws IndexOutOfBoundsException if the {@code offset} or {@code numPts} arguments are invalid.
-     * @throws TransformException if the operation failed for another reason (provided by Proj.4).
-     *
-     * @see org.opengis.referencing.operation.MathTransform#transform(double[], int, double[], int, int)
-     */
-    public native void transform(PJ target, int dimension, double[] coordinates, int offset, int numPts)
-            throws TransformException;
-
-    /**
-     * Returns a description of the last error that occurred, or {@code null} if none.
-     *
-     * @return the last error that occurred, or {@code null}.
-     *
-     * @todo this method is not thread-safe. Proj.4 provides a better alternative using a context parameter.
-     *       Note that this method needs to be safe even if {@link #ptr} is 0.
-     */
-    native String getLastError();
-
-    /**
-     * Returns a hash code value for this {@literal Proj.4} object.
-     */
-    @Override
-    public int hashCode() {
-        return ~getCode().hashCode();
-    }
-
-    /**
-     * Compares this identifier with the given object for equality.
-     */
-    @Override
-    public boolean equals(final Object other) {
-        return (other instanceof PJ) && getCode().equals(((PJ) other).getCode());
-    }
-
-    /**
-     * Returns the string representation of the PJ structure.
-     *
-     * @return the string representation.
-     */
-    @Override
-    public String toString() {
-        return IdentifiedObjects.toString(this);
-    }
-
-    /**
-     * Deallocates the native PJ data structure.
-     * It is okay if this method is invoked more than once.
-     */
-    @Override
-    @SuppressWarnings("FinalizeDeclaration")
-    protected final native void finalize();
-
-    /**
-     * The object serialized in place of {@literal Proj.4} wrappers.
-     * Deserialization checks for the presence of Proj.4 native library.
-     *
-     * @author  Martin Desruisseaux (Geomatys)
-     * @version 0.8
-     * @since   0.8
-     * @module
-     */
-    private static final class Serialized implements Serializable {
-        /**
-         * For cross-version compatibility.
-         */
-        private static final long serialVersionUID = -5705027681492462823L;
-
-        /**
-         * The {@literal Proj.4} definition string.
-         */
-        private final String definition;
-
-        /**
-         * Creates a new proxy for the given {@literal Proj.4} definition.
-         */
-        Serialized(final String definition) {
-            this.definition = definition;
-        }
-
-        /**
-         * Automatically invoked on deserialization for reconstructing the wrapper
-         * from the {@literal Proj.4} definition string.
-         */
-        protected final Object readResolve() throws ObjectStreamException {
-            try {
-                return new PJ(definition);
-            } catch (UnsatisfiedLinkError | NoClassDefFoundError | InvalidGeodeticParameterException e) {
-                throw (InvalidObjectException) new InvalidObjectException(Proj4.unavailable(e)).initCause(e);
-            }
-        }
-    }
-
-    /**
-     * Invoked automatically on serialization.
-     * Replaces this {@literal Proj.4} wrapper by a proxy without native resource.
-     */
-    protected final Object writeReplace() throws ObjectStreamException {
-        return new Serialized(getCode());
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java
deleted file mode 100644
index c7ad868..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4.java
+++ /dev/null
@@ -1,401 +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.storage.gdal;
-
-import javax.measure.Unit;
-import javax.measure.quantity.Angle;
-import javax.measure.format.ParserException;
-import org.opengis.metadata.Identifier;
-import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.metadata.extent.GeographicBoundingBox;
-import org.opengis.referencing.IdentifiedObject;
-import org.opengis.referencing.crs.GeodeticCRS;
-import org.opengis.referencing.crs.ProjectedCRS;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.cs.CoordinateSystemAxis;
-import org.opengis.referencing.cs.AxisDirection;
-import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.cs.CartesianCS;
-import org.opengis.referencing.cs.EllipsoidalCS;
-import org.opengis.referencing.datum.Ellipsoid;
-import org.opengis.referencing.datum.GeodeticDatum;
-import org.opengis.referencing.datum.PrimeMeridian;
-import org.opengis.referencing.operation.Projection;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
-import org.apache.sis.referencing.factory.UnavailableFactoryException;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
-import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
-import org.apache.sis.referencing.datum.BursaWolfParameters;
-import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.referencing.CRS;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.internal.referencing.AxisDirections;
-import org.apache.sis.internal.system.Modules;
-import org.apache.sis.internal.system.OS;
-import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.Utilities;
-import org.apache.sis.util.Static;
-import org.apache.sis.util.iso.Types;
-import org.apache.sis.measure.Units;
-
-
-/**
- * Bindings to the {@literal Proj.4} library as static convenience methods.
- * The methods in this class allow to:
- *
- * <ul>
- *   <li>{@linkplain #createCRS Create a Coordinate Reference System instance from a Proj.4 definition string}.</li>
- *   <li>Conversely, {@linkplain #definition get a Proj.4 definition string from a Coordinate Reference System}.</li>
- *   <li>{@linkplain #createOperation Create a coordinate operation backed by Proj.4 between two arbitrary CRS}.</li>
- * </ul>
- *
- * Most methods in this class delegate to {@link Proj4Factory}.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @author  Johann Sorel (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final class Proj4 extends Static {
-    /**
-     * Do not allow instantiation of this class.
-     */
-    private Proj4() {
-    }
-
-    /**
-     * Returns the version number of the {@literal Proj.4} library.
-     * Returns {@code null} if Proj.4 is not installed on the current system.
-     *
-     * <div class="note"><b>Example:</b> Rel. 4.9.3, 15 August 2016</div>
-     *
-     * @return the Proj.4 release string, or {@code null} if the native library has been found.
-     */
-    public static String version() {
-        try {
-            return PJ.getRelease();
-        } catch (UnsatisfiedLinkError e) {
-            // Thrown the first time that we try to use the library.
-            Logging.unexpectedException(Logging.getLogger(Modules.GDAL), Proj4.class, "version", e);
-        } catch (NoClassDefFoundError e) {
-            // Thrown on all attempts after the first one.
-            Logging.recoverableException(Logging.getLogger(Modules.GDAL), Proj4.class, "version", e);
-        }
-        return null;
-    }
-
-    /**
-     * Infers a {@literal Proj.4} definition from the given projected, geographic or geocentric coordinate reference system.
-     * This method does not need the Proj.4 native library; it can be used in a pure Java application.
-     * However the returned definition string may differ depending on whether the Proj.4 library is available or not.
-     *
-     * @param  crs  the coordinate reference system for which to create a Proj.4 definition.
-     * @return the definition of the given CRS in a Proj.4 format.
-     * @throws FactoryException if the Proj.4 definition string can not be created from the given CRS.
-     */
-    public static String definition(final CoordinateReferenceSystem crs) throws FactoryException {
-        ArgumentChecks.ensureNonNull("crs", crs);
-        /*
-         * If the given CRS object is associated to a Proj.4 structure, let Proj.4 formats itself
-         * the definition string. Note that this operation may fail if there is no Proj.4 library
-         * in the current system, or no JNI bindings to that library.
-         */
-        try {
-            for (final Identifier id : crs.getIdentifiers()) {
-                if (id instanceof PJ) {
-                    return ((PJ) id).getCode();
-                }
-            }
-        } catch (UnsatisfiedLinkError e) {
-            // Thrown the first time that we try to use the library.
-            Logging.unexpectedException(Logging.getLogger(Modules.GDAL), Proj4.class, "definition", e);
-        } catch (NoClassDefFoundError e) {
-            // Thrown on all attempts after the first one.
-            Logging.recoverableException(Logging.getLogger(Modules.GDAL), Proj4.class, "definition", e);
-        }
-        /*
-         * If we found no Proj.4 structure, formats the definition string ourself. The string may differ from
-         * what Proj.4 would have given. In particular, we do not provide "+init=" or "+datum=" parameter.
-         * But the definition should still be semantically equivalent.
-         */
-        final String method;
-        final GeodeticDatum datum;
-        final ParameterValueGroup parameters;
-        final CoordinateSystem cs = crs.getCoordinateSystem();
-        if (crs instanceof GeodeticCRS) {
-            if (cs instanceof EllipsoidalCS) {
-                method = "latlon";
-            } else if (cs instanceof CartesianCS) {
-                method = "geocent";
-            } else {
-                throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getClass()));
-            }
-            datum      = ((GeodeticCRS) crs).getDatum();
-            parameters = null;
-        } else if (crs instanceof ProjectedCRS) {
-            Projection c = ((ProjectedCRS) crs).getConversionFromBase();
-            datum        = ((ProjectedCRS) crs).getDatum();
-            method       = name(c.getMethod());
-            parameters   = c.getParameterValues();
-        } else {
-            throw new FactoryException(Errors.format(Errors.Keys.UnsupportedType_1, crs.getClass()));
-        }
-        /*
-         * Append the map projection parameters. Those parameters may include axis lengths (a and b),
-         * but not necessarily. If axis lengths are specified, then we will ignore the Ellipsoid instance
-         * associated to the CRS.
-         */
-        final StringBuilder definition = new StringBuilder(100);
-        definition.append(Proj4Factory.PROJ_PARAM).append(method);
-        boolean hasSemiMajor = false;
-        boolean hasSemiMinor = false;
-        if (parameters != null) {
-            definition.append(Proj4Factory.STANDARD_OPTIONS);
-            for (final GeneralParameterValue parameter : parameters.values()) {
-                if (parameter instanceof ParameterValue<?>) {
-                    final ParameterValue<?> pv = (ParameterValue<?>) parameter;
-                    final Object value;
-                    Unit<?> unit = pv.getUnit();
-                    if (unit != null) {
-                        unit = Units.isAngular(unit) ? Units.DEGREE : unit.getSystemUnit();
-                        value = pv.doubleValue(unit);       // Always in metres or degrees.
-                    } else {
-                        value = pv.getValue();
-                        if (value == null) {
-                            continue;
-                        }
-                    }
-                    final String pn = name(parameter.getDescriptor());
-                    hasSemiMajor |= pn.equals("a");
-                    hasSemiMinor |= pn.equals("b");
-                    definition.append(" +").append(pn).append('=').append(value);
-                }
-            }
-        }
-        /*
-         * Append datum information: axis lengths if they were not part of the parameters, then prime meridian.
-         */
-        final Ellipsoid ellipsoid = datum.getEllipsoid();
-        if (!hasSemiMajor) definition.append(" +a=").append(ellipsoid.getSemiMajorAxis());
-        if (!hasSemiMinor) definition.append(" +b=").append(ellipsoid.getSemiMinorAxis());
-        final PrimeMeridian pm = datum.getPrimeMeridian();
-        if (pm != null) {
-            double lon = pm.getGreenwichLongitude();
-            final Unit<Angle> unit = pm.getAngularUnit();
-            if (unit != null) {
-                lon = unit.getConverterTo(Units.DEGREE).convert(lon);
-            }
-            definition.append(" +pm=").append(lon);
-        }
-        /*
-         * Appends axis directions. This method always format a vertical direction (up or down)
-         * even if the coordinate system is two-dimensional, because Proj.4 seems to require it.
-         * Also extract axis units in the process.
-         */
-        final Unit<?>[] units = new Unit<?>[2];     // Horizontal at index 0, vertical at index 1.
-        boolean validCS = true;
-        definition.append(' ').append(Proj4Factory.AXIS_ORDER_PARAM);
-        final int dimension = Math.min(cs.getDimension(), 3);
-        boolean hasVertical = false;
-        for (int i=0; i<dimension; i++) {
-            final CoordinateSystemAxis axis = cs.getAxis(i);
-            final AxisDirection dir = axis.getDirection();
-            int unitIndex = 0;
-            if (!AxisDirections.isCardinal(dir)) {
-                if (!AxisDirections.isVertical(dir)) {
-                    throw new FactoryException(Errors.format(Errors.Keys.UnsupportedAxisDirection_1, dir));
-                }
-                hasVertical = true;
-                unitIndex = 1;
-            }
-            final Unit<?> old  = units[unitIndex];
-            units[unitIndex]   = axis.getUnit();
-            validCS &= (old == null || old.equals(units[unitIndex]));
-            definition.appendCodePoint(Character.toLowerCase(dir.name().codePointAt(0)));
-        }
-        if (!hasVertical && dimension < 3) {
-            definition.append('u');                    // Add a UP direction if not already present.
-        }
-        /*
-         * Append units of measurement, then verify the coordinate system validity.
-         */
-        for (int i=0; i<units.length; i++) {
-            final Unit<?> unit = units[i];
-            if (unit != null && !unit.equals(Units.DEGREE) && !unit.equals(Units.METRE)) {
-                validCS &= Units.isLinear(unit);
-                definition.append(" +");
-                if (i == 1) definition.append('v');     // "+vto_meter" parameter.
-                definition.append("to_meter=").append(Units.toStandardUnit(unit));
-            }
-        }
-        /*
-         * Append the "+towgs84" element if any. This is the last piece of information.
-         * Note that the use of a "+towgs84" parameter is an "early binding" approach,
-         * which is usually not recommended. But Proj4 works that way.
-         */
-        if (validCS) {
-            if (datum instanceof DefaultGeodeticDatum) {
-                for (final BursaWolfParameters bwp : ((DefaultGeodeticDatum) datum).getBursaWolfParameters()) {
-                    if (Utilities.equalsIgnoreMetadata(CommonCRS.WGS84.datum(), bwp.getTargetDatum())) {
-                        definition.append(" +towgs84=").append(bwp.tX).append(',').append(bwp.tY).append(',').append(bwp.tZ);
-                        if (!bwp.isTranslation()) {
-                            definition.append(',').append(bwp.rX).append(',').append(bwp.rY).append(',').append(bwp.rZ).append(',').append(bwp.dS);
-                        }
-                        break;
-                    }
-                }
-            }
-            return definition.toString();
-        }
-        /*
-         * If we reach this point, we detected a coordinate system that we can not format as a
-         * Proj.4 definition string. Format an error message with axis directions and units.
-         */
-        definition.setLength(0);
-        definition.append('(');
-        for (int i=0; i<units.length; i++) {
-            final CoordinateSystemAxis axis = cs.getAxis(i);
-            if (i != 0) definition.append(", ");
-            definition.append(axis.getUnit()).append(' ').append(Types.getCodeName(axis.getDirection()));
-        }
-        throw new FactoryException(Errors.format(Errors.Keys.IllegalCoordinateSystem_1, definition.append(')')));
-    }
-
-    /**
-     * Returns the {@literal Proj.4} name for the given parameter,
-     * or throws an exception if the {@literal Proj.4} name is unknown.
-     */
-    private static String name(final IdentifiedObject object) throws FactoryException {
-        final String name = IdentifiedObjects.getName(object, Citations.PROJ4);
-        if (name == null) {
-            throw new FactoryException(Errors.format(Errors.Keys.CanNotSetParameterValue_1, object.getName()));
-        }
-        return name;
-    }
-
-    /**
-     * Creates a new CRS from the given {@literal Proj.4} definition string.
-     * Some examples of definition strings are:
-     * <ul>
-     *   <li>{@code "+init=epsg:3395 +over"} (see warning below)</li>
-     *   <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"}</li>
-     *   <li>{@code "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +ellps=WGS84 +towgs84=0,0,0"}</li>
-     * </ul>
-     *
-     * <b>Warning:</b> despite the {@code "epsg"} word, coordinate reference systems created by {@code "+init=epsg:"}
-     * syntax are not necessarily compliant with EPSG definitions. In particular, the axis order is often different.
-     * Units of measurement may also differ.
-     *
-     * @param  definition  the Proj.4 definition string.
-     * @param  dimension   the number of dimension of the CRS to create (2 or 3).
-     * @return a CRS created from the given definition string and number of dimensions.
-     * @throws NullPointerException if the definition string is {@code null}.
-     * @throws IllegalArgumentException if the definition string is empty or the dimension argument is out of range.
-     * @throws UnavailableFactoryException if the Proj.4 native library is not available.
-     * @throws FactoryException if the CRS creation failed for another reason.
-     *
-     * @see Proj4Factory#createCoordinateReferenceSystem(String)
-     */
-    public static CoordinateReferenceSystem createCRS(String definition, final int dimension) throws FactoryException {
-        ArgumentChecks.ensureNonEmpty("definition", definition);
-        ArgumentChecks.ensureBetween("dimension", 2, 3, dimension);
-        definition = definition.trim();
-        try {
-            return Proj4Factory.INSTANCE.createCRS(definition, dimension >= 3);
-        } catch (IllegalArgumentException | ParserException e) {
-            throw new InvalidGeodeticParameterException(canNotParse(definition), e);
-        } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
-            throw new UnavailableFactoryException(unavailable(e), e);
-        }
-    }
-
-    /**
-     * Creates an operation for conversion or transformation between two coordinate reference systems.
-     * The given CRSs should be instances created by this package. If not, then there is a choice:
-     *
-     * <ul>
-     *   <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
-     *   <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
-     *       regardless if the given CRS were created from Proj.4 definition strings or not.
-     *       This method fails if it can not map the given CRS to Proj.4 data structures.</li>
-     * </ul>
-     *
-     * <h4>Recommended alternative</h4>
-     * Provided that an <a href="http://sis.apache.org/epsg.html">EPSG database is available</a>,
-     * Apache SIS {@link CRS#findOperation CRS.findOperation(…)} method produces results that are closer
-     * to the authoritative definitions of coordinate operations (technically, Apache SIS referencing
-     * engine is a <cite>late-binding</cite> implementation while Proj.4 is an <cite>early-binding</cite>
-     * implementation — see EPSG guidance notes for a definition of late versus early-binding approaches).
-     * Apache SIS also attaches metadata about
-     * {@linkplain AbstractCoordinateOperation#getCoordinateOperationAccuracy() coordinate operation accuracy} and
-     * {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}, have extended support of
-     * multi-dimensional CRS and provides transform derivatives. This {@code Proj4.createOperation(…)} method should
-     * be reserved to situations where an application needs to reproduce the same numerical results than Proj.4.
-     *
-     * @param  sourceCRS  the source coordinate reference system.
-     * @param  targetCRS  the target coordinate reference system.
-     * @param  force      whether to force the creation of a Proj.4 transform
-     *                    even if the given CRS are not wrappers around Proj.4 data structures.
-     * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
-     *         {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
-     * @throws UnavailableFactoryException if {@code force} is {@code true} and the Proj.4 native library is not available.
-     * @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
-     *         for the given pair of coordinate reference systems for another reason.
-     *
-     * @see Proj4Factory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
-     * @see CRS#findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
-     */
-    public static CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
-                                                      final CoordinateReferenceSystem targetCRS,
-                                                      final boolean force)
-            throws FactoryException
-    {
-        ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
-        ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
-        try {
-            return Proj4Factory.INSTANCE.createOperation(sourceCRS, targetCRS, force);
-        } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
-            throw new UnavailableFactoryException(unavailable(e), e);
-        }
-    }
-
-    /**
-     * Returns the error message for a {@literal Proj.4} not found.
-     */
-    static String unavailable(final Throwable e) {
-        String message = e.getLocalizedMessage();
-        if (message == null || message.indexOf(' ') < 0) {      // Keep existing message if it is a sentence.
-            message = Errors.format(Errors.Keys.NativeInterfacesNotFound_2, OS.uname(), "libproj");
-        }
-        return message;
-    }
-
-    /**
-     * Returns the error message for a {@literal Proj.4} string that can not be parsed.
-     */
-    static String canNotParse(final String code) {
-        return Errors.format(Errors.Keys.CanNotParse_1, code);
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
deleted file mode 100644
index c916424..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Factory.java
+++ /dev/null
@@ -1,886 +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.storage.gdal;
-
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Collections;
-import javax.measure.Unit;
-import javax.measure.format.ParserException;
-import org.opengis.util.FactoryException;
-import org.opengis.util.NoSuchIdentifierException;
-import org.opengis.metadata.Identifier;
-import org.opengis.metadata.citation.Citation;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.cs.*;
-import org.opengis.referencing.crs.*;
-import org.opengis.referencing.datum.*;
-import org.opengis.referencing.operation.*;
-import org.opengis.referencing.IdentifiedObject;
-import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.referencing.ImmutableIdentifier;
-import org.apache.sis.referencing.operation.DefaultConversion;
-import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
-import org.apache.sis.referencing.factory.UnavailableFactoryException;
-import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
-import org.apache.sis.referencing.CommonCRS;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.metadata.iso.citation.DefaultCitation;
-import org.apache.sis.internal.referencing.LazySet;
-import org.apache.sis.internal.referencing.AxisDirections;
-import org.apache.sis.internal.referencing.ReferencingFactoryContainer;
-import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.system.Modules;
-import org.apache.sis.internal.util.CollectionsExt;
-import org.apache.sis.util.collection.WeakValueHashMap;
-import org.apache.sis.util.SimpleInternationalString;
-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.CharSequences;
-import org.apache.sis.util.Classes;
-import org.apache.sis.measure.Latitude;
-import org.apache.sis.measure.Units;
-
-
-/**
- * A factory for Coordinate Reference Systems created from {@literal Proj.4} definitions.
- * This authority factory recognizes codes in the {@code "Proj4"} name space.
- * The main methods in this class are:
- * <ul>
- *   <li>{@link #getAuthority()}</li>
- *   <li>{@link #createCoordinateReferenceSystem(String)}</li>
- *   <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)}</li>
- *   <li>{@link #createParameterizedTransform(ParameterValueGroup)}</li>
- * </ul>
- *
- * Other methods delegate to one of above-cited methods if possible, or throw a {@link FactoryException} otherwise.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
- * @since   0.8
- * @module
- */
-public class Proj4Factory extends GeodeticAuthorityFactory implements CRSAuthorityFactory {
-    /*
-     * NOTE: Proj4Factory could implement CoordinateOperationFactory or MathTransformFactory.
-     *       But we don't do that yet because we are not sure about exposing large amount of
-     *       methods that are not really supported by Proj.4 wrappers. However this approach
-     *       is experimented in the MTFactory class in the test directory. MTFactory methods
-     *       could be refactored here if experience shows us that it would be useful.
-     */
-
-    /**
-     * The {@literal Proj.4} parameter used for projection name.
-     */
-    static final String PROJ_PARAM = '+' + Proj4Parser.PROJ + '=';
-
-    /**
-     * Options to be added in any {@literal Proj.4} definition strings.
-     * <ul>
-     *   <li>The {@code "+over"} option is for disabling the default wrapping of output longitudes in the -180 to 180 range.
-     *     We do that for having the same behavior between Proj.4 and Apache SIS. No wrapping reduce discontinuity problems
-     *     with geometries that cross the anti-meridian.</li>
-     *   <li>The {@code "+no_defs"} option is for ensuring that no defaults are read from {@code "/usr/share/proj/proj_def.dat"} file.
-     *     That file contains default values for various map projections, for example {@code "+lat_1=29.5"} and {@code "+lat_2=45.5"}
-     *     for the {@code "aea"} projection. Those defaults are assuming that users want Conterminous U.S. map.
-     *     This may cause surprising behavior for users outside USA.</li>
-     * </ul>
-     */
-    static String STANDARD_OPTIONS = " +over +no_defs";
-
-    /**
-     * The {@literal Proj.4} parameter used for declaration of axis order.  Proj.4 expects the axis parameter
-     * to be exactly 3 characters long, but Apache SIS accepts 2 characters as well. We relax the Proj.4 rule
-     * because we use the number of characters for determining the number of dimensions.
-     * This is okay since 1 character = 1 axis.
-     */
-    static final String AXIS_ORDER_PARAM = "+axis=";
-
-    /**
-     * The name to use when no specific name were found for an object.
-     */
-    static final String UNNAMED = "Unnamed";
-
-    /**
-     * The default factory instance.
-     */
-    static final Proj4Factory INSTANCE = new Proj4Factory();
-
-    /**
-     * The {@literal Proj.4} authority completed by the version string. Created when first needed.
-     *
-     * @see #getAuthority()
-     */
-    private volatile Citation authority;
-
-    /**
-     * The default properties, or an empty map if none. This map shall not change after construction in
-     * order to allow usage without synchronization in multi-thread context. But we do not need to wrap
-     * in a unmodifiable map since {@code Proj4Factory} does not provide public access to it.
-     */
-    private final Map<String,?> defaultProperties;
-
-    /**
-     * The factory for coordinate reference system objects.
-     */
-    private final CRSFactory crsFactory;
-
-    /**
-     * The factory for coordinate system objects.
-     */
-    private final CSFactory csFactory;
-
-    /**
-     * The factory for datum objects.
-     */
-    private final DatumFactory datumFactory;
-
-    /**
-     * The {@code MathTransform} factory on which to delegate operations that are not supported by {@code Proj4Factory}.
-     */
-    private final MathTransformFactory mtFactory;
-
-    /**
-     * The factory for coordinate operation objects, created when first needed.
-     * Currently restricted to Apache SIS implementation because we use a method not yet available in GeoAPI and
-     * because we configure it for using the {@link MathTransformFactory} provided by this {@code Proj4Factory}.
-     *
-     * @see #opFactory()
-     */
-    private volatile DefaultCoordinateOperationFactory opFactory;
-
-    /**
-     * Poll of identifiers created by this factory.
-     */
-    private final Map<String,Identifier> identifiers = new HashMap<>();
-
-    /**
-     * Pool of {@literal Proj.4} objects created so far. The keys are the Proj.4 definition strings.
-     * The same {@link PJ} instance may appear more than once if various definition strings resulted
-     * in the same Proj.4 object.
-     */
-    private final WeakValueHashMap<String,PJ> pool = new WeakValueHashMap<>(String.class);
-
-    /**
-     * Creates a default factory.
-     */
-    public Proj4Factory() {
-        this(null);
-    }
-
-    /**
-     * Creates a new {@literal Proj.4} factory. The {@code properties} argument is an optional map
-     * for specifying common properties shared by the objects to create. Some available properties are
-     * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#AbstractIdentifiedObject(Map) listed there}.
-     * Unknown properties, or properties that do not apply, or properties for which {@code Proj4Factory} supplies
-     * itself a value, are ignored.
-     *
-     * @param properties  common properties for the objects to create, or {@code null} if none.
-     */
-    public Proj4Factory(Map<String,?> properties) {
-        properties   = new HashMap<>(properties != null ? properties : Collections.emptyMap());
-        crsFactory   = factory(CRSFactory.class,           properties, ReferencingFactoryContainer.CRS_FACTORY);
-        csFactory    = factory(CSFactory.class,            properties, ReferencingFactoryContainer.CS_FACTORY);
-        datumFactory = factory(DatumFactory.class,         properties, ReferencingFactoryContainer.DATUM_FACTORY);
-        mtFactory    = factory(MathTransformFactory.class, properties, ReferencingFactoryContainer.MT_FACTORY);
-        defaultProperties = CollectionsExt.compact(properties);
-    }
-
-    /**
-     * Returns the factory to use, using the instance specified in the properties map if it exists,
-     * or the system-wide default instance otherwise.
-     */
-    @SuppressWarnings("unchecked")
-    private static <T> T factory(final Class<T> type, final Map<String,?> properties, final String key) {
-        final Object value = properties.remove(key);
-        if (value == null) {
-            return DefaultFactories.forBuildin(type);
-        }
-        if (type.isInstance(value)) {
-            return (T) value;
-        }
-        throw new IllegalArgumentException(Errors.getResources(properties)
-                .getString(Errors.Keys.IllegalPropertyValueClass_2, key, Classes.getClass(value)));
-    }
-
-    /**
-     * Returns the factory for coordinate operation objects.
-     * The factory is backed by this {@code Proj4Factory} as the {@code MathTransformFactory} implementation.
-     */
-    final DefaultCoordinateOperationFactory opFactory() {
-        DefaultCoordinateOperationFactory factory = opFactory;
-        if (factory == null) {
-            final Map<String,Object> properties = new HashMap<>(defaultProperties);
-            properties.put(ReferencingFactoryContainer.CRS_FACTORY,   crsFactory);
-            properties.put(ReferencingFactoryContainer.CS_FACTORY,    csFactory);
-            properties.put(ReferencingFactoryContainer.DATUM_FACTORY, datumFactory);
-            factory = new DefaultCoordinateOperationFactory(properties, mtFactory);
-            opFactory = factory;
-        }
-        return factory;
-    }
-
-    /**
-     * Returns the project that defines the codes recognized by this factory.
-     * The authority determines the {@linkplain #getCodeSpaces() code space}.
-     *
-     * @return {@link Citations#PROJ4}.
-     */
-    @Override
-    public Citation getAuthority() {
-        Citation c = authority;
-        if (c == null) {
-            c = Citations.PROJ4;
-            final String release = Proj4.version();
-            if (release != null) {
-                final DefaultCitation df = new DefaultCitation(c);
-                df.setEdition(new SimpleInternationalString(release));
-                df.transitionTo(DefaultCitation.State.FINAL);
-                c = df;
-            }
-            authority = c;
-        }
-        return c;
-    }
-
-    /**
-     * Returns the code space of the authority. The code space is the prefix that may appear before codes.
-     * It allows to differentiate Proj.4 definitions from EPSG codes or other authorities. The code space is
-     * removed by {@link #createCoordinateReferenceSystem(String)} before the definition string is passed to Proj.4
-     *
-     * <div class="note"><b>Example</b>
-     * a complete identifier can be {@code "Proj4:+init=epsg:4326"}.
-     * Note that this is <strong>not</strong> equivalent to the standard {@code "EPSG:4326"} definition since the
-     * axis order is not the same. The {@code "Proj4:"} prefix specifies that the remaining part of the string is
-     * a Proj.4 definition; the presence of an {@code "epsg"} word in the definition does not change that fact.
-     * </div>
-     *
-     * @return {@code "Proj4"}.
-     */
-    @Override
-    public Set<String> getCodeSpaces() {
-        return Collections.singleton(Constants.PROJ4);
-    }
-
-    /**
-     * Returns the set of authority codes for objects of the given type.
-     * Current implementation can not return complete Proj.4 definition strings.
-     * Instead, this method currently returns only fragments (e.g. {@code "+proj=lcc"}).
-     *
-     * @param  type  the spatial reference objects type.
-     * @return fragments of definition strings for spatial reference objects of the given type.
-     * @throws FactoryException if access to the underlying database failed.
-     */
-    @Override
-    public Set<String> getAuthorityCodes(Class<? extends IdentifiedObject> type) throws FactoryException {
-        final Set<String> codes = new LinkedHashSet<>(10);
-        if (type.isAssignableFrom(GeographicCRS.class)) {
-            codes.add("latlon");
-        }
-        if (type.isAssignableFrom(GeocentricCRS.class)) {
-            codes.add("geocent");
-        }
-        if (type.isAssignableFrom(ProjectedCRS.class)) {
-            codes.addAll(Arrays.asList("lcc", "merc", "tmerc", "stere"));   // Only a subset of supported projections.
-        }
-        final String[] methods = codes.toArray(new String[codes.size()]);
-        codes.clear();
-        for (final String method : methods) {
-            codes.add(PROJ_PARAM.concat(method));
-        }
-        return codes;
-    }
-
-    /**
-     * Returns some map projection methods supported by {@literal Proj.4}.
-     * Current implementation can not return the complete list of Proj.4 method, but returns the main ones.
-     * For each operation method in the returned set, the Proj.4 projection name can be obtained as below:
-     *
-     * {@preformat java
-     *     String proj = IdentifiedObjects.getName(method, Citations.PROJ4);
-     * }
-     *
-     * The {@code proj} names obtained as above can be given in argument to the
-     * {@link #getOperationMethod(String)} and {@link #getDefaultParameters(String)} methods.
-     *
-     * @param  type <code>{@linkplain SingleOperation}.class</code> for fetching all operation methods, or
-     *              <code>{@linkplain Projection}.class</code> for fetching only map projection methods.
-     * @return methods available in this factory for coordinate operations of the given type.
-     *
-     * @see org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory#getAvailableMethods(Class)
-     */
-    public Set<OperationMethod> getAvailableMethods(final Class<? extends SingleOperation> type) {
-        return new LazySet<>(CollectionsExt.filter(mtFactory.getAvailableMethods(type).iterator(), Proj4Factory::isSupported));
-    }
-
-    /**
-     * Returns the operation method of the given name. The given argument can be a Proj.4 projection name,
-     * but other authorities (OGC, EPSG…) are also accepted. A partial list of supported projection names
-     * can be obtained by {@link #getAvailableMethods(Class)}. Some examples of Proj.4 projection names
-     * are given below (not all of them are supported by this Proj.4 wrapper).
-     *
-     * <table class="sis">
-     *   <caption>Some Proj.4 projection names</caption>
-     *   <tr><th>Name</th>            <th>Meaning</th></tr>
-     *   <tr><td>{@code aea}</td>     <td>Albers Equal-Area Conic</td></tr>
-     *   <tr><td>{@code aeqd}</td>    <td>Azimuthal Equidistant</td></tr>
-     *   <tr><td>{@code cass}</td>    <td>Cassini-Soldner</td></tr>
-     *   <tr><td>{@code cea}</td>     <td>Cylindrical Equal Area</td></tr>
-     *   <tr><td>{@code eck4}</td>    <td>Eckert IV</td></tr>
-     *   <tr><td>{@code eck6}</td>    <td>Eckert VI</td></tr>
-     *   <tr><td>{@code eqdc}</td>    <td>Equidistant Conic</td></tr>
-     *   <tr><td>{@code gall}</td>    <td>Gall Stereograpic</td></tr>
-     *   <tr><td>{@code geos}</td>    <td>Geostationary Satellite View</td></tr>
-     *   <tr><td>{@code gnom}</td>    <td>Gnomonic</td></tr>
-     *   <tr><td>{@code krovak}</td>  <td>Krovak Oblique Conic Conformal</td></tr>
-     *   <tr><td>{@code laea}</td>    <td>Lambert Azimuthal Equal Area</td></tr>
-     *   <tr><td>{@code lcc}</td>     <td>Lambert Conic Conformal</td></tr>
-     *   <tr><td>{@code merc}</td>    <td>Mercator</td></tr>
-     *   <tr><td>{@code mill}</td>    <td>Miller Cylindrical</td></tr>
-     *   <tr><td>{@code moll}</td>    <td>Mollweide</td></tr>
-     *   <tr><td>{@code nzmg}</td>    <td>New Zealand Map Grid</td></tr>
-     *   <tr><td>{@code omerc}</td>   <td>Oblique Mercator</td></tr>
-     *   <tr><td>{@code ortho}</td>   <td>Orthographic</td></tr>
-     *   <tr><td>{@code sterea}</td>  <td>Oblique Stereographic</td></tr>
-     *   <tr><td>{@code stere}</td>   <td>Stereographic</td></tr>
-     *   <tr><td>{@code robin}</td>   <td>Robinson</td></tr>
-     *   <tr><td>{@code sinu}</td>    <td>Sinusoidal</td></tr>
-     *   <tr><td>{@code tmerc}</td>   <td>Transverse Mercator</td></tr>
-     *   <tr><td>{@code vandg}</td>   <td>VanDerGrinten</td></tr>
-     * </table>
-     *
-     * The default implementation delegates to a {@code DefaultCoordinateOperationFactory} instance.
-     * It works because the Apache SIS operation methods declare the Proj.4 projection names as
-     * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getAlias() aliases}.
-     *
-     * @param  name  the name of the operation method to fetch.
-     * @return the operation method of the given name.
-     * @throws FactoryException if the requested operation method can not be fetched.
-     *
-     * @see org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#getOperationMethod(String)
-     */
-    public OperationMethod getOperationMethod(final String name) throws FactoryException {
-        final OperationMethod method = opFactory().getOperationMethod(name);
-        if (isSupported(method)) {
-            return method;
-        }
-        throw new NoSuchIdentifierException(Errors.getResources(defaultProperties)
-                .getString(Errors.Keys.UnsupportedOperation_1, name), name);
-    }
-
-    /**
-     * Returns the default parameter values for a math transform using the given operation method.
-     * The given argument can be a Proj.4 projection name, but other authorities (OGC, EPSG…) are also accepted.
-     * A partial list of supported projection names can be obtained by {@link #getAvailableMethods(Class)}.
-     * The returned parameters can be given to {@link #createParameterizedTransform(ParameterValueGroup)}.
-     *
-     * @param  method  the case insensitive name of the coordinate operation method to search for.
-     * @return a new group of parameter values for the {@code OperationMethod} identified by the given name.
-     * @throws NoSuchIdentifierException if there is no method registered for the given name or identifier.
-     */
-    public ParameterValueGroup getDefaultParameters(final String method) throws NoSuchIdentifierException {
-        final ParameterValueGroup parameters = mtFactory.getDefaultParameters(method);
-        if (isSupported(parameters.getDescriptor())) {
-            return parameters;
-        }
-        throw new NoSuchIdentifierException(Errors.getResources(defaultProperties)
-                .getString(Errors.Keys.UnsupportedOperation_1, method), method);
-    }
-
-    /**
-     * Creates a transform from a group of parameters. The {@link OperationMethod} name is inferred from
-     * the {@linkplain org.opengis.parameter.ParameterDescriptorGroup#getName() parameter group name}.
-     * Each parameter value is formatted as a Proj.4 parameter in a definition string.
-     *
-     * <div class="note"><b>Example:</b>
-     * {@preformat java
-     *     ParameterValueGroup p = factory.getDefaultParameters("Mercator");
-     *     p.parameter("semi_major").setValue(6378137.000);
-     *     p.parameter("semi_minor").setValue(6356752.314);
-     *     MathTransform mt = factory.createParameterizedTransform(p);
-     * }
-     *
-     * The corresponding Proj.4 definition string is:
-     *
-     * {@preformat text
-     *     +proj=merc +a=6378137.0 +b=6356752.314
-     * }
-     * </div>
-     *
-     * @param  parameters  the parameter values.
-     * @return the parameterized transform.
-     * @throws FactoryException if the object creation failed. This exception is thrown
-     *         if some required parameter has not been supplied, or has illegal value.
-     *
-     * @see #getDefaultParameters(String)
-     * @see #getAvailableMethods(Class)
-     */
-    public MathTransform createParameterizedTransform(final ParameterValueGroup parameters) throws FactoryException {
-        final String proj = name(parameters.getDescriptor(), Errors.Keys.UnsupportedOperation_1);
-        final StringBuilder buffer = new StringBuilder(100).append(PROJ_PARAM).append(proj).append(STANDARD_OPTIONS);
-        /*
-         * Proj.4 requires some parameters that are not defined in the EPSG geodetic dataset for some projections.
-         * Those parameters are unnecessary since their values are implied by the other parameters. However Proj.4
-         * does not seem to have any "intelligence" for such inference; we have to specify explicitly those values
-         * in the 'switch' statements below. The Objects listed below are parameters needed for those special cases.
-         */
-        Object latitudeOfOrigin  = null;
-        Object latitudeTrueScale = null;
-        Object standardParallel1 = null;
-        for (final GeneralParameterValue p : parameters.values()) {
-            /*
-             * Unconditionally ask the parameter name in order to throw an exception
-             * with better error message in case of unrecognized parameter.
-             */
-            final String name = name(p.getDescriptor(), Errors.Keys.UnexpectedParameter_1);
-            if (p instanceof ParameterValue) {
-                final Object value = ((ParameterValue) p).getValue();
-                if (value != null) {
-                    append(buffer, name, value);
-                    switch (name) {
-                        case "lat_0":  latitudeOfOrigin  = value; break;
-                        case "lat_1":  standardParallel1 = value; break;
-                        case "lat_ts": latitudeTrueScale = value; break;
-                    }
-                }
-            }
-        }
-        /*
-         * See above comment about parameter inference in Proj4. To verify if those special cases
-         * are still necessary, one can try to disable them and run TransformTest. If those tests
-         * work with a future Proj4 version, then the special cases below should be deleted.
-         */
-        switch (proj) {
-            /*
-             * In "Lambert Conic Conformal (1SP)" case, there is no standard parallel (lat_1) since a scale factor (k_0)
-             * is used instead. That scale is defined as the "Scale factor at natural origin", i.e. at lat_0. But Proj4
-             * does not seem to know that definition, so we have to explicitly tell it that lat_0 is the latitude of
-             * true scale.
-             */
-            case "lcc": {
-                if (standardParallel1 == null && latitudeOfOrigin != null) {
-                    append(buffer, "lat_1", latitudeOfOrigin);
-                }
-                break;
-            }
-            /*
-             * In "Polar Stereographic (variant B)", the latitude of natural origin is always a pole (90°N or S).
-             * Whether it is the North or South pole is determined by the sign of the latitude of true scale.
-             */
-            case "stere": {
-                if (latitudeOfOrigin == null && latitudeTrueScale instanceof Number) {
-                    append(buffer, "lat_0", ((Number) latitudeTrueScale).doubleValue() < 0 ? Latitude.MIN_VALUE : Latitude.MAX_VALUE);
-                }
-                break;
-            }
-        }
-        final String definition = buffer.toString();
-        try {
-            final PJ pj = unique(new PJ(definition));
-            final PJ base = unique(new PJ(pj));
-            return new Transform(base, false, pj, false);
-        } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
-            throw new UnavailableFactoryException(Proj4.unavailable(e), e);
-        }
-    }
-
-    /**
-     * Appends a Proj4 parameter in the given string buffer.
-     */
-    private static void append(final StringBuilder buffer, final String param, final Object value) {
-        buffer.append(" +").append(param).append('=').append(value);
-    }
-
-    /**
-     * Creates a new geodetic object from the given {@literal Proj.4} definition.
-     * The default implementation delegates to {@link #createCoordinateReferenceSystem(String)}.
-     *
-     * @param  code  the Proj.4 definition of the geodetic object to create.
-     * @return a geodetic created from the given definition.
-     * @throws FactoryException if the geodetic object can not be created for the given definition.
-     */
-    @Override
-    public IdentifiedObject createObject(String code) throws FactoryException {
-        return createCoordinateReferenceSystem(code);
-    }
-
-    /**
-     * Creates a new CRS from the given {@literal Proj.4} definition.
-     * The {@code "Proj4:"} prefix (ignoring case), if present, is ignored.
-     *
-     * <h4>Apache SIS extension</h4>
-     * Proj.4 unconditionally requires 3 letters for the {@code "+axis="} parameter — for example {@code "neu"} for
-     * <cite>North</cite>, <cite>East</cite> and <cite>Up</cite> respectively — regardless the number of dimensions
-     * in the CRS to create. Apache SIS makes the vertical direction optional:
-     *
-     * <ul>
-     *   <li>If the vertical direction is present (as in {@code "neu"}), a three-dimensional CRS is created.</li>
-     *   <li>If the vertical direction is absent (as in {@code "ne"}), a two-dimensional CRS is created.</li>
-     * </ul>
-     *
-     * <div class="note"><b>Examples:</b>
-     * <ul>
-     *   <li>{@code "+init=epsg:4326"} (<strong>not</strong> equivalent to the standard EPSG::4326 definition)</li>
-     *   <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"} (default to two-dimensional CRS)</li>
-     *   <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=ne"} (explicitly two-dimensional)</li>
-     *   <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=neu"} (three-dimensional)</li>
-     * </ul>
-     * </div>
-     *
-     * @param  code  the Proj.4 definition of the CRS object to create.
-     * @return a CRS created from the given definition.
-     * @throws FactoryException if the CRS object can not be created for the given definition.
-     *
-     * @see Proj4#createCRS(String, int)
-     */
-    @Override
-    public CoordinateReferenceSystem createCoordinateReferenceSystem(String code) throws FactoryException {
-        code = trimNamespace(code);
-        boolean hasHeight = false;
-        /*
-         * Count the number of axes declared in the "+axis" parameter.
-         * If there is only two axes, add a 'u' (up) direction even in the two-dimensional case.
-         * We make this addition because Proj.4 seems to require the 3-letters code in all case.
-         */
-        int offset = code.indexOf(AXIS_ORDER_PARAM);
-        if (offset >= 0) {
-            offset += AXIS_ORDER_PARAM.length();
-            final CharSequence orientation = CharSequences.token(code, offset);
-            for (int i=orientation.length(); --i >= 0;) {
-                final char c = orientation.charAt(i);
-                hasHeight = (c == 'u' || c == 'd');
-                if (hasHeight) break;
-            }
-            if (!hasHeight && orientation.length() < 3) {
-                offset = code.indexOf(orientation.toString(), offset);
-                if (offset >= 0) {                          // Should never be -1, but we are paranoiac.
-                    offset += orientation.length();
-                    code = new StringBuilder(code).insert(offset, 'u').toString();
-                }
-            }
-        }
-        try {
-            return createCRS(code, hasHeight);
-        } catch (IllegalArgumentException | ParserException e) {
-            throw new InvalidGeodeticParameterException(Proj4.canNotParse(code), e);
-        } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
-            throw new UnavailableFactoryException(Proj4.unavailable(e), e);
-        }
-    }
-
-    /**
-     * Returns the identifier for the given code in {@literal Proj.4} namespace.
-     */
-    private Map<String,Object> identifier(final String code) {
-        Identifier id = identifiers.computeIfAbsent(code, (k) -> {
-            short i18n = 0;
-            if (k.equalsIgnoreCase( UNNAMED )) i18n = Vocabulary.Keys.Unnamed;
-            if (k.equalsIgnoreCase("Unknown")) i18n = Vocabulary.Keys.Unknown;
-            return new ImmutableIdentifier(Citations.PROJ4, Constants.PROJ4, k, null,
-                    (i18n != 0) ? Vocabulary.formatInternational(i18n) : null);
-        });
-        final Map<String,Object> properties = new HashMap<>(defaultProperties);
-        properties.put(IdentifiedObject.NAME_KEY, id);
-        return properties;
-    }
-
-    /**
-     * Creates a geodetic datum from the given {@literal Proj.4} wrapper.
-     *
-     * @param  pj      the Proj.4 object to wrap.
-     * @param  parser  the parameter values of the Proj.4 object to wrap.
-     * @throws NumberFormatException if a Proj.4 parameter value can not be parsed.
-     */
-    private GeodeticDatum createDatum(final PJ pj, final Proj4Parser parser) throws FactoryException {
-        final PrimeMeridian pm;
-        final double greenwichLongitude = Double.parseDouble(parser.value("pm", "0"));
-        if (greenwichLongitude == 0) {
-            pm = CommonCRS.WGS84.datum().getPrimeMeridian();
-        } else {
-            pm = datumFactory.createPrimeMeridian(identifier(UNNAMED), greenwichLongitude, Units.DEGREE);
-        }
-        final double[] def = pj.getEllipsoidDefinition();
-        return datumFactory.createGeodeticDatum(identifier(parser.value("datum", UNNAMED)),
-               datumFactory.createEllipsoid    (identifier(parser.value("ellps", UNNAMED)),
-                    def[0],                             // Semi-major axis length
-                    def[0] * Math.sqrt(1 - def[1]),     // Semi-minor axis length
-                    Units.METRE), pm);
-    }
-
-    /**
-     * Creates a coordinate reference system from the given {@literal Proj.4} wrapper.
-     * The given {@code pj} will be stored as the CRS identifier.
-     *
-     * @param  pj          the Proj.4 object to wrap.
-     * @param  withHeight  whether to include a height axis.
-     * @throws IllegalArgumentException if a Proj.4 parameter value can not be parsed or assigned.
-     * @throws ParserException if a unit symbol can not be parsed.
-     */
-    private CoordinateReferenceSystem createCRS(final PJ pj, final boolean withHeight) throws FactoryException {
-        final PJ.Type type = pj.getType();
-        final boolean geographic = PJ.Type.GEOGRAPHIC.equals(type);
-        final boolean geocentric = PJ.Type.GEOCENTRIC.equals(type);
-        final Proj4Parser parser = new Proj4Parser(pj.getCode());
-        final String dir = parser.value("axis", "enu");
-        final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[geocentric | withHeight ? dir.length() : 2];
-        for (int i=0; i<axes.length; i++) {
-            final char d = Character.toLowerCase(dir.charAt(i));
-            char abbreviation = Character.toUpperCase(d);
-            boolean vertical = false;
-            final AxisDirection c;
-            final String name;
-            if (geocentric) switch (d) {
-                case 'e': c = AxisDirection.GEOCENTRIC_X;  name = "Geocentric X";  break;
-                case 'n': c = AxisDirection.GEOCENTRIC_Y;  name = "Geocentric Y";  break;
-                case 'u': c = AxisDirection.GEOCENTRIC_Z;  name = "Geocentric Z";  break;
-                default:  c = AxisDirection.OTHER;         name = "Unknown";       break;
-            } else switch (d) {
-                case 'e': c = AxisDirection.EAST;  name = geographic ? "Geodetic longitude" : "Easting";  break;
-                case 'w': c = AxisDirection.WEST;  name = geographic ? "Geodetic longitude" : "Westing";  break;
-                case 'n': c = AxisDirection.NORTH; name = geographic ? "Geodetic latitude"  : "Northing"; break;
-                case 's': c = AxisDirection.SOUTH; name = geographic ? "Geodetic latitude"  : "Southing"; break;
-                case 'u': c = AxisDirection.UP;    name = "Height";  vertical = true; abbreviation = 'h'; break;
-                case 'd': c = AxisDirection.DOWN;  name = "Depth";   vertical = true; break;
-                default:  c = AxisDirection.OTHER; name = "Unknown"; break;
-            }
-            if (geographic && AxisDirections.isCardinal(c)) {
-                abbreviation = (d == 'e' || d == 'w') ? 'λ' : 'φ';
-            }
-            final Unit<?> unit = (vertical || !geographic) ? parser.unit(vertical) : Units.DEGREE;
-            axes[i] = csFactory.createCoordinateSystemAxis(identifier(name), String.valueOf(abbreviation).intern(), c, unit);
-        }
-        /*
-         * At this point we got the coordinate system axes. Now create the CRS. The given Proj.4 object
-         * will be stored as the CRS identifier for allowing OperationFactory to get it back before to
-         * attempt to create a new one for a given CRS.
-         */
-        final Map<String,Object> csName = identifier(UNNAMED);
-        final Map<String,Object> name = new HashMap<>(identifier(parser.name(type == PJ.Type.PROJECTED)));
-        name.put(CoordinateReferenceSystem.IDENTIFIERS_KEY, pj);
-        switch (type) {
-            case GEOGRAPHIC: {
-                return crsFactory.createGeographicCRS(name, createDatum(pj, parser), withHeight ?
-                        csFactory.createEllipsoidalCS(csName, axes[0], axes[1], axes[2]) :
-                        csFactory.createEllipsoidalCS(csName, axes[0], axes[1]));
-            }
-            case GEOCENTRIC: {
-                return crsFactory.createGeocentricCRS(name, createDatum(pj, parser),
-                        csFactory.createCartesianCS(csName, axes[0], axes[1], axes[2]));
-            }
-            case PROJECTED: {
-                final PJ base = unique(new PJ(pj));
-                final CoordinateReferenceSystem baseCRS = createCRS(base, withHeight);
-                final Transform tr = new Transform(pj, withHeight, base, withHeight);
-                /*
-                 * Try to convert the Proj.4 parameters into OGC parameters in order to have a less opaque structure.
-                 * Failure to perform this conversion will not cause a failure to create the ProjectedCRS. After all,
-                 * maybe the user invokes this method for using a map projection not yet supported by Apache SIS.
-                 * Instead, fallback on the more opaque Transform.METHOD description. Apache SIS will not be able to
-                 * perform analysis on those parameters, but it will not prevent the Proj.4 transformation to work.
-                 */
-                OperationMethod method;
-                ParameterValueGroup parameters;
-                try {
-                    method = parser.method(opFactory());
-                    parameters = parser.parameters();
-                } catch (IllegalArgumentException | FactoryException e) {
-                    Logging.recoverableException(Logging.getLogger(Modules.GDAL), Proj4Factory.class, "createProjectedCRS", e);
-                    method = Transform.METHOD;
-                    parameters = null;              // Will let Apache SIS infers the parameters from the Transform instance.
-                }
-                final Conversion fromBase = new DefaultConversion(name, method, tr, parameters);
-                return crsFactory.createProjectedCRS(name, (GeographicCRS) baseCRS, fromBase, withHeight ?
-                        csFactory.createCartesianCS(csName, axes[0], axes[1], axes[2]) :
-                        csFactory.createCartesianCS(csName, axes[0], axes[1]));
-            }
-            default: {
-                throw new FactoryException(Errors.getResources(defaultProperties)
-                        .getString(Errors.Keys.UnknownEnumValue_2, type, PJ.Type.class));
-            }
-        }
-    }
-
-    /**
-     * Gets the {@literal Proj.4} object from the given coordinate reference system. If an existing {@code PJ}
-     * instance is found, returns it. Otherwise if {@code force} is {@code true}, creates a new {@code PJ}
-     * instance from a Proj.4 definition inferred from the given CRS.
-     * This method is the converse of {@link #createCRS(PJ, boolean)}.
-     */
-    private PJ unwrapOrCreate(final CoordinateReferenceSystem crs, final boolean force) throws FactoryException {
-        for (final Identifier id : crs.getIdentifiers()) {
-            if (id instanceof PJ) {
-                return (PJ) id;
-            }
-        }
-        return force ? unique(new PJ(Proj4.definition(crs))) : null;
-    }
-
-    /**
-     * Returns a unique instance of the given {@literal Proj.4} object.
-     */
-    @SuppressWarnings("FinalizeCalledExplicitly")
-    private PJ unique(PJ pj) {
-        final PJ existing = pool.putIfAbsent(pj.getCode(), pj);
-        if (existing != null) {
-            pj.finalize();          // Release Proj.4 resources.
-            return existing;
-        }
-        return pj;
-    }
-
-    /**
-     * Creates a coordinate reference system from the given {@literal Proj.4} definition string.
-     * The {@code Proj4} suffix shall have been removed before to invoke this method.
-     *
-     * @param  definition  the Proj.4 definition.
-     * @param  withHeight  whether to include a height axis.
-     *
-     * @see Proj4#createCRS(String, int)
-     * @see #createCoordinateReferenceSystem(String)
-     */
-    final CoordinateReferenceSystem createCRS(final String definition, final boolean withHeight) throws FactoryException {
-        PJ pj = pool.get(definition);
-        if (pj == null) {
-            pj = unique(new PJ(definition));
-            pool.putIfAbsent(definition, pj);
-        }
-        return createCRS(pj, withHeight);
-    }
-
-    /**
-     * Creates an operation for conversion or transformation between two coordinate reference systems.
-     * The given CRSs should be instances {@linkplain #createCoordinateReferenceSystem created by this factory}.
-     * If not, then there is a choice:
-     *
-     * <ul>
-     *   <li>If {@code force} is {@code false}, then this method returns {@code null}.</li>
-     *   <li>Otherwise this method always uses Proj.4 for performing the coordinate operations,
-     *       regardless if the given CRS were created from Proj.4 definition strings or not.
-     *       This method fails if it can not map the given CRS to Proj.4 data structures.</li>
-     * </ul>
-     *
-     * @param  sourceCRS  the source coordinate reference system.
-     * @param  targetCRS  the target coordinate reference system.
-     * @param  force      whether to force the creation of a Proj.4 transform
-     *                    even if the given CRS are not wrappers around Proj.4 data structures.
-     * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS, or
-     *         {@code null} if the given CRS are not wrappers around Proj.4 data structures and {@code force} is false.
-     * @throws FactoryException if {@code force} is {@code true} and this method can not create Proj.4 transform
-     *         for the given pair of coordinate reference systems.
-     *
-     * @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
-     * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
-     */
-    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
-                                               final CoordinateReferenceSystem targetCRS,
-                                               final boolean force)
-            throws FactoryException
-    {
-        final PJ source, target;
-        try {
-            if ((source = unwrapOrCreate(sourceCRS, force)) == null ||
-                (target = unwrapOrCreate(targetCRS, force)) == null)
-            {
-                return null;            // At least one CRS is not a Proj.4 wrapper and 'force' is false.
-            }
-        } catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
-            throw new UnavailableFactoryException(Proj4.unavailable(e), e);
-        }
-        /*
-         * Before to create a transform, verify if the target CRS already contains a suitable transform.
-         * In such case, returning the existing operation is preferable since it usually contains better
-         * parameter description than what this method build.
-         */
-        if (targetCRS instanceof GeneralDerivedCRS) {
-            final CoordinateOperation op = ((GeneralDerivedCRS) targetCRS).getConversionFromBase();
-            final MathTransform tr = op.getMathTransform();
-            if (tr instanceof Transform && ((Transform) tr).isFor(sourceCRS, source, targetCRS, target)) {
-                return op;
-            }
-        }
-        /*
-         * The 'Transform' construction implies parameter validation, so we do it first before to
-         * construct other objects.
-         */
-        final Transform tr = new Transform(source, is3D("sourceCRS", sourceCRS),
-                                           target, is3D("targetCRS", targetCRS));
-        Identifier id;
-        String src = null, tgt = null, name = UNNAMED;
-        if ((id = sourceCRS.getName()) != null) src = id.getCode();
-        if ((id = targetCRS.getName()) != null) tgt = id.getCode();
-        if (src != null || tgt != null) {
-            final StringBuilder buffer = new StringBuilder();
-            if (src != null) buffer.append("From ").append(src);
-            if (tgt != null) buffer.append(buffer.length() == 0 ? "To " : " to ").append(tgt);
-            name = buffer.toString();
-        }
-        return opFactory().createSingleOperation(identifier(name), sourceCRS, targetCRS, null, Transform.METHOD, tr);
-    }
-
-    /**
-     * Returns whether the given CRS is three-dimensional.
-     * Thrown an exception if the number of dimension is unsupported.
-     */
-    private boolean is3D(final String arg, final CoordinateReferenceSystem crs) throws FactoryException {
-        final int dim = crs.getCoordinateSystem().getDimension();
-        final boolean is3D = (dim >= 3);
-        if (dim < 2 || dim > 3) {
-            throw new FactoryException(Errors.getResources(defaultProperties)
-                    .getString(Errors.Keys.MismatchedDimension_3, arg, is3D ? 3 : 2, dim));
-        }
-        return is3D;
-    }
-
-    /**
-     * Returns {@code true} if the given coordinate operation method or parameter group is supported.
-     */
-    private static boolean isSupported(final IdentifiedObject method) {
-        return IdentifiedObjects.getName(method, Citations.PROJ4) != null;
-    }
-
-    /**
-     * Returns the {@literal Proj.4} name of the given parameter value or parameter group.
-     *
-     * @param  param    the parameter value or parameter group for which to get the Proj.4 name.
-     * @param  errorKey the resource key of the error message to produce if no Proj.4 name has been found.
-     *                  The message shall expect exactly one argument. This error key can be
-     *                  {@link Errors.Keys#UnsupportedOperation_1} or {@link Errors.Keys#UnexpectedParameter_1}.
-     * @return the Proj.4 name of the given object (never null).
-     * @throws FactoryException if the Proj.4 name has not been found.
-     */
-    private String name(final IdentifiedObject param, final short errorKey) throws FactoryException {
-        String name = IdentifiedObjects.getName(param, Citations.PROJ4);
-        if (name == null) {
-            name = param.getName().getCode();
-            final String message = Errors.getResources(defaultProperties).getString(errorKey, name);
-            if (errorKey == Errors.Keys.UnsupportedOperation_1) {
-                throw new NoSuchIdentifierException(message, name);
-            } else {
-                throw new InvalidGeodeticParameterException(message);
-            }
-        }
-        return name;
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
deleted file mode 100644
index 785587e..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
+++ /dev/null
@@ -1,185 +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.storage.gdal;
-
-import java.util.Set;
-import java.util.Map;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Locale;
-import javax.measure.Unit;
-import javax.measure.format.ParserException;
-import org.apache.sis.measure.Units;
-import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.operation.OperationMethod;
-import org.apache.sis.util.CharSequences;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
-import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
-
-
-/**
- * Creates a parameter value group from a {@literal Proj.4} definition string.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-final class Proj4Parser {
-    /**
-     * {@literal Proj.4} parameters to ignore when building the parameter value group of a map projection.
-     * We ignore those parameters because they define for example the datum, prime meridian, <i>etc</i>.
-     * Those information will be fetched by other classes than this {@code Proj4Parser}.
-     */
-    private static final Set<String> EXCLUDES = new HashSet<>(16);
-    static {
-        EXCLUDES.add("init");           // Authority code
-        EXCLUDES.add("datum");          // Geodetic datum name
-        EXCLUDES.add("ellps");          // Ellipsoid name
-        EXCLUDES.add("pm");             // Prime meridian
-        EXCLUDES.add("units");          // Axis units
-        EXCLUDES.add("vunits");         // Vertical axis units
-        EXCLUDES.add("to_meter");       // Axis units conversion factor
-        EXCLUDES.add("vto_meter");      // Vertical axis units conversion factor
-        EXCLUDES.add("towgs84");        // Datum shift
-        EXCLUDES.add("axis");           // Axis order
-    }
-
-    /**
-     * The {@value} keyword used for projection name in {@literal Proj.4} definition strings.
-     */
-    static final String PROJ = "proj";
-
-    /**
-     * The values extracted from the {@literal Proj.4} definition strings.
-     * Keys are Proj.4 keywords like {@code "a"} or {@code "ts"}.
-     */
-    private final Map<String,String> parameters = new LinkedHashMap<>();
-
-    /**
-     * The map projection method inferred from the {@code "+proj="}, or {@code null} if not yet fetched.
-     */
-    private OperationMethod method;
-
-    /**
-     * Creates a parser for the given {@literal Proj.4} definition string.
-     */
-    Proj4Parser(final String definition) throws InvalidGeodeticParameterException {
-        final int length = definition.length();
-        int start = definition.indexOf('+');
-        while (start >= 0) {
-            final int end  = definition.indexOf('=', ++start);
-            final int next = definition.indexOf('+',   start);
-            if (end >= 0 && (next < 0 || end < next)) {
-                final String keyword = CharSequences.trimWhitespaces(definition, start, end).toString().toLowerCase(Locale.US);
-                final String value   = CharSequences.trimWhitespaces(definition, end+1, (next >= 0) ? next : length).toString();
-                if (!value.isEmpty()) {
-                    final String old = parameters.put(keyword, value);
-                    if (old != null && !old.equals(value)) {
-                        throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.KeyCollision_1, keyword));
-                    }
-                }
-            }
-            start = next;
-        }
-    }
-
-    /**
-     * Returns a suggested name for the coordinate reference system object to build.
-     */
-    final String name(final boolean isProjected) {
-        String name = parameters.get("datum");
-        if (name == null) {
-            name = parameters.get("ellps");
-            if (name == null) {
-                name = Proj4Factory.UNNAMED;
-            }
-        }
-        if (isProjected) {
-            final String proj = parameters.get(PROJ);
-            if (proj != null) {
-                name = name + ' ' + Proj4Factory.PROJ_PARAM + proj;
-            }
-        }
-        return name;
-    }
-
-    /**
-     * Returns the parameter value for the given keyword, or the given default value if none.
-     * The parameter value is removed from the map.
-     */
-    final String value(final String keyword, final String defaultValue) {
-        final String value = parameters.remove(keyword);
-        return (value != null) ? value : defaultValue;
-    }
-
-    /**
-     * Returns the operation method inferred from the {@code "proj"} parameter value.
-     * This method must be invoked at least once before {@link #parameters()}.
-     */
-    final OperationMethod method(final DefaultCoordinateOperationFactory opFactory) throws FactoryException {
-        if (method == null) {
-            final String name = parameters.remove(PROJ);
-            if (name == null) {
-                throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.ElementNotFound_1, PROJ));
-            }
-            method = opFactory.getOperationMethod(name);
-        }
-        return method;
-    }
-
-    /**
-     * Returns the parameter value group filled from the {@literal Proj.4} parameters.
-     *
-     * @throws IllegalArgumentException if a Proj.4 parameter can not be converted to the expected type.
-     */
-    final ParameterValueGroup parameters() throws IllegalArgumentException {
-        final ParameterValueGroup pg = method.getParameters().createValue();
-        for (final Map.Entry<String,String> entry : parameters.entrySet()) {
-            final String keyword = entry.getKey();
-            if (!EXCLUDES.contains(keyword)) {
-                final ParameterValue<?> value = pg.parameter(keyword);
-                value.setValue(Double.parseDouble(entry.getValue()));
-            }
-        }
-        return pg;
-    }
-
-    /**
-     * Returns the vertical or horizontal axis unit.
-     * This unit applies only to linear axes, not angular axes neither parameters.
-     *
-     * @param  vertical  {@code true} for querying the vertical unit, or {@code false} for the horizontal one.
-     * @return the vertical or horizontal axis unit of measurement, or {@code Units.METRE} if unspecified.
-     * @throws NumberFormatException if the unit conversion factor can not be parsed.
-     * @throws ParserException if the unit symbol can not be parsed.
-     */
-    final Unit<?> unit(final boolean vertical) throws ParserException {
-        String v = parameters.remove(vertical ? "vto_meter" : "to_meter");
-        if (v != null) {
-            return Units.METRE.divide(Double.parseDouble(v));
-        }
-        v = parameters.remove(vertical ? "vunits" : "units");
-        if (v != null) {
-            return Units.valueOf(v);
-        }
-        return Units.METRE;
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java
deleted file mode 100644
index 14fe2ae..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Transform.java
+++ /dev/null
@@ -1,247 +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.storage.gdal;
-
-import java.io.Serializable;
-import java.util.Collections;
-import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.referencing.operation.OperationMethod;
-import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.referencing.operation.DefaultOperationMethod;
-import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
-import org.apache.sis.util.ComparisonMode;
-
-
-/**
- * A math transform which delegate its work to the {@literal Proj.4} native library.
- * The WKT for this math transform looks like the following fragment:
- *
- * {@preformat wkt
- *   PARAM_MT["pj_transform",
- *     PARAMETER["srcdefn", "+proj=…"],
- *     PARAMETER["dstdefn", "+proj=…"]]
- * }
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-final class Transform extends AbstractMathTransform implements Serializable {
-    /**
-     * For cross-version compatibility.
-     */
-    private static final long serialVersionUID = -8593638007439108805L;
-
-    /**
-     * The operation method for a transformation between two {@link PJ} instances.
-     * The parameter names are taken from
-     * <a href="http://proj4.org/development/api.html#pj-transform">Proj.4 API</a>.
-     */
-    static final OperationMethod METHOD;
-    static {
-        final ParameterBuilder builder = new ParameterBuilder().setCodeSpace(Citations.PROJ4, Constants.PROJ4);
-        final ParameterDescriptor<?>[] p = {
-            builder.addName("srcdefn").setDescription("Source (input) coordinate system.").create(String.class, null),
-            builder.addName("dstdefn").setDescription("Destination (output) coordinate system.").create(String.class, null)
-        };
-        final ParameterDescriptorGroup params = builder.addName("pj_transform").createGroup(1, 1, p);
-        METHOD = new DefaultOperationMethod(Collections.singletonMap(OperationMethod.NAME_KEY, params.getName()), null, null, params);
-    }
-
-    /**
-     * The source and target CRS.
-     */
-    private final PJ source, target;
-
-    /**
-     * Whether the source and destination are 2 or 3 dimensional.
-     */
-    private final boolean source3D, target3D;
-
-    /**
-     * The inverse transform, created only when first needed.
-     */
-    private transient Transform inverse;
-
-    /**
-     * Creates a new operation for the given source and target CRS.
-     */
-    Transform(final PJ source, final boolean source3D, final PJ target, final boolean target3D) {
-        this.source   = source;
-        this.target   = target;
-        this.source3D = source3D;
-        this.target3D = target3D;
-    }
-
-    /**
-     * Returns the parameter descriptors for this math transform.
-     */
-    @Override
-    public ParameterDescriptorGroup getParameterDescriptors() {
-        return METHOD.getParameters();
-    }
-
-    /**
-     * Returns a copy of the parameter values for this parameterized object.
-     */
-    @Override
-    public ParameterValueGroup getParameterValues() {
-        final ParameterValueGroup pg = getParameterDescriptors().createValue();
-        pg.parameter("srcdefn").setValue(source.getCode().trim());
-        pg.parameter("dstdefn").setValue(target.getCode().trim());
-        return pg;
-    }
-
-    /**
-     * Returns the number of source dimensions.
-     */
-    @Override
-    public final int getSourceDimensions() {
-        return source3D ? 3 : 2;
-    }
-
-    /**
-     * Returns the number of target dimensions.
-     */
-    @Override
-    public final int getTargetDimensions() {
-        return target3D ? 3 : 2;
-    }
-
-    /**
-     * Returns {@code true} if this transform is the identity transform. Note that a value of
-     * {@code false} does not mean that the transform is not an identity transform, since this
-     * case is a bit difficult to determine from Proj.4 API.
-     */
-    @Override
-    public boolean isIdentity() {
-        return source3D == target3D && source.equals(target);
-    }
-
-    /**
-     * Transforms a single point. This method is inefficient; callers should prefer the methods
-     * transforming multiple points at once.
-     */
-    @Override
-    public Matrix transform(double[] srcPts, int srcOff,
-                            double[] dstPts, int dstOff,
-                            boolean derivate) throws TransformException
-    {
-        transform(srcPts, srcOff, dstPts, dstOff, 1);
-        return null;
-    }
-
-    /**
-     * Transforms an array of coordinate tuples.
-     */
-    @Override
-    public void transform(double[] srcPts, int srcOff,
-                          double[] dstPts, int dstOff,
-                          int numPts) throws TransformException
-    {
-        if (source3D != target3D) {
-            super.transform(srcPts, srcOff, dstPts, dstOff, numPts);
-        } else {
-            final int dim = getTargetDimensions();
-            if (srcPts != dstPts || srcOff != dstOff) {
-                final int length = dim * numPts;
-                System.arraycopy(srcPts, srcOff, dstPts, dstOff, length);
-            }
-            source.transform(target, dim, dstPts, dstOff, numPts);
-        }
-    }
-
-    /**
-     * Returns the inverse transform.
-     */
-    @Override
-    public synchronized MathTransform inverse() {
-        if (inverse == null) {
-            inverse = new Transform(target, target3D, source, source3D);
-            inverse.inverse = this;
-        }
-        return inverse;
-    }
-
-    /**
-     * If both transforms are {@literal Proj.4} wrappers, returns a single transform without intermediate step.
-     */
-    @Override
-    protected MathTransform tryConcatenate(final boolean applyOtherFirst, final MathTransform other,
-            final MathTransformFactory factory) throws FactoryException
-    {
-        if (other instanceof Transform) {
-            final Transform tr = (Transform) other;
-            if (applyOtherFirst) {
-                return new Transform(tr.source, tr.source3D, target, target3D);
-            } else {
-                return new Transform(source, source3D, tr.target, tr.target3D);
-            }
-        }
-        return super.tryConcatenate(applyOtherFirst, other, factory);
-    }
-
-    /**
-     * Returns {@code true} if this math transform is for the given pair of source and target CRS.
-     */
-    final boolean isFor(final CoordinateReferenceSystem sourceCRS, final PJ sourcePJ,
-                        final CoordinateReferenceSystem targetCRS, final PJ targetPJ)
-    {
-        return source.equals(sourcePJ) && dimensionMatches(sourceCRS, source3D) &&
-               target.equals(targetPJ) && dimensionMatches(targetCRS, target3D);
-    }
-
-    /**
-     * Tests whether the given CRS matches the expected number of dimensions.
-     */
-    private static boolean dimensionMatches(final CoordinateReferenceSystem crs, final boolean is3D) {
-        return crs.getCoordinateSystem().getDimension() == (is3D ? 3 : 2);
-    }
-
-    /**
-     * Computes a hash value for this transform. This method is invoked by {@link #hashCode()} when first needed.
-     */
-    @Override
-    protected int computeHashCode() {
-        return super.computeHashCode() + source.hashCode() + 31*target.hashCode();
-    }
-
-    /**
-     * Compares the given object with this transform for equality.
-     * This implementation can not ignore metadata or rounding errors.
-     */
-    @Override
-    public boolean equals(final Object object, final ComparisonMode mode) {
-        if (object instanceof Transform) {
-            final Transform that = (Transform) object;
-            return source.equals(that.source) && source3D == that.source3D
-                && target.equals(that.target) && target3D == that.target3D;
-        }
-        return false;
-    }
-}
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.java
deleted file mode 100644
index 2f3a633..0000000
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/package-info.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.
- */
-
-/**
- * Extensions to referencing services as wrapper around the C/C++ {@literal Proj.4} library.
- * Current version wraps only referencing services, but future versions are expected to wrap more GDAL functionalities.
- * Unless otherwise specified, this optional module requires the native (C/C++) <a href="http://proj.osgeo.org/">Proj.4</a>
- * library to be installed on the local machine. This package allows to:
- * <ul>
- *   <li>{@linkplain org.apache.sis.storage.gdal.Proj4#createCRS Create a Coordinate Reference System instance from a Proj.4 definition string}.</li>
- *   <li>Conversely, {@linkplain org.apache.sis.storage.gdal.Proj4#definition get a Proj.4 definition string from a Coordinate Reference System}.</li>
- *   <li>{@linkplain org.apache.sis.storage.gdal.Proj4#createOperation Create a coordinate operation backed by Proj.4 between two arbitrary CRS}.</li>
- * </ul>
- *
- * Note that Apache SIS provides its own map projection engine in pure Java, so this module is usually not needed.
- * This module is useful when a map projection is not yet available in Apache SIS, or when an application needs to
- * reproduce the exact same numerical results than Proj.4. But some Apache SIS features like
- * {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#derivative transform derivatives}
- * are not available through the Proj.4 wrappers.
- *
- * <p>When this optional module is available, the {@link org.apache.sis.referencing.CRS#forCode CRS.forCode(String)}
- * method accepts Proj.4 definition strings prefixed by {@code "Proj4::"}. Example:</p>
- *
- * {@preformat java
- *     CoordinateReferenceSystem crs = CRS.forCode("Proj4::+init=epsg:3395");
- * }
- *
- * Calls to {@link org.apache.sis.referencing.CRS#findOperation CRS.findOperation(…)} will delegate the coordinate
- * transformation to Proj.4 if {@code sourceCRS} and {@code targetCRS} were both obtained from a code in {@code "Proj4"}
- * namespace or by a method in this package. Otherwise, Apache SIS will use its own referencing engine.
- * The backing referencing engine can be seen by printing the {@code MathTransform}:
- * a transform backed by Proj.4 have a <cite>Well Known Text 1</cite> representation like below:
- *
- * {@preformat wkt
- *   PARAM_MT["pj_transform",
- *     PARAMETER["srcdefn", "+proj=…"],
- *     PARAMETER["dstdefn", "+proj=…"]]
- * }
- *
- * <h2>Note on Proj.4 definition strings</h2>
- * Proj.4 unconditionally requires 3 letters for the {@code "+axis="} parameter — for example {@code "neu"} for
- * <cite>North</cite>, <cite>East</cite> and <cite>Up</cite> respectively — regardless the number of dimensions
- * in the CRS to create. Apache SIS makes the vertical direction optional in order to specify whether the CRS to
- * create shall contain a vertical axis or not:
- *
- * <ul>
- *   <li>If the vertical direction is present (as in {@code "neu"}), a three-dimensional CRS is created.</li>
- *   <li>If the vertical direction is absent (as in {@code "ne"}), a two-dimensional CRS is created.</li>
- * </ul>
- *
- * <div class="note"><b>Examples:</b>
- * <ul>
- *   <li>{@code "+init=epsg:4326"} (<strong>not</strong> equivalent to the standard EPSG::4326 definition)</li>
- *   <li>{@code "+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"} (default to two-dimensional CRS)</li>
- *   <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=ne"} (explicitly two-dimensional)</li>
- *   <li>{@code "+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=neu"} (three-dimensional)</li>
- * </ul>
- * </div>
- *
- * <b>Warning:</b> despite the {@code "epsg"} word, coordinate reference systems created by {@code "+init=epsg:"}
- * syntax are not necessarily compliant with EPSG definitions. In particular, the axis order is often different.
- * Units of measurement may also differ.
- *
- * <h2>Installation</h2>
- * The Proj.4 library needs to be reachable on a platform-dependent library path.
- * For example the operating system may search in {@code /usr/lib}, {@code /opt/local/lib} and other directories.
- * One of those directories shall contain the {@code proj} or {@code libproj} file with platform-specific suffix
- * (e.g. {@code .so}, {@code .dylib} or {@code .dll}).
- * An easy way to install the library in appropriate directory is to use the package manager provided by the platform.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-package org.apache.sis.storage.gdal;
diff --git a/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory b/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
deleted file mode 100644
index 6478ec9..0000000
--- a/storage/sis-gdal/src/main/resources/META-INF/services/org.apache.sis.internal.referencing.SpecializedOperationFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.sis.internal.storage.gdal.OperationFactory
diff --git a/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory b/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
deleted file mode 100644
index 61ba431..0000000
--- a/storage/sis-gdal/src/main/resources/META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.sis.storage.gdal.Proj4Factory
diff --git a/storage/sis-gdal/src/main/resources/native/darwin/libproj-binding.so b/storage/sis-gdal/src/main/resources/native/darwin/libproj-binding.so
deleted file mode 100755
index d57a27d..0000000
Binary files a/storage/sis-gdal/src/main/resources/native/darwin/libproj-binding.so and /dev/null differ
diff --git a/storage/sis-gdal/src/main/resources/native/linux/libproj-binding.so b/storage/sis-gdal/src/main/resources/native/linux/libproj-binding.so
deleted file mode 100755
index 7579df9..0000000
Binary files a/storage/sis-gdal/src/main/resources/native/linux/libproj-binding.so and /dev/null differ
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
deleted file mode 100644
index 159510d..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/IntegrationTest.java
+++ /dev/null
@@ -1,63 +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.storage.gdal;
-
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.CRS;
-import org.apache.sis.test.TestCase;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.opengis.test.Assert.*;
-
-
-/**
- * Tests the integration of the {@code sis-gdal} module in the Apache SIS framework.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final strictfp class IntegrationTest extends TestCase {
-    /**
-     * Verifies if the {@literal Proj.4} library is available.
-     */
-    @BeforeClass
-    public static void verifyNativeLibraryAvailability() {
-        PJTest.verifyNativeLibraryAvailability();
-    }
-
-    /**
-     * Tests usage of {@link CRS#forCode(String)}. Note that the {@code "Proj4::"} prefix needs two colons,
-     * otherwise the text between {@code "Proj4:"} and {@code ":4326"} is interpreted as a version string.
-     *
-     * @throws FactoryException if the coordinate reference system can not be created.
-     * @throws TransformException if an error occurred while testing a coordinate transformation.
-     */
-    @Test
-    public void testCRS() throws FactoryException, TransformException {
-        final CoordinateReferenceSystem sourceCRS = CRS.forCode("Proj4::+init=epsg:4326");
-        final CoordinateReferenceSystem targetCRS = CRS.forCode("Proj4::+init=epsg:3395");
-        final CoordinateOperation op = CRS.findOperation(sourceCRS, targetCRS, null);
-        assertInstanceOf("Expected Proj.4 wrapper.", Transform.class, op.getMathTransform());
-        Proj4FactoryTest.testMercatorProjection(op.getMathTransform());
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java
deleted file mode 100644
index 13e8e77..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/MTFactory.java
+++ /dev/null
@@ -1,201 +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.storage.gdal;
-
-import java.util.Map;
-import java.text.ParseException;
-import org.opengis.util.FactoryException;
-import org.opengis.util.NoSuchIdentifierException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.referencing.cs.CoordinateSystem;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.crs.CRSAuthorityFactory;
-import org.opengis.referencing.operation.Conversion;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
-import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.operation.OperationMethod;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.Matrix;
-import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.io.wkt.WKTFormat;
-
-
-/**
- * Adds to {@link Proj4Factory} the missing method for making it a {@link MathTransformFactory} implementation.
- * We do not provide those methods in the main source directory yet because we are not sure about exposing large
- * amount of methods that are not really supported by Proj.4 wrappers. If experience shows that it would be useful,
- * selected methods from this class could be refactored into {@link Proj4Factory} in future Apache SIS versions.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-class MTFactory extends Proj4Factory implements CoordinateOperationFactory, MathTransformFactory {
-    /**
-     * The WKT parser to use, created when first needed.
-     *
-     * @see #createFromWKT(String)
-     */
-    private transient WKTFormat parser;
-
-    /**
-     * Creates a new {@literal Proj.4} factory.
-     *
-     * @param properties  common properties for the objects to create, or {@code null} if none.
-     */
-    public MTFactory(final Map<String,?> properties) {
-        super(properties);
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper — delegates to the Apache SIS default factory.
-     */
-    @Override
-    public OperationMethod createOperationMethod(Map<String,?> properties, Integer sourceDimension,
-            Integer targetDimension, ParameterDescriptorGroup parameters) throws FactoryException
-    {
-        return opFactory().createOperationMethod(properties, sourceDimension, targetDimension, parameters);
-    }
-
-    /**
-     * Creates an operation for conversion or transformation between two coordinate reference systems.
-     * This implementation always uses Proj.4 for performing the coordinate operations, regardless if
-     * the given CRS were created from Proj.4 definition strings or not. This method fails if it can
-     * not map the given CRS to Proj.4 data structures.
-     *
-     * @param  sourceCRS  the source coordinate reference system.
-     * @param  targetCRS  the target coordinate reference system.
-     * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS.
-     * @throws FactoryException if the given CRS are not instances recognized by this class.
-     *
-     * @see Proj4#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, boolean)
-     */
-    @Override
-    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
-                                               final CoordinateReferenceSystem targetCRS)
-            throws FactoryException
-    {
-        return createOperation(sourceCRS, targetCRS, true);
-    }
-
-    /**
-     * Ignores the given {@code method} argument and delegates to
-     * <code>{@linkplain #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)
-     * createOperation}(sourceCRS, targetCRS)</code>.
-     *
-     * @param  sourceCRS  the source coordinate reference system.
-     * @param  targetCRS  the target coordinate reference system.
-     * @return a coordinate operation for transforming coordinates from the given source CRS to the given target CRS.
-     * @throws FactoryException if the given CRS are not instances recognized by this class.
-     */
-    @Override
-    @Deprecated
-    public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
-                                               final CoordinateReferenceSystem targetCRS,
-                                               final OperationMethod method)
-            throws FactoryException
-    {
-        return createOperation(sourceCRS, targetCRS);
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper — delegates to the Apache SIS default factory.
-     */
-    @Override
-    public CoordinateOperation createConcatenatedOperation(Map<String,?> properties, CoordinateOperation... operations)
-            throws FactoryException
-    {
-        return opFactory().createConcatenatedOperation(properties, operations);
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper — delegates to the Apache SIS default factory.
-     */
-    @Override
-    public Conversion createDefiningConversion(Map<String,?> properties, OperationMethod method, ParameterValueGroup parameters)
-            throws FactoryException
-    {
-        return opFactory().createDefiningConversion(properties, method, parameters);
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper.
-     */
-    @Override
-    public MathTransform createBaseToDerived(CoordinateReferenceSystem baseCRS, ParameterValueGroup parameters, CoordinateSystem derivedCS)
-            throws NoSuchIdentifierException, FactoryException
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper.
-     */
-    @Override
-    public MathTransform createAffineTransform(Matrix matrix) throws FactoryException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Not yet implemented.
-     */
-    @Override
-    public MathTransform createConcatenatedTransform(MathTransform transform1, MathTransform transform2) throws FactoryException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Unsupported by the {@literal Proj.4} wrapper.
-     */
-    @Override
-    public MathTransform createPassThroughTransform(int firstAffectedCoordinate, MathTransform subTransform, int numTrailingCoordinates)
-            throws FactoryException
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Unconditionally returns the operation method that describes the {@literal Proj.4} {@link Transform} wrapper
-     * since it is the only kind of operation created by this class.
-     */
-    @Override
-    public OperationMethod getLastMethodUsed() {
-        return Transform.METHOD;
-    }
-
-    /**
-     * Parses the given Well Known Text (version 1) into a math transform.
-     */
-    @Override
-    public synchronized MathTransform createFromWKT(final String wkt) throws FactoryException {
-        ArgumentChecks.ensureNonEmpty("wkt", wkt);
-        if (parser == null) {
-            parser = new WKTFormat(null, null);
-            parser.setFactory(CRSAuthorityFactory.class, this);
-            parser.setFactory(MathTransformFactory.class, this);
-            parser.setFactory(CoordinateOperationFactory.class, this);
-        }
-        try {
-            return (MathTransform) parser.parseObject(wkt);
-        } catch (ParseException | ClassCastException e) {
-            throw new FactoryException(e);
-        }
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java
deleted file mode 100644
index 3e16edf..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java
+++ /dev/null
@@ -1,181 +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.storage.gdal;
-
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.test.TestCase;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.junit.Assume.assumeTrue;
-import static org.apache.sis.test.Assert.*;
-
-
-/**
- * Tests the {@link PJ} class.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final strictfp class PJTest extends TestCase {
-    /**
-     * If the {@literal Proj.4} library has been successfully initialized, an empty string.
-     * Otherwise, the reason why the library is not available.
-     */
-    private static String status;
-
-    /**
-     * Verifies if the {@literal Proj.4} library is available.
-     */
-    @BeforeClass
-    public static synchronized void verifyNativeLibraryAvailability() {
-        if (status == null) try {
-            out.println("Proj.4 version: " + PJ.getRelease());
-            status = "";
-        } catch (UnsatisfiedLinkError e) {
-            status = e.toString();
-        }
-        assumeTrue(status, status.isEmpty());
-    }
-
-    /**
-     * Ensures that the given object is the WGS84 definition.
-     */
-    private static void assertIsWGS84(final PJ pj) {
-        assertEquals("+proj=latlong +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0", pj.getCode());
-        assertEquals("Proj4",            pj.getCodeSpace());
-        assertSame  (Citations.PROJ4,    pj.getAuthority());
-        assertTrue  (Character.isDigit(  pj.getVersion().codePointAt(0)));
-        assertEquals(PJ.Type.GEOGRAPHIC, pj.getType());
-        final double[] ellps = pj.getEllipsoidDefinition();
-        assertEquals(2, ellps.length);
-        ellps[1] = 1 / (1 - StrictMath.sqrt(1 - ellps[1]));     // Replace eccentricity squared by inverse flattening.
-        assertArrayEquals(new double[] {6378137.0, 298.257223563}, ellps, 1E-9);
-    }
-
-    /**
-     * Tests the creation of a simple WGS84 object.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     */
-    @Test
-    public void testWGS84() throws FactoryException {
-        final PJ pj = new PJ("+proj=latlong +datum=WGS84");
-        assertIsWGS84(pj);
-    }
-
-    /**
-     * Tests the creation of the EPSG:3395 projected CRS.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     */
-    @Test
-    public void testEPSG3395() throws FactoryException {
-        final PJ pj = new PJ("+init=epsg:3395");
-        assertEquals(PJ.Type.PROJECTED, pj.getType());
-        final String definition = pj.getCode();
-        assertTrue(definition, definition.contains("+proj=merc"));
-        assertTrue(definition, definition.contains("+datum=WGS84"));
-        assertTrue(definition, definition.contains("+units=m"));
-        assertIsWGS84(new PJ(pj));
-    }
-
-    /**
-     * Tests the units of measurement.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     */
-    @Test
-    public void testGetLinearUnit() throws FactoryException {
-        PJ pj;
-        pj = new PJ("+proj=merc +to_meter=1");
-        String definition = pj.getCode();
-        assertTrue(definition, definition.contains("+to_meter=1"));
-        pj = new PJ("+proj=merc +to_meter=0.001");
-        definition = pj.getCode();
-        assertTrue(definition, definition.contains("+to_meter=0.001"));
-    }
-
-    /**
-     * Ensures that the native code correctly detects the case of null pointers.
-     * This is important in order to ensure that we don't have a JVM crash.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testNullPointerException() throws FactoryException, TransformException {
-        final PJ pj = new PJ("+proj=latlong +datum=WGS84");
-        try {
-            pj.transform(null, 2, null, 0, 1);
-            fail("Expected an exception to be thrown.");
-        } catch (NullPointerException e) {
-            // This is the expected exception.
-        }
-    }
-
-    /**
-     * Ensures that the native code correctly detects the case of index out of bounds.
-     * This is important in order to ensure that we don't have a JVM crash.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     * @throws TransformException should never happen.
-     */
-    @Test
-    public void testIndexOutOfBoundsException() throws FactoryException, TransformException {
-        final PJ pj = new PJ("+proj=latlong +datum=WGS84");
-        try {
-            pj.transform(pj, 2, new double[5], 2, 2);
-            fail("Expected an exception to be thrown.");
-        } catch (IndexOutOfBoundsException e) {
-            // This is the expected exception.
-        }
-    }
-
-    /**
-     * Tests a method that returns NaN. The native code is expected to returns the
-     * {@link java.lang.Double#NaN} constant, because not all C/C++ compiler define
-     * a {@code NAN} constant.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     */
-    @Test
-    @SuppressWarnings("FinalizeCalledExplicitly")
-    public void testNaN() throws FactoryException {
-        final PJ pj = new PJ("+proj=latlong +datum=WGS84");
-        pj.finalize();              // This cause the disposal of the internal PJ structure.
-        assertNull(pj.getCode());
-        assertNull(pj.getType());
-        assertNull(pj.getEllipsoidDefinition());
-    }
-
-    /**
-     * Tests serialization. Since we can not serialize native resources, {@link PJ} is expected
-     * to serialize the Proj.4 definition string instead.
-     *
-     * @throws FactoryException if the Proj.4 definition string used in this test is invalid.
-     */
-    @Test
-    public void testSerialization() throws FactoryException {
-        final PJ pj = new PJ("+proj=latlong +datum=WGS84");
-        assertNotSame(pj, assertSerializedEquals(pj));
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java
deleted file mode 100644
index bbc6438..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4FactoryTest.java
+++ /dev/null
@@ -1,148 +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.storage.gdal;
-
-import java.util.Arrays;
-import org.opengis.util.FactoryException;
-import org.opengis.geometry.DirectPosition;
-import org.opengis.referencing.cs.AxisDirection;
-import org.opengis.referencing.crs.ProjectedCRS;
-import org.opengis.referencing.crs.GeographicCRS;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.CoordinateOperation;
-import org.opengis.referencing.operation.Conversion;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.apache.sis.geometry.DirectPosition2D;
-import org.apache.sis.test.DependsOn;
-import org.apache.sis.test.TestCase;
-import org.apache.sis.test.TestUtilities;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.opengis.test.Assert.*;
-
-
-/**
- * Tests the {@link Proj4Factory} class.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-@DependsOn({PJTest.class, Proj4ParserTest.class})
-public final strictfp class Proj4FactoryTest extends TestCase {
-    /**
-     * Verifies if the {@literal Proj.4} library is available.
-     */
-    @BeforeClass
-    public static void verifyNativeLibraryAvailability() {
-        PJTest.verifyNativeLibraryAvailability();
-    }
-
-    /**
-     * Tests {@link Proj4Factory#getAuthorityCodes(Class)}.
-     *
-     * @throws FactoryException if an error occurred while querying the factory.
-     */
-    @Test
-    public void testGetAuthorityCodes() throws FactoryException {
-        final Proj4Factory factory = Proj4Factory.INSTANCE;
-        assertTrue(factory.getAuthorityCodes(GeographicCRS.class).containsAll(Arrays.asList("+proj=latlon")));
-        assertTrue(factory.getAuthorityCodes(ProjectedCRS.class).containsAll(Arrays.asList("+proj=merc", "+proj=lcc")));
-        assertTrue(factory.getAuthorityCodes(CoordinateReferenceSystem.class).containsAll(
-                Arrays.asList("+proj=latlon", "+proj=merc", "+proj=lcc")));
-    }
-
-    /**
-     * Tests the creation of the {@code "+init=epsg:4326"} geographic CRS.
-     * Note that the axis order is not the same than standard EPSG:4326.
-     *
-     * @throws FactoryException if an error occurred while creating the CRS objects.
-     */
-    @Test
-    public void test4326() throws FactoryException {
-        final Proj4Factory factory = Proj4Factory.INSTANCE;
-        final GeographicCRS crs = factory.createGeographicCRS("+init=epsg:4326");
-        final PJ pj = (PJ) TestUtilities.getSingleton(crs.getIdentifiers());
-        assertEquals(PJ.Type.GEOGRAPHIC, pj.getType());
-        final String definition = pj.getCode();
-        assertTrue(definition, definition.contains("+proj=longlat"));
-        assertTrue(definition, definition.contains("+datum=WGS84"));
-        assertAxisDirectionsEqual(definition, crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.NORTH);
-    }
-
-    /**
-     * Tests the creation of the {@code "+init=epsg:3395"} projected CRS.
-     *
-     * @throws FactoryException if an error occurred while creating the CRS objects.
-     */
-    @Test
-    public void test3395() throws FactoryException {
-        final Proj4Factory factory = Proj4Factory.INSTANCE;
-        final ProjectedCRS crs = factory.createProjectedCRS("+init=epsg:3395");
-        final PJ pj = (PJ) TestUtilities.getSingleton(crs.getIdentifiers());
-        assertEquals(PJ.Type.PROJECTED, pj.getType());
-        final String definition = pj.getCode();
-        assertTrue(definition, definition.contains("+proj=merc"));
-        assertTrue(definition, definition.contains("+datum=WGS84"));
-        assertAxisDirectionsEqual(definition, crs.getCoordinateSystem(), AxisDirection.EAST, AxisDirection.NORTH);
-    }
-
-    /**
-     * Tests the transformation from {@code "+init=epsg:4326"} to {@code "+init=epsg:3395"}.
-     *
-     * @throws FactoryException if an error occurred while creating the CRS objects.
-     * @throws TransformException if an error occurred while projecting a test point.
-     */
-    @Test
-    public void testTransform() throws FactoryException, TransformException {
-        final Proj4Factory  factory   = Proj4Factory.INSTANCE;
-        final GeographicCRS sourceCRS = factory.createGeographicCRS("+init=epsg:4326");
-        final ProjectedCRS  targetCRS = factory.createProjectedCRS("+init=epsg:3395");
-        final CoordinateOperation op  = factory.createOperation(sourceCRS, targetCRS, true);
-        assertInstanceOf("createOperation", Conversion.class, op);
-        testMercatorProjection(op.getMathTransform());
-    }
-
-    /**
-     * Tests EPSG:3395 on a point.
-     */
-    static void testMercatorProjection(final MathTransform mt) throws TransformException {
-        DirectPosition pt = new DirectPosition2D(20, 40);
-        pt = mt.transform(pt, pt);
-        assertEquals("Easting",  2226389.816, pt.getOrdinate(0), 0.01);
-        assertEquals("Northing", 4838471.398, pt.getOrdinate(1), 0.01);
-    }
-
-    /**
-     * Tests {@link Proj4Factory#createParameterizedTransform(ParameterValueGroup)}.
-     *
-     * @throws FactoryException if an error occurred while creating the CRS objects.
-     * @throws TransformException if an error occurred while projecting a test point.
-     */
-    @Test
-    public void testParameterizedTransform() throws FactoryException, TransformException {
-        final Proj4Factory factory   = Proj4Factory.INSTANCE;
-        final ParameterValueGroup pg = factory.getDefaultParameters("merc");
-        pg.parameter("a").setValue(6378137.0);
-        pg.parameter("b").setValue(6356752.314245179);
-        testMercatorProjection(factory.createParameterizedTransform(pg));
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4ParserTest.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4ParserTest.java
deleted file mode 100644
index 6a33d96..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4ParserTest.java
+++ /dev/null
@@ -1,83 +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.storage.gdal;
-
-import org.opengis.util.FactoryException;
-import org.opengis.referencing.operation.CoordinateOperationFactory;
-import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
-import org.apache.sis.internal.referencing.provider.Mercator1SP;
-import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.measure.Units;
-import org.apache.sis.test.TestCase;
-import org.junit.Test;
-import org.opengis.parameter.ParameterValueGroup;
-
-import static org.opengis.test.Assert.*;
-
-
-/**
- * Tests {@link Proj4Parser}.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final strictfp class Proj4ParserTest extends TestCase {
-    /**
-     * The factory needed for calls to {@code Proj4Parser.method(…)}.
-     */
-    private final DefaultCoordinateOperationFactory opFactory;
-
-    /**
-     * Creates a new test.
-     */
-    public Proj4ParserTest() {
-        opFactory = DefaultFactories.forBuildin(CoordinateOperationFactory.class, DefaultCoordinateOperationFactory.class);
-    }
-
-    /**
-     * Tests parsing of a Mercator projection definition string.
-     *
-     * @throws FactoryException if the parsing failed.
-     */
-    @Test
-    public void testMercator() throws FactoryException {
-        final Proj4Parser parser = new Proj4Parser("+init=epsg:3395 +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0"
-                      + " +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0");
-
-        assertInstanceOf("method", Mercator1SP.class, parser.method(opFactory));
-        final ParameterValueGroup pg = parser.parameters();
-        assertEquals("scale_factor", pg.parameter("scale_factor").getValue(), 1.0);
-        assertEquals(Units.METRE, parser.unit(false));
-    }
-
-    /**
-     * Tests parsing a definition string with axes in kilometres.
-     *
-     * @throws FactoryException if the parsing failed.
-     */
-    @Test
-    public void testKilometres() throws FactoryException {
-        final Proj4Parser parser = new Proj4Parser("+proj=merc +to_meter=0.001");
-
-        assertInstanceOf("method", Mercator1SP.class, parser.method(opFactory));
-        final ParameterValueGroup pg = parser.parameters();
-        assertEquals("scale_factor", pg.parameter("scale_factor").getValue(), 1.0);
-        assertEquals(Units.KILOMETRE, parser.unit(false));
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4Test.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4Test.java
deleted file mode 100644
index 5483cf5..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/Proj4Test.java
+++ /dev/null
@@ -1,46 +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.storage.gdal;
-
-import org.opengis.util.FactoryException;
-import org.apache.sis.referencing.crs.HardCodedCRS;
-import org.apache.sis.test.TestCase;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-
-/**
- * Tests the {@link Proj4} class.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-public final strictfp class Proj4Test extends TestCase {
-    /**
-     * Tests {@link Proj4#definition(CoordinateReferenceSystem)} on geographic CRS.
-     *
-     * @throws FactoryException if an error occurred while computing the Proj.4 definition string.
-     */
-    @Test
-    public void testGeographicDefinition() throws FactoryException {
-        assertEquals("+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=enu", Proj4.definition(HardCodedCRS.WGS84));
-        assertEquals("+proj=latlon +a=6378137.0 +b=6356752.314245179 +pm=0.0 +axis=neu", Proj4.definition(HardCodedCRS.WGS84_LATITUDE_FIRST));
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/TransformTest.java b/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/TransformTest.java
deleted file mode 100644
index 051569a..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/TransformTest.java
+++ /dev/null
@@ -1,102 +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.storage.gdal;
-
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Arrays;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.util.NoSuchIdentifierException;
-import org.opengis.test.referencing.ParameterizedTransformTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.junit.BeforeClass;
-import org.junit.AfterClass;
-
-import static org.apache.sis.test.Assert.*;
-
-
-/**
- * Tests various map projections using {@literal Proj.4} wrappers.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
- * @since   0.8
- * @module
- */
-@RunWith(JUnit4.class)
-public class TransformTest extends ParameterizedTransformTest {
-    /**
-     * The operation methods that we failed to instantiate.
-     * We use this set for verifying that there is no more failures than the expected ones.
-     */
-    private static final Set<String> FAILURES = new HashSet<>();
-
-    /**
-     * Creates a new test suite.
-     */
-    public TransformTest() {
-        super(new MTFactory(null) {
-            @Override
-            public ParameterValueGroup getDefaultParameters(final String method) throws NoSuchIdentifierException {
-                try {
-                    return super.getDefaultParameters(method);
-                } catch (NoSuchIdentifierException e) {
-                    FAILURES.add(method);
-                    throw e;                            // Instructs ParameterizedTransformTest to skip the test.
-                }
-            }
-        });
-        isDerivativeSupported = false;
-    }
-
-    /**
-     * Verifies if the {@literal Proj.4} library is available.
-     */
-    @BeforeClass
-    public static void verifyNativeLibraryAvailability() {
-        PJTest.verifyNativeLibraryAvailability();
-    }
-
-    /**
-     * Invoked after all the tests have been run for comparing the list of failures with the expected list.
-     * This method checks for the exact same content, so this method detects both unexpected failures and
-     * "unexpected" successes. Note that a failure is not necessarily because Proj.4 does not support the
-     * map projection; it may also be because Apache SIS does not yet declare the corresponding operation
-     * method.
-     */
-    @AfterClass
-    public static void verifyFailureList() {
-        /*
-         * The list of failures is empty if verifyNativeLibraryAvailability() failed,
-         * in which case no test have been run.
-         */
-        if (!FAILURES.isEmpty()) {
-            assertSetEquals(Arrays.asList(
-                    "Abridged Molodensky",
-                    "Krovak",                                   // No OperationMethod in SIS yet.
-                    "Lambert Azimuthal Equal Area",             // No OperationMethod in SIS yet.
-                    "Lambert Conic Conformal (2SP Belgium)",
-                    "Lambert Conic Conformal (2SP Michigan)",
-                    "Mercator (variant C)",                     // Need to verify if Proj4 handles easting/northing correctly.
-                    "Polar Stereographic (variant C)",          // Need to verify if Proj4 handles northing correctly.
-                    "Popular Visualisation Pseudo Mercator",
-                    "Transverse Mercator (South Orientated)"), FAILURES);
-            FAILURES.clear();
-        }
-    }
-}
diff --git a/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java b/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java
deleted file mode 100644
index 71e6d50..0000000
--- a/storage/sis-gdal/src/test/java/org/apache/sis/test/suite/GDALTestSuite.java
+++ /dev/null
@@ -1,50 +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.test.suite;
-
-import org.apache.sis.test.TestSuite;
-import org.junit.BeforeClass;
-import org.junit.runners.Suite;
-
-
-/**
- * All tests from the {@code sis-gdal} module, in rough dependency order.
- *
- * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
- * @since   0.8
- * @module
- */
-@Suite.SuiteClasses({
-    org.apache.sis.storage.gdal.PJTest.class,
-    org.apache.sis.storage.gdal.Proj4Test.class,
-    org.apache.sis.storage.gdal.Proj4ParserTest.class,
-    org.apache.sis.storage.gdal.Proj4FactoryTest.class,
-    org.apache.sis.storage.gdal.TransformTest.class,
-    org.apache.sis.storage.gdal.IntegrationTest.class
-})
-public final strictfp class GDALTestSuite extends TestSuite {
-    /**
-     * Verifies the list of tests before to run the suite.
-     * See {@link #verifyTestList(Class, Class[])} for more information.
-     */
-    @BeforeClass
-    public static void verifyTestList() {
-        assertNoMissingTest(GDALTestSuite.class);
-        verifyTestList(GDALTestSuite.class);
-    }
-}