The information in this guide is only available if you purchased the Real-time Engine component

Decluttering labels of moving objects, such as tracks, is a highly specialized and complex task. To help you with that task, the Real-time Engine component offers a continuous label decluttering algorithm through its classes TLcdGXYContinuousLabelingAlgorithm and TLspContinuousLabelingAlgorithm. This algorithm is ideally suited for labeling moving objects: the label of a moving object moves away smoothly if overlap with another label is about to occur, and sudden label jumps are avoided. Each label is visualized at all times, to prevent that essential information is dropped. For each track, you can define a desired location for the labels, relative to the objects they belong to. The labels on the track will gravitate toward that preferred location as a result.

Label decluttering in a Lightspeed view

A Lightspeed view offers basic label decluttering by default, but the Real-time Engine component offers a specialized algorithm suitable for labeling moving objects in a Lightspeed view: TLspContinuousLabelingAlgorithm.

The algorithm offers a number of configuration options:

  • setPadding to add space between labels

  • setReuseLocationsScaleRatioInterval to keep the relative location after zooming in the view

  • setClampOnScreenEdges to specify if labels must always be fully visible, or can be partially outside the view

  • setLabelMovementBehavior to specify when labels should be moved

  • setMinDistance to ensure labels are never too close to their object

  • setMaxDistance to ensure labels are never too far from their object

  • setDisallowedAngle to specify where a label can be positioned around its object

Program: Creating the continuous decluttering algorithm and setting it on a layer. shows how to create an instance of that algorithm and how you configure a TLspLabelStyler to use this algorithm.

Program: Creating the continuous decluttering algorithm and setting it on a layer.
private void setupLabelDecluttering(ILspView view, ILcdModel model) {
  //Configure labeling
  TLspContinuousLabelingAlgorithm labelingAlgorithm = new TLspContinuousLabelingAlgorithm();
  labelingAlgorithm.setReuseLocationsScaleRatioInterval(new TLcdInterval(0, Double.MAX_VALUE));
  labelingAlgorithm.setClampOnScreenEdges(false);
  labelingAlgorithm.setMinDistance(10);
  labelingAlgorithm.setMaxDistance(50);
  labelingAlgorithm.setLabelMovementBehavior(TLspContinuousLabelingAlgorithm.LabelMovementBehavior.REDUCED_MOVEMENT);
  labelingAlgorithm.setPadding(2);
  labelingAlgorithm.setDesiredRelativeLocation(new Point(0, -15));
  labelingAlgorithm.setMaxCoverage(0.30);

  TLspLabelStyler labelStyler = TLspLabelStyler.newBuilder()
                                               .algorithm(labelingAlgorithm)
                                               .group(TLspLabelPlacer.DEFAULT_REALTIME_GROUP)
                                               .build();

  TLspLayer layer = TLspShapeLayerBuilder.newBuilder()
                                         .model(model)
                                         .selectable(true)
                                         .labelStyler(TLspPaintState.REGULAR, labelStyler)
                                         .labelEditable(true)
                                         .labelEditor(new TLspLabelEditor())
                                         .labelScaleRange(new TLcdInterval(2 * 1e-4, Double.POSITIVE_INFINITY))
                                         .layerType(ILspLayer.LayerType.REALTIME)
                                         .culling(false)
                                         .build();
  view.addLayer(layer);
}

To prevent labels from overlapping with specific elements in a view, you can configure the view’s ILspLabelPlacer to use a custom ILspLabelObstacleProvider. You can implement this ILspLabelObstacleProvider to provide a list of TLspLabelObstacle objects. Each of those objects describes the bounds of the obstacle that needs to be avoided in view coordinates.

A possible implementation of a ILspLabelObstacleProvider can be found in samples.realtime.lightspeed.common.LabelObstacleProvider. For more information about labeling, please consult the LuciadLightspeed developer’s guide section on labeling domain objects in a Lightspeed view.

Label decluttering in a GXY view

Just as for Lightspeed views, the Real-time Engine component offers a specialized algorithm suitable for labeling moving objects in a GXY view: TLcdGXYContinuousLabelingAlgorithm.

Its behavior is identical to that of its Lightspeed counterpart TLspContinuousLabelingAlgorithm, and it has the same configuration options.