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;
}
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);
}
}
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;
}
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);
}
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);
}
Aggregations