Search in sources :

Example 11 with AxisDirection

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

the class Matrices method createTransform.

/**
 * Implementation of {@code createTransform(…)} public methods expecting envelopes and/or axis directions.
 * Argument validity shall be verified by the caller.
 *
 * @param useEnvelopes {@code true} if source and destination envelopes shall be taken in account.
 *        If {@code false}, then source and destination envelopes will be ignored and can be null.
 */
@SuppressWarnings("null")
private static MatrixSIS createTransform(final Envelope srcEnvelope, final AxisDirection[] srcAxes, final Envelope dstEnvelope, final AxisDirection[] dstAxes, final boolean useEnvelopes) {
    final DirectPosition dstCorner, srcCorner, srcOppositeCorner;
    if (useEnvelopes) {
        dstCorner = dstEnvelope.getLowerCorner();
        srcCorner = srcEnvelope.getLowerCorner();
        srcOppositeCorner = srcEnvelope.getUpperCorner();
    } else {
        dstCorner = srcCorner = srcOppositeCorner = null;
    }
    /*
         * Unconditionally create extended precision matrix even if standard precision would be
         * enough because callers in other package may perform additional arithmetic operations
         * on it (for example org.apache.sis.referencing.cs.CoordinateSystems.swapAndScaleAxes).
         */
    final MatrixSIS matrix = new GeneralMatrix(dstAxes.length + 1, srcAxes.length + 1, false, 2);
    /*
         * Maps source axes to destination axes. If no axis is moved (for example if the user
         * want to transform (NORTH,EAST) to (SOUTH,EAST)), then source and destination index
         * will be equal.   If some axes are moved (for example if the user want to transform
         * (NORTH,EAST) to (EAST,NORTH)), then ordinates at index {@code srcIndex} will have
         * to be moved at index {@code dstIndex}.
         */
    for (int dstIndex = 0; dstIndex < dstAxes.length; dstIndex++) {
        boolean hasFound = false;
        final AxisDirection dstDir = dstAxes[dstIndex];
        final AxisDirection search = AxisDirections.absolute(dstDir);
        for (int srcIndex = 0; srcIndex < srcAxes.length; srcIndex++) {
            final AxisDirection srcDir = srcAxes[srcIndex];
            if (search.equals(AxisDirections.absolute(srcDir))) {
                if (hasFound) {
                    throw new IllegalArgumentException(Resources.format(Resources.Keys.ColinearAxisDirections_2, srcDir, dstDir));
                }
                hasFound = true;
                /*
                     * Set the matrix elements. Some matrix elements will never be set.
                     * They will be left to zero, which is their desired value.
                     */
                final boolean same = srcDir.equals(dstDir);
                if (useEnvelopes) {
                    /*
                         * See the comment in transform(Envelope, Envelope) for an explanation about why
                         * we use the lower/upper corners instead than getMinimum()/getMaximum() methods.
                         */
                    final DoubleDouble scale = new DoubleDouble(same ? +1 : -1, 0);
                    scale.multiply(dstEnvelope.getSpan(dstIndex));
                    scale.divide(srcEnvelope.getSpan(srcIndex));
                    final DoubleDouble translate = new DoubleDouble(scale);
                    translate.multiply((same ? srcCorner : srcOppositeCorner).getOrdinate(srcIndex));
                    translate.negate();
                    translate.add(dstCorner.getOrdinate(dstIndex));
                    matrix.setNumber(dstIndex, srcIndex, scale);
                    matrix.setNumber(dstIndex, srcAxes.length, translate);
                } else {
                    matrix.setElement(dstIndex, srcIndex, same ? +1 : -1);
                }
            }
        }
        if (!hasFound) {
            throw new IllegalArgumentException(Resources.format(Resources.Keys.CanNotMapAxisToDirection_1, dstAxes[dstIndex]));
        }
    }
    matrix.setElement(dstAxes.length, srcAxes.length, 1);
    return matrix;
}
Also used : DirectPosition(org.opengis.geometry.DirectPosition) AxisDirection(org.opengis.referencing.cs.AxisDirection) DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Example 12 with AxisDirection

use of org.opengis.referencing.cs.AxisDirection in project hale by halestudio.

the class WindingOrder method isCRSFlip.

/**
 * To determine axis of given CRS is flip or not
 *
 * @param crs the CRS
 * @return true, if CRS is flip, else false
 */
