This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit c208f7273783a463b1c3e420d25bea9699556dec Author: Martin Desruisseaux <[email protected]> AuthorDate: Wed Oct 3 12:42:09 2018 -0400 Be more specific in operation builders about whether 'getSourceEnvelope()' maps cell corners or cell centers. Minor improvement in supportive methods. --- .../java/org/apache/sis/geometry/Envelopes.java | 2 ++ .../org/apache/sis/geometry/GeneralEnvelope.java | 26 ++++++++++---- .../operation/builder/LinearTransformBuilder.java | 11 ++++-- .../operation/builder/LocalizationGridBuilder.java | 42 +++++++++++++++++----- pom.xml | 23 +++++++++--- .../apache/sis/storage/geotiff/Localization.java | 2 +- 6 files changed, 82 insertions(+), 24 deletions(-) diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java index c96adbe..0bea159 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java @@ -220,6 +220,8 @@ public final class Envelopes extends Static { 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. final CoordinateOperation operation; try { operation = CoordinateOperations.factory().createOperation(sourceCRS, targetCRS); diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java index f6c21e0..cf2f0fb 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java @@ -401,14 +401,26 @@ public class GeneralEnvelope extends ArrayEnvelope implements Cloneable, Seriali final int beginIndex = beginIndex(); final int dimension = endIndex() - beginIndex; ensureDimensionMatches("envelope", dimension, envelope); - final DirectPosition lower = envelope.getLowerCorner(); - final DirectPosition upper = envelope.getUpperCorner(); final int d = ordinates.length >>> 1; - for (int i=0; i<dimension; i++) { - final int iLower = beginIndex + i; - final int iUpper = iLower + d; - ordinates[iLower] = lower.getOrdinate(i); - ordinates[iUpper] = upper.getOrdinate(i); + 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).ordinates; + final int srcOffset = ((ArrayEnvelope) envelope).beginIndex(); + System.arraycopy(source, srcOffset, ordinates, beginIndex, dimension); + System.arraycopy(source, srcOffset + (source.length >>> 1), ordinates, 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; + ordinates[iLower] = lower.getOrdinate(i); + ordinates[iUpper] = upper.getOrdinate(i); + } } final CoordinateReferenceSystem envelopeCRS = envelope.getCoordinateReferenceSystem(); if (envelopeCRS != null) { diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java index 4626307..88123bb 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java @@ -340,9 +340,16 @@ search: for (int j=0; j<numPoints; j++) { } /** - * Returns the envelope of source points. The lower and upper values are inclusive. + * Returns the envelope of source points. This method returns the known minimum and maximum values for each dimension, + * <strong>not</strong> expanded to encompass full cell surfaces. In other words, the returned envelope encompasses only + * {@linkplain org.opengis.referencing.datum.PixelInCell#CELL_CENTER cell centers}. * - * @return the envelope of source points. + * <p>If a grid size was {@link #LinearTransformBuilder(int...) specified at construction time}, + * then those minimums and maximums are inferred from the grid size and are always integer values. + * Otherwise, the minimums and maximums are extracted from the control points and may be any floating point values. + * In any cases, the lower and upper values are inclusive.</p> + * + * @return the envelope of source points (cell centers), inclusive. * @throws IllegalStateException if the source points are not yet known. * * @since 1.0 diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java index 56e0205..f0abca3 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java @@ -32,6 +32,7 @@ import org.apache.sis.referencing.operation.matrix.Matrix3; import org.apache.sis.referencing.datum.DatumShiftGrid; import org.apache.sis.internal.referencing.Resources; import org.apache.sis.geometry.DirectPosition2D; +import org.apache.sis.geometry.GeneralEnvelope; import org.apache.sis.geometry.Envelopes; import org.apache.sis.internal.util.Numerics; import org.apache.sis.util.ArgumentChecks; @@ -77,6 +78,7 @@ public class LocalizationGridBuilder extends TransformBuilder { /** * The transform for the linear part. + * Always created with a grid size specified to the constructor. */ private final LinearTransformBuilder linear; @@ -88,6 +90,7 @@ public class LocalizationGridBuilder extends TransformBuilder { /** * Conversions from source real-world coordinates to grid indices before interpolation. + * If there is no such conversion to apply, then this is the identity transform. */ private LinearTransform sourceToGrid; @@ -109,7 +112,7 @@ public class LocalizationGridBuilder extends TransformBuilder { * @param height the number of rows in the grid of target positions. */ public LocalizationGridBuilder(final int width, final int height) { - linear = new LinearTransformBuilder(width, height); + linear = new LinearTransformBuilder(width, height); sourceToGrid = MathTransforms.identity(2); } @@ -316,13 +319,25 @@ public class LocalizationGridBuilder extends TransformBuilder { } /** - * Returns the envelope of source coordinates. This is the envelope of the grid domain - * (i.e. the ranges of valid {@code gridX} and {@code gridY} argument values in calls - * to {@code get/setControlPoint(…)} methods) transformed by the inverse of - * {@linkplain #getSourceToGrid() source to grid} transform. - * The lower and upper values are inclusive. + * Returns the envelope of source coordinates. The {@code fullArea} argument control whether + * the returned envelope shall encompass full surface of every cells or only their centers: + * <ul> + * <li>If {@code true}, then the returned envelope encompasses full cell surfaces, + * from lower border to upper border. In other words, the returned envelope encompasses all + * {@linkplain org.opengis.referencing.datum.PixelInCell#CELL_CORNER cell corners}.</li> + * <li>If {@code false}, then the returned envelope encompasses only + * {@linkplain org.opengis.referencing.datum.PixelInCell#CELL_CENTER cell centers}, inclusive.</li> + * </ul> + * + * This is the envelope of the grid domain (i.e. the ranges of valid {@code gridX} and {@code gridY} argument + * values in calls to {@code get/setControlPoint(…)} methods) transformed as below: + * <ol> + * <li>expanded by ½ cell on each side if {@code fullArea} is {@code true}</li> + * <li>transformed by the inverse of {@linkplain #getSourceToGrid() source to grid} transform.</li> + * </ol> * - * @return the envelope of grid points. + * @param fullArea whether the the envelope shall encompass the full cell surfaces instead than only their centers. + * @return the envelope of grid points, from lower corner to upper corner. * @throws IllegalStateException if the grid points are not yet known. * @throws TransformException if the envelope can not be calculated. * @@ -330,8 +345,17 @@ public class LocalizationGridBuilder extends TransformBuilder { * * @since 1.0 */ - public Envelope getSourceEnvelope() throws TransformException { - return Envelopes.transform(sourceToGrid.inverse(), linear.getSourceEnvelope()); + public Envelope getSourceEnvelope(final boolean fullArea) throws TransformException { + Envelope envelope = linear.getSourceEnvelope(); + if (fullArea) { + for (int i = envelope.getDimension(); --i >= 0;) { + final GeneralEnvelope ge = GeneralEnvelope.castOrCopy(envelope); + ge.setRange(i, ge.getLower(i) - 0.5, + ge.getUpper(i) + 0.5); + envelope = ge; + } + } + return Envelopes.transform(sourceToGrid.inverse(), envelope); } /** diff --git a/pom.xml b/pom.xml index 26eb439..4961239 100644 --- a/pom.xml +++ b/pom.xml @@ -583,6 +583,24 @@ </executions> </plugin> + <!-- Cleanup local repository by removing Apache SIS snapshots --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>3.0.0</version> + <executions> + <execution> + <id>remove-old-artifacts</id> + <goals> + <goal>remove-project-artifact</goal> + </goals> + <configuration> + <removeAll>false</removeAll> <!-- Remove only snapshots of this project version. --> + </configuration> + </execution> + </executions> + </plugin> + <!-- Compile --> <plugin> <artifactId>maven-compiler-plugin</artifactId> @@ -893,11 +911,6 @@ <pluginManagement> <plugins> <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>build-helper-maven-plugin</artifactId> - <version>3.0.0</version> - </plugin> - <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.4.11.v20180605</version> diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java index 988db1e..66f5278 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java @@ -102,7 +102,7 @@ final class Localization { } grid.setDesiredPrecision(PRECISION); final MathTransform tr = grid.create(null); - if (addTo != null && addTo.put(grid.getSourceEnvelope(), tr) != null) { + if (addTo != null && addTo.put(grid.getSourceEnvelope(false), tr) != null) { throw new FactoryException(); // Should never happen. If it does, we have a bug in our algorithm. } return tr;
