javax.measure.UnitConverter Java Examples

The following examples show how to use javax.measure.UnitConverter. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForNonSystemUnit(ComparableUnit unit) throws IOException {
    
    if (unit.isSystemUnit()) {
        return null;
    }
    
    final Unit<?> parentUnit = unit.getSystemUnit();
    final UnitConverter converter = unit.getConverterTo(parentUnit);
    final StringBuilder sb = new StringBuilder();
    final boolean printSeparator = !ONE.equals(parentUnit);
    
    format(parentUnit, sb);
    formatConverter(converter, printSeparator, sb, symbolMap);
    
    return sb;
}
 
Example #2
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForKilogram(ComparableUnit unit) throws IOException {
    
    final Unit<?> systemUnit = unit.getSystemUnit();
    if (!systemUnit.equals(SI.KILOGRAM)) {
        return null;
    }

    final UnitConverter converter = 
            UCUMFormatHelper.toKnownPrefixConverterIfPossible(
                    unit.getConverterTo(systemUnit)
                    .concatenate(MultiplyConverter.ofPrefix(MetricPrefix.KILO)));
    
    final StringBuilder sb = new StringBuilder();
    final boolean printSeparator = true;
    
    // A special case because KILOGRAM is a BaseUnit instead of
    // a transformed unit, for compatibility with existing SI
    // unit system.
    format(SI.GRAM, sb);
    formatConverter(converter, printSeparator, sb, symbolMap);    
    
    return sb;
}
 
Example #3
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForTransformedUnit(ComparableUnit unit) throws IOException {
    if (!(unit instanceof TransformedUnit)) {
        return null;    
    }
    final StringBuilder sb = new StringBuilder();
    final Unit<?> parentUnit = ((TransformedUnit) unit).getParentUnit();
    final UnitConverter converter = 
            UCUMFormatHelper.toKnownPrefixConverterIfPossible(unit.getConverterTo(parentUnit));
    final boolean printSeparator = !ONE.equals(parentUnit);

    if (printSeparator && converter instanceof MultiplyConverter) { // workaround for #166
    	format(parentUnit, sb);
    }
    formatConverter(converter, printSeparator, sb, symbolMap);

    return sb;
}
 
Example #4
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForKilogram(ComparableUnit unit) throws IOException {
    
    final Unit<?> systemUnit = unit.getSystemUnit();
    if (!systemUnit.equals(SI.KILOGRAM)) {
        return null;
    }

    final UnitConverter converter = 
            UCUMFormatHelper.toKnownPrefixConverterIfPossible(
                    unit.getConverterTo(systemUnit)
                    .concatenate(MultiplyConverter.ofPrefix(MetricPrefix.KILO)));
    
    final StringBuilder sb = new StringBuilder();
    final boolean printSeparator = true;
    
    // A special case because KILOGRAM is a BaseUnit instead of
    // a transformed unit, for compatibility with existing SI
    // unit system.
    format(SI.GRAM, sb);
    formatConverter(converter, printSeparator, sb, symbolMap);    
    
    return sb;
}
 
Example #5
Source File: QuantityType.java    From openhab-core with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Convert this QuantityType to a new {@link QuantityType} using the given target unit.
 *
 * @param targetUnit the unit to which this {@link QuantityType} will be converted to.
 * @return the new {@link QuantityType} in the given {@link Unit} or {@code null} in case of a
 */
@SuppressWarnings("unchecked")
public @Nullable QuantityType<T> toUnit(Unit<?> targetUnit) {
    if (!targetUnit.equals(getUnit())) {
        try {
            UnitConverter uc = getUnit().getConverterToAny(targetUnit);
            Quantity<?> result = Quantities.getQuantity(uc.convert(quantity.getValue()), targetUnit);

            return new QuantityType<T>(result.getValue(), (Unit<T>) targetUnit);
        } catch (UnconvertibleException | IncommensurableException e) {
            logger.debug("Unable to convert unit from {} to {}", getUnit(), targetUnit);
            return null;
        }
    }
    return this;
}
 
Example #6
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForNonSystemUnit(ComparableUnit unit) throws IOException {
    
    if (unit.isSystemUnit()) {
        return null;
    }
    
    final Unit<?> parentUnit = unit.getSystemUnit();
    final UnitConverter converter = unit.getConverterTo(parentUnit);
    final StringBuilder sb = new StringBuilder();
    final boolean printSeparator = !parentUnit.equals(ONE);
    
    format(parentUnit, sb);
    formatConverter(converter, printSeparator, sb, symbolMap);
    
    return sb;
}
 
