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 8b4bd320fc Provide more metadata and better names for bands.
8b4bd320fc is described below
commit 8b4bd320fc7016b122d7a2ff98b0d789a8200b61
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Apr 18 21:12:39 2022 +0200
Provide more metadata and better names for bands.
---
.../apache/sis/coverage/grid/GridCoverage2D.java | 7 ++++-
.../sis/internal/coverage/j2d/ImageUtilities.java | 17 ++++-------
.../internal/coverage/j2d/ImageUtilitiesTest.java | 8 +++---
.../apache/sis/internal/storage/image/Image.java | 13 ++++++++-
.../apache/sis/internal/storage/image/Store.java | 7 +++++
.../sis/internal/storage/image/StoreTest.java | 33 +++++++++++++++++++++-
6 files changed, 66 insertions(+), 19 deletions(-)
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
index 3eaf6856b5..aa80d6a0e8 100644
---
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
+++
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java
@@ -395,7 +395,12 @@ public class GridCoverage2D extends GridCoverage {
final RenderedImage
data, final int numBands)
{
if (range == null) {
- final short[] names = (data != null) ?
ImageUtilities.bandNames(data) : ArraysExt.EMPTY_SHORT;
+ final short[] names;
+ if (data != null) {
+ names = ImageUtilities.bandNames(data.getColorModel(),
data.getSampleModel());
+ } else {
+ names = ArraysExt.EMPTY_SHORT;
+ }
final SampleDimension[] sd = new SampleDimension[numBands];
final NameFactory factory =
DefaultFactories.forBuildin(NameFactory.class);
for (int i=0; i<numBands; i++) {
diff --git
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
index 200d66ae5f..e95631f54c 100644
---
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
+++
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/ImageUtilities.java
@@ -264,26 +264,19 @@ public final class ImageUtilities extends Static {
}
/**
- * Returns names of bands based on inspection of the color model.
+ * Returns names of bands based on inspection of the sample model and
color model.
* The bands are identified by {@link Vocabulary.Keys} values for
* red, green, blue, cyan, magenta, yellow, black, gray, <i>etc</i>.
* If a band can not be identified, then its corresponding value is 0.
*
- * @param image the image for which to get band names (can not be null).
+ * @param cm the color model for which to get band names, or {@code
null} if unknown.
+ * @param sm the image sample model (can not be null).
* @return {@link Vocabulary.Keys} identifying the bands.
*/
@SuppressWarnings("fallthrough")
- public static short[] bandNames(final RenderedImage image) {
- final SampleModel sm = image.getSampleModel();
- final int n;
- if (sm != null) {
- n = sm.getNumBands();
- } else {
- // Should not happen since SampleModel is essential, but we try to
be robust.
- n = image.getTile(image.getMinTileX(),
image.getMinTileY()).getNumBands();
- }
+ public static short[] bandNames(final ColorModel cm, final SampleModel sm)
{
+ final int n = sm.getNumBands();
final short[] keys = new short[n];
- final ColorModel cm = image.getColorModel();
if (cm instanceof IndexColorModel) {
/*
* IndexColorModel normally uses exactly one band. But SIS has a
custom subtype which
diff --git
a/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/ImageUtilitiesTest.java
b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/ImageUtilitiesTest.java
index 458903b19f..eaa094f507 100644
---
a/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/ImageUtilitiesTest.java
+++
b/core/sis-feature/src/test/java/org/apache/sis/internal/coverage/j2d/ImageUtilitiesTest.java
@@ -38,7 +38,7 @@ import static
org.apache.sis.internal.util.Numerics.COMPARISON_THRESHOLD;
* Tests {@link ImageUtilities}.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
* @since 1.1
* @module
*/
@@ -103,7 +103,7 @@ public final strictfp class ImageUtilitiesTest extends
TestCase {
}
/**
- * Verifies that {@link ImageUtilities#bandNames(RenderedImage)} returns
expected band names.
+ * Verifies that {@link ImageUtilities#bandNames(ColorModel, SampleModel)}
returns expected band names.
*
* @param nde expected number of data elements. This number
categorizes the tests in this class.
* @param type one of the {@link BufferedImage} {@code TYPE_*}
constants.
@@ -111,8 +111,9 @@ public final strictfp class ImageUtilitiesTest extends
TestCase {
*/
private static void assertBandNamesEqual(final int nde, final int type,
final short... names) {
final BufferedImage image = new BufferedImage(1, 1, type);
+ final ColorModel cm = image.getColorModel();
assertEquals("numDataElements", nde,
image.getSampleModel().getNumDataElements());
- assertArrayEquals("bandNames", names, ImageUtilities.bandNames(image));
+ assertArrayEquals("bandNames", names, ImageUtilities.bandNames(cm,
image.getSampleModel()));
/*
* The following is more for testing our understanding of the way
BufferedImage works.
* We want to verify that no matter which BufferedImage.TYPE_*
constant we used, values
@@ -120,7 +121,6 @@ public final strictfp class ImageUtilitiesTest extends
TestCase {
*/
image.getRaster().setPixel(0, 0, new int[] {10, 20, 30, 40}); //
Always RGBA order for this test.
final Object data = image.getRaster().getDataElements(0, 0, null);
- final ColorModel cm = image.getColorModel();
for (final short k : names) {
final int expected, actual;
switch (k) {
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Image.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Image.java
index c803dee70b..a212a1fe9e 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Image.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Image.java
@@ -26,6 +26,7 @@ import javax.imageio.ImageReader;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
import org.apache.sis.image.ImageProcessor;
import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.coverage.grid.GridCoverage;
@@ -40,7 +41,9 @@ import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.internal.storage.StoreResource;
import org.apache.sis.internal.storage.RangeArgument;
+import org.apache.sis.internal.coverage.j2d.ImageUtilities;
import org.apache.sis.internal.util.UnmodifiableArrayList;
+import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.iso.Names;
@@ -150,13 +153,21 @@ class Image extends AbstractGridCoverageResource
implements StoreResource {
final ImageTypeSpecifier type =
reader.getRawImageType(imageIndex);
final SampleDimension[] bands = new
SampleDimension[type.getNumBands()];
final SampleDimension.Builder b = new
SampleDimension.Builder();
+ final short[] names =
ImageUtilities.bandNames(type.getColorModel(), type.getSampleModel());
for (int i=0; i<bands.length; i++) {
/*
* TODO: we could consider a mechanism similar to
org.apache.sis.internal.geotiff.SchemaModifier
* if there is a need to customize the sample dimensions.
`SchemaModifier` could become a shared
* public interface.
*/
- bands[i] = b.setName(i + 1).build();
+ final InternationalString name;
+ final short k;
+ if (i < names.length && (k = names[i]) != 0) {
+ name = Vocabulary.formatInternational(k);
+ } else {
+ name =
Vocabulary.formatInternational(Vocabulary.Keys.Band_1, i+1);
+ }
+ bands[i] = b.setName(name).build();
b.clear();
}
sampleDimensions = UnmodifiableArrayList.wrap(bands);
diff --git
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
index a19b90927b..a3ff6092b8 100644
---
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
+++
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/image/Store.java
@@ -35,6 +35,7 @@ import javax.imageio.stream.ImageInputStream;
import org.opengis.metadata.Metadata;
import org.opengis.metadata.maintenance.ScopeCode;
import org.opengis.referencing.datum.PixelInCell;
+import org.opengis.referencing.operation.TransformException;
import org.apache.sis.coverage.grid.GridExtent;
import org.apache.sis.coverage.grid.GridGeometry;
import org.apache.sis.storage.Aggregate;
@@ -43,6 +44,7 @@ import org.apache.sis.storage.GridCoverageResource;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreClosedException;
import org.apache.sis.storage.DataStoreContentException;
+import org.apache.sis.storage.DataStoreReferencingException;
import org.apache.sis.storage.UnsupportedStorageException;
import org.apache.sis.internal.storage.Resources;
import org.apache.sis.internal.storage.PRJDataStore;
@@ -364,11 +366,16 @@ loop: for (int convention=0;; convention++) {
builder.addFormatName(format); // Does
nothing if `format` is null.
builder.addResourceScope(ScopeCode.COVERAGE, null);
builder.addSpatialRepresentation(null,
getGridGeometry(MAIN_IMAGE), true);
+ if (gridGeometry.isDefined(GridGeometry.ENVELOPE)) {
+ builder.addExtent(gridGeometry.getEnvelope());
+ }
addTitleOrIdentifier(builder);
builder.setISOStandards(false);
metadata = builder.buildAndFreeze();
} catch (IOException e) {
throw new DataStoreException(e);
+ } catch (TransformException e) {
+ throw new DataStoreReferencingException(e);
}
return metadata;
}
diff --git
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/StoreTest.java
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/StoreTest.java
index c23bfca33b..42feef4317 100644
---
a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/StoreTest.java
+++
b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/image/StoreTest.java
@@ -16,6 +16,10 @@
*/
package org.apache.sis.internal.storage.image;
+import java.io.IOException;
+import org.opengis.metadata.Metadata;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.metadata.identification.Identification;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.ProbeResult;
@@ -23,6 +27,7 @@ import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
+import static org.apache.sis.test.TestUtilities.getSingleton;
/**
@@ -54,5 +59,31 @@ public final strictfp class StoreTest extends TestCase {
assertEquals("image/png", r.getMimeType());
}
-
+ /**
+ * Tests the metadata of the {@code "gradient.png"} file.
+ *
+ * @throws DataStoreException if an error occurred while reading the file.
+ * @throws IOException if an error occurred while creating the image
reader instance.
+ */
+ @Test
+ public void testMetadata() throws DataStoreException, IOException {
+ try (Store store = new Store(null, testData())) {
+ assertEquals("gradient", store.getIdentifier().get().toString());
+ final Metadata metadata = store.getMetadata();
+ final Identification id =
getSingleton(metadata.getIdentificationInfo());
+ final String format =
getSingleton(id.getResourceFormats()).getFormatSpecificationCitation().getTitle().toString();
+ assertTrue(format, format.contains("PNG"));
+ assertEquals("WGS 84",
getSingleton(metadata.getReferenceSystemInfo()).getName().getCode());
+ final GeographicBoundingBox bbox = (GeographicBoundingBox)
+
getSingleton(getSingleton(id.getExtents()).getGeographicElements());
+ assertEquals( -90, bbox.getSouthBoundLatitude(), STRICT);
+ assertEquals( +90, bbox.getNorthBoundLatitude(), STRICT);
+ assertEquals(-180, bbox.getWestBoundLongitude(), STRICT);
+ assertEquals(+180, bbox.getEastBoundLongitude(), STRICT);
+ /*
+ * Verify that the metadata is cached.
+ */
+ assertSame(metadata, store.getMetadata());
+ }
+ }
}