Search in sources :

Example 26 with Unit

use of javax.measure.Unit in project unit-api by unitsofmeasurement.

the class TestUnit method getConverterToAny.

public UnitConverter getConverterToAny(Unit<?> that) throws IncommensurableException, UnconvertibleException {
    if (!isCompatible(that))
        throw new IncommensurableException(this + " is not compatible with " + that);
    // Since both units are
    TestUnit thatAbstr = (TestUnit) that;
    // compatible they must
    // be both test
    // units.
    Unit thisSystemUnit = this.getSystemUnit();
    UnitConverter thisToDimension = this.getSystemConverter();
    Unit thatSystemUnit = thatAbstr.getSystemUnit();
    UnitConverter thatToDimension = thatAbstr.getSystemConverter();
    return thatToDimension.inverse().concatenate(thisToDimension);
}
Also used : IncommensurableException(javax.measure.IncommensurableException) UnitConverter(javax.measure.UnitConverter) Unit(javax.measure.Unit) BaseUnit(javax.measure.test.unit.BaseUnit)

Example 27 with Unit

use of javax.measure.Unit in project unit-api by unitsofmeasurement.

the class DefaultTestQuantityFormat method format.

@Override
public Appendable format(Quantity measure, Appendable dest) throws IOException {
    Unit unit = measure.getUnit();
    dest.append(measure.getValue().toString());
    if (measure.getUnit().equals(TestUnit.ONE))
        return dest;
    dest.append(' ');
    return SimpleTestUnitFormat.getInstance().format(unit, dest);
}
Also used : Unit(javax.measure.Unit) TestUnit(javax.measure.test.TestUnit)

Example 28 with Unit

use of javax.measure.Unit in project unit-api by unitsofmeasurement.

the class DefaultTestQuantityFormat method parse.

@SuppressWarnings("unchecked")
@Override
public Quantity<?> parse(CharSequence csq, ParsePosition cursor) throws MeasurementParseException {
    int startDecimal = cursor.getIndex();
    while ((startDecimal < csq.length()) && Character.isWhitespace(csq.charAt(startDecimal))) {
        startDecimal++;
    }
    int endDecimal = startDecimal + 1;
    while ((endDecimal < csq.length()) && !Character.isWhitespace(csq.charAt(endDecimal))) {
        endDecimal++;
    }
    BigDecimal decimal = new BigDecimal(csq.subSequence(startDecimal, endDecimal).toString());
    cursor.setIndex(endDecimal + 1);
    Unit unit = SimpleTestUnitFormat.getInstance().parse(csq);
    return TestQuantities.getQuantity(decimal, unit);
}
Also used : Unit(javax.measure.Unit) TestUnit(javax.measure.test.TestUnit) BigDecimal(java.math.BigDecimal)

Example 29 with Unit

use of javax.measure.Unit in project sis by apache.

the class CoordinateFormat method initialize.

/**
 * Computes the value of transient fields from the given CRS.
 */
