Java Code Examples for org.opengis.referencing.cs.CoordinateSystem#getAxis()

The following examples show how to use org.opengis.referencing.cs.CoordinateSystem#getAxis() . 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: GeometryUtils.java    From geowave with Apache License 2.0 6 votes vote down vote up
/**
 * @param val the value
 * @param crs
 * @param axis the coordinate axis
 * @return
 */
private static double clipRange(
    final double val,
    final CoordinateReferenceSystem crs,
    final int axis) {
  final CoordinateSystem coordinateSystem = crs.getCoordinateSystem();
  if (coordinateSystem.getDimension() > axis) {
    final CoordinateSystemAxis coordinateAxis = coordinateSystem.getAxis(axis);
    if (val < coordinateAxis.getMinimumValue()) {
      return coordinateAxis.getMinimumValue();
    } else if (val > coordinateAxis.getMaximumValue()) {
      return coordinateAxis.getMaximumValue();
    }
  }
  return val;
}
 
Example 2
Source File: TransformCommand.java    From sis with Apache License 2.0 6 votes vote down vote up
private void printAxes(final CoordinateSystem cs) {
    final int targetDim = cs.getDimension();
    for (int i=0; i<targetDim; i++) {
        if (i != 0) {
            out.print(',');
        }
        final CoordinateSystemAxis axis = cs.getAxis(i);
        String name =  axis.getName().getCode();
        name = Transliterator.DEFAULT.toShortAxisName(cs, axis.getDirection(), name);
        final String unit = axis.getUnit().toString();
        if (!unit.isEmpty()) {
            name = name + " (" + unit + ')';
        }
        printQuotedText(name, coordinateWidth, X364.FOREGROUND_CYAN);
    }
}
 
Example 3
Source File: DefaultGeographicCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a coordinate reference system of the same type than this CRS but with different axes.
 *
 * <h4>Special case</h4>
 * If the first axis is the longitude in the [-180 … +180]° range and the identifier is EPSG:4267,
 * EPSG:4269 or EPSG:4326, then this method magically add the CRS:27, CRS:83 or CRS:84 identifier.
 * Without this special case, the normal behavior would be no identifier. The expected behavior is
 * that {@code CommonCRS.WGS84.normalizedGeographic()} returns a CRS having the "CRS:84" identifier.
 */
@Override
final AbstractCRS createSameType(Map<String,?> properties, final CoordinateSystem cs) {
    final CoordinateSystemAxis axis = cs.getAxis(0);
    if (axis.getMinimumValue() == Longitude.MIN_VALUE &&
        axis.getMaximumValue() == Longitude.MAX_VALUE) // For excluding the AxesConvention.POSITIVE_RANGE case.
    {
        for (final ReferenceIdentifier identifier : super.getIdentifiers()) {
            if (EPSG.equals(identifier.getCodeSpace())) try {
                final int i = Arrays.binarySearch(EPSG_CODES, Short.parseShort(identifier.getCode()));
                if (i >= 0) {
                    final Map<String,Object> c = new HashMap<>(properties);
                    c.put(IDENTIFIERS_KEY, new ImmutableIdentifier(Citations.WMS, CRS, Short.toString(CRS_CODES[i])));
                    properties = c;
                }
            } catch (NumberFormatException e) {
                // Okay to igore, because it is not the purpose of this method to disallow non-numeric codes.
            }
        }
    }
    return new DefaultGeographicCRS(properties, super.getDatum(), (EllipsoidalCS) cs);
}
 
