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
commit 29ab2c8a4470bb677bbd4a370a616f600eda3063 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sat Jul 16 18:26:43 2022 +0200 Remove the `if (quantity instanceof Scalar)` special case in `Quantities` because it add conversions on top of conversions already done. Documentation updates related to units of measurement. --- .../apache/sis/internal/util/SetOfUnknownSize.java | 4 +-- .../java/org/apache/sis/measure/Quantities.java | 38 ++++++++++------------ .../org/apache/sis/measure/QuantityFormat.java | 13 +++----- .../java/org/apache/sis/measure/UnitFormat.java | 2 -- .../java/org/apache/sis/measure/UnitServices.java | 2 +- .../main/java/org/apache/sis/measure/Units.java | 3 -- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java b/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java index be3fcda9f4..399bdf67e3 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java +++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java @@ -68,8 +68,8 @@ public abstract class SetOfUnknownSize<E> extends AbstractSet<E> { /** * Returns the number of elements in this set. The default implementation counts the number of elements - * returned by the {@link #iterator() iterator}. Subclasses are encouraged to cache this value if they - * know that the underlying storage is immutable. + * returned by the {@linkplain #iterator() iterator}. Subclasses are encouraged to cache this value + * if they know that the underlying storage is immutable. * * @return the number of elements in this set. */ diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java index 3c47d6242d..f798ca6a74 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java @@ -42,7 +42,7 @@ import org.apache.sis.util.resources.Errors; * </ul> * * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.3 * @since 0.8 * @module */ @@ -218,25 +218,23 @@ public final class Quantities extends Static { Number v2 = u2.getConverterTo(s2).convert(q2.getValue()); if (Numbers.isNaN(v2)) return q1; if (Numbers.isNaN(v1)) return q2; - /* - * If the two types are instances of `Scalar`, we can compare them directly. Otherwise convert the - * `Scalar` type (if any) to `Double` type, then convert again to the widest type of both values. - */ - final boolean t1 = (v1 instanceof Scalar); - final boolean t2 = (v2 instanceof Scalar); - if (!(t1 & t2)) { - if (t1) v1 = v1.doubleValue(); - if (t2) v2 = v2.doubleValue(); - final Class<? extends Number> type = Numbers.widestClass(v1, v2); - v1 = Numbers.cast(v1, type); - v2 = Numbers.cast(v2, type); - } - /* - * Both v1 and v2 are instance of `Comparable<?>` because `Numbers.widestClass(…)` - * accepts only known number types such as `Integer`, `Float`, `BigDecimal`, etc. - */ - @SuppressWarnings("unchecked") - final int c = ((Comparable) v1).compareTo((Comparable) v2); + final int c = compare(v1, v2); return (max ? c >= 0 : c <= 0) ? q1 : q2; } + + /** + * Compares the two given number, without casting to {@code double} if we can avoid that cast. + * The intent is to avoid loosing precision for example by casting a {@code BigDecimal}. + */ + @SuppressWarnings("unchecked") + private static int compare(final Number v1, final Number v2) { + if (v1 instanceof Comparable<?>) { + if (v1.getClass().isInstance(v2)) { + return ((Comparable) v1).compareTo(v2); + } else if (v2 instanceof Comparable<?> && v2.getClass().isInstance(v1)) { + return -((Comparable) v2).compareTo(v1); + } + } + return Double.compare(v1.doubleValue(), v2.doubleValue()); + } } diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java index 9060ccf455..b727122486 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java @@ -24,6 +24,7 @@ import java.text.ParsePosition; import javax.measure.Quantity; import javax.measure.Unit; import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.internal.util.FinalFieldSetter; /** @@ -130,16 +131,10 @@ public class QuantityFormat extends Format { public QuantityFormat clone() { final QuantityFormat clone = (QuantityFormat) super.clone(); try { - java.lang.reflect.Field field; - field = QuantityFormat.class.getField("numberFormat"); - field.setAccessible(true); - field.set(clone, numberFormat.clone()); - - field = QuantityFormat.class.getField("unitFormat"); - field.setAccessible(true); - field.set(clone, unitFormat.clone()); + FinalFieldSetter.set(QuantityFormat.class, "numberFormat", "unitFormat", + clone, numberFormat.clone(), unitFormat.clone()); } catch (ReflectiveOperationException e) { - throw new AssertionError(e); + throw FinalFieldSetter.cloneFailure(e); } return clone; } 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 d5df26e825..73ca72bff9 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 @@ -68,8 +68,6 @@ import static java.util.logging.Logger.getLogger; * The attributes in netCDF files often merge the axis direction with the angular unit, * as in {@code "degrees_east"}, {@code "degrees_north"} or {@code "Degrees North"}. * This class ignores those suffixes and unconditionally returns {@link Units#DEGREE} for all axis directions. - * In particular, the units for {@code "degrees_west"} and {@code "degrees_east"} do <strong>not</strong> have - * opposite sign. It is caller responsibility to handle the direction of axes associated to netCDF units. * * <h2>Multi-threading</h2> * {@code UnitFormat} is generally not thread-safe. If units need to be parsed or formatted in different threads, diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java index 386e114762..0c615ea354 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java @@ -46,7 +46,7 @@ import static java.util.logging.Logger.getLogger; * without direct dependency. A {@code UnitServices} instance can be obtained by call to {@link #current()}. * * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.2 * @since 0.8 * @module */ 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 0cad26f04f..d2fa3a646f 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 @@ -1709,9 +1709,6 @@ public final class Units extends Static { * The attributes in netCDF files often merge the axis direction with the angular unit, * as in {@code "degrees_east"} or {@code "degrees_north"}. This {@code valueOf} method * ignores those suffixes and unconditionally returns {@link #DEGREE} for all axis directions. - * In particular, the units for {@code "degrees_west"} and {@code "degrees_east"} - * do <strong>not</strong> have opposite sign. - * It is caller responsibility to handle the direction of axes associated to netCDF units. * * @param uom the symbol to parse, or {@code null}. * @return the parsed symbol, or {@code null} if {@code uom} was null.