Search in sources :

Example 16 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem in project sis by apache.

the class Angle method valueOf.

/**
 * Returns the angular value of the axis having the given direction.
 * This helper method is used for subclass constructors expecting a {@link DirectPosition} argument.
 *
 * @param  position  the position from which to get an angular value.
 * @param  positive  axis direction of positive values.
 * @param  negative  axis direction of negative values.
 * @return angular value in degrees.
 * @throws IllegalArgumentException if the given coordinate it not associated to a CRS,
 *         or if no axis oriented toward the given directions is found, or if that axis
 *         does not use {@linkplain Units#isAngular angular units}.
 */
static double valueOf(final DirectPosition position, final AxisDirection positive, final AxisDirection negative) {
    final CoordinateReferenceSystem crs = position.getCoordinateReferenceSystem();
    if (crs == null) {
        throw new IllegalArgumentException(Errors.format(Errors.Keys.UnspecifiedCRS));
    }
    final CoordinateSystem cs = crs.getCoordinateSystem();
    final int dimension = cs.getDimension();
    IncommensurableException cause = null;
    for (int i = 0; i < dimension; i++) {
        final CoordinateSystemAxis axis = cs.getAxis(i);
        final AxisDirection dir = axis.getDirection();
        final boolean isPositive = dir.equals(positive);
        if (isPositive || dir.equals(negative)) {
            double value = position.getOrdinate(i);
            if (!isPositive)
                value = -value;
            final Unit<?> unit = axis.getUnit();
            if (unit != Units.DEGREE)
                try {
                    value = unit.getConverterToAny(Units.DEGREE).convert(value);
                } catch (IncommensurableException e) {
                    cause = e;
                    break;
                }
            return value;
        }
    }
    throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalCRSType_1, Classes.getLeafInterfaces(crs.getClass(), CoordinateReferenceSystem.class)[0]), cause);
}
Also used : IncommensurableException(javax.measure.IncommensurableException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) AxisDirection(org.opengis.referencing.cs.AxisDirection) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 17 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem in project sis by apache.

the class WKTUtilities method suggestFractionDigits.

/**
 * Suggests an amount of fraction digits to use for formatting numbers in each column of the given sequence
 * of points. The number of fraction digits may be negative if we could round the numbers to 10, <i>etc</i>.
 *
 * @param  crs     the coordinate reference system for each points, or {@code null} if unknown.
 * @param  points  the sequence of points. It is not required that each point has the same dimension.
 * @return suggested amount of fraction digits as an array as long as the longest row.
 */
public static int[] suggestFractionDigits(final CoordinateReferenceSystem crs, final double[]... points) {
    final int[] fractionDigits = Numerics.suggestFractionDigits(points);
    final Ellipsoid ellipsoid = ReferencingUtilities.getEllipsoid(crs);
    if (ellipsoid != null) {
        /*
             * Use heuristic precisions for geodetic or projected CRS. We do not apply those heuristics
             * for other kind of CRS (e.g. engineering) because we do not know what could be the size
             * of the object attached to the CRS.
             */
        final CoordinateSystem cs = crs.getCoordinateSystem();
        final int dimension = Math.min(cs.getDimension(), fractionDigits.length);
        final double scale = Formulas.scaleComparedToEarth(ellipsoid);
        for (int i = 0; i < dimension; i++) {
            final Unit<?> unit = cs.getAxis(i).getUnit();
            double precision;
            if (Units.isLinear(unit)) {
                // In metres
                precision = Formulas.LINEAR_TOLERANCE * scale;
            } else if (Units.isAngular(unit)) {
                // In radians
                precision = Formulas.ANGULAR_TOLERANCE * (Math.PI / 180) * scale;
            } else if (Units.isTemporal(unit)) {
                // In seconds
                precision = Formulas.TEMPORAL_TOLERANCE;
            } else {
                continue;
            }
            // In units used by the coordinates.
            precision /= Units.toStandardUnit(unit);
            final int f = DecimalFunctions.fractionDigitsForDelta(precision, false);
            if (f > fractionDigits[i]) {
                // Use at least the heuristic precision.
                fractionDigits[i] = f;
            }
        }
    }
    return fractionDigits;
}
Also used : CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) DefaultEllipsoid(org.apache.sis.referencing.datum.DefaultEllipsoid) Ellipsoid(org.opengis.referencing.datum.Ellipsoid)

Example 18 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem in project sis by apache.

the class MathTransformContext method getMatrix.

/**
 * Returns the normalization or denormalization matrix.
 */