Example 4
Source File: WraparoundAdjustment.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the range (maximum - minimum) of the given axis if it has wraparound meaning,
 * or {@link Double#NaN} otherwise. This method implements a fallback for the longitude
 * axis if it does not declare the minimum and maximum values as expected.
 *
 * @param  cs         the coordinate system for which to get wraparound range.
 * @param  dimension  dimension of the axis to test.
 * @return the wraparound range, or {@link Double#NaN} if none.
 */
static double range(final CoordinateSystem cs, final int dimension) {
    final CoordinateSystemAxis axis = cs.getAxis(dimension);
    if (axis != null && RangeMeaning.WRAPAROUND.equals(axis.getRangeMeaning())) {
        double period = axis.getMaximumValue() - axis.getMinimumValue();
        if (period > 0 && period != Double.POSITIVE_INFINITY) {
            return period;
        }
        final AxisDirection dir = AxisDirections.absolute(axis.getDirection());
        if (AxisDirection.EAST.equals(dir) && cs instanceof EllipsoidalCS) {
            period = Longitude.MAX_VALUE - Longitude.MIN_VALUE;
            final Unit<?> unit = axis.getUnit();
            if (unit != null) {
                period = Units.DEGREE.getConverterTo(Units.ensureAngular(unit)).convert(period);
            }
            return period;
        }
    }
    return Double.NaN;
}
 
Example 5
Source File: AxisDirections.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the angular unit of the specified coordinate system.
 * The preference will be given to the longitude axis, if found.
 *
 * @param  cs        the coordinate system from which to get the angular unit, or {@code null}.
 * @param  fallback  the default unit to return if no angular unit is found.
 * @return the angular unit, of {@code unit} if no angular unit was found.
 *
 * @see org.apache.sis.internal.referencing.ReferencingUtilities#getUnit(CoordinateSystem)
 *
 * @since 0.6
 */
public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> fallback) {
    if (cs != null) {
        for (int i = cs.getDimension(); --i>=0;) {
            final CoordinateSystemAxis axis = cs.getAxis(i);
            if (axis != null) {                                                     // Paranoiac check.
                final Unit<?> candidate = axis.getUnit();
                if (Units.isAngular(candidate)) {
                    fallback = candidate.asType(Angle.class);
                    if (AxisDirection.EAST.equals(absolute(axis.getDirection()))) {
                        break;                                                      // Found the longitude axis.
                    }
                }
            }
        }
    }
    return fallback;
}
 
Example 6
Source File: GeoWaveRasterReader.java    From geowave with Apache License 2.0 5 votes vote down vote up
private static int indexOf(
    final CoordinateReferenceSystem crs,
    final Set<AxisDirection> direction) {
  final CoordinateSystem cs = crs.getCoordinateSystem();
  for (int index = 0; index < cs.getDimension(); index++) {
    final CoordinateSystemAxis axis = cs.getAxis(index);
    if (direction.contains(axis.getDirection())) {
      return index;
    }
  }
  return -1;
}
 
Example 7
Source File: DefaultCoordinateSystemAxis.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new {@code ORDER[…]} element for the given axis in the given coordinate system.
 * If this method does not found exactly one instance of the given axis in the given coordinate system,
 * then returns {@code null}. In the later case, it is caller's responsibility to declare the WKT as invalid.
 *
 * <p>This method is a little bit inefficient since the enclosing {@link AbstractCS#formatTo(Formatter)}
 * method already know this axis index. But there is currently no API in {@link Formatter} for carrying
 * this information, and we are a little bit reluctant to introduce such API since it would force us to
 * introduce lists in a model which is, for everything else, purely based on trees.</p>
 *
 * @se <a href="https://issues.apache.org/jira/browse/SIS-163">SIS-163</a>
 */
static Order create(final CoordinateSystem cs, final DefaultCoordinateSystemAxis axis) {
    Order order = null;
    final int dimension = cs.getDimension();
    for (int i=0; i<dimension;) {
        if (cs.getAxis(i++) == axis) {
            if (order == null) {
                order = new Order(i);
            } else {
                return null;
            }
        }
    }
    return order;
}
 
Example 8
Source File: Normalizer.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a coordinate system with the same axes than the given CS, except that the wraparound axes
 * are shifted to a range of positive values. This method can be used in order to shift between the
 * [-180 … +180]° and [0 … 360]° ranges of longitude values.
 *
 * <p>This method shifts the axis {@linkplain CoordinateSystemAxis#getMinimumValue() minimum} and
 * {@linkplain CoordinateSystemAxis#getMaximumValue() maximum} values by a multiple of half the range
 * (typically 180°). This method does not change the meaning of coordinate values. For example a longitude
 * of -60° still locate the same point in the old and the new coordinate system. But the preferred way to
 * locate that point become the 300° value if the longitude range has been shifted to positive values.</p>
 *
 * @return a coordinate system using the given kind of longitude range, or {@code null} if no change is needed.
 */
private static AbstractCS shiftAxisRange(final CoordinateSystem cs) {
    boolean changed = false;
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
    for (int i=0; i<axes.length; i++) {
        CoordinateSystemAxis axis = cs.getAxis(i);
        if (RangeMeaning.WRAPAROUND.equals(axis.getRangeMeaning())) {
            double min = axis.getMinimumValue();
            if (min < 0) {
                double max = axis.getMaximumValue();
                double offset = (max - min) / 2;
                offset *= Math.floor(min/offset + Numerics.COMPARISON_THRESHOLD);
                min -= offset;
                max -= offset;
                if (min < max) { // Paranoiac check, but also a way to filter NaN values when offset is infinite.
                    axis = forRange(axis, min, max);
                    changed = true;
                }
            }
        }
        axes[i] = axis;
    }
    if (!changed) {
        return null;
    }
    return castOrCopy(cs).createForAxes(IdentifiedObjects.getProperties(cs, EXCLUDES), axes);
}
 
Example 9
Source File: AbstractCS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the axes of the given coordinate system.
 */
private static CoordinateSystemAxis[] getAxes(final CoordinateSystem cs) {
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
    for (int i=0; i<axes.length; i++) {
        axes[i] = cs.getAxis(i);
    }
    return axes;
}
 
Example 10
Source File: AbstractDirectPosition.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Ensures that the position is contained in the coordinate system domain.
 * For each dimension, this method compares the coordinate values against the
 * limits of the coordinate system axis for that dimension.
 * If some coordinates 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> coordinates), 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> coordinates), 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 coordinate = 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 (coordinate < minimum) coordinate = minimum;
                else if (coordinate > maximum) coordinate = maximum;
                else continue;
            } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
                final double csSpan = maximum - minimum;
                final double shift  = Math.floor((coordinate - minimum) / csSpan) * csSpan;
                if (shift == 0) {
                    continue;
                }
                coordinate -= shift;
            }
            setOrdinate(i, coordinate);
            changed = true;
        }
    }
    return changed;
}
 
