Geometry postProcessed = handler.postProcess(transform.inverse(), transformed); if (postProcessed == null) { return null;
Geometry postProcessed = handler.postProcess(mt, polygon);
@Test public void testUTMDatelineWrapping() throws Exception { CoordinateReferenceSystem crs = CRS.decode("EPSG:32601", true); ReferencedEnvelope re = new ReferencedEnvelope(300000, 409800, 5890200, 6000000, crs); MathTransform mt = CRS.findMathTransform(crs, WGS84); Geometry geom = JTS.toGeometry(re); ReferencedEnvelope targetReferenceEnvelope = new ReferencedEnvelope(-180, 180, -90, 90, WGS84); ProjectionHandler ph = ProjectionHandlerFinder.getHandler(targetReferenceEnvelope, crs, true); Geometry preProcessed = ph.preProcess(geom); Geometry transformed = JTS.transform(preProcessed, mt); Geometry postProcessed = ph.postProcess(mt.inverse(), transformed); // sits across the dateline and it's "small" (used to cover the entire planet) Envelope ppEnvelope = postProcessed.getGeometryN(0).getEnvelopeInternal(); assertTrue(ppEnvelope.contains(180, 54)); // the original width is 109km, at this latitude one degree of longitude is only 65km assertEquals(1.7, ppEnvelope.getWidth(), 0.1); }
geom = projectionHandler.postProcess(reverse, geom); if (geom == null) { shape = null;
if (preProcessed != null) { Geometry transformed = JTS.transform(inclusionGeometry, mt); inclusionGeometry = handler.postProcess(mt.inverse(), transformed);
@Test public void testWrapJumpLast() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-180, 180, -90, 90, WGS84); Geometry g = new WKTReader().read("POLYGON((-131 -73.5,0 -90,163 -60,174 -60,-131 -73.5))"); Geometry original = new WKTReader().read("POLYGON((-131 -73.5,0 -90,163 -60,174 -60,-131 -73.5))"); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process (provide identity transform to force wrap heuristic) Geometry postProcessed = handler.postProcess(CRS.findMathTransform(WGS84, WGS84), g); // check the geometry is in the same area as the rendering envelope assertEquals(original, postProcessed); }
@Test public void testLimitExcessiveDuplication() throws Exception { // a veeeery large rendering envelope, enough to trigger whatever are the default // protection limits (yes, it's in degrees!) ReferencedEnvelope renderingEnvelope = new ReferencedEnvelope(-1800000, 1800000, -50, 50, WGS84); // the geometry that will be wrapped Geometry g = new WKTReader().read("LINESTRING(-179 -89, 179 89)"); // make sure the geometry is not pre-processed ProjectionHandler handler = ProjectionHandlerFinder.getHandler(renderingEnvelope, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); assertEquals(g, preProcessed); Geometry postProcessed = handler.postProcess(IdentityTransform.create(2), g); // should have been copied several times, but not above the limit assertTrue(postProcessed instanceof MultiLineString); MultiLineString mls = (MultiLineString) postProcessed; assertEquals(ProjectionHandlerFinder.WRAP_LIMIT * 2 + 1, mls.getNumGeometries()); }
@Test public void testWorldLargeGeometry() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-180, 180, -90, 90, WGS84); // a geometry close to the dateline Geometry g = new WKTReader().read("POLYGON((-178 -90, -178 90, 178 90, 178 -90, -178 -90))"); Geometry original = new WKTReader().read("POLYGON((-178 -90, -178 90, 178 90, 178 -90, -178 -90))"); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process (provide identity transform to force wrap heuristic) Geometry postProcessed = handler.postProcess(CRS.findMathTransform(WGS84, WGS84), g); // check the geometry is in the same area as the rendering envelope assertEquals(original, postProcessed); }
@Test public void testWorldMeridian() throws Exception { ReferencedEnvelope requestWgs84 = new ReferencedEnvelope(-180, 180, -85, 85, WGS84); ReferencedEnvelope requestWebMercator = requestWgs84.transform(OSM, true); // a geometry close to the dateline Geometry g = new WKTReader().read("LINESTRING(0 -90, 0 90)"); Geometry expected = new WKTReader().read("LINESTRING(0 -85, 0 85)"); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(requestWebMercator, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // should have cut at 85 degrees, the web mercator breaks at the poles assertEquals(expected, preProcessed); // post process (provide identity transform to force wrap heuristic) Geometry postProcessed = handler.postProcess(CRS.findMathTransform(WGS84, WGS84), expected); // check the geometry is in the same area as the rendering envelope assertEquals(expected, postProcessed); }
@Test public void testWrapGeometrySmall() throws Exception { // projected dateline CRS CoordinateReferenceSystem FIJI = CRS.decode("EPSG:3460", true); // a small geometry that will cross the dateline Geometry g = new WKTReader() .read( "POLYGON ((2139122 5880020, 2139122 5880030, 2139922 5880030, 2139122 5880020))"); Geometry original = g.copy(); // rendering bounds only slightly bigger than geometry ReferencedEnvelope world = new ReferencedEnvelope(178, 181, -1, 1, WGS84); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, FIJI, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process MathTransform mt = CRS.findMathTransform(FIJI, WGS84); Geometry transformed = JTS.transform(g, mt); Geometry postProcessed = handler.postProcess(mt.inverse(), transformed); // check the geometry is in the same area as the rendering envelope assertTrue(world.contains(postProcessed.getEnvelopeInternal())); }
final Geometry postProcessed = handler.postProcess(mt, transformed);
@Test public void testWrapGeometryLatLonMultipleTimes() throws Exception { ReferencedEnvelope renderingEnvelope = new ReferencedEnvelope(-90, 90, -580, 540, ED50_LATLON); // a geometry close to the dateline Geometry g = new WKTReader().read("POLYGON((-74 -33, -29 -33, -29 5, -74 5, -74 -33))"); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(renderingEnvelope, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); MathTransform mt = handler.getRenderingTransform(CRS.findMathTransform(WGS84, ED50_LATLON)); Geometry transformed = JTS.transform(preProcessed, mt); // post process (provide identity transform to force wrap heuristic) Geometry postProcessed = handler.postProcess(mt, transformed); assertTrue(postProcessed.isValid()); // should have been replicated three times assertEquals(3, postProcessed.getNumGeometries()); }
@Test public void testWrapGeometryWGS84Duplicate() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-200, 200, -90, 90, WGS84); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope Geometry g = new WKTReader().read("POLYGON((-178 -90, -178 90, 178 90, 178 -90, -178 -90))"); Geometry original = new WKTReader().read("POLYGON((-178 -90, -178 90, 178 90, 178 -90, -178 -90))"); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process Geometry postProcessed = handler.postProcess(null, g); // check we have replicated the geometry in both directions Envelope ppEnvelope = postProcessed.getEnvelopeInternal(); Envelope expected = new Envelope(-538, 538, -90, 90); assertEquals(expected, ppEnvelope); }
@Test public void testWrapGeometryReprojectToED50() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-80, 80, -180, 180, ED50); ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope (with wgs84 lon/latcoordinates) String wkt = "POLYGON((178 -80, 178 80, 182 80, 182 80, 178 -80))"; Geometry g = new WKTReader().read(wkt); Geometry original = new WKTReader().read(wkt); MathTransform mt = CRS.findMathTransform(WGS84, ED50); mt = handler.getRenderingTransform(mt); Geometry reprojected = JTS.transform(original, mt); // make sure the geometry is not wrapped, but it is preserved assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process, this should wrap the geometry and clone it Geometry postProcessed = handler.postProcess(mt, reprojected); assertTrue(postProcessed instanceof MultiPolygon); }
@Test public void testWrapAnctartica() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-80, 80, -180, 180, ED50_LATLON); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope (with wgs84 lon/latcoordinates) String wkt = "POLYGON((180 -90, 180 90, -180 90, -180 -90, 180 -90))"; Geometry g = new WKTReader().read(wkt); MathTransform mt = CRS.findMathTransform(WGS84, ED50_LATLON); MathTransform prepared = handler.getRenderingTransform(mt); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); Geometry reprojected = JTS.transform(preProcessed, prepared); assertTrue(reprojected.isValid()); reprojected.apply( new CoordinateFilter() { @Override public void filter(Coordinate coord) { assertEquals(90.0, Math.abs(coord.getOrdinate(0)), 0.1); assertEquals(180.0, Math.abs(coord.getOrdinate(1)), 5); } }); // post process, this should wrap the geometry, make sure it's valid, and avoid large jumps // in its border Geometry postProcessed = handler.postProcess(prepared, reprojected); assertThat(postProcessed, CoreMatchers.instanceOf(MultiPolygon.class)); assertEquals(2, postProcessed.getNumGeometries()); }
@Test public void testWrapGeometryReprojectToLatLonED50() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-80, 80, -180, 180, ED50_LATLON); // make sure the geometry is not wrapped, but it is preserved ProjectionHandler handler = ProjectionHandlerFinder.getHandler(world, WGS84, true); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope (with wgs84 lon/latcoordinates) String wkt = "POLYGON((178 -80, 178 80, 182 80, 182 80, 178 -80))"; Geometry g = new WKTReader().read(wkt); Geometry original = new WKTReader().read(wkt); MathTransform mt = CRS.findMathTransform(WGS84, ED50_LATLON); MathTransform prepared = handler.getRenderingTransform(CRS.findMathTransform(WGS84, ED50_LATLON)); Geometry reprojected = JTS.transform(original, prepared); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(original, preProcessed); // post process, this should wrap the geometry and clone it Geometry postProcessed = handler.postProcess(prepared, reprojected); assertTrue(postProcessed instanceof MultiPolygon); }
@Test public void testWrapGeometryMercator() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(160, 180, -40, 40, WGS84); ReferencedEnvelope mercatorEnvelope = world.transform(MERCATOR, true); // move it so that it crosses the dateline (measures are still accurate for something // crossing the dateline mercatorEnvelope.translate(mercatorEnvelope.getWidth() / 2, 0); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope Geometry g = new WKTReader().read("LINESTRING(170 -40, 190 40)"); // make sure the geometry is not wrapped ProjectionHandler handler = ProjectionHandlerFinder.getHandler(mercatorEnvelope, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(g, preProcessed); // transform and post process MathTransform mt = CRS.findMathTransform(WGS84, MERCATOR, true); Geometry transformed = JTS.transform(g, mt); Geometry postProcessed = handler.postProcess(mt.inverse(), transformed); Envelope env = postProcessed.getEnvelopeInternal(); // check the geometry is in the same area as the rendering envelope assertEquals(mercatorEnvelope.getMinX(), env.getMinX(), EPS); assertEquals(mercatorEnvelope.getMaxX(), env.getMaxX(), EPS); }
@Test public void testDuplicateGeometryMercator() throws Exception { ReferencedEnvelope world = new ReferencedEnvelope(-180, 180, -50, 50, WGS84); ReferencedEnvelope mercatorEnvelope = world.transform(MERCATOR, true); // a geometry that will cross the dateline and sitting in the same area as the // rendering envelope Geometry g = new WKTReader().read("LINESTRING(170 -50, 190 50)"); // make sure the geometry is not wrapped ProjectionHandler handler = ProjectionHandlerFinder.getHandler(mercatorEnvelope, WGS84, true); assertTrue(handler.requiresProcessing(g)); Geometry preProcessed = handler.preProcess(g); // no cutting expected assertEquals(g, preProcessed); // transform and post process MathTransform mt = CRS.findMathTransform(WGS84, MERCATOR, true); Geometry transformed = JTS.transform(g, mt); Geometry postProcessed = handler.postProcess(mt, transformed); // should have been duplicated in two parts assertTrue(postProcessed instanceof MultiLineString); MultiLineString mls = (MultiLineString) postProcessed; assertEquals(2, mls.getNumGeometries()); // the two geometries width should be the same as 20° double twentyDegWidth = mercatorEnvelope.getWidth() / 18; assertEquals(twentyDegWidth, mls.getGeometryN(0).getEnvelopeInternal().getWidth(), EPS); assertEquals(twentyDegWidth, mls.getGeometryN(1).getEnvelopeInternal().getWidth(), EPS); }
geom = projectionHandler.postProcess(reverse, geom); if(geom == null) { shape = null;