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 f0226ebfbef6b42b5df9dff4355a59d9ce2939ef Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sun Apr 24 12:24:26 2022 +0200 Javadoc fixes and minor API adjustments in preparation for addition of BIL/BIP/BSQ reader. --- .../internal/coverage/j2d/ColorModelFactory.java | 1 + .../sis/metadata/iso/citation/DefaultContact.java | 2 +- .../main/java/org/apache/sis/util/ArraysExt.java | 20 +++++++++++++++++++- .../apache/sis/internal/storage/PRJDataStore.java | 20 +++++++++++++++++--- .../apache/sis/internal/storage/RangeArgument.java | 10 +++++----- .../sis/internal/storage/TiledGridResource.java | 2 +- .../apache/sis/internal/storage/URIDataStore.java | 4 +++- .../internal/storage/io/HyperRectangleReader.java | 22 ++++++++++------------ .../org/apache/sis/internal/storage/io/Region.java | 22 +++++++++++++++++----- 9 files changed, 74 insertions(+), 29 deletions(-) diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ColorModelFactory.java b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ColorModelFactory.java index 7b876fb8e1..c1f3093d4e 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ColorModelFactory.java +++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ColorModelFactory.java @@ -38,6 +38,7 @@ import org.apache.sis.util.collection.WeakHashSet; import org.apache.sis.util.collection.WeakValueHashMap; import org.apache.sis.util.Debug; + /** * A factory for {@link ColorModel} objects built from a sequence of colors. * diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java index 7dac0ae2a9..ea9dd8b2d1 100644 --- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java +++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java @@ -247,7 +247,7 @@ public class DefaultContact extends ISOMetadata implements Contact { } if (ignored != null) { /* - * Log a warning for ignored property using a call to 'ignored.toString()' instead of 'ignored' + * Log a warning for ignored property using a call to `ignored.toString()` instead of `ignored` * because we want the property to appear as "TelephoneType[FOO]" instead of "FOO". */ Context.warningOccured(Context.current(), DefaultContact.class, "getPhone", diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java b/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java index 9382504538..33f083fd3c 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java +++ b/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java @@ -67,7 +67,7 @@ import java.lang.reflect.Array; * objects. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 1.1 + * @version 1.2 * * @see Arrays * @@ -2068,6 +2068,24 @@ public final class ArraysExt extends Static { return true; } + /** + * Returns {@code true} if all values in the specified array are equal to the specified value. + * + * @param array the array to check. + * @param value the expected value. + * @return {@code true} if all elements in the given array are equal to the given value. + * + * @since 1.2 + */ + public static boolean allEquals(final int[] array, final int value) { + for (int i=0; i<array.length; i++) { + if (array[i] != value) { + return false; + } + } + return true; + } + /** * Returns {@code true} if the specified array contains the specified value, ignoring case. * This method should be used only for very small arrays. diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java index fb29f70e0b..5b15f2c860 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/PRJDataStore.java @@ -28,6 +28,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.NoSuchFileException; import java.text.ParseException; +import java.text.ParsePosition; import java.util.Arrays; import java.util.Locale; import java.util.Optional; @@ -41,6 +42,7 @@ import org.apache.sis.storage.DataStore; import org.apache.sis.storage.DataStoreProvider; import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.DataStoreContentException; +import org.apache.sis.storage.DataStoreReferencingException; import org.apache.sis.storage.StorageConnector; import org.apache.sis.internal.storage.io.IOUtilities; import org.apache.sis.internal.storage.wkt.StoreFormat; @@ -142,19 +144,31 @@ public abstract class PRJDataStore extends URIDataStore { * @throws DataStoreException if an error occurred while reading the file. */ protected final void readPRJ() throws DataStoreException { + Exception cause = null; try { final String wkt = readAuxiliaryFile(PRJ, encoding).toString(); if (wkt != null) { final StoreFormat format = new StoreFormat(locale, timezone, null, listeners); format.setConvention(Convention.WKT1_COMMON_UNITS); // Ignored if the format is WKT 2. - crs = (CoordinateReferenceSystem) format.parseObject(wkt); - format.validate(crs); + final ParsePosition pos = new ParsePosition(0); + crs = (CoordinateReferenceSystem) format.parse(wkt, pos); + if (crs != null) { + /* + * Some characters may exist after the WKT definition. For example we sometime see the CRS + * defined twice: as a WKT on the first line, followed by key-value pairs on next lines. + * Current Apache SIS implementation ignores the characters after WKT. + */ + format.validate(crs); + return; + } } } catch (NoSuchFileException | FileNotFoundException e) { listeners.warning(Resources.format(Resources.Keys.CanNotReadAuxiliaryFile_1, PRJ), e); + return; } catch (IOException | ParseException | ClassCastException e) { - throw new DataStoreException(Resources.format(Resources.Keys.CanNotReadAuxiliaryFile_1, PRJ), e); + cause = e; } + throw new DataStoreReferencingException(Resources.format(Resources.Keys.CanNotReadAuxiliaryFile_1, PRJ), cause); } /** diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/RangeArgument.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/RangeArgument.java index 4e843306d2..c828e43cdd 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/RangeArgument.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/RangeArgument.java @@ -18,6 +18,7 @@ package org.apache.sis.internal.storage; import java.util.List; import java.util.Arrays; +import java.util.Optional; import java.awt.image.ColorModel; import java.awt.image.SampleModel; import java.awt.image.RasterFormatException; @@ -358,14 +359,13 @@ public final class RangeArgument { * Returns a color model for the bands specified by the user. * * @param colors the original color model with all bands. Can be {@code null}. - * @return the color model for a subset of bands, or {@code null} if the given color model was null. + * @return the color model for a subset of bands, or empty if the given color model was null. */ - public ColorModel select(final ColorModel colors) { + public Optional<ColorModel> select(final ColorModel colors) { if (colors == null || isIdentity()) { - return colors; + return Optional.ofNullable(colors); } - return ColorModelFactory.createSubset(colors, getSelectedBands()) - .orElse(null); + return ColorModelFactory.createSubset(colors, getSelectedBands()); } /** diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridResource.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridResource.java index 7dcbc883c8..200f531923 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridResource.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridResource.java @@ -410,7 +410,7 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { this.ranges = bands; this.includedBands = includedBands; this.modelForBandSubset = rangeIndices.select(getSampleModel(), loadAllBands); - this.colorsForBandSubset = rangeIndices.select(getColorModel()); + this.colorsForBandSubset = rangeIndices.select(getColorModel()).orElse(null); this.fillValue = getFillValue(); /* * All `TiledGridCoverage` instances can share the same cache if they read all tiles fully. diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java index 62bb5e09e9..ecd27b3e68 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/URIDataStore.java @@ -141,8 +141,10 @@ public abstract class URIDataStore extends DataStore implements StoreResource, R * If the location was specified as a {@link Path} or {@link File} instance, returns that path. * Otherwise returns {@code null}. This method does not try to convert URI to {@link Path} * because this conversion may fail for HTTP and FTP connections. + * + * @return the path specified at construction time, or {@code null} if the storage was not specified as a path. */ - final Path getSpecifiedPath() { + protected final Path getSpecifiedPath() { return locationIsPath ? locationAsPath : null; } diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/HyperRectangleReader.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/HyperRectangleReader.java index 122336cb50..5eb18cc774 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/HyperRectangleReader.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/HyperRectangleReader.java @@ -46,7 +46,7 @@ import org.apache.sis.storage.DataStoreContentException; * @since 0.7 * @module */ -public final class HyperRectangleReader { +public class HyperRectangleReader { /** * The channel from which to read the values, together with a buffer for transferring data. */ @@ -61,15 +61,13 @@ public final class HyperRectangleReader { private long origin; /** - * Creates a new reader for the given input and source region. + * Creates a new reader for the given input. * * @param dataType the type of elements to read, as one of the constants defined in {@link Numbers}. * @param input the channel from which to read the values, together with a buffer for transferring data. * @throws DataStoreContentException if the given {@code dataType} is not one of the supported values. */ - public HyperRectangleReader(final byte dataType, final ChannelDataInput input) - throws DataStoreContentException - { + public HyperRectangleReader(final byte dataType, final ChannelDataInput input) throws DataStoreContentException { switch (dataType) { case Numbers.BYTE: reader = input.new BytesReader ( null); break; case Numbers.CHARACTER: reader = input.new CharsReader ((char[]) null); break; @@ -108,7 +106,7 @@ public final class HyperRectangleReader { * * @return the file identifier. */ - public String filename() { + public final String filename() { return reader.filename(); } @@ -123,11 +121,11 @@ public final class HyperRectangleReader { /** * Returns the {@code input} position of the first sample (ignoring sub-area and subsampling). - * This is initially the {@code origin} argument given to the constructor, copied verbatim. + * Default value is 0. * * @return the {@code input} position of the first sample (ignoring sub-area and subsampling). */ - public long getOrigin() { + public final long getOrigin() { return origin; } @@ -136,7 +134,7 @@ public final class HyperRectangleReader { * * @param p the new {@code input} position of the first sample (ignoring sub-area and subsampling). */ - public void setOrigin(final long p) { + public final void setOrigin(final long p) { origin = p; } @@ -149,14 +147,14 @@ public final class HyperRectangleReader { * @throws IOException if an error occurred while transferring data from the channel. * @throws ArithmeticException if the region to read is too large or too far from origin. */ - public Object read(final Region region) throws IOException { + public final Object read(final Region region) throws IOException { return read(region, 0, false); } /** * Reads data in the given region as a buffer. This method performs the same work * than {@link #read(Region)} except that the array is wrapped in a heap buffer. - * The {@code length} parameter is the minimal length of the array to allocate. + * The {@code capacity} argument is the minimal length of the array to allocate. * The actual length of data read will be the {@linkplain Buffer#limit() limit} * of the returned buffer. * @@ -166,7 +164,7 @@ public final class HyperRectangleReader { * @throws IOException if an error occurred while transferring data from the channel. * @throws ArithmeticException if the region to read is too large or too far from origin. */ - public Buffer readAsBuffer(final Region region, final int capacity) throws IOException { + public final Buffer readAsBuffer(final Region region, final int capacity) throws IOException { return (Buffer) read(region, capacity, true); } diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/Region.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/Region.java index 05230d51d9..8944f908c6 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/Region.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/Region.java @@ -19,7 +19,9 @@ package org.apache.sis.internal.storage.io; import org.apache.sis.io.TableAppender; import static java.lang.Math.addExact; +import static java.lang.Math.subtractExact; import static java.lang.Math.multiplyExact; +import static java.lang.Math.incrementExact; import static java.lang.Math.toIntExact; import static org.apache.sis.internal.util.Numerics.ceilDiv; @@ -39,7 +41,7 @@ import static org.apache.sis.internal.util.Numerics.ceilDiv; * * @author Johann Sorel (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.2 * @since 0.7 * @module */ @@ -99,8 +101,8 @@ public final class Region { * </ul> * * @param size the number of elements along each dimension. - * @param regionLower index of the first value to read or write along each dimension. - * @param regionUpper index after the last value to read or write along each dimension. + * @param regionLower indices of the first value to read or write along each dimension. + * @param regionUpper indices after the last value to read or write along each dimension. * @param subsampling subsampling along each dimension. Shall be greater than zero. * @throws ArithmeticException if the size of the region to read exceeds {@link Integer#MAX_VALUE}, * or the total hyper-cube size exceeds {@link Long#MAX_VALUE}. @@ -115,8 +117,8 @@ public final class Region { for (int i=0; i<dimension;) { final int step = subsampling[i]; final long lower = regionLower[i]; - final long count = ceilDiv(regionUpper[i] - lower, step); - final long upper = lower + ((count-1) * step + 1); + final long count = ceilDiv(subtractExact(regionUpper[i], lower), step); + final long upper = addExact(lower, incrementExact(multiplyExact(count-1, step))); final long span = size[i]; assert (count > 0) && (lower >= 0) && (upper > lower) && (upper <= span) : i; @@ -234,6 +236,16 @@ public final class Region { return toIntExact(size); } + /** + * Returns the size after reading only the sub-region at the given subsampling in the given dimension. + * + * @param dimension the dimension for which to get the target size. + * @return expected number of elements in the given dimension. + */ + public final int getTargetSize(final int dimension) { + return targetSize[dimension]; + } + /** * Returns a string representation of this region for debugging purpose. *