Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1767577&r1=1767576&r2=1767577&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] Tue Nov 1 21:03:06 2016
@@ -16,157 +16,919 @@
*/
package org.apache.sis.measure;
-import javax.measure.unit.SI;
-import javax.measure.unit.NonSI;
-import javax.measure.unit.Unit;
-import javax.measure.quantity.Angle;
-import javax.measure.quantity.Length;
-import javax.measure.quantity.Duration;
-import javax.measure.quantity.Dimensionless;
-import javax.measure.quantity.Quantity;
-import javax.measure.converter.UnitConverter;
+import javax.measure.Dimension;
+import javax.measure.Unit;
+import javax.measure.UnitConverter;
+import javax.measure.format.ParserException;
+import javax.measure.Quantity;
+import javax.measure.quantity.*;
+import javax.measure.quantity.Angle; // Because of name collision with Angle in this SIS package.
+import org.opengis.geometry.DirectPosition; // For javadoc
+
import org.apache.sis.util.Static;
import org.apache.sis.util.Workaround;
-import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.Exceptions;
-import org.apache.sis.util.CharSequences;
import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.DefinitionURI;
import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.util.XPaths;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
import static org.apache.sis.measure.SexagesimalConverter.EPS;
-import static org.apache.sis.util.CharSequences.trimWhitespaces;
/**
- * Static methods working on {@link Unit} instances, and some constants in addition to the
- * {@link SI} and {@link NonSI} ones.
+ * Provides constants for various Units of Measurement together with static methods working on {@link Unit} instances.
+ * This class focuses on the most commonly used units in the geospatial domain:
+ * angular units ({@linkplain #DEGREE degree}, {@linkplain #ARC_SECOND arc-second}, …),
+ * linear units ({@linkplain #KILOMETRE kilometre}, {@linkplain #NAUTICAL_MILE nautical mile}, …) and
+ * temporal units ({@linkplain #DAY day}, {@linkplain #TROPICAL_YEAR year}, …).
+ * But some other kind of units are also provided for completeness.
+ *
+ * <p>All Units of Measurement are based on units from the International System (SI).
+ * The fundamental units are listed below, together with some dimensionless units:</p>
+ *
+ * <table class="sis">
+ * <caption>SI fundamental units and dimensionless units</caption>
+ * <tr><th>Quantity type</th> <th>Dimension symbol</th> <th>Base unit</th></tr>
+ * <tr><td>{@link Length}</td> <td>L</td> <td>{@link #METRE}</td></tr>
+ * <tr><td>{@link Mass}</td> <td>M</td> <td>{@link #KILOGRAM}</td></tr>
+ * <tr><td>{@link Time}</td> <td>T</td> <td>{@link #SECOND}</td></tr>
+ * <tr><td>{@link ElectricCurrent}</td> <td>I</td> <td>{@link #AMPERE}</td></tr>
+ * <tr><td>{@link Temperature}</td> <td>Θ</td> <td>{@link #KELVIN}</td></tr>
+ * <tr><td>{@link AmountOfSubstance}</td> <td>N</td> <td>{@link #MOLE}</td></tr>
+ * <tr><td>{@link LuminousIntensity}</td> <td>J</td> <td>{@link #CANDELA}</td></tr>
+ * <tr><td>{@link Angle}</td> <td></td> <td>{@link #RADIAN}</td></tr>
+ * </table>
+ *
+ * Unit names and definitions in this class follow the definitions provided in the EPSG geodetic dataset
+ * (when the unit exists in that dataset),
+ * except “year” which has been renamed “{@linkplain #TROPICAL_YEAR tropical year}”.
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3
- * @version 0.7
+ * @version 0.8
* @module
*/
public final class Units extends Static {
/**
- * The suffixes that NetCDF files sometime put after the "degrees" unit.
- * Suffix at even index are for axes having the standard geometric direction,
- * while suffix at odd index are for axes having the reverse direction.
+ * Unit of measurement defined as 10<sup>-9</sup> metres (1 nm). This unit is often used in
+ * {@linkplain org.apache.sis.metadata.iso.content.DefaultBand#getBoundUnits() wavelength measurements}.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE}
+ * and the unlocalized name is "nanometre".
+ *
+ * @see #CENTIMETRE
+ * @see #MILLIMETRE
+ *
+ * @since 0.8
*/
- private static final String[] CARDINAL_DIRECTIONS = {"east", "west", "north", "south"};
+ public static final Unit<Length> NANOMETRE;
/**
- * Do not allows instantiation of this class.
+ * Unit of measurement defined as 0.001 metres (1 mm).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “millimetre” and the identifier is EPSG:1025.
+ *
+ * @see #NANOMETRE
+ * @see #CENTIMETRE
+ * @see #KILOMETRE
+ *
+ * @since 0.8
*/
- private Units() {
- }
+ public static final Unit<Length> MILLIMETRE;
+
+ /**
+ * Unit of measurement defined as 0.01 metres (1 cm).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “centimetre” and the identifier is EPSG:1033.
+ *
+ * @see #NANOMETRE
+ * @see #MILLIMETRE
+ * @see #KILOMETRE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> CENTIMETRE;
+
+ /**
+ * The SI base unit for distances (m).
+ * The unlocalized name is “metre” and the identifier is EPSG:9001.
+ * This is the base of all other {@linkplain #isLinear(Unit) linear} units:
+ *
+ * {@link #NANOMETRE} (nm),
+ * {@link #MILLIMETRE} (mm),
+ * {@link #CENTIMETRE} (cm),
+ * {@link #KILOMETRE} (km),
+ * {@link #NAUTICAL_MILE} (M),
+ * {@link #STATUTE_MILE} (mi),
+ * {@link #US_SURVEY_FOOT},
+ * {@link #FOOT} (ft),
+ * {@link #INCH} (in) and
+ * {@link #POINT} (pt)
+ * among others.
+ *
+ * @see #SQUARE_METRE
+ * @see #CUBIC_METRE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> METRE;
+
+ /**
+ * Unit of measurement defined as 1000 metres (1 km).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “kilometre” and the identifier is EPSG:9036.
+ *
+ * @see #STATUTE_MILE
+ * @see #NAUTICAL_MILE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> KILOMETRE;
+
+ /**
+ * Unit of measurement defined as exactly 1852 metres (1 M).
+ * This is approximatively the distance between two parallels of latitude
+ * separated by one {@linkplain #ARC_MINUTE arc-minute}.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “nautical mile” and the identifier is EPSG:9030.
+ *
+ * <p>There is no internationally agreed symbol for nautical mile. Apache SIS uses “M” in agreement with the
+ * International Hydrographic Organization (IHO) and the International Bureau of Weights and Measures (BIPM).
+ * But “NM” and “nmi” are also in use.</p>
+ *
+ * @see #STATUTE_MILE
+ * @see #KILOMETRE
+ * @see #ARC_MINUTE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> NAUTICAL_MILE;
+
+ /**
+ * Unit of measurement defined as exactly 1609.344 metres (1 mi).
+ * This unit is often named “mile” without qualifier, but Apache SIS uses “statute mile”
+ * for emphasing the difference with {@linkplain #NAUTICAL_MILE nautical mile}.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE}.
+ * The unlocalized name is “statute mile” but is localized as "international mile" in the US
+ * for avoiding confusion with the US survey mile.
+ * The identifier is EPSG:9093.
+ *
+ * @see #KILOMETRE
+ * @see #NAUTICAL_MILE
+ * @see #FOOT
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> STATUTE_MILE;
+
+ /**
+ * Unit of measurement approximatively equals to 0.3048006096… metres.
+ * The legal definition is exactly 12/39.37 metres.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “US survey foot” and the identifier is EPSG:9003.
+ *
+ * @see #FOOT
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> US_SURVEY_FOOT;
+
+ /**
+ * Unit of measurement defined as exactly 0.3048 metres (1 ft).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE},
+ * the unlocalized name is “foot” and the identifier is EPSG:9002.
+ *
+ * @see #US_SURVEY_FOOT
+ * @see #STATUTE_MILE
+ * @see #INCH
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> FOOT;
+
+ /**
+ * Unit of measurement defined as 2.54 centimetres (1 in).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE}
+ * and the unlocalized name is “inch”.
+ *
+ * @see #CENTIMETRE
+ * @see #POINT
+ * @see #FOOT
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> INCH;
+
+ /**
+ * Unit of measurement defined as 0.013837 inch (1 pt).
+ * This is commonly used to measure the height of a font.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #METRE}
+ * and the unlocalized name is “point”.
+ *
+ * @see #INCH
+ * @see #MILLIMETRE
+ * @see #PIXEL
+ *
+ * @since 0.8
+ */
+ public static final Unit<Length> POINT;
+
+ /**
+ * The SI unit for plane angles (rad).
+ * There is 2π radians in a circle.
+ * The unlocalized name is “radian” and the identifier is EPSG:9101.
+ * This is the base of all other {@linkplain #isAngular(Unit) angular} units:
+ *
+ * {@link #GRAD} (grad),
+ * {@link #DEGREE} (°),
+ * {@link #ARC_MINUTE} (′),
+ * {@link #ARC_SECOND} (″) and
+ * {@link #MICRORADIAN} (µrad)
+ * among others.
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> RADIAN;
+
+ /**
+ * Unit of measurement defined as π/200 radians (1 grad).
+ * There is 400 grads in a circle.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #RADIAN},
+ * the unlocalized name is “grad” and the identifier is EPSG:9105.
+ *
+ * @see #DEGREE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> GRAD;
+
+ /**
+ * Unit of measurement defined as π/180 radians (1°).
+ * There is 360° in a circle.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #RADIAN},
+ * the unlocalized name is “degree” and the identifier is EPSG:9102.
+ *
+ * @see #ARC_MINUTE
+ * @see #ARC_SECOND
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> DEGREE;
+
+ /**
+ * Unit of measurement defined as 1/60 degree (1′).
+ * The distance of one arc-minute of latitude on Earth is approximatively 1852 metres
+ * (one {@linkplain #NAUTICAL_MILE nautical mile}).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #RADIAN},
+ * the unlocalized name is “arc-minute” and the identifier is EPSG:9103.
+ *
+ * @see #DEGREE
+ * @see #ARC_SECOND
+ * @see #NAUTICAL_MILE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> ARC_MINUTE;
+
+ /**
+ * Unit of measurement defined as 1/(60×60) degree (1″).
+ * The distance of one arc-second of latitude on Earth is approximatively 31 metres.
+ * This unit of measurement is used for rotation terms in
+ * {@linkplain org.apache.sis.referencing.datum.BursaWolfParameters Bursa-Wolf parameters}.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #RADIAN},
+ * the unlocalized name is “arc-second” and the identifier is EPSG:9104.
+ *
+ * @see #DEGREE
+ * @see #ARC_MINUTE
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> ARC_SECOND;
+
+ /**
+ * Unit of measurement defined as 10<sup>-6</sup> radians (1 µrad).
+ * The distance of one microradian of latitude on Earth is approximatively 2 millimetres.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #RADIAN},
+ * the unlocalized name is “microradian” and the identifier is EPSG:9109.
+ *
+ * @see #ARC_MINUTE
+ * @see #ARC_SECOND
+ *
+ * @since 0.8
+ */
+ public static final Unit<Angle> MICRORADIAN;
+
+ /**
+ * Unit of measurement defined as 10<sup>-3</sup> seconds (1 ms).
+ * This unit is useful for inter-operability with various methods from the standard Java library.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “millisecond”.
+ *
+ * @see java.util.concurrent.TimeUnit#MILLISECONDS
+ */
+ public static final Unit<Time> MILLISECOND;
+
+ /**
+ * The SI base unit for durations (s).
+ * The unlocalized name is “second” and the identifier is EPSG:1040.
+ * This is the base of all other {@linkplain #isTemporal(Unit) temporal} units:
+ *
+ * {@link #MILLISECOND} (ms),
+ * {@link #MINUTE} (min),
+ * {@link #HOUR} (h),
+ * {@link #DAY} (d),
+ * {@link #WEEK} (wk) and
+ * {@link #TROPICAL_YEAR} (a)
+ * among others.
+ *
+ * @see #HERTZ
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> SECOND;
+
+ /**
+ * Unit of measurement defined as 60 seconds (1 min).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “minute”.
+ *
+ * @see #SECOND
+ * @see #HOUR
+ * @see #DAY
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> MINUTE;
+
+ /**
+ * Unit of measurement defined as 60×60 seconds (1 h).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “hour”.
+ *
+ * @see #SECOND
+ * @see #MINUTE
+ * @see #DAY
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> HOUR;
+
+ /**
+ * Unit of measurement defined as 24×60×60 seconds (1 d).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “day”.
+ *
+ * @see #HOUR
+ * @see #WEEK
+ * @see #TROPICAL_YEAR
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> DAY;
+
+ /**
+ * Unit of measurement defined as 7 days (1 wk).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND}
+ * and the unlocalized name is “week”.
+ *
+ * @see #DAY
+ * @see #TROPICAL_YEAR
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> WEEK;
+
+ /**
+ * Unit of measurement approximatively equals to 365.24219 days (1 a).
+ * This is defined by the International Union of Geological Sciences (IUGS) as exactly 31556925.445 seconds,
+ * taken as the length of the tropical year in the the year 2000.
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #SECOND},
+ * the unlocalized name is “year” and the identifier is EPSG:1029.
+ *
+ * @see #DAY
+ * @see #WEEK
+ *
+ * @since 0.8
+ */
+ public static final Unit<Time> TROPICAL_YEAR;
+
+ /**
+ * The SI derived unit for frequency (Hz).
+ * One hertz is equal to one cycle per second.
+ * The unlocalized name is “hertz”.
+ *
+ * @since 0.8
+ *
+ * @see #SECOND
+ */
+ public static final Unit<Frequency> HERTZ;
+
+ /**
+ * The SI derived unit for pressure (Pa).
+ * One pascal is equal to 1 N/m².
+ * Pressures are often used in {@linkplain org.apache.sis.referencing.crs.DefaultParametricCRS parametric CRS}
+ * for height measurements on a vertical axis.
+ * The unlocalized name is “pascal”.
+ *
+ * @see #NEWTON
+ * @see #SQUARE_METRE
+ * @see #HECTOPASCAL
+ *
+ * @since 0.8
+ */
+ public static final Unit<Pressure> PASCAL;
+
+ /**
+ * Unit of measurement defined as 100 pascals (1 hPa).
+ * The hectopascal is the international unit for measuring atmospheric or barometric pressure.
+ * One hectopascal is exactly equal to one millibar.
+ * The unlocalized name is “hectopascal”.
+ *
+ * @see #PASCAL
+ *
+ * @since 0.8
+ */
+ public static final Unit<Pressure> HECTOPASCAL;
+
+ /**
+ * Unit of measurement defined as 10,000 square metres (1 ha).
+ * One hectare is exactly equals to one hectometre (1 hm²).
+ * While not an SI unit, the hectare is often used in the measurement of land.
+ * The unlocalized name is “hectare”.
+ *
+ * @since 0.8
+ *
+ * @see #SQUARE_METRE
+ */
+ public static final Unit<Area> HECTARE;
+
+ /**
+ * The SI derived unit for area (m²).
+ * The unlocalized name is “square metre”.
+ *
+ * @since 0.8
+ *
+ * @see #HECTARE
+ * @see #METRE
+ * @see #CUBIC_METRE
+ */
+ public static final Unit<Area> SQUARE_METRE;
+
+ /**
+ * The SI derived unit for volume (m³).
+ * The unlocalized name is “cubic metre”.
+ *
+ * @since 0.8
+ *
+ * @see #METRE
+ * @see #SQUARE_METRE
+ */
+ public static final Unit<Volume> CUBIC_METRE;
+
+ /**
+ * The SI derived unit for speed (m/s).
+ * The unlocalized name is “metres per second” and the identifier is EPSG:1026.
+ *
+ * @see #METRE
+ * @see #SECOND
+ * @see #KILOMETRES_PER_HOUR
+ *
+ * @since 0.8
+ */
+ public static final Unit<Speed> METRES_PER_SECOND;
+
+ /**
+ * Unit of measurement defined as 60/1000 metres per second (1 km/h).
+ * The unlocalized name is “kilometres per hour”.
+ *
+ * @see #KILOMETRE
+ * @see #HOUR
+ * @see #METRES_PER_SECOND
+ *
+ * @since 0.8
+ */
+ public static final Unit<Speed> KILOMETRES_PER_HOUR;
/**
- * Unit for milliseconds. Useful for conversion from and to {@link java.util.Date} objects.
+ * The SI base unit for mass (kg).
+ * The unlocalized name is “kilogram”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<Mass> KILOGRAM;
+
+ /**
+ * The SI base unit for electric current (A).
+ * The unlocalized name is “ampere”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<ElectricCurrent> AMPERE;
+
+ /**
+ * The SI derived unit for force (N).
+ * One newton is the force required to give a mass of 1 kg an acceleration of 1 m/s².
+ * The unlocalized name is “newton”.
+ *
+ * @since 0.8
+ *
+ * @see #KILOGRAM
+ * @see #METRES_PER_SECOND
+ */
+ public static final Unit<Force> NEWTON;
+
+ /**
+ * The SI derived unit for energy (J).
+ * The unlocalized name is “joule”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<Energy> JOULE;
+
+ /**
+ * The SI derived unit for power (W).
+ * One watt is equal to one joule per second.
+ * The unlocalized name is “watt”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<Power> WATT;
+
+ /**
+ * The SI base unit for thermodynamic temperature (K).
+ * The unlocalized name is “kelvin”.
+ *
+ * @see #CELSIUS
+ *
+ * @since 0.8
+ */
+ public static final Unit<Temperature> KELVIN;
+
+ /**
+ * Unit of measurement defined as the temperature in Kelvin minus 273.15.
+ * The symbol is °C and the unlocalized name is “Celsius”.
+ * Note that this is the only SI unit with an upper-case letter in its name.
+ *
+ * @see #KELVIN
+ *
+ * @since 0.8
+ */
+ public static final Unit<Temperature> CELSIUS;
+
+ /**
+ * The SI base unit for luminous intensity (cd).
+ * The unlocalized name is “candela”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<LuminousIntensity> CANDELA;
+
+ /**
+ * The SI base unit for amount of substance (mol).
+ * The unlocalized name is “mole”.
+ *
+ * @since 0.8
+ */
+ public static final Unit<AmountOfSubstance> MOLE;
+
+ /**
+ * The base dimensionless unit for scale measurements.
+ * The unlocalized name is “unity” and the identifier is EPSG:9201.
+ * This is the base of all other {@linkplain #isScale(Unit) scale} units:
+ *
+ * {@link #PERCENT} (%),
+ * {@link #PPM} (ppm) and
+ * {@link #PIXEL} (px)
+ * among others.
+ *
+ * @since 0.8
*/
- public static final Unit<Duration> MILLISECOND = SI.MetricPrefix.MILLI(SI.SECOND);
+ public static final Unit<Dimensionless> UNITY;
/**
- * The EPSG:1029 definition of year.
+ * Dimensionless unit for percentages (%).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #UNITY}
+ * and the unlocalized name is “percentage”.
+ *
+ * @see #UNITY
+ * @see #PPM
+ *
+ * @since 0.8
*/
- private static final Unit<Duration> YEAR = SI.SECOND.divide(31556925.445);
+ public static final Unit<Dimensionless> PERCENT;
/**
- * Parts per million.
+ * Dimensionless unit for parts per million (ppm).
+ * The {@linkplain ConventionalUnit#getSystemUnit() system unit} is {@link #UNITY},
+ * the unlocalized name is “parts per million” and the identifier is EPSG:9202.
*
- * <p>This unit does not have an easily readable symbol because of the
- * <a href="http://kenai.com/jira/browse/JSR_275-41">JSR-275 bug</a>.</p>
+ * @see #UNITY
+ * @see #PERCENT
*/
- public static final Unit<Dimensionless> PPM = Unit.ONE.times(1E-6);//.alternate("ppm");
+ public static final Unit<Dimensionless> PPM;
/**
* Salinity measured using PSS-78. While this is a dimensionless measurement, the {@code "psu"} symbol
* is sometime added to PSS-78 measurement. However this is officially discouraged.
+ *
+ * <p>If we make this field public in a future SIS version, we should consider introducing a
+ * {@code Salinity} quantity type.</p>
*/
- static final Unit<Dimensionless> PSU = Unit.ONE.alternate("psu");
+ static final Unit<Dimensionless> PSU;
/**
* Sigma-level, used in oceanography. This is a way to measure a depth as a fraction of the sea floor depth.
+ *
+ * <p>If we make this field public in a future SIS version, we should consider introducing a new quantity type.
+ * The type to introduce has not yet been determined.</p>
*/
- static final Unit<Dimensionless> SIGMA = Unit.ONE.alternate("sigma");
+ static final Unit<Dimensionless> SIGMA;
+
+ /**
+ * Dimensionless unit for pixels (px).
+ * The unlocalized name is “pixel”.
+ *
+ * @see #POINT
+ */
+ public static final Unit<Dimensionless> PIXEL;
+
+ /**
+ * Sets to {@code true} by the static initializer after the initialization has been completed.
+ * This is a safety against unexpected changes in the {@link UnitRegistry#HARD_CODED} map.
+ *
+ * <p>We use here a "lazy final initialization" pattern. We rely on the fact that this field is
+ * initialized to {@code true} only at the end of the following static initializer. All methods
+ * invoked in the static initializer will see the default value, which is {@code false}, until
+ * the initializer fully completed. While apparently dangerous, this behavior is actually documented
+ * in <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1">section 12.4.1
+ * of Java language specification</a>:</p>
+ *
+ * <blockquote>The fact that initialization code is unrestricted allows examples to be constructed where
+ * the value of a class variable can be observed when it still has its initial default value, before its
+ * initializing expression is evaluated, but such examples are rare in practice. (…snip…) The full power
+ * of the Java programming language is available in these initializers; programmers must exercise some care.
+ * This power places an extra burden on code generators, but this burden would arise in any case because
+ * the Java programming language is concurrent.</blockquote>
+ */
+ static final boolean initialized;
+ static {
+ final UnitDimension length = new UnitDimension('L');
+ final UnitDimension mass = new UnitDimension('M');
+ final UnitDimension time = new UnitDimension('T');
+ final UnitDimension electric = new UnitDimension('I');
+ final UnitDimension temperature = new UnitDimension('Θ');
+ final UnitDimension amount = new UnitDimension('N');
+ final UnitDimension luminous = new UnitDimension('J');
+ final UnitDimension area = length.pow(2);
+ final UnitDimension speed = length.divide(time);
+ final UnitDimension force = mass.multiply(speed).divide(time);
+ final UnitDimension energy = force.multiply(length);
+ final UnitDimension pressure = force.divide(area);
+ final UnitDimension dimensionless = UnitDimension.NONE;
+ /*
+ * Base, derived or alternate units that we need to reuse more than once in this static initializer.
+ */
+ final SystemUnit<Length> m = add(Length.class, length, "m", UnitRegistry.SI, Constants.EPSG_METRE);
+ final SystemUnit<Area> m2 = add(Area.class, area, "m²", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Time> s = add(Time.class, time, "s", UnitRegistry.SI, (short) 1040);
+ final SystemUnit<Temperature> K = add(Temperature.class, temperature, "K", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Speed> mps = add(Speed.class, speed, "m∕s", UnitRegistry.SI, (short) 1026);
+ final SystemUnit<Pressure> Pa = add(Pressure.class, pressure, "Pa", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Angle> rad = add(Angle.class, dimensionless, "rad", UnitRegistry.SI, (short) 9101);
+ final SystemUnit<Dimensionless> one = add(Dimensionless.class, dimensionless, "", UnitRegistry.SI, (short) 9201);
+ /*
+ * All SI prefix to be used below.
+ */
+ final LinearConverter nano = LinearConverter.forPrefix('n');
+ final LinearConverter micro = LinearConverter.forPrefix('µ');
+ final LinearConverter milli = LinearConverter.forPrefix('m');
+ final LinearConverter centi = LinearConverter.forPrefix('c');
+ final LinearConverter hecto = LinearConverter.forPrefix('h');
+ final LinearConverter kilo = LinearConverter.forPrefix('k');
+ /*
+ * All Unit<Angle>
+ * 20 is the greatest common denominator between 180 and 200. The intend is to have arguments as small
+ * as possible in the call to the scale(double, double) method, while keeping the right side integer.
+ * Staying closer to zero during conversions helo to reduce rounding errors.
+ */
+ rad.related(4);
+ RADIAN = rad;
+ GRAD = add(rad, LinearConverter.scale(Math.PI / 20, 200 / 20), "grad", UnitRegistry.OTHER, (short) 9105);
+ DEGREE = add(rad, LinearConverter.scale(Math.PI / 20, 180 / 20), "°", UnitRegistry.ACCEPTED, Constants.EPSG_PARAM_DEGREES);
+ ARC_MINUTE = add(rad, LinearConverter.scale(Math.PI / 20, 180*60 / 20), "′", UnitRegistry.ACCEPTED, (short) 9103);
+ ARC_SECOND = add(rad, LinearConverter.scale(Math.PI / 20, 180*60*60 / 20), "″", UnitRegistry.ACCEPTED, (short) 9104);
+ MICRORADIAN = add(rad, micro, "µrad", UnitRegistry.SI, (short) 9109);
+ /*
+ * All Unit<Length>
+ */
+ m.related(6);
+ METRE = m;
+ NANOMETRE = add(m, nano, "nm", UnitRegistry.SI, (short) 0);
+ MILLIMETRE = add(m, milli, "mm", UnitRegistry.SI, (short) 1025);
+ CENTIMETRE = add(m, centi, "cm", UnitRegistry.SI, (short) 1033);
+ KILOMETRE = add(m, kilo, "km", UnitRegistry.SI, (short) 9036);
+ NAUTICAL_MILE = add(m, LinearConverter.scale( 1852, 1), "M", UnitRegistry.OTHER, (short) 9030);
+ STATUTE_MILE = add(m, LinearConverter.scale(1609344, 100), "mi", UnitRegistry.IMPERIAL, (short) 9093);
+ US_SURVEY_FOOT = add(m, LinearConverter.scale( 1200, 3937), "ft_US", UnitRegistry.OTHER, (short) 9003);
+ FOOT = add(m, LinearConverter.scale( 3048, 10000), "ft", UnitRegistry.IMPERIAL, (short) 9002);
+ INCH = add(m, LinearConverter.scale( 254, 10000), "in", UnitRegistry.IMPERIAL, (short) 0);
+ POINT = add(m, LinearConverter.scale( 996264, 72000000), "pt", UnitRegistry.OTHER, (short) 0);
+ /*
+ * All Unit<Time>
+ */
+ s.related(5);
+ SECOND = s;
+ MILLISECOND = add(s, milli, "ms", UnitRegistry.SI, (short) 0);
+ MINUTE = add(s, LinearConverter.scale( 60, 1), "min", UnitRegistry.ACCEPTED, (short) 0);
+ HOUR = add(s, LinearConverter.scale( 60*60, 1), "h", UnitRegistry.ACCEPTED, (short) 0);
+ DAY = add(s, LinearConverter.scale( 24*60*60, 1), "d", UnitRegistry.ACCEPTED, (short) 0);
+ WEEK = add(s, LinearConverter.scale( 7*24*60*60, 1), "wk", UnitRegistry.OTHER, (short) 0);
+ TROPICAL_YEAR = add(s, LinearConverter.scale(31556925445.0, 1000), "a", UnitRegistry.OTHER, (short) 1029);
+ /*
+ * Other units.
+ */
+ KELVIN = K;
+ PASCAL = Pa;
+ SQUARE_METRE = m2;
+ METRES_PER_SECOND = mps;
+ HERTZ = add(Frequency.class, time.pow(-1), "Hz", UnitRegistry.SI, (short) 0);
+ KILOGRAM = add(Mass.class, mass, "kg", UnitRegistry.SI, (short) 0);
+ CUBIC_METRE = add(Volume.class, length.pow(3), "m³", UnitRegistry.SI, (short) 0);
+ AMPERE = add(ElectricCurrent.class, electric, "A", UnitRegistry.SI, (short) 0);
+ NEWTON = add(Force.class, force, "N", UnitRegistry.SI, (short) 0);
+ JOULE = add(Energy.class, energy, "J", UnitRegistry.SI, (short) 0);
+ WATT = add(Power.class, energy.divide(time), "W", UnitRegistry.SI, (short) 0);
+ CANDELA = add(LuminousIntensity.class, luminous, "cd", UnitRegistry.SI, (short) 0);
+ MOLE = add(AmountOfSubstance.class, amount, "mol", UnitRegistry.SI, (short) 0);
+ HECTOPASCAL = add(Pa, hecto, "hPa", UnitRegistry.SI, (short) 0);
+ HECTARE = add(m2, LinearConverter.scale(10000, 1), "ha", UnitRegistry.ACCEPTED, (short) 0);
+ KILOMETRES_PER_HOUR = add(mps, LinearConverter.scale(6, 100), "km∕h", UnitRegistry.ACCEPTED, (short) 0);
+ CELSIUS = add(K, LinearConverter.offset(27315, 100), "°C", UnitRegistry.SI, (short) 0);
+ /*
+ * All Unit<Dimensionless>
+ */
+ PERCENT = add(one, centi, "%", UnitRegistry.OTHER, (short) 0);
+ PPM = add(one, micro, "ppm", UnitRegistry.OTHER, (short) 9202);
+ PSU = add(Dimensionless.class, dimensionless, "psu", UnitRegistry.OTHER, (short) 0);
+ SIGMA = add(Dimensionless.class, dimensionless, "sigma", UnitRegistry.OTHER, (short) 0);
+ PIXEL = add(Dimensionless.class, dimensionless, "px", UnitRegistry.OTHER, (short) 0);
+ UNITY = UnitRegistry.init(one); // Must be last in order to take precedence over all other units associated to UnitDimension.NONE.
+
+ UnitRegistry.alias(UNITY, Short.valueOf((short) 9203));
+ UnitRegistry.alias(DEGREE, Short.valueOf(Constants.EPSG_AXIS_DEGREES));
+ UnitRegistry.alias(ARC_MINUTE, "'");
+ UnitRegistry.alias(ARC_SECOND, "\"");
+ UnitRegistry.alias(KELVIN, "K"); // Ordinary "K" letter (not the dedicated Unicode character).
+ UnitRegistry.alias(CELSIUS, "℃");
+ UnitRegistry.alias(CELSIUS, "Cel");
+ UnitRegistry.alias(GRAD, "gon");
+ UnitRegistry.alias(HECTARE, "hm²");
+ UnitRegistry.alias(UNITY, "1");
+
+ initialized = true;
+ }
+
+ /**
+ * Invoked by {@code Units} static class initializer for registering SI base and derived units.
+ * This method shall be invoked in a single thread by the {@code Units} class initializer only.
+ */
+ private static <Q extends Quantity<Q>> SystemUnit<Q> add(Class<Q> quantity, UnitDimension dimension, String symbol, byte scope, short epsg) {
+ return UnitRegistry.init(new SystemUnit<>(quantity, dimension, symbol, scope, epsg));
+ }
+
+ /**
+ * Invoked by {@code Units} static class initializer for registering SI conventional units.
+ * This method shall be invoked in a single thread by the {@code Units} class initializer only.
+ */
+ private static <Q extends Quantity<Q>> ConventionalUnit<Q> add(SystemUnit<Q> target, UnitConverter toTarget, String symbol, byte scope, short epsg) {
+ final ConventionalUnit<Q> unit = UnitRegistry.init(new ConventionalUnit<>(target, toTarget, symbol, scope, epsg));
+ final ConventionalUnit<Q>[] related = target.related;
+ if (related != null && unit.scope != UnitRegistry.SI) {
+ // Search first empty slot. This algorithm is inefficient, but the length of those arrays is small (<= 6).
+ int i = 0;
+ while (related[i] != null) i++;
+ related[i] = unit;
+ }
+ return unit;
+ }
+
+ /**
+ * Returns the system unit for the given dimension, or {@code null} if none.
+ * Note that this method can not distinguish the different kinds of dimensionless units.
+ * If the symbol or the quantity type is known, use {@link #get(String)} or {@link #get(Class)} instead.
+ *
+ * <p><b>Implementation note:</b> this method must be defined in this {@code Units} class
+ * in order to force a class initialization before use.</p>
+ */
+ static SystemUnit<?> get(final Dimension dim) {
+ return (SystemUnit<?>) UnitRegistry.get(dim);
+ }
+
+ /**
+ * Returns the system unit for the given quantity, or {@code null} if none.
+ *
+ * <p><b>Implementation note:</b> this method must be defined in this {@code Units} class
+ * in order to force a class initialization before use.</p>
+ */
+ @SuppressWarnings("unchecked")
+ static <Q extends Quantity<Q>> SystemUnit<Q> get(final Class<Q> type) {
+ return (SystemUnit<Q>) UnitRegistry.get(type);
+ }
+
+ /**
+ * Returns the system unit for the given symbol, or {@code null} if none.
+ * This method does not perform any parsing (prefix, exponents, <i>etc</i>).
+ * It is only for getting one of the pre-defined constants, for example after deserialization.
+ *
+ * <p><b>Implementation note:</b> this method must be defined in this {@code Units} class
+ * in order to force a class initialization before use.</p>
+ */
+ @SuppressWarnings("unchecked")
+ static Unit<?> get(final String symbol) {
+ return (Unit<?>) UnitRegistry.get(symbol);
+ }
+
+ /**
+ * Do not allows instantiation of this class.
+ */
+ private Units() {
+ }
/**
* Returns {@code true} if the given unit is a linear unit.
- * Linear units are convertible to {@link NonSI#DEGREE_ANGLE}.
+ * Linear units are convertible to {@link #DEGREE}.
*
* <p>Angular units are dimensionless, which may be a cause of confusion with other
- * dimensionless units like {@link Unit#ONE} or {@link #PPM}. This method take care
+ * dimensionless units like {@link #UNITY} or {@link #PPM}. This method take care
* of differentiating angular units from other dimensionless units.</p>
*
- * @param unit The unit to check (may be {@code null}).
+ * @param unit the unit to check (may be {@code null}).
* @return {@code true} if the given unit is non-null and angular.
*
* @see #ensureAngular(Unit)
*/
public static boolean isAngular(final Unit<?> unit) {
- return (unit != null) && unit.toSI().equals(SI.RADIAN);
+ return (unit != null) && unit.getSystemUnit().equals(RADIAN);
}
/**
* Returns {@code true} if the given unit is a linear unit.
- * Linear units are convertible to {@link SI#METRE}.
+ * Linear units are convertible to {@link #METRE}.
*
- * @param unit The unit to check (may be {@code null}).
+ * @param unit the unit to check (may be {@code null}).
* @return {@code true} if the given unit is non-null and linear.
*
+ * @see #METRE
* @see #ensureLinear(Unit)
*/
public static boolean isLinear(final Unit<?> unit) {
- return (unit != null) && unit.toSI().equals(SI.METRE);
+ return (unit != null) && unit.getSystemUnit().equals(METRE);
}
/**
* Returns {@code true} if the given unit is a pressure unit.
- * Pressure units are convertible to {@link SI#PASCAL}.
+ * Pressure units are convertible to {@link #PASCAL}.
* Those units are sometime used instead of linear units for altitude measurements.
*
- * @param unit The unit to check (may be {@code null}).
+ * @param unit the unit to check (may be {@code null}).
* @return {@code true} if the given unit is non-null and a pressure unit.
*/
public static boolean isPressure(final Unit<?> unit) {
- return (unit != null) && unit.toSI().equals(SI.PASCAL);
+ return (unit != null) && unit.getSystemUnit().equals(PASCAL);
}
/**
* Returns {@code true} if the given unit is a temporal unit.
- * Temporal units are convertible to {@link SI#SECOND}.
+ * Temporal units are convertible to {@link #SECOND}.
*
- * @param unit The unit to check (may be {@code null}).
+ * @param unit the unit to check (may be {@code null}).
* @return {@code true} if the given unit is non-null and temporal.
*
* @see #ensureTemporal(Unit)
*/
public static boolean isTemporal(final Unit<?> unit) {
- return (unit != null) && unit.toSI().equals(SI.SECOND);
+ return (unit != null) && unit.getSystemUnit().equals(SECOND);
}
/**
* Returns {@code true} if the given unit is a dimensionless scale unit.
- * This include {@link Unit#ONE} and {@link #PPM}.
+ * This include {@link #UNITY} and {@link #PPM}.
*
- * @param unit The unit to check (may be {@code null}).
+ * @param unit the unit to check (may be {@code null}).
* @return {@code true} if the given unit is non-null and a dimensionless scale.
*
+ * @see #UNITY
* @see #ensureScale(Unit)
*/
public static boolean isScale(final Unit<?> unit) {
- return (unit != null) && unit.toSI().equals(Unit.ONE);
+ return (unit != null) && unit.getSystemUnit().equals(UNITY);
}
/**
* Makes sure that the specified unit is either null or an angular unit.
* This method is used for argument checks in constructors and setter methods.
*
- * @param unit The unit to check, or {@code null} if none.
- * @return The given {@code unit} argument, which may be null.
+ * @param unit the unit to check, or {@code null} if none.
+ * @return the given {@code unit} argument, which may be null.
* @throws IllegalArgumentException if {@code unit} is non-null and not an angular unit.
*
* @see #isAngular(Unit)
@@ -183,8 +945,8 @@ public final class Units extends Static
* Makes sure that the specified unit is either null or a linear unit.
* This method is used for argument checks in constructors and setter methods.
*
- * @param unit The unit to check, or {@code null} if none.
- * @return The given {@code unit} argument, which may be null.
+ * @param unit the unit to check, or {@code null} if none.
+ * @return the given {@code unit} argument, which may be null.
* @throws IllegalArgumentException if {@code unit} is non-null and not a linear unit.
*
* @see #isLinear(Unit)
@@ -201,26 +963,26 @@ public final class Units extends Static
* Makes sure that the specified unit is either null or a temporal unit.
* This method is used for argument checks in constructors and setter methods.
*
- * @param unit The unit to check, or {@code null} if none.
- * @return The given {@code unit} argument, which may be null.
+ * @param unit the unit to check, or {@code null} if none.
+ * @return the given {@code unit} argument, which may be null.
* @throws IllegalArgumentException if {@code unit} is non-null and not a temporal unit.
*
* @see #isTemporal(Unit)
*/
@SuppressWarnings("unchecked")
- public static Unit<Duration> ensureTemporal(final Unit<?> unit) throws IllegalArgumentException {
+ public static Unit<Time> ensureTemporal(final Unit<?> unit) throws IllegalArgumentException {
if (unit != null && !isTemporal(unit)) {
throw new IllegalArgumentException(Errors.format(Errors.Keys.NonTemporalUnit_1, unit));
}
- return (Unit<Duration>) unit;
+ return (Unit<Time>) unit;
}
/**
* Makes sure that the specified unit is either null or a scale unit.
* This method is used for argument checks in constructors and setter methods.
*
- * @param unit The unit to check, or {@code null} if none.
- * @return The given {@code unit} argument, which may be null.
+ * @param unit the unit to check, or {@code null} if none.
+ * @return the given {@code unit} argument, which may be null.
* @throws IllegalArgumentException if {@code unit} is non-null and not a scale unit.
*
* @see #isScale(Unit)
@@ -234,105 +996,162 @@ public final class Units extends Static
}
/**
- * Multiplies the given unit by the given factor. For example multiplying {@link SI#METRE}
- * by 1000 gives {@link SI#KILOMETRE}. Invoking this method is equivalent to invoking
- * {@link Unit#times(double)} except for the following:
+ * Multiplies the given unit by the given ratio. For example multiplying {@link #CENTIMETRE} by 254/100 gives
+ * {@link #INCH}. Invoking this method is equivalent to invoking <code>{@linkplain Unit#multiply(double)
+ * Unit.multiply}(numerator / denominator)</code> except that the use of a ration of integer values help
+ * Apache SIS to improve accuracy when more than one arithmetic operation are chained.
+ *
+ * @param <Q> the quantity measured by the unit.
+ * @param unit the unit to multiply.
+ * @param numerator the numerator of the multiplication factor.
+ * @param denominator the denominator of the multiplication factor.
+ * @return the unit multiplied by the given factor.
+ *
+ * @since 0.8
+ */
+ public static <Q extends Quantity<Q>> Unit<Q> multiply(Unit<Q> unit, double numerator, double denominator) {
+ return unit.transform(LinearConverter.scale(numerator, denominator));
+ }
+
+ /**
+ * Multiplies the given unit by the given factor. For example multiplying {@link #METRE}
+ * by 1000 gives {@link #KILOMETRE}. Invoking this method is equivalent to invoking
+ * {@link Unit#multiply(double)} except for the following:
*
* <ul>
* <li>A small tolerance factor is applied for a few factors commonly used in GIS.
- * For example {@code multiply(SI.RADIANS, 0.0174532925199...)} will return
- * {@link NonSI#DEGREE_ANGLE} even if the given numerical value is slightly
- * different than {@linkplain Math#PI pi}/180. The tolerance factor and the
- * set of units handled especially may change in future SIS versions.</li>
+ * For example {@code multiply(RADIANS, 0.0174532925199...)} will return {@link #DEGREE}
+ * even if the given numerical value is slightly different than {@linkplain Math#PI π}/180.
+ * The tolerance factor and the set of units handled especially may change in future SIS versions.</li>
* <li>This method tries to returns unique instances for some common units.</li>
* </ul>
*
- * @param <Q> The quantity measured by the unit.
- * @param unit The unit to multiply.
- * @param factor The multiplication factor.
- * @return The unit multiplied by the given factor.
+ * @param <Q> the quantity measured by the unit.
+ * @param unit the unit to multiply.
+ * @param factor the multiplication factor.
+ * @return the unit multiplied by the given factor.
+ *
+ * @deprecated Replaced by Apache SIS implementation of {@link Unit#multiply(double)}.
*/
+ @Deprecated
@Workaround(library="JSR-275", version="0.9.3")
@SuppressWarnings("unchecked")
- public static <Q extends Quantity> Unit<Q> multiply(Unit<Q> unit, final double factor) {
- if (SI.RADIAN.equals(unit)) {
+ public static <Q extends Quantity<Q>> Unit<Q> multiply(Unit<Q> unit, final double factor) {
+ if (RADIAN.equals(unit)) {
if (abs(factor - (PI / 180)) <= (EPS * PI/180)) {
- return (Unit<Q>) NonSI.DEGREE_ANGLE;
+ return (Unit<Q>) DEGREE;
}
if (abs(factor - (PI / 200)) <= (EPS * PI/200)) {
- return (Unit<Q>) NonSI.GRADE;
+ return (Unit<Q>) GRAD;
}
- } else if (SI.METRE.equals(unit)) {
+ } else if (METRE.equals(unit)) {
if (abs(factor - 0.3048) <= (EPS * 0.3048)) {
- return (Unit<Q>) NonSI.FOOT;
+ return (Unit<Q>) FOOT;
}
if (abs(factor - (1200.0/3937)) <= (EPS * (1200.0/3937))) {
- return (Unit<Q>) NonSI.FOOT_SURVEY_US;
+ return (Unit<Q>) US_SURVEY_FOOT;
}
}
if (abs(factor - 1) > EPS) {
- final long fl = (long) factor;
- if (fl == factor) {
- /*
- * Invoke the Unit.times(long) overloaded method, not Unit.scale(double),
- * because as of JSR-275 0.9.3 the method with the long argument seems to
- * do a better work of detecting when the result is an existing unit.
- */
- unit = unit.times(fl);
- } else {
- unit = unit.times(factor);
- }
+ unit = unit.multiply(factor);
}
- return UnitsMap.canonicalize(unit);
+ return unit;
}
/**
* Returns the factor by which to multiply the standard unit in order to get the given unit.
- * The "standard" unit is usually the SI unit on which the given unit is based.
+ * The "standard" unit is usually the SI unit on which the given unit is based, as given by
+ * {@link Unit#getSystemUnit()}.
*
- * <p><b>Example:</b> If the given unit is <var>kilometre</var>, then this method returns 1000
- * since a measurement in kilometres must be multiplied by 1000 in order to give the equivalent
- * measurement in the "standard" units (here <var>metres</var>).</p>
- *
- * @param <Q> The quantity measured by the unit.
- * @param unit The unit for which we want the multiplication factor to standard unit.
- * @return The factor by which to multiply a measurement in the given unit in order to
- * get an equivalent measurement in the standard unit.
- */
- @Workaround(library="JSR-275", version="0.9.3")
- public static <Q extends Quantity> double toStandardUnit(final Unit<Q> unit) {
- return derivative(unit.getConverterTo(unit.toSI()), 0);
+ * <div class="note"><b>Example:</b>
+ * if the given unit is {@link #KILOMETRE}, then this method returns 1000 since a measurement in kilometres
+ * must be multiplied by 1000 in order to give the equivalent measurement in the "standard" units
+ * (here {@link #METRE}).</div>
+ *
+ * If the given unit is {@code null} or if the conversion to the "standard" unit can not be expressed
+ * by a single multiplication factor, then this method returns {@link Double#NaN}.
+ *
+ * @param <Q> the quantity measured by the unit, or {@code null}.
+ * @param unit the unit for which we want the multiplication factor to standard unit, or {@code null}.
+ * @return the factor by which to multiply a measurement in the given unit in order to get an equivalent
+ * measurement in the standard unit, or NaN if the conversion can not be expressed by a scale factor.
+ */
+ public static <Q extends Quantity<Q>> double toStandardUnit(final Unit<Q> unit) {
+ if (unit != null) {
+ final UnitConverter converter = unit.getConverterTo(unit.getSystemUnit());
+ if (converter.isLinear() && converter.convert(0) == 0) {
+ // Above check for converter(0) is a paranoiac check since
+ // JSR-363 said that a "linear" converter has no offset.
+ return converter.convert(1);
+ }
+ }
+ return Double.NaN;
}
/**
- * Returns an estimation of the derivative of the given converter at the given value.
- * This method is a workaround for a method which existed in previous JSR-275 API but
- * have been removed in more recent releases. This method will be deprecated if the
- * removed API is reinserted in future JSR-275 release.
+ * Returns the coefficients of the given converter expressed as a polynomial equation.
+ * This method returns the first of the following choices that apply:
*
- * <p>Current implementation computes the derivative as below:</p>
+ * <ul>
+ * <li>If the given converter {@linkplain UnitConverter#isIdentity() is identity}, returns an empty array.</li>
+ * <li>If the given converter shifts the values without scaling them (for example the conversion from Kelvin to
+ * Celsius degrees), returns an array of length 1 containing only the offset.</li>
+ * <li>If the given converter scales the values (optionally in addition to shifting them), returns an array of
+ * length 2 containing the offset and scale factor, in that order.</li>
+ * </ul>
*
- * {@preformat java
- * return converter.convert(value + 1) - converter.convert(value);
- * }
+ * This method returns {@code null} if it can not get the polynomial equation coefficients from the given converter.
*
- * The above is exact for {@linkplain javax.measure.converter.LinearConverter linear converters},
- * which is the case of the vast majority of unit converters in use. It may not be exact for a
- * few unusual converter like the one from sexagesimal degrees to decimal degrees for example.
+ * @param converter the converter from which to get the coefficients of the polynomial equation, or {@code null}.
+ * @return the polynomial equation coefficients (may be any length, including zero), or {@code null} if the given
+ * converter is {@code null} or if this method can not get the coefficients.
*
- * @param converter The converter for which we want the derivative at a given point.
- * @param value The point at which to compute the derivative.
- * @return The derivative at the given point.
+ * @since 0.8
+ */
+ @SuppressWarnings("fallthrough")
+ public static Number[] coefficients(final UnitConverter converter) {
+ if (converter != null) {
+ if (converter instanceof AbstractConverter) {
+ return ((AbstractConverter) converter).coefficients();
+ }
+ if (converter.isIdentity()) {
+ return new Number[0];
+ }
+ if (converter.isLinear()) {
+ final double offset = converter.convert(0); // Should be zero as per JSR-363 specification, but we are paranoiac.
+ final double scale = converter.convert(1) - offset;
+ final Number[] c = new Number[(scale != 1) ? 2 : (offset != 0) ? 1 : 0];
+ switch (c.length) {
+ case 2: c[1] = scale; // Fall through
+ case 1: c[0] = offset;
+ case 0: break;
+ }
+ return c;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the derivative of the given converter at the given value,
+ * or {@code NaN} if this method can not compute it.
+ *
+ * @param converter the converter for which we want the derivative at a given point, or {@code null}.
+ * @param value the point at which to compute the derivative.
+ * @return the derivative at the given point, or {@code NaN} if unknown.
+ *
+ * @see org.apache.sis.referencing.operation.transform.AbstractMathTransform#derivative(DirectPosition)
*/
- @Workaround(library="JSR-275", version="0.9.3")
public static double derivative(final UnitConverter converter, final double value) {
- return converter.convert(value + 1) - converter.convert(value);
+ return AbstractConverter.derivative(converter, value);
}
/**
- * Parses the given symbol. This method is similar to {@link Unit#valueOf(CharSequence)}, but
- * hands especially a few symbols found in WKT parsing or in XML files. The list of symbols
- * handled especially is implementation-dependent and may change in future SIS versions.
+ * Parses the given symbol. Invoking this method is equivalent to invoking
+ * {@link UnitFormat#parse(CharSequence)} on a shared locale-independent instance.
+ * This method is capable to handle some symbols found during WKT parsing or in XML files.
+ * The list of symbols supported by this method is implementation-dependent
+ * and may change in future SIS versions.
*
* <div class="section">Parsing authority codes</div>
* As a special case, if the given {@code uom} arguments is of the form {@code "EPSG:####"}
@@ -342,158 +1161,25 @@ public final class Units extends Static
* <div class="section">NetCDF unit symbols</div>
* 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 NonSI#DEGREE_ANGLE} 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.
- * @throws IllegalArgumentException if the given symbol can not be parsed.
- */
- public static Unit<?> valueOf(String uom) throws IllegalArgumentException {
- if (uom == null) {
- return null;
- }
- uom = trimWhitespaces(CharSequences.toASCII(uom)).toString();
- final int length = uom.length();
- /*
- * Check for authority codes (currently only EPSG, but more could be added later).
- * If the unit is not an authority code (which is the most common case), then we
- * will check for hard-coded unit symbols.
- *
- * DefinitionURI.codeOf(…) returns 'uom' directly (provided that whitespaces were already trimmed)
- * if no ':' character were found, in which case the string is assumed to be the code directly.
- * This is the intended behavior for AuthorityFactory, but in the particular case of this method
- * we want to try to parse as a xpointer before to give up.
- */
- if (isURI(uom)) {
- String code = DefinitionURI.codeOf("uom", Constants.EPSG, uom);
- if (code != null && code != uom) try { // Really identity check, see above comment.
- return valueOfEPSG(Integer.parseInt(code));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(Errors.format(
- Errors.Keys.IllegalArgumentValue_2, "uom", uom), e);
- }
- code = XPaths.xpointer("uom", uom);
- if (code != null) {
- uom = code;
- }
- }
- /*
- * Check for degrees units. Note that "deg" could be both angular and Celsius degrees.
- * We try to resolve this ambiguity in the code below by looking for the "Celsius" suffix.
- * Other suffixes commonly found in NetCDF files are "west", "east", "north" or "south".
- * Those suffixes are ignored.
- */
- if (uom.regionMatches(true, 0, "deg", 0, 3)) {
- switch (length) {
- case 3: return NonSI.DEGREE_ANGLE; // Exactly "deg"
- case 4: {
- if (uom.charAt(3) == 'K') {
- return SI.KELVIN; // Exactly "degK".
- }
- break;
- }
- }
- String prefix = uom;
- boolean isTemperature = false;
- final int s = Math.max(uom.lastIndexOf(' '), uom.lastIndexOf('_'));
- if (s >= 1) {
- final String suffix = (String) trimWhitespaces(uom, s+1, length);
- if (ArraysExt.containsIgnoreCase(CARDINAL_DIRECTIONS, suffix) || (isTemperature = isCelsius(suffix))) {
- prefix = (String) trimWhitespaces(uom, 0, s); // Remove the suffix only if we recognized it.
- }
- }
- if (equalsIgnorePlural(prefix, "degree")) {
- return isTemperature ? SI.CELSIUS : NonSI.DEGREE_ANGLE;
- }
- } else {
- /*
- * Check for unit symbols that do not begin with "deg". If a symbol begins
- * with "deg", then the check should be put in the above block instead.
- */
- if (uom.equals("°") || equalsIgnorePlural(uom, "decimal_degree")) return NonSI.DEGREE_ANGLE;
- if (uom.equalsIgnoreCase("arcsec")) return NonSI.SECOND_ANGLE;
- if (uom.equalsIgnoreCase("rad") || equalsIgnorePlural(uom, "radian")) return SI.RADIAN;
- if (equalsIgnorePlural(uom, "meter") || equalsIgnorePlural(uom, "metre")) return SI.METRE;
- if (equalsIgnorePlural(uom, "kilometer") || equalsIgnorePlural(uom, "kilometre")) return SI.KILOMETRE;
- if (equalsIgnorePlural(uom, "week")) return NonSI.WEEK;
- if (equalsIgnorePlural(uom, "day")) return NonSI.DAY;
- if (equalsIgnorePlural(uom, "hour")) return NonSI.HOUR;
- if (equalsIgnorePlural(uom, "minute")) return NonSI.MINUTE;
- if (equalsIgnorePlural(uom, "second")) return SI .SECOND;
- if (equalsIgnorePlural(uom, "pixel")) return NonSI.PIXEL;
- if (equalsIgnorePlural(uom, "grade")) return NonSI.GRADE;
- if (isCelsius(uom)) return SI.CELSIUS;
- if (uom.isEmpty()) return Unit.ONE;
- if (uom.equalsIgnoreCase("US survey foot")) return NonSI.FOOT_SURVEY_US;
- if (uom.equalsIgnoreCase("ppm")) return PPM;
- if (uom.equalsIgnoreCase("psu")) return PSU;
- if (uom.equalsIgnoreCase("sigma")) return SIGMA;
- }
- final Unit<?> unit;
- try {
- unit = Unit.valueOf(uom);
- } catch (IllegalArgumentException e) {
- // Provides a better error message than the default JSR-275 0.9.4 implementation.
- throw Exceptions.setMessage(e, Errors.format(Errors.Keys.IllegalArgumentValue_2, "uom", uom), true);
- }
- /*
- * Special case: JSR-275 version 0.6.1 parses "1/s" and "s-1" as "Baud", which is not what
- * we use in geoscience. Replace "Baud" by "Hertz" if the symbol was not explicitely "Bd".
- */
- if (unit.isCompatible(SI.HERTZ) && !uom.equals("Bd")) {
- return SI.HERTZ;
- }
- return UnitsMap.canonicalize(unit);
- }
-
- /**
- * Returns {@code true} if the given {@code uom} is equals to the given expected string,
- * ignoring trailing {@code 's'} character (if any).
- */
- @SuppressWarnings("fallthrough")
- private static boolean equalsIgnorePlural(final String uom, final String expected) {
- final int length = expected.length();
- switch (uom.length() - length) {
- case 0: break; // uom has exactly the expected length.
- case 1: if (Character.toLowerCase(uom.charAt(length)) == 's') break; // else fallthrough.
- default: return false;
- }
- return uom.regionMatches(true, 0, expected, 0, length);
- }
-
- /**
- * Returns {@code true} if the given {@code uom} is equals to {@code "Celsius"} or
- * {@code "Celcius"}. The later is a common misspelling.
- */
- private static boolean isCelsius(final String uom) {
- return uom.equalsIgnoreCase("Celsius") || uom.equalsIgnoreCase("Celcius");
- }
-
- /**
- * Returns {@code true} if the given unit seems to be an URI. Example:
- * <ul>
- * <li>{@code "urn:ogc:def:uom:EPSG::9001"}</li>
- * <li>{@code "http://schemas.opengis.net/iso/19139/20070417/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])"}</li>
- * </ul>
+ * 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.
+ * @throws ParserException if the given symbol can not be parsed.
+ *
+ * @see UnitFormat#parse(CharSequence)
*/
- private static boolean isURI(final String uom) {
- for (int i=uom.length(); --i>=0;) {
- final char c = uom.charAt(i);
- if (c == ':' || c == '#') {
- return true;
- }
- }
- return false;
+ public static Unit<?> valueOf(String uom) throws ParserException {
+ return (uom != null) ? UnitFormat.INSTANCE.parse(uom) : null;
}
/**
- * Returns a hard-coded unit from an EPSG code. The {@code code} argument given to this
- * method shall be a code identifying a record in the {@code "Unit of Measure"} table of
- * the EPSG database. If this method does not recognize the given code, then it returns
- * {@code null}.
+ * Returns a hard-coded unit from an EPSG code. The {@code code} argument given to this method shall
+ * be a code identifying a record in the {@code "Unit of Measure"} table of the EPSG geodetic dataset.
+ * If this method does not recognize the given code, then it returns {@code null}.
*
* <p>The list of units recognized by this method is not exhaustive. This method recognizes
* the base units declared in the {@code TARGET_UOM_CODE} column of the above-cited table,
@@ -521,7 +1207,7 @@ public final class Units extends Static
* <tr><td>9102</td><td>decimal degree</td></tr>
* <tr><td>9103</td><td>minute</td></tr>
* <tr><td>9104</td><td>second</td></tr>
- * <tr><td>9105</td><td>grade</td></tr>
+ * <tr><td>9105</td><td>grad</td></tr>
* <tr><td>9107</td><td>degree-minute-second</td></tr>
* <tr><td>9108</td><td>degree-minute-second</td></tr>
* <tr><td>9109</td><td>microradian</td></tr>
@@ -531,11 +1217,14 @@ public final class Units extends Static
* </table></td>
* <td class="sep"><table class="compact" summary="Linear units">
* <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
+ * <tr><td>1025</td><td>millimetre</td></tr>
+ * <tr><td>1033</td><td>centimetre</td></tr>
* <tr><td>9001</td><td>metre</td></tr>
* <tr><td>9002</td><td>foot</td></tr>
* <tr><td>9003</td><td>US survey foot</td></tr>
* <tr><td>9030</td><td>nautical mile</td></tr>
* <tr><td>9036</td><td>kilometre</td></tr>
+ * <tr><td>9093</td><td>statute mile</td></tr>
* </table></td>
* <td class="sep"><table class="compact" summary="Time units">
* <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
@@ -544,9 +1233,9 @@ public final class Units extends Static
* </table></td>
* <td class="sep"><table class="compact" summary="Scale units">
* <tr><td style="width: 40px"><b>Code</b></td><td><b>Unit</b></td></tr>
- * <tr><td>9201</td><td>one</td></tr>
- * <tr><td>9202</td><td>part per million</td></tr>
- * <tr><td>9203</td><td>one</td></tr>
+ * <tr><td>9201</td><td>unity</td></tr>
+ * <tr><td>9202</td><td>parts per million</td></tr>
+ * <tr><td>9203</td><td>unity</td></tr>
* </table></td>
* </tr>
* </table>
@@ -556,36 +1245,32 @@ public final class Units extends Static
* and code 9122 (<cite>degree (supplier to define representation)</cite>) for coordinate system axes.
* But Apache SIS considers those two codes as synonymous.</div>
*
- * @param code The EPSG code for a unit of measurement.
- * @return The unit, or {@code null} if the code is unrecognized.
+ * @param code the EPSG code for a unit of measurement.
+ * @return the unit, or {@code null} if the code is unrecognized.
*
* @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#createUnit(String)
*/
public static Unit<?> valueOfEPSG(final int code) {
+ /*
+ * The switch for the SexagesimalConverter cases are needed since we did not put those units
+ * in the UnitRegistry map for reducing a little bit class loading in the common cases where
+ * those units are not needed. Other cases are redundant with the UnitRegistry check, but we
+ * add them opportunistically as a shortcut since those units are frequently used.
+ */
switch (code) {
case Constants.EPSG_PARAM_DEGREES: // Fall through
- case Constants.EPSG_AXIS_DEGREES: return NonSI.DEGREE_ANGLE;
- case Constants.EPSG_METRE: return SI.METRE;
+ case Constants.EPSG_AXIS_DEGREES: return DEGREE;
+ case Constants.EPSG_METRE: return METRE;
- case 1029: return YEAR;
- case 1040: return SI .SECOND;
- case 9002: return NonSI.FOOT;
- case 9003: return NonSI.FOOT_SURVEY_US;
- case 9030: return NonSI.NAUTICAL_MILE;
- case 9036: return SI .KILOMETRE;
- case 9101: return SI .RADIAN;
- case 9103: return NonSI.MINUTE_ANGLE;
- case 9104: return NonSI.SECOND_ANGLE;
- case 9105: return NonSI.GRADE;
- case 9109: return SI.MetricPrefix.MICRO(SI.RADIAN);
case 9107: // Fall through
case 9108: return SexagesimalConverter.DMS_SCALED;
case 9110: return SexagesimalConverter.DMS;
case 9111: return SexagesimalConverter.DM;
case 9203: // Fall through
- case 9201: return Unit .ONE;
- case 9202: return Units.PPM;
- default: return null;
+ case 9201: return UNITY;
+ default: {
+ return (code > 0 && code <= Short.MAX_VALUE) ? (Unit<?>) UnitRegistry.get((short) code) : null;
+ }
}
}
@@ -602,17 +1287,28 @@ public final class Units extends Static
* When such choice exists, the code to return is determined by the {@code inAxis} argument,
* which specifies whether the code will be used for axis definition or in other context.
*
- * @param unit The unit for which to get the EPSG code.
+ * @param unit the unit for which to get the EPSG code.
* @param inAxis {@code true} for a unit used in Coordinate System Axis definition.
- * @return The EPSG code of the given units, or {@code null} if unknown.
+ * @return the EPSG code of the given units, or {@code null} if unknown.
*
* @since 0.4
*/
- public static Integer getEpsgCode(final Unit<?> unit, final boolean inAxis) {
- Integer code = UnitsMap.EPSG_CODES.get(unit);
- if (inAxis && code != null && code == Constants.EPSG_PARAM_DEGREES) {
- code = UnitsMap.EPSG_AXIS_DEGREES;
+ public static Integer getEpsgCode(Unit<?> unit, final boolean inAxis) {
+ if (unit != null) {
+ if (!(unit instanceof AbstractUnit<?>)) {
+ unit = get(unit.getSymbol());
+ if (!(unit instanceof AbstractUnit<?>)) {
+ return null;
+ }
+ }
+ short code = ((AbstractUnit<?>) unit).epsg;
+ if (code != 0) {
+ if (inAxis && code == Constants.EPSG_PARAM_DEGREES) {
+ code = Constants.EPSG_AXIS_DEGREES;
+ }
+ return Integer.valueOf(code);
+ }
}
- return code;
+ return null;
}
}
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java?rev=1767577&r1=1767576&r2=1767577&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java [UTF-8] Tue Nov 1 21:03:06 2016
@@ -36,7 +36,7 @@
*
* @author Martin Desruisseaux (MPO, IRD, Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.8
* @module
*/
package org.apache.sis.measure;
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1767577&r1=1767576&r2=1767577&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java [UTF-8] Tue Nov 1 21:03:06 2016
@@ -921,10 +921,10 @@ search: for (; fromIndex <= toIndex;
/**
* Replaces some Unicode characters by ASCII characters on a "best effort basis".
- * For example the {@code 'é'} character is replaced by {@code 'e'} (without accent).
- *
- * <p>The current implementation replaces the characters in the range {@code 00C0}
- * to {@code 00FF} (inclusive) and some space and punctuation characters.</p>
+ * For example the “ é ” character is replaced by “ e ” (without accent),
+ * the “ ″ ” symbol for minutes of angle is replaced by straight double quotes “ " ”,
+ * and combined characters like ㎏, ㎎, ㎝, ㎞, ㎢, ㎦, ㎖, ㎧, ㎩, ㎐, <i>etc.</i> are replaced
+ * by the corresponding sequences of characters.
*
* <div class="note"><b>Note:</b>
* the replacement of Greek letters is a more complex task than what this method can do,
@@ -938,6 +938,7 @@ search: for (; fromIndex <= toIndex;
*
* @see StringBuilders#toASCII(StringBuilder)
* @see org.apache.sis.io.wkt.Transliterator#filter(String)
+ * @see java.text.Normalizer
*/
public static CharSequence toASCII(final CharSequence text) {
return StringBuilders.toASCII(text, null);
@@ -1620,7 +1621,7 @@ cmp: while (ia < lga) {
* @param s1 the first characters sequence to compare, or {@code null}.
* @param s2 the second characters sequence to compare, or {@code null}.
* @param filter the subset of characters to compare, or {@code null} for comparing all characters.
- * @param ignoreCase {@code true} for comparing cases, or {@code false} for requiring exact match.
+ * @param ignoreCase {@code true} for ignoring cases, or {@code false} for requiring exact match.
* @return {@code true} if both arguments are {@code null} or if the two given texts are equal,
* optionally ignoring case and filtered-out characters.
*/
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java?rev=1767577&r1=1767576&r2=1767577&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java [UTF-8] Tue Nov 1 21:03:06 2016
@@ -86,7 +86,7 @@ public final class Characters extends St
* They are ASCII codes 32 to 125 inclusive except ! (33), # (35), $ (36), @ (64) and ` (96),
* plus the addition of ° (176) despite being formally outside the ASCII character set.
*
- * @param c The code point to test.
+ * @param c the code point to test.
* @return {@code true} if the given code point is a valid WKT character.
*
* @see org.apache.sis.io.wkt.Transliterator
@@ -110,7 +110,7 @@ public final class Characters extends St
* line separator}, a {@linkplain Character#PARAGRAPH_SEPARATOR paragraph separator} or one
* of the {@code '\r'} or {@code '\n'} control characters.
*
- * @param c The code point to test.
+ * @param c the code point to test.
* @return {@code true} if the given code point is a line or paragraph separator.
*
* @see #LINE_SEPARATOR
@@ -130,7 +130,7 @@ public final class Characters extends St
* This method returns {@code true} if {@code c} is between {@code '0'} and {@code '9'} inclusive,
* or between {@code 'A'} and {@code 'F'} inclusive, or between {@code 'a'} and {@code 'f'} inclusive.
*
- * @param c The character to test.
+ * @param c the character to test.
* @return {@code true} if the given character is an hexadecimal digit.
*
* @since 0.5
@@ -152,16 +152,16 @@ public final class Characters extends St
* ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ
* }
*
- * @param c The character to test.
+ * @param c the character to test.
* @return {@code true} if the given character is a superscript.
*/
public static boolean isSuperScript(final int c) {
switch (c) {
case '¹': // Legacy values in "Latin-1 supplement" space: 00B9, 00B2 and 00B3.
- case '²': // Those values are outside the normal [2070 … 207F] range.
+ case '²': // Those values are outside the usual [2070 … 207F] range.
case '³': return true;
- case '\u2071': // Would be the '¹', '²' and '³' values if they were declared in the
- case '\u2072': // normal range. Since they are not, those values are unassigned.
+ case '\u2071': // Would be the '¹', '²' and '³' values if they were declared in the usual range.
+ case '\u2072': // Since they are not, those values are unassigned.
case '\u2073': return false;
default: return (c >= '⁰' && c <= 'ⁿ');
}
@@ -175,7 +175,7 @@ public final class Characters extends St
* ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎
* }
*
- * @param c The character to test.
+ * @param c the character to test.
* @return {@code true} if the given character is a subscript.
*/
public static boolean isSubScript(final int c) {
@@ -190,9 +190,8 @@ public final class Characters extends St
* 0 1 2 3 4 5 6 7 8 9 + - = ( ) n
* }
*
- * @param c The character to convert.
- * @return The given character as a superscript, or {@code c}
- * if the given character can not be converted.
+ * @param c the character to convert.
+ * @return the given character as a superscript, or {@code c} if the given character can not be converted.
*/
public static char toSuperScript(char c) {
switch (c) {
@@ -223,9 +222,8 @@ public final class Characters extends St
* 0 1 2 3 4 5 6 7 8 9 + - = ( )
* }
*
- * @param c The character to convert.
- * @return The given character as a subscript, or {@code c}
- * if the given character can not be converted.
+ * @param c the character to convert.
+ * @return the given character as a subscript, or {@code c} if the given character can not be converted.
*/
public static char toSubScript(char c) {
switch (c) {
@@ -247,8 +245,8 @@ public final class Characters extends St
/**
* Converts the given character argument to normal script.
*
- * @param c The character to convert.
- * @return The given character as a normal script, or {@code c} if the
+ * @param c the character to convert.
+ * @return the given character as a normal script, or {@code c} if the
* given character was not a superscript or a subscript.
*/
public static char toNormalScript(char c) {
@@ -369,8 +367,8 @@ public final class Characters extends St
/**
* Creates a new subset of the given name.
*
- * @param name The subset name.
- * @param types A bitmask of character types.
+ * @param name the subset name.
+ * @param types a bitmask of character types.
*/
Filter(final String name, final long types) {
super(name);
@@ -380,7 +378,7 @@ public final class Characters extends St
/**
* Returns {@code true} if this subset contains the given Unicode character.
*
- * @param codePoint The Unicode character, as a code point value.
+ * @param codePoint the Unicode character, as a code point value.
* @return {@code true} if this subset contains the given character.
*/
public boolean contains(final int codePoint) {
@@ -395,7 +393,7 @@ public final class Characters extends St
* {@link Character#DECIMAL_DIGIT_NUMBER DECIMAL_DIGIT_NUMBER} or
* {@link Character#SPACE_SEPARATOR SPACE_SEPARATOR}.
*
- * @param type One of the {@link Character} constants.
+ * @param type one of the {@link Character} constants.
* @return {@code true} if this subset contains the characters of the given type.
*
* @see Character#getType(int)
@@ -407,8 +405,8 @@ public final class Characters extends St
/**
* Returns a subset representing the union of all Unicode characters of the given types.
*
- * @param types The character types, as {@link Character} constants.
- * @return The subset of Unicode characters of the given type.
+ * @param types the character types, as {@link Character} constants.
+ * @return the subset of Unicode characters of the given type.
*
* @see Character#LOWERCASE_LETTER
* @see Character#UPPERCASE_LETTER
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java?rev=1767577&r1=1767576&r2=1767577&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Static.java [UTF-8] Tue Nov 1 21:03:06 2016
@@ -49,7 +49,7 @@ package org.apache.sis.util;
* <tr><td>{@link org.apache.sis.referencing.operation.matrix.Matrices}</td>
* <td>Create and compare {@link org.opengis.referencing.operation.Matrix} objects</td></tr>
* <tr><td>{@link org.apache.sis.measure.Units}</td>
- * <td>Get a {@linkplain javax.measure.unit.Unit unit} from a symbol or EPSG code,
+ * <td>Get a {@linkplain javax.measure.Unit unit} from a symbol or EPSG code,
* and test if a unit is angular, linear or temporal.</td></tr>
*
* <tr><th colspan="2" class="hsep">OGC/ISO objects (metadata, referencing, geometries)</th></tr>
|