package org.geotools.renderer.lite; import static org.junit.Assert.assertEquals; import java.awt.Color; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.concurrent.atomic.AtomicInteger; import org.geotools.TestData; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.grid.io.GridCoverage2DReader; import org.geotools.data.FeatureSource; import org.geotools.data.Query; import org.geotools.data.property.PropertyDataStore; import org.geotools.factory.GeoTools; import org.geotools.factory.Hints; import org.geotools.filter.text.cql2.CQL; import org.geotools.filter.text.cql2.CQLException; import org.geotools.gce.geotiff.GeoTiffReader; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.image.ImageWorker; import org.geotools.map.FeatureLayer; import org.geotools.map.GridCoverageLayer; import org.geotools.map.GridReaderLayer; import org.geotools.map.MapContent; import org.geotools.referencing.CRS; import org.geotools.renderer.RenderListener; import org.geotools.styling.Style; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.opengis.coverage.grid.Format; import org.opengis.feature.simple.SimpleFeature; import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; public class RenderingTransformationTest { private static final long TIME = 4000; @Before public void setup() { // System.setProperty("org.geotools.test.interactive", "true"); System.setProperty( GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER, "false" ); CRS.reset("all"); } @After public void tearDown() { Hints.removeSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER); } @Test public void testTransformReprojectedGridReader() throws Exception { Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld"); GeoTiffReader reader = new GeoTiffReader(TestData.copy(this, "geotiff/world.tiff")); MapContent mc = new MapContent(); mc.addLayer(new GridReaderLayer(reader, style)); StreamingRenderer renderer = new StreamingRenderer(); renderer.setMapContent(mc); ReferencedEnvelope reWgs84 = new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326")); ReferencedEnvelope re = reWgs84.transform(CRS.decode("EPSG:3857"), true); BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, re); // if everything worked we are going to have a red dot in the middle of the map assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 2)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 4)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 4)); } @Test public void testTransformReprojectedGridCoverage() throws Exception { Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld"); GeoTiffReader reader = new GeoTiffReader(TestData.copy(this, "geotiff/world.tiff")); MapContent mc = new MapContent(); mc.addLayer(new GridCoverageLayer(reader.read(null), style)); StreamingRenderer renderer = new StreamingRenderer(); renderer.setMapContent(mc); ReferencedEnvelope reWgs84 = new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326")); ReferencedEnvelope re = reWgs84.transform(CRS.decode("EPSG:3857"), true); BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, re); // if everything worked we are going to have a red dot in the middle of the map assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 2)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 4)); assertEquals(Color.WHITE, getPixelColor(image, image.getWidth() / 4, image.getHeight() / 4)); } @Test public void testTransformNullCoverage() throws Exception { Style style = RendererBaseTest.loadStyle(this, "coverageCenter.sld"); GridCoverage2DReader reader = new AbstractGridCoverage2DReader() { @Override public Format getFormat() { return null; } @Override public GridCoverage2D read(GeneralParameterValue[] parameters) throws IllegalArgumentException, IOException { // we return null on purpose, simulating a reader queried outside of its area, or // on a dimension value it does not have return null; } }; MapContent mc = new MapContent(); mc.addLayer(new GridReaderLayer(reader, style)); StreamingRenderer renderer = new StreamingRenderer(); renderer.setMapContent(mc); ReferencedEnvelope re = new ReferencedEnvelope(-70, 70, -160, 160, CRS.decode("EPSG:4326")); BufferedImage image = RendererBaseTest.showRender("Transformation with null input", renderer, TIME, re); // full white, no NPE double[] minimums = new ImageWorker(image).getMinimums(); assertEquals(255, minimums[0], 0d); assertEquals(255, minimums[1], 0d); assertEquals(255, minimums[2], 0d); assertEquals(255, minimums[3], 0d); } @Test public void testTransformWithQueryNoInvert() throws Exception { testTransformWithQuery(false); } @Test public void testTransformWithQueryInvert() throws Exception { testTransformWithQuery(true); } private void testTransformWithQuery(boolean invert) throws IOException, URISyntaxException, CQLException, NoSuchAuthorityCodeException, FactoryException, Exception { // grab the style Style style = RendererBaseTest.loadStyle(this, invert ? "attributeRename.sld" : "attributeRenameNoInvert.sld"); // grab the data File property = new File(TestData.getResource(this, "point.properties").toURI()); PropertyDataStore ds = new PropertyDataStore(property.getParentFile()); FeatureSource fs = ds.getFeatureSource("point"); // prepare a feature layer with a query and the rendering tx FeatureLayer layer = new FeatureLayer(fs, style); layer.setQuery(new Query(null, CQL.toFilter("id > 5"))); // render it MapContent mc = new MapContent(); mc.addLayer(layer); StreamingRenderer renderer = new StreamingRenderer(); final AtomicInteger counter = new AtomicInteger(); renderer.addRenderListener(new RenderListener() { @Override public void featureRenderer(SimpleFeature feature) { counter.incrementAndGet(); } @Override public void errorOccurred(Exception e) { } }); renderer.setMapContent(mc); ReferencedEnvelope re = new ReferencedEnvelope(0, 12, 0, 12, CRS.decode("EPSG:4326")); BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, re); // if everything went fine we'll have a single red dot in the middle, and we rendered // just one feature assertEquals(1, counter.get()); assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2)); } @Test public void testTransformReproject() throws Exception { // grab the style Style style = RendererBaseTest.loadStyle(this, "reproject-rt.sld"); // grab the data File property = new File(TestData.getResource(this, "point.properties").toURI()); PropertyDataStore ds = new PropertyDataStore(property.getParentFile()); FeatureSource fs = ds.getFeatureSource("point"); // prepare a feature layer with a query and the rendering tx FeatureLayer layer = new FeatureLayer(fs, style); // prepare a bbox in UTM-32N ReferencedEnvelope reWgs84 = new ReferencedEnvelope(0, 12, 0, 12, CRS.decode("EPSG:4326")); ReferencedEnvelope reUTM32N = reWgs84.transform(CRS.decode("EPSG:3857"), true); // render it MapContent mc = new MapContent(); mc.addLayer(layer); StreamingRenderer renderer = new StreamingRenderer(); final AtomicInteger counter = new AtomicInteger(); renderer.addRenderListener(new RenderListener() { @Override public void featureRenderer(SimpleFeature feature) { counter.incrementAndGet(); } @Override public void errorOccurred(Exception e) { } }); renderer.setMapContent(mc); BufferedImage image = RendererBaseTest.showRender("Lines with circle stroke", renderer, TIME, reUTM32N); // if everything went fine we rendered all the features assertEquals(10, counter.get()); assertEquals(Color.RED, getPixelColor(image, image.getWidth() / 2, image.getHeight() / 2)); } /** * Gets a specific pixel color from the specified buffered image * * @param image * @param i * @param j * @param color * @return */ protected Color getPixelColor(BufferedImage image, int i, int j) { ColorModel cm = image.getColorModel(); Raster raster = image.getRaster(); Object pixel = raster.getDataElements(i, j, null); Color actual; if (cm.hasAlpha()) { actual = new Color(cm.getRed(pixel), cm.getGreen(pixel), cm.getBlue(pixel), cm.getAlpha(pixel)); } else { actual = new Color(cm.getRed(pixel), cm.getGreen(pixel), cm.getBlue(pixel), 255); } return actual; } }