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 <[email protected]> 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
