sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/02: Replace checked exceptions by unchecked exceptions in GeodeticCalculator API.
Date Tue, 13 Aug 2019 11:59:23 GMT
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 07448caccffe67c985a0cf2ac00ff6f55e8bdf5a
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Aug 13 13:45:39 2019 +0200

    Replace checked exceptions by unchecked exceptions in GeodeticCalculator API.
---
 .../org/apache/sis/services/LocationServlet.java   | 13 +--
 .../org/apache/sis/distance/LatLonPointRadius.java | 43 ++++------
 .../apache/sis/internal/referencing/Resources.java |  5 ++
 .../sis/internal/referencing/Resources.properties  |  1 +
 .../internal/referencing/Resources_fr.properties   |  1 +
 .../sis/referencing/GeodesicsOnEllipsoid.java      |  9 +-
 .../apache/sis/referencing/GeodeticCalculator.java | 97 ++++++++++++++--------
 ...odesicException.java => GeodeticException.java} | 33 +++++---
 .../sis/referencing/GeodesicsOnEllipsoidTest.java  | 18 +---
 .../sis/referencing/GeodeticCalculatorTest.java    | 49 +++--------
 .../java/org/apache/sis/index/tree/QuadTree.java   |  7 +-
 11 files changed, 134 insertions(+), 142 deletions(-)

diff --git a/application/sis-webapp/src/main/java/org/apache/sis/services/LocationServlet.java
b/application/sis-webapp/src/main/java/org/apache/sis/services/LocationServlet.java
index e06d73a..d3754f4 100644
--- a/application/sis-webapp/src/main/java/org/apache/sis/services/LocationServlet.java
+++ b/application/sis-webapp/src/main/java/org/apache/sis/services/LocationServlet.java
@@ -51,7 +51,6 @@ import org.w3c.dom.Text;
 import org.xml.sax.SAXException;
 
 import org.opengis.geometry.DirectPosition;
-import org.opengis.referencing.operation.TransformException;
 
 //SIS imports
 import org.apache.sis.geometry.DirectPosition2D;
