What is it ?
A WMS client requests images from the WMS server. The client can do this in different ways:
-
Requesting a single image: the client requests map data according to the current bounds or dimensions of the view.
If the size of your view is large, it can take some time to retrieve the corresponding map data from the WMS service, depending on the available bandwidth and performance of the service.
A new image for the whole map must be requested each time the user navigates the map.
-
Request multiple tiles: the client can divide the view in different tiles, and send a request to the server for each of those tiles.
When navigating around, the client only needs to request data for the new tiles. This increases the responsiveness of the map compared to requesting a single image.
If the client uses a fixed tile grid, it also becomes easy to cache the tiles on the client side.
A drawback of this approach is that it does not work well with watermarks or labeled data. For example the watermark is typically added by the server on each image, which in this case would mean each tile.
Lightspeed view: switching between tiled and single image requests
For Lightspeed views, you specify the mode on the layer builder. This is illustrated in the following snippets:
String serverURL = "https://sampleservices.luciad.com/wms";
String wmsLayerName = "cities";
//First create the model by decoding a WMS data source
TLcdWMSDataSource dataSource = TLcdWMSDataSource.newBuilder()
.uri(serverURL)
.addLayer(wmsLayerName)
.build();
ILcdModelDecoder decoder = new TLcdOGCWMSProxyModelDecoder();
ILcdModel model = decoder.decodeSource(dataSource);
//Create a layer for the model and use the tiled paint strategy
ILspLayer layer = TLspWMSLayerBuilder.newBuilder()
.model(model)
.paintStrategy(ELcdWMSPaintStrategy.TILED)
.build();
//First create the model
//Start by creating a TLcdWMSDataSource for the coverage
String serverURL = "https://sampleservices.luciad.com/wms";
String wmsLayerName = "cities";
TLcdWMSDataSource dataSource = TLcdWMSDataSource.newBuilder()
.uri(serverURL)
.addLayer(wmsLayerName)
.build();
//Decode the model by passing the datasource to the model decoder
ILcdModelDecoder decoder =
new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));
ILcdModel model = decoder.decodeSource(dataSource);
//Create a layer for the model and use the tiled paint strategy
ILspLayer layer = TLspWMSLayerBuilder.newBuilder()
.model(model)
.paintStrategy(ELcdWMSPaintStrategy.TILED)
.build();
//Add the layer to the Lightspeed view (an ILspView)
view.addLayer(layer);
GXY view: switching between tiled and single image requests
For GXY views, switching between the two approaches is done by replacing the painter on the layer. This is illustrated in following snippets:
String serverURL = "https://sampleservices.luciad.com/wms";
String wmsLayerName = "cities";
//First create the model by decoding a WMS data source
TLcdWMSDataSource dataSource = TLcdWMSDataSource.newBuilder()
.uri(serverURL)
.addLayer(wmsLayerName)
.build();
ILcdModelDecoder decoder = new TLcdOGCWMSProxyModelDecoder();
ILcdModel model = decoder.decodeSource(dataSource);
//Create a layer for the model
TLcdWMSProxyGXYLayerFactory wmsProxyGXYLayerFactory = new TLcdWMSProxyGXYLayerFactory();
//Make sure the layer factory used a tiled painter (this is the default)
wmsProxyGXYLayerFactory.setTiled(true);
ILcdGXYLayer layer = wmsProxyGXYLayerFactory.createGXYLayer(model);
//Wrap the layer with an async layer wrapper to ensure
//that the view remains responsive while data is being painted
ILcdGXYLayer asyncLayer = ILcdGXYAsynchronousLayerWrapper.create(layer);
//Add the async layer to the GXY view (an ILcdGXYView)
view.addGXYLayer(asyncLayer);
//First create the model
//Start by creating a TLcdWMSDataSource for the coverage
String serverURL = "https://sampleservices.luciad.com/wms";
String wmsLayerName = "cities";
TLcdWMSDataSource dataSource = TLcdWMSDataSource.newBuilder()
.uri(serverURL)
.addLayer(wmsLayerName)
.build();
//Decode the model by passing the datasource to the model decoder
ILcdModelDecoder decoder =
new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));
ILcdModel model = decoder.decodeSource(dataSource);
//Create a layer for the model
ILcdGXYLayer layer = new TLcdWMSProxyGXYLayerFactory().createGXYLayer(model);
//Replace the painter provider with a tiled painter
((TLcdGXYLayer) layer).setGXYPainterProvider(new TLcdGXYTiledWMSProxyPainter());
//Wrap the layer with an async layer wrapper to ensure
//that the view remains responsive while data is being painted
ILcdGXYLayer asyncLayer = ILcdGXYAsynchronousLayerWrapper.create(layer);
//Add the async layer to the GXY view (an ILcdGXYView)
view.addGXYLayer(layer);
Quality and performance guidelines for tiled painting
You can use a tiled approach to visualize a WMS layer. Tiled painters retrieve imagery in tiles of a fixed size, at a number of predefined zoom levels. This ensures that imagery can be loaded incrementally, and re-used when navigating in the view.
As a consequence of the tiled painting approach, LuciadLightspeed will interpolate in between these levels, causing more imagery to be loaded than may seem necessary. You can adjust the painting quality using:
-
the
levelSwitchFactor
property onTLspRasterStyle
for Lightspeed views -
the
setQuality
method onTLcdGXYTiledWMSProxyPainter
for GXY views.
A high value of 1, for example, will offer the sharpest imagery possible, but labeled imagery may become too small to read comfortably due to the downscaling. Setting the quality to a lower value, 0.33 for example, will increase performance, and keep labeled imagery at a more realistic size.
Finally, you can improve the GXY warping interpolation quality by calling the setOversamplingRate
method of TLcdGXYTiledWMSProxyPainter
.
As usual, this will also affect performance.