/**
  * Tests the transformations of a rectangle using a coordinate operation. With assertions enabled,
  * this also test the transformation of an envelope.
  */
 @Test
 public void testTransformationOverPole() throws FactoryException, TransformException {
   final CoordinateReferenceSystem mapCRS = CRS.parseWKT(WKT.POLAR_STEREOGRAPHIC);
   final CoordinateReferenceSystem WGS84 = DefaultGeographicCRS.WGS84;
   final CoordinateOperation operation =
       CRS.getCoordinateOperationFactory(false).createOperation(mapCRS, WGS84);
   final MathTransform transform = operation.getMathTransform();
   assertTrue(transform instanceof MathTransform2D);
   /*
    * The rectangle to test, which contains the South pole.
    */
   Rectangle2D envelope =
       XRectangle2D.createFromExtremums(
           -3943612.4042124213, -4078471.954436003, 3729092.5890516187, 4033483.085688618);
   /*
    * This is what we get without special handling of singularity point.
    * Note that is doesn't include the South pole as we would expect.
    */
   Rectangle2D expected =
       XRectangle2D.createFromExtremums(
           -178.49352310409273, -88.99136583196398, 137.56220967463082, -40.905775004205864);
   /*
    * Tests what we actually get.
    */
   Rectangle2D actual = CRS.transform((MathTransform2D) transform, envelope, null);
   assertTrue(XRectangle2D.equalsEpsilon(expected, actual));
   /*
    * Using the transform(CoordinateOperation, ...) method,
    * the singularity at South pole is taken in account.
    */
   expected = XRectangle2D.createFromExtremums(-180, -90, 180, -40.905775004205864);
   actual = CRS.transform(operation, envelope, actual);
   assertTrue(XRectangle2D.equalsEpsilon(expected, actual));
   /*
    * The rectangle to test, which contains the South pole, but this time the south
    * pole is almost in a corner of the rectangle
    */
   envelope = XRectangle2D.createFromExtremums(-4000000, -4000000, 300000, 30000);
   expected = XRectangle2D.createFromExtremums(-180, -90, 180, -41.03163170198091);
   actual = CRS.transform(operation, envelope, actual);
   assertTrue(XRectangle2D.equalsEpsilon(expected, actual));
 }
  /** Tests the transformations of an envelope. */
  @Test
  public void testEnvelopeTransformation() throws FactoryException, TransformException {
    final CoordinateReferenceSystem mapCRS = CRS.parseWKT(WKT.UTM_10N);
    final CoordinateReferenceSystem WGS84 = DefaultGeographicCRS.WGS84;
    final MathTransform crsTransform = CRS.findMathTransform(WGS84, mapCRS, true);
    assertFalse(crsTransform.isIdentity());

    final GeneralEnvelope firstEnvelope, transformedEnvelope, oldEnvelope;
    firstEnvelope = new GeneralEnvelope(new double[] {-124, 42}, new double[] {-122, 43});
    firstEnvelope.setCoordinateReferenceSystem(WGS84);

    transformedEnvelope = CRS.transform(crsTransform, firstEnvelope);
    transformedEnvelope.setCoordinateReferenceSystem(mapCRS);

    oldEnvelope = CRS.transform(crsTransform.inverse(), transformedEnvelope);
    oldEnvelope.setCoordinateReferenceSystem(WGS84);

    assertTrue(oldEnvelope.contains(firstEnvelope, true));
    assertTrue(oldEnvelope.equals(firstEnvelope, 0.02, true));
  }
  /**
   * Tests the transformations of an envelope when the two CRS have identify transforms but
   * different datum names
   */
  @Test
  public void testEnvelopeTransformation2() throws FactoryException, TransformException {
    final CoordinateReferenceSystem WGS84Altered = CRS.parseWKT(WKT.WGS84_ALTERED);
    final CoordinateReferenceSystem WGS84 = DefaultGeographicCRS.WGS84;
    final MathTransform crsTransform = CRS.findMathTransform(WGS84, WGS84Altered, true);
    assertTrue(crsTransform.isIdentity());

    final GeneralEnvelope firstEnvelope;
    firstEnvelope = new GeneralEnvelope(new double[] {-124, 42}, new double[] {-122, 43});
    firstEnvelope.setCoordinateReferenceSystem(WGS84);

    // this triggered a assertion error in GEOT-2934
    Envelope transformed = CRS.transform(firstEnvelope, WGS84Altered);

    // check the envelope is what we expect
    assertEquals(transformed.getCoordinateReferenceSystem(), WGS84Altered);
    double EPS = 1e-9;
    assertEquals(transformed.getMinimum(0), firstEnvelope.getMinimum(0), EPS);
    assertEquals(transformed.getMinimum(1), firstEnvelope.getMinimum(1), EPS);
    assertEquals(transformed.getMaximum(0), firstEnvelope.getMaximum(0), EPS);
    assertEquals(transformed.getMaximum(1), firstEnvelope.getMaximum(1), EPS);
  }