@@ -312,14 +311,10 @@ public class LocationServlet extends HttpServlet {
 
         StringBuilder regionStr = new StringBuilder();
 
-        try {
-          for (int i = 0; i <= 360; i += 10) {
-            calculator.setStartingAzimuth(i);
-            DirectPosition pt = calculator.getEndPoint();
-            regionStr.append(pt.getOrdinate(1)).append(',').append(pt.getOrdinate(0)).append(',');
-          }
-        } catch (TransformException e) {
-          throw new ServletException(e);            // Should never happen.
+        for (int i = 0; i <= 360; i += 10) {
+          calculator.setStartingAzimuth(i);
+          DirectPosition pt = calculator.getEndPoint();
+          regionStr.append(pt.getOrdinate(1)).append(',').append(pt.getOrdinate(0)).append(',');
         }
         regions.add(regionStr.substring(0, regionStr.length() - 1));
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/distance/LatLonPointRadius.java
b/core/sis-referencing/src/main/java/org/apache/sis/distance/LatLonPointRadius.java
index 976bec6..a58d767 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/distance/LatLonPointRadius.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/distance/LatLonPointRadius.java
@@ -24,7 +24,6 @@ import java.awt.geom.Rectangle2D;
 
 // GeoAPI import
 import org.opengis.geometry.DirectPosition;
-import org.opengis.referencing.operation.TransformException;
 
 //SIS imports
 import org.apache.sis.geometry.DirectPosition2D;
@@ -86,15 +85,11 @@ public class LatLonPointRadius {
     calculator.setStartGeographicPoint(center.getOrdinate(1), center.getOrdinate(0));
     calculator.setGeodesicDistance(radius);
 
-    try {
-      for (int i = 0; i < numberOfPoints; i++)
-      {
-        calculator.setStartingAzimuth(i * bearingIncrement);
-        DirectPosition p = calculator.getEndPoint();
-        points[i] = new DirectPosition2D(p.getOrdinate(1), p.getOrdinate(0));
-      }
-    } catch (TransformException e) {
-      throw new IllegalStateException(e);       // Should never happen.
+    for (int i = 0; i < numberOfPoints; i++)
+    {
+      calculator.setStartingAzimuth(i * bearingIncrement);
+      DirectPosition p = calculator.getEndPoint();
+      points[i] = new DirectPosition2D(p.getOrdinate(1), p.getOrdinate(0));
     }
 
     points[numberOfPoints] = points[0];
@@ -121,24 +116,20 @@ public class LatLonPointRadius {
     Path2D path = new Path2D.Double();
     double initX = Double.NaN, previousX = Double.NaN;
     calculator.setGeodesicDistance(radius);
-    try {
-      for (int i = 0; i < 360; i++) {
-        calculator.setStartingAzimuth(i);
-        DirectPosition pt = calculator.getEndPoint();
-        double x = pt.getOrdinate(1) + 180.0;
-        double y = pt.getOrdinate(0) + 90.0;
-        if (i == 0) {
-          initX = Longitude.normalize(x);
-          path.moveTo(x, y);
-        } else {
-          path.lineTo(x, y);
-          if (dateLineCrossOver(previousX, previousX = Longitude.normalize(x))) {
-            numberOfCrossOvers++;
-          }
+    for (int i = 0; i < 360; i++) {
+      calculator.setStartingAzimuth(i);
+      DirectPosition pt = calculator.getEndPoint();
+      double x = pt.getOrdinate(1) + 180.0;
+      double y = pt.getOrdinate(0) + 90.0;
+      if (i == 0) {
+        initX = Longitude.normalize(x);
+        path.moveTo(x, y);
+      } else {
+        path.lineTo(x, y);
+        if (dateLineCrossOver(previousX, previousX = Longitude.normalize(x))) {
+          numberOfCrossOvers++;
         }
       }
-    } catch (TransformException e) {
-      throw new IllegalStateException(e);       // Should never happen.
     }
     if (dateLineCrossOver(previousX, initX)) {
       numberOfCrossOvers++;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
index 5a419f7..c456c97 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
@@ -88,6 +88,11 @@ public final class Resources extends IndexedResourceBundle {
         public static final short CanNotConcatenateTransforms_2 = 3;
 
         /**
+         * Can not convert a point {0,choice,0#from|1#to} coordinate reference system “{1}”.
+         */
+        public static final short CanNotConvertCoordinates_2 = 89;
+
+        /**
          * Can not create an object of type “{1}” as an instance of class ‘{0}’.
          */
         public static final short CanNotCreateObjectAsInstanceOf_2 = 4;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
index 755e08b..854340c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
@@ -46,6 +46,7 @@ AzimuthAndDistanceNotSet          = The azimuth and distance have not been
speci
 CanNotCombineUriAsType_1          = Can not create objects of type \u2018{0}\u2019 from combined
URI.
 CanNotComputeDerivative           = Can not compute the coordinate operation derivative.
 CanNotConcatenateTransforms_2     = Can not concatenate transforms \u201c{0}\u201d and \u201c{1}\u201d.
+CanNotConvertCoordinates_2        = Can not convert a point {0,choice,0#from|1#to} coordinate
reference system \u201c{1}\u201d.
 CanNotCreateObjectAsInstanceOf_2  = Can not create an object of type \u201c{1}\u201d as an
instance of class \u2018{0}\u2019.
 CanNotFindCommonCRS               = Can not find a coordinate reference system common to
all given envelopes.
 CanNotInferGridSizeFromValues_1   = Can not infer a grid size from the given values in {0}
range.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
index aca7f24..7a32d59 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
@@ -51,6 +51,7 @@ AzimuthAndDistanceNotSet          = Le cap et la distance n\u2019ont pas
\u00e9t
 CanNotCombineUriAsType_1          = Ne peut pas cr\u00e9er d\u2019objets de type \u2018{0}\u2019
\u00e0 partir d\u2019un URI combin\u00e9.
 CanNotComputeDerivative           = La d\u00e9riv\u00e9 de l\u2019op\u00e9ration sur les
coordonn\u00e9es ne peut pas \u00eatre calcul\u00e9e.
 CanNotConcatenateTransforms_2     = Les transformations \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb
ne peuvent pas \u00eatre combin\u00e9es.
+CanNotConvertCoordinates_2        = Ne peut pas convertir un point {0,choice,0#\u00e0 partir
du|1#vers le} syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es \u00ab\u202f{1}\u202f\u00bb.
 CanNotCreateObjectAsInstanceOf_2  = Ne peut pas cr\u00e9er un objet du type \u00ab\u202f{1}\u202f\u00bb
comme une instance de la classe \u2018{0}\u2019.
 CanNotFindCommonCRS               = Ne peut pas trouver un syst\u00e8me de r\u00e9f\u00e9rence
des coordonn\u00e9es commun pour toutes les enveloppes donn\u00e9es.
 CanNotInferGridSizeFromValues_1   = Ne peut pas inf\u00e9rer une taille de grille \u00e0
partir des valeurs donn\u00e9es dans la plage {0}.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
index 52ba4db..0191dc4 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing;
 import org.opengis.geometry.coordinate.Position;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.referencing.operation.GeodesicException;
 import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.math.MathFunctions;
@@ -555,10 +554,10 @@ class GeodesicsOnEllipsoid extends GeodeticCalculator {
      * </ul>
      *
      * @throws IllegalStateException if the distance or azimuth has not been set.
-     * @throws GeodesicException if an azimuth or the distance can not be computed.
+     * @throws GeodeticException if an azimuth or the distance can not be computed.
      */
     @Override
-    final void computeDistance() throws GeodesicException {
+    final void computeDistance() {
         canComputeDistance();
         /*
          * The algorithm in this method requires the following canonical configuration:
@@ -612,7 +611,7 @@ class GeodesicsOnEllipsoid extends GeodeticCalculator {
              */
             if (Δλ > axisRatio * PI) {
                 // Karney's special case documented before equation 45.
-                throw new GeodesicException("Can not compute geodesics for antipodal points
on equator.");
+                throw new GeodeticException("Can not compute geodesics for antipodal points
on equator.");
             }
             super.computeDistance();
             return;
@@ -751,7 +750,7 @@ class GeodesicsOnEllipsoid extends GeodeticCalculator {
             if (abs(Δλ_error) <= ITERATION_TOLERANCE) {
                 moreRefinements = 0;
             } else if (--moreRefinements == 0) {
-                throw new GeodesicException(Resources.format(Resources.Keys.NoConvergence));
+                throw new GeodeticException(Resources.format(Resources.Keys.NoConvergence));
             }
             /*
              * Special case for α₁ = π/2 and β₂ = ±β₁ (Karney's equation 47).
We replace the β₂ = ±β₁
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
index ffae49b..6ebfdb4 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
@@ -37,7 +37,6 @@ import org.apache.sis.measure.AngleFormat;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Units;
 import org.apache.sis.geometry.CoordinateFormat;
-import org.apache.sis.referencing.operation.GeodesicException;
 import org.apache.sis.internal.referencing.PositionTransformer;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.j2d.ShapeUtilities;
@@ -344,21 +343,34 @@ public class GeodeticCalculator {
     }
 
     /**
+     * Returns the error message to give to {@link GeodeticException} when a {@link TransformException}
occurred.
+     *
+     * @param  toCRS  {@code false} if converting from the position CRS, {@code true} if
converting to the position CRS.
+     */
+    private String transformError(final boolean toCRS) {
+        return Resources.format(Resources.Keys.CanNotConvertCoordinates_2,
+                toCRS ? 1 : 0, IdentifiedObjects.getName(getPositionCRS(), null));
+    }
+
+    /**
      * Returns the starting point in the CRS specified at construction time.
      * This method returns the last point given to a {@code setStartPoint(…)} method,
      * transformed to the {@linkplain #getPositionCRS() position CRS}.
      *
      * @return the starting point represented in the CRS specified at construction time.
-     * @throws TransformException if the coordinates can not be transformed to {@linkplain
#getPositionCRS() position CRS}.
      * @throws IllegalStateException if the start point has not yet been specified.
+     * @throws GeodeticException if the coordinates can not be transformed to {@linkplain
#getPositionCRS() position CRS}.
      *
      * @see #getEndPoint()
      */
-    public DirectPosition getStartPoint() throws TransformException {
+    public DirectPosition getStartPoint() {
         if (isInvalid(START_POINT)) {
             throw new IllegalStateException(Resources.format(Resources.Keys.StartOrEndPointNotSet_1,
0));
+        } else try {
+            return geographic(φ1, λ1).inverseTransform();
+        } catch (TransformException e) {
+            throw new GeodeticException(transformError(true), e);
         }
-        return geographic(φ1, λ1).inverseTransform();
     }
 
     /**
@@ -368,12 +380,17 @@ public class GeodeticCalculator {
      * the CRS specified at construction time.
      *
      * @param  point  the starting point in any coordinate reference system.
-     * @throws TransformException if the coordinates can not be transformed.
+     * @throws IllegalArgumentException if the given coordinates can not be transformed.
      *
      * @see #setEndPoint(Position)
      */
-    public void setStartPoint(final Position point) throws TransformException {
-        final DirectPosition p = userToGeodetic.transform(point.getDirectPosition());
+    public void setStartPoint(final Position point) {
+        final DirectPosition p;
+        try {
+            p = userToGeodetic.transform(point.getDirectPosition());
+        } catch (TransformException e) {
+            throw new IllegalArgumentException(transformError(false), e);
+        }
         setStartGeographicPoint(p.getOrdinate(0), p.getOrdinate(1));
     }
 
@@ -407,16 +424,20 @@ public class GeodeticCalculator {
      * and the current azimuth and distance.
      *
      * @return the destination (end point) represented in the CRS specified at construction
time.
-     * @throws TransformException if the coordinates can not be computed.
      * @throws IllegalStateException if the destination point, azimuth or distance have not
been set.
+     * @throws GeodeticException if the coordinates can not be computed.
      *
      * @see #getStartPoint()
      */
-    public DirectPosition getEndPoint() throws TransformException {
+    public DirectPosition getEndPoint() {
         if (isInvalid(END_POINT)) {
             computeEndPoint();
         }
-        return geographic(φ2, λ2).inverseTransform();
+        try {
+            return geographic(φ2, λ2).inverseTransform();
+        } catch (TransformException e) {
+            throw new GeodeticException(transformError(true), e);
+        }
     }
 
     /**
@@ -426,12 +447,17 @@ public class GeodeticCalculator {
      * the CRS specified at construction time.
      *
      * @param  position  the destination (end point) in any coordinate reference system.
-     * @throws TransformException if the coordinates can not be transformed.
+     * @throws IllegalArgumentException if the given coordinates can not be transformed.
      *
      * @see #setStartPoint(Position)
      */
-    public void setEndPoint(final Position position) throws TransformException {
-        final DirectPosition p = userToGeodetic.transform(position.getDirectPosition());
+    public void setEndPoint(final Position position) {
+        final DirectPosition p;
+        try {
+            p = userToGeodetic.transform(position.getDirectPosition());
+        } catch (TransformException e) {
+            throw new IllegalArgumentException(transformError(false), e);
+        }
         setEndGeographicPoint(p.getOrdinate(0), p.getOrdinate(1));
     }
 
@@ -466,9 +492,9 @@ public class GeodeticCalculator {
      *
      * @return the azimuth in degrees from -180° to +180°. 0° is toward North and values
are increasing clockwise.
      * @throws IllegalStateException if the end point, azimuth or distance have not been
set.
-     * @throws GeodesicException if the azimuth can not be computed.
+     * @throws GeodeticException if the azimuth can not be computed.
      */
-    public double getStartingAzimuth() throws GeodesicException {
+    public double getStartingAzimuth() {
         if (isInvalid(STARTING_AZIMUTH)) {
             computeDistance();
         }
@@ -504,9 +530,9 @@ public class GeodeticCalculator {
      *
      * @return the azimuth in degrees from -180° to +180°. 0° is toward North and values
are increasing clockwise.
      * @throws IllegalStateException if the destination point, azimuth or distance have not
been set.
-     * @throws GeodesicException if the azimuth can not be computed.
+     * @throws GeodeticException if the azimuth can not be computed.
      */
-    public double getEndingAzimuth() throws GeodesicException {
+    public double getEndingAzimuth() {
         if (isInvalid(ENDING_AZIMUTH)) {
             if (isInvalid(END_POINT)) {
                 computeEndPoint();                      // Compute also ending azimuth from
start point and distance.
@@ -522,7 +548,8 @@ public class GeodeticCalculator {
      * Azimuth is relative to geographic North with values increasing clockwise.
      *
      * @return the azimuth in degrees from -180° to +180°. 0° is toward North and values
are increasing clockwise.
-     * @throws IllegalStateException if a point has not been set.
+     * @throws IllegalStateException if the start point or end point has not been set.
+     * @throws GeodeticException if the azimuth can not be computed.
      */
     public double getConstantAzimuth() {
         if (isInvalid(RHUMBLINE_LENGTH)) {
@@ -538,12 +565,12 @@ public class GeodeticCalculator {
      * the distance will be computed from the {@linkplain #getStartPoint() start point} and
current end point.
      *
      * @return the shortest distance in the unit of measurement given by {@link #getDistanceUnit()}.
-     * @throws IllegalStateException if a point has not been set.
-     * @throws GeodesicException if the distance can not be computed.
+     * @throws IllegalStateException if the start point or end point has not been set.
+     * @throws GeodeticException if the distance can not be computed.
      *
      * @see #getDistanceUnit()
      */
-    public double getGeodesicDistance() throws GeodesicException {
+    public double getGeodesicDistance() {
         if (isInvalid(GEODESIC_DISTANCE)) {
             computeDistance();
         }
@@ -669,9 +696,9 @@ public class GeodeticCalculator {
      * </ul>
      *
      * @throws IllegalStateException if the distance or azimuth has not been set.
-     * @throws GeodesicException if an azimuth or the distance can not be computed.
+     * @throws GeodeticException if an azimuth or the distance can not be computed.
      */
-    void computeDistance() throws GeodesicException {
+    void computeDistance() {
         canComputeDistance();
         final double Δλ    = λ2 - λ1;           // No need to reduce to −π … +π
range.
         final double sinΔλ = sin(Δλ);
@@ -720,9 +747,9 @@ public class GeodeticCalculator {
      * spherical formulas. Subclasses should override if they can provide ellipsoidal formulas.</p>
      *
      * @throws IllegalStateException if the start point, azimuth or distance has not been
set.
-     * @throws GeodesicException if the end point or azimuth can not be computed.
+     * @throws GeodeticException if the end point or ending azimuth can not be computed.
      */
-    void computeEndPoint() throws GeodesicException {
+    void computeEndPoint() {
         canComputeEndPoint();                   // May throw IllegalStateException.
         final double m     = hypot(msinα1, mcosα1);
         final double Δσ    = geodesicDistance / semiMajorAxis;
@@ -751,9 +778,9 @@ public class GeodeticCalculator {
      * some of them will need to be specified again.
      *
      * @see #setStartGeographicPoint(double, double)
-     * @throws GeodesicException if the end point or azimuth can not be computed.
+     * @throws GeodeticException if the end point or ending azimuth can not be computed.
      */
-    public void moveToEndPoint() throws GeodesicException {
+    public void moveToEndPoint() {
         if (isInvalid(END_POINT)) {
             computeEndPoint();
         }
@@ -797,10 +824,10 @@ public class GeodeticCalculator {
      *                    in the units of measurement given by {@link #getDistanceUnit()}.
      *                    This is approximate; the actual errors may vary around that value.
      * @return an approximation of geodesic track as Bézier curves in a Java2D object.
-     * @throws TransformException if the coordinates can not be transformed to {@linkplain
#getPositionCRS() position CRS}.
      * @throws IllegalStateException if some required properties have not been specified.
+     * @throws GeodeticException if some coordinates can not be computed.
      */
-    public Shape createGeodesicPath2D(final double tolerance) throws TransformException {
+    public Shape createGeodesicPath2D(final double tolerance) {
         ArgumentChecks.ensureStrictlyPositive("tolerance", tolerance);
         if (isInvalid(START_POINT | STARTING_AZIMUTH | END_POINT | ENDING_AZIMUTH | GEODESIC_DISTANCE))
{
             if (isInvalid(END_POINT)) {
@@ -813,6 +840,8 @@ public class GeodeticCalculator {
         final Path2D path;
         try {
             path = bezier.build();
+        } catch (TransformException e) {
+            throw new GeodeticException(transformError(true), e);
         } finally {
             bezier.reset();
         }
@@ -844,10 +873,10 @@ public class GeodeticCalculator {
      * @param  tolerance  maximal error in the units of measurement given by {@link #getDistanceUnit()}.
      *                    This is approximate; the actual errors may vary around that value.
      * @return an approximation of circular region as a Java2D object.
-     * @throws TransformException if the coordinates can not be transformed to {@linkplain
#getPositionCRS() position CRS}.
      * @throws IllegalStateException if some required properties have not been specified.
+     * @throws GeodeticException if some coordinates can not be computed.
      */
-    public Shape createGeodesicCircle2D(final double tolerance) throws TransformException
{
+    public Shape createGeodesicCircle2D(final double tolerance) {
         ArgumentChecks.ensureStrictlyPositive("tolerance", tolerance);
         if (isInvalid(START_POINT | GEODESIC_DISTANCE)) {
             computeDistance();
@@ -856,6 +885,8 @@ public class GeodeticCalculator {
         final Path2D path;
         try {
             path = bezier.build();
+        } catch (TransformException e) {
+            throw new GeodeticException(transformError(true), e);
         } finally {
             bezier.reset();
         }
@@ -1086,7 +1117,7 @@ public class GeodeticCalculator {
                         pointFormat.format(endPoint ? getEndPoint() : getStartPoint(), table);
                         table.nextColumn();
                         table.append(azimuthFormat.format(endPoint ? getEndingAzimuth() :
getStartingAzimuth()));
-                    } catch (IllegalStateException | TransformException e) {
+                    } catch (IllegalStateException | GeodeticException e) {
                         // Ignore.
                     }
                     table.nextLine();
@@ -1106,7 +1137,7 @@ public class GeodeticCalculator {
                 resources.appendLabel(Vocabulary.Keys.GeodesicDistance, buffer);
                 buffer.append(' ').append(nf.format(distance))
                       .append(' ').append(unit).append(lineSeparator);
-            } catch (IllegalStateException | GeodesicException e) {
+            } catch (IllegalStateException | GeodeticException e) {
                 // Ignore.
             }
         } catch (IOException e) {
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/GeodesicException.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticException.java
similarity index 63%
rename from core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/GeodesicException.java
rename to core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticException.java
index ca6ce6a..fdeb297 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/GeodesicException.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticException.java
@@ -14,25 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation;
-
-import org.opengis.referencing.operation.TransformException;
+package org.apache.sis.referencing;
 
 
 /**
- * Thrown when an error occurred while computing geodesic between two points.
- *
- * <div class="note"><b>API note:</b>
- * defined as a sub-type of {@link TransformException} because some kind of coordinate operations
are involved in
- * geodesics calculation (e.g. transformation of latitudes and longitudes to coordinates
on an auxiliary sphere).
- * The starting and ending points can also be given in a CRS that require additional coordinate
operations.</div>
+ * Thrown when an error occurred while computing geodesic or rhumb line between two points.
+ * This exception may have a {@link org.opengis.referencing.operation.TransformException}
as its cause.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.0
- * @since   1.0
+ *
+ * @see GeodeticCalculator
+ *
+ * @since 1.0
  * @module
  */
-public class GeodesicException extends TransformException {
+public class GeodeticException extends RuntimeException {
     /**
      * For cross-version compatibility.
      */
@@ -41,7 +38,7 @@ public class GeodesicException extends TransformException {
     /**
      * Constructs a new exception with no message.
      */
-    public GeodesicException() {
+    public GeodeticException() {
         super();
     }
 
@@ -50,7 +47,17 @@ public class GeodesicException extends TransformException {
      *
      * @param message  the detail message, or {@code null} if none.
      */
-    public GeodesicException(final String message) {
+    public GeodeticException(final String message) {
         super(message);
     }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     *
+     * @param message  the detail message, or {@code null} if none.
+     * @param cause    the cause, or {@code null} if none.
+     */
+    public GeodeticException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
 }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
index d753cae..61705de 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
@@ -21,8 +21,6 @@ import java.util.HashMap;
 import java.util.Arrays;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.crs.GeographicCRS;
-import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.operation.GeodesicException;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.referencing.crs.HardCodedCRS;
@@ -224,11 +222,9 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
      * Those values are verified if {@link GeodesicsOnEllipsoid#STORE_LOCAL_VARIABLES} is
{@code true}.
      *
      * <p><b>Source:</b> Karney (2013), <u>Algorithms for geodesics</u>
table 2.</p>
-     *
-     * @throws TransformException should never happen since this method does not apply map
projections.
      */
     @Test
-    public void testComputeEndPoint() throws TransformException {
+    public void testComputeEndPoint() {
         createTracked();
         verifyParametersForWGS84();
         testedEarth.setStartGeographicPoint(40, 10);
@@ -316,12 +312,10 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
      * Those values are verified if {@link GeodesicsOnEllipsoid#STORE_LOCAL_VARIABLES} is
{@code true}.
      *
      * <p><b>Source:</b> Karney (2013), <u>Algorithms for geodesics</u>
table 3.</p>
-     *
-     * @throws GeodesicException if a geodesic can not be computed.
      */
     @Test
     @DependsOnMethod("testComputeEndPoint")
-    public void testComputeShortDistance() throws GeodesicException {
+    public void testComputeShortDistance() {
         createTracked();
         verifyParametersForWGS84();
         testedEarth.setStartGeographicPoint(-30.12345, 2);
@@ -375,12 +369,10 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
      * Those values are verified if {@link GeodesicsOnEllipsoid#STORE_LOCAL_VARIABLES} is
{@code true}.
      *
      * <p><b>Source:</b> Karney (2013), <u>Algorithms for geodesics</u>
tables 4, 5 and 6.</p>
-     *
-     * @throws GeodesicException if a geodesic can not be computed.
      */
     @Test
     @DependsOnMethod("testComputeShortDistance")
-    public void testComputeNearlyAntipodal() throws GeodesicException {
+    public void testComputeNearlyAntipodal() {
         createTracked();
         verifyParametersForWGS84();
         testedEarth.setStartGeographicPoint(-30, 0);
@@ -452,13 +444,11 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
      * Same test than the one defined in parent class, but with expected results modified
for ellipsoidal formulas.
      * Input points are from <a href="https://en.wikipedia.org/wiki/Great-circle_navigation#Example">Wikipedia</a>.
      * Outputs were computed with GeographicLib.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
     @Override
     @DependsOnMethod({"testComputeEndPoint", "testComputeNearlyAntipodal"})
-    public void testGeodesicDistanceAndAzimuths() throws TransformException {
+    public void testGeodesicDistanceAndAzimuths() {
         final GeodeticCalculator c = create(false);
         c.setStartGeographicPoint(-33.0, -71.6);            // Valparaíso
         c.setEndGeographicPoint  ( 31.4, 121.8);            // Shanghai
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
index 5a309fb..2d9ae74 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
@@ -27,8 +27,6 @@ import java.io.IOException;
 import java.io.LineNumberReader;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.cs.AxisDirection;
-import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.operation.GeodesicException;
 import org.apache.sis.internal.referencing.j2d.ShapeUtilitiesExt;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.referencing.crs.HardCodedCRS;
@@ -123,11 +121,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * Tests some simple azimuth directions. The expected directions are approximately North,
East,
      * South and West, but not exactly because of Earth curvature. The test verify merely
that the
      * azimuths are approximately correct.
-     *
-     * @throws GeodesicException if a geodesic can not be computed.
      */
     @Test
-    public void testCardinalAzimuths() throws GeodesicException {
+    public void testCardinalAzimuths() {
         final GeodeticCalculator c = create(false);
         final double tolerance = 0.2;
         c.setStartGeographicPoint(20, 12);
@@ -139,12 +135,10 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
 
     /**
      * Tests azimuths at poles.
-     *
-     * @throws GeodesicException if a geodesic can not be computed.
      */
     @Test
     @DependsOnMethod("testCardinalAzimuths")
-    public void testAzimuthAtPoles() throws GeodesicException {
+    public void testAzimuthAtPoles() {
         final GeodeticCalculator c = create(false);
         final double tolerance = 0.2;
         c.setStartGeographicPoint( 90,  30);
@@ -163,11 +157,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
 
     /**
      * Tests geodesic distances and rhumb line length on the equator.
-     *
-     * @throws GeodesicException if a geodesic can not be computed.
      */
     @Test
-    public void testDistanceAtEquator() throws GeodesicException {
+    public void testDistanceAtEquator() {
         final Random random = TestUtilities.createRandomNumberGenerator(86909845084528L);
         final GeodeticCalculator c = create(false);
         final double a = c.ellipsoid.getSemiMajorAxis();
@@ -188,13 +180,11 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * Tests {@link GeodeticCalculator#getGeodesicDistance()} and azimuths with the example
given in Wikipedia.
      * This computes the great circle route from Valparaíso (33°N 71.6W) to Shanghai (31.4°N
121.8°E).
      *
-     * @throws TransformException if an error occurred while transforming coordinates.
-     *
      * @see <a href="https://en.wikipedia.org/wiki/Great-circle_navigation#Example">Great-circle
navigation on Wikipedia</a>
      */
     @Test
     @DependsOnMethod({"testCardinalAzimuths", "testDistanceAtEquator"})
-    public void testGeodesicDistanceAndAzimuths() throws TransformException {
+    public void testGeodesicDistanceAndAzimuths() {
         final GeodeticCalculator c = create(false);
         c.setStartGeographicPoint(-33.0, -71.6);            // Valparaíso
         c.setEndGeographicPoint  ( 31.4, 121.8);            // Shanghai
@@ -227,12 +217,10 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * Tests geodetic calculator involving a coordinate operation.
      * This test uses a simple CRS with only the axis order interchanged.
      * The coordinates are the same than {@link #testGeodesicDistanceAndAzimuths()}.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
     @DependsOnMethod("testGeodesicDistanceAndAzimuths")
-    public void testUsingTransform() throws TransformException {
+    public void testUsingTransform() {
         final GeodeticCalculator c = create(true);
         assertAxisDirectionsEqual("GeographicCRS", c.getGeographicCRS().getCoordinateSystem(),
AxisDirection.NORTH, AxisDirection.EAST);
         assertAxisDirectionsEqual("PositionCRS",     c.getPositionCRS().getCoordinateSystem(),
AxisDirection.EAST, AxisDirection.NORTH);
@@ -252,11 +240,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
 
     /**
      * Tests {@link GeodeticCalculator#moveToEndPoint()}.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
-    public void testMoveToEndPoint() throws TransformException {
+    public void testMoveToEndPoint() {
         // Following relationship is required by GeodeticCalculator.moveToEndPoint() implementation.
         assertEquals(GeodeticCalculator.ENDING_AZIMUTH >>> 1, GeodeticCalculator.STARTING_AZIMUTH);
         final GeodeticCalculator c = create(false);
@@ -268,12 +254,10 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
 
     /**
      * Tests {@link GeodeticCalculator#createGeodesicCircle2D(double)}.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
     @DependsOnMethod("testUsingTransform")
-    public void testGeodesicCircle2D() throws TransformException {
+    public void testGeodesicCircle2D() {
         final GeodeticCalculator c = create(true);
         c.setStartGeographicPoint(-33.0, -71.6);                // Valparaíso
         c.setGeodesicDistance(100000);                          // 100 km
@@ -293,12 +277,10 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * as a way to verify that user-specified CRS is taken in account. The start point and
end point are the same
      * than in {@link #testGeodesicDistanceAndAzimuths()}. Note that this path crosses the
anti-meridian,
      * so the end point needs to be shifted by 360°.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
     @DependsOnMethod("testUsingTransform")
-    public void testGeodesicPath2D() throws TransformException {
+    public void testGeodesicPath2D() {
         final GeodeticCalculator c = create(true);
         c.setStartGeographicPoint(-33.0, -71.6);                                        //
Valparaíso
         c.setEndGeographicPoint  ( 31.4, 121.8);                                        //
Shanghai
@@ -323,11 +305,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
 
     /**
      * Verifies that all <var>y</var> coordinates are zero for a geodesic path
on equator.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
-    public void testGeodesicPathOnEquator() throws TransformException {
+    public void testGeodesicPathOnEquator() {
         final GeodeticCalculator c = create(false);
         final double tolerance = 1E-12;
         c.setStartGeographicPoint(0, 20);
@@ -346,11 +326,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
     /**
      * Tests geodesic path between random points. The coordinates are compared with values
computed by
      * <a href="https://geographiclib.sourceforge.io/">GeographicLib</a>, taken
as reference implementation.
-     *
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
-    public void testBetweenRandomPoints() throws TransformException {
+    public void testBetweenRandomPoints() {
         final Random random = TestUtilities.createRandomNumberGenerator();
         final GeodeticCalculator c = create(false);
         final Geodesic reference = createReferenceImplementation(c);
@@ -402,7 +380,7 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * @param  resolution  tolerance threshold for the curve approximation, in metres.
      * @return statistics about errors relative to the resolution.
      */
-    private static Statistics[] geodesicPathFitness(final GeodeticCalculator c, final double
resolution) throws TransformException {
+    private static Statistics[] geodesicPathFitness(final GeodeticCalculator c, final double
resolution) {
         final PathIterator iterator = c.createGeodesicPath2D(resolution).getPathIterator(null,
Formulas.ANGULAR_TOLERANCE);
         final Statistics   xError   = new Statistics("∆x/r");
         final Statistics   yError   = new Statistics("∆y/r");
@@ -445,10 +423,9 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
      * This is an optional test executed only if the {@code $SIS_DATA/Tests/GeodTest.dat}
file is found.
      *
      * @throws IOException if an error occurred while reading the test file.
-     * @throws TransformException if an error occurred while transforming coordinates.
      */
     @Test
-    public void compareAgainstDataset() throws IOException, TransformException {
+    public void compareAgainstDataset() throws IOException {
         int noConvergenceCount = 0;
         try (LineNumberReader reader = OptionalTestData.GEODESIC.reader()) {
             final Random random = TestUtilities.createRandomNumberGenerator();
@@ -531,7 +508,7 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
                     assertEquals("λ₂", expected[COLUMN_λ2], end.getOrdinate(1),     
longitudeTolerance);
                     assertEquals("α₂", expected[COLUMN_α2], c.getEndingAzimuth(),   
azimuthTolerance / cosφ2);
                     assertEquals("∆s", expected[COLUMN_Δs], c.getGeodesicDistance(), linearTolerance);
-                } catch (GeodesicException | AssertionError e) {
+                } catch (GeodeticException | AssertionError e) {
                     if (!isTestingInverse || e instanceof AssertionError || isFailure(expected))
{
                         out.printf("Test failure at line %d: %s%n"
                                 + "The values provided in the test file are:%n"
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/index/tree/QuadTree.java b/storage/sis-storage/src/main/java/org/apache/sis/index/tree/QuadTree.java
index 9bbce43..cfb8e4d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/index/tree/QuadTree.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/index/tree/QuadTree.java
@@ -25,7 +25,6 @@ import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.distance.LatLonPointRadius;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.GeodeticCalculator;
-import org.apache.sis.referencing.operation.GeodesicException;
 
 /**
  * Implementation of Quad Tree Index. Insertion algorithm implemented based on
@@ -353,11 +352,7 @@ public class QuadTree {
                     synchronized (calculator) {
                         calculator.setStartGeographicPoint(latLon.y, latLon.x);
                         calculator.setEndGeographicPoint(point.y, point.x);
-                        try {
-                            distance = calculator.getGeodesicDistance();
-                        } catch (GeodesicException e) {
-                            throw new RuntimeException(e);
-                        }
+                        distance = calculator.getGeodesicDistance();
                     }
                     if (distance <= radiusKM) {
                         matches.add(data[i]);


Mime
View raw message