Search in sources :

Example 1 with SphericalCS

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;
}
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 2 with SphericalCS

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);
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) EngineeringCRS(org.opengis.referencing.crs.EngineeringCRS) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) DerivedCRS(org.opengis.referencing.crs.DerivedCRS) CompoundCRS(org.opengis.referencing.crs.CompoundCRS) GeodeticDatum(org.opengis.referencing.datum.GeodeticDatum) GeodeticCRS(org.opengis.referencing.crs.GeodeticCRS) SphericalCS(org.opengis.referencing.cs.SphericalCS) TemporalCRS(org.opengis.referencing.crs.TemporalCRS) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) ImageCRS(org.opengis.referencing.crs.ImageCRS) VerticalCRS(org.opengis.referencing.crs.VerticalCRS) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) GeocentricCRS(org.opengis.referencing.crs.GeocentricCRS)

Example 3 with SphericalCS

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);
}
Also used : SphericalCS(org.opengis.referencing.cs.SphericalCS) PolarCS(org.opengis.referencing.cs.PolarCS) CylindricalCS(org.opengis.referencing.cs.CylindricalCS) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS)

Example 4 with SphericalCS

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);
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) SphericalCS(org.opengis.referencing.cs.SphericalCS) PolarCS(org.opengis.referencing.cs.PolarCS) CylindricalCS(org.opengis.referencing.cs.CylindricalCS) OperationNotFoundException(org.opengis.referencing.operation.OperationNotFoundException) MathTransform(org.opengis.referencing.operation.MathTransform) IncommensurableException(javax.measure.IncommensurableException) OperationNotFoundException(org.opengis.referencing.operation.OperationNotFoundException) IncommensurableException(javax.measure.IncommensurableException) FactoryException(org.opengis.util.FactoryException)

Aggregations

SphericalCS (org.opengis.referencing.cs.SphericalCS)4 CartesianCS (org.opengis.referencing.cs.CartesianCS)3 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)3 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)2 CylindricalCS (org.opengis.referencing.cs.CylindricalCS)2 PolarCS (org.opengis.referencing.cs.PolarCS)2 FactoryException (org.opengis.util.FactoryException)2 IncommensurableException (javax.measure.IncommensurableException)1 Matrix4 (org.apache.sis.referencing.operation.matrix.Matrix4)1 MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)1 CompoundCRS (org.opengis.referencing.crs.CompoundCRS)1 DerivedCRS (org.opengis.referencing.crs.DerivedCRS)1 EngineeringCRS (org.opengis.referencing.crs.EngineeringCRS)1 GeocentricCRS (org.opengis.referencing.crs.GeocentricCRS)1 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)1 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)1 ImageCRS (org.opengis.referencing.crs.ImageCRS)1 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)1 TemporalCRS (org.opengis.referencing.crs.TemporalCRS)1 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)1