private void initialize(final CoordinateReferenceSystem crs) {
    types = null;
    formats = null;
    units = null;
    toFormatUnit = null;
    unitSymbols = null;
    epochs = null;
    negate = 0;
    lastCRS = crs;
    if (crs == null) {
        return;
    }
    /*
         * If no CRS were specified, we will format everything as numbers. Working with null CRS
         * is sometime useful because null CRS are allowed in DirectPosition according ISO 19107.
         * Otherwise (if a CRS is given), infer the format subclasses from the axes.
         */
    final CoordinateSystem cs = crs.getCoordinateSystem();
    final int dimension = cs.getDimension();
    final byte[] types = new byte[dimension];
    final Format[] formats = new Format[dimension];
    for (int i = 0; i < dimension; i++) {
        final CoordinateSystemAxis axis = cs.getAxis(i);
        final Unit<?> unit = axis.getUnit();
        /*
             * Formatter for angular units. Target unit is DEGREE_ANGLE.
             * Type is LONGITUDE, LATITUDE or ANGLE depending on axis direction.
             */
        if (Units.isAngular(unit)) {
            byte type = ANGLE;
            final AxisDirection dir = axis.getDirection();
            if (AxisDirection.NORTH.equals(dir)) {
                type = LATITUDE;
            } else if (AxisDirection.EAST.equals(dir)) {
                type = LONGITUDE;
            } else if (AxisDirection.SOUTH.equals(dir)) {
                type = LATITUDE;
                negate(i);
            } else if (AxisDirection.WEST.equals(dir)) {
                type = LONGITUDE;
                negate(i);
            }
            types[i] = type;
            formats[i] = getFormat(Angle.class);
            setConverter(dimension, i, unit.asType(javax.measure.quantity.Angle.class).getConverterTo(Units.DEGREE));
            continue;
        }
        /*
             * Formatter for temporal units. Target unit is MILLISECONDS.
             * Type is DATE.
             */
        if (Units.isTemporal(unit)) {
            final CoordinateReferenceSystem t = CRS.getComponentAt(crs, i, i + 1);
            if (t instanceof TemporalCRS) {
                if (epochs == null) {
                    epochs = new long[dimension];
                }
                types[i] = DATE;
                formats[i] = getFormat(Date.class);
                epochs[i] = ((TemporalCRS) t).getDatum().getOrigin().getTime();
                setConverter(dimension, i, unit.asType(Time.class).getConverterTo(Units.MILLISECOND));
                if (AxisDirection.PAST.equals(axis.getDirection())) {
                    negate(i);
                }
                continue;
            }
            types[i] = TIME;
        // Fallthrough: formatted as number.
        }
        /*
             * Formatter for all other units. Do NOT set types[i] since it may have been set
             * to a non-zero value by previous case. If not, the default value (zero) is the
             * one we want.
             */
        formats[i] = getFormat(Number.class);
        if (unit != null) {
            if (units == null) {
                units = new Unit<?>[dimension];
            }
            units[i] = unit;
            final String symbol = getFormat(Unit.class).format(unit);
            if (!symbol.isEmpty()) {
                if (unitSymbols == null) {
                    unitSymbols = new String[dimension];
                }
                unitSymbols[i] = symbol;
            }
        }
    }
    // Assign only on success.
    this.types = types;
    this.formats = formats;
}
Also used : CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) Unit(javax.measure.Unit) Date(java.util.Date) TemporalCRS(org.opengis.referencing.crs.TemporalCRS) Format(java.text.Format) SimpleDateFormat(java.text.SimpleDateFormat) NumberFormat(java.text.NumberFormat) DateFormat(java.text.DateFormat) AngleFormat(org.apache.sis.measure.AngleFormat) CompoundFormat(org.apache.sis.io.CompoundFormat) DecimalFormat(java.text.DecimalFormat) Angle(org.apache.sis.measure.Angle) AxisDirection(org.opengis.referencing.cs.AxisDirection) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 30 with Unit

use of javax.measure.Unit in project sis by apache.

the class CoordinateFormat method parse.

/**
 * Parses a coordinate from the given character sequence.
 * This method presumes that the coordinate reference system is the {@linkplain #getDefaultCRS() default CRS}.
 * The parsing begins at the {@linkplain ParsePosition#getIndex() index} given by the {@code pos} argument.
 * If parsing succeeds, then the {@code pos} index is updated to the index after the last ordinate value and
 * the parsed coordinate is returned. Otherwise (if parsing fails), the {@code pos} index is left unchanged,
 * the {@code pos} {@linkplain ParsePosition#getErrorIndex() error index} is set to the index of the first
 * unparsable character and an exception is thrown with a similar {@linkplain ParseException#getErrorOffset()
 * error index}.
 *
 * @param  text  the character sequence for the coordinate to parse.
 * @param  pos   the index where to start the parsing.
 * @return the parsed coordinate (never {@code null}).
 * @throws ParseException if an error occurred while parsing the coordinate.
 */