@Override
@SuppressWarnings("fallthrough")
public Matrix getMatrix(final MatrixRole role) throws FactoryException {
    final CoordinateSystem cs;
    boolean inverse = false;
    double rotation;
    switch(role) {
        default:
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "role", role));
        // Fall through
        case INVERSE_NORMALIZATION:
            inverse = true;
        case NORMALIZATION:
            rotation = sourceMeridian;
            cs = getSourceCS();
            break;
        // Fall through
        case INVERSE_DENORMALIZATION:
            inverse = true;
        case DENORMALIZATION:
            inverse = !inverse;
            rotation = targetMeridian;
            cs = getTargetCS();
            break;
    }
    Matrix matrix = super.getMatrix(role);
    if (rotation != 0) {
        if (inverse)
            rotation = -rotation;
        MatrixSIS cm = MatrixSIS.castOrCopy(matrix);
        if (cs instanceof CartesianCS) {
            rotation = Math.toRadians(rotation);
            final Matrix4 rot = new Matrix4();
            rot.m00 = rot.m11 = Math.cos(rotation);
            rot.m01 = -(rot.m10 = Math.sin(rotation));
            if (inverse) {
                // Apply the rotation after denormalization.
                matrix = Matrices.multiply(rot, cm);
            } else {
                // Apply the rotation before normalization.
                matrix = cm.multiply(rot);
            }
        } else if (cs == null || cs instanceof EllipsoidalCS || cs instanceof SphericalCS) {
            final Double value = rotation;
            if (inverse) {
                // Longitude is the first axis in normalized CS.
                cm.convertBefore(0, null, value);
            } else {
                cm.convertAfter(0, null, value);
            }
            matrix = cm;
        } else {
            throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getName()));
        }
    }
    return matrix;
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) SphericalCS(org.opengis.referencing.cs.SphericalCS) Matrix(org.opengis.referencing.operation.Matrix) FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS) Matrix4(org.apache.sis.referencing.operation.matrix.Matrix4)

Example 19 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem in project sis by apache.

the class AbstractDirectPosition method normalize.

/**
 * Ensures that the position is contained in the coordinate system domain.
 * For each dimension, this method compares the ordinate values against the
 * limits of the coordinate system axis for that dimension.
 * If some ordinates are out of range, then there is a choice depending on the
 * {@linkplain CoordinateSystemAxis#getRangeMeaning() axis range meaning}:
 *
 * <ul>
 *   <li>If {@link RangeMeaning#EXACT} (typically <em>latitudes</em> ordinates), then values
 *       greater than the {@linkplain CoordinateSystemAxis#getMaximumValue() axis maximal value}
 *       are replaced by the axis maximum, and values smaller than the
 *       {@linkplain CoordinateSystemAxis#getMinimumValue() axis minimal value}
 *       are replaced by the axis minimum.</li>
 *
 *   <li>If {@link RangeMeaning#WRAPAROUND} (typically <em>longitudes</em> ordinates), then
 *       a multiple of the axis range (e.g. 360° for longitudes) is added or subtracted.</li>
 * </ul>
 *
 * @return {@code true} if this position has been modified as a result of this method call,
 *         or {@code false} if no change has been done.
 *
 * @see GeneralEnvelope#normalize()
 */
public boolean normalize() {
    boolean changed = false;
    final CoordinateReferenceSystem crs = getCoordinateReferenceSystem();
    if (crs != null) {
        final int dimension = getDimension();
        final CoordinateSystem cs = crs.getCoordinateSystem();
        for (int i = 0; i < dimension; i++) {
            double ordinate = getOrdinate(i);
            final CoordinateSystemAxis axis = cs.getAxis(i);
            final double minimum = axis.getMinimumValue();
            final double maximum = axis.getMaximumValue();
            final RangeMeaning rm = axis.getRangeMeaning();
            if (RangeMeaning.EXACT.equals(rm)) {
                if (ordinate < minimum)
                    ordinate = minimum;
                else if (ordinate > maximum)
                    ordinate = maximum;
                else
                    continue;
            } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
                final double csSpan = maximum - minimum;
                final double shift = Math.floor((ordinate - minimum) / csSpan) * csSpan;
                if (shift == 0) {
                    continue;
                }
                ordinate -= shift;
            }
            setOrdinate(i, ordinate);
            changed = true;
        }
    }
    return changed;
}
Also used : RangeMeaning(org.opengis.referencing.cs.RangeMeaning) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 20 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem 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)

Aggregations

CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)43 Test (org.junit.Test)16 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)15 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)13 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)9 DependsOnMethod (org.apache.sis.test.DependsOnMethod)7 FactoryException (org.opengis.util.FactoryException)7 AxisDirection (org.opengis.referencing.cs.AxisDirection)6 CartesianCS (org.opengis.referencing.cs.CartesianCS)6 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)5 Convention (org.apache.sis.io.wkt.Convention)4 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)4 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)4 TransformException (org.opengis.referencing.operation.TransformException)4 Unit (javax.measure.Unit)3 IdentifiedObject (org.opengis.referencing.IdentifiedObject)3 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)3 GeodeticDatum (org.opengis.referencing.datum.GeodeticDatum)3 MathTransform (org.opengis.referencing.operation.MathTransform)3 NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)3