Skip to content

Commit

Permalink
Expose PAM dataset and raster attribute table from internal represent…
Browse files Browse the repository at this point in the history
…ation, rather than external file
  • Loading branch information
aaime committed Oct 18, 2023
1 parent ecbce7b commit 970b149
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,27 @@
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;

import it.geosolutions.imageio.pam.PAMDataset;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.FieldDefn;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.FieldType;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.GDALRasterAttributeTable;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.Histograms;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.Histograms.HistItem;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.Metadata;
import it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.Row;
import org.gdal.gdal.Band;
import org.gdal.gdal.ColorTable;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.InfoOptions;
import org.gdal.gdal.RasterAttributeTable;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconst;
import org.gdal.gdalconst.gdalconstConstants;
import org.w3c.dom.Node;

import static it.geosolutions.imageio.pam.PAMDataset.PAMRasterBand.FieldUsage.fromValue;

/**
* Class needed to store all available information of a GDAL Dataset with the
* add of additional information. For convenience and future re-use this class
Expand All @@ -68,6 +80,7 @@ public class GDALCommonIIOImageMetadata extends CoreCommonImageMetadata {
* domain, the ImageStructure domain, as well as any xml prefixed domain)
*/
Map<String, Map<String, String>> gdalDomainMetadataMap;
private PAMDataset pamDataSet;

/**
* <code>GDALCommonIIOImageMetadata</code> constructor. Firstly, it
Expand Down Expand Up @@ -248,6 +261,79 @@ private void setGeoreferencingInfo(final Dataset dataset) {
setProjection(dataset.GetProjection());
setGcpProjection(dataset.GetGCPProjection());
setGcpNumber(dataset.GetGCPCount());
setPamDataset(dataset);
}
public PAMDataset getPamDataset() {
return pamDataSet;
}

/**
* Creates a PAMDataset object form internal metadata, rather than from an auxiliary xml file.
* @param dataset
*/
private void setPamDataset(Dataset dataset) {
PAMDataset pd = new PAMDataset();

int bandCount = dataset.getRasterCount();
for (int b = 1; b <= bandCount; b++) {
Band band = dataset.GetRasterBand(b);
PAMDataset.PAMRasterBand pdBand = new PAMDataset.PAMRasterBand();
pdBand.setBand(b);
double min[] = new double[1];
double max[] = new double[1];
double mean[] = new double[1];
double stddev[] = new double[1];
// grab stats if available, but don't force creation
if (band.GetStatistics(false, false, min, max, mean, stddev) != gdalconstConstants.CE_None) {
Metadata metadata = new Metadata();
List<Metadata.MDI> mdis = metadata.getMDI();
mdis.add(createMDI("STATISTICS_MINIMUM", min[0]));
mdis.add(createMDI("STATISTICS_MAXIMUM", max[0]));
mdis.add(createMDI("STATISTICS_MEAN", mean[0]));
mdis.add(createMDI("STATISTICS_STDDEV", stddev[0]));
pdBand.setMetadata(metadata);
}
setupRasterAttributeTable(band, pdBand);
band.delete();
pd.getPAMRasterBand().add(pdBand);
}
this.pamDataSet = pd;
}

private static void setupRasterAttributeTable(Band band, PAMDataset.PAMRasterBand pdBand) {
RasterAttributeTable rat = band.GetDefaultRAT();
if (rat != null) {
GDALRasterAttributeTable pdRAT = new GDALRasterAttributeTable();
List<FieldDefn> fields = pdRAT.getFieldDefn();
int columns = rat.GetColumnCount();
for (int i = 0; i < columns; i++) {
FieldDefn field = new FieldDefn();
field.setIndex(i);
field.setName(rat.GetNameOfCol(i));
field.setType(FieldType.fromValue(rat.GetTypeOfCol(i)));
field.setUsage(fromValue(rat.GetUsageOfCol(i)));
fields.add(field);
}
List<Row> pdRows = pdRAT.getRow();
int rows = rat.GetRowCount();
for (int r = 0; r < rows; r++) {
Row row = new Row();
List<String> values = row.getF();
for (int c = 0; c < columns; c++) {
values.add(rat.GetValueAsString(r, c));
}
pdRows.add(row);
}
pdBand.setGdalRasterAttributeTable(pdRAT);
rat.delete();
}
}