Example #7
Source File: UCUMFormat.java    From uom-systems with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
@SuppressWarnings({ "unchecked", "rawtypes" })
private CharSequence symbolForTransformedUnit(ComparableUnit unit) throws IOException {
    if (!(unit instanceof TransformedUnit)) {
        return null;    
    }
    final StringBuilder sb = new StringBuilder();
    final Unit<?> parentUnit = ((TransformedUnit) unit).getParentUnit();
    final UnitConverter converter = 
            UCUMFormatHelper.toKnownPrefixConverterIfPossible(unit.getConverterTo(parentUnit));
    final boolean printSeparator = !parentUnit.equals(ONE);
    if (printSeparator && converter instanceof MultiplyConverter) { // workaround for #166
    	format(parentUnit, sb);
    }
    formatConverter(converter, printSeparator, sb, symbolMap);

    return sb;
}
 
Example #8
Source File: QuantityType.java    From smarthome with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Convert this QuantityType to a new {@link QuantityType} using the given target unit.
 *
 * @param targetUnit the unit to which this {@link QuantityType} will be converted to.
 * @return the new {@link QuantityType} in the given {@link Unit} or {@code null} in case of a
 */
@SuppressWarnings("unchecked")
public @Nullable QuantityType<T> toUnit(Unit<?> targetUnit) {
    if (!targetUnit.equals(getUnit())) {
        try {
            UnitConverter uc = getUnit().getConverterToAny(targetUnit);
            Quantity<?> result = Quantities.getQuantity(uc.convert(quantity.getValue()), targetUnit);

            return new QuantityType<T>(result.getValue(), (Unit<T>) targetUnit);
        } catch (UnconvertibleException | IncommensurableException e) {
            logger.debug("Unable to convert unit from {} to {}", getUnit(), targetUnit);
            return null;
        }
    }
    return this;
}
 
Example #9
Source File: ConventionalUnit.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a converter from this unit to the specified unit of unknown type.
 * This method can be used when the quantity type of the specified unit is unknown at compile-time
 * or when dimensional analysis allows for conversion between units of different type.
 *
 * @param  that  the unit to which to convert the numeric values.
 * @return the converter from this unit to {@code that} unit.
 * @throws IncommensurableException if this unit is not {@linkplain #isCompatible(Unit) compatible} with {@code that} unit.
 *
 * @see #isCompatible(Unit)
 */
@Override
public UnitConverter getConverterToAny(final Unit<?> that) throws IncommensurableException {
    if (that == this) {
        return IdentityConverter.INSTANCE;
    }
    ArgumentChecks.ensureNonNull("that", that);
    UnitConverter c = toTarget;
    if (target != that) {                           // Optimization for a common case.
        final Unit<?> step = that.getSystemUnit();
        if (target != step && !target.isCompatible(step)) {
            throw new IncommensurableException(incompatible(that));
        }
        c = target.getConverterToAny(step).concatenate(c);      // Usually leave 'c' unchanged.
        c =   step.getConverterToAny(that).concatenate(c);
    }
    return c;
}
 
Example #10
Source File: ConventionalUnit.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a converter of numeric values from this unit to another unit of same type.
 *
 * @param  that  the unit of same type to which to convert the numeric values.
 * @return the converter from this unit to {@code that} unit.
 * @throws UnconvertibleException if the converter can not be constructed.
 */
@Override
public UnitConverter getConverterTo(final Unit<Q> that) throws UnconvertibleException {
    if (that == this) {
        return IdentityConverter.INSTANCE;
    }
    ArgumentChecks.ensureNonNull("that", that);
    UnitConverter c = toTarget;
    if (target != that) {                           // Optimization for a common case.
        final Unit<Q> step = that.getSystemUnit();
        if (target != step && !target.isCompatible(step)) {
            // Should never occur unless parameterized type has been compromised.
            throw new UnconvertibleException(incompatible(that));
        }
        c = target.getConverterTo(step).concatenate(c);         // Usually leave 'c' unchanged.
        c =   step.getConverterTo(that).concatenate(c);
    }
    return c;
}
 
Example #11
Source File: ChannelDecoder.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Converts the given numerical values to date, using the information provided in the given unit symbol.
 * The unit symbol is typically a string like <cite>"days since 1970-01-01T00:00:00Z"</cite>.
 *
 * @param  values  the values to convert. May contain {@code null} elements.
 * @return the converted values. May contain {@code null} elements.
 */
@Override
public Date[] numberToDate(final String symbol, final Number... values) {
    final Date[] dates = new Date[values.length];
    final Matcher parts = Variable.TIME_UNIT_PATTERN.matcher(symbol);
    if (parts.matches()) try {
        final UnitConverter converter = Units.valueOf(parts.group(1)).getConverterToAny(Units.MILLISECOND);
        final long epoch = StandardDateFormat.toDate(StandardDateFormat.FORMAT.parse(parts.group(2))).getTime();
        for (int i=0; i<values.length; i++) {
            final Number value = values[i];
            if (value != null) {
                dates[i] = new Date(epoch + Math.round(converter.convert(value.doubleValue())));
            }
        }
    } catch (IncommensurableException | ParserException | DateTimeException | ArithmeticException e) {
        listeners.warning(e);
    }
    return dates;
}
 
Example #12
Source File: DefaultParameterValue.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the converter to be used by {@link #doubleValue(Unit)} and {@link #doubleValueList(Unit)}.
 */
private UnitConverter getConverterTo(final Unit<?> unit) {
    final Unit<?> source = getUnit();
    if (source == null) {
        throw new IllegalStateException(Resources.format(Resources.Keys.UnitlessParameter_1, Verifier.getDisplayName(descriptor)));
    }
    ensureNonNull("unit", unit);
    final short expectedID = Verifier.getUnitMessageID(source);
    if (Verifier.getUnitMessageID(unit) != expectedID) {
        throw new IllegalArgumentException(Errors.format(expectedID, unit));
    }
    try {
        return source.getConverterToAny(unit);
    } catch (IncommensurableException e) {
        throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatibleUnits_2, source, unit), e);
    }
}
 
