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 2019/12/26 17:36:03 UTC
[sis] 01/03: GridCoverage2D.toString() provides some information
about the image (origin, tile size, data type, whether the image is opaque).
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 0f3ada707eed5ea3d188237f5c035a8603e80900
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Thu Dec 26 16:14:26 2019 +0100
GridCoverage2D.toString() provides some information about the image (origin, tile size, data type, whether the image is opaque).
---
.../org/apache/sis/coverage/grid/GridCoverage.java | 14 +++++
.../apache/sis/coverage/grid/GridCoverage2D.java | 64 ++++++++++++++++++++++
.../coverage/j2d/AbstractRenderedImage.java | 2 +-
.../sis/internal/coverage/j2d/ImageUtilities.java | 42 ++++++++++++--
.../org/apache/sis/internal/feature/Resources.java | 15 +++++
.../sis/internal/feature/Resources.properties | 3 +
.../sis/internal/feature/Resources_fr.properties | 3 +
.../internal/coverage/j2d/ImageUtilitiesTest.java | 20 ++++---
.../sis/util/resources/IndexedResourceBundle.java | 5 ++
.../org/apache/sis/util/resources/Vocabulary.java | 20 +++++++
.../sis/util/resources/Vocabulary.properties | 4 ++
.../sis/util/resources/Vocabulary_fr.properties | 4 ++
12 files changed, 182 insertions(+), 14 deletions(-)
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java
index bb9d7f1..d61d454 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java
@@ -380,9 +380,23 @@ public abstract class GridCoverage {
TreeTable.Node branch = root.newChild();
branch.setValue(column, vocabulary.getString(Vocabulary.Keys.CoverageDomain));
gridGeometry.formatTo(locale, vocabulary, bitmask, branch);
+ appendDataLayout(root, vocabulary, column);
branch = root.newChild();
branch.setValue(column, vocabulary.getString(Vocabulary.Keys.SampleDimensions));
branch.newChild().setValue(column, SampleDimension.toString(locale, sampleDimensions));
return tree;
}
+
+ /**
+ * Appends a "data layout" branch (if it exists) to the tree representation of this coverage.
+ * That branch will be inserted between "coverage domain" and "sample dimensions" branches.
+ * The default implementation does nothing.
+ *
+ * @param root root of the tree where to add a branch.
+ * @param vocabulary localized resources for vocabulary.
+ * @param column the single column where to write texts.
+ */
+ @Debug
+ void appendDataLayout(TreeTable.Node root, Vocabulary vocabulary, TableColumn<CharSequence> column) {
+ }
}
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 629d5b1..0eac980 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
@@ -19,6 +19,10 @@ package org.apache.sis.coverage.grid;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.text.NumberFormat;
+import java.text.FieldPosition;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
@@ -37,10 +41,13 @@ import org.apache.sis.internal.coverage.j2d.ConvertedGridCoverage;
import org.apache.sis.internal.coverage.j2d.TranslatedRenderedImage;
import org.apache.sis.internal.feature.Resources;
import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.util.collection.TableColumn;
+import org.apache.sis.util.collection.TreeTable;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.Workaround;
+import org.apache.sis.util.Debug;
// Branch-specific imports
import org.opengis.coverage.CannotEvaluateException;
@@ -513,4 +520,61 @@ public class GridCoverage2D extends GridCoverage {
throw new CannotEvaluateException(e.getMessage(), e);
}
}
+
+ /**
+ * Appends a "data layout" branch (if it exists) to the tree representation of this coverage.
+ * That branch will be inserted between "coverage domain" and "sample dimensions" branches.
+ *
+ * @param root root of the tree where to add a branch.
+ * @param vocabulary localized resources for vocabulary.
+ * @param column the single column where to write texts.
+ */
+ @Debug
+ @Override
+ void appendDataLayout(final TreeTable.Node root, final Vocabulary vocabulary, final TableColumn<CharSequence> column) {
+ final TreeTable.Node branch = root.newChild();
+ branch.setValue(column, vocabulary.getString(Vocabulary.Keys.ImageLayout));
+ final NumberFormat nf = NumberFormat.getIntegerInstance(vocabulary.getLocale());
+ final FieldPosition pos = new FieldPosition(0);
+ final StringBuffer buffer = new StringBuffer();
+write: for (int item=0; ; item++) try {
+ switch (item) {
+ case 0: {
+ vocabulary.appendLabel(Vocabulary.Keys.Origin, buffer);
+ nf.format(data.getMinX(), buffer.append(' '), pos);
+ nf.format(data.getMinY(), buffer.append(", "), pos);
+ break;
+ }
+ case 1: {
+ final int tx = data.getTileWidth();
+ final int ty = data.getTileHeight();
+ if (tx == data.getWidth() && ty == data.getHeight()) continue;
+ vocabulary.appendLabel(Vocabulary.Keys.TileSize, buffer);
+ nf.format(tx, buffer.append( ' ' ), pos);
+ nf.format(ty, buffer.append(" × "), pos);
+ break;
+ }
+ case 2: {
+ final String type = ImageUtilities.getDataTypeName(data.getSampleModel());
+ if (type == null) continue;
+ vocabulary.appendLabel(Vocabulary.Keys.DataType, buffer);
+ buffer.append(' ').append(type);
+ break;
+ }
+ case 3: {
+ final short t = ImageUtilities.getTransparencyDescription(data.getColorModel());
+ if (t != 0) {
+ final String desc = Resources.forLocale(vocabulary.getLocale()).getString(t);
+ branch.newChild().setValue(column, desc);
+ }
+ continue;
+ }
+ default: break write;
+ }
+ branch.newChild().setValue(column, buffer.toString());
+ buffer.setLength(0);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e); // Should never happen since we are writing to StringBuilder.
+ }
+ }
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/AbstractRenderedImage.java b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/AbstractRenderedImage.java
index 2decb87..2a067aa 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/AbstractRenderedImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/AbstractRenderedImage.java
@@ -295,7 +295,7 @@ public abstract class AbstractRenderedImage implements RenderedImage {
final SampleModel sm = getSampleModel();
if (sm != null) {
buffer.append(" × ").append(sm.getNumBands()).append(" bands");
- final String type = ImageUtilities.dataTypeName(sm.getDataType());
+ final String type = ImageUtilities.getDataTypeName(sm);
if (type != null) {
buffer.append(" of type ").append(type);
}
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 afad309..6289f3b 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
@@ -28,6 +28,7 @@ import java.awt.image.RenderedImage;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
+import org.apache.sis.internal.feature.Resources;
import org.apache.sis.internal.system.Modules;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Vocabulary;
@@ -111,13 +112,46 @@ public final class ImageUtilities {
}
/**
- * Returns the name of a {@link DataBuffer} type.
+ * Returns the name of the {@link DataBuffer} type used by the given sample model.
*
- * @param type one of {@link DataBuffer} constants.
+ * @param sm the sample model for which to get the data type name, or {@code null}.
* @return name of the given constant, or {@code null} if unknown.
*/
- public static String dataTypeName(final int type) {
- return (type >= 0 && type < TYPE_NAMES.length) ? TYPE_NAMES[type] : null;
+ public static String getDataTypeName(final SampleModel sm) {
+ if (sm != null) {
+ final int type = sm.getDataType();
+ if (type >= 0 && type < TYPE_NAMES.length) {
+ return TYPE_NAMES[type];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the key of a localizable text that describes the transparency.
+ * This method returns one of the following values:
+ * <ul>
+ * <li>{@link Resources.Keys#ImageAllowsTransparency}</li>
+ * <li>{@link Resources.Keys#ImageHasAlphaChannel}</li>
+ * <li>{@link Resources.Keys#ImageIsOpaque}</li>
+ * <li>0 if the transparency is unknown.</li>
+ * </ul>
+ *
+ * @param cm the color model from which to get the transparency, or {@code null}.
+ * @return a {@link Resources.Keys} value for the transparency, or 0 if unknown.
+ */
+ public static short getTransparencyDescription(final ColorModel cm) {
+ if (cm != null) {
+ if (cm.hasAlpha()) {
+ return Resources.Keys.ImageHasAlphaChannel;
+ }
+ switch (cm.getTransparency()) {
+ case ColorModel.TRANSLUCENT:
+ case ColorModel.BITMASK: return Resources.Keys.ImageAllowsTransparency;
+ case ColorModel.OPAQUE: return Resources.Keys.ImageIsOpaque;
+ }
+ }
+ return 0;
}
/**
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
index 195583c..6c2a399 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
@@ -184,6 +184,21 @@ public final class Resources extends IndexedResourceBundle {
public static final short IllegalTransferFunction_1 = 34;
/**
+ * Image allows transparency.
+ */
+ public static final short ImageAllowsTransparency = 63;
+
+ /**
+ * Image has alpha channel.
+ */
+ public static final short ImageHasAlphaChannel = 64;
+
+ /**
+ * Image is opaque.
+ */
+ public static final short ImageIsOpaque = 65;
+
+ /**
* The ({0}, {1}) tile has an unexpected size, number of bands or sample layout.
*/
public static final short IncompatibleTile_2 = 35;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
index e950146..2355891 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
@@ -43,6 +43,9 @@ IllegalGridGeometryComponent_1 = Can not create a grid geometry with the give
IllegalPropertyType_2 = Type or result of \u201c{0}\u201d property can not be \u2018{1}\u2019 for this operation.
IllegalPropertyValueClass_3 = Property \u201c{0}\u201d does not accept values of type \u2018{2}\u2019. Expected an instance of \u2018{1}\u2019 or derived type.
IllegalTransferFunction_1 = Illegal transfer function for \u201c{0}\u201d category.
+ImageAllowsTransparency = Image allows transparency.
+ImageHasAlphaChannel = Image has alpha channel.
+ImageIsOpaque = Image is opaque.
IncompatibleTile_2 = The ({0}, {1}) tile has an unexpected size, number of bands or sample layout.
InvalidExpression_2 = Invalid or unsupported \u201c{1}\u201d expression at index {0}.
IterationIsFinished = Iteration is finished.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
index 1b0618b..bd333d7 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
@@ -48,6 +48,9 @@ IllegalGridGeometryComponent_1 = Ne peut pas construire une g\u00e9om\u00e9tr
IllegalPropertyType_2 = Le type ou le r\u00e9sultat de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb ne peut pas \u00eatre \u2018{1}\u2019 pour cette op\u00e9ration.
IllegalPropertyValueClass_3 = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019accepte pas les valeurs de type \u2018{2}\u2019. Une instance de \u2018{1}\u2019 ou d\u2019un type d\u00e9riv\u00e9 \u00e9tait attendue.
IllegalTransferFunction_1 = Fonction de transfert ill\u00e9gale pour la cat\u00e9gorie \u00ab\u202f{0}\u202f\u00bb.
+ImageAllowsTransparency = L\u2019image permet la transparence.
+ImageHasAlphaChannel = L\u2019image a un canal alpha.
+ImageIsOpaque = L\u2019image est opaque.
IncompatibleTile_2 = La tuile ({0}, {1}) a une taille, un nombre de bandes ou une disposition des valeurs inattendu.
InvalidExpression_2 = Expression \u00ab\u202f{1}\u202f\u00bb invalide ou non-support\u00e9e \u00e0 l\u2019index {0}.
IterationIsFinished = L\u2019it\u00e9ration est termin\u00e9e.
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 71693be..8d5f3e1 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
@@ -17,9 +17,11 @@
package org.apache.sis.internal.coverage.j2d;
import java.awt.image.ColorModel;
-import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.RenderedImage;
+import java.awt.image.BufferedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.BandedSampleModel;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -37,16 +39,16 @@ import static org.junit.Assert.*;
*/
public final strictfp class ImageUtilitiesTest extends TestCase {
/**
- * Tests {@link ImageUtilities#dataTypeName(int)}.
+ * Tests {@link ImageUtilities#getDataTypeName(SampleModel)}.
*/
@Test
- public void testDataTypeName() {
- assertEquals("byte", ImageUtilities.dataTypeName(DataBuffer.TYPE_BYTE));
- assertEquals("short", ImageUtilities.dataTypeName(DataBuffer.TYPE_SHORT));
- assertEquals("ushort", ImageUtilities.dataTypeName(DataBuffer.TYPE_USHORT));
- assertEquals("int", ImageUtilities.dataTypeName(DataBuffer.TYPE_INT));
- assertEquals("float", ImageUtilities.dataTypeName(DataBuffer.TYPE_FLOAT));
- assertEquals("double", ImageUtilities.dataTypeName(DataBuffer.TYPE_DOUBLE));
+ public void testGetDataTypeName() {
+ assertEquals("byte", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_BYTE, 1, 1, 1)));
+ assertEquals("short", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_SHORT, 1, 1, 1)));
+ assertEquals("ushort", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_USHORT, 1, 1, 1)));
+ assertEquals("int", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_INT, 1, 1, 1)));
+ assertEquals("float", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_FLOAT, 1, 1, 1)));
+ assertEquals("double", ImageUtilities.getDataTypeName(new BandedSampleModel(DataBuffer.TYPE_DOUBLE, 1, 1, 1)));
}
/**
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
index fa3a6c7..7904b91 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
@@ -471,6 +471,11 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
* Writes the localized string identified by the given key followed by a colon.
* The way to write the colon depends on the language.
*
+ * <div class="note"><b>API note:</b>
+ * we do not provide a method with {@link StringBuilder} argument and without {@link IOException} clause
+ * because it is not needed by Apache SIS in practice. We found that codes invoking this method with a
+ * {@link StringBuilder} happen in contexts where an {@link IOException} is thrown elsewhere anyway.</div>
+ *
* @param key the key for the desired string.
* @param toAppendTo where to write the localized string followed by a colon.
* @throws IOException if an error occurred while writing to the given destination.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
index 214f330..8705377 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
@@ -257,6 +257,11 @@ public final class Vocabulary extends IndexedResourceBundle {
public static final short DataFormats = 36;
/**
+ * Data type
+ */
+ public static final short DataType = 185;
+
+ /**
* Datum
*/
public static final short Datum = 37;
@@ -457,6 +462,11 @@ public final class Vocabulary extends IndexedResourceBundle {
public static final short Identity = 74;
/**
+ * Image layout
+ */
+ public static final short ImageLayout = 186;
+
+ /**
* Implementation
*/
public static final short Implementation = 75;
@@ -682,6 +692,11 @@ public final class Vocabulary extends IndexedResourceBundle {
public static final short Options = 118;
/**
+ * Origin
+ */
+ public static final short Origin = 188;
+
+ /**
* Origin in a cell center
*/
public static final short OriginInCellCenter = 119;
@@ -837,6 +852,11 @@ public final class Vocabulary extends IndexedResourceBundle {
public static final short TemporaryFiles = 147;
/**
+ * Tile size
+ */
+ public static final short TileSize = 187;
+
+ /**
* Time
*/
public static final short Time = 148;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
index 3f8be4d..aecdb5b 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
@@ -54,6 +54,7 @@ Cyan = Cyan
DataBase = Database
DataDirectory = Data directory
DataFormats = Data formats
+DataType = Data type
Datum = Datum
DatumShift = Datum shift
DaylightTime = Daylight time
@@ -93,6 +94,7 @@ Green = Green
GridExtent = Grid extent
Height = Height
Identifier = Identifier
+ImageLayout = Image layout
Implementation = Implementation
InBetweenWords = \u2002in\u2002
Identity = Identity
@@ -139,6 +141,7 @@ OperatingSystem = Operating system
Operations = Operations
Optional = Optional
Options = Options
+Origin = Origin
OriginInCellCenter = Origin in a cell center
Others = Others
OtherSurface = Other surface
@@ -170,6 +173,7 @@ SupersededBy_1 = Superseded by {0}.
TemporaryFiles = Temporary files
Temporal = Temporal
TemporalExtent = Temporal extent
+TileSize = Tile size
Time = Time
Time_1 = {0} time
Timezone = Timezone
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
index 44a736f..0276620 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
@@ -61,6 +61,7 @@ CycleOmitted = Cycle omit
DataBase = Base de donn\u00e9es
DataDirectory = R\u00e9pertoire des donn\u00e9es
DataFormats = Formats de donn\u00e9es
+DataType = Type de donn\u00e9es
Datum = R\u00e9f\u00e9rentiel
DatumShift = Changement de r\u00e9f\u00e9rentiel
DaylightTime = Heure normale
@@ -100,6 +101,7 @@ Green = Vert
GridExtent = \u00c9tendue de la grille
Height = Hauteur
Identifier = Identifiant
+ImageLayout = Agencement de l\u2019image
Implementation = Impl\u00e9mentation
InBetweenWords = \u2002dans\u2002
Identity = Identit\u00e9
@@ -146,6 +148,7 @@ OperatingSystem = Syst\u00e8me d\u2019exploitation
Operations = Op\u00e9rations
Optional = Optionnel
Options = Options
+Origin = Origine
OriginInCellCenter = Origine au centre d\u2019une cellule
Others = Autres
OtherSurface = Autre surface
@@ -177,6 +180,7 @@ SupersededBy_1 = Remplac\u00e9 par {0}.
TemporaryFiles = Fichiers temporaires
Temporal = Temporel
TemporalExtent = Plage temporelle
+TileSize = Taille des tuiles
Time = Temps
Time_1 = Heure {0}
Timezone = Fuseau horaire