This article describes the LuciadLightspeed WMS Server API, which provides a framework to set up a Web Map Service. The WMS
is implemented as a Java servlet with all required request handling facilities and support for different output formats: JPEG,
PNG. Support for Styled Layer Descriptors is also available: clients of a LuciadLightspeed WMS can use remote or embedded
A regular WMS, which does not provide SLD support, contains a number of layers, optionally associated with a number of styles.
Both the layers and styles are each identified by a unique name. The unique names are published in the result of a
GetCapabilities request. Clients can use the unique names in their
GetFeatureInfo requests. The layers and styles are defined on server-side and are in general fixed for a certain period, depending on how
often the capabilities of a server are updated.
A WMS that supports the use of SLD in client requests allows the user to define own styling rules for the layers available at the server. Furthermore, it optionally also allows the user to define custom layers: such user-defined layers define a dataset that is located on a remote server, which can be an OGC Web Coverage Service or Web Feature Service. This requires the WMS to contact the specified remote server, query the necessary data, and style them according to the specified SLD. More information about SLD and its application within a WMS can be found in the OGC Styled Layer Descriptor specification. This developer guide assumes that the reader is familiar with this specification.
Configuring a WMS introduces the main concepts of the WMS Server API and explains how to build a regular WMS server. The main task that remains
for the user of the API is to implement the server-side data repository for the WMS.
The user may choose to read geographic data from files, a database, or any other data source.
Providing support for Styled Layer Descriptors continues this discussion and describes how a WMS server can be built that accepts SLD requests. The WMS Server API is located
in the package
The LuciadLightspeed WMS is a Java HTTP servlet. A Java HTTP servlet must implement the abstract class
javax.servlet.http.HttpServlet, which is located in the Java EE API. The class
TLcdWMSServlet in the WMS Server API provides an implementation of this class. This servlet uses an instance of
ALcdWMSCommandDispatcher to handle all incoming requests. The
ALcdWMSCommandDispatcher instance is created during server startup, and is used throughout the lifetime of the servlet. The creation of an
ALcdWMSCommandDispatcher instance uses a Factory pattern: the method
createWMSCommandDispatcher(ServletConfig) of the factory class
ALcdWMSCommandDispatcherFactory allows to create and return a specific implementation of
ALcdWMSCommandDispatcher. This mechanism is illustrated in Figure 1, “Main classes of the LuciadLightspeed WMS Server API.”.
It is up to the user to provide an implementation of
ALcdWMSCommandDispatcherFactory that initializes a
For convenience, a default implementation
TLcdOGCWMSCommandDispatcherFactory and an abstract extension
ALcdWMSCommandDispatcherFactory are provided that implement the factory method.
This extension returns a
TLcdOGCWMSCommandDispatcher as command dispatcher implementation.
Next to the implementation of the factory method,
ALcdOGCWMSCommandDispatcherFactory adds protected methods that are used
to configure the created
TLcdOGCWMSCommandDispatcher instance at server startup.
This initialization procedure is illustrated in the sequence diagram in Figure 2, “Sequence diagram of the WMS initialization procedure.”.
The following sections describe these configuration methods in more detail.
Each time the server receives a
GetFeatureInfo request, an internal view or map is built containing the layers described in the request parameters. This process is similar
to a stand-alone LuciadLightspeed application:
Data is decoded into models through a model decoder.
Layers are created for each model through a layer factory.
All layers are added to a view or map.
The internal view, its layers and models are all created through factory classes. These factory classes can
be configured by the user of the API, through the
The WMS server uses an
ILcdModelDecoderFactory to create model decoders that load the data.
createModelDecoder(String) is invoked with a data source name as argument and returns an
that can read the data from that source.
The data source can be a single file, an URL, a database, and so on.
The command dispatcher factory must provide an array of one or more valid model decoder factories, or the WMS will not be able to load any data.
To optimize performance,
TLcdOGCWMSCommandDispatcher maintains a cache of models so that they do not need to be decoded on every request.
To decode models, the server does not use the model decoder factories and model decoders directly. Instead, the server uses
ILcdModelProvider which provides central access to all models. A model provider holds a reference to the model decoder factories and uses them
to decode the actual data. The main advantage of this centralized approach is that it allows implementations to define additional
functionality, that is global for all model decoders. A typical example is a caching mechanism, to improve the performance.
The default implementation returns a model provider that maintains a cache for all decoded models. To prevent memory problems,
it makes use of
java.lang.ref.SoftReference objects, which are cleared at the discretion of the garbage collector in response to memory demand. Soft references are
most often used to implement memory-sensitive caches.
In general, it is not necessary to create a custom implementation of
ILcdModelProvider. A situation where it can be useful is when a server needs to be dynamic, in the sense that its capabilities can be updated
at runtime. If a certain dataset has been updated or removed, the cache of the model provider needs to be updated in some
cases. A removed dataset typically does not pose any problems in that case, since the default implementation uses soft references
for the cached models. An updated dataset can cause a problem however, since the cached model will not be up to date anymore.
Configuration of the capabilities further explains the concept of dynamic capabilities.
Once a model decoder has been created with the appropriate model decoder factory, the server is ready to actually load data.
To create layers for the decoded models, the WMS server uses an
The command dispatcher factory must provide an array of one or more valid layer factories, or the WMS will not be able to render any data.
Finally, the created layers are added to an internal view, which is positioned at the requested bounding box and has the requested
dimensions. This view is a
TLcdGXYViewBufferedImage, which is an implementation of the
ILcdGXYView interface using an off-screen image. It does not depend on AWT or Swing components, and is well-suited for generating images
on the server-side to be sent to clients. The construction and initialization of the view is done via the factory class
TLcdWMSGXYViewFactory, returned by default in
TLcdWMSGXYViewFactory creates and initializes regular
TLcdGXYViewBufferedImage instances, but other implementations may be defined that return extensions of
TLcdGXYViewBufferedImage or that set additional configuration properties on a view. For example, if each map returned by a
GetMap request should contain a fixed logo, an implementation could be defined that adds this logo to each created view instance,
by using the method
putCornerIcon() available in
As soon as the WMS server has constructed the view with the requested layers in a
it must be encoded to a pictorial format like JPEG or PNG before it can be sent to the client.
To encode a view, the WMS server uses an
To determine the output format, the interface contains a method
getContentType() which returns a
The command dispatcher factory must provide an array of one or more valid view encoders, or the WMS will not be able to encode a view.
The default implementation in
ALcdOGCWMSCommandDispatcherFactory returns an array containing a subset of the available view encoders
in the package
: Encoder for the JPEG format, MIME type image/jpeg.
: Encoder for the PNG format, MIME type image/png.
GetFeatureInfo request is an optional operation designed to retrieve feature information for a specified location on a map. When the server
receives such a request, it automatically searches the objects that are located at the given location in the layers of the
map. The selected objects are then placed in a
ILcdGXYLayerSubsetList, which defines a list of one or more
ILcdGXYLayer subset(s). As soon as the
ILcdGXYLayerSubsetList is created, it is submitted to an
ILcdWMSGetFeatureInfoRequestEncoder. This interface is used to retrieve the feature information from the selected object(s) in the
ILcdGXYLayerSubsetList and to encode it to a specific format. The format of a
ILcdWMSGetFeatureInfoRequestEncoder is determined by a MIME type returned by the method
getContentType(). Which information about the selected objects is actually returned, can be chosen freely by the
ILcdWMSGetFeatureInfoRequestEncoder implementation, as this cannot be specified within a
The creation and initialization of a
ILcdGXYLayerSubsetList with the selected objects is done automatically by the command dispatcher.
The initialization and registration of one or more
ILcdWMSGetFeatureInfoRequestEncoder implementations is left to the user of the API,
because the user needs to decide which output formats for a
GetFeatureInfo request are available and which information must be returned in practice.
The default implementation of
createWMSGetFeatureInfoEncoders() creates a list of
encoders using the service look-up mechanism. By default the API contains an implementation that can generate the feature
info result as JSON.
To offer support for the
GetFeatureInfo request, an implementation of
createWMSGetFeatureInfoEncoders() must return one or more valid encoders.
Furthermore, the capabilities of the server should reflect that support for the
GetFeatureInfo request is offered:
one or more available layers should be marked queryable and the capabilities should list the available output formats for
How to configure the capabilities of a server is further described in createWMSCapabilitiesDecoder().
The capabilities of a server refer to the content that it offers. This includes a list of the available layers, the supported
output formats, the supported reference systems, and some metadata about the server itself. The capabilities of a server can
be queried by a client using a
GetCapabilities request. To model these capabilities, the WMS server uses the abstract class
ALcdWMSCapabilities. When a client sends a
GetCapabilities request, the information stored in
ALcdWMSCapabilities is encoded to the WMS capabilities format defined by the OGC WMS specification and sent to the client.
Figure 3, “Structure of
ALcdWMSCapabilities” shows the structure of this class. Note that the available layers in the capabilities are of the type
ALcdWMSLayer and not of the type
ILcdGXYLayer is used for displaying the objects of an
ILcdModel in an
ALcdWMSLayer on the other hand is not used for visualization but for declaring that a layer is available at the server. As illustrated
in Figure 3, “Structure of
ALcdWMSLayer instances can be arranged in a hierarchical way. Its most important properties are:
A name that uniquely identifies the layer. It is used by a client to refer to a layer in a request. Through the method
isNameVisible(), one can prevent that a client sees this name when querying the capabilities, making it impossible to use it in requests: this is done when an
ALcdWMSLayeris only used to group a number of layers (for example when they offer related content) instead of representing an actual data layer.
A title, which is a short description of the layer. The title is typically used by clients as display name for the layer.
A property indicating whether the layer is queryable or not. This property indicates whether a client can invoke
GetFeatureInforequests on the layer.
A property indicating whether the layer is opaque or not. If this property is absent or false, then maps made from this layer will generally have significant no-data areas that a client may display as transparent. If this property is true, the layer represents an area-filling coverage. For example, a map that represents topography and bathymetry as regions of differing colors will have no transparent areas, while a map representing vector data such as lines and points will typically have several transparent areas. The opaque declaration should be taken as a hint to the client to place such a layer at the bottom of a stack of maps. Note that this attribute only describes the layer’s data content, not the picture format of the map response.
An optional list of dimensions, which can be used to represent multi-dimensional data. This is further explained in Providing support for multi-dimensional data.
A source name, indicating the data source to use for the layer. The source name is required when a layer can be requested by a client, for example when
true, and when it has no associated dimensions. If the layer has one or more dimensions, there is no exact mapping between the layer and a data source because this relation depends on the dimensional parameters provided by a client. More information regarding multi-dimensional data can be found in Providing support for multi-dimensional data. If the layer does not have any dimensions, the server uses the source name to decode an
ILcdModelcontaining the data. This information is not part of the capabilities that are sent to the client.
The full list of properties can be found in the LuciadLightspeed reference documentation.
The implementation of the interface
ILcdWMSCapabilitiesProvider is the main entry point to determine
which data is served by the WMS server.
The interface is built such that for operations other than GetCapabilities only a sub-set of the information is requested to handle the request. This allows for implementations that load as little information in memory as possible.
The capabilities provider generates the capabilities only when a client request is performed. It avoids loading (data) in memory during server start up.
The use of the capabilities provider interface makes it easy to create a dynamic WMS server in which the capabilities are updated during the server’s runtime.
Take the following guidelines into account when you are implementing a capabilities provider that is dynamic:
The server keeps working while you are updating the capabilities, so precautions must be taken to prevent any inconsistencies. The capabilities returned by
getCapabilities(ILcdRequest aRequest)should never return an instance that is changed directly. Instead, an implementation should create a new capabilities object representing the most recent capabilities. Or make a clone of the capabilities, apply the changes and set the new capabilities object internally within the provider.
When datasets can be updated, it could be useful to implement a custom
ILcdModelProvideras described in Reading data. The default implementation uses a caching mechanism for all decoded models, which can cause problems in the case of updated data. Removed datasets should not cause any problems however, because soft references are used in the model cache.
The default capabilities provider created within
TLcdOGCWMSCommandDispatcherFactory uses the capabilities
decoder to read from configuration what data needs to be served to client applications.
During server startup, a capabilities decoder is created using the method
ALcdOGCWMSCommandDispatcherFactory, as illustrated in the sequence diagram in Figure 2, “Sequence diagram of the WMS initialization procedure.”.
Subsequently, the method
decodeWMSCapabilities(String) on the capabilities decoder is invoked to retrieve the capabilities.
The single parameter in the method
decodeWMSCapabilities(String) contains the source name of this capabilities file.
It is stored as a servlet parameter in the deployment descriptor of the WMS servlet, which is described in Installing an OGC web server.
This method is used to apply additional configuration settings. By default, the JAI tile cache size is configured. These settings are further explained in Installing an OGC web server. One can override this method to apply additional settings.
The command dispatcher factory class contains a default set of references parsers that are used to convert coordinate
reference systems (CRS) from a string representation to an
ILcdXYWorldReference needed within the WMS server.
During the creation of the method it also populates a list of coordinate reference systems for publishing within the WMS capabilities as being supported. This list of CRSes is populated by default with the most common used references.
It is possible to configure the list either programmatically or by configuration.
When configuring it programmaticly you have two options.
One is to override the
createReferenceParsersSFCT method of the
You can add references to the list or replace the contents of the list entirely with the ones you want.
A second option is to do this entirely within the
ILcdWMSCapabilitiesProvider where you have control over the
list of CRSes that are put within the
Next to this the list can be controlled through configuration via the web deployment descriptor.
Controlling the list through configuration is explained in Installing an OGC web server.
The OGC WMS specification introduces additional concepts that can ease the integration of multi-dimensional datasets. Multi-dimensional
datasets are spatial datasets that are similar in nature but differ in time, elevation or other dimensions. Common examples
are daily composite images of the Earth and weather charts for various heights. Instead of defining a new layer in the capabilities
for each data source in a multi-dimensional dataset, the OGC WMS specification allows to define one layer with one or more
dimensions. These dimensions each have a dimensional axis with a unit of measure and a set of allowable values. This approach
results in a more compact and orderly representation of the dataset in the capabilities of the server. A client can retrieve
the available dimensions for a layer through the capabilities, and use this information to specify one or more dimension values
GetFeatureInfo request. The server uses these values to determine the correct data source.
The LuciadLightspeed WMS Server API provides support for multi-dimensional data. To include support in an implementation, there are two tasks that need to be carried out:
The required dimensions need to be defined in the capabilities for the correct layers.
The server must know how to map a certain request containing dimensional parameters to a concrete data source.
These steps are explained in the following paragraphs.
A dimension is represented by the class
ALcdWMSDimension. It holds the dimension-related parameters, such as the name, the unit, and so on. The available values or intervals for
ALcdWMSDimension are represented by
TLcdWMSDimensionExtent. One or more
ALcdWMSDimension objects can be added to an
ALcdWMSLayer to define a multi-dimensional layer. When a client sends a
GetCapabilities request, the dimension information will be encoded automatically in the returned capabilities document. How to configure
the capabilities of a server is described in createWMSCapabilitiesDecoder().
As explained in Reading data, the WMS server uses an
ILcdModelProvider as a central access point for all data sources. Its single method
getModel(String) retrieves an
ILcdModel for a given source name. The source name itself is retrieved from the
ALcdWMSLayer requested by a client. In case of a multi-dimensional layer however, there is no exact mapping between the
ALcdWMSLayer and a source name. In this situation, determining the source name depends both on the
ALcdWMSLayer and dimensional parameters provided by the client. To model this step, an extension of
ILcdModelProvider is introduced, namely
ALcdMultiDimensionalModelProvider. This class serves two purposes:
Resolving the dimensional parameters supplied by the client. For each requested layer, the server checks if there are any dimensions defined for the layer at the server. If positive, it analyzes the client’s request to find any applicable dimensional parameters. For each dimension of the layer, a corresponding
TLcdWMSDimensionExtentis created that represents the client’s parameter (may be
null, if the client has not included a parameter for a dimension) and resolved through the method
getDimensionExtent(ALcdWMSLayer, ALcdWMSDimension, TLcdWMSDimensionExtent, TLcdWMSRequestContext)in
ALcdMultiDimensionalModelProvider. The purpose of this method is to determine the correct dimensional parameter, based on the parameter provided by the client. For example, if a supplied value does not match any available value, an implementation could perform interpolation to find a nearest value that is correct. The exact implementation requirements of this method can be found in the LuciadLightspeed reference documentation. By default, an implementation is provided that offers support for dimensions that use numeric values or intervals. For dimensions that use other units, such as specific date formats or non-numeric values and intervals, a proper implementation must be provided.
Mapping the resolved dimensional parameters to a concrete data source. After resolving the supplied dimensional parameters, the data source is decoded. For this purpose,
ALcdMultiDimensionalModelProviderdefines an abstract method
getModel(ALcdWMSLayer, ALcdWMSDimension, TLcdWMSDimensionExtent, TLcdWMSRequestContext)which maps a layer and the corresponding resolved dimensional parameters on an
ILcdModel. Implementations can rely on the regular
getModel(String)method, by determining a concrete data source name.