Search in sources :

Example 31 with CoordinateSystem

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

the class DefaultCoordinateSystemAxis method formatTo.

/**
 * Formats this axis as a <cite>Well Known Text</cite> {@code Axis[…]} element.
 *
 * <div class="section">Constraints for WKT validity</div>
 * The ISO 19162 specification puts many constraints on axis names, abbreviations and directions allowed in WKT.
 * Most of those constraints are inherited from ISO 19111 — see {@link CoordinateSystemAxis} javadoc for some of
 * those. The current Apache SIS implementation does not verify whether this axis name and abbreviation are
 * compliant; we assume that the user created a valid axis.
 * The only actions (derived from ISO 19162 rules) taken by this method (by default) are:
 *
 * <ul>
 *   <li>Replace <cite>“Geodetic latitude”</cite> and <cite>“Geodetic longitude”</cite> names (case insensitive)
 *       by <cite>“latitude”</cite> and <cite>“longitude”</cite> respectively.</li>
 *   <li>For latitude and longitude axes, replace “φ” and “λ” abbreviations by <var>“B”</var> and <var>“L”</var>
 *       respectively (from German “Breite” and “Länge”, used in academic texts worldwide).
 *       Note that <var>“L”</var> is also the transliteration of Greek letter “lambda” (λ).</li>
 *   <li>In {@link SphericalCS}, replace “φ” and “θ” abbreviations by <var>“U”</var> and <var>“V”</var> respectively.</li>
 *   <li>In {@link PolarCS}, replace “θ” abbreviation by <var>“U”</var>.</li>
 * </ul>
 *
 * The above-cited replacements of name and Greek letters can be controlled by a call to
 * {@link org.apache.sis.io.wkt.WKTFormat#setTransliterator(Transliterator)}.
 *
 * @return {@code "Axis"}.
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#39">WKT 2 specification §7.5.3</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    final Convention convention = formatter.getConvention();
    final boolean isWKT1 = (convention.majorVersion() == 1);
    final boolean isInternal = (convention == Convention.INTERNAL);
    final CoordinateSystem cs = getEnclosingCS(formatter);
    AxisDirection dir = getDirection();
    String name = IdentifiedObjects.getName(this, formatter.getNameAuthority());
    if (name == null) {
        name = IdentifiedObjects.getName(this, null);
    }
    if (name != null && !isInternal) {
        final String old = name;
        name = formatter.getTransliterator().toShortAxisName(cs, dir, name);
        if (name == null && isWKT1) {
            // WKT 1 does not allow omission of name.
            name = old;
        }
    }
    /*
         * ISO 19162:2015 §7.5.3 suggests to put abbreviation in parentheses, e.g. "Easting (x)".
         * The specification also suggests to write only the abbreviation (e.g. "(X)") in the
         * special case of Geocentric axis, and disallows Greek letters.
         */
    if (!isWKT1) {
        final String a = formatter.getTransliterator().toLatinAbbreviation(cs, dir, getAbbreviation());
        if (a != null && !a.equals(name)) {
            final StringBuilder buffer = new StringBuilder();
            if (name != null) {
                buffer.append(name).append(' ');
            }
            name = buffer.append('(').append(a).append(')').toString();
        }
    }
    formatter.append(name, ElementKind.AXIS);
    /*
         * Format the axis direction, optionally followed by a MERIDIAN[…] element
         * if the direction is of the kind "South along 90°N" for instance.
         */
    DirectionAlongMeridian meridian = null;
    if (AxisDirections.isUserDefined(dir)) {
        meridian = DirectionAlongMeridian.parse(dir);
        if (meridian != null) {
            dir = meridian.baseDirection;
            if (isWKT1) {
                formatter.setInvalidWKT(this, null);
            }
        }
    }
    formatter.append(dir);
    formatter.append(meridian);
    /*
         * Formats the axis unit only if the enclosing CRS element does not provide one.
         * If the enclosing CRS provided a contextual unit, then it is assumed to apply
         * to all axes (we do not verify).
         */
    if (!isWKT1) {
        if (convention == Convention.WKT2 && cs != null) {
            final Order order = Order.create(cs, this);
            if (order != null) {
                formatter.append(order);
            } else {
                formatter.setInvalidWKT(cs, null);
            }
        }
        if (!formatter.hasContextualUnit(1)) {
            formatter.append(getUnit());
        }
    }
    return WKTKeywords.Axis;
}
Also used : Convention(org.apache.sis.io.wkt.Convention) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) AxisDirection(org.opengis.referencing.cs.AxisDirection) InternationalString(org.opengis.util.InternationalString)

