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 e087dea Fix units formatting when the denominator is unitless. https://issues.apache.org/jira/browse/SIS-414. e087dea is described below commit e087dead60576dacce1a2544443bb5611c0f1ae6 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Mon Jul 30 18:46:38 2018 +0200 Fix units formatting when the denominator is unitless. https://issues.apache.org/jira/browse/SIS-414. --- .../main/java/org/apache/sis/math/Fraction.java | 17 ++++++++++- .../java/org/apache/sis/measure/UnitFormat.java | 35 +++++++++++++++------- .../sis/util/collection/DerivedIterator.java | 2 +- .../org/apache/sis/util/collection/DerivedSet.java | 4 +-- .../java/org/apache/sis/math/FractionTest.java | 16 +++++++++- .../org/apache/sis/measure/UnitFormatTest.java | 13 ++++++++ 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/core/sis-utility/src/main/java/org/apache/sis/math/Fraction.java b/core/sis-utility/src/main/java/org/apache/sis/math/Fraction.java index 1cfde39..acc3cdd 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/math/Fraction.java +++ b/core/sis-utility/src/main/java/org/apache/sis/math/Fraction.java @@ -26,7 +26,7 @@ import org.apache.sis.util.collection.WeakHashSet; * All {@code Fraction} instances are immutable and thus inherently thread-safe. * * @author Martin Desruisseaux (MPO, Geomatys) - * @version 0.8 + * @version 1.0 * @since 0.8 * @module */ @@ -364,6 +364,21 @@ public final class Fraction extends Number implements Comparable<Fraction>, Seri } /** + * Returns the sign of this fraction. The return value is -1 if this fraction is negative; + * 0 if the numerator is zero; and 1 if this fraction is positive. + * + * @return the sign of this fraction. + * + * @see Integer#signum(int) + * + * @since 1.0 + */ + public int signum() { + if (numerator == 0) return 0; + return ((numerator ^ denominator) >> (Integer.SIZE - 2)) | 1; + } + + /** * Compares this fraction with the given one for order. * * @param other the fraction to compare to this fraction for ordering. diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java index 033566c..0ff9cc9 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java @@ -642,6 +642,26 @@ public class UnitFormat extends Format implements javax.measure.format.UnitForma * Note that this may produce more verbose symbols than needed since derived units like Volt or Watt are * decomposed into their base SI units. */ + boolean hasPositivePower = false; + final Map<? extends Unit<?>, ? extends Number> components; + if (unit instanceof AbstractUnit<?>) { + // In Apache SIS implementation, power may be fractional. + final Map<SystemUnit<?>, Fraction> c = ((AbstractUnit<?>) unit).getBaseSystemUnits(); + for (final Fraction power : c.values()) { + hasPositivePower = (power.signum() > 0); + if (hasPositivePower) break; + } + components = c; + } else { + // Fallback for foreigner implementations (power restricted to integer). + Map<? extends Unit<?>, Integer> c = unit.getBaseUnits(); + if (c == null) c = Collections.singletonMap(unit, 1); + for (final Integer power : c.values()) { + hasPositivePower = (power > 0); + if (hasPositivePower) break; + } + components = c; + } final double scale = Units.toStandardUnit(unit); if (scale != 1) { if (Double.isNaN(scale)) { @@ -668,18 +688,11 @@ public class UnitFormat extends Format implements javax.measure.format.UnitForma } toAppendTo.append(text, 0, length); } - toAppendTo.append(style.multiply); - } - Map<? extends Unit<?>, ? extends Number> components; - if (unit instanceof AbstractUnit<?>) { - // In Apache SIS implementation, the powers may be ratios. - components = ((AbstractUnit<?>) unit).getBaseSystemUnits(); - } else { - // Fallback for foreigner implementations (powers restricted to integers). - components = unit.getBaseUnits(); - if (components == null) { - components = Collections.singletonMap(unit, 1); + if (hasPositivePower) { + toAppendTo.append(style.multiply); } + } else if (!hasPositivePower) { + toAppendTo.append('1'); } formatComponents(components, style, toAppendTo); return toAppendTo; diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedIterator.java b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedIterator.java index 1dd042b..17699ff 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedIterator.java +++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedIterator.java @@ -23,7 +23,7 @@ import org.apache.sis.util.ObjectConverter; /** * An iterator which performs conversions on the fly using the given converter. * If a value is converted into a null value, then this iterator skips that value. - * Consequently this iterator can not returns null value. + * Consequently this iterator can not return null value. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 0.3 diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java index 0cc5d93..1512eab 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java +++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DerivedSet.java @@ -54,7 +54,7 @@ import org.apache.sis.internal.util.SetOfUnknownSize; * especially the result of the {@link #size()} method. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 0.8 + * @version 1.0 * * @param <S> the type of elements in the storage set. * @param <E> the type of elements in this set. @@ -132,7 +132,7 @@ class DerivedSet<S,E> extends SetOfUnknownSize<E> implements CheckedContainer<E> */ @Override public boolean isEmpty() { - return !storage.isEmpty() || !iterator().hasNext(); + return storage.isEmpty() || !iterator().hasNext(); } /** diff --git a/core/sis-utility/src/test/java/org/apache/sis/math/FractionTest.java b/core/sis-utility/src/test/java/org/apache/sis/math/FractionTest.java index e5ee6ae..afd4552 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/math/FractionTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/math/FractionTest.java @@ -26,7 +26,7 @@ import static org.apache.sis.test.Assert.*; * Tests the {@link Fraction} class. * * @author Martin Desruisseaux (Geomatys) - * @version 0.8 + * @version 1.0 * @since 0.8 * @module */ @@ -76,6 +76,20 @@ public final strictfp class FractionTest extends TestCase { } /** + * Tests the {@link Fraction#signum()} method. + */ + @Test + public void testSignum() { + final int[] numerators = { 0, 1, 2, -3, -9}; + final int[] denominators = { 3, 3, -3, 3, -3}; + final int[] signums = { 0, 1, -1, -1, 1}; + for (int i=0; i<signums.length; i++) { + final Fraction f = new Fraction(numerators[i], denominators[i]); + assertEquals(signums[i], f.signum()); + } + } + + /** * Tests the {@link Fraction#round()} method. */ @Test diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java index 0eded4b..2086412 100644 --- a/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java +++ b/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java @@ -280,6 +280,19 @@ public final strictfp class UnitFormatTest extends TestCase { } /** + * Tests formatting of units when the numerator is unity. + * + * @see <a href="https://issues.apache.org/jira/browse/SIS-414">SIS-414</a> + */ + @Test + public void testUnity() { + final UnitFormat f = new UnitFormat(Locale.UK); + assertEquals( "1∕m²", f.format(Units.UNITY.divide(Units.SQUARE_METRE))); + assertEquals("10⁻²∕m²", f.format(Units.UNITY.divide(100).divide(Units.SQUARE_METRE))); + assertEquals("10⁻²∕m²", f.format(Units.PERCENT.divide(Units.SQUARE_METRE))); + } + + /** * Tests parsing of names. */ @Test