public static boolean isCRSFlip(CoordinateReferenceSystem crs) {
    // get number of dimensions and it should be two
    if (crs.getCoordinateSystem().getDimension() == 2) {
        AxisDirection axis1 = crs.getCoordinateSystem().getAxis(0).getDirection();
        AxisDirection axis2 = crs.getCoordinateSystem().getAxis(1).getDirection();
        // check if direction is flip?
        if (axis1.equals(AxisDirection.EAST) || axis1.equals(AxisDirection.WEST)) {
            if (axis1.equals(AxisDirection.EAST) && (axis2.equals(AxisDirection.SOUTH) || axis2.equals(AxisDirection.DOWN))) {
                return true;
            } else if (axis1.equals(AxisDirection.WEST) && (axis2.equals(AxisDirection.NORTH) || axis2.equals(AxisDirection.UP))) {
                return true;
            }
        } else {
            // Check if order of axis flip?
            if ((axis1.equals(AxisDirection.SOUTH) || axis1.equals(AxisDirection.DOWN)) && axis2.equals(AxisDirection.WEST)) {
                return true;
            } else if ((axis1.equals(AxisDirection.NORTH) || axis1.equals(AxisDirection.UP)) && axis2.equals(AxisDirection.EAST)) {
                return true;
            }
        }
    }
    // if not any case return false above.
    return false;
}
Also used : AxisDirection(org.opengis.referencing.cs.AxisDirection)

Example 13 with AxisDirection

use of org.opengis.referencing.cs.AxisDirection 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 14 with AxisDirection

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

the class StandardDefinitions method createAxis.

/**
 * Creates an axis from hard-coded values for the given code.
 *
 * @param  code  the EPSG code.
 * @return the coordinate system axis for the given code.
 */
static CoordinateSystemAxis createAxis(final short code) {
    final String name, abrv;
    Unit<?> unit = Units.METRE;
    double min = Double.NEGATIVE_INFINITY;
    double max = Double.POSITIVE_INFINITY;
    RangeMeaning rm = null;
    final AxisDirection dir;
    switch(code) {
        case 1:
            name = "Easting";
            abrv = "E";
            dir = AxisDirection.EAST;
            break;
        case 2:
            name = "Northing";
            abrv = "N";
            dir = AxisDirection.NORTH;
            break;
        case 60:
            name = "Spherical latitude";
            // See HardCodedAxes.SPHERICAL_LATITUDE in tests.
            abrv = "φ′";
            unit = Units.DEGREE;
            dir = AxisDirection.NORTH;
            min = Latitude.MIN_VALUE;
            max = Latitude.MAX_VALUE;
            rm = RangeMeaning.EXACT;
            break;
        case 61:
            name = "Spherical longitude";
            // See HardCodedAxes.SPHERICAL_LONGITUDE in tests.
            abrv = "θ";
            unit = Units.DEGREE;
            dir = AxisDirection.EAST;
            min = Longitude.MIN_VALUE;
            max = Longitude.MAX_VALUE;
            rm = RangeMeaning.WRAPAROUND;
            break;
        case 62:
            name = "Geocentric radius";
            // See HardCodedAxes.GEOCENTRIC_RADIUS in tests.
            abrv = "R";
            dir = AxisDirection.UP;
            rm = RangeMeaning.EXACT;
            min = 0;
            break;
        // Used in Ellipsoidal 3D.
        case 108:
        case 106:
            name = AxisNames.GEODETIC_LATITUDE;
            abrv = "φ";
            unit = Units.DEGREE;
            dir = AxisDirection.NORTH;
            min = Latitude.MIN_VALUE;
            max = Latitude.MAX_VALUE;
            rm = RangeMeaning.EXACT;
            break;
        // Used in Ellipsoidal 3D.
        case 109:
        case 107:
            name = AxisNames.GEODETIC_LONGITUDE;
            abrv = "λ";
            unit = Units.DEGREE;
            dir = AxisDirection.EAST;
            min = Longitude.MIN_VALUE;
            max = Longitude.MAX_VALUE;
            rm = RangeMeaning.WRAPAROUND;
            break;
        case 110:
            name = AxisNames.ELLIPSOIDAL_HEIGHT;
            abrv = "h";
            dir = AxisDirection.UP;
            break;
        case 114:
            name = AxisNames.GRAVITY_RELATED_HEIGHT;
            abrv = "H";
            dir = AxisDirection.UP;
            break;
        case 113:
            name = AxisNames.DEPTH;
            abrv = "D";
            dir = AxisDirection.DOWN;
            break;
        case 115:
            name = AxisNames.GEOCENTRIC_X;
            abrv = "X";
            dir = AxisDirection.GEOCENTRIC_X;
            break;
        case 116:
            name = AxisNames.GEOCENTRIC_Y;
            abrv = "Y";
            dir = AxisDirection.GEOCENTRIC_Y;
            break;
        case 117:
            name = AxisNames.GEOCENTRIC_Z;
            abrv = "Z";
            dir = AxisDirection.GEOCENTRIC_Z;
            break;
        // Actually no axis allocated by EPSG here, but createCoordinateSystem(1027) needs this number.
        case 1057:
        case 1056:
            name = "Easting";
            abrv = "E";
            dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 90);
            break;
        case 1058:
            name = "Northing";
            abrv = "N";
            dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 0);
            break;
        case 1065:
            name = "Easting";
            abrv = "E";
            dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 90);
            break;
        case 1066:
            name = "Northing";
            abrv = "N";
            dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 180);
            break;
        default:
            throw new AssertionError(code);
    }
    final Map<String, Object> properties = properties(code, name, null, false);
    properties.put(DefaultCoordinateSystemAxis.MINIMUM_VALUE_KEY, min);
    properties.put(DefaultCoordinateSystemAxis.MAXIMUM_VALUE_KEY, max);
    properties.put(DefaultCoordinateSystemAxis.RANGE_MEANING_KEY, rm);
    return new DefaultCoordinateSystemAxis(properties, abrv, dir, unit);
}
Also used : RangeMeaning(org.opengis.referencing.cs.RangeMeaning) AxisDirection(org.opengis.referencing.cs.AxisDirection) DefaultCoordinateSystemAxis(org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis)

