org.opengis.geometry.Envelope Java Examples

The following examples show how to use org.opengis.geometry.Envelope. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ArrayEnvelope.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs a new envelope with the same data than the specified envelope.
 *
 * @param envelope  the envelope to copy.
 */
public ArrayEnvelope(final Envelope envelope) {
    ensureNonNull("envelope", envelope);
    /*
     * Do not optimize with `if (envelope instanceof ArrayEnvelope)` because subclasses may change the semantic.
     * In particular the SubEnvelope subclass uses only a subrange of this array. If we still want to optimize,
     * we would have to test for specific classes. It is probably not worth at this stage.
     */
    crs = envelope.getCoordinateReferenceSystem();
    final int dimension = envelope.getDimension();
    coordinates = new double[dimension * 2];
    final DirectPosition lowerCorner = envelope.getLowerCorner();
    final DirectPosition upperCorner = envelope.getUpperCorner();
    for (int i=0; i<dimension; i++) {
        coordinates[i]           = lowerCorner.getOrdinate(i);
        coordinates[i+dimension] = upperCorner.getOrdinate(i);
    }
    verifyRanges(crs, coordinates);
}
 
Example #2
Source File: StoreUtilities.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the spatiotemporal envelope of the given metadata.
 * This method computes the union of all {@link GeographicBoundingBox} in the metadata, assuming the
 * {@linkplain org.apache.sis.referencing.CommonCRS#defaultGeographic() default geographic CRS}
 * (usually WGS 84).
 *
 * @param  metadata  the metadata from which to compute the envelope, or {@code null}.
 * @return the spatiotemporal extent, or {@code null} if none.
 */
public static Envelope getEnvelope(final Metadata metadata) {
    GeneralEnvelope bounds = null;
    if (metadata != null) {
        for (final Identification identification : metadata.getIdentificationInfo()) {
            if (!(identification instanceof AbstractIdentification)) {
                continue;       // Following cast is specific to GeoAPI 3.0 branch.
            }
            for (final Extent extent : ((AbstractIdentification) identification).getExtents()) {
                for (final GeographicExtent ge : extent.getGeographicElements()) {
                    if (ge instanceof GeographicBoundingBox) {
                        final GeneralEnvelope env = new GeneralEnvelope((GeographicBoundingBox) ge);
                        if (bounds == null) {
                            bounds = env;
                        } else {
                            bounds.add(env);
                        }
                    }
                }
            }
        }
    }
    return bounds;
}
 
Example #3
Source File: WraparoundAdjustmentTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link WraparoundAdjustment#shift(Envelope)}
 * with an envelope that cause the method to expand the area of interest. Illustration:
 *
 * {@preformat text
 *                  ┌────────────────────────────────────────────┐
 *                  │             Domain of validity             │
 *                  └────────────────────────────────────────────┘
 *   ┌────────────────────┐                                ┌─────
 *   │  Area of interest  │                                │  AOI
 *   └────────────────────┘                                └─────
 *    ↖………………………………………………………360° period……………………………………………………↗︎
 * }
 *
 * @throws TransformException should never happen since this test does not transform coordinates.
 */
@Test
public void testAxesCausingExpansion() throws TransformException {
    final GeneralEnvelope domainOfValidity = new GeneralEnvelope(HardCodedCRS.WGS84);
    domainOfValidity.setRange(0,   5, 345);
    domainOfValidity.setRange(1, -70, +70);

    final GeneralEnvelope areaOfInterest = new GeneralEnvelope(HardCodedCRS.WGS84);
    areaOfInterest.setRange(0, -30,  40);
    areaOfInterest.setRange(1, -60,  60);

    final GeneralEnvelope expected = new GeneralEnvelope(HardCodedCRS.WGS84);
    expected.setRange(0, -30, 400);
    expected.setRange(1, -60,  60);

    final Envelope actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
    assertEnvelopeEquals(expected, actual);
}
 
Example #4
Source File: DatumShiftGridFile.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a transformation between two geodetic CRS, including the sub-grid transforms.
 * If the given grid has no sub-grid, then this method is equivalent to a direct call to
 * {@link InterpolatedTransform#createGeodeticTransformation(MathTransformFactory, DatumShiftGrid)}.
 *
 * @param  provider  the provider which is creating a transform.
 * @param  factory   the factory to use for creating the transform.
 * @param  grid      the grid of datum shifts from source to target datum.
 * @return the transformation between geodetic coordinates.
 * @throws FactoryException if an error occurred while creating a transform.
 *
 * @see InterpolatedTransform#createGeodeticTransformation(MathTransformFactory, DatumShiftGrid)
 */
public static MathTransform createGeodeticTransformation(final Class<? extends AbstractProvider> provider,
        final MathTransformFactory factory, final DatumShiftGridFile<Angle,Angle> grid) throws FactoryException
{
    MathTransform global = InterpolatedTransform.createGeodeticTransformation(factory, grid);
    final DatumShiftGridFile<Angle,Angle>[] subgrids = grid.subgrids;
    if (subgrids == null) {
        return global;
    }
    final Map<Envelope,MathTransform> specializations = new LinkedHashMap<>(Containers.hashMapCapacity(subgrids.length));
    for (final DatumShiftGridFile<Angle,Angle> sg : subgrids) try {
        final Envelope domain = sg.getDomainOfValidity(Units.DEGREE);
        final MathTransform st = createGeodeticTransformation(provider, factory, sg);
        if (specializations.putIfAbsent(domain, st) != null) {
            DatumShiftGridLoader.log(provider, Errors.getResources((Locale) null)
                    .getLogRecord(Level.FINE, Errors.Keys.DuplicatedElement_1, domain));
        }
    } catch (TransformException e) {
        throw new FactoryException(e);
    }
    return MathTransforms.specialize(global, specializations);
}
 
Example #5
Source File: FitToIndexGridCoverage.java    From geowave with Apache License 2.0 6 votes vote down vote up
public FitToIndexGridCoverage(
    final GridCoverage gridCoverage,
    final byte[] partitionKey,
    final byte[] sortKey,
    final Resolution resolution,
    final Envelope originalEnvelope,
    final Geometry footprintWorldGeometry,
    final Geometry footprintScreenGeometry,
    final Map properties) {
  this.gridCoverage = gridCoverage;
  this.partitionKey = partitionKey;
  this.sortKey = sortKey;
  this.resolution = resolution;
  this.originalEnvelope = originalEnvelope;
  this.footprintWorldGeometry = footprintWorldGeometry;
  this.footprintScreenGeometry = footprintScreenGeometry;
  this.properties = properties;
}
 
Example #6
Source File: AbstractEnvelopeTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Verifies some invariants for the given envelope of the given type.
 */
private static void verifyInvariants(final int type, final Envelope envelope) {
    assertSame(WGS84, envelope.getCoordinateReferenceSystem());
    switch (type) {
        case SUBENVELOPE: {
            // Asserts that other dimensions in the original envelope has not been modified.
            final double[] coordinates = ((SubEnvelope) envelope).coordinates;
            assertEquals(2, coordinates[0], STRICT);
            assertEquals(3, coordinates[5], STRICT);
            assertEquals(4, coordinates[3], STRICT);
            assertEquals(6, coordinates[8], STRICT);
            assertEquals(8, coordinates[4], STRICT);
            assertEquals(9, coordinates[9], STRICT);
            break;
        }
    }
}
 
Example #7
Source File: RasterUtils.java    From geowave with Apache License 2.0 6 votes vote down vote up
public static ReferencedEnvelope getReferenceEnvelope(
    final GridCoverage gridCoverage,
    final CoordinateReferenceSystem targetCrs) {
  final CoordinateReferenceSystem sourceCrs = gridCoverage.getCoordinateReferenceSystem();
  final Envelope sampleEnvelope = gridCoverage.getEnvelope();

  final ReferencedEnvelope sampleReferencedEnvelope =
      new ReferencedEnvelope(
          new org.locationtech.jts.geom.Envelope(
              sampleEnvelope.getMinimum(0),
              sampleEnvelope.getMaximum(0),
              sampleEnvelope.getMinimum(1),
              sampleEnvelope.getMaximum(1)),
          gridCoverage.getCoordinateReferenceSystem());

  ReferencedEnvelope projectedReferenceEnvelope = sampleReferencedEnvelope;
  if ((targetCrs != null) && !targetCrs.equals(sourceCrs)) {
    try {
      projectedReferenceEnvelope = sampleReferencedEnvelope.transform(targetCrs, true);
    } catch (TransformException | FactoryException e) {
      LOGGER.warn("Unable to transform envelope of grid coverage to " + targetCrs.getName(), e);
    }
  }
  return projectedReferenceEnvelope;
}
 
Example #8
Source File: MosaicFormModel.java    From snap-desktop with GNU General Public License v3.0 6 votes vote down vote up
public Product getBoundaryProduct() throws FactoryException, TransformException {
    final CoordinateReferenceSystem mapCRS = getTargetCRS();
    if (mapCRS != null) {
        final ReferencedEnvelope envelope = getTargetEnvelope();
        final Envelope mapEnvelope = envelope.transform(mapCRS, true);

        final double pixelSizeX = (Double) getPropertyValue(PROPERTY_PIXEL_SIZE_X);
        final double pixelSizeY = (Double) getPropertyValue(PROPERTY_PIXEL_SIZE_Y);
        final int w = MathUtils.floorInt(mapEnvelope.getSpan(0) / pixelSizeX);
        final int h = MathUtils.floorInt(mapEnvelope.getSpan(1) / pixelSizeY);

        final Product product = new Product("mosaic", "MosaicBounds", w, h);
        final GeoCoding geoCoding = new CrsGeoCoding(mapCRS,
                                                     w, h,
                                                     mapEnvelope.getMinimum(0),
                                                     mapEnvelope.getMaximum(1),
                                                     pixelSizeX, pixelSizeY);
        product.setSceneGeoCoding(geoCoding);

        return product;
    }
    return null;
}
 
Example #9
Source File: CoverageUtilities.java    From hortonmachine with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Get the array of region parameters covered by the {@link GridCoverage2D coverage}. 
 * 
 * @param gridCoverage the coverage.
 * @return the array of region parameters as [n, s, w, e, xres, yres, cols, rows]
 */
public static double[] getRegionArrayFromGridCoverage( GridCoverage2D gridCoverage ) {
    Envelope envelope = gridCoverage.getEnvelope();
    DirectPosition lowerCorner = envelope.getLowerCorner();
    double[] westSouth = lowerCorner.getCoordinate();
    DirectPosition upperCorner = envelope.getUpperCorner();
    double[] eastNorth = upperCorner.getCoordinate();

    GridGeometry2D gridGeometry = gridCoverage.getGridGeometry();
    GridEnvelope2D gridRange = gridGeometry.getGridRange2D();
    int height = gridRange.height;
    int width = gridRange.width;

    AffineTransform gridToCRS = (AffineTransform) gridGeometry.getGridToCRS();
    double xRes = XAffineTransform.getScaleX0(gridToCRS);
    double yRes = XAffineTransform.getScaleY0(gridToCRS);

    double[] params = new double[]{eastNorth[1], westSouth[1], westSouth[0], eastNorth[0], xRes, yRes, width, height};

    return params;
}
 
Example #10
Source File: WraparoundAdjustmentTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link WraparoundAdjustment#shift(Envelope)}
 * with an envelope crossing the anti-meridian.
 *
 * @throws TransformException should never happen since this test does not transform coordinates.
 */
@Test
public void testOverAntiMeridian() throws TransformException {
    final GeneralEnvelope domainOfValidity = new GeneralEnvelope(HardCodedCRS.WGS84);
    domainOfValidity.setRange(0,  80, 280);
    domainOfValidity.setRange(1, -90, +90);

    final GeneralEnvelope areaOfInterest = new GeneralEnvelope(HardCodedCRS.WGS84);
    areaOfInterest.setRange(0, 140, -179);                 // Cross anti-meridian.
    areaOfInterest.setRange(1, -90,   90);

    final GeneralEnvelope expected = new GeneralEnvelope(HardCodedCRS.WGS84);
    expected.setRange(0, 140, 181);
    expected.setRange(1, -90, +90);

    final Envelope actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
    assertEnvelopeEquals(expected, actual);
}
 
Example #11
Source File: SwtMapPane.java    From gama with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Check if the envelope corresponds to full extent. It will probably not equal the full extent envelope because of
 * slack space in the display area, so we check that at least one pair of opposite edges are equal to the full
 * extent envelope, allowing for slack space on the other two sides.
 * <p>
 * Note: this method returns {@code false} if the full extent envelope is wholly within the requested envelope (e.g.
 * user has zoomed out from full extent), only touches one edge, or touches two adjacent edges. In all these cases
 * we assume that the user wants to maintain the slack space in the display.
 * <p>
 * This method is part of the work-around that the map pane needs because of the differences in how raster and
 * vector layers are treated by the renderer classes.
 *
 * @param envelope
 *            a pending display envelope to compare to the full extent envelope
 *
 * @return true if the envelope is coincident with the full extent evenlope on at least two edges; false otherwise
 *
 * @todo My logic here seems overly complex - I'm sure there must be a simpler way for the map pane to handle this.
 */
private boolean equalsFullExtent(final Envelope envelope) {
	if (fullExtent == null || envelope == null) { return false; }

	final double TOL = 1.0e-6d * (fullExtent.getWidth() + fullExtent.getHeight());

	boolean touch = false;
	if (Math.abs(envelope.getMinimum(0) - fullExtent.getMinimum(0)) < TOL) {
		touch = true;
	}
	if (Math.abs(envelope.getMaximum(0) - fullExtent.getMaximum(0)) < TOL) {
		if (touch) { return true; }
	}
	if (Math.abs(envelope.getMinimum(1) - fullExtent.getMinimum(1)) < TOL) {
		touch = true;
	}
	if (Math.abs(envelope.getMaximum(1) - fullExtent.getMaximum(1)) < TOL) {
		if (touch) { return true; }
	}

	return false;
}
 
Example #12
Source File: MilitaryGridReferenceSystemTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Implementation of {@code testIteratorXXX()} methods.
 */
private static void testIterator(final Envelope areaOfInterest, final List<String> expected) throws TransformException {
    final MilitaryGridReferenceSystem.Coder coder = coder();
    coder.setClipToValidArea(false);
    coder.setPrecision(100000);
    /*
     * Test sequential iteration using iterator.
     */
    final Set<String> remaining = new HashSet<>(expected);
    assertEquals("List of expected codes has duplicated values.", expected.size(), remaining.size());
    for (final Iterator<String> it = coder.encode(areaOfInterest); it.hasNext();) {
        final String code = it.next();
        assertTrue(code, remaining.remove(code));
    }
    assertTrue(remaining.toString(), remaining.isEmpty());
    /*
     * Test parallel iteration using stream.
     */
    assertTrue(remaining.addAll(expected));
    final Set<String> sync = Collections.synchronizedSet(remaining);
    assertEquals("List of expected codes has duplicated values.", expected.size(), sync.size());
    coder.encode(areaOfInterest, true).forEach((code) -> assertTrue(code, sync.remove(code)));
    assertTrue(sync.toString(), sync.isEmpty());
}
 
Example #13
Source File: Formatter.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tries to append an object of the {@code KEYWORD[something]} form. The given value is typically,
 * but not necessarily, a {@link FormattableObject} object or an instance of an interface that can
 * be converted to {@code FormattableObject}.
 *
 * @return {@code true} on success, or {@code false} if the given type is not recognized.
 */
final boolean appendElement(final Object value) {
    if (value instanceof FormattableObject) {
        append((FormattableObject) value);
    } else if (value instanceof IdentifiedObject) {
        append(AbstractIdentifiedObject.castOrCopy((IdentifiedObject) value));
    } else if (value instanceof MathTransform) {
        append((MathTransform) value);
    } else if (value instanceof Unit<?>) {
        append((Unit<?>) value);
    } else if (value instanceof GeographicBoundingBox) {
        append((GeographicBoundingBox) value, BBOX_ACCURACY);
    } else if (value instanceof VerticalExtent) {
        appendVerticalExtent(Extents.getVerticalRange(new SimpleExtent(null, (VerticalExtent) value, null)));
    } else if (value instanceof TemporalExtent) {
        appendTemporalExtent(Extents.getTimeRange(new SimpleExtent(null, null, (TemporalExtent) value)));
    } else if (value instanceof Position) {
        append(AbstractDirectPosition.castOrCopy(((Position) value).getDirectPosition()));
    } else if (value instanceof Envelope) {
        append(AbstractEnvelope.castOrCopy((Envelope) value));          // Non-standard
    } else {
        return false;
    }
    return true;
}
 
Example #14
Source File: Envelope2D.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns {@code true} if {@code this} envelope bounds is equal to {@code that} envelope
 * bounds in two specified dimensions. The coordinate reference system is not compared, since
 * it doesn't need to have the same number of dimensions.
 *
 * @param that  the envelope to compare to.
 * @param xDim  the dimension of {@code that} envelope to compare to the <var>x</var> dimension of {@code this} envelope.
 * @param yDim  the dimension of {@code that} envelope to compare to the <var>y</var> dimension of {@code this} envelope.
 * @param eps   a small tolerance number for floating point number comparisons. This value will be scaled
 *              according this envelope {@linkplain #width width} and {@linkplain #height height}.
 * @return {@code true} if the envelope bounds are the same (up to the specified tolerance
 *         level) in the specified dimensions, or {@code false} otherwise.
 */
public boolean boundsEquals(final Envelope that, final int xDim, final int yDim, double eps) {
    eps *= 0.5*(width + height);
    for (int i=0; i<4; i++) {
        final int dim2D = (i & 1);
        final int dimND = (dim2D == 0) ? xDim : yDim;
        final double value2D, valueND;
        if ((i & 2) == 0) {
            value2D = this.getMinimum(dim2D);
            valueND = that.getMinimum(dimND);
        } else {
            value2D = this.getMaximum(dim2D);
            valueND = that.getMaximum(dimND);
        }
        // Use '!' for catching NaN values.
        if (!(Math.abs(value2D - valueND) <= eps)) {
            return false;
        }
    }
    return true;
}
 
Example #15
Source File: WraparoundAdjustmentTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link WraparoundAdjustment#shift(Envelope)} with a projected envelope.
 *
 * @throws TransformException if an error occurred while projecting a coordinate.
 */
@Test
public void testWithProjection() throws TransformException {
    final GeneralEnvelope domainOfValidity = new GeneralEnvelope(HardCodedCRS.WGS84);
    domainOfValidity.setRange(0,  50,  60);
    domainOfValidity.setRange(1, -70, +70);

    final DefaultProjectedCRS mercator = HardCodedConversions.mercator();
    final GeneralEnvelope areaOfInterest = new GeneralEnvelope(mercator);
    areaOfInterest.setRange(0,   5000000,  7000000);                        // About 45°E to 63°E
    areaOfInterest.setRange(1, -10000000, 10000000);                        // About 66.6°S to 66.6°N
    /*
     * AOI intersects the domain of validity: expected result is identical to given AOI.
     */
    final GeneralEnvelope expected = new GeneralEnvelope(areaOfInterest);
    final MathTransform validToAOI = mercator.getConversionFromBase().getMathTransform();
    Envelope actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, validToAOI);
    assertEnvelopeEquals(expected, actual);
    /*
     * AOI is on the right side of domain of validity. Expect a 360° shift to the left.
     * We add 40000 km to AOI, which is approximately the Earth circumference.
     */
    areaOfInterest.setRange(0, 45000000, 47000000);
    actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, validToAOI);
    assertEnvelopeEquals(expected, actual, 1E+5, Formulas.LINEAR_TOLERANCE);
}
 
Example #16
Source File: NTv2Test.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Writes a sub-grid of the given grid in pseudo-NTv2 format. This method is used only for creating the test file.
 * The file created by this method is not fully NTv2 compliant (in particular, we do not write complete header),
 * but we take this opportunity for testing {@code NTv2.Loader} capability to be lenient.
 *
 * <p>This method has been executed once for creating the {@code "NTF_R93-extract.gsb"} test file and should not
 * be needed anymore, but we keep it around in case we have new test files to generate. The parameter used for
 * creating the test file are:</p>
 *
 * <ul>
 *   <li>{@code gridX} = 72</li>
 *   <li>{@code gridY} = 74</li>
 *   <li>{@code nx}    =  6</li>
 *   <li>{@code ny}    =  7</li>
 * </ul>
 *
 * This ensure that the grid indices (75.7432814, 78.4451225) is included in the test file.
 * Those grid indices is the location of the (2°25′32.4187″N 48°50′40.2441″W) test point to interpolate.
 *
 * <h4>Limitations</h4>
 * This method assumes that bounding box and increments have integer values, and that any fractional part
 * is rounding errors. This is usually the case when using the {@code "SECONDS"} unit of measurement.
 * This assumption does not apply to the shift values.
 *
 * @param  grid   the full grid from which to extract a few values.
 * @param  out    where to write the test file.
 * @param  gridX  index along the longitude axis of the first cell to write.
 * @param  gridY  index along the latitude axis of the first cell to write.
 * @param  nx     number of cells to write along the longitude axis.
 * @param  ny     number of cells to write along the latitude axis.
 * @throws TransformException if an error occurred while computing the envelope.
 * @throws IOException if an error occurred while writing the test file.
 */
public static void writeSubGrid(final DatumShiftGridFile<Angle,Angle> grid, final Path out,
        final int gridX, final int gridY, final int nx, final int ny) throws IOException, TransformException
{
    Envelope envelope = new Envelope2D(null, gridX, gridY, nx - 1, ny - 1);
    envelope = Envelopes.transform(grid.getCoordinateToGrid().inverse(), envelope);
    final ByteBuffer buffer = ByteBuffer.allocate(4096);
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    writeString(buffer, "NUM_OREC"); buffer.putInt(5); nextRecord(buffer);
    writeString(buffer, "NUM_SREC"); buffer.putInt(7); nextRecord(buffer);
    writeString(buffer, "NUM_FILE"); buffer.putInt(1); nextRecord(buffer);
    writeString(buffer, "GS_TYPE");  writeString(buffer, "SECONDS");
    writeString(buffer, "VERSION");  writeString(buffer, "SIS_TEST");   // Last overview record.
    writeString(buffer, "S_LAT");    buffer.putDouble(StrictMath.rint( envelope.getMinimum(1)));
    writeString(buffer, "N_LAT");    buffer.putDouble(StrictMath.rint( envelope.getMaximum(1)));
    writeString(buffer, "E_LONG");   buffer.putDouble(StrictMath.rint(-envelope.getMaximum(0)));  // Sign reversed.
    writeString(buffer, "W_LONG");   buffer.putDouble(StrictMath.rint(-envelope.getMinimum(0)));
    writeString(buffer, "LAT_INC");  buffer.putDouble(StrictMath.rint( envelope.getSpan(1) / (ny - 1)));
    writeString(buffer, "LONG_INC"); buffer.putDouble(StrictMath.rint( envelope.getSpan(0) / (nx - 1)));
    writeString(buffer, "GS_COUNT"); buffer.putInt(nx * ny); nextRecord(buffer);
    for (int y=0; y<ny; y++) {
        for (int x=0; x<nx; x++) {
            buffer.putFloat((float) grid.getCellValue(1, gridX + x, gridY + y));
            buffer.putFloat((float) grid.getCellValue(0, gridX + x, gridY + y));
            buffer.putFloat(ACCURACY);
            buffer.putFloat(ACCURACY);
        }
    }
    writeString(buffer, "END");
    nextRecord(buffer);
    try (WritableByteChannel c = Files.newByteChannel(out, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
        buffer.flip();
        c.write(buffer);
    }
}
 
Example #17
Source File: ReaderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Verifies property values for the given track.
 *
 * @param  f         the track to verify.
 * @param  v11       {@code true} for GPX 1.1, or {@code false} for GPX 1.0.
 * @param  numLinks  expected number of links.
 */
@SuppressWarnings("fallthrough")
private static void verifyTrack(final AbstractFeature f, final boolean v11, final int numLinks) {
    assertEquals("name",       "Track name",          f.getPropertyValue("name"));
    assertEquals("cmt",        "Track comment",       f.getPropertyValue("cmt"));
    assertEquals("desc",       "Track description",   f.getPropertyValue("desc"));
    assertEquals("src",        "Track source",        f.getPropertyValue("src"));
    assertEquals("type", v11 ? "Track type" : null,   f.getPropertyValue("type"));
    assertEquals("number",      7,                    f.getPropertyValue("number"));

    final List<?> links = (List<?>) f.getPropertyValue("link");
    assertEquals("links.size()", numLinks, links.size());
    switch (numLinks) {
        default: // Fallthrough everywhere.
        case 3:  assertStringEquals("http://track-address3.org", links.get(2));
        case 2:  assertStringEquals("http://track-address2.org", links.get(1));
        case 1:  assertStringEquals("http://track-address1.org", links.get(0));
        case 0:  break;
    }

    final List<?> segments = (List<?>) f.getPropertyValue("trkseg");
    assertEquals("segments.size()", 2, segments.size());
    final AbstractFeature seg1 = (AbstractFeature) segments.get(0);
    final AbstractFeature seg2 = (AbstractFeature) segments.get(1);
    final List<?> points = (List<?>) seg1.getPropertyValue("trkpt");
    assertEquals("points.size()", 3, points.size());
    verifyPoint((AbstractFeature) points.get(0), 0, v11);
    verifyPoint((AbstractFeature) points.get(1), 1, v11);
    verifyPoint((AbstractFeature) points.get(2), 2, v11);
    assertTrue(((Collection<?>) seg2.getPropertyValue("trkpt")).isEmpty());

    final Polyline p = (Polyline) f.getPropertyValue("sis:geometry");
    assertEquals("pointCount", 3, p.getPointCount());
    assertEquals("point(0)", new Point(15, 10), p.getPoint(0));
    assertEquals("point(1)", new Point(25, 20), p.getPoint(1));
    assertEquals("point(2)", new Point(35, 30), p.getPoint(2));
    assertEnvelopeEquals(15, 35, 10, 30, (Envelope) f.getPropertyValue("sis:envelope"));
}
 
Example #18
Source File: CoverageUtilities.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
public static RegionMap gridGeometry2RegionParamsMap( GridGeometry2D gridGeometry ) {
    RegionMap envelopeParams = new RegionMap();

    Envelope envelope = gridGeometry.getEnvelope2D();
    DirectPosition lowerCorner = envelope.getLowerCorner();
    double[] westSouth = lowerCorner.getCoordinate();
    DirectPosition upperCorner = envelope.getUpperCorner();
    double[] eastNorth = upperCorner.getCoordinate();

    GridEnvelope2D gridRange = gridGeometry.getGridRange2D();
    int height = gridRange.height;
    int width = gridRange.width;

    AffineTransform gridToCRS = (AffineTransform) gridGeometry.getGridToCRS();
    double xRes = XAffineTransform.getScaleX0(gridToCRS);
    double yRes = XAffineTransform.getScaleY0(gridToCRS);

    envelopeParams.put(NORTH, eastNorth[1]);
    envelopeParams.put(SOUTH, westSouth[1]);
    envelopeParams.put(WEST, westSouth[0]);
    envelopeParams.put(EAST, eastNorth[0]);
    envelopeParams.put(XRES, xRes);
    envelopeParams.put(YRES, yRes);
    envelopeParams.put(ROWS, (double) height);
    envelopeParams.put(COLS, (double) width);

    return envelopeParams;
}
 
Example #19
Source File: CoverageUtilities.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Get the parameters of the region covered by the {@link ImageMosaicReader}. 
 * 
 * @param reader the ImageMosaicReader.
 * @return the {@link HashMap map} of parameters. ( {@link #NORTH} and the 
 *          other static vars can be used to retrieve them.
 */
public static RegionMap getRegionParamsFromImageMosaicReader( ImageMosaicReader reader ) throws IOException {
    RegionMap envelopeParams = new RegionMap();

    Envelope envelope = reader.getOriginalEnvelope();

    DirectPosition lowerCorner = envelope.getLowerCorner();
    double[] westSouth = lowerCorner.getCoordinate();
    DirectPosition upperCorner = envelope.getUpperCorner();
    double[] eastNorth = upperCorner.getCoordinate();

    GridEnvelope2D gridRange = (GridEnvelope2D) reader.getOriginalGridRange();
    int height = gridRange.height;
    int width = gridRange.width;
    double[][] resolutionLevels = reader.getResolutionLevels();
    double xRes = resolutionLevels[0][0];
    double yRes = resolutionLevels[0][1];

    envelopeParams.put(NORTH, eastNorth[1]);
    envelopeParams.put(SOUTH, westSouth[1]);
    envelopeParams.put(WEST, westSouth[0]);
    envelopeParams.put(EAST, eastNorth[0]);
    envelopeParams.put(XRES, xRes);
    envelopeParams.put(YRES, yRes);
    envelopeParams.put(ROWS, (double) height);
    envelopeParams.put(COLS, (double) width);

    return envelopeParams;
}
 
Example #20
Source File: CoverageUtilities.java    From hortonmachine with GNU General Public License v3.0 5 votes vote down vote up
public static GridGeometry2D gridGeometryFromRegionValues( double north, double south, double east, double west, int cols,
        int rows, CoordinateReferenceSystem crs ) {
    Envelope envelope = new Envelope2D(crs, west, south, east - west, north - south);
    GridEnvelope2D gridRange = new GridEnvelope2D(0, 0, cols, rows);
    GridGeometry2D gridGeometry2D = new GridGeometry2D(gridRange, envelope);
    return gridGeometry2D;
}
 
Example #21
Source File: FranceGeocentricInterpolationTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Verifies the envelope and the interpolation performed by the given grid.
 *
 * @throws TransformException if an error occurred while computing the envelope.
 */
private static void verifyGrid(final DatumShiftGridFile<Angle,Length> grid) throws TransformException {
    final Envelope envelope = grid.getDomainOfValidity();
    assertEquals("xmin",  2.2, envelope.getMinimum(0), 1E-12);
    assertEquals("xmax",  2.5, envelope.getMaximum(0), 1E-12);
    assertEquals("ymin", 48.5, envelope.getMinimum(1), 1E-12);
    assertEquals("ymax", 49.0, envelope.getMaximum(1), 1E-12);
    /*
     * The values in the NTG_88 document are:
     *
     * (gridX=2, gridY=3)  00002    2.400000000   48.800000000  -168.252   -58.630   320.170  01   2314
     * (gridX=2, gridY=4)  00002    2.400000000   48.900000000  -168.275   -58.606   320.189  01   2314
     * (gridX=3, gridY=3)  00002    2.500000000   48.800000000  -168.204   -58.594   320.125  01   2314
     * (gridX=3, gridY=4)  00002    2.500000000   48.900000000  -168.253   -58.554   320.165  01   2314
     *
     * Directions (signs) are reversed compared to NTG_88 document.
     */
    assertEquals("translationDimensions", 3, grid.getTranslationDimensions());
    assertEquals("grid.accuracy",      0.05, grid.accuracy,              STRICT);
    assertEquals("getCellValue",    168.196, grid.getCellValue(0, 2, 1), STRICT);
    assertEquals("getCellValue",     58.778, grid.getCellValue(1, 2, 1), STRICT);
    assertEquals("getCellValue",   -320.127, grid.getCellValue(2, 2, 1), STRICT);
    /*
     * Interpolate the (ΔX, ΔY, ΔZ) at a point.
     * Directions (signs) are reversed compared to NTG_88 document.
     */
    final double[] expected = {
         168.253,       // ΔX: Toward prime meridian
          58.609,       // ΔY: Toward 90° east
        -320.170        // ΔZ: Toward north pole
    };
    final double[] point  = samplePoint(3);
    final double[] vector = grid.interpolateAt(point[0], point[1]);
    assertArrayEquals("(ΔX, ΔY, ΔZ)", expected, vector, 0.0005);
}
 
Example #22
Source File: EnvelopesTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Test {@link Envelopes#compound(Envelope...)} method.
 *
 * @throws FactoryException if an error occurred while creating the compound CRS.
 *
 * @since 1.0
 */
@Test
public void testCompound() throws FactoryException {
    final GeneralEnvelope element0 = new GeneralEnvelope(HardCodedCRS.WGS84);
    final GeneralEnvelope element1 = new GeneralEnvelope(HardCodedCRS.TIME);
    final GeneralEnvelope expected = new GeneralEnvelope(3);
    element0.setRange(0,   20,   30);
    expected.setRange(0,   20,   30);
    element0.setRange(1,   40,   45);
    expected.setRange(1,   40,   45);
    element1.setRange(0, 1000, 1010);
    expected.setRange(2, 1000, 1010);
    Envelope env = Envelopes.compound(element0, element1);
    final List<SingleCRS> crs = CRS.getSingleComponents(env.getCoordinateReferenceSystem());
    assertEnvelopeEquals(expected, env);
    assertEquals("crs.components.count", 2, crs.size());
    assertSame("crs.components[0]", HardCodedCRS.WGS84, crs.get(0));
    assertSame("crs.components[1]", HardCodedCRS.TIME, crs.get(1));
    /*
     * Try again without CRS in the second component.
     * The compound envelope shall not have CRS anymore.
     */
    element1.setCoordinateReferenceSystem(null);
    env = Envelopes.compound(element0, element1);
    assertEnvelopeEquals(expected, env);
    assertNull("crs.components", env.getCoordinateReferenceSystem());
}
 
Example #23
Source File: Envelopes.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Formats the given envelope as a {@code POLYGON} element in the <cite>Well Known Text</cite>
 * (WKT) format. {@code POLYGON} can be used as an alternative to {@code BOX} when the element
 * needs to be considered as a standard WKT geometry.
 *
 * <p>The string returned by this method can be {@linkplain GeneralEnvelope#GeneralEnvelope(CharSequence)
 * parsed} by the {@code GeneralEnvelope} constructor.</p>
 *
 * @param  envelope  the envelope to format.
 * @return the envelope as a {@code POLYGON} in WKT format.
 * @throws IllegalArgumentException if the given envelope can not be formatted.
 *
 * @see org.apache.sis.io.wkt
 */
public static String toPolygonWKT(final Envelope envelope) throws IllegalArgumentException {
    /*
     * Get the dimension, ignoring the trailing ones which have infinite values.
     */
    int dimension = envelope.getDimension();
    while (dimension != 0) {
        final double length = envelope.getSpan(dimension - 1);
        if (Double.isFinite(length)) {
            break;
        }
        dimension--;
    }
    if (dimension < 2) {
        throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyEnvelope2D));
    }
    final StringBuilder buffer = new StringBuilder("POLYGON(");
    String separator = "(";
    for (int corner = 0; corner < CORNERS.length; corner += 2) {
        for (int i=0; i<dimension; i++) {
            final double value;
            switch (i) {
                case  0: // Fall through
                case  1: value = CORNERS[corner+i] ? envelope.getMaximum(i) : envelope.getMinimum(i); break;
                default: value = envelope.getMedian(i); break;
            }
            trimFractionalPart(buffer.append(separator).append(value));
            separator = " ";
        }
        separator = ", ";
    }
    return buffer.append("))").toString();
}
 
Example #24
Source File: SpecializableTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new transform with the given global transform and some amount of specializations.
 *
 * @param  global  the transform to use globally where there is no suitable specialization.
 * @param  specializations  more accurate transforms available in sub-areas.
 */
SpecializableTransform(final MathTransform global, final Map<Envelope,MathTransform> specializations) {
    this.global = global;
    SubArea root = null;
    final int sourceDim = global.getSourceDimensions();
    final int targetDim = global.getTargetDimensions();
    for (final Map.Entry<Envelope,MathTransform> entry : specializations.entrySet()) {
        MathTransform tr = entry.getValue();
        ensureDimensionMatches(0, sourceDim, tr.getSourceDimensions());
        ensureDimensionMatches(1, targetDim, tr.getTargetDimensions());
        /*
         * If the given MathTransform is another SpecializableTransform, then instead of storing nested
         * SpecializableTransforms we will store directly the specializations that it contains. It will
         * reduce the amountof steps when transforming coordinates.
         */
        List<SubArea> inherited = Collections.emptyList();
        if (tr instanceof SpecializableTransform) {
            inherited = ((SpecializableTransform) tr).roots();
            tr        = ((SpecializableTransform) tr).global;
        }
        final SubArea area = new SubArea(entry.getKey(), tr);
        ArgumentChecks.ensureDimensionMatches("envelope", sourceDim, area);
        if (!area.isEmpty()) {
            if (root == null) root = area;
            else root.addNode(area);
            /*
             * If the transform was another SpecializableTransform, copies the nested RTreeNode.
             * A copy is necessary: we shall not modify the nodes of the given transform.
             */
            for (final SubArea other : inherited) {
                final SubArea e = new SubArea(other, other.transform);
                e.intersect(area);
                if (!e.isEmpty()) {
                    root.addNode(e);
                }
            }
        }
    }
    domains = (root != null) ? root.finish() : null;
}
 
Example #25
Source File: EnvelopeOperationTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of the test methods.
 */
private static void run(final AbstractFeature feature) {
    assertNull("Before a geometry is set", feature.getPropertyValue("bounds"));
    GeneralEnvelope expected;

    // Set one geometry
    Polygon classes = new Polygon();
    classes.startPath(10, 20);
    classes.lineTo(10, 30);
    classes.lineTo(15, 30);
    classes.lineTo(15, 20);
    feature.setPropertyValue("classes", classes);
    expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
    expected.setRange(0, 10, 15);
    expected.setRange(1, 20, 30);
    assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));

    // Set second geometry
    Point wall = new Point(18, 40);
    feature.setPropertyValue("climbing wall", wall);
    expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
    expected.setRange(0, 10, 18);
    expected.setRange(1, 20, 40);
    assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));

    // Set third geometry. This geometry has CRS axis order reversed.
    Polygon gymnasium = new Polygon();
    gymnasium.startPath(-5, -30);
    gymnasium.lineTo(-6, -30);
    gymnasium.lineTo(-6, -31);
    gymnasium.lineTo(-5, -31);
    feature.setPropertyValue("gymnasium", gymnasium);
    expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
    expected.setRange(0, -31, 18);
    expected.setRange(1,  -6, 40);
    assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));
}
 
