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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 4c685b5 Add a Units.converter(scale, offset) method. 4c685b5 is described below commit 4c685b550d04354050a5934e7486b2e1b64f21f0 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Mon Aug 6 18:53:16 2018 +0200 Add a Units.converter(scale, offset) method. --- .../operation/transform/MathTransforms.java | 4 ++- .../java/org/apache/sis/measure/AbstractUnit.java | 3 ++ .../org/apache/sis/measure/LinearConverter.java | 34 ++++++++++++++++++++-- .../main/java/org/apache/sis/measure/Units.java | 15 ++++++++++ .../apache/sis/measure/LinearConverterTest.java | 10 +++++++ 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java index c62765d..8322ba6 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java @@ -93,6 +93,8 @@ public final class MathTransforms extends Static { * @param scale the {@code scale} term in the linear equation. * @param offset the {@code offset} term in the linear equation. * @return the linear transform for the given scale and offset. + * + * @see org.apache.sis.measure.Units#converter(Number, Number) */ public static LinearTransform linear(final double scale, final double offset) { return LinearTransform1D.create(scale, offset); @@ -154,7 +156,7 @@ public final class MathTransforms extends Static { * Both {@code preimage} (the <var>x</var>) and {@code values} (the <var>y</var>) arguments can be null: * * <ul> - * <li>If both {@code preimage} and {@code values} arrays are non-null, then the must have the same length.</li> + * <li>If both {@code preimage} and {@code values} arrays are non-null, then they must have the same length.</li> * <li>If both {@code preimage} and {@code values} arrays are null, then this method returns the identity transform.</li> * <li>If only {@code preimage} is null, then the <var>x</var> values are taken as {0, 1, 2, …, {@code values.length} - 1}.</li> * <li>If only {@code values} is null, then the <var>y</var> values are taken as {0, 1, 2, …, {@code preimage.length} - 1}.</li> diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java index 66b7530..6e4783d 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java @@ -241,6 +241,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo */ @Override public final Unit<Q> shift(final double offset) { + if (offset == 0) return this; return transform(LinearConverter.offset(offset, 1)); } @@ -253,6 +254,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo */ @Override public final Unit<Q> multiply(double multiplier) { + if (multiplier == 1) return this; final double divisor = inverse(multiplier); if (divisor != 1) multiplier = 1; return transform(LinearConverter.scale(multiplier, divisor)); @@ -267,6 +269,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements Unit<Q>, LenientCo */ @Override public final Unit<Q> divide(double divisor) { + if (divisor == 1) return this; final double multiplier = inverse(divisor); if (multiplier != 1) divisor = 1; return transform(LinearConverter.scale(multiplier, divisor)); diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java index 1277864..42fb5b0 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java @@ -100,12 +100,31 @@ final class LinearConverter extends AbstractConverter implements LenientComparab } /** + * Creates a linear converter from the given scale and offset, which may be {@link BigDecimal} instances. + * This is the implementation of public {@link Units#converter(Number, Number)} method. + */ + static LinearConverter create(final Number scale, final Number offset) { + final double numerator, divisor; + double shift = (offset != null) ? offset.doubleValue() : 0; + if (scale instanceof Fraction) { + numerator = ((Fraction) scale).numerator; + divisor = ((Fraction) scale).denominator; + shift *= divisor; + } else { + numerator = (scale != null) ? scale.doubleValue() : 1; + divisor = 1; + } + final LinearConverter c = create(numerator, shift, divisor); + if (scale instanceof BigDecimal) c.scale10 = (BigDecimal) scale; + if (offset instanceof BigDecimal) c.offset10 = (BigDecimal) offset; + return c; + } + + /** * Returns a linear converter for the given scale and offset. */ private static LinearConverter create(final double scale, final double offset, final double divisor) { - if (offset == 0) { - if (scale == divisor) return IDENTITY; - } + if (offset == 0 && scale == divisor) return IDENTITY; return new LinearConverter(scale, offset, divisor); } @@ -113,6 +132,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab * Returns a linear converter for the given ratio. The scale factor is specified as a ratio because * the unit conversion factors are often defined with a value in base 10. That value is considered * exact by definition, but IEEE 754 has no exact representation of decimal fraction digits. + * + * <p>It is caller's responsibility to skip this method call when {@code numerator} = {@code denominator}. + * This method does not perform this check because it is usually already done (indirectly) by the caller.</p> */ static LinearConverter scale(final double numerator, final double denominator) { return new LinearConverter(numerator, 0, denominator); @@ -122,6 +144,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab * Returns a converter for the given shift. The translation is specified as a fraction because the * unit conversion terms are often defined with a value in base 10. That value is considered exact * by definition, but IEEE 754 has no exact representation of decimal fraction digits. + * + * <p>It is caller's responsibility to skip this method call when {@code numerator} = 0. + * This method does not perform this check because it is usually already done by the caller.</p> */ static LinearConverter offset(final double numerator, final double denominator) { return new LinearConverter(denominator, numerator, denominator); @@ -132,6 +157,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab * {@linkplain #isLinear() is linear} (this is not verified) and takes only the scale factor; * the offset (if any) is ignored. * + * <p>It is caller's responsibility to skip this method call when {@code n} = 1. + * This method does not perform this check because it is usually already done (indirectly) by the caller.</p> + * * @param converter the converter to raise to the given power. * @param n the exponent. * @param root {@code true} for raising to 1/n instead of n. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java index 1b7335d..8822a43 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java @@ -1503,6 +1503,21 @@ public final class Units extends Static { } /** + * Creates a linear converter from the given scale and offset. + * + * @param scale the scale factor, or {@code null} if none. + * @param offset the offset, or {@code null} if none. + * @return a converter for the given scale and offset. + * + * @see org.apache.sis.referencing.operation.transform.MathTransforms#linear(double, double) + * + * @since 1.0 + */ + public static UnitConverter converter(final Number scale, final Number offset) { + return LinearConverter.create(scale, offset); + } + + /** * Returns the coefficients of the given converter expressed as a polynomial equation. * This method returns the first of the following choices that apply: * diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java index d25e8d5..c4b3ca0 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java @@ -59,6 +59,16 @@ public final strictfp class LinearConverterTest extends TestCase { } /** + * Tests {@link LinearConverter#create(Number, Number)}. + */ + @Test + public void testCreate() { + assertTrue(LinearConverter.create(null, null).isIdentity()); + assertScale(3, 1, LinearConverter.create(3, 0)); + assertScale(3, 2, LinearConverter.create(new Fraction(3, 2), null)); + } + + /** * Tests {@link LinearConverter#pow(UnitConverter, int, boolean)}. */ @Test