Example 11
Source File: AbstractEnvelope.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the axis of the given coordinate reference system for the given dimension,
 * or {@code null} if none.
 *
 * @param  crs        the envelope CRS, or {@code null}.
 * @param  dimension  the dimension for which to get the axis.
 * @return the axis at the given dimension, or {@code null}.
 */
static CoordinateSystemAxis getAxis(final CoordinateReferenceSystem crs, final int dimension) {
    if (crs != null) {
        final CoordinateSystem cs = crs.getCoordinateSystem();
        if (cs != null) {                                       // Paranoiac check (should never be null).
            return cs.getAxis(dimension);
        }
    }
    return null;
}
 
Example 12
Source File: AxisDirections.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
     * Returns the index of the first dimension in {@code cs} where axes are colinear with the {@code subCS} axes.
     * If no such dimension is found, returns -1. If more than one sequence of {@code cs} axes are colinear with
     * all {@code subCS} axes, then the following rules apply:
     *
     * <ol>
     *   <li>If a sequence of {@code cs} axes are equal to the {@code subCS} axes, that sequence has precedence.</li>
     *   <li>Otherwise if a sequence of {@code cs} axes have similar names than the {@code subCS} axes (as determined
     *       by {@linkplain org.apache.sis.referencing.IdentifiedObjects#isHeuristicMatchForName heuristic match},
     *       that sequence has precedence.</li>
     *   <li>Otherwise the index of the first sequence if returned, regardless axis names.</li>
     * </ol>
     *
     * Note that colinear axes are normally not allowed, except if the case of {@link org.opengis.referencing.crs.TemporalCRS}
     * when one time axis is the runtime (the date where a numerical model has been executed) and the other time axis is the
     * forecast time (the date at which a prevision is made).
     *
     * @param  cs     the coordinate system which contains all axes, or {@code null}.
     * @param  subCS  the coordinate system to search into {@code cs}.
     * @return the first dimension of a sequence of axes colinear with {@code subCS} axes, or {@code -1} if none.
     *
     * @since 0.5
     */
    public static int indexOfColinear(final CoordinateSystem cs, final CoordinateSystem subCS) {
        int fallback = -1;
        if (cs != null) {
            boolean fallbackMatches = false;
            final int subDim = subCS.getDimension();
            final int limit = cs.getDimension() - subDim;
next:       for (int i=0; i <= limit; i++) {
                boolean equal = true;
                boolean match = true;
                for (int j=0; j<subDim; j++) {
                    final CoordinateSystemAxis expected = subCS.getAxis(j);
                    final CoordinateSystemAxis actual = cs.getAxis(i + j);
                    if (!isColinear(expected.getDirection(), actual.getDirection())) {
                        continue next;
                    }
                    if (equal) {
                        equal = Utilities.deepEquals(expected, actual, ComparisonMode.BY_CONTRACT);
                        if (equal) continue;
                    }
                    if (match) {
                        match = NameToIdentifier.isHeuristicMatchForName(actual, expected.getName().getCode());
                    }
                }
                if (equal) {
                    return i;
                }
                if (fallback < 0 | (match & !fallbackMatches)) {
                    fallbackMatches = match;
                    fallback = i;
                }
            }
        }
        return fallback;
    }
 
Example 13
Source File: EPSGFactoryTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests creation of deprecated coordinate systems.
 *
 * @throws FactoryException if an error occurred while querying the factory.
 */
@Test
public void testDeprecatedCoordinateSystems() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    for (final Map.Entry<Integer,Integer> entry : EPSGDataAccess.deprecatedCS().entrySet()) {
        final CoordinateSystem expected = factory.createEllipsoidalCS(entry.getValue().toString());
        loggings.assertNoUnexpectedLog();
        final String code = entry.getKey().toString();
        final CoordinateSystem deprecated;
        try {
            deprecated = factory.createEllipsoidalCS(code);
        } catch (FactoryException e) {
            final String m = e.getMessage();
            if (m.contains("9115") || m.contains("9116") || m.contains("9117") ||
                m.contains("9118") || m.contains("9119") || m.contains("9120"))
            {
                // Unit "9116" to "9120" are known to be unsupported.
                continue;
            }
            throw e;
        }
        loggings.assertNextLogContains(code);
        final int dimension = expected.getDimension();
        assertEquals("dimension", dimension, deprecated.getDimension());
        for (int i=0; i<dimension; i++) {
            final CoordinateSystemAxis ref  = expected.getAxis(i);
            final CoordinateSystemAxis axis = deprecated.getAxis(i);
            assertEquals("name",         ref.getName(),                 axis.getName());
            assertEquals("alias",        ref.getAlias(),                axis.getAlias());
            assertEquals("direction",    ref.getDirection(),            axis.getDirection());
            assertEquals("rangeMeaning", ref.getRangeMeaning(),         axis.getRangeMeaning());
            assertEquals("unit",         ref.getUnit().getSystemUnit(), axis.getUnit().getSystemUnit());
        }
    }
}
 
Example 14
Source File: Angle.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * 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);
}
 