Example #26
Source File: GeneralEnvelope.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Sets this envelope to the same coordinate values than the specified envelope.
 * If the given envelope has a non-null Coordinate Reference System (CRS), then
 * the CRS of this envelope will be set to the CRS of the given envelope.
 *
 * @param  envelope  the envelope to copy coordinates from.
 * @throws MismatchedDimensionException if the specified envelope doesn't have
 *         the expected number of dimensions.
 */
public void setEnvelope(final Envelope envelope) throws MismatchedDimensionException {
    if (envelope == this) {
        return;     // Optimization for methods chaining like env.setEnvelope(Envelopes.transform(env, crs))
    }
    ensureNonNull("envelope", envelope);
    final int beginIndex = beginIndex();
    final int dimension = endIndex() - beginIndex;
    ensureDimensionMatches("envelope", dimension, envelope);
    final int d = coordinates.length >>> 1;
    if (envelope instanceof ArrayEnvelope) {
        /*
         * Optimization for a common case. This code path is used by Envelopes.compound(…).
         * The main intent is to avoid the creation of temporary DirectPosition objects.
         */
        final double[] source = ((ArrayEnvelope) envelope).coordinates;
        final int srcOffset = ((ArrayEnvelope) envelope).beginIndex();
        System.arraycopy(source, srcOffset, coordinates, beginIndex, dimension);
        System.arraycopy(source, srcOffset + (source.length >>> 1), coordinates, beginIndex + d, dimension);
    } else {
        @SuppressWarnings("null")
        final DirectPosition lower = envelope.getLowerCorner();
        final DirectPosition upper = envelope.getUpperCorner();
        for (int i=0; i<dimension; i++) {
            final int iLower = beginIndex + i;
            final int iUpper = iLower + d;
            coordinates[iLower] = lower.getOrdinate(i);
            coordinates[iUpper] = upper.getOrdinate(i);
        }
    }
    final CoordinateReferenceSystem envelopeCRS = envelope.getCoordinateReferenceSystem();
    if (envelopeCRS != null) {
        crs = envelopeCRS;
        assert crs.getCoordinateSystem().getDimension() == getDimension() : crs;
        assert envelope.getClass() != getClass() || equals(envelope) : envelope;
    }
}
 