@Override
public DirectPosition parse(final CharSequence text, final ParsePosition pos) throws ParseException {
    ArgumentChecks.ensureNonNull("text", text);
    ArgumentChecks.ensureNonNull("pos", pos);
    final int start = pos.getIndex();
    final int length = text.length();
    /*
         * The NumberFormat, DateFormat and AngleFormat work only on String values, not on CharSequence.
         * If the given text is not a String, we will convert an arbitrarily small section of the given
         * text. Note that this will require to adjust the ParsePosition indices.
         */
    final int offset;
    final String asString;
    final ParsePosition subPos;
    if (text instanceof String) {
        offset = 0;
        subPos = pos;
        asString = (String) text;
    } else {
        offset = start;
        subPos = new ParsePosition(0);
        asString = text.subSequence(start, Math.min(start + READ_AHEAD_LIMIT, length)).toString();
    }
    /*
         * The Format instances to be used for each ordinate values is determined by the default CRS.
         * If no such CRS has been specified, then we will parse everything as plain numbers.
         */
    if (lastCRS != defaultCRS) {
        initialize(defaultCRS);
    }
    final double[] ordinates;
    Format format;
    final Format[] formats = this.formats;
    if (formats != null) {
        format = null;
        ordinates = new double[formats.length];
    } else {
        format = getFormat(Number.class);
        ordinates = new double[DEFAULT_DIMENSION];
    }
    /*
         * For each ordinate value except the first one, we need to skip the separator.
         * If we do not find the separator, we may consider that we reached the coordinate
         * end ahead of time. We currently allow that only for coordinate without CRS.
         */
    for (int i = 0; i < ordinates.length; i++) {
        if (i != 0) {
            final int end = subPos.getIndex();
            int index = offset + end;
            while (!CharSequences.regionMatches(text, index, parseSeparator)) {
                if (index < length) {
                    final int c = Character.codePointAt(text, index);
                    if (Character.isSpaceChar(c)) {
                        index += Character.charCount(c);
                        continue;
                    }
                }
                if (formats == null) {
                    pos.setIndex(index);
                    return new GeneralDirectPosition(Arrays.copyOf(ordinates, i));
                }
                pos.setIndex(start);
                pos.setErrorIndex(index);
                throw new LocalizedParseException(getLocale(), Errors.Keys.UnexpectedCharactersAfter_2, new CharSequence[] { text.subSequence(start, end), CharSequences.token(text, index) }, index);
            }
            subPos.setIndex(index + parseSeparator.length() - offset);
        }
        /*
             * At this point 'subPos' is set to the beginning of the next ordinate to parse in 'asString'.
             * Parse the value as a number, angle or date, as determined from the coordinate system axis.
             */
        if (formats != null) {
            format = formats[i];
        }
        @SuppressWarnings("null") final Object object = format.parseObject(asString, subPos);
        if (object == null) {
            /*
                 * If we failed to parse, build an error message with the type that was expected for that ordinate.
                 * If the given CharSequence was not a String, we may need to update the error index since we tried
                 * to parse only a substring.
                 */
            Class<?> type = Number.class;
            if (types != null) {
                switch(types[i]) {
                    case LONGITUDE:
                        type = Longitude.class;
                        break;
                    case LATITUDE:
                        type = Latitude.class;
                        break;
                    case ANGLE:
                        type = Angle.class;
                        break;
                    case DATE:
                        type = Date.class;
                        break;
                }
            }
            pos.setIndex(start);
            if (subPos != pos) {
                pos.setErrorIndex(offset + subPos.getErrorIndex());
            }
            throw new LocalizedParseException(getLocale(), type, text, pos);
        }
        double value;
        if (object instanceof Angle) {
            value = ((Angle) object).degrees();
        } else if (object instanceof Date) {
            value = ((Date) object).getTime() - epochs[i];
        } else {
            value = ((Number) object).doubleValue();
        }
        /*
             * The conversions and sign reversal applied below shall be in exact reverse order than
             * in the 'format(…)' method. However we have one additional step compared to format(…):
             * the unit written after the ordinate value may not be the same than the unit declared
             * in the CRS axis, so we have to parse the unit and convert the value before to apply
             * the reverse of 'format(…)' steps.
             */
        if (units != null) {
            final Unit<?> target = units[i];
            if (target != null) {
                final int base = subPos.getIndex();
                int index = base;
                /*
                     * Skip whitespaces using Character.isSpaceChar(…), not Character.isWhitespace(…),
                     * because we need to skip also the non-breaking space (Characters.NO_BREAK_SPACE).
                     * If we can not parse the unit after those spaces, we will revert to the original
                     * position (absence of unit will not be considered an error).
                     */
                while (index < asString.length()) {
                    final int c = asString.codePointAt(index);
                    if (Character.isSpaceChar(c)) {
                        index += Character.charCount(c);
                        continue;
                    }
                    subPos.setIndex(index);
                    final Object unit = getFormat(Unit.class).parseObject(asString, subPos);
                    if (unit == null) {
                        subPos.setIndex(base);
                        subPos.setErrorIndex(-1);
                    } else
                        try {
                            value = ((Unit<?>) unit).getConverterToAny(target).convert(value);
                        } catch (IncommensurableException e) {
                            index += offset;
                            pos.setIndex(start);
                            pos.setErrorIndex(index);
                            throw (ParseException) new ParseException(e.getMessage(), index).initCause(e);
                        }
                    break;
                }
            }
        }
        if (toFormatUnit != null) {
            final UnitConverter c = toFormatUnit[i];
            if (c != null) {
                value = c.inverse().convert(value);
            }
        }
        if (isNegative(i)) {
            value = -value;
        }
        ordinates[i] = value;
    }
    final GeneralDirectPosition position = new GeneralDirectPosition(ordinates);
    position.setCoordinateReferenceSystem(defaultCRS);
    return position;
}
Also used : IncommensurableException(javax.measure.IncommensurableException) Unit(javax.measure.Unit) Date(java.util.Date) Format(java.text.Format) SimpleDateFormat(java.text.SimpleDateFormat) NumberFormat(java.text.NumberFormat) DateFormat(java.text.DateFormat) AngleFormat(org.apache.sis.measure.AngleFormat) CompoundFormat(org.apache.sis.io.CompoundFormat) DecimalFormat(java.text.DecimalFormat) LocalizedParseException(org.apache.sis.internal.util.LocalizedParseException) Angle(org.apache.sis.measure.Angle) UnitConverter(javax.measure.UnitConverter) ParseException(java.text.ParseException) LocalizedParseException(org.apache.sis.internal.util.LocalizedParseException) ParsePosition(java.text.ParsePosition)

Aggregations

Unit (javax.measure.Unit)52 AbstractUnit (tech.units.indriya.AbstractUnit)12 AbstractUnit (tec.uom.se.AbstractUnit)11 UnitConverter (javax.measure.UnitConverter)5 Test (org.junit.Test)5 CoordinateSystem (com.revolsys.geometry.cs.CoordinateSystem)4 ProjectedCoordinateSystem (com.revolsys.geometry.cs.ProjectedCoordinateSystem)4 BigDecimal (java.math.BigDecimal)4 Length (javax.measure.quantity.Length)4 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)4 GeographicCoordinateSystem (com.revolsys.geometry.cs.GeographicCoordinateSystem)3 Format (java.text.Format)3 NumberFormat (java.text.NumberFormat)3 IncommensurableException (javax.measure.IncommensurableException)3 Angle (javax.measure.quantity.Angle)3 TestUnit (javax.measure.test.TestUnit)3 Test (org.junit.jupiter.api.Test)3 IdentifiedObject (org.opengis.referencing.IdentifiedObject)3 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)3 ChainedCoordinatesOperation (com.revolsys.geometry.cs.projection.ChainedCoordinatesOperation)2