Search in sources :

Example 11 with EllipsoidalCS

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

the class EllipsoidalHeightCombiner method createCompoundCRS.

/**
 * Creates a compound CRS, but we special processing for (two-dimensional Geographic + ellipsoidal heights) tupples.
 * If any such tupple is found, a three-dimensional geographic CRS is created instead than the compound CRS.
 *
 * @param  properties  name and other properties to give to the new object.
 * @param  components  ordered array of {@code CoordinateReferenceSystem} objects.
 * @return the coordinate reference system for the given properties.
 * @throws FactoryException if the object creation failed.
 */
public final CoordinateReferenceSystem createCompoundCRS(final Map<String, ?> properties, CoordinateReferenceSystem... components) throws FactoryException {
    for (int i = 0; i < components.length; i++) {
        final CoordinateReferenceSystem vertical = components[i];
        if (vertical instanceof VerticalCRS) {
            final VerticalDatum datum = ((VerticalCRS) vertical).getDatum();
            if (datum != null && datum.getVerticalDatumType() == VerticalDatumTypes.ELLIPSOIDAL) {
                int axisPosition = 0;
                CoordinateSystem cs = null;
                CoordinateReferenceSystem crs = null;
                if (i == 0 || (cs = getCsIfHorizontal2D(crs = components[i - 1])) == null) {
                    /*
                         * GeographicCRS are normally before VerticalCRS. But Apache SIS is tolerant to the
                         * opposite order (note however that such ordering is illegal according ISO 19162).
                         */
                    if (i + 1 >= components.length || (cs = getCsIfHorizontal2D(crs = components[i + 1])) == null) {
                        continue;
                    }
                    axisPosition = 1;
                }
                /*
                     * At this point we have the horizontal and vertical components. The horizontal component
                     * begins at 'axisPosition', which is almost always zero. Create the three-dimensional CRS.
                     * If the result is the CRS to be returned directly by this method (components.length == 2),
                     * use the properties given in argument. Otherwise we need to use other properties; current
                     * implementation recycles the properties of the existing two-dimensional CRS.
                     */
                final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[3];
                axes[axisPosition++] = cs.getAxis(0);
                axes[axisPosition++] = cs.getAxis(1);
                axes[axisPosition %= 3] = vertical.getCoordinateSystem().getAxis(0);
                final ReferencingServices referencing = ReferencingServices.getInstance();
                final Map<String, ?> csProps = referencing.getProperties(cs, false);
                final Map<String, ?> crsProps = (components.length == 2) ? properties : referencing.getProperties(crs, false);
                if (crs instanceof GeodeticCRS) {
                    initialize(CS | CRS);
                    cs = csFactory.createEllipsoidalCS(csProps, axes[0], axes[1], axes[2]);
                    crs = crsFactory.createGeographicCRS(crsProps, ((GeodeticCRS) crs).getDatum(), (EllipsoidalCS) cs);
                } else {
                    initialize(CS | CRS | OPERATION);
                    final ProjectedCRS proj = (ProjectedCRS) crs;
                    GeographicCRS base = proj.getBaseCRS();
                    if (base.getCoordinateSystem().getDimension() == 2) {
                        base = (GeographicCRS) createCompoundCRS(referencing.getProperties(base, false), base, vertical);
                    }
                    /*
                         * In Apache SIS implementation, the Conversion contains the source and target CRS together with
                         * a MathTransform2D. We need to recreate the same conversion, but without CRS and MathTransform
                         * for letting SIS create or associate new ones, which will be three-dimensional now.
                         */
                    Conversion fromBase = proj.getConversionFromBase();
                    fromBase = opFactory.createDefiningConversion(referencing.getProperties(fromBase, true), fromBase.getMethod(), fromBase.getParameterValues());
                    cs = csFactory.createCartesianCS(csProps, axes[0], axes[1], axes[2]);
                    crs = crsFactory.createProjectedCRS(crsProps, base, fromBase, (CartesianCS) cs);
                }
                /*
                     * Remove the VerticalCRS and store the three-dimensional GeographicCRS in place of the previous
                     * two-dimensional GeographicCRS. Then let the loop continues in case there is other CRS to merge
                     * (should never happen, but we are paranoiac).
                     */
                components = ArraysExt.remove(components, i, 1);
                // GeographicCRS before VerticalCRS (usual case).
                if (axisPosition != 0)
                    i--;
                components[i] = crs;
            }
        }
    }
    switch(components.length) {
        case 0:
            return null;
        case 1:
            return components[0];
        default:
            initialize(CRS);
            return crsFactory.createCompoundCRS(properties, components);
    }
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) VerticalDatum(org.opengis.referencing.datum.VerticalDatum) Conversion(org.opengis.referencing.operation.Conversion) GeodeticCRS(org.opengis.referencing.crs.GeodeticCRS) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) VerticalCRS(org.opengis.referencing.crs.VerticalCRS) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) GeographicCRS(org.opengis.referencing.crs.GeographicCRS)

