Controlling the paint order of objects in a single layer and a single paint representation

Within a single paint representation of a single layer, you can control the order in which objects — or parts of objects — are painted. To do so, you can set the zOrder property on the styles. Styles of the same type are painted from the lowest Z-order to the highest Z-order, so styles with the highest Z-order will be painted on top.

The Z-order works in 2D views.

When you are using a 3D view, the Z-order affects certain cases only. For example, when you are visualizing points using a TLspIconStyle, the Z-order is respected when the icons are draped on the terrain. However, when you are not draping the icons, the painting order is determined by the relative position of the point compared to the camera.

Controlling the paint order of objects in different layers

Z-order only affects the paint order of objects within the same layer. However, there may be cases where you want to paint certain elements of one layer above certain elements of another layer. If it is not a viable option to re-organize the elements in different layers to match the desired paint order, you can still achieve this by introducing a new TLspPaintRepresentation.

For example, a custom TLspPaintRepresentation can be defined as follows:

private static final TLspPaintRepresentation BOUNDS_BODY = TLspPaintRepresentation.getInstance("BOUNDS_BODY", 50);

Note the sortOrder parameter, which determines the order in which the paint representations are painted. TLspPaintRepresentation.BODY has a sort order of 100, while TLspPaintRepresentation.LABEL has 200. This means that labels are painted on top of regular geometries, regardless of the layer they’re in, and a custom paint representation with sort order 50 gets painted below both of those.

In order to make use of our custom paint representation, you need to configure a painter and ALspStyler for it on the affected layers:

Program: Configuring a custom TLspPaintRepresentation
TLspStyler styler = new TLspStyler();
styler.addStyles(
    new BoundsStyler(),
    TLspFillStyle.newBuilder().color(new Color(0.5f, 0.5f, 0.5f, 0.2f)).build(),
    TLspLineStyle.newBuilder().color(new Color(0.5f, 0.5f, 0.5f, 0.8f)).build());

TLspShapePainter painter = new TLspShapePainter();
painter.setStyler(TLspPaintState.REGULAR, styler);
painter.setStyler(TLspPaintState.SELECTED, styler);
painter.setStyler(TLspPaintState.EDITED, styler);
aLayer.addPaintRepresentation(BOUNDS_BODY);
aLayer.setPainter(BOUNDS_BODY, painter);

The painter now decides which objects are painted for that given paint representation.

See also samples/lightspeed/customization/paintrepresentation for the full sample code.

Controlling the paint order between layers and paint representations

Finally, you can determine the painting order of layers and their paint representations in a view through an implementation of ILspPaintingOrder. You can retrieve ILspPaintingOrder from an ILspView, or set it on an ILspView. This can be useful when you need to change the paint order of existing paint representations. For example, if you want to change the default order such that regular labels are not obscured by selected bodies.

For most users, the default implementation, TLspPaintingOrder, should be sufficient. It ensures that:

  • Layers are painted in the order of the layer tree in the view.

  • Selected objects are painted on top.

  • Labels appear above the domain object to which they belong.

For more information about implementing custom ordering behavior, see the API documentation of ILspPaintingOrder and TLspPaintingOrder.

An example use case for installing a custom painting order is: layer A is located above layer B in the layer tree of a view. Consequently, you want to ensure that selected objects from layer B are never painted on top of objects from layer A.