use of org.opengis.referencing.cs.CoordinateSystemAxis 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;
}
use of org.opengis.referencing.cs.CoordinateSystemAxis in project sis by apache.
the class ArrayEnvelope method getMaximum.
/**
* {@inheritDoc}
*/
@Override
public double getMaximum(final int dimension) throws IndexOutOfBoundsException {
ensureValidIndex(endIndex(), dimension);
final int i = dimension + beginIndex();
double upper = ordinates[i + (ordinates.length >>> 1)];
if (isNegative(upper - ordinates[i])) {
// Special handling for -0.0
final CoordinateSystemAxis axis = getAxis(crs, dimension);
upper = isWrapAround(axis) ? axis.getMaximumValue() : Double.NaN;
}
return upper;
}
use of org.opengis.referencing.cs.CoordinateSystemAxis in project sis by apache.
the class ArrayEnvelope method getMinimum.
/**
* {@inheritDoc}
*/
@Override
public double getMinimum(final int dimension) throws IndexOutOfBoundsException {
ensureValidIndex(endIndex(), dimension);
final int i = dimension + beginIndex();
double lower = ordinates[i];
if (isNegative(ordinates[i + (ordinates.length >>> 1)] - lower)) {
// Special handling for -0.0
final CoordinateSystemAxis axis = getAxis(crs, dimension);
lower = isWrapAround(axis) ? axis.getMinimumValue() : Double.NaN;
}
return lower;
}
use of org.opengis.referencing.cs.CoordinateSystemAxis 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;
}
use of org.opengis.referencing.cs.CoordinateSystemAxis in project sis by apache.
the class Envelope2D method getMaximum.
/**
* Returns the maximal ordinate along the specified dimension. This method handles
* anti-meridian spanning as documented in the {@link AbstractEnvelope#getMaximum(int)}
* method.
*
* @param dimension the dimension to query.
* @return the maximal ordinate value along the given dimension.
* @throws IndexOutOfBoundsException if the given index is out of bounds.
*/
@Override
public double getMaximum(final int dimension) throws IndexOutOfBoundsException {
final double value, span;
switch(dimension) {
case 0:
value = x;
span = width;
break;
case 1:
value = y;
span = height;
break;
default:
throw indexOutOfBounds(dimension);
}
if (isNegative(span)) {
// Special handling for -0.0
final CoordinateSystemAxis axis = getAxis(crs, dimension);
return isWrapAround(axis) ? axis.getMaximumValue() : NaN;
}
return value + span;
}
Aggregations