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 24f9656e3605f761226d1a9ff242289bc138a734 Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu Jan 3 16:59:42 2019 +0100 Replaced checked exceptions by an unchecked exception in GridGeometry. --- .../org/apache/sis/coverage/grid/GridGeometry.java | 133 ++++++++++++--------- .../grid/InvalidGridGeometryException.java | 67 +++++++++++ .../apache/sis/coverage/grid/GridGeometryTest.java | 36 ++---- 3 files changed, 155 insertions(+), 81 deletions(-) diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java index 3d4c2cc..0b2644d 100644 --- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java +++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridGeometry.java @@ -237,35 +237,39 @@ public class GridGeometry implements Serializable { * @param extent the new extent for the grid geometry to construct, or {@code null} if none. * @param toOther transform from this grid coordinates to {@code other} grid coordinates, or {@code null} if none. * @throws NullPointerException if {@code extent} is {@code null} and the other grid geometry contains no other information. - * @throws TransformException if the math transform can not compute the geospatial envelope from the grid extent. + * @throws InvalidGridGeometryException if the math transform can not compute the geospatial envelope from the grid extent. * * @see #subExtent(Envelope) * @see #subgrid(Envelope, double...) */ - GridGeometry(final GridGeometry other, final GridExtent extent, final MathTransform toOther) throws TransformException { + GridGeometry(final GridGeometry other, final GridExtent extent, final MathTransform toOther) { ArgumentChecks.ensureNonNull("other", other); final int dimension = other.getDimension(); this.extent = extent; ensureDimensionMatches(dimension, extent); - if (toOther == null || toOther.isIdentity()) { - gridToCRS = other.gridToCRS; - cornerToCRS = other.cornerToCRS; - resolution = other.resolution; - nonLinears = other.nonLinears; - } else { - gridToCRS = MathTransforms.concatenate(toOther, other.gridToCRS); - cornerToCRS = MathTransforms.concatenate(toOther, other.cornerToCRS); - resolution = resolution(gridToCRS, extent); - nonLinears = findNonLinearTargets(gridToCRS); - } - ImmutableEnvelope envelope = other.envelope; // We will share the same instance if possible. - ImmutableEnvelope computed = computeEnvelope(gridToCRS, (envelope != null) ? envelope.getCoordinateReferenceSystem() : null, envelope); - if (computed == null || !computed.equals(envelope)) { - envelope = computed; - } - this.envelope = envelope; - if (envelope == null && gridToCRS == null) { - ArgumentChecks.ensureNonNull("extent", extent); + try { + if (toOther == null || toOther.isIdentity()) { + gridToCRS = other.gridToCRS; + cornerToCRS = other.cornerToCRS; + resolution = other.resolution; + nonLinears = other.nonLinears; + } else { + gridToCRS = MathTransforms.concatenate(toOther, other.gridToCRS); + cornerToCRS = MathTransforms.concatenate(toOther, other.cornerToCRS); + resolution = resolution(gridToCRS, extent); + nonLinears = findNonLinearTargets(gridToCRS); + } + ImmutableEnvelope envelope = other.envelope; // We will share the same instance if possible. + ImmutableEnvelope computed = computeEnvelope(gridToCRS, (envelope != null) ? envelope.getCoordinateReferenceSystem() : null, envelope); + if (computed == null || !computed.equals(envelope)) { + envelope = computed; + } + this.envelope = envelope; + if (envelope == null && gridToCRS == null) { + ArgumentChecks.ensureNonNull("extent", extent); + } + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); } } @@ -308,23 +312,25 @@ public class GridGeometry implements Serializable { * @param crs the coordinate reference system of the "real world" coordinates, or {@code null} if unknown. * @throws NullPointerException if {@code extent}, {@code gridToCRS} and {@code crs} arguments are all null. * @throws MismatchedDimensionException if the math transform and the CRS do not have consistent dimensions. - * @throws TransformException if the math transform can not compute the geospatial envelope or resolution from the grid extent. + * @throws InvalidGridGeometryException if the math transform can not compute the geospatial envelope or resolution from the grid extent. */ - public GridGeometry(final GridExtent extent, final PixelInCell anchor, final MathTransform gridToCRS, - final CoordinateReferenceSystem crs) throws TransformException - { + public GridGeometry(final GridExtent extent, final PixelInCell anchor, final MathTransform gridToCRS, final CoordinateReferenceSystem crs) { if (gridToCRS != null) { ensureDimensionMatches(gridToCRS.getSourceDimensions(), extent); ArgumentChecks.ensureDimensionMatches("crs", gridToCRS.getTargetDimensions(), crs); } else if (crs == null) { ArgumentChecks.ensureNonNull("extent", extent); } - this.extent = extent; - this.gridToCRS = PixelTranslation.translate(gridToCRS, anchor, PixelInCell.CELL_CENTER); - this.cornerToCRS = PixelTranslation.translate(gridToCRS, anchor, PixelInCell.CELL_CORNER); - this.envelope = computeEnvelope(gridToCRS, crs, null); // 'gridToCRS' specified by the user, not 'this.gridToCRS'. - this.resolution = resolution(gridToCRS, extent); // 'gridToCRS' or 'cornerToCRS' does not matter here. - this.nonLinears = findNonLinearTargets(gridToCRS); + try { + this.extent = extent; + this.gridToCRS = PixelTranslation.translate(gridToCRS, anchor, PixelInCell.CELL_CENTER); + this.cornerToCRS = PixelTranslation.translate(gridToCRS, anchor, PixelInCell.CELL_CORNER); + this.envelope = computeEnvelope(gridToCRS, crs, null); // 'gridToCRS' specified by the user, not 'this.gridToCRS'. + this.resolution = resolution(gridToCRS, extent); // 'gridToCRS' or 'cornerToCRS' does not matter here. + this.nonLinears = findNonLinearTargets(gridToCRS); + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } } /** @@ -389,12 +395,10 @@ public class GridGeometry implements Serializable { * There is no guarantees that the envelope actually stored in the {@code GridGeometry} * will be equal to this specified envelope. * @param rounding controls behavior of rounding from floating point values to integers. - * @throws TransformException if the math transform can not compute the grid extent or the resolution. + * @throws InvalidGridGeometryException if the math transform can not compute the grid extent or the resolution. */ @SuppressWarnings("null") - public GridGeometry(final PixelInCell anchor, final MathTransform gridToCRS, final Envelope envelope, - final GridRoundingMode rounding) throws TransformException - { + public GridGeometry(final PixelInCell anchor, final MathTransform gridToCRS, final Envelope envelope, final GridRoundingMode rounding) { if (gridToCRS == null) { ArgumentChecks.ensureNonNull("envelope", envelope); } else { @@ -406,9 +410,14 @@ public class GridGeometry implements Serializable { Matrix scales = MathTransforms.getMatrix(gridToCRS); int numToIgnore = 1; if (envelope != null && cornerToCRS != null) { - GeneralEnvelope env = Envelopes.transform(cornerToCRS.inverse(), envelope); - extent = new GridExtent(env, GridRoundingMode.NEAREST, null, null, null); - env = extent.toCRS(cornerToCRS, gridToCRS); // 'gridToCRS' specified by the user, not 'this.gridToCRS'. + GeneralEnvelope env; + try { + env = Envelopes.transform(cornerToCRS.inverse(), envelope); + extent = new GridExtent(env, GridRoundingMode.NEAREST, null, null, null); + env = extent.toCRS(cornerToCRS, gridToCRS); // 'gridToCRS' specified by the user, not 'this.gridToCRS'. + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } env.setCoordinateReferenceSystem(envelope.getCoordinateReferenceSystem()); this.envelope = new ImmutableEnvelope(env); if (scales == null) try { @@ -433,9 +442,7 @@ public class GridGeometry implements Serializable { * @param extent the extent to validate, or {@code null} if none. * @param expected the expected number of dimension. */ - private static void ensureDimensionMatches(final int expected, final GridExtent extent) - throws MismatchedDimensionException - { + private static void ensureDimensionMatches(final int expected, final GridExtent extent) throws MismatchedDimensionException { if (extent != null) { final int dimension = extent.getDimension(); if (dimension != expected) { @@ -656,14 +663,18 @@ public class GridGeometry implements Serializable { * @param areaOfInterest the desired spatiotemporal region in any CRS (transformations will be applied as needed). * @return a grid extent of the same dimension than the grid geometry which intersects the given area of interest. * @throws IncompleteGridGeometryException if this grid geometry has no extent or no "grid to CRS" transform. - * @throws TransformException if an error occurred while converting the envelope coordinates to grid coordinates. + * @throws InvalidGridGeometryException if an error occurred while converting the envelope coordinates to grid coordinates. * * @see #subgrid(Envelope, double...) */ - public GridExtent subExtent(final Envelope areaOfInterest) throws IncompleteGridGeometryException, TransformException { + public GridExtent subExtent(final Envelope areaOfInterest) throws IncompleteGridGeometryException { ArgumentChecks.ensureNonNull("areaOfInterest", areaOfInterest); requireGridToCRS(); - return new SubgridCalculator(this, cornerToCRS, areaOfInterest, null).extent; + try { + return new SubgridCalculator(this, cornerToCRS, areaOfInterest, null).extent; + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } } /** @@ -679,15 +690,19 @@ public class GridGeometry implements Serializable { * * @param slicePoint the coordinates where to get a slice. * @return a slice of the grid extent at the given slice point. - * @throws TransformException if an error occurred while converting the point coordinates to grid coordinates. + * @throws InvalidGridGeometryException if an error occurred while converting the point coordinates to grid coordinates. * @throws PointOutsideCoverageException if the given point is outside the grid extent. * * @see #slice(DirectPosition) */ - public GridExtent subExtent(final DirectPosition slicePoint) throws TransformException { + public GridExtent subExtent(final DirectPosition slicePoint) { ArgumentChecks.ensureNonNull("slicePoint", slicePoint); requireGridToCRS(); - return new SubgridCalculator(this, cornerToCRS, slicePoint).extent; + try { + return new SubgridCalculator(this, cornerToCRS, slicePoint).extent; + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } } /** @@ -1021,14 +1036,19 @@ public class GridGeometry implements Serializable { * or {@code null} or an empty array if no sub-sampling is desired. * @return a grid geometry over the specified sub-region of this grid geometry with the specified resolution. * @throws IncompleteGridGeometryException if this grid geometry has no extent or no "grid to CRS" transform. - * @throws TransformException if an error occurred while converting the envelope coordinates to grid coordinates. + * @throws InvalidGridGeometryException if an error occurred while converting the envelope coordinates to grid coordinates. * * @see #subExtent(Envelope) * @see GridExtent#subsample(int[]) */ - public GridGeometry subgrid(final Envelope areaOfInterest, double... targetResolution) throws TransformException { + public GridGeometry subgrid(final Envelope areaOfInterest, double... targetResolution) { requireGridToCRS(); - final SubgridCalculator sub = new SubgridCalculator(this, cornerToCRS, areaOfInterest, targetResolution); + final SubgridCalculator sub; + try { + sub = new SubgridCalculator(this, cornerToCRS, areaOfInterest, targetResolution); + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } if (sub.toSubsampled != null || sub.extent != extent) { return new GridGeometry(this, sub.extent, sub.toSubsampled); } @@ -1058,15 +1078,20 @@ public class GridGeometry implements Serializable { * * @param slicePoint the coordinates where to get a slice. * @return a slice of this grid geometry at the given slice point. May be {@code this}. - * @throws TransformException if an error occurred while converting the point coordinates to grid coordinates. + * @throws InvalidGridGeometryException if an error occurred while converting the point coordinates to grid coordinates. * @throws PointOutsideCoverageException if the given point is outside the grid extent. * * @see #subExtent(DirectPosition) */ - public GridGeometry slice(final DirectPosition slicePoint) throws TransformException { + public GridGeometry slice(final DirectPosition slicePoint) { ArgumentChecks.ensureNonNull("slicePoint", slicePoint); requireGridToCRS(); - final GridExtent slice = new SubgridCalculator(this, cornerToCRS, slicePoint).extent; + final GridExtent slice; + try { + slice = new SubgridCalculator(this, cornerToCRS, slicePoint).extent; + } catch (TransformException e) { + throw new InvalidGridGeometryException(e); + } return (slice != extent) ? new GridGeometry(this, slice, null) : this; } @@ -1091,7 +1116,7 @@ public class GridGeometry implements Serializable { } else try { return new GridGeometry(this, lower, upper); } catch (FactoryException e) { - throw new RuntimeException(e); // TODO + throw new InvalidGridGeometryException(e); } } diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/InvalidGridGeometryException.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/InvalidGridGeometryException.java new file mode 100644 index 0000000..3e25392 --- /dev/null +++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/InvalidGridGeometryException.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.coverage.grid; + + +/** + * Thrown when the argument specified to a method or constructor would result in an invalid {@link GridGeometry}. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.0 + * @since 1.0 + * @module + */ +public class InvalidGridGeometryException extends IllegalArgumentException { + /** + * Serial number for inter-operability with different versions. + */ + private static final long serialVersionUID = -7849140502096470380L; + + /** + * Constructs an exception with no detail message. + */ + public InvalidGridGeometryException() { + } + + /** + * Constructs an exception with the specified detail message. + * + * @param message the detail message. + */ + public InvalidGridGeometryException(final String message) { + super(message); + } + + /** + * Constructs an exception with the specified cause. + * + * @param cause the cause for this exception. + */ + public InvalidGridGeometryException(final Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the specified detail message and cause. + * + * @param message the detail message. + * @param cause the cause for this exception. + */ + public InvalidGridGeometryException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java b/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java index f484946..a86d706 100644 --- a/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java +++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/grid/GridGeometryTest.java @@ -56,11 +56,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests construction with an identity transform mapping pixel corner. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testFromPixelCorner() throws TransformException { + public void testFromPixelCorner() { final long[] low = new long[] {100, 300, 3, 6}; final long[] high = new long[] {200, 400, 4, 7}; final GridExtent extent = new GridExtent(null, low, high, true); @@ -102,11 +100,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests construction with an identity transform mapping pixel center. * This results a 0.5 pixel shifts in the "real world" envelope. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testFromPixelCenter() throws TransformException { + public void testFromPixelCenter() { final long[] low = new long[] { 0, 0, 2}; final long[] high = new long[] {99, 199, 4}; final GridExtent extent = new GridExtent(null, low, high, true); @@ -146,11 +142,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests the {@link GridGeometry#GridGeometry(GridGeometry, GridExtent, MathTransform)} constructor. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testFromOther() throws TransformException { + public void testFromOther() { long[] low = new long[] { 1, 3, 2}; long[] high = new long[] {101, 203, 4}; GridExtent extent = new GridExtent(null, low, high, false); @@ -173,11 +167,9 @@ public final strictfp class GridGeometryTest extends TestCase { * Tests construction from a <cite>grid to CRS</cite> having a 0.5 pixel translation. * This translation happens in transform mapping <cite>pixel center</cite> when the * corresponding <cite>pixel corner</cite> transformation is identity. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testShifted() throws TransformException { + public void testShifted() { final long[] low = new long[] {100, 300}; final long[] high = new long[] {200, 400}; final GridExtent extent = new GridExtent(null, low, high, true); @@ -191,11 +183,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests construction with a non-linear component in the transform. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testNonLinear() throws TransformException { + public void testNonLinear() { final GridExtent extent = new GridExtent( new DimensionNameType[] { DimensionNameType.COLUMN, @@ -221,11 +211,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests the construction from a geospatial envelope. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test - public void testFromGeospatialEnvelope() throws TransformException { + public void testFromGeospatialEnvelope() { final GeneralEnvelope envelope = new GeneralEnvelope(HardCodedCRS.WGS84_φλ); envelope.setRange(0, -70.001, +80.002); envelope.setRange(1, 4.997, 15.003); @@ -249,12 +237,10 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests {@link GridGeometry#subExtent(Envelope)}. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test @DependsOnMethod("testFromGeospatialEnvelope") - public void testSubExtent() throws TransformException { + public void testSubExtent() { GeneralEnvelope envelope = new GeneralEnvelope(HardCodedCRS.WGS84_3D); envelope.setRange(0, -80, 120); envelope.setRange(1, -12, 21); @@ -281,12 +267,10 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests {@link GridGeometry#subExtent(Envelope)} with a non-linear "grid to CRS" transform. - * - * @throws TransformException if an error occurred while using the "grid to CRS" transform. */ @Test @DependsOnMethod({"testNonLinear", "testSubExtent"}) - public void testSubExtentNonLinear() throws TransformException { + public void testSubExtentNonLinear() { final GridExtent extent = new GridExtent( new DimensionNameType[] { DimensionNameType.COLUMN, @@ -372,11 +356,9 @@ public final strictfp class GridGeometryTest extends TestCase { /** * Tests {@link GridGeometry#slice(DirectPosition)}. - * - * @throws TransformException if an error occurred during computation. */ @Test - public void testSlice() throws TransformException { + public void testSlice() { final GridGeometry grid = new GridGeometry( new GridExtent(null, new long[] {336, 20, 4}, new long[] {401, 419, 10}, true), PixelInCell.CELL_CORNER, MathTransforms.linear(new Matrix4(