Example 12 with EllipsoidalCS

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

the class StandardDefinitionsTest method testCreateGeographicCRS.

/**
 * Compares the values created by {@code StandardDefinitions} against hard-coded constants.
 * This method tests the following methods:
 *
 * <ul>
 *   <li>{@link StandardDefinitions#createEllipsoid(short)}</li>
 *   <li>{@link StandardDefinitions#createGeodeticDatum(short, Ellipsoid, PrimeMeridian)}</li>
 *   <li>{@link StandardDefinitions#createGeographicCRS(short, GeodeticDatum, EllipsoidalCS)}</li>
 * </ul>
 *
 * The geodetic objects are compared against the {@link HardCodedCRS}, {@link HardCodedDatum} and
 * {@link GeodeticDatumMock} constants. Actually this is more a test of the above-cited constants
 * than a {@code StandardDefinitions} one - in case of test failure, any of those classes could be
 * at fault.
 */
@Test
@DependsOnMethod("testCreateAxis")
public void testCreateGeographicCRS() {
    final PrimeMeridian pm = StandardDefinitions.primeMeridian();
    final EllipsoidalCS cs = (EllipsoidalCS) StandardDefinitions.createCoordinateSystem((short) 6422);
    for (final CommonCRS e : CommonCRS.values()) {
        final Ellipsoid ellipsoid = StandardDefinitions.createEllipsoid(e.ellipsoid);
        switch(e) {
            case WGS84:
                compare(GeodeticDatumMock.WGS84.getEllipsoid(), ellipsoid);
                break;
            case WGS72:
                compare(GeodeticDatumMock.WGS72.getEllipsoid(), ellipsoid);
                break;
            case NAD83:
                compare(GeodeticDatumMock.NAD83.getEllipsoid(), ellipsoid);
                break;
            case NAD27:
                compare(GeodeticDatumMock.NAD27.getEllipsoid(), ellipsoid);
                break;
            case SPHERE:
                compare(GeodeticDatumMock.SPHERE.getEllipsoid(), ellipsoid);
                break;
        }
        final GeodeticDatum datum = StandardDefinitions.createGeodeticDatum(e.datum, ellipsoid, pm);
        switch(e) {
            case WGS84:
                compare(HardCodedDatum.WGS84, datum);
                break;
            case WGS72:
                compare(HardCodedDatum.WGS72, datum);
                break;
            case SPHERE:
                compare(HardCodedDatum.SPHERE, datum);
                break;
        }
        final GeographicCRS crs = StandardDefinitions.createGeographicCRS(e.geographic, datum, cs);
        Validators.validate(crs);
        switch(e) {
            case WGS84:
                compare(HardCodedCRS.WGS84, crs);
                break;
        }
        Validators.validate(crs);
    }
}
Also used : EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) GeodeticDatum(org.opengis.referencing.datum.GeodeticDatum) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) Ellipsoid(org.opengis.referencing.datum.Ellipsoid) PrimeMeridian(org.opengis.referencing.datum.PrimeMeridian) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 13 with EllipsoidalCS

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

the class CoordinateSystemsTest method testReplaceAxes.

/**
 * Tests {@link CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)}
 * without change of coordinate system type.
 */
@Test
public void testReplaceAxes() {
    final EllipsoidalCS sourceCS = HardCodedCS.GEODETIC_3D;
    // What we want to get.
    final EllipsoidalCS targetCS = HardCodedCS.ELLIPSOIDAL_gon;
    final CoordinateSystem actualCS = CoordinateSystems.replaceAxes(sourceCS, new AxisFilter() {

        @Override
        public boolean accept(final CoordinateSystemAxis axis) {
            return Units.isAngular(axis.getUnit());
        }

        @Override
        public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> unit) {
            if (Units.isAngular(unit)) {
                unit = Units.GRAD;
            }
            return unit;
        }
    });
    assertEqualsIgnoreMetadata(targetCS, actualCS);
}
Also used : CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) Unit(javax.measure.Unit) Test(org.junit.Test)

Example 14 with EllipsoidalCS

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

the class CoordinateSystemsTest method testReplaceAxesWithTypeChange.

/**
 * Tests {@link CoordinateSystems#replaceAxes(CoordinateSystem, AxisFilter)}
 * with a change of coordinate system type.
 */
