Search in sources :

Example 6 with Convention

use of org.apache.sis.io.wkt.Convention in project sis by apache.

the class DefaultParameterValue method formatTo.

/**
 * Formats this parameter as a <cite>Well Known Text</cite> {@code Parameter[…]} element.
 * Example:
 *
 * {@preformat wkt
 *   Parameter["False easting", 0.0, LengthUnit["metre", 1]]
 * }
 *
 * <div class="section">Unit of measurement</div>
 * The units of measurement were never specified in WKT 1 format, and are optional in WKT 2 format.
 * If the units are not specified, then they are inferred from the context.
 * Typically, parameter values that are lengths are given in the unit for the projected CRS axes
 * while parameter values that are angles are given in the unit for the base geographic CRS.
 *
 * <div class="note"><b>Example:</b>
 * The snippet below show WKT representations of the map projection parameters of a projected CRS
 * (most other elements are omitted). The map projection uses a <cite>"Latitude of natural origin"</cite>
 * parameters which is set to 52 <strong>grads</strong>, as defined in the {@code UNIT[…]} element of the
 * enclosing CRS. A similar rule applies to <cite>“False easting”</cite> and <cite>“False northing”</cite>
 * parameters, which are in kilometres in this example.
 *
 * <p><b>WKT 1:</b></p>
 * {@preformat wkt
 *   PROJCS[…,
 *     GEOGCS[…,
 *       UNIT[“grad”, 0.015707963267948967]],       // Unit for all angles
 *     PROJECTION[“Lambert_Conformal_Conic_1SP”]
 *     PARAMETER[“latitude_of_origin”, 52.0],       // In grads
 *     PARAMETER[“scale_factor”, 0.99987742],
 *     PARAMETER[“false_easting”, 600.0],           // In kilometres
 *     PARAMETER[“false_northing”, 2200.0],         // In kilometres
 *     UNIT[“kilometre”, 1000]]                            // Unit for all lengths
 * }
 *
 * <p><b>WKT 2:</b></p>
 * {@preformat wkt
 *   ProjectedCRS[…
 *     BaseGeodCRS[…
 *       AngleUnit[“grad”, 0.015707963267948967]],
 *     Conversion[“Lambert zone II”,
 *       Method[“Lambert Conic Conformal (1SP)”],
 *       Parameter[“Latitude of natural origin”, 52.0],
 *       Parameter[“Scale factor at natural origin”, 0.99987742],
 *       Parameter[“False easting”, 600.0],
 *       Parameter[“False northing”, 2200.0]],
 *     CS[“Cartesian”, 2],
 *       LengthUnit[“kilometre”, 1000]]
 * }
 * </div>
 *
 * @param  formatter  the formatter where to format the inner content of this WKT element.
 * @return {@code "Parameter"} or {@code "ParameterFile"}.
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#119">WKT 2 specification §17.2.4</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    // Gives to users a chance to override this property.
    final ParameterDescriptor<T> descriptor = getDescriptor();
    WKTUtilities.appendName(descriptor, formatter, ElementKind.PARAMETER);
    final Convention convention = formatter.getConvention();
    final boolean isWKT1 = convention.majorVersion() == 1;
    // Gives to users a chance to override this property.
    Unit<?> unit = getUnit();
    if (unit == null) {
        // Gives to users a chance to override this property.
        final T value = getValue();
        if (!isWKT1 && isFile(value)) {
            formatter.append(value.toString(), null);
            return WKTKeywords.ParameterFile;
        } else {
            formatter.appendAny(value);
        }
    } else {
        /*
             * In the WKT 1 specification, the unit of measurement is given by the context.
             * If this parameter value does not use the same unit, we will need to convert it.
             * Otherwise we can write the value as-is.
             *
             * Note that we take the descriptor unit as a starting point instead than this parameter unit
             * in order to give precedence to the descriptor units in Convention.WKT1_COMMON_UNITS mode.
             */
        Unit<?> contextualUnit;
        if (descriptor == null || (contextualUnit = descriptor.getUnit()) == null) {
            // Should be very rare (probably a buggy descriptor), but we try to be safe.
            contextualUnit = unit;
        }
        contextualUnit = formatter.toContextualUnit(contextualUnit);
        boolean ignoreUnits;
        if (isWKT1) {
            unit = contextualUnit;
            ignoreUnits = true;
        } else {
            if (convention != Convention.INTERNAL) {
                unit = WKTUtilities.toFormattable(unit);
            }
            ignoreUnits = unit.equals(contextualUnit);
        }
        double value;
        try {
            value = doubleValue(unit);
        } catch (IllegalStateException exception) {
            // but no value has been set for this parameter.
            if (descriptor != null) {
                formatter.setInvalidWKT(descriptor, exception);
            } else {
                // Null descriptor should be illegal but may happen after unmarshalling of invalid GML.
                // We make this WKT formatting robust since it is used by 'toString()' implementation.
                formatter.setInvalidWKT(DefaultParameterValue.class, exception);
            }
            value = Double.NaN;
        }
        formatter.append(value);
        /*
             * In the WKT 2 specification, the unit and the identifier are optional but recommended.
             * We follow that recommendation in strict WKT2 mode, but omit them in non-strict modes.
             * The only exception is when the parameter unit is not the same than the contextual unit,
             * in which case we have no choice: we must format that unit, unless the numerical value
             * is identical in both units (typically the 0 value).
             */
        if (!ignoreUnits && !Double.isNaN(value)) {
            // Test equivalent to unit.equals(contextualUnit) but more aggressive.
            ignoreUnits = Numerics.equals(value, doubleValue(contextualUnit));
        }
        if (ignoreUnits && convention != Convention.INTERNAL) {
            // One last check about if we are really allowed to ignore units.
            ignoreUnits = convention.isSimplified() && hasContextualUnit(formatter);
        }
        if (!ignoreUnits) {
            if (!isWKT1) {
                formatter.append(unit);
            } else if (!ignoreUnits) {
                if (descriptor != null) {
                    formatter.setInvalidWKT(descriptor, null);
                } else {
                    // Null descriptor should be illegal but may happen after unmarshalling of invalid GML.
                    // We make this WKT formatting robust since it is used by 'toString()' implementation.
                    formatter.setInvalidWKT(DefaultParameterValue.class, null);
                }
            }
        }
    }
    // ID will be added by the Formatter itself.
    return WKTKeywords.Parameter;
}
Also used : Convention(org.apache.sis.io.wkt.Convention)