Example 32 with CoordinateSystem

use of org.opengis.referencing.cs.CoordinateSystem 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 33 with CoordinateSystem

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

the class ServicesForMetadata method setGeographicExtent.

/**
 * Implementation of the public {@code setBounds(…, DefaultGeographicBoundingBox, …)} methods for
 * the horizontal extent. If the {@code crs} argument is null, then it is caller's responsibility
 * to ensure that the given envelope is two-dimensional.
 *
 * @param  envelope       the source envelope.
 * @param  target         the target bounding box.
 * @param  crs            the envelope CRS, or {@code null} if unknown.
 * @param  normalizedCRS  the horizontal component of the given CRS, or null if the {@code crs} argument is null.
 * @throws TransformException if the given envelope can not be transformed.
 */
private void setGeographicExtent(Envelope envelope, final DefaultGeographicBoundingBox target, final CoordinateReferenceSystem crs, final GeographicCRS normalizedCRS) throws TransformException {
    if (normalizedCRS != null) {
        // No need to check for dimension, since GeodeticCRS can not have less than 2.
        final CoordinateSystem cs1 = crs.getCoordinateSystem();
        final CoordinateSystem cs2 = normalizedCRS.getCoordinateSystem();
        if (!Utilities.equalsIgnoreMetadata(cs2.getAxis(0), cs1.getAxis(0)) || !Utilities.equalsIgnoreMetadata(cs2.getAxis(1), cs1.getAxis(1))) {
            final CoordinateOperation operation;
            final CoordinateOperationFactory factory = CoordinateOperations.factory();
            try {
                operation = factory.createOperation(crs, normalizedCRS);
            } catch (FactoryException e) {
                throw new TransformException(Resources.format(Resources.Keys.CanNotTransformEnvelopeToGeodetic), e);
            }
            envelope = Envelopes.transform(operation, envelope);
        }
    }
    /*
         * At this point, the envelope should use (longitude, latitude) coordinates in degrees.
         * However the prime meridian is not necessarily Greenwich.
         */
    double westBoundLongitude = envelope.getMinimum(0);
    double eastBoundLongitude = envelope.getMaximum(0);
    double southBoundLatitude = envelope.getMinimum(1);
    double northBoundLatitude = envelope.getMaximum(1);
    if (normalizedCRS != null) {
        final double rotation = CRS.getGreenwichLongitude(normalizedCRS);
        westBoundLongitude += rotation;
        eastBoundLongitude += rotation;
    }
    target.setBounds(westBoundLongitude, eastBoundLongitude, southBoundLatitude, northBoundLatitude);
    target.setInclusion(Boolean.TRUE);
}
Also used : FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) DefaultCoordinateOperationFactory(org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory) CoordinateOperationFactory(org.opengis.referencing.operation.CoordinateOperationFactory) TransformException(org.opengis.referencing.operation.TransformException) CoordinateOperation(org.opengis.referencing.operation.CoordinateOperation)

Example 34 with CoordinateSystem

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

the class CommonCRSTest method testNormalizedGeographic.

/**
 * Tests the {@link CommonCRS#normalizedGeographic()} method.
 */
