package org.mapfish.print.processor.map; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.junit.Test; import org.mapfish.print.Constants; import org.mapfish.print.attribute.map.BBoxMapBounds; import org.mapfish.print.attribute.map.CenterScaleMapBounds; import org.mapfish.print.attribute.map.MapAttribute; import org.mapfish.print.attribute.map.MapBounds; import org.mapfish.print.attribute.map.MapfishMapContext; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.crs.CRSAuthorityFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import static java.lang.Math.PI; import static org.geotools.referencing.crs.DefaultGeographicCRS.WGS84; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mapfish.print.Constants.PDF_DPI; public class MapfishMapContextTest { @Test public void testGetRoundedScale() { assertRoundedScale(0.111, 0.111); assertRoundedScale(0.11, 0.11); assertRoundedScale(9, 9); assertRoundedScale(9.1, 9); assertRoundedScale(239, 240); assertRoundedScale(993, 990); assertRoundedScale(1113, 1100); assertRoundedScale(11130, 11000); assertRoundedScale(225229, 230000); assertRoundedScale(1234229, 1200000); assertRoundedScale(12342290, 12000000); } private void assertRoundedScale(double actualScaleDenominator, double roundedScale) { MapBounds bounds = new CenterScaleMapBounds(WGS84, 0, 0, actualScaleDenominator); Dimension paint = new Dimension(200, 200); MapfishMapContext transformer = new MapfishMapContext(bounds, paint, 90, PDF_DPI, true, true); assertEquals(roundedScale, transformer.getRoundedScaleDenominator(), 0.00001); } @Test public void testGetRotation() { MapfishMapContext transformer = new MapfishMapContext(null, null, PI / 2, PDF_DPI, null, true); assertEquals("converted to radians", PI / 2, transformer.getRotation(), 1e-9); } @Test public void testGetRotatedBounds_BBoxMapBounds() { MapBounds bounds = new BBoxMapBounds(WGS84, 5, 45, 25, 55); // rotate 90 degree MapfishMapContext transformer = new MapfishMapContext(bounds, null, PI / 2, PDF_DPI, null, true); MapBounds rotatedBounds = new BBoxMapBounds(WGS84, 10, 40, 20, 60); assertEquals(rotatedBounds, transformer.getRotatedBounds()); // rotate 180 degree transformer = new MapfishMapContext(bounds, null, PI, PDF_DPI, null, true); rotatedBounds = new BBoxMapBounds(WGS84, 5, 45, 25, 55); assertEquals(rotatedBounds, transformer.getRotatedBounds()); // rotate 45 degree transformer = new MapfishMapContext(bounds, null, PI / 4, PDF_DPI, null, true); ReferencedEnvelope rotatedEnvelope = transformer.getRotatedBounds().toReferencedEnvelope(new Rectangle(1, 1)); assertEquals(4.393398, rotatedEnvelope.getMinX(), 1e-6); assertEquals(25.606601, rotatedEnvelope.getMaxX(), 1e-6); assertEquals(39.393398, rotatedEnvelope.getMinY(), 1e-6); assertEquals(60.606601, rotatedEnvelope.getMaxY(), 1e-6); // rotate 45 degree bounds = new BBoxMapBounds(WGS84, -0.5, -0.5, 0.5, 0.5); transformer = new MapfishMapContext(bounds, null, PI / 4, PDF_DPI, null, true); rotatedEnvelope = transformer.getRotatedBounds().toReferencedEnvelope(new Rectangle(1, 1)); assertEquals(-0.707106, rotatedEnvelope.getMinX(), 1e-6); assertEquals(0.707106, rotatedEnvelope.getMaxX(), 1e-6); assertEquals(-0.707106, rotatedEnvelope.getMinY(), 1e-6); assertEquals(0.707106, rotatedEnvelope.getMaxY(), 1e-6); } @Test public void testGetRotatedBounds_CenterScaleMapBounds() { MapBounds bounds = new CenterScaleMapBounds(WGS84, 0, 0, 1000); MapfishMapContext transformer = new MapfishMapContext(bounds, null, 90, PDF_DPI, true, true); // nothing changes assertEquals(bounds, transformer.getRotatedBounds()); } /** * Tests that the bounds are calculated correctly for rotations. * * For example when printing a map at [2742033.0, 1253823.0] at scale 25 000 with a map size of 780 x 330px * at 100 DPI: * - The map size is adapted to the higher resolution: 1083 x 458px * - A bbox is calculated with the center coordinate, scale and map size: [2738594.475, 1252368.85, 2745471.525, 1255277.15] * - The map size is rotated: 993.4847683568174 x 1150.9542483185592px (not rounded) and 993 x 1151px (rounded) * - The bbox is rotated: [2738878.6857910156, 1250168.7202148438, 2745187.3142089844,1257477.2797851562] * - And adapted to the rounding of the map size: [2738880.2249305826, 1250168.5749532534, 2745185.7750694174, 1257477.4250467466] */ @Test public void testGetRotatedBounds_AdaptedToPaintAreaRounding() throws FactoryException { CRSAuthorityFactory factory = CRS.getAuthorityFactory(true); CoordinateReferenceSystem epsg2056 = factory.createCoordinateReferenceSystem("EPSG:2056"); MapAttribute.MapAttributeValues mapValues = (new MapAttribute()).new MapAttributeValues(null, 780, 330); mapValues.dpi = 100; mapValues.rotation = 55.26239249861529; mapValues.setMapBounds(new CenterScaleMapBounds(epsg2056, 2742033.0, 1253823.0, 25000)); MapBounds centerBounds = mapValues.getMapBounds(); Rectangle paintAreaRotated = new Rectangle( (int) Math.round(995.0 * PDF_DPI / 100.0), (int) Math.round(1152.0 * PDF_DPI / 100.0)); ReferencedEnvelope optimalBbox = centerBounds.toReferencedEnvelope(paintAreaRotated); paintAreaRotated = new Rectangle(995, 1152); MapfishMapContext transformer = CreateMapProcessor.createMapContext(mapValues); Rectangle2D.Double paintAreaPrecise = transformer.getRotatedMapSizePrecise(); Rectangle paintArea = new Rectangle(MapfishMapContext.rectangleDoubleToDimension(paintAreaPrecise)); assertEquals(paintAreaRotated, paintArea); MapBounds rotatedBounds = transformer.getRotatedBounds(paintAreaPrecise, paintArea); ReferencedEnvelope adaptedBbox = rotatedBounds.toReferencedEnvelope(null); assertEquals(optimalBbox.getMinX(), adaptedBbox.getMinX(), 4); assertEquals(optimalBbox.getMaxX(), adaptedBbox.getMaxX(), 4); assertEquals(optimalBbox.getMinY(), adaptedBbox.getMinY(), 4); assertEquals(optimalBbox.getMaxY(), adaptedBbox.getMaxY(), 4); } @Test public void testGetRotatedMapSize() { // no rotation MapfishMapContext transformer = new MapfishMapContext(null, new Dimension(1, 1), 0, PDF_DPI, true, true); assertEquals(new Dimension(1, 1), transformer.getRotatedMapSize()); // rotate 90 degree transformer = new MapfishMapContext(null, new Dimension(2, 1), PI / 2, PDF_DPI, true, true); assertEquals(new Dimension(1, 2), transformer.getRotatedMapSize()); // rotate 180 degree transformer = new MapfishMapContext(null, new Dimension(2, 1), PI, PDF_DPI, true, true); assertEquals(new Dimension(2, 1), transformer.getRotatedMapSize()); // rotate 45 degree transformer = new MapfishMapContext(null, new Dimension(100, 100), PI / 4, PDF_DPI, true, true); Dimension rotatedMapSize = transformer.getRotatedMapSize(); assertEquals(141, rotatedMapSize.getWidth(), 1e-6); assertEquals(141, rotatedMapSize.getHeight(), 1e-6); } @Test public void testGetTransform() { MapBounds bounds = new BBoxMapBounds(WGS84, -0.5, -0.5, 0.5, 0.5); Dimension mapSize = new Dimension(100, 100); // no rotation MapfishMapContext transformer = new MapfishMapContext(bounds, mapSize, 0, PDF_DPI, true, true); assertNull(transformer.getTransform()); // rotate 180 degree transformer = new MapfishMapContext(bounds, mapSize, PI, PDF_DPI, true, true); AffineTransform transform = transformer.getTransform(); assertEquals(100, transform.getTranslateX(), 1e-6); assertEquals(100, transform.getTranslateY(), 1e-6); double[] matrix = new double[6]; transform.getMatrix(matrix); assertArrayEquals(new double[] {-1.0, 0.0, 0.0, -1.0, 100.0, 100.0}, matrix, 1e-6); // rotate 90 degree transformer = new MapfishMapContext(bounds, mapSize, PI / 2, PDF_DPI, true, true); transform = transformer.getTransform(); assertEquals(100, transform.getTranslateX(), 1e-6); assertEquals(0, transform.getTranslateY(), 1e-6); matrix = new double[6]; transform.getMatrix(matrix); assertArrayEquals(new double[] {0.0, 1.0, -1.0, -0.0, 100.0, 0.0}, matrix, 1e-6); } }