use of org.opengis.geometry.Envelope in project sis by apache.
the class MatricesTest method testCreateTransformFromEnvelopes.
/**
* Tests {@link Matrices#createTransform(Envelope, Envelope)}.
* This method tests the example given in {@code Matrices.createTransform(…)} javadoc.
*/
@Test
public void testCreateTransformFromEnvelopes() {
final Envelope srcEnvelope = new Envelope2D(null, -20, -40, 100, 200);
final Envelope dstEnvelope = new Envelope2D(null, -10, -25, 300, 500);
MatrixSIS matrix = Matrices.createTransform(srcEnvelope, dstEnvelope);
assertTrue("isAffine", matrix.isAffine());
assertFalse("isIdentity", matrix.isIdentity());
assertEquals("numRow", 3, matrix.getNumRow());
assertEquals("numCol", 3, matrix.getNumCol());
assertEquals(Matrices.create(3, 3, new double[] { 3.0, 0, 50, 0, 2.5, 75, 0, 0, 1 }), matrix);
/*
* Test dropping a dimension.
*/
final GeneralEnvelope expanded = new GeneralEnvelope(3);
expanded.subEnvelope(0, 2).setEnvelope(srcEnvelope);
expanded.setRange(2, 1000, 2000);
matrix = Matrices.createTransform(expanded, dstEnvelope);
assertEquals("numRow", 3, matrix.getNumRow());
assertEquals("numCol", 4, matrix.getNumCol());
assertEquals(Matrices.create(3, 4, new double[] { 3.0, 0, 0, 50, 0, 2.5, 0, 75, 0, 0, 0, 1 }), matrix);
/*
* Test adding a dimension with ordinate values set to zero.
*/
expanded.subEnvelope(0, 2).setEnvelope(dstEnvelope);
matrix = Matrices.createTransform(srcEnvelope, expanded);
assertEquals("numRow", 4, matrix.getNumRow());
assertEquals("numCol", 3, matrix.getNumCol());
assertEquals(Matrices.create(4, 3, new double[] { 3.0, 0, 50, 0, 2.5, 75, 0, 0, 0, 0, 0, 1 }), matrix);
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class MatricesTest method testCreateTransformFromEnvelopesAndAxes.
/**
* Tests {@link Matrices#createTransform(Envelope, AxisDirection[], Envelope, AxisDirection[])}.
* This method tests the example given in {@code Matrices.createTransform(…)} javadoc.
*/
@Test
@DependsOnMethod({ "testCreateTransformFromEnvelopes", "testCreateTransformWithLessAxes" })
public void testCreateTransformFromEnvelopesAndAxes() {
// swapped (y,-x)
final Envelope srcEnvelope = new Envelope2D(null, -40, +20, 200, 100);
final Envelope dstEnvelope = new Envelope2D(null, -10, -25, 300, 500);
MatrixSIS matrix = Matrices.createTransform(srcEnvelope, new AxisDirection[] { NORTH, WEST }, dstEnvelope, new AxisDirection[] { EAST, NORTH });
assertTrue("isAffine", matrix.isAffine());
assertFalse("isIdentity", matrix.isIdentity());
assertEquals("numRow", 3, matrix.getNumRow());
assertEquals("numCol", 3, matrix.getNumCol());
assertMatrixEquals("(N,E) → (E,N)", Matrices.create(3, 3, new double[] { 0, -3.0, 350, 2.5, 0, 75, 0, 0, 1 }), matrix, STRICT);
/*
* Test dropping a dimension.
*/
final GeneralEnvelope expanded = new GeneralEnvelope(3);
expanded.subEnvelope(0, 2).setEnvelope(srcEnvelope);
expanded.setRange(2, 1000, 2000);
matrix = Matrices.createTransform(expanded, new AxisDirection[] { NORTH, WEST, UP }, dstEnvelope, new AxisDirection[] { EAST, NORTH });
assertEquals("numRow", 3, matrix.getNumRow());
assertEquals("numCol", 4, matrix.getNumCol());
assertMatrixEquals("(N,E,U) → (E,N)", Matrices.create(3, 4, new double[] { 0, -3.0, 0, 350, 2.5, 0, 0, 75, 0, 0, 0, 1 }), matrix, STRICT);
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class AbstractEnvelope method toSimpleEnvelopes.
/**
* Returns this envelope as an array of simple (without wraparound) envelopes.
* The length of the returned array depends on the number of dimensions where a
* {@linkplain org.opengis.referencing.cs.RangeMeaning#WRAPAROUND wraparound} range is found.
* Typically, wraparound occurs only in the range of longitude values, when the range crosses
* the anti-meridian (a.k.a. date line). However this implementation will take in account any
* axis having wraparound {@linkplain CoordinateSystemAxis#getRangeMeaning() range meaning}.
*
* <p>Special cases:</p>
*
* <ul>
* <li>If this envelope {@linkplain #isEmpty() is empty}, then this method returns an empty array.</li>
* <li>If this envelope does not have any wraparound behavior, then this method returns {@code this}
* in an array of length 1. This envelope is <strong>not</strong> cloned.</li>
* <li>If this envelope crosses the <cite>anti-meridian</cite> (a.k.a. <cite>date line</cite>)
* then this method represents this envelope as two separated simple envelopes.
* <li>While uncommon, the envelope could theoretically crosses the limit of other axis having
* wraparound range meaning. If wraparound occur along <var>n</var> axes, then this method
* represents this envelope as 2ⁿ separated simple envelopes.
* </ul>
*
* @return a representation of this envelope as an array of non-empty envelope.
*
* @see Envelope2D#toRectangles()
* @see GeneralEnvelope#simplify()
*
* @since 0.4
*/
@SuppressWarnings("ReturnOfCollectionOrArrayField")
public Envelope[] toSimpleEnvelopes() {
// A bitmask of the dimensions having a "wrap around" behavior.
long isWrapAround = 0;
CoordinateReferenceSystem crs = null;
final int dimension = getDimension();
for (int i = 0; i != dimension; i++) {
// Do not use getSpan(i).
final double span = getUpper(i) - getLower(i);
if (!(span > 0)) {
// Use '!' for catching NaN.
if (!isNegative(span)) {
// Span is positive zero.
return EMPTY;
}
if (crs == null) {
crs = getCoordinateReferenceSystem();
}
if (!isWrapAround(crs, i)) {
return EMPTY;
}
if (i >= Long.SIZE) {
// a CRS is unusual enough for not being worth to make the distinction in the error message.
throw new IllegalStateException(Errors.format(Errors.Keys.ExcessiveListSize_2, "axis", dimension));
}
isWrapAround |= (1L << i);
}
}
/*
* The number of simple envelopes is 2ⁿ where n is the number of wraparound found. In most
* cases, isWrapAround == 0 so we have an array of length 1 containing only this envelope.
*/
final int bitCount = Long.bitCount(isWrapAround);
if (bitCount >= Integer.SIZE - 1) {
// Should be very unusual, but let be paranoiac.
throw new IllegalStateException(Errors.format(Errors.Keys.ExcessiveListSize_2, "wraparound", bitCount));
}
final Envelope[] envelopes = new Envelope[1 << bitCount];
if (envelopes.length == 1) {
envelopes[0] = this;
} else {
/*
* Need to create at least 2 envelopes. Instantiate now all envelopes with ordinate values
* initialized to a copy of this envelope. We will write directly in their internal arrays later.
*/
double[] c = new double[dimension * 2];
for (int i = 0; i < dimension; i++) {
c[i] = getLower(i);
c[i + dimension] = getUpper(i);
}
final double[][] ordinates = new double[envelopes.length][];
for (int i = 0; i < envelopes.length; i++) {
final GeneralEnvelope envelope = new GeneralEnvelope(i == 0 ? c : c.clone());
envelope.crs = crs;
envelopes[i] = envelope;
ordinates[i] = envelope.ordinates;
}
/*
* Assign the minimum and maximum ordinate values in the dimension where a wraparound has been found.
* The 'for' loop below iterates only over the 'i' values for which the 'isWrapAround' bit is set to 1.
*/
// For identifying whether we need to set the lower or the upper ordinate.
int mask = 1;
@SuppressWarnings("null") final CoordinateSystem // Should not be null at this point.
cs = crs.getCoordinateSystem();
for (int i; (i = Long.numberOfTrailingZeros(isWrapAround)) != Long.SIZE; isWrapAround &= ~(1L << i)) {
final CoordinateSystemAxis axis = cs.getAxis(i);
final double min = axis.getMinimumValue();
final double max = axis.getMaximumValue();
for (int j = 0; j < ordinates.length; j++) {
c = ordinates[j];
if ((j & mask) == 0) {
c[i + dimension] = max;
} else {
c[i] = min;
}
}
mask <<= 1;
}
}
return envelopes;
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class LocationViewer method addLocation.
/**
* Adds the location identified by the given label
*
* @param label a label that identify the location to add.
* @param location the location to add to the list of locations shown by this widget.
* @throws FactoryException if a transformation to the display CRS can not be obtained.
* @throws TransformException if an error occurred while transforming an envelope.
*/
public void addLocation(final String label, final AbstractLocation location) throws FactoryException, TransformException {
final Envelope envelope = location.getEnvelope();
final MathTransform2D tr = (MathTransform2D) CRS.findOperation(envelope.getCoordinateReferenceSystem(), displayCRS, null).getMathTransform();
final Shape shape = tr.createTransformedShape(new IntervalRectangle(envelope));
if (locations.putIfAbsent(label, shape) != null) {
throw new IllegalArgumentException("A location is already defined for " + label);
}
final Rectangle2D b = shape.getBounds2D();
if (bounds == null) {
bounds = b;
} else {
bounds.add(b);
}
}
use of org.opengis.geometry.Envelope in project sis by apache.
the class AbstractLocation method getPosition.
/**
* Returns coordinates of a representative point for the location instance.
* This is typically (but not necessarily) the centroid of the location instance.
*
* <p>The default implementation returns the {@linkplain #getEnvelope()} median position.</p>
*
* @return coordinates of a representative point for the location instance, or {@code null} if none.
*/
public Position getPosition() {
final Envelope envelope = getEnvelope();
if (envelope == null) {
return null;
}
final int dimension = envelope.getDimension();
final GeneralDirectPosition pos = new GeneralDirectPosition(dimension);
pos.setCoordinateReferenceSystem(envelope.getCoordinateReferenceSystem());
for (int i = 0; i < dimension; i++) {
pos.setOrdinate(i, envelope.getMedian(i));
}
return pos;
}
Aggregations