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

Reply via email to