ProjectionHandler { public Geometry preProcess(Geometry geometry) throws TransformException, FactoryException { if(validAreaBounds == null) return geometry; CoordinateReferenceSystem geometryCRS = CRS.getHorizontalCRS(sourceCRS); if (geometryCRS == null || CRS.findMathTransform(geometryCRS, renderingEnvelope.getCoordinateReferenceSystem()).isIdentity()) { return geometry; } Geometry mask; if(validArea == null) { ReferencedEnvelope ge = new ReferencedEnvelope(geometry.getEnvelopeInternal(), geometryCRS); ReferencedEnvelope geWGS84 = ge.transform(WGS84, true); if (validAreaBounds.contains((Envelope) geWGS84)) { return geometry; } ReferencedEnvelope envIntWgs84 = new ReferencedEnvelope(validAreaBounds.intersection(geWGS84), WGS84); if(envIntWgs84.isEmpty()) { return null; } ReferencedEnvelope envInt = envIntWgs84.transform(geometryCRS, true); mask = JTS.toGeometry((Envelope) envInt); } else { ReferencedEnvelope ge = new ReferencedEnvelope(geometry.getEnvelopeInternal(), geometryCRS); ReferencedEnvelope geWGS84 = ge.transform(WGS84, true); if (validaAreaTester.contains(JTS.toGeometry(geWGS84))) { return geometry; } ReferencedEnvelope envIntWgs84 = new ReferencedEnvelope(validAreaBounds.intersection(geWGS84), WGS84); if(envIntWgs84.isEmpty()) { return null; } Polygon polyIntWgs84 = JTS.toGeometry(envIntWgs84); Geometry maskWgs84 = intersect(validArea, polyIntWgs84, geometryCRS); if(maskWgs84 == null || maskWgs84.isEmpty()) { return null; } mask = JTS.transform(maskWgs84, CRS.findMathTransform(WGS84, geometryCRS)); } return intersect(geometry, mask, geometryCRS); } ProjectionHandler(CoordinateReferenceSystem sourceCRS, Envelope validAreaBounds, ReferencedEnvelope renderingEnvelope);  ProjectionHandler(CoordinateReferenceSystem sourceCRS, Geometry validArea, ReferencedEnvelope renderingEnvelope); ReferencedEnvelope getRenderingEnvelope(); CoordinateReferenceSystem getSourceCRS(); List<ReferencedEnvelope> getQueryEnvelopes(); boolean requiresProcessing(Geometry geometry); Geometry preProcess(Geometry geometry); MathTransform getRenderingTransform(MathTransform mt); Geometry postProcess(MathTransform mt, Geometry geometry); ReferencedEnvelope getValidAreaBounds();  }
@Test public void testCutGeometryLambertConformal() throws Exception { ReferencedEnvelope wgs84South = new ReferencedEnvelope(-180, -90, -40, 0, WGS84); ReferencedEnvelope laeSouth = wgs84South.transform(CRS.decode("EPSG:2194"), true); ProjectionHandler handler = ProjectionHandlerFinder.getHandler(laeSouth, WGS84, true); Polygon geometry = JTS.toGeometry(new Envelope(5, 15, 0, 10)); Geometry preProcessed = handler.preProcess(geometry); assertTrue("Should have sliced the geometry in two parts", preProcessed instanceof MultiPolygon); }
@Test public void testRobustCutting() throws Exception { String wkt = "PROJCS[\"Asia_South_Lambert_Conformal_Conic\", \n" + " GEOGCS[\"GCS_WGS_1984\", \n" + " DATUM[\"WGS_1984\", \n" + " SPHEROID[\"WGS_1984\", 6378137.0, 298.257223563]], \n" + " PRIMEM[\"Greenwich\", 0.0], \n" + " UNIT[\"degree\", 0.017453292519943295], \n" + " AXIS[\"Longitude\", EAST], \n" + " AXIS[\"Latitude\", NORTH]], \n" + " PROJECTION[\"Lambert_Conformal_Conic_2SP\"], \n" + " PARAMETER[\"central_meridian\", 125.0], \n" + " PARAMETER[\"latitude_of_origin\", -15.0], \n" + " PARAMETER[\"standard_parallel_1\", 7.0], \n" + " PARAMETER[\"false_easting\", 0.0], \n" + " PARAMETER[\"false_northing\", 0.0], \n" + " PARAMETER[\"scale_factor\", 1.0], \n" + " PARAMETER[\"standard_parallel_2\", -32.0], \n" + " UNIT[\"m\", 1.0], \n" + " AXIS[\"x\", EAST], \n" + " AXIS[\"y\", NORTH], \n" + " AUTHORITY[\"EPSG\",\"102030\"]]"; CoordinateReferenceSystem crs = CRS.parseWKT(wkt); Geometry geom; try (Reader reader = new InputStreamReader(new GZIPInputStream( ProjectionHandlerTest.class.getResourceAsStream("para.wkt.gz")))) { geom = new WKTReader().read(reader); } ReferencedEnvelope re = new ReferencedEnvelope(1.2248782489837505E7, 2.0320948299686E7, -4848266.752703998, 3223899.0571445003, crs); ProjectionHandler handler = ProjectionHandlerFinder.getHandler(re, WGS84, true); Geometry preprocessed = handler.preProcess(geom); assertNotEquals(preprocessed, geom); }