use of org.opengis.geometry.Envelope in project sis by apache.
the class NTv2Test method testRGF93.
/**
* Implementation of {@link #testLoader()} and {@link #testRGF93(Path)}.
*
* @param xmin negative of value of {@code "W_LONG"} record.
* @param xmax negative of value of {@code "E_LONG"} record.
* @param ymin value of the {@code "S_LAT"} record.
* @param ymax value of the {@code "N_LAT"} record.
*/
private static void testRGF93(final Path file, final double xmin, final double xmax, final double ymin, final double ymax) throws IOException, FactoryException, TransformException {
final double cellSize = 360;
final DatumShiftGridFile<Angle, Angle> grid = NTv2.getOrLoad(file);
assertInstanceOf("Should not be compressed.", DatumShiftGridFile.Float.class, grid);
assertEquals("coordinateUnit", Units.ARC_SECOND, grid.getCoordinateUnit());
assertEquals("translationUnit", Units.ARC_SECOND, grid.getTranslationUnit());
assertEquals("translationDimensions", 2, grid.getTranslationDimensions());
assertTrue("isCellValueRatio", grid.isCellValueRatio());
assertEquals("cellPrecision", (ACCURACY / 10) / cellSize, grid.getCellPrecision(), 0.5E-6 / cellSize);
/*
* Verify the envelope and the conversion between geographic coordinates and grid indices.
* The cells are expected to have the same size (360″ or 0.1°) in longitudes and latitudes.
*/
final Envelope envelope = grid.getDomainOfValidity();
assertEquals("xmin", xmin - cellSize / 2, envelope.getMinimum(0), STRICT);
assertEquals("xmax", xmax + cellSize / 2, envelope.getMaximum(0), STRICT);
assertEquals("ymin", ymin - cellSize / 2, envelope.getMinimum(1), STRICT);
assertEquals("ymax", ymax + cellSize / 2, envelope.getMaximum(1), STRICT);
assertMatrixEquals("coordinateToGrid", new Matrix3(-cellSize, 0, xmax, 0, +cellSize, ymin, 0, 0, 1), grid.getCoordinateToGrid().inverse().getMatrix(), STRICT);
/*
* Test the same point than FranceGeocentricInterpolationTest, which is itself derived from the
* NTG_88 guidance note. If we were using the official NTF_R93.gsb file, we would obtain after
* conversion the grid indices listed on the left side. But since we are using a sub-set of the
* grid, we rather obtain the grid indices on the right side.
*
* gridX ≈ 75.7432814 in official file, ≈ 3.7432814 in the test file.
* gridY ≈ 78.4451225 in official file, ≈ 4.4451225 in the test file.
*/
final double[] position = FranceGeocentricInterpolationTest.samplePoint(1);
final double[] expected = FranceGeocentricInterpolationTest.samplePoint(3);
final double[] indices = new double[position.length];
final double[] vector = new double[2];
for (int i = 0; i < expected.length; i++) {
position[i] *= DatumShiftGridLoader.DEGREES_TO_SECONDS;
expected[i] *= DatumShiftGridLoader.DEGREES_TO_SECONDS;
// We will test the interpolated shifts rather than final coordinates.
expected[i] -= position[i];
}
grid.getCoordinateToGrid().transform(position, 0, indices, 0, 1);
grid.interpolateInCell(indices[0], indices[1], vector);
// Was positive toward west.
vector[0] *= -cellSize;
vector[1] *= +cellSize;
assertArrayEquals("interpolateInCell", expected, vector, FranceGeocentricInterpolationTest.ANGULAR_TOLERANCE * DatumShiftGridLoader.DEGREES_TO_SECONDS);
// Same test than above, but let DatumShiftGrid do the conversions for us.
assertArrayEquals("interpolateAt", expected, grid.interpolateAt(position), FranceGeocentricInterpolationTest.ANGULAR_TOLERANCE * DatumShiftGridLoader.DEGREES_TO_SECONDS);
assertSame("Grid should be cached.", grid, NTv2.getOrLoad(file));
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class EnvelopesTest method testTransform4to2D.
/**
* Tests the transformation of an envelope from a 4D CRS to a 2D CRS
* where the ordinates in one dimension are NaN.
*
* @throws TransformException if an error occurred while transforming the envelope.
*
* @since 0.8
*/
@Test
public void testTransform4to2D() throws TransformException {
final CoordinateReferenceSystem targetCRS = HardCodedCRS.WGS84;
final CoordinateReferenceSystem sourceCRS = new DefaultCompoundCRS(Collections.singletonMap(DefaultCompoundCRS.NAME_KEY, "4D CRS"), HardCodedCRS.WGS84, HardCodedCRS.GRAVITY_RELATED_HEIGHT, HardCodedCRS.TIME);
final GeneralEnvelope env = new GeneralEnvelope(sourceCRS);
env.setRange(0, -170, 170);
env.setRange(1, -80, 80);
env.setRange(2, -50, -50);
env.setRange(3, Double.NaN, Double.NaN);
// Opportunist test (not really the topic of this method).
assertFalse("isAllNaN", env.isAllNaN());
// Opportunist test (not really the topic of this method).
assertTrue("isEmpty", env.isEmpty());
/*
* If the referencing framework has selected the CopyTransform implementation
* as expected, then the envelope ordinates should not be NaN.
*/
final Envelope env2D = Envelopes.transform(env, targetCRS);
assertEquals(-170, env2D.getMinimum(0), 0);
assertEquals(170, env2D.getMaximum(0), 0);
assertEquals(-80, env2D.getMinimum(1), 0);
assertEquals(80, env2D.getMaximum(1), 0);
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class AbstractEnvelopeTest method testRange360.
/**
* Tests a case crossing the anti-meridian crossing, from 0° to -0°.
*/
@Test
public void testRange360() {
final DirectPosition2D inside = new DirectPosition2D(18, 32);
final DirectPosition2D wasOutside = new DirectPosition2D(3, 32);
final Envelope2D contained = (Envelope2D) create(RECTANGLE, 14, 16, 35, 40);
final Envelope2D intersect = (Envelope2D) create(RECTANGLE, -2, 16, 35, 40);
final Envelope2D spanning = (Envelope2D) create(RECTANGLE, 16, -8, 35, 40);
for (int type = 0; type < LAST; type++) {
final String label = "Type " + type;
final Envelope envelope = create(type, 0.0, -0.0, 30, 50);
final DirectPosition lower = envelope.getLowerCorner();
final DirectPosition upper = envelope.getUpperCorner();
assertEquals(label, 30, envelope.getMinimum(1), STRICT);
assertEquals(label, 50, envelope.getMaximum(1), STRICT);
assertEquals(label, 40, envelope.getMedian(1), STRICT);
assertEquals(label, 20, envelope.getSpan(1), STRICT);
assertEquals(label, 0.0, lower.getOrdinate(0), STRICT);
assertEquals(label, -180, envelope.getMinimum(0), STRICT);
assertEquals(label, -0.0, upper.getOrdinate(0), STRICT);
assertEquals(label, +180, envelope.getMaximum(0), STRICT);
assertEquals(label, 180, envelope.getMedian(0), STRICT);
assertEquals(label, 360, envelope.getSpan(0), STRICT);
switch(type) {
default:
{
final AbstractEnvelope ext = (AbstractEnvelope) envelope;
assertTrue(label, ext.contains(inside));
assertTrue(label, ext.contains(wasOutside));
assertTrue(label, ext.intersects(intersect, false));
assertContains(ext, contained);
assertContains(ext, spanning);
break;
}
case RECTANGLE:
{
final Rectangle2D ext = (Rectangle2D) envelope;
assertTrue(label, ext.contains(inside));
assertTrue(label, ext.contains(wasOutside));
assertTrue(label, ext.intersects(intersect));
assertContains(ext, contained);
assertContains(ext, spanning);
break;
}
}
verifyInvariants(type, envelope);
}
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class AbstractEnvelopeTest method testCrossingAntiMeridianThreeTimes.
/**
* Tests a the anti-meridian case with a larger empty space
* on the left and right sides.
*/
@Test
public void testCrossingAntiMeridianThreeTimes() {
final DirectPosition2D wasInside = new DirectPosition2D(18, 32);
final DirectPosition2D outside = new DirectPosition2D(3, 32);
final Envelope2D wasContained = (Envelope2D) create(RECTANGLE, 14, 16, 35, 40);
final Envelope2D wasIntersect = (Envelope2D) create(RECTANGLE, -2, 16, 35, 40);
final Envelope2D disjoint = (Envelope2D) create(RECTANGLE, -2, 10, 35, 40);
final Envelope2D spanning = (Envelope2D) create(RECTANGLE, 16, -8, 35, 40);
for (int type = 0; type < LAST; type++) {
final String label = "Type " + type;
final Envelope envelope = create(type, 372, -364, 30, 50);
final DirectPosition lower = envelope.getLowerCorner();
final DirectPosition upper = envelope.getUpperCorner();
assertEquals(label, 30, envelope.getMinimum(1), STRICT);
assertEquals(label, 50, envelope.getMaximum(1), STRICT);
assertEquals(label, 40, envelope.getMedian(1), STRICT);
assertEquals(label, 20, envelope.getSpan(1), STRICT);
assertEquals(label, 372, lower.getOrdinate(0), STRICT);
assertEquals(label, -180, envelope.getMinimum(0), STRICT);
assertEquals(label, -364, upper.getOrdinate(0), STRICT);
assertEquals(label, +180, envelope.getMaximum(0), STRICT);
// Note the alternance with the previous test methods.
assertEquals(label, -176, envelope.getMedian(0), STRICT);
// testCrossingAntiMeridianTwice() + 360°.
assertEquals(label, NaN, envelope.getSpan(0), STRICT);
switch(type) {
default:
{
final AbstractEnvelope ext = (AbstractEnvelope) envelope;
assertFalse(label, ext.contains(wasInside));
assertFalse(label, ext.contains(outside));
assertFalse(label, ext.contains(spanning, false));
assertTrue(label, ext.intersects(spanning, false));
assertDisjoint(ext, wasIntersect);
assertDisjoint(ext, disjoint);
assertDisjoint(ext, wasContained);
break;
}
case RECTANGLE:
{
final Rectangle2D ext = (Rectangle2D) envelope;
assertFalse(label, ext.contains(wasInside));
assertFalse(label, ext.contains(outside));
assertFalse(label, ext.contains(spanning));
assertTrue(label, ext.intersects(spanning));
assertDisjoint(ext, wasIntersect);
assertDisjoint(ext, disjoint);
assertDisjoint(ext, wasContained);
break;
}
}
verifyInvariants(type, envelope);
}
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class Extents method getGeographicBoundingBox.
/**
* Returns a single geographic bounding box from the specified extent.
* This method tries to find the bounding box in the cheapest way
* before to fallback on more expansive computations:
*
* <ol>
* <li>First, this method searches geographic elements that are instance of {@link GeographicBoundingBox}.<ul>
* <li>If exactly one such instance is found, then this method returns that instance directly (no copy).</li>
* <li>If more than one instance is found, then this method computes and returns the
* {@linkplain DefaultGeographicBoundingBox#add union} of all bounding boxes.</li>
* </ul></li>
* <li>If above step found no {@code GeographicBoundingBox}, then this method inspects geographic elements
* that are instance of {@link BoundingPolygon}, taking in account only the envelopes associated to a
* coordinate reference system of kind {@link GeographicCRS}. If such envelopes are found, then this
* method computes and returns their union.</li>
* <li>If above step found no polygon's envelope associated to a geographic CRS, then in last resort this
* method uses all polygon's envelopes regardless their coordinate reference system (provided that the
* CRS is not null), applying coordinate transformations if needed.</li>
* <li>If above step found no polygon's envelope, then this method returns {@code null}.</li>
* </ol>
*
* @param extent the extent to convert to a geographic bounding box, or {@code null}.
* @return a geographic bounding box extracted from the given extent, or {@code null} if none.
*
* @see org.apache.sis.referencing.CRS#getDomainOfValidity(CoordinateReferenceSystem)
*/
public static GeographicBoundingBox getGeographicBoundingBox(final Extent extent) {
GeographicBoundingBox bounds = null;
if (extent != null) {
DefaultGeographicBoundingBox modifiable = null;
final List<Envelope> fallbacks = new ArrayList<>();
for (final GeographicExtent element : extent.getGeographicElements()) {
/*
* If a geographic bounding box can be obtained, add it to the previous boxes (if any).
* All exclusion boxes before the first inclusion box are ignored.
*/
if (element instanceof GeographicBoundingBox) {
final GeographicBoundingBox item = (GeographicBoundingBox) element;
if (bounds == null) {
/*
* We use DefaultGeographicBoundingBox.getInclusion(Boolean) below because
* add(…) method that we use cares about the case where inclusion is false.
*/
if (DefaultGeographicBoundingBox.getInclusion(item.getInclusion())) {
bounds = item;
}
} else {
if (modifiable == null) {
bounds = modifiable = new DefaultGeographicBoundingBox(bounds);
}
modifiable.add(item);
}
}
}
/*
* If we found not explicit GeographicBoundingBox element, use the information that we
* collected in BoundingPolygon elements. This may involve coordinate transformations.
*/
if (bounds == null)
try {
for (final Envelope envelope : fallbacks) {
final DefaultGeographicBoundingBox item = new DefaultGeographicBoundingBox();
item.setBounds(envelope);
if (bounds == null) {
bounds = item;
} else {
if (modifiable == null) {
bounds = modifiable = new DefaultGeographicBoundingBox(bounds);
}
modifiable.add(item);
}
}
} catch (TransformException e) {
throw new InvalidMetadataException(Errors.format(Errors.Keys.CanNotTransformEnvelope), e);
}
}
return bounds;
}
Aggregations