Example #27
Source File: Envelopes.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Finds a mathematical operation from the CRS of the given source envelope to the CRS of the given target envelope.
 * For non-null georeferenced envelopes, this method is equivalent to the following code with {@code areaOfInterest}
 * computed as the union of the two envelopes:
 *
 * <blockquote><code>return {@linkplain CRS#findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem,
 * GeographicBoundingBox)} CRS.findOperation(source.getCoordinateReferenceSystem(), target.getCoordinateReferenceSystem(),
 * <var>areaOfInterest</var>)</code></blockquote>
 *
 * If at least one envelope is null or has no CRS, then this method returns {@code null}.
 *
 * @param  source  the source envelope, or {@code null}.
 * @param  target  the target envelope, or {@code null}.
 * @return the mathematical operation from {@code source} CRS to {@code target} CRS,
 *         or {@code null} if at least one argument is null or has no CRS.
 * @throws OperationNotFoundException if no operation was found between the given pair of CRS.
 * @throws FactoryException if the operation can not be created for another reason.
 *
 * @see CRS#findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
 *
 * @since 1.0
 */
public static CoordinateOperation findOperation(final Envelope source, final Envelope target) throws FactoryException {
    if (source != null && target != null) {
        final CoordinateReferenceSystem sourceCRS, targetCRS;
        if ((sourceCRS = source.getCoordinateReferenceSystem()) != null &&
            (targetCRS = target.getCoordinateReferenceSystem()) != null)
        {
            /*
             * Computing the area of interest (AOI) unconditionally would be harmless, but it is useless if the CRS
             * are the same since the result will be identity anyway. Conversely we could skip AOI computation more
             * often for example with the following condition instead of !=:
             *
             *     !Utilities.deepEquals(sourceCRS, targetCRS, ComparisonMode.ALLOW_VARIANT)
             *
             * but it would not be very advantageous if testing the condition is almost as long as computing the AOI.
             * For now we keep != as a very cheap test which will work quite often.
             */
            DefaultGeographicBoundingBox areaOfInterest = null;
            if (sourceCRS != targetCRS) try {
                final DefaultGeographicBoundingBox targetAOI;
                final ReferencingServices converter = ReferencingServices.getInstance();
                areaOfInterest = converter.setBounds(source, null, "findOperation");                // Should be first.
                targetAOI      = converter.setBounds(target, null, "findOperation");
                if (areaOfInterest == null) {
                    areaOfInterest = targetAOI;
                } else if (targetAOI != null) {
                    areaOfInterest.add(targetAOI);
                }
            } catch (TransformException e) {
                /*
                 * Note: we may succeed to transform 'source' and fail to transform 'target' to geographic bounding box,
                 * but the opposite is unlikely because 'source' should not have less dimensions than 'target'.
                 */
                Logging.recoverableException(Logging.getLogger(Loggers.GEOMETRY), Envelopes.class, "findOperation", e);
            }
            return CRS.findOperation(sourceCRS, targetCRS, areaOfInterest);
        }
    }
    return null;
}
 