Example #13
Source File: Units.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the coefficients of the given converter expressed as a polynomial equation.
 * This method returns the first of the following choices that apply:
 *
 * <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>
 *
 * This method returns {@code null} if it can not get the polynomial equation coefficients from the given converter.
 *
 * @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.
 *
 * @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;
}
 
Example #14
Source File: SystemUnit.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the unit derived from this unit using the specified converter.
 *
 * @param  operation  the converter from the transformed unit to this unit.
 * @return the unit after the specified transformation.
 */
@Override
public Unit<Q> transform(UnitConverter operation) {
    ArgumentChecks.ensureNonNull("operation", operation);
    AbstractUnit<Q> base = this;
    final ConventionalUnit<Q> pseudo = Prefixes.pseudoSystemUnit(this);
    if (pseudo != null) {
        /*
         * Special case for Units.KILOGRAM, to be replaced by Units.GRAM so a prefix can be computed.
         * The kilogram may appear in an expression like "kg/m", which we want to replace by "g/m".
         *
         * Note: we could argue that this block should be UnitFormat's work rather than SystemUnit.
         * We perform this work here because this unit symbol may be different than what UnitFormat
         * would infer, for example because of symbols recorded by sequence of Unit.multiply(Unit)
         * and Unit.divide(Unit) operations.
         */
        operation = operation.concatenate(pseudo.toTarget.inverse());
        base = pseudo;
    }
    return ConventionalUnit.create(base, operation);
}
 