@Test
@DependsOnMethod("testGeographic")
public void testNormalizedGeographic() {
    final GeographicCRS geographic = CommonCRS.WGS84.geographic();
    final GeographicCRS normalized = CommonCRS.WGS84.normalizedGeographic();
    Validators.validate(normalized);
    assertSame(geographic.getDatum(), normalized.getDatum());
    final CoordinateSystem φλ = geographic.getCoordinateSystem();
    final CoordinateSystem λφ = normalized.getCoordinateSystem();
    assertSame("Longitude", φλ.getAxis(1), λφ.getAxis(0));
    assertSame("Latitude", φλ.getAxis(0), λφ.getAxis(1));
    assertSame("Cached value", normalized, CommonCRS.WGS84.normalizedGeographic());
}
Also used : CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 35 with CoordinateSystem

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

the class DefaultEngineeringCRSTest method testCartesianXML.

/**
 * Tests XML (un)marshalling of an engineering CRS using a Cartesian CS.
 *
 * @throws JAXBException if an error occurred during (un)marshalling.
 */
@Test
public void testCartesianXML() throws JAXBException {
    final String xml = marshal(createCartesian());
    assertXmlEquals("<gml:EngineeringCRS xmlns:gml=\"" + Namespaces.GML + "\">\n" + "  <gml:name>A construction site CRS</gml:name>\n" + "  <gml:cartesianCS gml:id=\"Cartesian2D\">\n" + "    <gml:name>Cartesian 2D</gml:name>\n" + "    <gml:axis>\n" + "      <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"x\">\n" + "        <gml:name>x</gml:name>\n" + "        <gml:axisAbbrev>x</gml:axisAbbrev>\n" + "        <gml:axisDirection codeSpace=\"EPSG\">east</gml:axisDirection>\n" + "      </gml:CoordinateSystemAxis>\n" + "    </gml:axis>\n" + "    <gml:axis>\n" + "      <gml:CoordinateSystemAxis uom=\"urn:ogc:def:uom:EPSG::9001\" gml:id=\"y\">\n" + "        <gml:name>y</gml:name>\n" + "        <gml:axisAbbrev>y</gml:axisAbbrev>\n" + "        <gml:axisDirection codeSpace=\"EPSG\">north</gml:axisDirection>\n" + "      </gml:CoordinateSystemAxis>\n" + "    </gml:axis>\n" + "  </gml:cartesianCS>\n" + "  <gml:engineeringDatum>\n" + "    <gml:EngineeringDatum gml:id=\"P1\">\n" + "      <gml:name>P1</gml:name>\n" + "    </gml:EngineeringDatum>\n" + "  </gml:engineeringDatum>\n" + "</gml:EngineeringCRS>", xml, "xmlns:*");
    final DefaultEngineeringCRS crs = unmarshal(DefaultEngineeringCRS.class, xml);
    assertEquals("name", "A construction site CRS", crs.getName().getCode());
    assertEquals("datum.name", "P1", crs.getDatum().getName().getCode());
    final CoordinateSystem cs = crs.getCoordinateSystem();
    assertInstanceOf("coordinateSystem", CartesianCS.class, cs);
    assertEquals("cs.name", "Cartesian 2D", cs.getName().getCode());
    assertEquals("cs.dimension", 2, cs.getDimension());
    assertAxisDirectionsEqual("cartesianCS", cs, AxisDirection.EAST, AxisDirection.NORTH);
    assertEquals("cs.axis[0].name", "x", cs.getAxis(0).getName().getCode());
    assertEquals("cs.axis[1].name", "y", cs.getAxis(1).getName().getCode());
}
Also used : CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) Test(org.junit.Test)

Aggregations

CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)43 Test (org.junit.Test)16 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)15 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)13 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)9 DependsOnMethod (org.apache.sis.test.DependsOnMethod)7 FactoryException (org.opengis.util.FactoryException)7 AxisDirection (org.opengis.referencing.cs.AxisDirection)6 CartesianCS (org.opengis.referencing.cs.CartesianCS)6 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)5 Convention (org.apache.sis.io.wkt.Convention)4 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)4 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)4 TransformException (org.opengis.referencing.operation.TransformException)4 Unit (javax.measure.Unit)3 IdentifiedObject (org.opengis.referencing.IdentifiedObject)3 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)3 GeodeticDatum (org.opengis.referencing.datum.GeodeticDatum)3 MathTransform (org.opengis.referencing.operation.MathTransform)3 NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)3