Example #28
Source File: CRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the domain of validity of the specified coordinate reference system, or {@code null} if unknown.
 * If non-null, then the returned envelope will use the same coordinate reference system them the given CRS
 * argument.
 *
 * @param  crs  the coordinate reference system, or {@code null}.
 * @return the envelope with coordinates in the given CRS, or {@code null} if none.
 *
 * @see #getGeographicBoundingBox(CoordinateReferenceSystem)
 *
 * @category information
 * @since 0.8
 */
public static Envelope getDomainOfValidity(final CoordinateReferenceSystem crs) {
    Envelope envelope = null;
    GeneralEnvelope merged = null;
    /* if (envelope == null) */ {   // Condition needed on other branches but not on trunk.
        final GeographicBoundingBox bounds = getGeographicBoundingBox(crs);
        if (bounds != null && !Boolean.FALSE.equals(bounds.getInclusion())) {
            /*
             * We do not assign WGS84 unconditionally to the geographic bounding box, because
             * it is not defined to be on a particular datum; it is only approximated bounds.
             * We try to get the GeographicCRS from the user-supplied CRS in order to reduce
             * the amount of transformation needed.
             */
            final SingleCRS targetCRS = getHorizontalComponent(crs);
            final GeographicCRS sourceCRS = ReferencingUtilities.toNormalizedGeographicCRS(targetCRS, false, false);
            if (sourceCRS != null) {
                envelope = merged = new GeneralEnvelope(bounds);
                merged.translate(-getGreenwichLongitude(sourceCRS), 0);
                merged.setCoordinateReferenceSystem(sourceCRS);
                try {
                    envelope = Envelopes.transform(envelope, targetCRS);
                } catch (TransformException exception) {
                    /*
                     * The envelope is probably outside the range of validity for this CRS.
                     * It should not occurs, since the envelope is supposed to describe the
                     * CRS area of validity. Logs a warning and returns null, since it is a
                     * legal return value according this method contract.
                     */
                    unexpectedException("getEnvelope", exception);
                    envelope = null;
                }
            }
        }
    }
    return envelope;
}
 
