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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 2514bc80b8 Replace the use of `java.net.URI` by an internal `GridFile`
class which take in charge the URI resolutions. This is for making easier the
cases where the URI needs to be resolved relatively to the GML or WKT file
instead of resolved in the "$SIS_DATA/DatumChanges" directory.
2514bc80b8 is described below
commit 2514bc80b80d9987fbee054eac5aa4ed9af9c355
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Dec 28 17:23:01 2023 +0100
Replace the use of `java.net.URI` by an internal `GridFile` class which
take in charge the URI resolutions.
This is for making easier the cases where the URI needs to be resolved
relatively to the GML or WKT file
instead of resolved in the "$SIS_DATA/DatumChanges" directory.
---
.../sis/parameter/DefaultParameterValue.java | 1 +
.../main/org/apache/sis/parameter/Parameters.java | 24 ++
.../referencing/operation/gridded/GridFile.java | 290 +++++++++++++++++++++
.../referencing/operation/gridded/GridGroup.java | 5 +-
.../referencing/operation/gridded/GridLoader.java | 79 +-----
.../referencing/operation/gridded/LoadedGrid.java | 22 +-
.../provider/FranceGeocentricInterpolation.java | 35 +--
.../sis/referencing/operation/provider/NADCON.java | 34 +--
.../sis/referencing/operation/provider/NTv2.java | 18 +-
.../operation/provider/DatumShiftTestCase.java | 5 +-
.../FranceGeocentricInterpolationTest.java | 13 +-
.../referencing/operation/provider/NADCONTest.java | 7 +-
.../referencing/operation/provider/NTv2Test.java | 19 +-
.../sis/test/integration/DatumShiftTest.java | 5 +-
.../main/org/apache/sis/system/DataDirectory.java | 36 +--
15 files changed, 402 insertions(+), 191 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
index 7cdc01b585..ce89c5b038 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java
@@ -258,6 +258,7 @@ public class DefaultParameterValue<T> extends
FormattableObject implements Param
* }
*
* @see #setSourceFile(URI)
+ * @see Parameters#getSourceFile(ParameterDescriptor)
* @see org.apache.sis.io.wkt.WKTFormat#getSourceFile()
* @see org.apache.sis.xml.MarshalContext#getDocumentURI()
* @see URI#resolve(URI)
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
index 7f62e5f7d0..c4257787bb 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
@@ -19,7 +19,9 @@ package org.apache.sis.parameter;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
+import java.util.Optional;
import java.util.function.Predicate;
+import java.net.URI;
import java.io.Serializable;
import jakarta.xml.bind.annotation.XmlTransient;
import javax.measure.Unit;
@@ -513,6 +515,28 @@ public abstract class Parameters implements
ParameterValueGroup, Cloneable, Prin
return false;
}
+ /**
+ * {@return the URI of the GML document or WKT file from which a parameter
value has been read}.
+ * This information can be used together with {@code
getValue(ParameterDescriptor<URI>)} for
+ * resolving a parameter value as a path relative to the GML or WKT file
declaring the parameter.
+ * Note that the source file is not necessarily the same for all
parameters in a group, because a GML
+ * document could define parameters in files referenced by different
{@code xlink:href} attribute values.
+ *
+ * @see DefaultParameterValue#getSourceFile()
+ * @see org.apache.sis.io.wkt.WKTFormat#getSourceFile()
+ * @see org.apache.sis.xml.MarshalContext#getDocumentURI()
+ * @see URI#resolve(URI)
+ *
+ * @since 1.5
+ */
+ public Optional<URI> getSourceFile(final ParameterDescriptor<?> parameter)
throws ParameterNotFoundException {
+ final ParameterValue<?> p = getParameter(parameter);
+ if (p instanceof DefaultParameterValue<?>) {
+ return ((DefaultParameterValue<?>) p).getSourceFile();
+ }
+ return Optional.empty();
+ }
+
/**
* Returns the value of the parameter identified by the given descriptor,
or {@code null} if none.
* This method uses the following information from the given {@code
parameter} descriptor:
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridFile.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridFile.java
new file mode 100644
index 0000000000..c6fc045fa4
--- /dev/null
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridFile.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.gridded;
+
+import java.net.URI;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Path;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.FileSystemNotFoundException;
+import java.util.logging.Level;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.factory.FactoryDataException;
+import org.apache.sis.referencing.factory.MissingFactoryResourceException;
+import org.apache.sis.referencing.operation.provider.AbstractProvider;
+import org.apache.sis.referencing.internal.Resources;
+import org.apache.sis.system.DataDirectory;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.resources.Messages;
+
+
+/**
+ * Resolved path to a grid file. The starting point is the path specified by a
parameter.
+ * If that path is relative, then this class tries to resolve it in a
directory specified
+ * by the {@code SIS_DATA} environment variable. If the path cannot be
resolved that way,
+ * then this method check if it can be resolved relatively to the GML or WKT
file containing
+ * the parameter.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public final class GridFile {
+ /**
+ * Whether the tip about the location of datum shift files has been logged.
+ * We log this tip only once, and only if we failed to load at least one
grid.
+ */
+ private static final AtomicBoolean datumDirectoryLogged = new
AtomicBoolean();
+
+ /**
+ * The directory where to search for a local copy of the data, or {@code
null} if none.
+ */
+ private final DataDirectory localDirectory;
+
+ /**
+ * The URI specified in the parameter. This URI is usually relative to an
unspecified directory.
+ *
+ * @see #resolved()
+ */
+ public final URI parameter;
+
+ /**
+ * The URI as an absolute path.
+ */
+ private URI resolved;
+
+ /**
+ * The base URI used for resolving the parameter, or {@code null} if none.
+ */
+ private URI base;
+
+ /**
+ * The resolved URI as a path, or {@code null} if not yet computed or not
convertible.
+ */
+ private Path asPath;
+
+ /**
+ * Creates a file for the given URI, assumed already resolved.
+ * This constructor is for testing purposes.
+ *
+ * @param resolved the resolved URI.
+ */
+ public GridFile(final URI resolved) {
+ parameter = resolved;
+ this.resolved = resolved;
+ localDirectory = DataDirectory.DATUM_CHANGES;
+ }
+
+ /**
+ * Resolves the given parameter as an absolute URI, resolved in the {@code
"$SIS_DATA/DatumChanges"} directory
+ * if the URI is relative. If the URI cannot be resolved, a {@link
MissingFactoryResourceException} is thrown.
+ * That exception type is necessary for letting the caller know that a
coordinate operation is probably valid
+ * but cannot be constructed because an optional configuration is missing.
+ * It is typically because the {@code SIS_DATA} environment variable has
not been set.
+ *
+ * @param group the group of parameters from which to get the URI.
+ * @param param identification of the parameter to fetch.
+ * @throws ParameterNotFoundException if the specified parameter is not
found in the given group.
+ * @throws MissingFactoryResourceException if the path cannot be resolved.
+ */
+ public GridFile(final Parameters group, final ParameterDescriptor<URI>
param) throws MissingFactoryResourceException {
+ this(group, param, DataDirectory.DATUM_CHANGES);
+ }
+
+ /**
+ * Resolves the given parameter as an absolute URI, resolved with the
specified {@code DataDirectory}
+ * if the URI is relative. If the URI cannot be resolved, a {@link
MissingFactoryResourceException} is thrown.
+ * That exception type is necessary for letting the caller know that a
coordinate operation is probably valid
+ * but cannot be constructed because an optional configuration is missing.
+ * It is typically because the {@code SIS_DATA} environment variable has
not been set.
+ *
+ * @param group the group of parameters from which to get the
URI.
+ * @param param identification of the parameter to fetch.
+ * @param localDirectory the directory where to search for a local copy
of the data, or {@code null} if none.
+ * @throws ParameterNotFoundException if the specified parameter is not
found in the given group.
+ * @throws MissingFactoryResourceException if the path cannot be resolved.
+ */
+ public GridFile(final Parameters group, final ParameterDescriptor<URI>
param, final DataDirectory localDirectory)
+ throws MissingFactoryResourceException
+ {
+ RuntimeException error = null;
+ this.localDirectory = localDirectory;
+ parameter = group.getMandatoryValue(param);
+ if (parameter.isAbsolute()) {
+ resolved = parameter.normalize();
+ } else {
+ /*
+ * First, try to resolve the parameter relative to the
"$SIS_DATA/DatumChanges" directory.
+ * That directory can be seen as a cache to be tried before to
download data that may be
+ * on the network.
+ */
+ if (localDirectory != null) {
+ base = localDirectory.getDirectoryAsURI();
+ if (base != null) try {
+ resolved = base.resolve(parameter).normalize();
+ asPath = Path.of(resolved);
+ if (Files.exists(asPath)) {
+ return;
+ }
+ } catch (IllegalArgumentException |
FileSystemNotFoundException e) {
+ error = e;
+ }
+ }
+ /*
+ * If the "$SIS_DATA/DatumChanges" directory cannot be used, check
if we
+ * have another base URI that we could try. If not, we cannot
continue.
+ */
+ final URI document = group.getSourceFile(param).orElse(null);
+ if (document == null) {
+ if (resolved != null) {
+ return; // NoSuchFileException will be thrown
later by `newByteChannel()`.
+ }
+ final String message;
+ if (parameter.isOpaque()) {
+ message = Errors.format(Errors.Keys.CanNotOpen_1,
parameter);
+ } else {
+ final String env = DataDirectory.getenv();
+ if (env == null) {
+ message =
Messages.format(Messages.Keys.DataDirectoryNotSpecified_1, DataDirectory.ENV);
+ } else {
+ message =
Messages.format(Messages.Keys.DataDirectoryNotAccessible_2, DataDirectory.ENV,
env);
+ }
+ }
+ throw new MissingFactoryResourceException(message, error);
+ }
+ /*
+ * Use the alternative base URI without checking if it exists.
+ * This check will be done when the file will be opened.
+ */
+ base = document;
+ resolved = document.resolve(parameter).normalize();
+ }
+ try {
+ asPath = Path.of(resolved);
+ } catch (IllegalArgumentException | FileSystemNotFoundException e) {
+ if (error == null) error = e;
+ else error.addSuppressed(e);
+ asPath = null;
+ }
+ if (error != null) {
+ Logging.ignorableException(AbstractProvider.LOGGER,
GridFile.class, "<init>", error);
+ }
+ }
+
+ /**
+ * {@return the resolved URI}.
+ *
+ * @see #parameter
+ */
+ public URI resolved() {
+ return resolved;
+ }
+
+ /**
+ * Creates a channel for reading bytes from the file at the path specified
at construction time.
+ * This method tries to open using the file system before to open from the
URL.
+ *
+ * @return a channel for reading bytes from the file.
+ * @throws IOException if the channel cannot be created.
+ */
+ public ReadableByteChannel newByteChannel() throws IOException {
+ if (asPath != null) {
+ return Files.newByteChannel(asPath);
+ } else {
+ return Channels.newChannel(resolved.toURL().openStream());
+ }
+ }
+
+ /**
+ * Creates a buffered reader for reading characters from the file at the
path specified at construction time.
+ * This method tries to open using the file system before to open from the
URL.
+ *
+ * @return a channel for reading bytes from the file.
+ * @throws IOException if the reader cannot be created.
+ */
+ public BufferedReader newBufferedReader() throws IOException {
+ if (asPath != null) {
+ return Files.newBufferedReader(asPath);
+ } else {
+ return new BufferedReader(new
InputStreamReader(resolved.toURL().openStream()));
+ }
+ }
+
+ /**
+ * Logs a message about a grid which is about to be loaded.
+ * The logger will be {@code "org.apache.sis.referencing.operation"} and
the originating
+ * method will be {@code "createMathTransform"} in the specified {@code
caller} class.
+ *
+ * @param caller the provider to logs as the source class.
+ */
+ public void startLoading(final Class<?> caller) {
+ startLoading(caller, parameter);
+ }
+
+ /**
+ * Logs a message about a grid which is about to be loaded.
+ * The logger will be {@code "org.apache.sis.referencing.operation"} and
the originating
+ * method will be {@code "createMathTransform"} in the specified {@code
caller} class.
+ *
+ * @param caller the provider to logs as the source class.
+ * @param file the grid file, as a {@link String} or a {@link URI}.
+ */
+ public static void startLoading(final Class<?> caller, final Object file) {
+ GridLoader.log(caller,
Resources.forLocale(null).getLogRecord(Level.FINE,
Resources.Keys.LoadingDatumShiftFile_1, file));
+ }
+
+ /**
+ * Creates the exception to throw when the provider failed to load the
grid file.
+ * The first time that this method is invoked, an information message is
logged
+ * as a tip to the user about where data where searched.
+ *
+ * @param caller the provider to logs as the source class if a warning
occurs.
+ * @param format the format name (e.g. "NTv2" or "NADCON").
+ * @param cause the cause of the failure to load the grid file.
+ */
+ public FactoryException canNotLoad(final Class<?> caller, final String
format, final Exception cause) {
+ if (localDirectory != null && !datumDirectoryLogged.get()) {
+ final Path directory = localDirectory.getDirectory();
+ if (directory != null && !datumDirectoryLogged.getAndSet(true)) {
+ GridLoader.log(caller,
Resources.forLocale(null).getLogRecord(Level.INFO,
+ Resources.Keys.DatumChangesDirectory_1,
directory));
+ }
+ }
+ if (cause instanceof NoSuchFileException || cause instanceof
FileNotFoundException) {
+ return new
MissingFactoryResourceException(Resources.format(Resources.Keys.FileNotFound_2),
cause);
+ } else {
+ return new
FactoryDataException(Resources.format(Resources.Keys.FileNotReadable_2, format,
parameter), cause);
+ }
+ }
+
+ /**
+ * {@return a string representation of this path for debugging purposes}.
+ */
+ @Override
+ public String toString() {
+ return String.valueOf(resolved);
+ }
+}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
index 2216277902..497eff3efc 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.operation.gridded;
import java.util.Map;
import java.util.List;
import java.util.LinkedHashMap;
-import java.net.URI;
import java.io.IOException;
import java.awt.Dimension;
import java.awt.Rectangle;
@@ -156,7 +155,7 @@ public final class GridGroup<C extends Quantity<C>, T
extends Quantity<T>> exten
* @throws IOException declared because {@link Tile#getRegion()} declares
it, but should not happen.
*/
public static <C extends Quantity<C>, T extends Quantity<T>>
GridGroup<C,T> create(
- final URI file, final List<LoadedGrid<C,T>> subgrids)
+ final GridFile file, final List<LoadedGrid<C,T>> subgrids)
throws IOException, FactoryException,
NoninvertibleTransformException
{
final TileOrganizer mosaic = new TileOrganizer(null);
@@ -182,7 +181,7 @@ public final class GridGroup<C extends Quantity<C>, T
extends Quantity<T>> exten
*/
final Map.Entry<Tile,Tile[]> result =
CollectionsExt.singletonOrNull(mosaic.tiles().entrySet());
if (result == null) {
- throw new
FactoryException(Resources.format(Resources.Keys.MisalignedDatumShiftGrid_1,
file));
+ throw new
FactoryException(Resources.format(Resources.Keys.MisalignedDatumShiftGrid_1,
file.parameter));
}
final Tile global = result.getKey();
return new GridGroup<>(result.getValue(), grids,
global.getGridToCRS(), global.getSize());
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
index 17e9e5be3f..0deb5bdc4e 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
@@ -16,27 +16,13 @@
*/
package org.apache.sis.referencing.operation.gridded;
-import java.util.logging.Level;
import java.util.logging.LogRecord;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.io.EOFException;
import java.io.IOException;
-import java.io.FileNotFoundException;
import java.nio.ByteBuffer;
-import java.net.URI;
-import java.nio.file.Path;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.FileSystemNotFoundException;
import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.Channels;
-import org.opengis.util.FactoryException;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.logging.Logging;
-import org.apache.sis.system.DataDirectory;
-import org.apache.sis.referencing.internal.Resources;
-import org.apache.sis.referencing.factory.FactoryDataException;
-import org.apache.sis.referencing.factory.MissingFactoryResourceException;
import org.apache.sis.referencing.operation.provider.AbstractProvider;
@@ -72,7 +58,7 @@ public abstract class GridLoader {
/**
* The file to load, used for parameter declaration and if we have errors
to report.
*/
- protected final URI file;
+ protected final GridFile file;
/**
* The channel opened on the file.
@@ -84,12 +70,6 @@ public abstract class GridLoader {
*/
protected final ByteBuffer buffer;
- /**
- * Whether the tip about the location of datum shift files has been logged.
- * We log this tip only once, and only if we failed to load at least one
grid.
- */
- private static final AtomicBoolean datumDirectoryLogged = new
AtomicBoolean();
-
/**
* Creates a new loader for the given channel and an existing buffer.
*
@@ -97,7 +77,7 @@ public abstract class GridLoader {
* @param buffer the buffer to use.
* @param file path to the longitude or latitude difference file.
Used for parameter declaration and error reporting.
*/
- protected GridLoader(final ReadableByteChannel channel, final ByteBuffer
buffer, final URI file) throws IOException {
+ protected GridLoader(final ReadableByteChannel channel, final ByteBuffer
buffer, final GridFile file) throws IOException {
this.file = file;
this.buffer = buffer;
this.channel = channel;
@@ -149,35 +129,6 @@ public abstract class GridLoader {
buffer.position(p);
}
- /**
- * Creates a channel for reading bytes from the file at the specified path.
- * This method tries to open using the file system before to open from the
URL.
- *
- * @param path the path from where to read bytes.
- * @return a channel for reading bytes from the given path.
- * @throws IOException if the channel cannot be created.
- */
- public static ReadableByteChannel newByteChannel(final URI path) throws
IOException {
- try {
- return Files.newByteChannel(Path.of(path));
- } catch (FileSystemNotFoundException e) {
- Logging.ignorableException(AbstractProvider.LOGGER,
GridLoader.class, "newByteChannel", e);
- }
- return Channels.newChannel(path.toURL().openStream());
- }
-
- /**
- * Logs a message about a grid which is about to be loaded.
- * The logger will be {@code "org.apache.sis.referencing.operation"} and
the originating
- * method will be {@code "createMathTransform"} in the specified {@code
caller} class.
- *
- * @param caller the provider to logs as the source class.
- * @param file the grid file, as a {@link String} or a {@link URI}.
- */
- public static void startLoading(final Class<?> caller, final Object file) {
- log(caller, Resources.forLocale(null).getLogRecord(Level.FINE,
Resources.Keys.LoadingDatumShiftFile_1, file));
- }
-
/**
* Logs the given record.
* The logger will be {@code "org.apache.sis.referencing.operation"} and
the originating
@@ -189,30 +140,4 @@ public abstract class GridLoader {
protected static void log(final Class<?> caller, final LogRecord record) {
Logging.completeAndLog(AbstractProvider.LOGGER, caller,
"createMathTransform", record);
}
-
- /**
- * Creates the exception to throw when the provider failed to load the
grid file.
- *
- * @param caller the provider to logs as the source class if a warning
occurs.
- * @param format the format name (e.g. "NTv2" or "NADCON").
- * @param file the grid file that the subclass tried to load.
- * @param cause the cause of the failure to load the grid file.
- */
- public static FactoryException canNotLoad(final Class<?> caller, final
String format, final URI file, final Exception cause) {
- if (!datumDirectoryLogged.get()) {
- final Path directory = DataDirectory.DATUM_CHANGES.getDirectory();
- if (directory != null && !datumDirectoryLogged.getAndSet(true)) {
- log(caller, Resources.forLocale(null).getLogRecord(Level.INFO,
- Resources.Keys.DatumChangesDirectory_1,
directory));
- }
- }
- final boolean notFound = (cause instanceof NoSuchFileException) ||
(cause instanceof FileNotFoundException);
- final String message = Resources.format(notFound ?
Resources.Keys.FileNotFound_2
- :
Resources.Keys.FileNotReadable_2, format, file);
- if (notFound) {
- return new MissingFactoryResourceException(message, cause);
- } else {
- return new FactoryDataException(message, cause);
- }
- }
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
index 81c85a28d7..9ba298bb2f 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
@@ -179,7 +179,7 @@ public abstract class LoadedGrid<C extends Quantity<C>, T
extends Quantity<T>> e
* @param nx number of cells along the <var>x</var> axis in
the grid.
* @param ny number of cells along the <var>y</var> axis in
the grid.
* @param descriptor the parameter descriptor of the provider that
created this grid.
- * @param files the file(s) from which the grid has been
loaded. This array is not cloned.
+ * @param files the file(s) from which the grid has been
loaded.
*/
LoadedGrid(final Unit<C> coordinateUnit,
final Unit<T> translationUnit,
@@ -188,12 +188,15 @@ public abstract class LoadedGrid<C extends Quantity<C>, T
extends Quantity<T>> e
final double Δx, final double Δy,
final int nx, final int ny,
final ParameterDescriptorGroup descriptor,
- final URI... files) throws NoninvertibleTransformException
+ final GridFile... sources) throws
NoninvertibleTransformException
{
super(coordinateUnit, new AffineTransform2D(Δx, 0, 0, Δy, x0,
y0).inverse(),
new int[] {nx, ny}, isCellValueRatio, translationUnit);
- this.descriptor = descriptor;
- this.files = files;
+ files = new URI[sources.length];
+ for (int i=0; i<sources.length; i++) {
+ files[i] = sources[i].resolved();
+ }
+ this.descriptor = descriptor;
this.scanlineStride = nx;
if (Units.isAngular(coordinateUnit)) {
periodX = Math.rint((Longitude.MAX_VALUE - Longitude.MIN_VALUE) /
Math.abs(Δx));
@@ -260,10 +263,13 @@ public abstract class LoadedGrid<C extends Quantity<C>, T
extends Quantity<T>> e
*
* @see GridLoader#canNotLoad(Class, String, URI, Exception)
*/
- public static LoadedGrid<?,?> getOrLoad(final URI f1, final URI f2, final
Callable<LoadedGrid<?,?>> loader)
+ public static LoadedGrid<?,?> getOrLoad(final GridFile f1, final GridFile
f2, final Callable<LoadedGrid<?,?>> loader)
throws Exception
{
- final Object key = (f2 != null) ? new
AbstractMap.SimpleImmutableEntry<>(f1, f2) : f1;
+ Object key = f1.resolved();
+ if (f2 != null) {
+ key = new AbstractMap.SimpleImmutableEntry<>(key, f2.resolved());
+ }
return CACHE.getOrCreate(key, loader);
}
@@ -550,7 +556,7 @@ public abstract class LoadedGrid<C extends Quantity<C>, T
extends Quantity<T>> e
final double Δx, final double Δy,
final int nx, final int ny,
final ParameterDescriptorGroup descriptor,
- final URI... files) throws NoninvertibleTransformException
+ final GridFile... files) throws
NoninvertibleTransformException
{
super(coordinateUnit, translationUnit, isCellValueRatio, x0, y0,
Δx, Δy, nx, ny, descriptor, files);
offsets = new float[dim][Math.multiplyExact(nx, ny)];
@@ -663,7 +669,7 @@ public abstract class LoadedGrid<C extends Quantity<C>, T
extends Quantity<T>> e
final double Δx, final double Δy,
final int nx, final int ny,
final ParameterDescriptorGroup descriptor,
- final URI... files) throws
NoninvertibleTransformException
+ final GridFile... files) throws
NoninvertibleTransformException
{
super(coordinateUnit, translationUnit, isCellValueRatio, x0, y0,
Δx, Δy, nx, ny, descriptor, files);
offsets = new double[dim][Math.multiplyExact(nx, ny)];
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java
index c2cbceab50..44585f67ed 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java
@@ -28,7 +28,6 @@ import java.util.concurrent.Callable;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
-import java.io.InputStreamReader;
import static java.lang.Float.parseFloat;
import jakarta.xml.bind.annotation.XmlTransient;
import javax.measure.quantity.Angle;
@@ -47,6 +46,7 @@ import
org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.util.FactoryException;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.datum.DefaultEllipsoid;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.referencing.operation.gridded.LoadedGrid;
import org.apache.sis.referencing.operation.gridded.GridLoader;
import org.apache.sis.referencing.operation.gridded.CompressedGrid;
@@ -59,7 +59,6 @@ import org.apache.sis.measure.Units;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Errors;
-import org.apache.sis.system.DataDirectory;
import static org.apache.sis.util.internal.Constants.DIM;
@@ -268,14 +267,14 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
/**
* Returns {@code true} if the given path seems to be a grid published by
the French mapping agency for France.
* In principle this <q>France geocentric interpolation</q> is designed
specifically for use with the
- * {@code "gr3df97a.txt"} grid, but in fact the Apache SIS implementation
should be flexible enough for use
- * with other area.
+ * {@code "gr3df97a.txt"} grid, but in fact the Apache SIS implementation
should be flexible enough
+ * for use with other area.
*
* @param file the grid file.
* @return {@code true} if the given file looks like a fie from the French
mapping agency.
*/
- public static boolean isRecognized(final URI file) {
- final String filename = file.getPath();
+ public static boolean isRecognized(final GridFile file) {
+ final String filename = file.resolved().getPath();
final int s = filename.lastIndexOf('/') + 1;
return filename.regionMatches(true, s, DEFAULT, 0, 5);
}
@@ -344,13 +343,13 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
default: throw new InvalidParameterValueException(Errors.format(
Errors.Keys.IllegalArgumentValue_2, DIM, dim),
DIM, dim);
}
- final URI file = pg.getMandatoryValue(FILE);
+ final GridFile file = new GridFile(pg, FILE);
final LoadedGrid<Angle,Length> grid;
try {
grid = getOrLoad(file, isRecognized(file) ? new double[] {TX, TY,
TZ} : null, PRECISION);
} catch (Exception e) {
// NumberFormatException, ArithmeticException,
NoSuchElementException, and more.
- throw GridLoader.canNotLoad(FranceGeocentricInterpolation.class,
HEADER, file, e);
+ throw file.canNotLoad(FranceGeocentricInterpolation.class, HEADER,
e);
}
MathTransform tr =
InterpolatedGeocentricTransform.createGeodeticTransformation(factory,
createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR,
@@ -377,11 +376,10 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
*
* @see GridLoader#canNotLoad(Class, String, URI, Exception)
*/
- static LoadedGrid<Angle,Length> getOrLoad(final URI file, final double[]
averages, final double scale)
+ static LoadedGrid<Angle,Length> getOrLoad(final GridFile file, final
double[] averages, final double scale)
throws Exception
{
- final URI resolved = DataDirectory.DATUM_CHANGES.toAbsolutePath(file);
- return LoadedGrid.getOrLoad(resolved, null, new Loader(resolved,
averages, scale))
+ return LoadedGrid.getOrLoad(file, null, new Loader(file, averages,
scale))
.castTo(Angle.class, Length.class);
}
@@ -391,7 +389,7 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
*/
static final class Loader implements Callable<LoadedGrid<?,?>> {
/** The file to load. */
- private final URI file;
+ private final GridFile file;
/** An "average" value for the offset in each dimension, or {@code
null} if unknown. */
private final double[] averages;
@@ -400,17 +398,12 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
private final double scale;
/** Creates a new loader for the given file. */
- Loader(final URI file, final double[] averages, final double scale) {
+ Loader(final GridFile file, final double[] averages, final double
scale) {
this.file = file;
this.averages = averages;
this.scale = scale;
}
- /** Returns the reader for the specified URI. */
- static BufferedReader newBufferedReader(final URI file) throws
IOException {
- return new BufferedReader(new
InputStreamReader(file.toURL().openStream()));
- }
-
/**
* Invoked when the gridded data are not in the cache.
* This method load grid data from the file specified at construction
time.
@@ -423,8 +416,8 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
@Override
public LoadedGrid<?,?> call() throws Exception {
final LoadedGrid<?,?> grid;
- try (BufferedReader in = newBufferedReader(file)) {
- GridLoader.startLoading(FranceGeocentricInterpolation.class,
file);
+ try (BufferedReader in = file.newBufferedReader()) {
+ file.startLoading(FranceGeocentricInterpolation.class);
final LoadedGrid.Float<Angle,Length> g = load(in, file);
grid = CompressedGrid.compress(g, averages, scale);
}
@@ -442,7 +435,7 @@ public final class FranceGeocentricInterpolation extends
GeodeticOperation {
* @throws FactoryException if an problem is found with the file
content.
* @throws ArithmeticException if the width or the height exceed the
integer capacity.
*/
- static LoadedGrid.Float<Angle,Length> load(final BufferedReader in,
final URI file)
+ static LoadedGrid.Float<Angle,Length> load(final BufferedReader in,
final GridFile file)
throws IOException, FactoryException,
NoninvertibleTransformException
{
LoadedGrid.Float<Angle,Length> grid = null;
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
index 4aee4d03f4..43f0709f22 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
@@ -39,12 +39,12 @@ import
org.apache.sis.referencing.factory.MissingFactoryResourceException;
import org.apache.sis.referencing.operation.gridded.CompressedGrid;
import org.apache.sis.referencing.operation.gridded.GridLoader;
import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.measure.Units;
-import org.apache.sis.system.DataDirectory;
/**
@@ -142,9 +142,11 @@ public final class NADCON extends AbstractProvider {
throws ParameterNotFoundException, FactoryException
{
final Parameters pg = Parameters.castOrWrap(values);
+ final GridFile latitudeShifts = new GridFile(pg, LATITUDE);
+ final GridFile longitudeShifts = new GridFile(pg, LONGITUDE);
try {
- return LoadedGrid.createGeodeticTransformation(NADCON.class,
factory,
- getOrLoad(pg.getMandatoryValue(LATITUDE),
pg.getMandatoryValue(LONGITUDE)));
+ LoadedGrid<Angle,Angle> grid = getOrLoad(latitudeShifts,
longitudeShifts);
+ return LoadedGrid.createGeodeticTransformation(NADCON.class,
factory, grid);
} catch (NoSuchFileException e) {
throw new MissingFactoryResourceException(e.getMessage(), e);
} catch (Exception e) {
@@ -160,36 +162,34 @@ public final class NADCON extends AbstractProvider {
* @param longitudeShifts relative or absolute path name of the grid
file for longitude shifts.
* @throws Exception if an error occurred while loading the grid.
*/
- static LoadedGrid<Angle,Angle> getOrLoad(final URI latitudeShifts, final
URI longitudeShifts)
+ static LoadedGrid<Angle,Angle> getOrLoad(final GridFile latitudeShifts,
final GridFile longitudeShifts)
throws Exception
{
- final URI rlat =
DataDirectory.DATUM_CHANGES.toAbsolutePath(latitudeShifts);
- final URI rlon =
DataDirectory.DATUM_CHANGES.toAbsolutePath(longitudeShifts);
- return LoadedGrid.getOrLoad(rlat, rlon, () -> {
+ return LoadedGrid.getOrLoad(latitudeShifts, longitudeShifts, () -> {
final Loader loader;
- URI file = latitudeShifts;
+ GridFile file = latitudeShifts; // Used if an error needs
to be reported.
final LoadedGrid<?,?> grid;
try {
// Note: buffer size must be divisible by the size of `float`
data type.
final ByteBuffer buffer =
ByteBuffer.allocate(4096).order(ByteOrder.LITTLE_ENDIAN);
final FloatBuffer fb = buffer.asFloatBuffer();
- try (ReadableByteChannel in = GridLoader.newByteChannel(rlat))
{
- GridLoader.startLoading(NADCON.class,
CharSequences.commonPrefix(
+ try (ReadableByteChannel in = latitudeShifts.newByteChannel())
{
+ GridFile.startLoading(NADCON.class,
CharSequences.commonPrefix(
latitudeShifts.toString(),
longitudeShifts.toString()).toString() + '…');
- loader = new Loader(in, buffer, file);
+ loader = new Loader(in, buffer, latitudeShifts);
loader.readGrid(fb, null, longitudeShifts);
}
buffer.clear();
file = longitudeShifts;
- try (ReadableByteChannel in = GridLoader.newByteChannel(rlon))
{
- new Loader(in, buffer, file).readGrid(fb, loader, null);
+ try (ReadableByteChannel in =
longitudeShifts.newByteChannel()) {
+ new Loader(in, buffer, longitudeShifts).readGrid(fb,
loader, null);
}
} catch (IOException | NoninvertibleTransformException |
RuntimeException e) {
/*
* Handle the exception here instead of by the caller
* because we know which of the 2 files is problematic.
*/
- throw GridLoader.canNotLoad(NADCON.class, "NADCON", file, e);
+ throw file.canNotLoad(NADCON.class, "NADCON", e);
}
grid = CompressedGrid.compress(loader.grid, null,
loader.grid.accuracy);
return grid.useSharedData();
@@ -270,7 +270,7 @@ public final class NADCON extends AbstractProvider {
* and have a capacity divisible by the size of the
{@code float} type.
* @param file path to the longitude or latitude difference file.
Used for parameter declaration and error reporting.
*/
- Loader(final ReadableByteChannel channel, final ByteBuffer buffer,
final URI file)
+ Loader(final ReadableByteChannel channel, final ByteBuffer buffer,
final GridFile file)
throws IOException, FactoryException
{
super(channel, buffer, file);
@@ -385,7 +385,7 @@ public final class NADCON extends AbstractProvider {
* @param longitudeShifts the file for the longitude grid.
*/
@SuppressWarnings("lossy-conversions") // Implicit cast from
double to float in compound assignment.
- final void readGrid(final FloatBuffer fb, final Loader latitudeShifts,
final URI longitudeShifts)
+ final void readGrid(final FloatBuffer fb, final Loader latitudeShifts,
final GridFile longitudeShifts)
throws IOException, FactoryException,
NoninvertibleTransformException
{
final int dim;
@@ -401,7 +401,7 @@ public final class NADCON extends AbstractProvider {
y0 != latitudeShifts.y0 || Δy != latitudeShifts.Δy || ny
!= latitudeShifts.ny || nz != latitudeShifts.nz)
{
throw new
FactoryException(Errors.format(Errors.Keys.MismatchedGridGeometry_2,
- latitudeShifts.file.getPath(), file.getPath()));
+ latitudeShifts.file.parameter.getPath(),
file.parameter.getPath()));
}
dim = 0; //
Dimension of longitudes
scale = -DEGREES_TO_SECONDS * Δx; //
NADCON shifts are positive west.
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
index 863f795653..1d6218a3a0 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
@@ -46,6 +46,7 @@ import
org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.referencing.operation.gridded.CompressedGrid;
import org.apache.sis.referencing.operation.gridded.GridLoader;
import org.apache.sis.referencing.operation.gridded.GridGroup;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.referencing.operation.gridded.LoadedGrid;
import org.apache.sis.referencing.util.Formulas;
import org.apache.sis.referencing.internal.Resources;
@@ -56,7 +57,6 @@ import org.apache.sis.util.internal.Strings;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.measure.Units;
-import org.apache.sis.system.DataDirectory;
/**
@@ -145,13 +145,12 @@ public final class NTv2 extends AbstractProvider {
final MathTransformFactory factory, final ParameterValueGroup
values, final int version)
throws ParameterNotFoundException, FactoryException
{
- final Parameters pg = Parameters.castOrWrap(values);
- final URI file = pg.getMandatoryValue(FILE);
+ final GridFile file = new GridFile(Parameters.castOrWrap(values),
FILE);
final LoadedGrid<Angle,Angle> grid;
try {
grid = getOrLoad(provider, file, version);
} catch (Exception e) {
- throw GridLoader.canNotLoad(provider, provider.getSimpleName(),
file, e);
+ throw file.canNotLoad(provider, provider.getSimpleName(), e);
}
return LoadedGrid.createGeodeticTransformation(provider, factory,
grid);
}
@@ -169,13 +168,12 @@ public final class NTv2 extends AbstractProvider {
* @see GridLoader#canNotLoad(String, URI, Exception)
*/
static LoadedGrid<Angle,Angle> getOrLoad(final Class<? extends
AbstractProvider> provider,
- final URI file, final int version) throws Exception
+ final GridFile file, final int version) throws Exception
{
- final URI resolved = DataDirectory.DATUM_CHANGES.toAbsolutePath(file);
- return LoadedGrid.getOrLoad(resolved, null, () -> {
+ return LoadedGrid.getOrLoad(file, null, () -> {
final LoadedGrid<?,?> grid;
- try (ReadableByteChannel in = GridLoader.newByteChannel(resolved))
{
- GridLoader.startLoading(provider, file);
+ try (ReadableByteChannel in = file.newByteChannel()) {
+ file.startLoading(provider);
final Loader loader = new Loader(in, file, version);
grid = loader.readAllGrids();
loader.report(provider);
@@ -318,7 +316,7 @@ public final class NTv2 extends AbstractProvider {
* @param version the expected version (1 or 2).
* @throws FactoryException if a data record cannot be parsed.
*/
- Loader(final ReadableByteChannel channel, final URI file, int version)
throws IOException, FactoryException {
+ Loader(final ReadableByteChannel channel, final GridFile file, int
version) throws IOException, FactoryException {
super(channel, ByteBuffer.allocate(4096), file);
header = new LinkedHashMap<>();
ensureBufferContains(RECORD_LENGTH);
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftTestCase.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftTestCase.java
index 915c1bebc2..7654b5c8e7 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftTestCase.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftTestCase.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.operation.provider;
import java.net.URI;
import java.net.URL;
import java.net.URISyntaxException;
+import org.apache.sis.referencing.operation.gridded.GridFile;
// Test dependencies
import static org.junit.Assert.*;
@@ -64,11 +65,11 @@ public abstract class DatumShiftTestCase extends TestCase {
* @param name name of the resource to get.
* @return the requested resources.
*/
- static URI getResource(final String name) throws URISyntaxException {
+ static GridFile getResource(final String name) throws URISyntaxException {
final URL file = getResourceAsConvertibleURL(name);
if (file == null) {
assumeFalse("Cannot read grid data in a JAR file.",
"jar".equals(file.getProtocol()));
}
- return file.toURI();
+ return new GridFile(file.toURI());
}
}
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
index d24a15cac0..cf741ae2f2 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
@@ -25,6 +25,7 @@ import javax.measure.quantity.Length;
import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.referencing.operation.gridded.LoadedGrid;
import org.apache.sis.referencing.operation.gridded.CompressedGrid;
@@ -101,10 +102,10 @@ public final class FranceGeocentricInterpolationTest
extends DatumShiftTestCase
*/
@Test
public void testIsRecognized() throws URISyntaxException {
- assertTrue (FranceGeocentricInterpolation.isRecognized(new
URI("GR3DF97A.txt")));
- assertTrue (FranceGeocentricInterpolation.isRecognized(new
URI("gr3df")));
- assertFalse(FranceGeocentricInterpolation.isRecognized(new
URI("gr3d")));
- assertTrue (FranceGeocentricInterpolation.isRecognized(new
URI(TEST_FILE)));
+ assertTrue (FranceGeocentricInterpolation.isRecognized(new
GridFile(new URI("GR3DF97A.txt"))));
+ assertTrue (FranceGeocentricInterpolation.isRecognized(new
GridFile(new URI("gr3df"))));
+ assertFalse(FranceGeocentricInterpolation.isRecognized(new
GridFile(new URI("gr3d"))));
+ assertTrue (FranceGeocentricInterpolation.isRecognized(new
GridFile(new URI(TEST_FILE))));
}
/**
@@ -144,9 +145,9 @@ public final class FranceGeocentricInterpolationTest
extends DatumShiftTestCase
private static LoadedGrid<Angle,Length> testGridAsFloats()
throws URISyntaxException, IOException, FactoryException,
TransformException
{
- final URI file = getResource(TEST_FILE);
+ final GridFile file = getResource(TEST_FILE);
final LoadedGrid.Float<Angle,Length> grid;
- try (BufferedReader in =
FranceGeocentricInterpolation.Loader.newBufferedReader(file)) {
+ try (BufferedReader in = file.newBufferedReader()) {
grid = FranceGeocentricInterpolation.Loader.load(in, file);
}
assertEquals("cellPrecision", 0.005, grid.getCellPrecision(),
STRICT);
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
index 374aa14b37..e6179f07ee 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
@@ -25,8 +25,9 @@ import java.nio.file.Files;
import javax.measure.quantity.Angle;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.referencing.operation.gridded.GridLoader;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
import org.apache.sis.referencing.operation.matrix.Matrix3;
import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.geometry.Envelopes;
@@ -120,7 +121,7 @@ public final class NADCONTest extends DatumShiftTestCase {
* @param longitudeShifts path to the official {@code "conus.los"} file.
* @throws Exception if an error occurred while loading or computing the
grid, or while testing transformations.
*/
- public static void testNADCON(final URI latitudeShifts, final URI
longitudeShifts) throws Exception {
+ public static void testNADCON(final GridFile latitudeShifts, final
GridFile longitudeShifts) throws Exception {
testNADCON(latitudeShifts, longitudeShifts, -131, -63, 20, 50);
}
@@ -132,7 +133,7 @@ public final class NADCONTest extends DatumShiftTestCase {
* @param ymin southmost latitude.
* @param ymax northmost latitude.
*/
- private static void testNADCON(final URI latitudeShifts, final URI
longitudeShifts,
+ private static void testNADCON(final GridFile latitudeShifts, final
GridFile longitudeShifts,
final double xmin, final double xmax, final double ymin, final
double ymax)
throws Exception
{
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
index b28c08f035..0d803d1d5c 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
@@ -28,14 +28,16 @@ import java.nio.charset.StandardCharsets;
import javax.measure.quantity.Angle;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.util.Formulas;
+import org.apache.sis.referencing.operation.matrix.Matrix3;
+import org.apache.sis.referencing.operation.gridded.GridFile;
import org.apache.sis.referencing.operation.gridded.GridGroup;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
import static
org.apache.sis.referencing.operation.gridded.GridLoader.DEGREES_TO_SECONDS;
-import org.apache.sis.referencing.operation.matrix.Matrix3;
import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.geometry.Envelopes;
import org.apache.sis.measure.Units;
-import org.apache.sis.referencing.util.Formulas;
+import org.apache.sis.parameter.Parameters;
import org.apache.sis.system.DataDirectory;
// Test dependencies
@@ -109,7 +111,7 @@ public final class NTv2Test extends DatumShiftTestCase {
* @param file path to the official {@code "NTF_R93.gsb"} file.
* @throws Exception if an error occurred while loading or computing the
grid, or while testing transformations.
*/
- public static void testRGF93(final URI file) throws Exception {
+ public static void testRGF93(final GridFile file) throws Exception {
testRGF93(file, -19800, 36000, 147600, 187200);
}
@@ -121,7 +123,7 @@ public final class NTv2Test extends DatumShiftTestCase {
* @param ymin value of the {@code "S_LAT"} record.
* @param ymax value of the {@code "N_LAT"} record.
*/
- private static void testRGF93(final URI file, final double xmin, final
double xmax,
+ private static void testRGF93(final GridFile file, final double xmin,
final double xmax,
final double ymin, final double ymax) throws Exception
{
final double cellSize = 360;
@@ -188,8 +190,11 @@ public final class NTv2Test extends DatumShiftTestCase {
public void testMultiGrids() throws Exception {
assumeTrue(RUN_EXTENSIVE_TESTS);
assumeTrue(DataDirectory.getenv() != null);
- final URI file = DataDirectory.DATUM_CHANGES.toAbsolutePath(new
URI(MULTIGRID_TEST_FILE));
- assumeTrue(Files.exists(Path.of(file)));
+ final Parameters pg = Parameters.castOrWrap(new
NTv2().getParameters().createValue());
+ pg.getOrCreate(NTv2.FILE).setValue(new URI(MULTIGRID_TEST_FILE));
+ final GridFile file = new GridFile(pg, NTv2.FILE);
+ assumeTrue(Files.exists(Path.of(file.resolved())));
+
final LoadedGrid<Angle,Angle> grid = NTv2.getOrLoad(NTv2.class, file,
2);
assertInstanceOf("Should contain many grids.", GridGroup.class, grid);
assertEquals("coordinateUnit", Units.ARC_SECOND,
grid.getCoordinateUnit());
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/DatumShiftTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/DatumShiftTest.java
index e5d186752b..1fc24344a2 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/DatumShiftTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/DatumShiftTest.java
@@ -18,6 +18,7 @@ package org.apache.sis.test.integration;
import java.net.URI;
import org.apache.sis.system.DataDirectory;
+import org.apache.sis.referencing.operation.gridded.GridFile;
// Test dependencies
import org.junit.Test;
@@ -57,7 +58,7 @@ public final class DatumShiftTest extends TestCase {
@Test
public void testRGF93() throws Exception {
final URI file = assumeDataExists(DataDirectory.DATUM_CHANGES,
"ntf_r93.gsb");
- NTv2Test.testRGF93(file);
+ NTv2Test.testRGF93(new GridFile(file));
}
/**
@@ -70,6 +71,6 @@ public final class DatumShiftTest extends TestCase {
public void testNADCON() throws Exception {
final URI latitudeShifts =
assumeDataExists(DataDirectory.DATUM_CHANGES, "conus.las");
final URI longitudeShifts =
assumeDataExists(DataDirectory.DATUM_CHANGES, "conus.los");
- NADCONTest.testNADCON(latitudeShifts, longitudeShifts);
+ NADCONTest.testNADCON(new GridFile(latitudeShifts), new
GridFile(longitudeShifts));
}
}
diff --git
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java
index 81daa118a4..025851083c 100644
---
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java
+++
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java
@@ -21,12 +21,10 @@ import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.InvalidPathException;
-import java.nio.file.NoSuchFileException;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.internal.Strings;
-import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Messages;
@@ -238,7 +236,7 @@ public enum DataDirectory {
*
* @return the sub-directory, or {@code null} if unspecified.
*/
- private synchronized URI getDirectoryAsURI() {
+ public final synchronized URI getDirectoryAsURI() {
if (directoryAsURI == null) {
@SuppressWarnings("LocalVariableHidesMemberVariable")
final Path directory = getDirectory();
@@ -252,36 +250,4 @@ public enum DataDirectory {
}
return directoryAsURI;
}
-
- /**
- * Returns the given URI as an absolute URI, resolved with this {@code
DataDirectory} if the URI is relative.
- * If the URI cannot be made absolute, a {@link NoSuchFileException} is
thrown. This is necessary for letting
- * the caller know that a coordinate operation is probably valid but
cannot be constructed because an optional
- * configuration is missing. It is typically because the {@code SIS_DATA}
environment variable has not been set.
- *
- * @param path the URI to make absolute.
- * @return an absolute URI to the data.
- * @throws NoSuchFileException if the path cannot be made absolute.
- */
- public final URI toAbsolutePath(URI path) throws NoSuchFileException {
- final URI base = getDirectoryAsURI();
- if (base != null) {
- path = base.resolve(path);
- }
- if (path.isAbsolute()) {
- return path;
- }
- final String message;
- if (path.isOpaque()) {
- message = Errors.format(Errors.Keys.CanNotOpen_1, path);
- } else {
- final String env = getenv();
- if (env == null) {
- message =
Messages.format(Messages.Keys.DataDirectoryNotSpecified_1, ENV);
- } else {
- message =
Messages.format(Messages.Keys.DataDirectoryNotAccessible_2, ENV, env);
- }
- }
- throw new NoSuchFileException(path.toString(), null, message);
- }
}