This article provides more details about working with layers in LuciadLightspeed, and explains how to:

  • Access layers added to the view

  • Group layers into nodes

  • Manage layers in layer hierarchies

Accessing layers in a view

Both ILspView and ILcdGXYView implement the ILcdLayered interface to support the addition of layer sequences. A layer list of the type ILcdLayered is suitable for organizing layers with data sets that are not related to each other and that you want to access sequentially. These are shown in Figure 1, “a sequential list of layers”. The numbers refer to the index numbers of the layers in the layer list.

fundamentals layer list
Figure 1. a sequential list of layers

Each layer in a view has an index number that ranges from 0 to the total number of layers in the list minus one (layerCount()-1). The layers are ordered by their index number, and painted in the view in the order of addition. The top layer, identified with layerCount()-1, is the layer that was added to the view last, and is painted last in the view.

To organize your layers thematically, you can add related layers to a layer node and create a hierarchical layer structure, as explained in Grouping layers.

Grouping layers

If you have layers containing data sets that logically belong together, you can group those layers.

Using ILcdLayerTreeNode to group layers

For the purpose of grouping layers, LuciadLightspeed provides the interface ILcdLayerTreeNode. It extends both the ILcdLayer and ILcdLayered interfaces, as shown in Figure 2, “ILcdLayerTreeNode allows you to group layers”.

ILcdLayerTreeNode
Figure 2. ILcdLayerTreeNode allows you to group layers

ILcdLayerTreeNode allows you to create a layer node. A layer node acts as a layer by itself, but also lets you add other layers and layer nodes as child layers.

Once you have created a layer node and added the child layers, you can add the layer node to the view. The child layers are automatically added to the view as well, because they are part of the layer node. Similarly, if you remove a layer node from a layer list or a view, the child layers will be removed as well.

An ILcdLayerTreeNode is empty by default. To associate an ILcdLayerTreeNode with a model, use the method setModel. In practice, most layer nodes with child layers are themselves empty, though.

Program: Create a layer node with the flight plan layer and the waypoint layer
// Create a combined layer that holds both the waypoint- and the flight plan layer
TLspLayerTreeNode combinedLayer = new TLspLayerTreeNode("Combined Layer");
combinedLayer.addLayer(flightPlanLayer);
combinedLayer.addLayer(waypointLayer);
// Add the combined layer to the view
aView.addLayer(combinedLayer);

Figure 3, “The Combined layer with the layers for the flight plans and way points” shows the layer group with the flight plans and way points grouped in a layer node with the Combined layer name. It also shows the layer index numbers returned when the layers in the view are enumerated.

layer list grouped
Figure 3. The Combined layer with the layers for the flight plans and way points

Grouping layers in GXY views is very similar to layer grouping in Lightspeed views.

Program: Create a layer node with the flight plan layer and the waypoint layer in a GXY view shows how to create a layer node in a GXY view, and add the layers for the flight plans and the way points as child layers, resulting in the Combined layer.

Program: Create a layer node with the flight plan layer and the waypoint layer in a GXY view
TLcdGXYLayerTreeNode combinedLayer = new TLcdGXYLayerTreeNode("Combined layer");
combinedLayer.addLayer(flightplanLayer);
combinedLayer.addLayer(waypointLayer);

Each ILcdLayer and ILcdLayerTreeNode may appear only once in one hierarchical layer structure.

Keep in mind that all methods inherited from ILcdLayer only apply to the layer node itself, as a layer. They do not affect the child layers of the layer node. For example, calling ILcdLayer.setVisible(boolean) for a layer node only changes the visibility of the layer node and not of its child layers. On the other hand, all methods inherited from ILcdLayered just apply to the child layers, and not to the node. For example, the ILcdLayered method layerCount() returns the number of child layers of a given layer node.

Working with layers in a tree structure

Accessing layers in a view explained how to access layers sequentially. If you have grouped your layers into nodes, however, you may need to access the layers in your view as a hierarchy. To this end, all implementations of ILspView and ILcdGXYView extend both ILcdLayered and ILcdTreeLayered.

These allow you to approach the layers in a view in two manners. ILcdLayered allows you to access all layers in the view regardless of their position in the layer hierarchy. ILcdTreeLayered provides access to the layers through an additional root node: a layer node that is inserted at the top of the layer hierarchy, and provides a gateway to the layer tree structure through its child layers.

The following sections use the view layer structure in Figure 4, “An example of a view with grouped layers” as an example to provide more information about each approach.

examplelayertree
Figure 4. An example of a view with grouped layers

Approaching the view as a flat list of layers

A view allows you to perform all the operations defined in the ILcdLayered interface on the hierarchical structure as if it were a flat list, with the layers listed in their painting order. If you call the layers method on the view, it returns such a flat layer list. For example, Figure 5, “The view approached as a flat list” displays the layers of Figure 4, “An example of a view with grouped layers” as a flat list. Calling the layers method results in the layers Grid, San Francisco, Layer node 1, Way Points, Flight Plans, Layer node 2, Trajectories and Tracks.