Example #29
Source File: WraparoundAdjustmentTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests {@link WraparoundAdjustment#shift(Envelope)}
 * with an envelope shifted by 360° before or after the grid valid area.
 *
 * @throws TransformException should never happen since this test does not transform coordinates.
 */
@Test
@DependsOnMethod("testRange")
public void testWithShiftedAOI() throws TransformException {
    final GeneralEnvelope domainOfValidity = new GeneralEnvelope(HardCodedCRS.WGS84);
    domainOfValidity.setRange(0,  80, 100);
    domainOfValidity.setRange(1, -70, +70);

    final GeneralEnvelope areaOfInterest = new GeneralEnvelope(HardCodedCRS.WGS84);
    areaOfInterest.setRange(0,  70, 90);
    areaOfInterest.setRange(1, -80, 60);
    /*
     * AOI intersects the domain of validity: expected result is identical to given AOI.
     */
    final GeneralEnvelope expected = new GeneralEnvelope(areaOfInterest);
    Envelope actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
    assertEnvelopeEquals(expected, actual);
    /*
     * AOI is on the left side of domain of validity. Expect a 360° shift to the right.
     */
    areaOfInterest.setRange(0, -290, -270);                    // [70 … 90] - 360
    actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
    assertEnvelopeEquals(expected, actual);
    /*
     * AOI is on the right side of domain of validity. Expect a 360° shift to the left.
     */
    areaOfInterest.setRange(0, 430, 450);                      // [70 … 90] + 360
    actual = adjustWraparoundAxes(areaOfInterest, domainOfValidity, null);
    assertEnvelopeEquals(expected, actual);
}
 
Example #30
Source File: Envelopes.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Transforms the given envelope to the specified CRS. If any argument is null, or if the
 * {@linkplain GeneralEnvelope#getCoordinateReferenceSystem() envelope CRS} is null or the
 * same instance than the given target CRS, then the given envelope is returned unchanged.
 * Otherwise a new transformed envelope is returned.
 *
 * <h4>Performance tip</h4>
 * If there is many envelopes to transform with the same source and target CRS, then it is more efficient
 * to get the {@link CoordinateOperation} or {@link MathTransform} instance once and invoke one of the
 * others {@code transform(…)} methods.
 *
 * @param  envelope   the envelope to transform (may be {@code null}).
 * @param  targetCRS  the target CRS (may be {@code null}).
 * @return a new transformed envelope, or directly {@code envelope} if no change was required.
 * @throws TransformException if a transformation was required and failed.
 *
 * @since 0.5
 */
public static Envelope transform(Envelope envelope, final CoordinateReferenceSystem targetCRS)
        throws TransformException
{
    if (envelope != null && targetCRS != null) {
        final CoordinateReferenceSystem sourceCRS = envelope.getCoordinateReferenceSystem();
        if (sourceCRS != targetCRS) {
            if (sourceCRS == null) {
                // Slight optimization: just copy the given Envelope.
                envelope = new GeneralEnvelope(envelope);
                ((GeneralEnvelope) envelope).setCoordinateReferenceSystem(targetCRS);
            } else {
                // TODO: create an CoordinateOperationContext with the envelope as geographic area.
                //       May require that we optimize the search for CoordinateOperation with non-null context first.
                //       See https://issues.apache.org/jira/browse/SIS-442
                final CoordinateOperation operation;
                try {
                    operation = CoordinateOperations.factory().createOperation(sourceCRS, targetCRS);
                } catch (FactoryException exception) {
                    throw new TransformException(Errors.format(Errors.Keys.CanNotTransformEnvelope), exception);
                }
                envelope = transform(operation, envelope);
            }
            assert Utilities.deepEquals(targetCRS, envelope.getCoordinateReferenceSystem(), ComparisonMode.DEBUG);
        }
    }
    return envelope;
}