Module org.apache.sis.referencing
Package org.apache.sis.io.wkt

# Class WKTFormat

Object
Format
CompoundFormat<Object>
WKTFormat

All Implemented Interfaces:
  `Serializable`, `Cloneable`, `Localized`

public class WKTFormat extends CompoundFormat<Object>
Parser and formatter for Well Known Text (WKT) strings. This format handles a pair of `Parser` and `Formatter`, used by the `parse(…)` and `format(…)` methods respectively. `WKTFormat` objects allow the following configuration:

- The preferred authority of object name to format (see `Formatter​.getNameAuthority()` for more information).
- The symbols to use (curly braces or brackets, etc).
- The transliterator to use for replacing Unicode characters by ASCII ones.
- Whether ANSI X3.64 colors are allowed or not (default is not).
- The indentation.

## String expansion

Because the strings to be parsed by this class are long and tend to contain repetitive substrings, `WKTFormat` provides a mechanism for performing string substitutions before the parsing take place. Long strings can be assigned short names by calls to the `addFragment(String, String)` method. After fragments have been added, any call to a parsing method will replace all occurrences (except in quoted text) of tokens like `$foo` by the WKT fragment named "foo".

### Example

In the example below, the `$WGS84` substring which appear in the argument given to the `parseObject(…)` method will be expanded into the full `GeodeticCRS[“WGS84”, …]` string before the parsing proceed.

> `addFragment("deg", "AngleUnit[“degree”, 0.0174532925199433]");
> addFragment("lat", "Axis[“Latitude”, NORTH, $deg]");
> addFragment("lon", "Axis[“Longitude”, EAST, $deg]");
> addFragment("MyBaseCRS", "GeodeticCRS[“WGS84”, Datum[` …etc… `], CS[` …etc… `], $lat, $lon]");
> Object crs = parseObject("ProjectedCRS[“Mercator_1SP”, $MyBaseCRS,` …etc… `]");`

Note that the parsing of WKT fragment does not always produce the same object. In particular, the default linear and angular units depend on the context in which the WKT fragment appears.

## Limitations

- The WKT format is not lossless! Objects formatted by `WKTFormat` are not guaranteed to be identical after parsing. Some metadata may be lost or altered, but the coordinate operations between two CRS should produce the same numerical results provided that the two CRS were formatted independently (do not rely on `GeneralDerivedCRS​.getConversionFromBase()` for instance).
- Instances of this class are not synchronized for multi-threading. It is recommended to create separated format instances for each thread. If multiple threads access a `WKTFormat` concurrently, it must be synchronized externally.
- Serialized objects of this class are not guaranteed to be compatible with future Apache SIS releases. Serialization support is appropriate for short term storage or RMI between applications running the same version of Apache SIS.

Since:
  0.4
See Also:
  - WKT 2 specification
  - Legacy WKT 1
  - Serialized Form

