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 <[email protected]> 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(); + } + }