Example #15
Source File: DefaultTemporalCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Initialize the fields required for {@link #toInstant(double)} and {@link #toValue(Instant)} operations.
 */
private void initializeConverter() {
    toSeconds = getUnit().getConverterTo(Units.SECOND);
    long t = datum.getOrigin().getTime();
    origin = t / MILLIS_PER_SECOND;
    t %= MILLIS_PER_SECOND;
    if (t != 0) {
        /*
         * The origin is usually an integer amount of days or hours. It rarely has a fractional amount of seconds.
         * If it happens anyway, put the fractional amount of seconds in the converter instead than adding another
         * field in this class for such very rare situation. Accuracy should be okay since the offset is small.
         */
        UnitConverter c = Units.converter(null, new Fraction((int) t, MILLIS_PER_SECOND).simplify());
        toSeconds = c.concatenate(toSeconds);
    }
}
 
Example #16
Source File: SystemUnit.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a converter of numeric values from this unit to another unit of same type.
 *
 * @param  unit  the unit of same type to which to convert the numeric values.
 * @return the converter from this unit to {@code that} unit.
 * @throws UnconvertibleException if the converter can not be constructed.
 */
@Override
public UnitConverter getConverterTo(final Unit<Q> unit) throws UnconvertibleException {
    ArgumentChecks.ensureNonNull("unit", unit);
    final Unit<Q> step = unit.getSystemUnit();
    if (step != this && !equalsIgnoreMetadata(step)) {
        // Should never occur unless parameterized type has been compromised.
        throw new UnconvertibleException(incompatible(unit));
    }
    if (step == unit) {
        return IdentityConverter.INSTANCE;
    }
    /*
     * At this point we know that the given units is not a system unit. Ask the conversion
     * FROM the given units (before to inverse it) instead than TO the given units because
     * in Apache SIS implementation, the former returns directly ConventionalUnit.toTarget
     * while the later implies a recursive call to this method.
     */
    return unit.getConverterTo(step).inverse();
}
 
Example #17
Source File: CoordinateFormat.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Adjusts the resolution units for the given coordinate system axis. This methods select the units which
 * result in the smallest absolute value of {@link #resolution}.
 *
 * @param  maxValue  the maximal absolute value that a coordinate on the axis may have.
 * @param  axisUnit  {@link CoordinateSystemAxis#getUnit()}.
 * @return whether the given axis unit is compatible with the expected unit.
 */
boolean forAxis(double maxValue, final Unit<?> axisUnit) throws IncommensurableException {
    if (!axisUnit.isCompatible(unit)) {
        return false;
    }
    final UnitConverter c = unit.getConverterToAny(axisUnit);
    final double r = Math.abs(c.convert(resolution));
    if (r < resolution) {
        resolution = r;                                         // To units producing the smallest value.
        unit = axisUnit;
    } else {
        maxValue = Math.abs(c.inverse().convert(maxValue));     // From axis units to selected units.
    }
    if (maxValue > magnitude) {
        magnitude = maxValue;
    }
    return true;
}
 
Example #18
Source File: Prefixes.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * If the given system unit should be replaced by pseudo-unit for the purpose of formatting,
 * returns that pseudo-unit. Otherwise returns {@code null}. This method is for handling the
 * Special case of {@link Units#KILOGRAM}, to be replaced by {@link Units#GRAM} so a prefix
 * can be computed. The kilogram may appear in an expression like "kg/m", which we want to
 * replace by "g/m". We do that by dividing the unit by 1000 (the converter for "milli" prefix).
 */
@SuppressWarnings("unchecked")
static <Q extends Quantity<Q>> ConventionalUnit<Q> pseudoSystemUnit(final SystemUnit<Q> unit) {
    if ((unit.scope & ~UnitRegistry.SI) == 0 && unit.dimension.numeratorIs('M')) {
        if (unit == Units.KILOGRAM) {
            return (ConventionalUnit<Q>) Units.GRAM;            // Optimization for a common case.
        } else {
            String symbol = unit.getSymbol();
            if (symbol != null && symbol.length() >= 3 && symbol.startsWith("kg")
                    && !AbstractUnit.isSymbolChar(symbol.codePointAt(2)))
            {
                symbol = symbol.substring(1);
                UnitConverter c = converter('m');
                return new ConventionalUnit<>(unit, c, symbol, UnitRegistry.PREFIXABLE, (short) 0).unique(symbol);
            }
        }
    }
    return null;
}
 
Example #19
Source File: DerivedScalar.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new {@link Fallback} instance implementing the given quantity type.
 *
 * @see ScalarFallback#factory(double, Unit, Class)
 */
@SuppressWarnings("unchecked")
static <Q extends Quantity<Q>> Q factory(final double value, final Unit<Q> unit,
        final Unit<Q> systemUnit, final UnitConverter toSystem, final Class<Q> type)
{
    final Fallback<Q> quantity = new Fallback<>(value, unit, systemUnit, toSystem, type);
    return (Q) Proxy.newProxyInstance(Scalar.class.getClassLoader(), new Class<?>[] {type}, quantity);
}
 
Example #20
Source File: ConventionalUnit.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the unit derived from this unit using the specified converter.
 *
 * @param  operation  the converter from the transformed unit to this unit.
 * @return the unit after the specified transformation.
 */
@Override
public Unit<Q> transform(UnitConverter operation) {
    ArgumentChecks.ensureNonNull("operation", operation);
    AbstractUnit<Q> base = this;
    if (!isPrefixable()) {
        base = target;
        operation = toTarget.concatenate(operation);
    }
    return create(base, operation);
}
 
Example #21
Source File: MeasurementRange.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Casts this range to the specified type and converts to the specified unit.
 * This method is invoked on the {@code other} instance in expressions like
 * {@code this.operation(other)}.
 *
 * @param  type  the class to cast to. Must be one of {@link Byte}, {@link Short},
 *               {@link Integer}, {@link Long}, {@link Float} or {@link Double}.
 * @param  targetUnit the target unit, or {@code null} for no change.
 * @return the casted range, or {@code this}.
 * @throws IncommensurableException if the given target unit is not compatible with the unit of this range.
 */
@SuppressWarnings("unchecked")
private <N extends Number & Comparable<? super N>> MeasurementRange<N>
        convertAndCast(final Class<N> type, Unit<?> targetUnit) throws IncommensurableException
{
    if (targetUnit == null || targetUnit.equals(unit)) {
        if (elementType == type) {
            return (MeasurementRange<N>) this;
        }
        targetUnit = unit;
    } else if (unit != null) {
        final UnitConverter converter = unit.getConverterToAny(targetUnit);
        if (!converter.isIdentity()) {
            boolean minInc = isMinIncluded;
            boolean maxInc = isMaxIncluded;
            double minimum = converter.convert(getMinDouble());
            double maximum = converter.convert(getMaxDouble());
            if (minimum > maximum) {
                final double  td = minimum; minimum = maximum; maximum = td;
                final boolean tb = minInc;  minInc  = maxInc;  maxInc  = tb;
            }
            if (Numbers.isInteger(type)) {
                minInc &= (minimum == (minimum = Math.floor(minimum)));
                maxInc &= (maximum == (maximum = Math.ceil (maximum)));
            }
            return new MeasurementRange<>(type,
                    Numbers.cast(minimum, type), minInc,
                    Numbers.cast(maximum, type), maxInc, targetUnit);
        }
    }
    return new MeasurementRange<>(type, this, targetUnit);
}
 
Example #22
Source File: LinearConverter.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Raises the given converter to the given power. This method assumes that the given converter
 * {@linkplain #isLinear() is linear} (this is not verified) and takes only the scale factor;
 * the offset (if any) is ignored.
 *
 * <p>It is caller's responsibility to skip this method call when {@code n} = 1.
 * This method does not perform this check because it is usually already done (indirectly) by the caller.</p>
 *
 * @param  converter  the converter to raise to the given power.
 * @param  n          the exponent.
 * @param  root       {@code true} for raising to 1/n instead of n.
 * @return the converter raised to the given power.
 */
static LinearConverter pow(final UnitConverter converter, final int n, final boolean root) {
    double numerator, denominator;
    if (converter instanceof LinearConverter) {
        final LinearConverter lc = (LinearConverter) converter;
        numerator   = lc.scale;
        denominator = lc.divisor;
    } else {
        // Subtraction by convert(0) is a paranoiac safety.
        numerator   = converter.convert(1d) - converter.convert(0d);
        denominator = 1;
    }
    if (root) {
        switch (n) {
            case 1:  break;
            case 2:  numerator   = Math.sqrt(numerator);
                     denominator = Math.sqrt(denominator);
                     break;
            case 3:  numerator   = Math.cbrt(numerator);
                     denominator = Math.cbrt(denominator);
                     break;
            default: final double r = 1.0 / n;
                     numerator   = Math.pow(numerator,   r);
                     denominator = Math.pow(denominator, r);
                     break;
        }
    } else {
        numerator   = (numerator   == 10) ? MathFunctions.pow10(n) : Math.pow(numerator,   n);
        denominator = (denominator == 10) ? MathFunctions.pow10(n) : Math.pow(denominator, n);
    }
    return scale(numerator, denominator);
}
 
Example #23
Source File: ConcatenatedConverter.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the inverse of this unit converter.
 */
@Override
public synchronized UnitConverter inverse() {
    if (inverse == null) {
        inverse = new ConcatenatedConverter(c2.inverse(), c1.inverse());
        inverse.inverse = this;
    }
    return inverse;
}
 
Example #24
Source File: SystemUnit.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of {@link #multiply(Unit)} and {@link #divide(Unit)} methods.
 *
 * @param  inverse  wether to use the inverse of {@code other}.
 */
private <T extends Quantity<T>> Unit<?> product(final Unit<T> other, final boolean inverse) {
    final Unit<T> intermediate = other.getSystemUnit();
    final Dimension dim = intermediate.getDimension();
    final UnitDimension newDimension;
    final char operation;
    if (inverse) {
        operation = DIVIDE;
        newDimension = dimension.divide(dim);
    } else {
        operation = MULTIPLY;
        newDimension = dimension.multiply(dim);
    }
    final boolean transformed = (intermediate != other);
    Unit<?> result = create(newDimension, operation, transformed ? null : other);
    if (transformed) {
        UnitConverter c = other.getConverterTo(intermediate);
        if (!c.isLinear()) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.NonRatioUnit_1, other));
        }
        if (!c.isIdentity()) {
            if (inverse) c = c.inverse();
            result = result.transform(c);
            /*
             * If the system unit product is an Apache SIS implementation, try to infer a unit symbol
             * to be given to our customized 'transform' method. Otherwise fallback on standard API.
             */
            result = inferSymbol(result, operation, other);
        }
    }
    return result;
}
 
Example #25
Source File: SystemUnit.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a converter from this unit to the specified unit of unknown type.
 * This method can be used when the quantity type of the specified unit is unknown at compile-time
 * or when dimensional analysis allows for conversion between units of different type.
 *
 * @param  unit  the unit to which to convert the numeric values.
 * @return the converter from this unit to {@code that} unit.
 * @throws IncommensurableException if this unit is not {@linkplain #isCompatible(Unit) compatible} with {@code that} unit.
 *
 * @see #isCompatible(Unit)
 */
@Override
public UnitConverter getConverterToAny(final Unit<?> unit) throws IncommensurableException {
    ArgumentChecks.ensureNonNull("unit", unit);
    final Unit<?> step = unit.getSystemUnit();
    if (step != this && !isCompatible(step)) {
        throw new IncommensurableException(incompatible(unit));
    }
    if (step == unit) {
        return IdentityConverter.INSTANCE;
    }
    // Same remark than in getConverterTo(Unit).
    return unit.getConverterToAny(step).inverse();
}
 
Example #26
Source File: ConventionalUnitTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests conversion of a temperature value between two conventional units.
 */
@Test
public void testConvertTemperature() {
    final UnitConverter c = Units.FAHRENHEIT.getConverterTo(Units.CELSIUS);
    assertEquals("50°F",  10, c.convert(50),          STRICT);
    assertEquals("5°F",  -15, c.convert(5),           STRICT);
    assertEquals("0°C",   32, c.inverse().convert(0), STRICT);
}
 
Example #27
Source File: SexagesimalConverterTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Converts the given value to an other unit, compares with the expected value, and verify
 * the inverse conversion. Then tries again with the negative of the given values.
 */
private static <Q extends Quantity<Q>> void checkConversion(
        final double expected, final Unit<Q> unitExpected,
        final double actual,   final Unit<Q> unitActual)
{
    final UnitConverter converter = unitActual.getConverterTo(unitExpected);
    final UnitConverter inverse   = converter.inverse();
    assertEquals( expected, converter.convert( actual), TOLERANCE);
    assertEquals( actual,   inverse.convert( expected), TOLERANCE);
    assertEquals(-expected, converter.convert(-actual), TOLERANCE);
    assertEquals(-actual,   inverse.convert(-expected), TOLERANCE);
}
 
Example #28
Source File: DerivedScalar.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Constructor for {@link Quantities} factory only.
 */
private Fallback(final double value, final Unit<Q> unit, final Unit<Q> systemUnit,
                 final UnitConverter toSystem, final Class<Q> type)
{
    super(value, unit, systemUnit, toSystem);
    this.type = type;
}
 
Example #29
Source File: WaterTankUnitTest.java    From tutorials with MIT License 5 votes vote down vote up
@Test
public void givenMeters_whenConvertToKilometer_ThenConverted() {
    double distanceInMeters = 50.0;
    UnitConverter metreToKilometre = METRE.getConverterTo(MetricPrefix.KILO(METRE));
    double distanceInKilometers = metreToKilometre.convert(distanceInMeters);
    assertEquals(0.05, distanceInKilometers, 0.00f);
}
 
Example #30
Source File: ConcatenatedConverter.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Concatenates this converter with another converter. The resulting converter is equivalent to first converting
 * by the specified converter (right converter), and then converting by this converter (left converter).
 */
@Override
public UnitConverter concatenate(final UnitConverter converter) {
    ArgumentChecks.ensureNonNull("converter", converter);
    if (equals(converter.inverse())) {
        return IdentityConverter.INSTANCE;
    }
    // Delegate to c1 and c2 because they may provide more intelligent 'concatenate' implementations.
    return c2.concatenate(c1.concatenate(converter));
}