This is an automated email from the ASF dual-hosted git repository.
jsorel 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 5364df70d4 Handle more divers structures in GIMI files
5364df70d4 is described below
commit 5364df70d40967b0511184daed56b53f7be18a36
Author: jsorel <[email protected]>
AuthorDate: Tue Oct 1 16:50:40 2024 +0200
Handle more divers structures in GIMI files
---
.../org/apache/sis/storage/gimi/GimiProvider.java | 2 +-
.../org/apache/sis/storage/gimi/GimiStore.java | 17 ++-
.../apache/sis/storage/gimi/GimiTileMatrix.java | 4 +-
.../org/apache/sis/storage/gimi/ResourceGrid.java | 64 +++++++---
.../storage/gimi/ResourceImageUncompressed.java | 134 ++++++++++++++++-----
.../apache/sis/storage/gimi/ResourcePyramid.java | 62 +++++++++-
.../sis/storage/gimi/internal/ScaleSortedMap.java | 2 +-
.../isobmff/gimi/ModelTransformationProperty.java | 9 ++
.../gimi/isobmff/gimi/WellKnownText2Property.java | 9 ++
.../gimi/isobmff/iso23001_17/TAIClockInfo.java | 4 +-
10 files changed, 250 insertions(+), 57 deletions(-)
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiProvider.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiProvider.java
index 3ec75d1fe1..239e08d1e5 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiProvider.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiProvider.java
@@ -90,7 +90,7 @@ public final class GimiProvider extends DataStoreProvider {
final Path path = connector.getStorageAs(Path.class);
if (path != null) {
final String name = path.getFileName().toString().toLowerCase();
- if (name.endsWith(".heij") || name.endsWith(".heif")) {
+ if (name.endsWith(".heij") || name.endsWith(".heif") ||
name.endsWith(".heic") || name.endsWith(".avif")) {
return new ProbeResult(true, MIME_TYPE, null);
}
}
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiStore.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiStore.java
index 74a6aa4039..5490c19cb4 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiStore.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiStore.java
@@ -27,12 +27,14 @@ import java.util.Optional;
import org.opengis.metadata.Metadata;
import org.opengis.parameter.ParameterValueGroup;
import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.Resource;
import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.base.MetadataBuilder;
import org.apache.sis.storage.gimi.isobmff.Box;
import org.apache.sis.storage.gimi.isobmff.ISOBMFFReader;
import org.apache.sis.storage.gimi.isobmff.iso14496_12.GroupList;
@@ -40,6 +42,7 @@ import
org.apache.sis.storage.gimi.isobmff.iso14496_12.ItemInfo;
import org.apache.sis.storage.gimi.isobmff.iso14496_12.ItemInfoEntry;
import org.apache.sis.storage.gimi.isobmff.iso14496_12.Meta;
import org.apache.sis.storage.gimi.isobmff.iso23008_12.ImagePyramidEntityGroup;
+import org.apache.sis.util.iso.Names;
/**
@@ -52,6 +55,7 @@ public final class GimiStore extends DataStore implements
Aggregate {
private List<Resource> components;
private Map<Integer,Resource> componentIndex;
+ private Metadata metadata;
//cache the reader
private ISOBMFFReader reader;
@@ -72,8 +76,13 @@ public final class GimiStore extends DataStore implements
Aggregate {
}
@Override
- public Metadata getMetadata() throws DataStoreException {
- throw new UnsupportedOperationException("Not supported yet.");
+ public synchronized Metadata getMetadata() throws DataStoreException {
+ if (metadata == null) {
+ final MetadataBuilder builder = new MetadataBuilder();
+ builder.addIdentifier(Names.createLocalName(null, null,
IOUtilities.filenameWithoutExtension(gimiPath.getFileName().toString())),
MetadataBuilder.Scope.ALL);
+ metadata = builder.buildAndFreeze();
+ }
+ return metadata;
}
@Override
@@ -154,6 +163,10 @@ public final class GimiStore extends DataStore implements
Aggregate {
final ResourcePyramid pyramid = new
ResourcePyramid(this, img);
components.add(pyramid);
componentIndex.put(pyramid.group.groupId, pyramid);
+
+ //force initialize now, pyramids may amend existing
grids
+ pyramid.getGridGeometry();
+
}
}
}
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiTileMatrix.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiTileMatrix.java
index 3ba53d813c..c7e09cf8fd 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiTileMatrix.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/GimiTileMatrix.java
@@ -40,9 +40,9 @@ final class GimiTileMatrix implements TileMatrix {
private final ResourceGrid grid;
private final GenericName identifier;
private final GridGeometry tilingScheme;
- private final int[] tileSize;
+ private final long[] tileSize;
- public GimiTileMatrix(ResourceGrid grid, GridGeometry tilingScheme, int[]
tileSize) {
+ public GimiTileMatrix(ResourceGrid grid, GridGeometry tilingScheme, long[]
tileSize) {
this.grid = grid;
this.identifier = Names.createLocalName(null, null,
grid.getIdentifier().get().tip().toString() + "_tm");
this.tilingScheme = tilingScheme;
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceGrid.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceGrid.java
index 7853028cb5..e617a76823 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceGrid.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceGrid.java
@@ -33,11 +33,14 @@ import org.apache.sis.storage.Resource;
import org.apache.sis.storage.base.StoreResource;
import org.apache.sis.storage.gimi.internal.MatrixGridRessource;
import org.apache.sis.storage.gimi.isobmff.Box;
+import org.apache.sis.storage.gimi.isobmff.gimi.ModelTransformationProperty;
+import org.apache.sis.storage.gimi.isobmff.gimi.WellKnownText2Property;
import org.apache.sis.storage.gimi.isobmff.iso23008_12.ImageSpatialExtents;
import org.apache.sis.storage.tiling.TileMatrix;
import org.apache.sis.storage.tiling.TileMatrixSet;
import org.apache.sis.storage.tiling.TiledResource;
import org.apache.sis.util.iso.Names;
+import org.opengis.util.FactoryException;
/**
@@ -94,6 +97,8 @@ final class ResourceGrid extends MatrixGridRessource
implements TiledResource, S
}
private synchronized void initialize() throws DataStoreException {
+ if (tileMatrix != null) return;
+
final Resource first =
item.store.getComponent(item.references.get(0).toItemId[0]);
if (first instanceof GridCoverageResource) {
this.first = (GridCoverageResource) first;
@@ -101,23 +106,54 @@ final class ResourceGrid extends MatrixGridRessource
implements TiledResource, S
throw new DataStoreException("Expecting a GridCoverageResource
tile but was a " + first.getClass().getName());
}
final GridGeometry firstTileGridGeom = this.first.getGridGeometry();
- this.crs = firstTileGridGeom.getCoordinateReferenceSystem();
+
final GridExtent tileExtent = firstTileGridGeom.getExtent();
- final int[] tileSize = new
int[]{Math.toIntExact(tileExtent.getSize(0)),
Math.toIntExact(tileExtent.getSize(1))};
- final MathTransform matrixGridToCrs =
firstTileGridGeom.derive().subgrid(null,
tileSize).build().getGridToCRS(PixelInCell.CELL_CENTER);
- for (Box b : item.properties) {
- if (b instanceof ImageSpatialExtents) {
- final ImageSpatialExtents ext = (ImageSpatialExtents) b;
- final long matrixWidth = ext.imageWidth /
tileExtent.getSize(0);
- final long matrixHeight = ext.imageHeight /
tileExtent.getSize(1);
- //create tile matrix
- final GridGeometry tilingScheme = new GridGeometry(new
GridExtent(matrixWidth, matrixHeight), PixelInCell.CELL_CENTER,
matrixGridToCrs, crs);
- tileMatrix = new GimiTileMatrix(this, tilingScheme, tileSize);
- //create tile matrix set
- tileMatrixSet = new
GimiTileMatrixSet(Names.createLocalName(null, null, identifier.tip().toString()
+ "_tms"), crs);
- tileMatrixSet.matrices.insertByScale(tileMatrix);
+ final long[] tileSize = new long[]{tileExtent.getSize(0),
tileExtent.getSize(1)};
+
+ ImageSpatialExtents imageExts = null;
+ ModelTransformationProperty modelTrs = null;
+ WellKnownText2Property modelWkt = null;
+
+ for (Box box : item.properties) {
+ if (box instanceof ImageSpatialExtents) {
+ imageExts = (ImageSpatialExtents) box;
+ } else if (box instanceof ModelTransformationProperty) {
+ modelTrs = (ModelTransformationProperty) box;
+ } else if (box instanceof WellKnownText2Property) {
+ modelWkt = (WellKnownText2Property) box;
+ }
+ }
+
+ if (modelWkt != null) {
+ try {
+ this.crs = modelWkt.toCRS();
+ } catch (FactoryException ex) {
+ throw new DataStoreException(ex.getMessage(), ex);
}
+ } else {
+ this.crs = null;
+ }
+
+ MathTransform matrixGridToCrs;
+ if (modelTrs != null) {
+ matrixGridToCrs = modelTrs.toMathTransform();
+ } else {
+ matrixGridToCrs = null;
}
+
+ //create tile matrix
+ GridGeometry tilingScheme = new GridGeometry(new
GridExtent(imageExts.imageWidth, imageExts.imageHeight),
PixelInCell.CELL_CENTER, matrixGridToCrs, crs);
+ tilingScheme = tilingScheme.derive().subgrid(null, tileSize).build();
//remove tile size from scheme
+ tileMatrix = new GimiTileMatrix(this, tilingScheme, tileSize);
+ //create tile matrix set
+ tileMatrixSet = new GimiTileMatrixSet(Names.createLocalName(null,
null, identifier.tip().toString() + "_tms"), crs);
+ tileMatrixSet.matrices.insertByScale(tileMatrix);
+ }
+
+ void amendTilingScheme(GridGeometry tilingScheme, long[] tileSize) {
+ tileMatrix = new GimiTileMatrix(this, tilingScheme, tileSize);
+ tileMatrixSet = new GimiTileMatrixSet(Names.createLocalName(null,
null, identifier.tip().toString() + "_tms"), crs);
+ tileMatrixSet.matrices.insertByScale(tileMatrix);
}
@Override
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java
index e1d66e52fb..bfd8883b51 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourceImageUncompressed.java
@@ -19,6 +19,7 @@ package org.apache.sis.storage.gimi;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -30,7 +31,6 @@ import org.apache.sis.coverage.grid.GridCoverageBuilder;
import org.apache.sis.coverage.grid.GridExtent;
import org.apache.sis.coverage.grid.GridGeometry;
import org.apache.sis.coverage.grid.PixelInCell;
-import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.privy.AffineTransform2D;
import org.apache.sis.storage.AbstractGridCoverageResource;
@@ -44,7 +44,9 @@ import
org.apache.sis.storage.gimi.isobmff.gimi.WellKnownText2Property;
import org.apache.sis.storage.gimi.isobmff.iso23001_17.ComponentDefinition;
import org.apache.sis.storage.gimi.isobmff.iso23001_17.UncompressedFrameConfig;
import org.apache.sis.storage.gimi.isobmff.iso23008_12.ImageSpatialExtents;
+import
org.apache.sis.storage.gimi.isobmff.iso23008_12.PixelInformationProperty;
import org.apache.sis.util.iso.Names;
+import org.opengis.referencing.operation.MathTransform;
/**
@@ -58,8 +60,19 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
protected final GimiStore store;
protected final Item item;
private final GenericName identifier;
- protected ComponentDefinition compDef;
protected ImageSpatialExtents imageExt;
+ /**
+ * Can be null
+ */
+ protected PixelInformationProperty pixelDef;
+ /**
+ /**
+ * Can be null
+ */
+ protected ComponentDefinition compDef;
+ /**
+ * Can be null
+ */
protected UncompressedFrameConfig frameConf;
/**
* Can be null
@@ -74,6 +87,12 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
*/
protected WellKnownText2Property modelWkt;
+
+ //computed values for decoding
+ private final int tileWidth;
+ private final int tileHeight;
+ private final int tileByteArrayLength;
+
public ResourceImageUncompressed(GimiStore store, Item item) throws
DataStoreException {
super(store);
this.store = store;
@@ -91,6 +110,8 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
modelTp = (ModelTiePointProperty) box;
} else if (box instanceof WellKnownText2Property) {
modelWkt = (WellKnownText2Property) box;
+ } else if (box instanceof PixelInformationProperty) {
+ pixelDef = (PixelInformationProperty) box;
}
}
if (item.entry.itemName == null || item.entry.itemName.isBlank()) {
@@ -98,6 +119,25 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
} else {
this.identifier = Names.createLocalName(null, null,
item.entry.itemName);
}
+
+ //pre-computed values
+ if (frameConf == null) {
+ //use a dumy one
+ frameConf = new UncompressedFrameConfig();
+ frameConf.numTileColsMinusOne = 0;
+ frameConf.numTileRowsMinusOne = 0;
+ }
+ tileWidth = imageExt.imageWidth / (frameConf.numTileColsMinusOne+1);
+ tileHeight = imageExt.imageHeight / (frameConf.numTileRowsMinusOne+1);
+
+ //TODO handle all kind of component length and subsampling
+ if (pixelDef != null) {
+ tileByteArrayLength = tileWidth * tileHeight *
pixelDef.bitsPerChannel.length;
+ } else if (compDef != null) {
+ tileByteArrayLength = tileWidth * tileHeight *
compDef.componentType.length;
+ } else {
+ throw new DataStoreException("Failed to compute tile sizein
bytes");
+ }
}
@Override
@@ -114,21 +154,18 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
public GridGeometry getGridGeometry() throws DataStoreException {
try {
final GridExtent extent = new GridExtent(imageExt.imageWidth,
imageExt.imageHeight);
- final AffineTransform2D gridToCrs;
+ final MathTransform gridToCrs;
if (modelTrs == null) {
gridToCrs = new AffineTransform2D(1, 0, 0, 1, 0, 0);
} else {
- gridToCrs = new AffineTransform2D(modelTrs.transform[0],
modelTrs.transform[3], modelTrs.transform[1], modelTrs.transform[4],
modelTrs.transform[2], modelTrs.transform[5]);
+ gridToCrs = modelTrs.toMathTransform();
}
final CoordinateReferenceSystem crs;
if (modelWkt == null) {
//TODO we should have an Image CRS
- crs = CommonCRS.defaultGeographic();
+ crs = CommonCRS.Engineering.GRID.crs();
} else {
- String wkt = modelWkt.wkt2;
- //TODO remove this hack when SIS support BASEGEOGCRS
- wkt = wkt.replace("BASEGEOGCRS", "BASEGEODCRS");
- crs = CRS.fromWKT(wkt);
+ crs = modelWkt.toCRS();
}
return new GridGeometry(extent, PixelInCell.CELL_CENTER,
gridToCrs, crs);
} catch (FactoryException ex) {
@@ -139,20 +176,28 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
@Override
public List<SampleDimension> getSampleDimensions() throws
DataStoreException {
final List<SampleDimension> sd = new ArrayList<>();
- for (int i = 0; i < compDef.componentType.length; i++) {
- final SampleDimension.Builder sdb = new SampleDimension.Builder();
- switch (compDef.componentType[i]) {
- case 4:
- sdb.setName("Red");
- break;
- case 5:
- sdb.setName("Green");
- break;
- case 6:
- sdb.setName("Blue");
- break;
+ if (compDef != null) {
+ for (int i = 0; i < compDef.componentType.length; i++) {
+ final SampleDimension.Builder sdb = new
SampleDimension.Builder();
+ switch (compDef.componentType[i]) {
+ case 4:
+ sdb.setName("Red");
+ break;
+ case 5:
+ sdb.setName("Green");
+ break;
+ case 6:
+ sdb.setName("Blue");
+ break;
+ }
+ sd.add(sdb.build());
+ }
+ } else if (pixelDef != null) {
+ for (int i = 0; i < pixelDef.bitsPerChannel.length; i++) {
+ final SampleDimension.Builder sdb = new
SampleDimension.Builder();
+ sdb.setName(""+i);
+ sd.add(sdb.build());
}
- sd.add(sdb.build());
}
return sd;
}
@@ -160,15 +205,23 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
@Override
public GridCoverage read(GridGeometry gg, int... ints) throws
DataStoreException {
final byte[] data = item.getData();
- final BufferedImage img = new BufferedImage(2048, 1024,
BufferedImage.TYPE_3BYTE_BGR);
- final WritableRaster raster = img.getRaster();
- for (int y = 0; y < 1024; y++) {
- for (int x = 0; x < 2048; x++) {
- int offset = y * 2048 + x;
- raster.setSample(x, y, 0, data[offset * 3] & 0xFF);
- raster.setSample(x, y, 1, data[offset * 3 + 1] & 0xFF);
- raster.setSample(x, y, 2, data[offset * 3 + 2] & 0xFF);
+
+ final BufferedImage img;
+ if ( (compDef != null && Arrays.equals(compDef.componentType, new
int[]{4,5,6}))
+ || (pixelDef != null && pixelDef.bitsPerChannel.length == 3)
+ ) {
+ // RGB case
+ int width = imageExt.imageWidth;
+ int height = imageExt.imageHeight;
+ img = new BufferedImage(width, height,
BufferedImage.TYPE_3BYTE_BGR);
+ final WritableRaster raster = img.getRaster();
+ for (int y = 0; y <= frameConf.numTileRowsMinusOne; y++) {
+ for (int x = 0; x <= frameConf.numTileColsMinusOne; x++) {
+ readTile(data, x, y, raster, x*tileWidth, y*tileHeight);
+ }
}
+ } else {
+ throw new DataStoreException("Unsupported component model");
}
final GridGeometry gridGeometry = getGridGeometry();
GridCoverageBuilder gcb = new GridCoverageBuilder();
@@ -179,4 +232,25 @@ class ResourceImageUncompressed extends
AbstractGridCoverageResource implements
return gcb.build();
}
+ /**
+ *
+ * @param data
+ * @param tileX starting from image left
+ * @param tileY starting from image top
+ */
+ private void readTile(byte[] data, int tileX, int tileY, WritableRaster
raster, int offsetX, int offsetY) {
+ final int tileOffset = (tileX + tileY *
(frameConf.numTileColsMinusOne+1)) * tileByteArrayLength;
+ for (int y = 0; y < tileHeight; y++) {
+ for (int x = 0; x < tileWidth; x++) {
+ final int offset = y * tileWidth + x;
+ final int finalX = offsetX + x;
+ final int finalY = offsetY + y;
+ raster.setSample(finalX, finalY, 0, data[tileOffset + offset *
3] & 0xFF);
+ raster.setSample(finalX, finalY, 1, data[tileOffset + offset *
3 + 1] & 0xFF);
+ raster.setSample(finalX, finalY, 2, data[tileOffset + offset *
3 + 2] & 0xFF);
+ }
+ }
+ }
+
+
}
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourcePyramid.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourcePyramid.java
index 01529ac58c..ffef8b7d67 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourcePyramid.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/ResourcePyramid.java
@@ -17,7 +17,9 @@
package org.apache.sis.storage.gimi;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,6 +29,10 @@ import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.coverage.grid.GridCoverage;
import org.apache.sis.coverage.grid.GridExtent;
import org.apache.sis.coverage.grid.GridGeometry;
+import org.apache.sis.coverage.grid.PixelInCell;
+import org.apache.sis.referencing.CommonCRS;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.referencing.privy.AffineTransform2D;
import org.apache.sis.storage.AbstractGridCoverageResource;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
@@ -41,6 +47,8 @@ import org.apache.sis.storage.tiling.TileMatrix;
import org.apache.sis.storage.tiling.TileMatrixSet;
import org.apache.sis.storage.tiling.TiledResource;
import org.apache.sis.util.iso.Names;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
/**
@@ -74,8 +82,11 @@ final class ResourcePyramid extends
AbstractGridCoverageResource implements Tile
if (tileMatrixSet != null) {
return;
}
- final GridCoverageResource first = (GridCoverageResource)
store.getComponent(group.entitiesId[0]);
- tileMatrixSet = new GimiTileMatrixSet(Names.createLocalName(null,
null, getIdentifier().get().tip().toString() + "_tms"),
first.getGridGeometry().getCoordinateReferenceSystem());
+
+ /*
+ * Find all resources of the pyramid
+ */
+ final List<ResourceGrid> candidates = new ArrayList<>();
for (int i = 0; i < group.matrices.length; i++) {
Resource res = store.getComponent(group.entitiesId[i]);
if (res instanceof GridCoverageResource && !(res instanceof
TiledResource)) {
@@ -97,13 +108,54 @@ final class ResourcePyramid extends
AbstractGridCoverageResource implements Tile
}
if (res instanceof ResourceGrid) {
final ResourceGrid tr = (ResourceGrid) res;
- final TileMatrix tm = tr.getTileMatrix();
- grids.put(tm.getIdentifier(), tr);
- tileMatrixSet.matrices.insertByScale(tm);
+ candidates.add(tr);
} else {
throw new DataStoreException("A resource in the pyramid in not
a coverage, itemId : " + group.entitiesId[i]);
}
}
+
+ /*
+ * Sort by scale, lowest resolution at index 0.
+ * Only the most accurate matrix seems to contains georeferencing
informations
+ */
+ Collections.sort(candidates, (ResourceGrid o1, ResourceGrid o2) -> {
+ return Long.compare(
+
o2.getTileMatrix().getTilingScheme().getExtent().getSize(0),
+
o1.getTileMatrix().getTilingScheme().getExtent().getSize(0));
+ });
+
+ /*
+ * Define each matrix CRS and transform based on the lowest one.
+ * each level is 2x resolution with the same tope left corner.
+ */
+ final TileMatrix referenceMatrix = candidates.get(0).getTileMatrix();
+ final GridGeometry reference = referenceMatrix.getTilingScheme();
+ final MathTransform referenceTransform =
reference.isDefined(GridGeometry.GRID_TO_CRS) ?
reference.getGridToCRS(PixelInCell.CELL_CENTER) : new AffineTransform2D(1, 0,
0, 1, 0, 0);
+ final CoordinateReferenceSystem crs =
reference.isDefined(GridGeometry.CRS) ?
referenceMatrix.getTilingScheme().getCoordinateReferenceSystem() :
CommonCRS.Engineering.GRID.crs();
+
+ tileMatrixSet = new GimiTileMatrixSet(Names.createLocalName(null,
null, getIdentifier().get().tip().toString() + "_tms"), crs);
+ grids.put(referenceMatrix.getIdentifier(), candidates.get(0));
+ tileMatrixSet.matrices.insertByScale(referenceMatrix);
+ final long[] tileSize = new long[]{group.tileSizeX, group.tileSizeY};
+
+ for (int i = 1, n = candidates.size(); i < n; i++) {
+ final ResourceGrid resource = candidates.get(i);
+
+ final double scale = Math.pow(2, i);
+ final MathTransform scaleTrs = new AffineTransform2D(scale, 0, 0,
scale, 0, 0);
+
+ final GridGeometry fixed = new GridGeometry(
+ resource.getTileMatrix().getTilingScheme().getExtent(),
+ PixelInCell.CELL_CENTER,
+ MathTransforms.concatenate(scaleTrs, referenceTransform),
+ reference.getCoordinateReferenceSystem());
+
+ resource.amendTilingScheme(fixed, tileSize);
+ final TileMatrix matrix = resource.getTileMatrix();
+
+ grids.put(matrix.getIdentifier(), resource);
+ tileMatrixSet.matrices.insertByScale(matrix);
+ }
}
@Override
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/ScaleSortedMap.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/ScaleSortedMap.java
index e1892d9d24..cb02157a8d 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/ScaleSortedMap.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/ScaleSortedMap.java
@@ -42,7 +42,7 @@ public final class ScaleSortedMap<T extends TileMatrix>
extends TreeMap<GenericN
ArgumentChecks.ensureNonNull("identifier", id);
final ScaleComparator comparator = (ScaleComparator) comparator();
if (comparator.matricesByScale.containsKey(id)) {
- throw new IllegalArgumentException("Key " + id + "already exist");
+ throw new IllegalArgumentException("Key already exist : " + id);
}
final double resolution = tileMatrix.getResolution()[0];
comparator.matricesByScale.put(id, resolution);
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/ModelTransformationProperty.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/ModelTransformationProperty.java
index c6fc069376..d3f422c45a 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/ModelTransformationProperty.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/ModelTransformationProperty.java
@@ -17,8 +17,10 @@
package org.apache.sis.storage.gimi.isobmff.gimi;
import java.io.IOException;
+import org.apache.sis.referencing.privy.AffineTransform2D;
import org.apache.sis.storage.gimi.isobmff.ISOBMFFReader;
import org.apache.sis.storage.gimi.isobmff.iso14496_12.ItemFullProperty;
+import org.opengis.referencing.operation.MathTransform;
/**
@@ -42,5 +44,12 @@ public final class ModelTransformationProperty extends
ItemFullProperty {
}
}
+ public MathTransform toMathTransform() {
+ if (transform.length == 6) {
+ return new AffineTransform2D(transform[0], transform[3],
transform[1], transform[4], transform[2], transform[5]);
+ } else {
+ throw new UnsupportedOperationException("3D transform not
supported yet");
+ }
+ }
}
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/WellKnownText2Property.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/WellKnownText2Property.java
index e2c968b29d..2b5560e9fd 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/WellKnownText2Property.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/gimi/WellKnownText2Property.java
@@ -17,8 +17,11 @@
package org.apache.sis.storage.gimi.isobmff.gimi;
import java.io.IOException;
+import org.apache.sis.referencing.CRS;
import org.apache.sis.storage.gimi.isobmff.ISOBMFFReader;
import org.apache.sis.storage.gimi.isobmff.iso14496_12.ItemFullProperty;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.util.FactoryException;
/**
@@ -36,4 +39,10 @@ public final class WellKnownText2Property extends
ItemFullProperty {
wkt2 = reader.readUtf8String();
}
+ public CoordinateReferenceSystem toCRS() throws FactoryException {
+ //TODO remove this hack when SIS support BASEGEOGCRS
+ String wkt = this.wkt2.replace("BASEGEOGCRS", "BASEGEODCRS");
+ return CRS.fromWKT(wkt);
+ }
+
}
diff --git
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso23001_17/TAIClockInfo.java
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso23001_17/TAIClockInfo.java
index ac2254e2f1..0458e6bbce 100644
---
a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso23001_17/TAIClockInfo.java
+++
b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/isobmff/iso23001_17/TAIClockInfo.java
@@ -30,7 +30,7 @@ public final class TAIClockInfo extends FullBox {
public static final String FCC = "taic";
- public long timeUncertainty;
+ public int timeUncertainty;
public int clockResolution;
public int clockDriftRate;
public int unknown;
@@ -38,7 +38,7 @@ public final class TAIClockInfo extends FullBox {
@Override
protected void readProperties(ISOBMFFReader reader) throws IOException {
- timeUncertainty = reader.channel.readLong();
+ timeUncertainty = reader.channel.readInt();
clockResolution = reader.channel.readInt();
clockDriftRate = reader.channel.readInt();
unknown = reader.channel.readInt();