Search in sources :

Example 11 with VerticalCRS

use of org.opengis.referencing.crs.VerticalCRS 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 VerticalCRS

use of org.opengis.referencing.crs.VerticalCRS in project sis by apache.

the class ServicesForMetadata method setBounds.

/**
 * Sets a vertical extent with the value inferred from the given envelope.
 * Only the vertical ordinates are extracted; all other ordinates are ignored.
 *
 * @param  envelope  the source envelope.
 * @param  target    the target vertical extent where to store envelope information.
 * @throws TransformException if no vertical component can be extracted from the given envelope.
 */
@Override
public void setBounds(final Envelope envelope, final DefaultVerticalExtent target) throws TransformException {
    final CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
    final VerticalCRS verticalCRS = CRS.getVerticalComponent(crs, true);
    if (verticalCRS == null && envelope.getDimension() != 1) {
        throw new TransformException(dimensionNotFound(Resources.Keys.MissingVerticalDimension_1, crs));
    }
    setVerticalExtent(envelope, target, crs, verticalCRS);
}
Also used : VerticalCRS(org.opengis.referencing.crs.VerticalCRS) TransformException(org.opengis.referencing.operation.TransformException) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 13 with VerticalCRS

use of org.opengis.referencing.crs.VerticalCRS in project sis by apache.

the class CommonCRSTest method testVertical.

/**
 * Verifies the vertical datum enumeration.
 */
@Test
public void testVertical() {
    for (final CommonCRS.Vertical e : CommonCRS.Vertical.values()) {
        final VerticalDatumType datumType;
        final String axisName, datumName;
        switch(e) {
            case NAVD88:
                axisName = AxisNames.GRAVITY_RELATED_HEIGHT;
                datumName = "North American Vertical Datum 1988";
                datumType = VerticalDatumType.GEOIDAL;
                break;
            case BAROMETRIC:
                axisName = "Barometric altitude";
                datumName = "Constant pressure surface";
                datumType = VerticalDatumType.BAROMETRIC;
                break;
            case MEAN_SEA_LEVEL:
                axisName = AxisNames.GRAVITY_RELATED_HEIGHT;
                datumName = "Mean Sea Level";
                datumType = VerticalDatumType.GEOIDAL;
                break;
            case DEPTH:
                axisName = AxisNames.DEPTH;
                datumName = "Mean Sea Level";
                datumType = VerticalDatumType.GEOIDAL;
                break;
            case ELLIPSOIDAL:
                axisName = AxisNames.ELLIPSOIDAL_HEIGHT;
                datumName = "Ellipsoid";
                datumType = VerticalDatumTypes.ELLIPSOIDAL;
                break;
            case OTHER_SURFACE:
                axisName = "Height";
                datumName = "Other surface";
                datumType = VerticalDatumType.OTHER_SURFACE;
                break;
            default:
                throw new AssertionError(e);
        }
        final String name = e.name();
        final VerticalDatum datum = e.datum();
        final VerticalCRS crs = e.crs();
        if (e.isEPSG) {
            /*
                 * BAROMETRIC, ELLIPSOIDAL and OTHER_SURFACE uses an axis named "Height", which is not
                 * a valid axis name according ISO 19111. We skip the validation test for those enums.
                 */
            Validators.validate(crs);
        }
        // Datum before CRS creation.
        assertSame(name, datum, e.datum());
        // Datum after CRS creation.
        assertSame(name, crs.getDatum(), e.datum());
        assertEquals(name, datumName, datum.getName().getCode());
        assertEquals(name, datumType, datum.getVerticalDatumType());
        assertEquals(name, axisName, crs.getCoordinateSystem().getAxis(0).getName().getCode());
    }
}
Also used : VerticalDatumType(org.opengis.referencing.datum.VerticalDatumType) VerticalCRS(org.opengis.referencing.crs.VerticalCRS) VerticalDatum(org.opengis.referencing.datum.VerticalDatum) Test(org.junit.Test)

Example 14 with VerticalCRS

use of org.opengis.referencing.crs.VerticalCRS in project sis by apache.

the class StandardDefinitionsTest method testCreateVerticalCRS.

/**
 * Tests the creation of vertical CRS.
 *
 * @since 0.7
 */
@Test
@DependsOnMethod("testCreateAxis")
public void testCreateVerticalCRS() {
    VerticalDatum datum;
    VerticalCRS crs;
    datum = StandardDefinitions.createVerticalDatum(CommonCRS.Vertical.NAVD88.datum);
    crs = StandardDefinitions.createVerticalCRS(CommonCRS.Vertical.NAVD88.crs, datum);
    assertEquals("name", "NAVD88 height", crs.getName().getCode());
    assertEquals("identifier", "5703", IdentifiedObjects.getIdentifier(crs, Citations.EPSG).getCode());
    assertEquals("identifier", "88", IdentifiedObjects.getIdentifier(crs, Citations.WMS).getCode());
    assertEquals("direction", AxisDirection.UP, crs.getCoordinateSystem().getAxis(0).getDirection());
    datum = StandardDefinitions.createVerticalDatum(CommonCRS.Vertical.MEAN_SEA_LEVEL.datum);
    crs = StandardDefinitions.createVerticalCRS(CommonCRS.Vertical.MEAN_SEA_LEVEL.crs, datum);
    assertEquals("name", "MSL height", crs.getName().getCode());
    assertEquals("identifier", "5714", IdentifiedObjects.getIdentifier(crs, Citations.EPSG).getCode());
    assertNull("identifier", IdentifiedObjects.getIdentifier(crs, Citations.OGC));
    assertEquals("direction", AxisDirection.UP, crs.getCoordinateSystem().getAxis(0).getDirection());
    datum = StandardDefinitions.createVerticalDatum(CommonCRS.Vertical.DEPTH.datum);
    crs = StandardDefinitions.createVerticalCRS(CommonCRS.Vertical.DEPTH.crs, datum);
    assertEquals("name", "MSL depth", crs.getName().getCode());
    assertEquals("identifier", "5715", IdentifiedObjects.getIdentifier(crs, Citations.EPSG).getCode());
    assertNull("identifier", IdentifiedObjects.getIdentifier(crs, Citations.OGC));
    assertEquals("direction", AxisDirection.DOWN, crs.getCoordinateSystem().getAxis(0).getDirection());
}
Also used : VerticalCRS(org.opengis.referencing.crs.VerticalCRS) VerticalDatum(org.opengis.referencing.datum.VerticalDatum) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 15 with VerticalCRS