- ## Nested Class Summary

  ## Nested classes/interfaces inherited from class Format

  `Format​.Field`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `SINGLE_LINE`
  The indentation value to give to the `setIndentation(int)` method for formatting the complete object on a single line.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `WKTFormat(Locale locale, TimeZone timezone)`
  Creates a format for the given locale and timezone.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addFragment(String name, String wkt)`
  Adds a fragment of Well Know Text (WKT).
  `WKTFormat`
  `clone()`
  Returns a clone of this format.
  `protected Format`
  `createFormat(Class<?> valueType)`
  Creates a new format to use for parsing and formatting values of the given type.
  `void`
  `format(Object object, Appendable toAppendTo)`
  Formats the specified object as a Well Know Text.
  `Colors`
  `getColors()`
  Returns the colors to use for syntax coloring, or `null` if none.
  `Convention`
  `getConvention()`
  Returns the convention for parsing and formatting WKT elements.
  `<T extends Factory>
  T`
  `getFactory(Class<T> type)`
  Returns one of the factories used by this `WKTFormat` for parsing WKT.
  `Set<String>`
  `getFragmentNames()`
  Returns the name of all WKT fragments known to this `WKTFormat`.
  `int`
  `getIndentation()`
  Returns the current indentation to be used for formatting objects.
  `KeywordCase`
  `getKeywordCase()`
  Returns whether WKT keywords should be written with upper cases or camel cases.
  `KeywordStyle`
  `getKeywordStyle()`
  Returns whether to use short or long WKT keywords.
  `Locale`
  `getLocale(Locale​.Category category)`
  Returns the locale for the given category.
  `int`
  `getMaximumListElements()`
  Returns the maximum number of elements to show in lists of values.
  `Citation`
  `getNameAuthority()`
  Returns the preferred authority to look for when fetching identified object names and identifiers.
  `Symbols`
  `getSymbols()`
  Returns the symbols used for parsing and formatting WKT.
  `Transliterator`
  `getTransliterator()`
  Returns a mapper between Java character sequences and the characters to write in WKT.
  `final Class<Object>`
  `getValueType()`
  Returns the type of objects formatted by this class.
  `Warnings`
  `getWarnings()`
  If warnings occurred during the last WKT parsing or formatting, returns the warnings.
  `Object`
  `parse(CharSequence wkt, ParsePosition pos)`
  Creates an object from the given character sequence.
  `void`
  `setColors(Colors colors)`
  Sets the colors to use for syntax coloring.
  `void`
  `setConvention(Convention convention)`
  Sets the convention for parsing and formatting WKT elements.
  `<T extends Factory>
  void`
  `setFactory(Class<T> type, T factory)`
  Sets one of the factories to be used by this `WKTFormat` for parsing WKT.
  `void`
  `setIndentation(int indentation)`
  Sets a new indentation to be used for formatting objects.
  `void`
  `setKeywordCase(KeywordCase keywordCase)`
  Sets whether WKT keywords should be written with upper cases or camel cases.
  `void`
  `setKeywordStyle(KeywordStyle keywordStyle)`
  Sets whether to use short or long WKT keywords.
  `void`
  `setMaximumListElements(int limit)`
  Sets a new limit for the number of elements to show in lists.
  `void`
  `setNameAuthority(Citation authority)`
  Sets the preferred authority for choosing the projection and parameter names.
  `void`
  `setSymbols(Symbols symbols)`
  Sets the symbols used for parsing and formatting WKT.
  `void`
  `setTransliterator(Transliterator transliterator)`
  Sets the mapper between Java character sequences and the characters to write in WKT.

  ### Methods inherited from class CompoundFormat

  `format, getFormat, getLocale, getTimeZone, parseObject, parseObject`

  ### Methods inherited from class Format

  `format, formatToCharacterIterator`

  ### Methods inherited from class Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### SINGLE_LINE

    public static final int SINGLE_LINE
    The indentation value to give to the `setIndentation(int)` method for formatting the complete object on a single line.
    See Also:
      - `getIndentation()`
      - `setIndentation(int)`
      - `OptionKey​.INDENTATION`
      - Constant Field Values

- ## Constructor Details

  - ### WKTFormat

    public WKTFormat(Locale locale, TimeZone timezone)
    Creates a format for the given locale and timezone. The given locale will be used for `InternationalString` localization; this is not the locale for number format.
    Parameters:
      `locale` - the locale for the new `Format`, or `null` for `Locale​.ROOT`.
      `timezone` - the timezone, or `null` for UTC.

- ## Method Details

  - ### getLocale

    public Locale getLocale(Locale.Category category)
    Returns the locale for the given category. This method implements the following mapping:
    - `Locale​.Category​.FORMAT`: the value of `Symbols​.getLocale()`, normally fixed to `Locale​.ROOT`, used for number formatting.
    - `Locale​.Category​.DISPLAY`: the `locale` given at construction time, used for `InternationalString` localization.
    Overrides:
      `getLocale` in class `CompoundFormat<Object>`
    Parameters:
      `category` - the category for which a locale is desired.
    Returns:
      the locale for the given category (never `null`).

  - ### getSymbols

    public Symbols getSymbols()
    Returns the symbols used for parsing and formatting WKT. This method returns an unmodifiable instance. Modifications, if desired, should be applied on a clone of the returned object.
    Returns:
      the current set of symbols used for parsing and formatting WKT.

  - ### setSymbols

    public void setSymbols(Symbols symbols)
    Sets the symbols used for parsing and formatting WKT.
    Parameters:
      `symbols` - the new set of symbols to use for parsing and formatting WKT.

  - ### getTransliterator

    public Transliterator getTransliterator()
    Returns a mapper between Java character sequences and the characters to write in WKT. The intent is to specify how to write characters that are not allowed in WKT strings according ISO 19162 specification. Return values can be:
    - `Transliterator​.DEFAULT` for performing replacements like "é" → "e" in all WKT elements except `REMARKS["…"]`.
    - `Transliterator​.IDENTITY` for preserving non-ASCII characters.
    - Any other user supplied mapping.
    Returns:
      the mapper between Java character sequences and the characters to write in WKT.
    Since:
      0.6

  - ### setTransliterator

    public void setTransliterator(Transliterator transliterator)
    Sets the mapper between Java character sequences and the characters to write in WKT.

    If this method is never invoked, or if this method is invoked with a `null` value, then the default mapper is `Transliterator​.DEFAULT` except for WKT formatted according the internal convention.

    Parameters:
      `transliterator` - the new mapper to use, or `null` for restoring the default value.
    Since:
      0.6

  - ### getKeywordCase

    public KeywordCase getKeywordCase()
    Returns whether WKT keywords should be written with upper cases or camel cases.
    Returns:
      the case to use for formatting keywords.

  - ### setKeywordCase

    public void setKeywordCase(KeywordCase keywordCase)
    Sets whether WKT keywords should be written with upper cases or camel cases.
    Parameters:
      `keywordCase` - the case to use for formatting keywords.

  - ### getKeywordStyle

    public KeywordStyle getKeywordStyle()
    Returns whether to use short or long WKT keywords.
    Returns:
      the style used for formatting keywords.
    Since:
      0.6

  - ### setKeywordStyle

    public void setKeywordStyle(KeywordStyle keywordStyle)
    Sets whether to use short or long WKT keywords.
    Parameters:
      `keywordStyle` - the style to use for formatting keywords.
    Since:
      0.6

  - ### getColors

    public Colors getColors()
    Returns the colors to use for syntax coloring, or `null` if none. This method returns an unmodifiable instance. Modifications, if desired, should be applied on a clone of the returned object. By default there is no syntax coloring.
    Returns:
      the colors for syntax coloring, or `null` if none.

  - ### setColors

    public void setColors(Colors colors)
    Sets the colors to use for syntax coloring. This property applies only when formatting text.

    Newly created `WKTFormat`s have no syntax coloring. If a non-null argument like `Colors​.DEFAULT` is given to this method, then the `format(…)` method tries to highlight most of the elements that are relevant to `Utilities​.equalsIgnoreMetadata(Object, Object)`.

    Parameters:
      `colors` - the colors for syntax coloring, or `null` if none.

  - ### getConvention

    public Convention getConvention()
    Returns the convention for parsing and formatting WKT elements. The default value is `Convention​.WKT2`.
    Returns:
      the convention to use for formatting WKT elements (never `null`).

  - ### setConvention

    public void setConvention(Convention convention)
    Sets the convention for parsing and formatting WKT elements.
    Parameters:
      `convention` - the new convention to use for parsing and formatting WKT elements.

  - ### getNameAuthority

    public Citation getNameAuthority()
    Returns the preferred authority to look for when fetching identified object names and identifiers. The difference between various authorities are most easily seen in projection and parameter names. If no authority has been explicitly set, then this method returns the default authority for the current convention.

    #### Example

    The following table shows the names given by various organizations or projects for the same projection:

    Projection name examples
    Authority | Projection name
    --- | ---
    EPSG | Mercator (variant A)
    OGC | Mercator_1SP
    GEOTIFF | CT_Mercator

    Returns:
      the organization, standard or project to look for when fetching projection and parameter names.
    See Also:
      - `Formatter​.getNameAuthority()`

  - ### setNameAuthority

    public void setNameAuthority(Citation authority)
    Sets the preferred authority for choosing the projection and parameter names. If non-null, the given priority will have precedence over the authority usually associated to the convention. A `null` value restore the default behavior.
    Parameters:
      `authority` - the new authority, or `null` for inferring it from the convention.
    See Also:
      - `Formatter​.getNameAuthority()`

  - ### getIndentation

    public int getIndentation()
    Returns the current indentation to be used for formatting objects. The -1 value means that the whole WKT is to be formatted on a single line.
    Returns:
      the current indentation.

  - ### setIndentation

    public void setIndentation(int indentation)
    Sets a new indentation to be used for formatting objects. The -1 value means that the whole WKT is to be formatted on a single line.
    Parameters:
      `indentation` - the new indentation to use.
    See Also:
      - `OptionKey​.INDENTATION`

  - ### getMaximumListElements

    public int getMaximumListElements()
    Returns the maximum number of elements to show in lists of values. If a list length is greater than this limit, then only the first and last elements will be shown together with a message saying that some elements were omitted. This limit is useful in particular with `MathTransform` parameter values of `double[]` type, since those parameters may be large interpolation tables.
    Returns:
      the current lists size limit, or `Integer​.MAX_VALUE` if unlimited.
    Since:
      1.0

  - ### setMaximumListElements

    public void setMaximumListElements(int limit)
    Sets a new limit for the number of elements to show in lists. If this method is never invoked, then the default is unlimited.
    Parameters:
      `limit` - the new lists size limit, or `Integer​.MAX_VALUE` if unlimited.
    Since:
      1.0

  - ### getFactory

    public <T extends Factory> T getFactory(Class<T> type)
    Returns one of the factories used by this `WKTFormat` for parsing WKT. The given `type` argument can be one of the following values:
    - `CRSFactory.class`
    - `CSFactory.class`
    - `DatumFactory.class`
    - `MathTransformFactory.class`
    - `CoordinateOperationFactory.class`
    Type Parameters:
      `T` - the compile-time type of the `type` argument.
    Parameters:
      `type` - the factory type.
    Returns:
      the factory used by this `WKTFormat` for the given type.
    Throws:
      `IllegalArgumentException` - if the `type` argument is not one of the valid values.

  - ### setFactory

    public <T extends Factory> void setFactory(Class<T> type, T factory)
    Sets one of the factories to be used by this `WKTFormat` for parsing WKT. The given `type` argument can be one of the following values:
    - `CRSFactory.class`
    - `CSFactory.class`
    - `DatumFactory.class`
    - `MathTransformFactory.class`
    - `CoordinateOperationFactory.class`

    #### Limitation

    The current implementation does not serialize the given factories, because they are usually not `Serializable`. The factories used by `WKTFormat` instances after deserialization are the default ones.
    Type Parameters:
      `T` - the compile-time type of the `type` argument.
    Parameters:
      `type` - the factory type.
      `factory` - the factory to be used by this `WKTFormat` for the given type.
    Throws:
      `IllegalArgumentException` - if the `type` argument is not one of the valid values.

  - ### getValueType

    public final Class<Object> getValueType()
    Returns the type of objects formatted by this class. This method has to return `Object​.class` since it is the only common parent to all object types accepted by this formatter.
    Specified by:
      `getValueType` in class `CompoundFormat<Object>`
    Returns:
      `Object​.class`

  - ### getFragmentNames

    public Set<String> getFragmentNames()
    Returns the name of all WKT fragments known to this `WKTFormat`. The returned collection is initially empty. WKT fragments can be added by call to `addFragment(String, String)`.

    The returned collection is modifiable. In particular, a call to `Set​.clear()` removes all fragments from this `WKTFormat`.

    Returns:
      the name of all fragments known to this `WKTFormat`.

  - ### addFragment

    public void addFragment(String name, String wkt) throws IllegalArgumentException, ParseException
    Adds a fragment of Well Know Text (WKT). The `wkt` argument given to this method can contains itself other fragments specified in some previous calls to this method.

    #### Example

    If the following method is invoked:

        addFragment("MyEllipsoid", "Ellipsoid[“Bessel 1841”, 6377397.155, 299.1528128, ID[“EPSG”,“7004”]]");

    Then other WKT strings parsed by this `WKTFormat` instance can refer to the above fragment as below (WKT after the ellipsoid omitted for brevity):

        Object crs = parseObject("GeodeticCRS[“Tokyo”, Datum[“Tokyo”, $MyEllipsoid], …]");

    For removing a fragment, use `getFragmentNames().remove(name)`.
    Parameters:
      `name` - the name to assign to the WKT fragment (case-sensitive). Must be a valid Unicode identifier.
      `wkt` - the Well Know Text (WKT) fragment represented by the given identifier.
    Throws:
      `IllegalArgumentException` - if the given name is not a valid Unicode identifier or if a fragment is already associated to that name.
      `ParseException` - if an error occurred while parsing the given WKT.

  - ### parse

    public Object parse(CharSequence wkt, ParsePosition pos) throws ParseException
    Creates an object from the given character sequence. The parsing begins at the index given by the `pos` argument. After successful parsing, `ParsePosition​.getIndex()` gives the position after the last parsed character. In case of error, `ParseException​.getErrorOffset()` gives the position of the first illegal character.
    Specified by:
      `parse` in class `CompoundFormat<Object>`
    Parameters:
      `wkt` - the character sequence for the object to parse.
      `pos` - index of the first character to parse (on input) or after last parsed character (on output).
    Returns:
      the parsed object (never `null`).
    Throws:
      `ParseException` - if an error occurred while parsing the WKT.

  - ### format

    public void format(Object object, Appendable toAppendTo) throws IOException
    Formats the specified object as a Well Know Text. The formatter accepts at least the following types: `FormattableObject`, `IdentifiedObject`, `MathTransform`, `GeographicBoundingBox`, `VerticalExtent`, `TemporalExtent`, `Envelope`, `Position` and `Unit`.
    Specified by:
      `format` in class `CompoundFormat<Object>`
    Parameters:
      `object` - the object to format.
      `toAppendTo` - where the text is to be appended.
    Throws:
      `IOException` - if an error occurred while writing to `toAppendTo`.
    See Also:
      - `FormattableObject​.toWKT()`

  - ### createFormat

    protected Format createFormat(Class<?> valueType)
    Creates a new format to use for parsing and formatting values of the given type. This method is invoked the first time that a format is needed for the given type. The `valueType` can be any types declared in the parent class.
    Overrides:
      `createFormat` in class `CompoundFormat<Object>`
    Parameters:
      `valueType` - the base type of values to parse or format.
    Returns:
      the format to use for parsing of formatting values of the given type, or `null` if none.

  - ### getWarnings

    public Warnings getWarnings()
    If warnings occurred during the last WKT parsing or formatting, returns the warnings. Otherwise returns `null`. The warnings are cleared every time a new object is parsed or formatted.
    Returns:
      the warnings of the last parsing of formatting operation, or `null` if none.
    Since:
      0.6

  - ### clone

    public WKTFormat clone()
    Returns a clone of this format. The clone has the same configuration (including any added fragments), except the warnings.
    Overrides:
      `clone` in class `CompoundFormat<Object>`
    Returns:
      a clone of this format.