Example 7 with Convention

use of org.apache.sis.io.wkt.Convention in project sis by apache.

the class DefaultDerivedCRS method formatTo.

/**
 * Formats the inner part of the <cite>Well Known Text</cite> (WKT) representation of this CRS.
 *
 * @return {@code "Fitted_CS"} (WKT 1) or a type-dependent keyword (WKT 2).
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#93">WKT 2 specification §15</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    // Gives to users a chance to override.
    final Conversion conversion = getConversionFromBase();
    if (conversion == null) {
        /*
             * Should never happen except temporarily at construction time, or if the user invoked the copy
             * constructor with an invalid Conversion, or if the user overrides the getConversionFromBase()
             * method. Delegates to the super-class method for avoiding a NullPointerException. That method
             * returns 'null', which will cause the WKT to be declared invalid.
             */
        return super.formatTo(formatter);
    }
    WKTUtilities.appendName(this, formatter, null);
    final Convention convention = formatter.getConvention();
    final boolean isWKT1 = (convention.majorVersion() == 1);
    /*
         * Both WKT 1 and WKT 2 format the base CRS. But WKT 1 formats the MathTransform before the base CRS,
         * while WKT 2 formats the conversion method and parameter values after the base CRS.
         */
    if (isWKT1) {
        MathTransform inverse = conversion.getMathTransform();
        try {
            inverse = inverse.inverse();
        } catch (NoninvertibleTransformException exception) {
            formatter.setInvalidWKT(this, exception);
            inverse = null;
        }
        formatter.newLine();
        formatter.append(inverse);
    }
    formatter.newLine();
    formatter.append(WKTUtilities.toFormattable(getBaseCRS()));
    if (isWKT1) {
        return WKTKeywords.Fitted_CS;
    } else {
        formatter.newLine();
        formatter.append(new // Format inside a "DefiningConversion" element.
        FormattableObject() {

            @Override
            protected String formatTo(final Formatter formatter) {
                WKTUtilities.appendName(conversion, formatter, null);
                formatter.newLine();
                formatter.append(DefaultOperationMethod.castOrCopy(conversion.getMethod()));
                formatter.newLine();
                for (final GeneralParameterValue param : conversion.getParameterValues().values()) {
                    WKTUtilities.append(param, formatter);
                }
                return WKTKeywords.DerivingConversion;
            }
        });
        if (convention == Convention.INTERNAL || !isBaseCRS(formatter)) {
            final CoordinateSystem cs = getCoordinateSystem();
            formatCS(formatter, cs, ReferencingUtilities.getUnit(cs), isWKT1);
        }
        return keyword(formatter);
    }
}
Also used : NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) Convention(org.apache.sis.io.wkt.Convention) AxesConvention(org.apache.sis.referencing.cs.AxesConvention) MathTransform(org.opengis.referencing.operation.MathTransform) Formatter(org.apache.sis.io.wkt.Formatter) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) CS_CoordinateSystem(org.apache.sis.internal.jaxb.referencing.CS_CoordinateSystem) Conversion(org.opengis.referencing.operation.Conversion) DefaultConversion(org.apache.sis.referencing.operation.DefaultConversion)

Example 8 with Convention

use of org.apache.sis.io.wkt.Convention in project sis by apache.

the class DefaultEllipsoid method formatTo.

