use of org.opengis.referencing.cs.SphericalCS 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;
}
use of org.opengis.referencing.cs.SphericalCS in project sis by apache.
the class SubTypes method castOrCopy.
/**
* Returns a SIS implementation for the given coordinate reference system.
*
* @see AbstractCRS#castOrCopy(CoordinateReferenceSystem)
*/
static AbstractCRS castOrCopy(final CoordinateReferenceSystem object) {
if (object instanceof DerivedCRS) {
return DefaultDerivedCRS.castOrCopy((DerivedCRS) object);
}
if (object instanceof ProjectedCRS) {
return DefaultProjectedCRS.castOrCopy((ProjectedCRS) object);
}
if (object instanceof GeodeticCRS) {
if (object instanceof GeographicCRS) {
return DefaultGeographicCRS.castOrCopy((GeographicCRS) object);
}
if (object instanceof GeocentricCRS) {
return DefaultGeocentricCRS.castOrCopy((GeocentricCRS) object);
}
/*
* The GeographicCRS and GeocentricCRS types are not part of ISO 19111.
* ISO uses a single type, GeodeticCRS, for both of them and infer the
* geographic or geocentric type from the coordinate system. We do this
* check here for instantiating the most appropriate SIS type, but only
* if we need to create a new object anyway (see below for rational).
*/
if (object instanceof DefaultGeodeticCRS) {
/*
* Result of XML unmarshalling — keep as-is. We avoid creating a new object because it
* would break object identities specified in GML document by the xlink:href attribute.
* However we may revisit this policy in the future. See SC_CRS.setElement(AbstractCRS).
*/
return (DefaultGeodeticCRS) object;
}
final Map<String, ?> properties = IdentifiedObjects.getProperties(object);
final GeodeticDatum datum = ((GeodeticCRS) object).getDatum();
final CoordinateSystem cs = object.getCoordinateSystem();
if (cs instanceof EllipsoidalCS) {
return new DefaultGeographicCRS(properties, datum, (EllipsoidalCS) cs);
}
if (cs instanceof SphericalCS) {
return new DefaultGeocentricCRS(properties, datum, (SphericalCS) cs);
}
if (cs instanceof CartesianCS) {
return new DefaultGeocentricCRS(properties, datum, (CartesianCS) cs);
}
}
if (object instanceof VerticalCRS) {
return DefaultVerticalCRS.castOrCopy((VerticalCRS) object);
}
if (object instanceof TemporalCRS) {
return DefaultTemporalCRS.castOrCopy((TemporalCRS) object);
}
if (object instanceof EngineeringCRS) {
return DefaultEngineeringCRS.castOrCopy((EngineeringCRS) object);
}
if (object instanceof ImageCRS) {
return DefaultImageCRS.castOrCopy((ImageCRS) object);
}
if (object instanceof CompoundCRS) {
return DefaultCompoundCRS.castOrCopy((CompoundCRS) object);
}
/*
* Intentionally check for AbstractCRS after the interfaces because user may have defined his own
* subclass implementing the interface. If we were checking for AbstractCRS before the interfaces,
* the returned instance could have been a user subclass without the JAXB annotations required
* for XML marshalling.
*/
if (object == null || object instanceof AbstractCRS) {
return (AbstractCRS) object;
}
return new AbstractCRS(object);
}
use of org.opengis.referencing.cs.SphericalCS in project sis by apache.
the class Normalizer method normalize.
/**
* Optionally normalizes and reorders the axes in an attempt to get a right-handed system.
* If no axis change is needed, then this method returns {@code null}.
*
* @param cs the coordinate system to normalize.
* @param changes the change to apply on axis direction and units.
* @param reorder {@code true} for reordering the axis for a right-handed coordinate system.
* @return the normalized coordinate system, or {@code null} if no normalization is needed.
*/
static AbstractCS normalize(final CoordinateSystem cs, final AxisFilter changes, final boolean reorder) {
boolean changed = false;
final int dimension = cs.getDimension();
CoordinateSystemAxis[] axes = new CoordinateSystemAxis[dimension];
int n = 0;
for (int i = 0; i < dimension; i++) {
CoordinateSystemAxis axis = cs.getAxis(i);
if (changes != null) {
if (!changes.accept(axis)) {
continue;
}
changed |= (axis != (axis = normalize(axis, changes)));
}
axes[n++] = axis;
}
axes = ArraysExt.resize(axes, n);
/*
* Sort the axes in an attempt to create a right-handed system.
* If nothing changed, return the given Coordinate System as-is.
*/
if (reorder) {
int angularUnitOrder = 0;
if (// (λ,φ,h) order
cs instanceof EllipsoidalCS || cs instanceof SphericalCS)
// (λ,φ,h) order
angularUnitOrder = -1;
else // (r,θ) order
if (cs instanceof CylindricalCS || cs instanceof PolarCS)
angularUnitOrder = +1;
changed |= sort(axes, angularUnitOrder);
if (angularUnitOrder == 1) {
/*
* Change (r,z,θ) to (r,θ,z) order in CylindricalCS. The check on unit of
* measurements should be always true, but we verify as a paranoiac check.
*/
if (axes.length == 3 && isLengthAndAngle(axes, 1)) {
ArraysExt.swap(axes, 1, 2);
}
/*
* If we were not allowed to normalize the axis direction, we may have a
* left-handed coordinate system here. If so, make it right-handed.
*/
if (AxisDirections.CLOCKWISE.equals(axes[1].getDirection()) && isLengthAndAngle(axes, 0)) {
ArraysExt.swap(axes, 0, 1);
}
}
}
if (!changed && n == dimension) {
return null;
}
/*
* Create a new coordinate system of the same type than the given one, but with the given axes.
* We need to change the Coordinate System name, since it is likely to not be valid anymore.
*/
final AbstractCS impl = castOrCopy(cs);
final StringBuilder buffer = (StringBuilder) CharSequences.camelCaseToSentence(impl.getInterface().getSimpleName());
return impl.createForAxes(singletonMap(AbstractCS.NAME_KEY, AxisDirections.appendTo(buffer, axes)), axes);
}
use of org.opengis.referencing.cs.SphericalCS in project sis by apache.
the class CoordinateSystemTransform method create.
/**
* Implementation of {@link DefaultMathTransformFactory#createCoordinateSystemChange(CoordinateSystem,
* CoordinateSystem, Ellipsoid)}, defined here for reducing the {@code DefaultMathTransformFactory}
* weight in the common case where the conversions handled by this class are not needed.
*/
static MathTransform create(final MathTransformFactory factory, final CoordinateSystem source, final CoordinateSystem target) throws FactoryException {
int passthrough = 0;
CoordinateSystemTransform kernel = null;
if (source instanceof CartesianCS) {
if (target instanceof SphericalCS) {
kernel = CartesianToSpherical.INSTANCE;
} else if (target instanceof PolarCS) {
kernel = CartesianToPolar.INSTANCE;
} else if (target instanceof CylindricalCS) {
kernel = CartesianToPolar.INSTANCE;
passthrough = 1;
}
} else if (target instanceof CartesianCS) {
if (source instanceof SphericalCS) {
kernel = SphericalToCartesian.INSTANCE;
} else if (source instanceof PolarCS) {
kernel = PolarToCartesian.INSTANCE;
} else if (source instanceof CylindricalCS) {
kernel = PolarToCartesian.INSTANCE;
passthrough = 1;
}
}
Exception cause = null;
try {
if (kernel == null) {
return factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(source, target));
} else if (source.getDimension() == kernel.getSourceDimensions() + passthrough && target.getDimension() == kernel.getTargetDimensions() + passthrough) {
final MathTransform tr = (passthrough == 0) ? kernel.completeTransform(factory) : kernel.passthrough(factory);
final MathTransform before = factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(source, CoordinateSystems.replaceAxes(source, AxesConvention.NORMALIZED)));
final MathTransform after = factory.createAffineTransform(CoordinateSystems.swapAndScaleAxes(CoordinateSystems.replaceAxes(target, AxesConvention.NORMALIZED), target));
return factory.createConcatenatedTransform(before, factory.createConcatenatedTransform(tr, after));
}
} catch (IllegalArgumentException | IncommensurableException e) {
cause = e;
}
throw new OperationNotFoundException(Resources.format(Resources.Keys.CoordinateOperationNotFound_2, WKTUtilities.toType(CoordinateSystem.class, source.getClass()), WKTUtilities.toType(CoordinateSystem.class, target.getClass())), cause);
}
Aggregations