layered list
Figure 5. The view approached as a flat list

You can perform the same operations on the layers in the layer tree as on the layer list, such as enumeration and reordering. For more information about layer reordering, see Layer ordering.

If you perform an operation on the layers in the flat list, it will have an effect on the layer tree. If a layer is removed from the flat list presentation, for example, it will be removed from the hierarchical layer structure as well. This works both ways: if a layer is removed from the hierarchical structure, for example, it will also be removed from the flat list representation.

Be careful when copying all layers from one view to another. For more information, refer to Copying layer nodes between layer trees in GXY views.

Approaching the view as a layer tree

You can approach a view as a layer tree by exposing a root node for the tree. To access the root node, call the method getRootNode, and access all tree levels, including layer nodes and layer descendants, from there. If you call the layers method on the root node, it returns its child layers.

Figure 6, “An example of view layers approached from the root node” illustrates the approach of the layers in Figure 4, “An example of a view with grouped layers” through a root node. Calling the layers method on the root node results in the layers Grid, San Francisco, Layer node 1, and Layer node 2.

tree layered
Figure 6. An example of view layers approached from the root node

The root node of a view is not considered a regular layer node. This means that you cannot retrieve it using containsLayer. You cannot move or remove it either.

Approaching all descendants of a layer node

By default, calling layers on a layer node, such as the root node, results in its direct descendants only. The returned list only includes the child layers of the node. To work with all descendants of a layer node, you can make use of the utility class TLcdLayerTreeNodeUtil. It provides methods to access all layers in a layer node, and retrieve the hierarchical relations between the grouped layers.

For more information, see the API reference documentation.

Layer ordering

How are layers ordered?

In general, the order of addition determines the layer order in a view. The first layer is assigned layer index zero in an ILcdLayered list, is painted first and ends up at the bottom of the layer stack. Each extra layer is added to the layer stack, and painted on top of the previous layer.

In Lightspeed views, you can use ILspPaintingOrder to further set up layer ordering. You can set its default implementation TLspPaintingOrder on the ILspView to ensure that layers are painted according to their indexing order, but that selected objects and labels are painted on top.

Within layer nodes, child layers are added in the same order as in the view. You can influence the layer order in nodes using ILcdInitialLayerIndexProvider. Each ILcdLayerTreeNode, including the root node of a layer tree, can have such an ILcdInitialLayerIndexProvider. It determines the appropriate index for a new layer, if it is added without a specific index. This allows you to centralize the layer ordering logic in the node, and base it on the type of data that is loaded. For example, you could set up an ILcdInitialLayerIndexProvider that adds vector data on top of typical background data like raster data.

Lightspeed views work with a specific implementation of this interface, TLspInitialLayerIndexProvider. It offers automatic correct layer placement based on the type of the layer: For instance, BACKGROUND layers are moved as far as possible towards the bottom, while INTERACTIVE layers are moved as far as possible to the top.

Moving layers up and down

Moving tree layers in a LuciadLightspeed application can mean two things:

  • Move layers up and down in the layer painting order. To move a layer up in the painting order, you move it to a higher index, closer to the top of the list order. As a result, the moved layer may end up on top of other layers, and could cover up those layers.

  • Move layers up and down in GUI widgets displaying the layer tree.

LuciadLightspeed allows you to move layers up and down in the GUI, and change the painting ordering at the same time. This also works the other way around: if you change the painting order, the layers will also move up and down in the GUI.

In a GXY view, you can also choose to disconnect the painting order and GUI layer order, so that one does not influence the other. See Independently ordering layers in a GXY view for more information.

Moving a layer to a different index

To change the painting order of one layer in an ILcdLayered list, you can move it to another index using the method moveLayerAt. Program: Moving a layer to the top of the layer list in a Lightspeed view shows how to move a layer of the view to the top of the layer list so that it is displayed on top of the other layers in the view.

Program: Moving a layer to the top of the layer list in a Lightspeed view
ILspLayer layer = view.addLayersFor(model).iterator().next();
view.moveLayerAt(view.layerCount() - 1, layer);

When a layer node is moved, the child layers also move by default.

All actions that rely on the painting order of the layers, such as selecting objects in a layer, should use the layers method of the view, and not the layer tree structure.

Independently ordering layers in a GXY view

In the event that you want to move layers around in the layer tree of a GXY view without affecting the painting order, you can pass a TLcdIndependentOrderTreeLayeredSupport object to the view constructor when you create the view. You can also use TLcdIndependentOrderTreeLayeredSupport to move layers around in the painting order, without affecting the layer order in the hierarchical tree. Moving a layer node in the layer list in independent order only moves the node and not its child layers.