Example 15 with AxisDirection

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

the class CoordinateSystems method parseAxisDirection.

/**
 * Returns an axis direction code from the given direction name.
 * Names are case-insensitive. They may be:
 *
 * <ul>
 *   <li>Cardinal directions like <cite>"north"</cite> and <cite>"east"</cite>.</li>
 *   <li>Inter-cardinal directions <cite>"north-east"</cite> and <cite>"south-south-east"</cite>,
 *       using either {@code '-'}, {@code '_'} or spaces as separator between the cardinal points.</li>
 *   <li>Directions from a pole like <cite>"South along 180 deg"</cite> and <cite>"South along 90° East"</cite>,
 *       using either the {@code "deg"} or {@code "°"} symbol. Note that the meridian is not necessarily relative
 *       to Greenwich (see {@link #directionAlongMeridian directionAlongMeridian(…)} for more information).</li>
 * </ul>
 *
 * @param  name  the direction name (e.g. "north", "north-east", <i>etc.</i>).
 * @return the axis direction for the given name.
 * @throws IllegalArgumentException if the given name is not a known axis direction.
 */
public static AxisDirection parseAxisDirection(String name) throws IllegalArgumentException {
    ensureNonNull("name", name);
    name = CharSequences.trimWhitespaces(name);
    AxisDirection candidate = AxisDirections.valueOf(name);
    if (candidate != null) {
        return candidate;
    }
    /*
         * Some EPSG direction names are of the form "South along 180 deg". We check that the
         * direction before "along" is valid and create a new axis direction if it is. We can
         * not just replace "South along 180 deg" by "South" because the same CRS may use two
         * of those directions. For example EPSG:32661 has the following axis direction:
         *
         * South along 180 deg
         * South along 90 deg East
         */
    final DirectionAlongMeridian meridian = DirectionAlongMeridian.parse(name);
    if (meridian != null) {
        candidate = meridian.getDirection();
        assert candidate == AxisDirections.valueOf(meridian.toString());
        return candidate;
    }
    throw new IllegalArgumentException(Resources.format(Resources.Keys.UnknownAxisDirection_1, name));
}
Also used : AxisDirection(org.opengis.referencing.cs.AxisDirection)

Aggregations

AxisDirection (org.opengis.referencing.cs.AxisDirection)22 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)6 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)4 IncommensurableException (javax.measure.IncommensurableException)3 Test (org.junit.Test)3 Unit (javax.measure.Unit)2 DoubleDouble (org.apache.sis.internal.util.DoubleDouble)2 Angle (org.apache.sis.measure.Angle)2 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)2 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)2 Field (java.lang.reflect.Field)1 DateFormat (java.text.DateFormat)1 DecimalFormat (java.text.DecimalFormat)1 Format (java.text.Format)1 NumberFormat (java.text.NumberFormat)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Matcher (java.util.regex.Matcher)1