Class WKTDictionary
- All Implemented Interfaces:
org.opengis.referencing.AuthorityFactory,org.opengis.util.Factory
create(…) method is invoked for the first time for a given key.
Sub-classing and instantiation
Newly constructedWKTDictionary are initially empty.
The dictionary can be populated in the following ways:
- Invoke
load(BufferedReader)for reading definitions from file(s). - Invoke
addDefinitions(Stream)for providing definitions from an arbitrary source. - Override
fetchDefinition(DefaultIdentifier)in a subclass for fetching WKT definitions on-the-fly (for example from the"spatial_ref_sys"table of a spatial database.
fetchDefinition(…) is not overridden
because WKTDictionary does not implement any of the
CRSAuthorityFactory,
CSAuthorityFactory or
DatumAuthorityFactory.
The choice of interfaces to implement is left to subclasses.
CRS.forCode(String).
The additional CRS are defined by Well-Known Text strings in a "MyCRS.txt" file.
First step is to create a CRS factory with those definitions:
The second step is to register this factory as a service with a
META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory file on the classpath.
That file shall contain the fully qualified class name of above MyCRS class.Errors management
Well-Known Text parsing is performed in two steps, each of them executed at a different time:Early validation
WKT strings added byload(…) or addDefinitions(…) methods are verified
for matching quotes, balanced parenthesis or brackets, and valid number or date formats.
If a syntax error is detected, the loading process is interrupted at the point the error occurred;
CRS definitions after the error location are not loaded.
However, WKT keywords and geodetic parameters (e.g. map projections) are not validated at this stage.
Late validation
WKT keywords and geodetic parameters inside WKT elements are validated only whencreateObject(String)
is invoked. If an error occurs at this stage, only the CRS (or other geodetic object) for the code given to
the createFoo(…) method become invalid. Objects associated to other codes are not impacted.
Multi-threading
This class is thread-safe but not necessarily concurrent. This class is designed for a relatively small amount of WKT; it is not a replacement for database-backed factory such asEPSGFactory.- Since:
- 1.1
- Version:
- 1.1
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final classA special kind of value used in thedefinitionsmap when the same code is used by more than one authority and version.private final classImplementation ofload(BufferedReader)method. -
Field Summary
FieldsModifier and TypeFieldDescriptionAuthorities declared in all"ID[CITATION[…]]"elements found in WKT definitions.private org.opengis.metadata.citation.CitationThe organization or specification that defines the codes recognized by this factory.Cache of authority codes computed bygetAuthorityCodes(Class).Code spaces of authority codes recognized by this factory.CRS definitions associated to authority:version:code keys.private final ReadWriteLockThe write lock forparserand the read/write locks fordefinitionsaccesses.protected final WKTFormatThe parser to use for creating geodetic objects from WKT definitions. -
Constructor Summary
ConstructorsConstructorDescriptionWKTDictionary(org.opengis.metadata.citation.Citation authority) Creates an initially empty factory. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidaddDefinition(StoredTree tree) Adds the definition of a CRS (or other geodetic objects) from a tree of WKT elements.voidaddDefinitions(Stream<String> objects) Adds definitions of CRS (or other geodetic objects) from Well-Known Texts.org.opengis.referencing.IdentifiedObjectcreateObject(String code) Returns an arbitrary object from a code.protected StringfetchDefinition(DefaultIdentifier identifier) Fetches the Well-Known Text for a user-specified identifier not found in thisWKTDictionary.(package private) final voidforEachValue(Consumer<Object> addTo) Adds all definition values to the given supplier.org.opengis.metadata.citation.CitationReturns the authority or specification that defines the codes recognized by this factory.getAuthorityCodes(Class<? extends org.opengis.referencing.IdentifiedObject> type) Returns the set of authority codes for objects of the given type.Returns all namespaces recognized by this factory.org.opengis.util.InternationalStringgetDescriptionText(String code) Gets a description of the object corresponding to a code.private ObjectgetOrCreate(String code, boolean create) Returns the object associated to the given code.voidload(BufferedReader source) Adds to this factory all definitions read from the given source.private org.opengis.referencing.IdentifiedObjectparseAndAdd(String codespace, String version, String code, String wkt, DefaultIdentifier defaultIdentifier) Parses immediately the given WKT and caches the result under the given identifier.private ResourcesConvenience methods for resources in the language used for error messages.private static StringtrimOrNull(Object value) Trims the leading and trailing spaces of the string representation of given object.private StringunexpectedText(int lineNumber, String wkt, int end) Produces an error message for unexpected characters at the end of WKT string.private voidIfauthorityis not yet defined, computes a value fromID[…]found in all WKT strings.Methods inherited from class org.apache.sis.referencing.factory.GeodeticAuthorityFactory
createCartesianCS, createCompoundCRS, createCoordinateOperation, createCoordinateReferenceSystem, createCoordinateSystem, createCoordinateSystemAxis, createCylindricalCS, createDatum, createDerivedCRS, createEllipsoid, createEllipsoidalCS, createEngineeringCRS, createEngineeringDatum, createExtent, createFromCoordinateReferenceSystemCodes, createGeocentricCRS, createGeodeticDatum, createGeographicCRS, createImageCRS, createImageDatum, createOperationMethod, createParameterDescriptor, createParametricCRS, createParametricCS, createParametricDatum, createPolarCS, createPrimeMeridian, createProjectedCRS, createSphericalCS, createTemporalCRS, createTemporalDatum, createTimeCS, createUnit, createVerticalCRS, createVerticalCS, createVerticalDatum, newIdentifiedObjectFinder, toString, trimNamespaceMethods inherited from class org.apache.sis.util.iso.AbstractFactory
getVendorMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.opengis.util.Factory
getVendor
-
Field Details
-
authority
private volatile org.opengis.metadata.citation.Citation authorityThe organization or specification that defines the codes recognized by this factory. May benullif not yet determined.- See Also:
-
authorities
-
codespaces
Code spaces of authority codes recognized by this factory. This set is computed from the"ID[…]"elements found in WKT definitions.- See Also:
-
codeCaches
Cache of authority codes computed bygetAuthorityCodes(Class). This cache can be cleared at any time; values are recomputed when needed. -
parser
The parser to use for creating geodetic objects from WKT definitions. Subclasses can modify theWKTFormatconfiguration in their constructor, but should not use it directly after construction (for thread safety reasons). -
lock
The write lock forparserand the read/write locks fordefinitionsaccesses. Allparserusages afterWKTDictionaryconstruction shall be synchronized by theReadWriteLock.writeLock().Implementation note: we manage the locks ourselves instead of using aConcurrentHashMapbecause if adefinitionsvalue needs to be computed, then we need to block all other threads anyway sinceparseris not thread-safe. Consequently, the high concurrency capability provided byConcurrentHashMapdoes not help us in this case. -
definitions
CRS definitions associated to authority:version:code keys. Keys are authority codes, ignoring code space (authority) and version. For example, in "EPSG:9.1:4326" the key would be only "4326". Values can be one of the following 4 types:StoredTree: this is the initial state when there are no duplicated codes. This is the root of a tree of WKT keywords with their values as children. A tree can be parsed later as anIdentifiedObjectwhen first requested.IdentifiedObject: the result of parsing theStoredTreewhencreateObject(String)is invoked for a given authority code. The parsing result replaces the previousStoredTreevalue.WKTDictionary.Disambiguation: if the same code is used by two or more authorities or versions, then above-citedStoredTreeorIdentifiedObjectalternatives are wrapped in aWKTDictionary.Disambiguationobject.Stringif parsing failed, in which case the string is the error message.
Synchronization
All read operations in this map shall be synchronized by thelock.readLock()and write operations synchronized by thelock.writeLock().
-
-
Constructor Details
-
WKTDictionary
public WKTDictionary(org.opengis.metadata.citation.Citation authority) Creates an initially empty factory. The authority can specified explicitly or inferred from the WKTs. In the latter case (when the given authority isnull), an authority will be inferred from allID[…]orAUTHORITY[…]elements found in WKT strings as below, in preference order:- Most frequent
CITATION[…]value. - If there is no citation, then most frequent code space
in
ID[…]orAUTHORITY[…]elements.
load(BufferedReader)oraddDefinitions(Stream)after construction.- Parameters:
authority- organization that defines the codes recognized by this factory, ornull.
- Most frequent
-
-
Method Details
-
updateAuthority
private void updateAuthority()Ifauthorityis not yet defined, computes a value fromID[…]found in all WKT strings. This method should be invoked after new WKTs have been added. -
load
Adds to this factory all definitions read from the given source. Each Coordinate Reference System (or other geodetic object) is defined by a string in WKT format. The key associated to each object is given by theID[…]orAUTHORITY[…]element, which is typically the last element of a WKT string and is mandatory for definitions in this file.WKT strings can span many lines. All lines after the first line shall be indented with at least one white space. Non-indented lines start new definitions.
Blank lines and lines starting with the
#character (ignoring white spaces) are ignored.Aliases for WKT fragments
Files with more than one WKT definition tend to repeat the same WKT fragments many times. For example, the sameBaseGeogCRS[…]element may be repeated in everyProjectedCRSdefinitions. Redundant fragments can be replaced by aliases for making the file more compact, easier to read, faster to parse and with smaller memory footprint.Each line starting with "
SET <identifier>=<WKT>" defines an alias for a fragment of WKT string. The WKT can span many lines as described above. Aliases are local to the file where they are defined. Aliases can be expanded in other WKT strings by "$<identifier>".Validation
This method verifies that definitions have matching quotes, balanced parenthesis or brackets, and valid number or date formats. It does not verify WKT keywords or geodetic parameters. See class javadoc for more details.Example
An example is available here.- Parameters:
source- the source of WKT definitions.- Throws:
org.opengis.util.FactoryException- if the definition file cannot be read.
-
addDefinition
Adds the definition of a CRS (or other geodetic objects) from a tree of WKT elements. The authority code is inferred from theID[…]orAUTHORITY[…]element. Caller must own the write lock before to invoke this method.updateAuthority()should be invoked after this method.- Parameters:
tree- a tree of WKT elements.- Throws:
IllegalArgumentException- if acodespace:version:codetuple is assigned twice.FactoryDataException- if the WKT does not have anID[…]orAUTHORITY[…]element.- See Also:
-
addDefinitions
Adds definitions of CRS (or other geodetic objects) from Well-Known Texts. Blank strings are ignored. Each non-blankStringshall contain the complete definition of exactly one geodetic object. A geodetic object cannot have its definition splitted in two or moreStrings.The key associated to each object is given by the
ID[…]orAUTHORITY[…]element, which is typically the last element of a WKT string and is mandatory. WKT strings can contain line separators for human readability.- Parameters:
objects- CRS (or other geodetic objects) definitions as WKT strings.- Throws:
org.opengis.util.FactoryException- if a WKT cannot be parsed, or does not contain anID[…]orAUTHORITY[…]element, or if the samecodespace:version:codetuple is used for two objects.
-
parseAndAdd
private org.opengis.referencing.IdentifiedObject parseAndAdd(String codespace, String version, String code, String wkt, DefaultIdentifier defaultIdentifier) throws org.opengis.util.FactoryException Parses immediately the given WKT and caches the result under the given identifier. This method is invoked only if subclass overridesfetchDefinition(DefaultIdentifier)for producing WKT on-the-fly.- Parameters:
codespace- the authority (or other kind of code space) providing CRS definitions.version- version of the CRS definition, ornullif unspecified.code- code allocated by the authority for the CRS definition.wkt- the Well-Known Text to parse immediately.defaultIdentifier- identifier to assign to the object if the WKT does not provide one.- Returns:
- the parsed object.
- Throws:
org.opengis.util.FactoryException- if parsing failed.
-
fetchDefinition
protected String fetchDefinition(DefaultIdentifier identifier) throws org.opengis.util.FactoryException Fetches the Well-Known Text for a user-specified identifier not found in thisWKTDictionary. Subclasses can override this method if WKT strings are not loaded or specified in advance, but instead fetched when first needed. An example of such scenario is WKTs provided by the"spatial_ref_sys"table of a spatial database. If no WKT is found for the given identifier, then this method returnsnull.On input,
identifiercontains only the pieces of information provided by user. For example if user invokedcreateGeographicCRS("Foo"), then the identifier code will be"Foo"but the codespace and version will be undefined (null). On output,identifiershould be completed with missing code space and version (if available).Overriding
The default implementation returnsnull. If a subclass overrides this method, then it should also overridegetAuthorityCodes(Class)becauseWKTDictionarydoes not know the codes that this method can recognize.- Parameters:
identifier- the code specified by user, possible with code space and version.- Returns:
- Well-Known Text (WKT) for the given identifier, or
nullif none. - Throws:
org.opengis.util.FactoryException- if an error occurred while fetching the WKT.
-
unexpectedText
Produces an error message for unexpected characters at the end of WKT string.- Parameters:
lineNumber- line where the error occurred.wkt- the WKT being parsed.end- end of WKT parsing.- Returns:
- message to give to exception constructor.
-
resources
Convenience methods for resources in the language used for error messages. -
trimOrNull
Trims the leading and trailing spaces of the string representation of given object. If null, empty or contains only spaces, then this method returnsnull. -
forEachValue
Adds all definition values to the given supplier. This is for testing purposes only. This method performs no locking because it is not needed for current JUnit tests.- See Also:
-
getAuthority
public org.opengis.metadata.citation.Citation getAuthority()Returns the authority or specification that defines the codes recognized by this factory. This is the first of the following values, in preference order:- The authority explicitly specified at construction time.
- A citation built from the most frequent value found in
CITATIONelements. - A citation built from the most frequent value found in
IDorAUTHORITYelements.
- Specified by:
getAuthorityin interfaceorg.opengis.referencing.AuthorityFactory- Specified by:
getAuthorityin classGeodeticAuthorityFactory- Returns:
- the organization responsible for CRS definitions, or
nullif unknown. - See Also:
-
getCodeSpaces
Returns all namespaces recognized by this factory. Those namespaces can appear before codes in calls tocreateFoo(String)methods, for example"ESRI"in"ESRI:102018". Namespaces are case-insensitive.- Overrides:
getCodeSpacesin classGeodeticAuthorityFactory- Returns:
- the namespaces recognized by this factory.
-
getAuthorityCodes
public Set<String> getAuthorityCodes(Class<? extends org.opengis.referencing.IdentifiedObject> type) throws org.opengis.util.FactoryException Returns the set of authority codes for objects of the given type. Thetypeargument specifies the base type of identified objects.- Parameters:
type- the spatial reference objects type.- Returns:
- the set of authority codes for spatial reference objects of the given type.
- Throws:
org.opengis.util.FactoryException- if an error occurred while fetching the codes.
-
getDescriptionText
public org.opengis.util.InternationalString getDescriptionText(String code) throws org.opengis.util.FactoryException Gets a description of the object corresponding to a code.- Specified by:
getDescriptionTextin interfaceorg.opengis.referencing.AuthorityFactory- Overrides:
getDescriptionTextin classGeodeticAuthorityFactory- Parameters:
code- value allocated by authority.- Returns:
- a description of the object, or
nullifnullif none. - Throws:
org.opengis.referencing.NoSuchAuthorityCodeException- if the specifiedcodewas not found.org.opengis.util.FactoryException- if the query failed for some other reason.
-
createObject
public org.opengis.referencing.IdentifiedObject createObject(String code) throws org.opengis.util.FactoryException Returns an arbitrary object from a code.- Specified by:
createObjectin interfaceorg.opengis.referencing.AuthorityFactory- Specified by:
createObjectin classGeodeticAuthorityFactory- Parameters:
code- value allocated by authority.- Returns:
- the object for the given code.
- Throws:
org.opengis.referencing.NoSuchAuthorityCodeException- if the specifiedcodewas not found.org.opengis.util.FactoryException- if the object creation failed for some other reason.- See Also:
-
getOrCreate
Returns the object associated to the given code.- Parameters:
code- value allocated by authority.create- whether to createIdentifiedObjectfromStoredTree.- Returns:
- the object for the given code, possibly as a
StoredTreeifcreateisfalse. - Throws:
org.opengis.referencing.NoSuchAuthorityCodeException- if the specifiedcodewas not found.org.opengis.util.FactoryException- if the object creation failed for some other reason.
-