use of org.opengis.referencing.crs.VerticalCRS in project sis by apache.

the class EllipsoidalHeightCombinerTest method testGeographicCRS.

/**
 * Tests {@link EllipsoidalHeightCombiner#createCompoundCRS EllipsoidalHeightCombiner.createCompoundCRS(…)}
 * with a geographic CRS.
 *
 * @throws FactoryException if a CRS can not be created.
 */
@Test
public void testGeographicCRS() throws FactoryException {
    final EllipsoidalHeightCombiner services = create();
    final Map<String, String> properties = Collections.singletonMap(CoordinateReferenceSystem.NAME_KEY, "WGS 84 (4D)");
    final GeographicCRS horizontal = HardCodedCRS.WGS84;
    final GeographicCRS volumetric = HardCodedCRS.WGS84_3D;
    final VerticalCRS vertical = HardCodedCRS.ELLIPSOIDAL_HEIGHT;
    final TemporalCRS temporal = HardCodedCRS.TIME;
    final VerticalCRS geoidal = HardCodedCRS.GRAVITY_RELATED_HEIGHT;
    /*
         * createCompoundCRS(…) should not combine GeographicCRS with non-ellipsoidal height.
         */
    CoordinateReferenceSystem compound = services.createCompoundCRS(properties, horizontal, geoidal, temporal);
    assertArrayEqualsIgnoreMetadata(new SingleCRS[] { horizontal, geoidal, temporal }, CRS.getSingleComponents(compound).toArray());
    /*
         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height.
         */
    compound = services.createCompoundCRS(properties, horizontal, vertical);
    assertArrayEqualsIgnoreMetadata(new SingleCRS[] { volumetric }, CRS.getSingleComponents(compound).toArray());
    /*
         * createCompoundCRS(…) should combine GeographicCRS with ellipsoidal height and keep time.
         */
    compound = services.createCompoundCRS(properties, horizontal, vertical, temporal);
    assertArrayEqualsIgnoreMetadata(new SingleCRS[] { volumetric, temporal }, CRS.getSingleComponents(compound).toArray());
    /*
         * Non-standard feature: accept (VerticalCRS + GeodeticCRS) order.
         * The test below use the reverse order for all axes compared to the previous test.
         */
    compound = services.createCompoundCRS(properties, temporal, vertical, HardCodedCRS.WGS84_φλ);
    final Object[] components = CRS.getSingleComponents(compound).toArray();
    assertEquals(2, components.length);
    assertEqualsIgnoreMetadata(temporal, components[0]);
    assertInstanceOf("Shall be a three-dimensional geographic CRS.", GeographicCRS.class, components[1]);
    assertAxisDirectionsEqual("Shall be a three-dimensional geographic CRS.", ((CoordinateReferenceSystem) components[1]).getCoordinateSystem(), AxisDirection.UP, AxisDirection.NORTH, AxisDirection.EAST);
}
Also used : TemporalCRS(org.opengis.referencing.crs.TemporalCRS) VerticalCRS(org.opengis.referencing.crs.VerticalCRS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) Test(org.junit.Test)

Aggregations

VerticalCRS (org.opengis.referencing.crs.VerticalCRS)18 Test (org.junit.Test)9 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)9 TemporalCRS (org.opengis.referencing.crs.TemporalCRS)5 VerticalDatum (org.opengis.referencing.datum.VerticalDatum)5 DependsOnMethod (org.apache.sis.test.DependsOnMethod)4 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)4 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)4 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)4 VerticalExtent (org.opengis.metadata.extent.VerticalExtent)3 CompoundCRS (org.opengis.referencing.crs.CompoundCRS)3 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)3 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)3 TransformException (org.opengis.referencing.operation.TransformException)3 DefaultGeographicBoundingBox (org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox)2 DefaultVerticalExtent (org.apache.sis.metadata.iso.extent.DefaultVerticalExtent)2 DefaultCompoundCRS (org.apache.sis.referencing.crs.DefaultCompoundCRS)2 DefaultTemporalCRS (org.apache.sis.referencing.crs.DefaultTemporalCRS)2 DefaultVerticalCRS (org.apache.sis.referencing.crs.DefaultVerticalCRS)2 DefaultVerticalCS (org.apache.sis.referencing.cs.DefaultVerticalCS)2