You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/07/16 21:11:06 UTC
[sis] 01/03: 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.
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 <ma...@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.