/**
 * Formats this ellipsoid as a <cite>Well Known Text</cite> {@code Ellipsoid[…]} element.
 *
 * @return {@code "Ellipsoid"} (WKT 2) or {@code "Spheroid"} (WKT 1).
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#52">WKT 2 specification §8.2.1</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    super.formatTo(formatter);
    final Convention convention = formatter.getConvention();
    final boolean isWKT1 = convention.majorVersion() == 1;
    // Gives to users a chance to override properties.
    final Unit<Length> unit = getAxisUnit();
    double length = getSemiMajorAxis();
    if (isWKT1) {
        length = unit.getConverterTo(Units.METRE).convert(length);
    }
    formatter.append(length);
    // Gives to users a chance to override properties.
    final double inverseFlattening = getInverseFlattening();
    formatter.append(isInfinite(inverseFlattening) ? 0 : inverseFlattening);
    if (isWKT1) {
        return WKTKeywords.Spheroid;
    }
    if (!convention.isSimplified() || !Units.METRE.equals(unit)) {
        formatter.append(unit);
    }
    return WKTKeywords.Ellipsoid;
}
Also used : Convention(org.apache.sis.io.wkt.Convention) Length(javax.measure.quantity.Length)

Example 9 with Convention

use of org.apache.sis.io.wkt.Convention in project sis by apache.

the class DefaultImageDatum method formatTo.

/**
 * Formats this datum as a <cite>Well Known Text</cite> {@code ImageDatum[…]} element.
 *
 * <div class="note"><b>Compatibility note:</b>
 * {@code ImageDatum} is defined in the WKT 2 specification only.</div>
 *
 * @return {@code "ImageDatum"}.
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#81">WKT 2 specification §12.2</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    super.formatTo(formatter);
    final Convention convention = formatter.getConvention();
    if (convention == Convention.INTERNAL) {
        // This is an extension compared to ISO 19162.
        formatter.append(getPixelInCell());
    } else if (convention.majorVersion() == 1) {
        formatter.setInvalidWKT(this, null);
    }
    return formatter.shortOrLong(WKTKeywords.IDatum, WKTKeywords.ImageDatum);
}
Also used : Convention(org.apache.sis.io.wkt.Convention)

Example 10 with Convention

use of org.apache.sis.io.wkt.Convention in project sis by apache.

the class DefaultPrimeMeridian method formatTo.

/**
 * Formats this prime meridian as a <cite>Well Known Text</cite> {@code PrimeMeridian[…]} element.
 *
 * @return {@code "PrimeMeridian"} (WKT 2) or {@code "PrimeM"} (WKT 1).
 *
 * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#53">WKT 2 specification §8.2.2</a>
 */
@Override
protected String formatTo(final Formatter formatter) {
    super.formatTo(formatter);
    final Convention convention = formatter.getConvention();
    final boolean isWKT1 = (convention.majorVersion() == 1);
    final Unit<Angle> contextualUnit = formatter.toContextualUnit(Units.DEGREE);
    Unit<Angle> unit = contextualUnit;
    if (!isWKT1) {
        unit = getAngularUnit();
        if (convention != Convention.INTERNAL) {
            unit = WKTUtilities.toFormattable(unit);
        }
    }
    formatter.append(getGreenwichLongitude(unit));
    if (isWKT1) {
        return WKTKeywords.PrimeM;
    }
    if (!convention.isSimplified() || !contextualUnit.equals(unit) || beConservative(formatter, contextualUnit)) {
        formatter.append(unit);
    }
    return formatter.shortOrLong(WKTKeywords.PrimeM, WKTKeywords.PrimeMeridian);
}
Also used : Convention(org.apache.sis.io.wkt.Convention) Angle(javax.measure.quantity.Angle)

Aggregations

Convention (org.apache.sis.io.wkt.Convention)11 AxesConvention (org.apache.sis.referencing.cs.AxesConvention)4 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)4 Angle (javax.measure.quantity.Angle)3 Formatter (org.apache.sis.io.wkt.Formatter)2 CartesianCS (org.opengis.referencing.cs.CartesianCS)2 InternationalString (org.opengis.util.InternationalString)2 Length (javax.measure.quantity.Length)1 CS_CoordinateSystem (org.apache.sis.internal.jaxb.referencing.CS_CoordinateSystem)1 FormattableObject (org.apache.sis.io.wkt.FormattableObject)1 DefaultConversion (org.apache.sis.referencing.operation.DefaultConversion)1 Citation (org.opengis.metadata.citation.Citation)1 GeneralParameterValue (org.opengis.parameter.GeneralParameterValue)1 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)1 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)1 SingleCRS (org.opengis.referencing.crs.SingleCRS)1 AxisDirection (org.opengis.referencing.cs.AxisDirection)1 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)1 GeodeticDatum (org.opengis.referencing.datum.GeodeticDatum)1 PrimeMeridian (org.opengis.referencing.datum.PrimeMeridian)1