You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by js...@apache.org on 2025/06/12 10:07:57 UTC
(sis) 02/02: Implement ExportableTransform for EllipsoidToRadiusTransform
This is an automated email from the ASF dual-hosted git repository.
jsorel pushed a commit to branch feat/exportableTransform
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 9386f8fe782404391b2b3bec0f95abde818b9211
Author: jsorel <jo...@geomatys.com>
AuthorDate: Thu Jun 12 12:07:20 2025 +0200
Implement ExportableTransform for EllipsoidToRadiusTransform
---
.../sis/referencing/ExportableTransform.java | 2 +-
.../transform/EllipsoidToCentricTransform.java | 103 ++++++++++++---------
.../transform/EllipsoidToRadiusTransform.java | 63 +++++++++----
3 files changed, 105 insertions(+), 63 deletions(-)
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/ExportableTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/ExportableTransform.java
index 52f9238575..ad0250efc0 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/ExportableTransform.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/ExportableTransform.java
@@ -26,7 +26,7 @@ public interface ExportableTransform {
/**
* The produced code should transform one value only.
* Input array is expected to be named src.
- * Ouput array is expected to be named dat.
+ * Ouput array is expected to be named dst.
*
* Example of expected produced code :
* <pre>
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
index 46ef6c71e6..cf7824023b 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java
@@ -966,12 +966,19 @@ public class EllipsoidToCentricTransform extends AbstractMathTransform implement
"\t\tconst sinφ = Math.sin(φ);\n" +
"\t\tconst ν = 1.0/Math.sqrt(1 - eccentricitySquared * (sinφ*sinφ)); // Prime vertical radius of curvature at latitude φ\n" +
"\t\tconst rcosφ = (ν + h) * Math.cos(φ);\n" +
- "\t\tconst d0 = rcosφ * Math.cos(λ); // X: Toward prime meridian\n" +
- "\t\tconst d1 = rcosφ * Math.sin(λ); // Y: Toward 90° east\n" +
- "\t\tconst d2 = (ν * (1 - eccentricitySquared) + h) * sinφ; // Z: Toward north pole\n" +
- "\t\treturn [d0,d1,d2];\n" +
- "\t}\n"
+ "\t\tconst Z = (h + ν * (1.0 - eccentricitySquared)) * sinφ;\n");
+
+ if (toSphericalCS) {
+ sb.append(
+ "\t\treturn [λ, Math.atan(Z / rcosφ), Math.hypot(Z, rcosφ)];" +
+ "\t}\n"
+ );
+ } else {
+ sb.append(
+ "\t\treturn [rcosφ * Math.cos(λ), rcosφ * Math.sin(λ), Z];" +
+ "\t}\n"
);
+ }
} else {
//constants
sb.append("\t_ANGULAR_TOLERANCE : ").append(Double.toString(Formulas.ANGULAR_TOLERANCE)).append(",\n");
@@ -986,54 +993,62 @@ public class EllipsoidToCentricTransform extends AbstractMathTransform implement
sb.append(
"\ttransform : function(src){\n" +
- "\t\tlet dst = new Array("+getTargetDimensions()+");\n" +
- "\t\tconst X = src[0];\n" +
- "\t\tconst Y = src[1];\n" +
- "\t\tconst Z = src[2];\n" +
- "\t\tconst p = Math.hypot(X, Y);\n" +
- "\t\tconst tanq = Z / (p*this._axisRatio);\n" +
- "\t\tconst cos2q = 1.0/(1.0 + tanq*tanq);\n" +
- "\t\tconst sin2q = 1.0 - cos2q;\n" +
- "\t\tlet φ = Math.atan((Z + this._copySign(this._eccentricitySquared * sin2q*Math.sqrt(sin2q), tanq) / this._axisRatio) /\n" +
- " (p - this._eccentricitySquared * cos2q*Math.sqrt(cos2q)));\n" +
- "\t\t\n");
- if (!useIterations) {
+ "\t\tlet dst = new Array("+getTargetDimensions()+");\n"
+ );
+
+ if (toSphericalCS) {
sb.append(
- "\t\tdst[0] = Math.atan2(Y, X);\n" +
- "\t\tdst[1] = φ;\n");
- if (withHeight) {
- sb.append(
- "\t\tconst sinφ = Math.sin(φ);\n" +
- "\t\tconst ν = 1.0/Math.sqrt(1 - this._eccentricitySquared * (sinφ*sinφ));\n" +
- "\t\tdst[2] = p/Math.cos(φ) - ν;\n");
- }
+ "\t\tconst λ = src[0]; // Spherical longitude\n" +
+ "\t\tconst Ω = src[1]; // Spherical latitude\n" +
+ "\t\tconst R = src[2]; // Spherical radius\n" +
+ "\t\tconst p = R * Math.cos(Ω); // Projection of radius in equatorial plane\n" +
+ "\t\tconst Z = R * Math.sin(Ω); // Toward north pole\n"
+ );
} else {
sb.append(
- "\t\tlet found = false;\n" +
- "\t\tfor (let it = this._MAXIMUM_ITERATIONS; !found && it >= 0; it--) {\n" +
- "\t\t\tconst sinφ = Math.sin(φ);\n" +
- "\t\t\tconst ν = 1/sqrt(1 - this._eccentricitySquared * (sinφ*sinφ));\n" +
- "\t\t\tconst Δφ = φ - (φ = atan((Z + this._eccentricitySquared * ν * sinφ) / p));\n" +
- "\t\t\tif (!(abs(Δφ) >= this._ANGULAR_TOLERANCE * (Math.PI/180) * 0.25)) { // Use ! for accepting NaN.\n" +
- "\t\t\t\tdst[0] = Math.atan2(Y, X);\n" +
- "\t\t\t\tdst[1] = φ;\n");
+ "\t\tconst X = src[0]; // Toward prime meridian\n" +
+ "\t\tconst Y = src[1]; // Toward 90° east\n" +
+ "\t\tconst Z = src[2]; // Toward north pole\n" +
+ "\t\tconst p = Math.hypot(X, Y); // Projection of radius in equatorial plane\n" +
+ "\t\tconst λ = Math.atan2(Y, X); // Spherical and geodetic longitude\n"
+ );
+ }
+
+ sb.append(
+ "\t\tconst tanq = Z / (p*this._axisRatio);\n" +
+ "\t\tconst cos2q = 1/(1 + tanq*tanq);\n" +
+ "\t\tconst sin2q = 1 - cos2q;\n" +
+ "\t\tlet φ = Math.atan((Z + this._copySign(this._eccentricitySquared * (Math.sqrt(sin2q) * sin2q), tanq) / this._axisRatio) / (p - this._eccentricitySquared * (Math.sqrt(cos2q) * cos2q)));\n"
+ );
+
+ if (useIterations) {
+ sb.append(
+ "\t\tlet it = this._MAXIMUM_ITERATIONS;\n" +
+ "\t\tlet sinφ = 0.0;\n" +
+ "\t\tlet iν = 0.0;\n" +
+ "\t\tlet Δφ = 0.0;\n" +
+ "\t\tdo {\n" +
+ "\t\t\tif (--it <0) {\n" +
+ "\t\t\t\tthrow new Error(\"No convergence.\");\n" +
+ "\t\t\t}\n" +
+ "\t\t\tsinφ = Math.sin(φ);\n" +
+ "\t\t\tiν = Math.sqrt(1 - this._eccentricitySquared * (sinφ*sinφ));\n" +
+ "\t\t\tΔφ = φ - (φ = Math.atan((Z + this._eccentricitySquared * sinφ / iν) / p));\n" +
+ "\t\twhile (Math.abs(Δφ) >= this._ANGULAR_TOLERANCE * (Math.PI/180) * 0.25);\n"
+ );
if (withHeight) {
sb.append(
- "\t\t\t\tdst[2] = p/Math.cos(φ) - ν;\n");
+ "\t\tdst[2] = (Math.abs(sinφ) == 1.0) ? (Math.abs(Z) - this._axisRatio) : (p/Math.cos(φ) - 1.0/iν);\n"
+ );
}
- sb.append(
- "\t\t\t\tfound = true;\n" +
- "\t\t\t}\n" +
- "\t\t}\n" +
- "\t\tif (!found) {\n" +
- "\t\t\tdst[0] = Number.NaN;\n" +
- "\t\t\tdst[1] = Number.NaN;\n" +
- "\t\t}\n"
- );
}
+
sb.append(
+ "\t\tdst[0] = λ;\n" +
+ "\t\tdst[1] = φ;\n" +
"\t\treturn dst;\n" +
- "\t}\n");
+ "\t}\n"
+ );
}
sb.append("}");
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
index 94e625e118..14dd9cc8b6 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
@@ -16,38 +16,39 @@
*/
package org.apache.sis.referencing.operation.transform;
-import java.util.Arrays;
import java.io.Serializable;
import static java.lang.Math.*;
+import java.util.Arrays;
import javax.measure.Unit;
import javax.measure.quantity.Length;
-import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.referencing.datum.Ellipsoid;
-import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.MathTransformFactory;
-import org.opengis.referencing.operation.TransformException;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.parameter.Parameterized;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.ExportableTransform;
import org.apache.sis.referencing.datum.DefaultEllipsoid;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.provider.MapProjection;
import org.apache.sis.referencing.operation.provider.Spherical2Dto3D;
import org.apache.sis.referencing.operation.provider.Spherical3Dto2D;
-import org.apache.sis.referencing.privy.ReferencingUtilities;
import org.apache.sis.referencing.privy.Formulas;
-import org.apache.sis.parameter.Parameters;
-import org.apache.sis.parameter.Parameterized;
-import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.util.Debug;
+import org.apache.sis.referencing.privy.ReferencingUtilities;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.Debug;
import org.apache.sis.util.privy.Constants;
import org.apache.sis.util.privy.DoubleDouble;
import org.apache.sis.util.privy.Numerics;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.util.FactoryException;
/**
@@ -86,7 +87,7 @@ import org.apache.sis.util.privy.Numerics;
*
* @since 1.5
*/
-public class EllipsoidToRadiusTransform extends AbstractMathTransform implements Serializable {
+public class EllipsoidToRadiusTransform extends AbstractMathTransform implements Serializable, ExportableTransform {
/**
* Serial number for inter-operability with different versions.
*/
@@ -405,7 +406,7 @@ public class EllipsoidToRadiusTransform extends AbstractMathTransform implements
* The "almost" is because {@link #inverse()} returns a non-linear transform.
* For that reason, this class cannot implement {@link LinearTransform}.
*/
- private final class Inverse extends OnewayLinearTransform implements Parameterized {
+ private final class Inverse extends OnewayLinearTransform implements Parameterized, ExportableTransform {
/**
* Serial number for inter-operability with different versions.
*/
@@ -463,6 +464,11 @@ public class EllipsoidToRadiusTransform extends AbstractMathTransform implements
pg.values().addAll(EllipsoidToRadiusTransform.this.getParameterValues().values());
return pg;
}
+
+ @Override
+ public String toECMAScript() throws UnsupportedOperationException {
+ return DELEGATE.toECMAScript();
+ }
}
/**
@@ -502,4 +508,25 @@ public class EllipsoidToRadiusTransform extends AbstractMathTransform implements
}
return false;
}
+
+ @Override
+ public String toECMAScript() throws UnsupportedOperationException {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("{\n");
+
+ sb.append(
+ "\ttransform : function(src){\n" +
+ "\t\tconst eccentricitySquared = " + Double.toString(eccentricitySquared) + ";\n" +
+ "\t\tconst Ω = src[1];\n" +
+ "\t\tconst cosΩ = Math.cos(Ω);\n" +
+ "\t\tconst r2 = 1 - eccentricitySquared*(cosΩ*cosΩ);\n" +
+ "\t\tconst r = Math.sqrt(r2); // Inverse of radius.\n" +
+ "\t\treturn [src[0], Ω, 1.0/r];\n" +
+ "\t}\n"
+ );
+
+ sb.append("}");
+ return sb.toString();
+ }
+
}