/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014, Open Source Geospatial Foundation (OSGeo) * (C) 2001-2014 TOPP - www.openplans.org. * * 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.geotools.process.raster; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import javax.media.jai.Interpolation; import javax.media.jai.InterpolationBicubic; import javax.media.jai.InterpolationBilinear; import javax.media.jai.InterpolationNearest; import javax.media.jai.iterator.RandomIter; import javax.media.jai.iterator.RandomIterFactory; import org.geotools.TestData; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.coverage.grid.io.GridFormatFinder; import org.geotools.coverage.processing.CoverageProcessor; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.factory.GeoTools; import org.geotools.geometry.jts.JTS; import org.geotools.process.ProcessException; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.opengis.coverage.grid.GridCoverageReader; import org.opengis.feature.simple.SimpleFeature; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.metadata.spatial.PixelOrientation; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform2D; import org.opengis.referencing.operation.TransformException; import com.vividsolutions.jts.geom.Point; public class RasterAsPointCollectionProcessTest { private static final String NORTH = "N"; private static GridCoverage2D coverage; private static GridCoverage2D inputCoverage; private static int pixelNumber; private static RasterAsPointCollectionProcess process; private static String bandName; @BeforeClass public static void setup() throws FileNotFoundException, IOException { // Selection of the File to use File tiff = TestData.file(RasterAsPointCollectionProcessTest.class, "sample.tif"); // Reading of the file with the GeoTiff reader AbstractGridFormat format = GridFormatFinder.findFormat(tiff); // Get a reader for the selected format GridCoverageReader reader = format.getReader(tiff); // Read the input Coverage inputCoverage = (GridCoverage2D) reader.read(null); // Reproject to the default WGS84 CRS final CoverageProcessor processor = CoverageProcessor.getInstance(GeoTools .getDefaultHints()); final ParameterValueGroup param = processor.getOperation("Resample").getParameters(); param.parameter("Source").setValue(inputCoverage); param.parameter("CoordinateReferenceSystem").setValue(DefaultGeographicCRS.WGS84); coverage = (GridCoverage2D) processor.doOperation(param); // Reader disposal reader.dispose(); // Definition of the Image Size pixelNumber = coverage.getRenderedImage().getHeight() * coverage.getRenderedImage().getWidth(); // Definition of the process process = new RasterAsPointCollectionProcess(); // Definition of the Name of the unique GridSampleDimension bandName = coverage.getSampleDimension(0).getDescription().toString(); } @Test(expected = ProcessException.class) public void testNullCoverage() { process.execute(null, null, null, null, false); } @Test public void testCoverageWithoutParam() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess without setting any additional parameter SimpleFeatureCollection collection = process.execute(coverage, null, null, null, false); // Check if the points are exactly as the number of pixel number Assert.assertEquals(pixelNumber, collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, false, null, null); } @Test public void testCoverageWithHemisphere() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere to true boolean hemisphere = true; SimpleFeatureCollection collection = process .execute(coverage, null, null, null, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals(pixelNumber, collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, null, null); } @Test public void testCoverageWithScaleFactor() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere and scaleFactor boolean hemisphere = true; float scaleFactor = 2.0f; SimpleFeatureCollection collection = process.execute(coverage, null, scaleFactor, null, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, null); } @Test public void testCoverageWithSmallScaleFactor() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere and scaleFactor boolean hemisphere = true; float scaleFactor = 1f/18; SimpleFeatureCollection collection = process.execute(coverage, null, scaleFactor, null, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals(1, collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, null); } @Test public void testCoverageWithNearestInterp() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere, scaleFactor and nearest interpolation boolean hemisphere = true; float scaleFactor = 2.0f; Interpolation interp = new InterpolationNearest(); SimpleFeatureCollection collection = process.execute(coverage, null, scaleFactor, interp, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, null); } @Test public void testCoverageWithBilinearInterp() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere, scaleFactor and bilinear interpolation boolean hemisphere = true; float scaleFactor = 2.0f; Interpolation interp = new InterpolationBilinear(); SimpleFeatureCollection collection = process.execute(coverage, null, scaleFactor, interp, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, null); } @Test public void testCoverageWithBicubicInterp() throws MismatchedDimensionException, TransformException { // Execution of the RasterAsPointCollectionProcess setting hemisphere, scaleFactor and bicubic interpolation boolean hemisphere = true; float scaleFactor = 2.0f; Interpolation interp = new InterpolationBicubic(8); SimpleFeatureCollection collection = process.execute(coverage, null, scaleFactor, interp, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, null); } @Test public void testCoverageWithTargetCRS() throws MismatchedDimensionException, TransformException, FactoryException { // Execution of the RasterAsPointCollectionProcess setting hemisphere, scaleFactor, nearest interpolation and targetCRS boolean hemisphere = true; float scaleFactor = 2.0f; Interpolation interp = new InterpolationNearest(); // Selection of the Lambert Conformal Conic CRS String wkt = "PROJCS[\"Lambert_Conformal_Conic\"," + "GEOGCS[\"GCS_unknown\",DATUM[\"D_unknown\"," + "SPHEROID[\"Sphere\",6367470,0]],PRIMEM[\"Greenwich\",0]," + "UNIT[\"Degree\",0.017453292519943295]]," + "PROJECTION[\"Lambert_Conformal_Conic_1SP\"]," + "PARAMETER[\"latitude_of_origin\",38.5]," + "PARAMETER[\"central_meridian\",-97.5]," + "PARAMETER[\"scale_factor\",1]," + "PARAMETER[\"false_easting\",0]," + "PARAMETER[\"false_northing\",0],UNIT[\"m\",1.0]]"; CoordinateReferenceSystem targetCRS = CRS.parseWKT(wkt); SimpleFeatureCollection collection = process.execute(coverage, targetCRS, scaleFactor, interp, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, targetCRS); } @Test public void testCoverageDifferentCRS() throws MismatchedDimensionException, TransformException, FactoryException { // Execution of the RasterAsPointCollectionProcess setting hemisphere, scaleFactor, nearest interpolation and targetCRS boolean hemisphere = true; float scaleFactor = 2.0f; Interpolation interp = new InterpolationNearest(); // Selection of the Lambert Conformal Conic CRS String wkt = "PROJCS[\"Lambert_Conformal_Conic\"," + "GEOGCS[\"GCS_unknown\",DATUM[\"D_unknown\"," + "SPHEROID[\"Sphere\",6367470,0]],PRIMEM[\"Greenwich\",0]," + "UNIT[\"Degree\",0.017453292519943295]]," + "PROJECTION[\"Lambert_Conformal_Conic_1SP\"]," + "PARAMETER[\"latitude_of_origin\",38.5]," + "PARAMETER[\"central_meridian\",-97.5]," + "PARAMETER[\"scale_factor\",1]," + "PARAMETER[\"false_easting\",0]," + "PARAMETER[\"false_northing\",0],UNIT[\"m\",1.0]]"; CoordinateReferenceSystem targetCRS = CRS.parseWKT(wkt); // The input coverage is not in the Default WGS84 CRS SimpleFeatureCollection collection = process.execute(inputCoverage, targetCRS, scaleFactor, interp, hemisphere); // Check if the points are exactly as the number of pixel number Assert.assertEquals((int) (pixelNumber * scaleFactor * scaleFactor), collection.size()); // Check if each Point Attribute contains the same values of the Input coverage checkCollectionPoints(collection, hemisphere, scaleFactor, targetCRS); } private void checkCollectionPoints(SimpleFeatureCollection collection, boolean hemisphere, Float scaleFactor, CoordinateReferenceSystem targetCRS) throws MismatchedDimensionException, TransformException { // World2Grid transform associated to the coverage MathTransform2D w2g = coverage.getGridGeometry() .getCRSToGrid2D(PixelOrientation.UPPER_LEFT); // Iterator on the FeatureCollection SimpleFeatureIterator it = collection.features(); // Iterator on the input image RandomIter imageIterator = RandomIterFactory.create(coverage.getRenderedImage(), null); // Boolean indicating that the TargetCRS is not null boolean crsExists = targetCRS != null; // Cycle on the Collection try { while (it.hasNext()) { // Selection of the feature SimpleFeature ft = it.next(); // If the scale factor is more than 1 then no comparison between the values is done due // to possible differences on the interpolation if (scaleFactor == null) { // Selection of the associated point Point point = (Point) ft.getDefaultGeometry(); Point rasterPoint = (Point) JTS.transform(point, w2g); int x = (int) (rasterPoint.getX()); int y = (int) (rasterPoint.getY()); // Selection of the value for the single band for the selected position int sampleIMG = imageIterator.getSample(x, y, 0); int sampleColl = (Short) ft.getAttribute(bandName); // Ensure the values are equal Assert.assertEquals(sampleIMG, sampleColl); } // Check the hemisphere if (hemisphere) { Assert.assertEquals(NORTH, ft.getAttribute("emisphere")); } // Check the GridConvergenceAngle if (crsExists) { double angle = (double) ft.getAttribute("gridConvergenceAngleCorrection"); Assert.assertTrue(angle != 0); } } } finally { if (it != null) { it.close(); } } } }