@Test
@DependsOnMethod("testReplaceAxes")
public void testReplaceAxesWithTypeChange() {
    final EllipsoidalCS sourceCS = HardCodedCS.GEODETIC_3D;
    // What we want to get.
    final VerticalCS targetCS = HardCodedCS.ELLIPSOIDAL_HEIGHT;
    final CoordinateSystem actualCS = CoordinateSystems.replaceAxes(sourceCS, new AxisFilter() {

        @Override
        public boolean accept(final CoordinateSystemAxis axis) {
            return Units.isLinear(axis.getUnit());
        }
    });
    assertEqualsIgnoreMetadata(targetCS, actualCS);
}
Also used : VerticalCS(org.opengis.referencing.cs.VerticalCS) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 15 with EllipsoidalCS

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

the class DefaultMathTransformFactory method createCoordinateSystemChange.

/**
 * Creates a math transform that represent a change of coordinate system. If exactly one argument is
 * an {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS ellipsoidal coordinate systems},
 * then the {@code ellipsoid} argument is mandatory. In all other cases (including the case where both
 * coordinate systems are ellipsoidal), the ellipsoid argument is ignored and can be {@code null}.
 *
 * <div class="note"><b>Design note:</b>
 * this method does not accept separated ellipsoid arguments for {@code source} and {@code target} because
 * this method should not be used for datum shifts. If the two given coordinate systems are ellipsoidal,
 * then they are assumed to use the same ellipsoid. If different ellipsoids are desired, then a
 * {@linkplain #createParameterizedTransform parameterized transform} like <cite>"Molodensky"</cite>,
 * <cite>"Geocentric translations"</cite>, <cite>"Coordinate Frame Rotation"</cite> or
 * <cite>"Position Vector transformation"</cite> should be used instead.</div>
 *
 * @param  source     the source coordinate system.
 * @param  target     the target coordinate system.
 * @param  ellipsoid  the ellipsoid of {@code EllipsoidalCS}, or {@code null} if none.
 * @return a conversion from the given source to the given target coordinate system.
 * @throws FactoryException if the conversion can not be created.
 *
 * @since 0.8
 */
public MathTransform createCoordinateSystemChange(final CoordinateSystem source, final CoordinateSystem target, final Ellipsoid ellipsoid) throws FactoryException {
    ArgumentChecks.ensureNonNull("source", source);
    ArgumentChecks.ensureNonNull("target", target);
    if (ellipsoid != null) {
        final boolean isEllipsoidalSource = (source instanceof EllipsoidalCS);
        if (isEllipsoidalSource != (target instanceof EllipsoidalCS)) {
            /*
                 * For now we support only conversion between EllipsoidalCS and CartesianCS.
                 * But future Apache SIS versions could add support for conversions between
                 * EllipsoidalCS and SphericalCS or other coordinate systems.
                 */
            if ((isEllipsoidalSource ? target : source) instanceof CartesianCS) {
                final Context context = new Context();
                final EllipsoidalCS cs;
                final String operation;
                if (isEllipsoidalSource) {
                    operation = GeographicToGeocentric.NAME;
                    context.setSource(cs = (EllipsoidalCS) source, ellipsoid);
                    context.setTarget(target);
                } else {
                    operation = GeocentricToGeographic.NAME;
                    context.setSource(source);
                    context.setTarget(cs = (EllipsoidalCS) target, ellipsoid);
                }
                final ParameterValueGroup pg = getDefaultParameters(operation);
                // Apache SIS specific parameter.
                if (cs.getDimension() < 3)
                    pg.parameter("dim").setValue(2);
                return createParameterizedTransform(pg, context);
            }
        }
    }
    return CoordinateSystemTransform.create(this, source, target);
// No need to use unique(…) here.
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) DefaultParameterValueGroup(org.apache.sis.parameter.DefaultParameterValueGroup) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS)

Aggregations

EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)16 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)9 CartesianCS (org.opengis.referencing.cs.CartesianCS)7 Test (org.junit.Test)5 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)5 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)5 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)4 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)4 GeodeticDatum (org.opengis.referencing.datum.GeodeticDatum)4 DependsOnMethod (org.apache.sis.test.DependsOnMethod)3 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)3 SphericalCS (org.opengis.referencing.cs.SphericalCS)3 PrimeMeridian (org.opengis.referencing.datum.PrimeMeridian)3 Unit (javax.measure.Unit)2 Angle (javax.measure.quantity.Angle)2 BursaWolfParameters (org.apache.sis.referencing.datum.BursaWolfParameters)2 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)2 IdentifiedObject (org.opengis.referencing.IdentifiedObject)2 EngineeringCRS (org.opengis.referencing.crs.EngineeringCRS)2 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)2