/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, Geomatys * * 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; * version 2.1 of the License. * * 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 org.geotoolkit.coverage; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.DataBuffer; import java.awt.image.DirectColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.util.Arrays; import org.apache.sis.geometry.GeneralDirectPosition; import org.apache.sis.geometry.GeneralEnvelope; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.coverage.grid.ViewType; import org.geotoolkit.coverage.io.CoverageReader; import org.geotoolkit.coverage.io.GridCoverageReadParam; import org.geotoolkit.util.NamesExt; import org.apache.sis.referencing.CRS; import org.geotoolkit.image.BufferedImages; import static org.junit.Assert.*; import org.geotoolkit.storage.coverage.CoverageStore; import org.geotoolkit.storage.coverage.GridMosaic; import org.geotoolkit.storage.coverage.Pyramid; import org.geotoolkit.storage.coverage.PyramidalCoverageReference; import org.junit.Test; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.Envelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.util.GenericName; import org.apache.sis.util.Utilities; /** * Pyramid store read and write tests. * * @author Johann Sorel (Geomatys) * @module */ public abstract class AbstractPyramidalModelStoreTest extends org.geotoolkit.test.TestBase { private static final double DELTA = 0.00000001; private CoverageStore store; private DirectPosition corner; private CoordinateReferenceSystem crs; //RGBA reference private PyramidalCoverageReference rgbaCoverageRef; private ColorModel rgbaColorModel; //Float 1 band reference private PyramidalCoverageReference float1bCoverageRef; private ColorModel float1bColorModel; protected abstract CoverageStore createStore() throws Exception ; private CoverageStore getCoverageStore() throws Exception { if(store != null){ return store; } store = createStore(); crs = CRS.forCode("EPSG:3395"); //////////////////////////////////////////////////////////////////////// //create a small RGBA pyramid ////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// final GenericName rgbaName = NamesExt.create("rgba"); rgbaCoverageRef = (PyramidalCoverageReference) store.create(rgbaName); rgbaCoverageRef.setPackMode(ViewType.RENDERED); //define the coverage informations rgbaColorModel = createRGBA(Color.RED).getColorModel(); // rgbaCoverageRef.setColorModel(rgbaColorModel);//-- temporary in comment in attempt to update TiffImageReader corner = new GeneralDirectPosition(crs); corner.setOrdinate(0, 100); corner.setOrdinate(1, 20); final Pyramid rgbaPyramid = rgbaCoverageRef.createPyramid(crs); final GridMosaic rgbaMosaic1 = rgbaCoverageRef.createMosaic(rgbaPyramid.getId(), new Dimension(2, 2), new Dimension(10, 10) , corner, 1); final GridMosaic rgbaMosaic2 = rgbaCoverageRef.createMosaic(rgbaPyramid.getId(), new Dimension(4, 3), new Dimension(10, 10) , corner, 0.5); //insert tiles rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic1.getId(), 0, 0, createRGBA(Color.RED)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic1.getId(), 1, 0, createRGBA(Color.GREEN)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic1.getId(), 0, 1, createRGBA(Color.BLUE)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic1.getId(), 1, 1, createRGBA(Color.BLACK)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 0, 0, createRGBA(Color.RED)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 1, 0, createRGBA(Color.GREEN)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 2, 0, createRGBA(Color.BLUE)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 3, 0, createRGBA(Color.BLACK)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 0, 1, createRGBA(Color.CYAN)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 1, 1, createRGBA(Color.MAGENTA)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 2, 1, createRGBA(Color.YELLOW)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 3, 1, createRGBA(Color.PINK)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 0, 2, createRGBA(Color.DARK_GRAY)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 1, 2, createRGBA(Color.LIGHT_GRAY)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 2, 2, createRGBA(Color.WHITE)); rgbaCoverageRef.writeTile(rgbaPyramid.getId(), rgbaMosaic2.getId(), 3, 2, createRGBA(Color.BLACK)); //////////////////////////////////////////////////////////////////////// //create a small Float 1 band pyramid ////////////////////////////////// //////////////////////////////////////////////////////////////////////// final GenericName float1bName = NamesExt.create("float1b"); float1bCoverageRef = (PyramidalCoverageReference) store.create(float1bName); float1bCoverageRef.setPackMode(ViewType.GEOPHYSICS); //define the coverage informations float1bColorModel = createFloat(1.1f).getColorModel(); // float1bCoverageRef.setColorModel(float1bColorModel);//-- temporary in comment in attempt to update TiffImageReader corner = new GeneralDirectPosition(crs); corner.setOrdinate(0, 100); corner.setOrdinate(1, 20); final Pyramid float1bPyramid = float1bCoverageRef.createPyramid(crs); final GridMosaic float1bMosaic1 = float1bCoverageRef.createMosaic(float1bPyramid.getId(), new Dimension(2, 2), new Dimension(10, 10) , corner, 1); final GridMosaic float1bMosaic2 = float1bCoverageRef.createMosaic(float1bPyramid.getId(), new Dimension(4, 3), new Dimension(10, 10) , corner, 0.5); //insert tiles float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic1.getId(), 0, 0, createFloat(1.1f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic1.getId(), 1, 0, createFloat(2.2f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic1.getId(), 0, 1, createFloat(3.3f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic1.getId(), 1, 1, createFloat(4.4f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 0, 0, createFloat(-1.1f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 1, 0, createFloat(-2.2f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 2, 0, createFloat(-3.3f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 3, 0, createFloat(-4.4f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 0, 1, createFloat(-5.5f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 1, 1, createFloat(-6.6f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 2, 1, createFloat(-7.7f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 3, 1, createFloat(-8.8f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 0, 2, createFloat(-9.9f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 1, 2, createFloat(-10.10f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 2, 2, createFloat(-11.11f)); float1bCoverageRef.writeTile(float1bPyramid.getId(), float1bMosaic2.getId(), 3, 2, createFloat(-12.12f)); return store; } private static BufferedImage createFloat(final float val){ final BufferedImage buffer = BufferedImages.createImage(10, 10, 1, DataBuffer.TYPE_FLOAT); final WritableRaster raster = buffer.getRaster(); for(int y=0;y<10;y++){ for(int x=0;x<10;x++){ raster.setPixel(x,y,new float[]{val}); } } return buffer; } private static BufferedImage createRGBA(final Color color){ final BufferedImage buffer = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); final Graphics2D g = buffer.createGraphics(); g.setColor(color); g.fillRect(0, 0, 10, 10); return buffer; } /** * Read the full RGBA image. * @throws Exception */ @Test public void readRGBANoArgumentTest() throws Exception{ //load the coverage store getCoverageStore(); final CoverageReader reader = rgbaCoverageRef.acquireReader(); final GridCoverage2D coverage = (GridCoverage2D) reader.read(0, null); rgbaCoverageRef.recycle(reader); //check defined color model //testColorModel(rgbaColorModel, rgbaCoverageRef.getColorModel()); //check coverage informations final CoordinateReferenceSystem covcrs = coverage.getCoordinateReferenceSystem(); assertTrue(Utilities.equalsIgnoreMetadata(crs, covcrs)); final Envelope env = coverage.getEnvelope(); assertEquals(corner.getOrdinate(0), env.getMinimum(0), DELTA); assertEquals(corner.getOrdinate(1), env.getMaximum(1), DELTA); assertEquals(corner.getOrdinate(0) +(4*10)*0.5, env.getMaximum(0), DELTA); assertEquals(corner.getOrdinate(1) -(3*10)*0.5, env.getMinimum(1), DELTA); assertTrue(Utilities.equalsIgnoreMetadata(crs, env.getCoordinateReferenceSystem())); //check tile aggregation final RenderedImage img = coverage.getRenderedImage(); final Raster raster = img.getData(); //check defined color model, do not test the colorspace //testColorModel(rgbaColorModel, img.getColorModel()); assertEquals(4*10,img.getWidth()); assertEquals(3*10,img.getHeight()); //we should have a different color each 10pixel final int[] buffer1 = new int[4]; final int[] buffer2 = new int[4]; for(int x=5;x<img.getWidth();x+=10){ for(int y=5;y<img.getHeight();y+=10){ raster.getPixel(x, y, buffer2); assertFalse(Arrays.equals(buffer1, buffer2)); System.arraycopy(buffer2, 0, buffer1, 0, 4); } } } /** * Read the full RGBA image. * @throws Exception */ @Test public void readFloat1BNoArgumentTest() throws Exception{ //load the coverage store getCoverageStore(); final CoverageReader reader = float1bCoverageRef.acquireReader(); final GridCoverage2D coverage = (GridCoverage2D) reader.read(0, null); float1bCoverageRef.recycle(reader); //check defined color model, do not test the colorspace //testColorModel(float1bColorModel, float1bCoverageRef.getColorModel()); //check coverage informations final CoordinateReferenceSystem covcrs = coverage.getCoordinateReferenceSystem(); assertTrue(Utilities.equalsIgnoreMetadata(crs, covcrs)); final Envelope env = coverage.getEnvelope(); assertEquals(corner.getOrdinate(0), env.getMinimum(0), DELTA); assertEquals(corner.getOrdinate(1), env.getMaximum(1), DELTA); assertEquals(corner.getOrdinate(0) +(4*10)*0.5, env.getMaximum(0), DELTA); assertEquals(corner.getOrdinate(1) -(3*10)*0.5, env.getMinimum(1), DELTA); assertTrue(Utilities.equalsIgnoreMetadata(crs, env.getCoordinateReferenceSystem())); //check tile aggregation final RenderedImage img = coverage.getRenderedImage(); final Raster raster = img.getData(); //check defined color model, do not test the colorspace //testColorModel(float1bColorModel, img.getColorModel()); assertEquals(4*10,img.getWidth()); assertEquals(3*10,img.getHeight()); //we should have a different color each 10pixel final int[] buffer1 = new int[4]; final int[] buffer2 = new int[4]; for(int x=5;x<img.getWidth();x+=10){ for(int y=5;y<img.getHeight();y+=10){ raster.getPixel(x, y, buffer2); assertFalse(Arrays.equals(buffer1, buffer2)); System.arraycopy(buffer2, 0, buffer1, 0, 4); } } } /** * Read and image subset. * @throws Exception */ @Test public void reduceAreaTest() throws Exception{ //load the coverage store getCoverageStore(); final CoverageReader reader = rgbaCoverageRef.acquireReader(); final GeneralEnvelope paramEnv = new GeneralEnvelope(crs); paramEnv.setRange(0, corner.getOrdinate(0) +(1*10)*1, corner.getOrdinate(0) +(2*10)*1); paramEnv.setRange(1, corner.getOrdinate(1) -(2*10)*1, corner.getOrdinate(1)); //we should obtain tiles [1,0] and [1,1] final GridCoverageReadParam param = new GridCoverageReadParam(); param.setCoordinateReferenceSystem(crs); param.setResolution(1.2,1.2); param.setEnvelope(paramEnv); final GridCoverage2D coverage = (GridCoverage2D) reader.read(0, param); rgbaCoverageRef.recycle(reader); //check coverage informations assertTrue(Utilities.equalsApproximatively(crs, coverage.getCoordinateReferenceSystem())); final Envelope env = coverage.getEnvelope(); assertEquals(corner.getOrdinate(0) +(1*10)*1, env.getMinimum(0), DELTA); assertEquals(corner.getOrdinate(1), env.getMaximum(1), DELTA); assertEquals(corner.getOrdinate(0) +(1*10)*1+(1*10)*1, env.getMaximum(0), DELTA); assertEquals(corner.getOrdinate(1) -(2*10)*1, env.getMinimum(1), DELTA); assertTrue(Utilities.equalsApproximatively(crs, env.getCoordinateReferenceSystem())); //check tile aggregation final RenderedImage img = coverage.getRenderedImage(); final Raster raster = img.getData(); assertEquals(1*10,img.getWidth()); assertEquals(2*10,img.getHeight()); //we should have a different color each 10pixel final int[] buffer1 = new int[4]; final int[] buffer2 = new int[4]; for(int x=5;x<img.getWidth();x+=10){ for(int y=5;y<img.getHeight();y+=10){ raster.getPixel(x, y, buffer2); assertFalse(Arrays.equals(buffer1, buffer2)); System.arraycopy(buffer2, 0, buffer1, 0, 4); } } } private void testColorModel(ColorModel expected, ColorModel candidate){ if(expected instanceof DirectColorModel){ final DirectColorModel edm = (DirectColorModel) expected; final DirectColorModel cdm = (DirectColorModel) candidate; assertEquals(edm.getPixelSize(), cdm.getPixelSize()); assertEquals(edm.getRedMask(), cdm.getRedMask()); assertEquals(edm.getGreenMask(), cdm.getGreenMask()); assertEquals(edm.getBlueMask(), cdm.getBlueMask()); assertEquals(edm.getAlphaMask(), cdm.getAlphaMask()); assertEquals(edm.hasAlpha(), cdm.hasAlpha()); assertEquals(edm.isAlphaPremultiplied(), cdm.isAlphaPremultiplied()); assertEquals(edm.getTransferType(), cdm.getTransferType()); }else if(expected instanceof ComponentColorModel){ final ComponentColorModel edm = (ComponentColorModel) expected; final ComponentColorModel cdm = (ComponentColorModel) candidate; //assertArrayEquals(edm.getComponentSize(), cdm.getComponentSize()); this is modified by the colorspace assertEquals(edm.hasAlpha(), cdm.hasAlpha()); assertEquals(edm.isAlphaPremultiplied(), cdm.isAlphaPremultiplied()); assertEquals(edm.getTransparency(), cdm.getTransparency()); assertEquals(edm.getTransferType(), cdm.getTransferType()); }else{ assertEquals(float1bColorModel, candidate); } } }