private Metadata.MDI createMDI(String key, Object value) {
Metadata.MDI mdi = new Metadata.MDI();
mdi.setKey(key);
mdi.setValue(String.valueOf(value));
return mdi;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* ImageI/O-Ext - OpenSource Java Image translation Library
* http://www.geo-solutions.it/
* https://github.com/geosolutions-it/imageio-ext
* (C) 2023, GeoSolutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* either version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package it.geosolutions.imageio.plugins.vrt;

import it.geosolutions.imageio.gdalframework.AbstractGDALTest;
import it.geosolutions.imageio.gdalframework.GDALCommonIIOImageMetadata;
import it.geosolutions.imageio.gdalframework.Viewer;
import it.geosolutions.imageio.pam.PAMDataset;
import it.geosolutions.imageio.utilities.ImageIOUtilities;
import it.geosolutions.resources.TestData;
import org.junit.Assert;
import org.junit.Test;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.RenderedOp;
import java.awt.Rectangle;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* Test reading RasterAttributeTable embedded inside VRT file
*/
public class RasterAttributeTableTest extends AbstractGDALTest {
public RasterAttributeTableTest() {
super();
}


@Test
public void readImageIO() throws FileNotFoundException, IOException {
if (!isGDALAvailable) {
return;
}
final File file = TestData.file(this, "095b_dem_90m.asc.vrt");


final Iterator<ImageReader> it = ImageIO.getImageReaders(file);
assertTrue(it.hasNext());
final ImageReader reader = (ImageReader) it.next();
assertTrue(reader instanceof VRTImageReader);
reader.setInput(file);

IIOMetadata genericMeta = reader.getImageMetadata(0);
assertTrue(genericMeta instanceof GDALCommonIIOImageMetadata);

GDALCommonIIOImageMetadata gdalMeta = (GDALCommonIIOImageMetadata) genericMeta;

PAMDataset pam = gdalMeta.getPamDataset();
assertNotNull(pam);

PAMDataset.PAMRasterBand band = pam.getPAMRasterBand().get(0);
PAMDataset.PAMRasterBand.GDALRasterAttributeTable rat = band.getGdalRasterAttributeTable();
assertNotNull(rat);

// Check each field
List<PAMDataset.PAMRasterBand.FieldDefn> fields = rat.getFieldDefn();
assertEquals(3, fields.size());
assertField(fields.get(0), "con_min", PAMDataset.PAMRasterBand.FieldType.Real,
PAMDataset.PAMRasterBand.FieldUsage.Min);
assertField(fields.get(1), "con_max", PAMDataset.PAMRasterBand.FieldType.Real,
PAMDataset.PAMRasterBand.FieldUsage.Max);
assertField(fields.get(2), "test", PAMDataset.PAMRasterBand.FieldType.String,
PAMDataset.PAMRasterBand.FieldUsage.Generic);

// Check rows
List<PAMDataset.PAMRasterBand.Row> rows = rat.getRow();
assertEquals(8, rows.size());

// one sample row
PAMDataset.PAMRasterBand.Row row = rows.get(1);
List<String> fieldValues = row.getF();
assertEquals("1.4", fieldValues.get(0));
assertEquals("1.6", fieldValues.get(1));
assertEquals("white", fieldValues.get(2));

reader.dispose();
}


private void assertField(PAMDataset.PAMRasterBand.FieldDefn fieldDefn, String name,
PAMDataset.PAMRasterBand.FieldType type,
PAMDataset.PAMRasterBand.FieldUsage usage) {
assertEquals(name, fieldDefn.getName());
assertEquals(type, fieldDefn.getType());
assertEquals(usage, fieldDefn.getUsage());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,62 @@
<SrcRect xOff="0" yOff="0" xSize="351" ySize="350" />
<DstRect xOff="0" yOff="0" xSize="351" ySize="350" />
</SimpleSource>
<GDALRasterAttributeTable tableType="thematic">
<FieldDefn index="0">
<Name>con_min</Name>
<Type>1</Type>
<Usage>3</Usage>
</FieldDefn>
<FieldDefn index="1">
<Name>con_max</Name>
<Type>1</Type>
<Usage>4</Usage>
</FieldDefn>
<FieldDefn index="2">
<Name>test</Name>
<Type>2</Type>
<Usage>0</Usage>
</FieldDefn>
<Row index="0">
<F>1.000000023841858</F>
<F>1.200000023841858</F>
<F>green</F>
</Row>
<Row index="1">
<F>1.4</F>
<F>1.6</F>
<F>white</F>
</Row>
<Row index="2">
<F>2.4</F>
<F>2.6</F>
<F>gold</F>
</Row>
<Row index="3">
<F>5.099999809265137</F>
<F>5.299999809265136</F>
<F>blue</F>
</Row>
<Row index="4">
<F>7.200000190734864</F>
<F>7.400000190734863</F>
<F>red</F>
</Row>
<Row index="5">
<F>9.000000381469727</F>
<F>9.200000381469726</F>
<F>orange</F>
</Row>
<Row index="6">
<F>11.00000038146973</F>
<F>11.20000038146973</F>
<F>black</F>
</Row>
<Row index="7">
<F>12.09999980926514</F>
<F>12.29999980926514</F>
<F>purple</F>
</Row>
</GDALRasterAttributeTable>
</VRTRasterBand>
</VRTDataset>

0 comments on commit 970b149

Please sign in to comment.