Example 15
Source File: GeneralEnvelope.java    From sis with Apache License 2.0 4 votes vote down vote up
/**
 * Normalizes only the dimensions returned by the given iterator, or all dimensions if the iterator is null.
 * This is used for normalizing the result of a coordinate operation where a wrap around axis does not
 * necessarily means that the coordinates need to be normalized along that axis.
 *
 * @param  cs          the coordinate system of this envelope CRS (as an argument because sometime already known).
 * @param  beginIndex  index of the first coordinate value in {@link #coordinates} array. Non-zero for sub-envelopes.
 * @param  count       number of coordinates, i.e. this envelope dimensions.
 * @param  dimensions  the dimensions to check for normalization, or {@code null} for all dimensions.
 * @return {@code true} if this envelope has been modified as a result of this method call.
 */
final boolean normalize(final CoordinateSystem cs, final int beginIndex, final int count, final Iterator<Integer> dimensions) {
    boolean changed = false;
    final int d = coordinates.length >>> 1;
    for (int j=0; j<count; j++) {
        final int i = (dimensions != null) ? dimensions.next() : j;
        final int iLower = beginIndex + i;
        final int iUpper = iLower + d;
        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 (coordinates[iLower] < minimum) {coordinates[iLower] = minimum; changed = true;}
            if (coordinates[iUpper] > maximum) {coordinates[iUpper] = maximum; changed = true;}
        } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
            final double csSpan = maximum - minimum;
            if (csSpan > 0 && csSpan < Double.POSITIVE_INFINITY) {
                double o1 = coordinates[iLower];
                double o2 = coordinates[iUpper];
                if (Math.abs(o2-o1) >= csSpan) {
                    /*
                     * If the range exceed the CS span, then we have to replace it by the
                     * full span, otherwise the range computed by the "else" block is too
                     * small. The full range will typically be [-180 … 180]°.  However we
                     * make a special case if the two bounds are multiple of the CS span,
                     * typically [0 … 360]°. In this case the [0 … -0]° range matches the
                     * original values and is understood by GeneralEnvelope as a range
                     * spanning all the world.
                     */
                    if (o1 != minimum || o2 != maximum) {
                        if ((o1 % csSpan) == 0 && (o2 % csSpan) == 0) {
                            coordinates[iLower] = +0.0;
                            coordinates[iUpper] = -0.0;
                        } else {
                            coordinates[iLower] = minimum;
                            coordinates[iUpper] = maximum;
                        }
                        changed = true;
                    }
                } else {
                    o1 = Math.floor((o1 - minimum) / csSpan) * csSpan;
                    o2 = Math.floor((o2 - minimum) / csSpan) * csSpan;
                    if (o1 != 0) {coordinates[iLower] -= o1; changed = true;}
                    if (o2 != 0) {coordinates[iUpper] -= o2; changed = true;}
                }
            }
        }
    }
    return changed;
}
 
Example 16
Source File: CoordinateSystems.java    From sis with Apache License 2.0 3 votes vote down vote up
/**
 * Returns the axis directions for the specified coordinate system.
 * This method guarantees that the returned array is non-null and does not contain any null direction.
 *
 * @param  cs  the coordinate system.
 * @return the axis directions for the specified coordinate system.
 * @throws NullArgumentException if {@code cs} is null, or one of its axes is null,
 *         or a value returned by {@link CoordinateSystemAxis#getDirection()} is null.
 *
 * @since 0.8
 */
public static AxisDirection[] getAxisDirections(final CoordinateSystem cs) {
    ArgumentChecks.ensureNonNull("cs", cs);
    final AxisDirection[] directions = new AxisDirection[cs.getDimension()];
    for (int i=0; i<directions.length; i++) {
        final CoordinateSystemAxis axis = cs.getAxis(i);
        ArgumentChecks.ensureNonNullElement("cs", i, cs);
        ArgumentChecks.ensureNonNullElement("cs[#].direction", i, directions[i] = axis.getDirection());
    }
    return directions;
}