Problem Description

You have added a military layer to you Lightspeed view containing multiple icon symbols. You have set the azimuth modifier for (some of) those icon symbols, yet the "Direction of Movement Indicator" arrow is not visible or hidden underneath other layers.

Your map might look something like this:

directionofmovement
Figure 1. Direction of Movement Arrows hidden by other layer

Cause

This is caused by the paint representation configuration. By default, the movement indication arrows are painted with a separate paint representation in LuciadLightspeed (see TLspMS2525bLayerBuilder#ARROW_PAINT_REPRESENTATION). The purpose of this paint representation was to make sure that all "Direction of Movement Indicator" arrows are drawn underneath the military icons symbols. This is especially useful when you have multiple military layers, in such a case, arrows often overlap with icon symbols, which obstructs the icon of the symbols and makes them difficult to recognize. Another advantage is that you can easily switch the "Direction of Movement Indicator" arrows on and off using the ILspLayer#setVisible method. However, the default TLspPaintingOrder for Lightspeed views pains objects with the arrow paint representation before objects with the body paint representation (sere BODY paint representations). This means that all your non-background layers (e.g. a SHP file layer) are painted after the arrows are painted. This ensures that the arrows are always painted underneath the icon symbols as a side effect, all other objects are also painted on top of them.

Solution

One solution is to take full control over the view’s painting order by plugging in a custom ILspPaintingOrder. This painting order can be set directly on the ILspView using the setPaintingOrder method. An ILspPaintingOrder is essentially a Comparator used to sort the various ILspPaintingOrder.PaintStep objects before a (re)paint of the view. This sorting will determine the priority in which various objects will be painted. The code snippet bellow shows an example ILspPaintingOrder that sorts the ILspPaintingOrder.PaintStep objects in such a way so that the "Direction of Movement Indicator" arrows are painted with the same priority as the military symbols.

After setting this ILspPaintingOrder on the ILspView, the map at above looks like this:

directionofmovementfixed
Figure 2. Direction of Movement Arrows are now visible
Program: Custom ILspPaintingOrder
  public class ArrowPaintingOrderWrapper extends TLspPaintingOrder {

    private final ILspPaintingOrder fDelegate;

    public ArrowPaintingOrderWrapper(ILspView aView) {
      super(aView);
      fDelegate = aView.getPaintingOrder();
    }

    @Override
    public int compare(PaintStep aOnePaintStep, PaintStep aOtherPaintStep) {
      // extract paint states and paint representations from the paint steps
      TLspPaintRepresentationState prs1 = aOnePaintStep.getPaintRepresentationState();
      TLspPaintRepresentationState prs2 = aOtherPaintStep.getPaintRepresentationState();

      TLspPaintRepresentation onePaintRepresentation = prs1.getPaintRepresentation();
      TLspPaintRepresentation otherPaintRepresentation = prs2.getPaintRepresentation();

      TLspPaintState onePaintState = prs1.getPaintState();
      TLspPaintState otherPaintState = prs2.getPaintState();

      // if the paint representation is the ARROW_PAINT_REPRESENTATION,
      // we create an adapted paint step with a BODY paint representation
      // instead of the ARROW_PAINT_REPRESENTATION
      // and compare them as normal
      PaintStep adaptedOneStep = TLspMS2525bLayerBuilder.ARROW_PAINT_REPRESENTATION.equals(onePaintRepresentation)
                                 ? new PaintStep(aOnePaintStep.getLayer(),
                                                 TLspPaintRepresentationState.getInstance(TLspPaintRepresentation.BODY, onePaintState))
                                 : aOnePaintStep;

      PaintStep adaptedOtherStep = TLspMS2525bLayerBuilder.ARROW_PAINT_REPRESENTATION.equals(otherPaintRepresentation)
                                   ? new PaintStep(aOtherPaintStep.getLayer(),
                                                   TLspPaintRepresentationState.getInstance(TLspPaintRepresentation.BODY, otherPaintState))
                                   : aOtherPaintStep;

      int comparison = fDelegate.compare(adaptedOneStep, adaptedOtherStep);
      if (comparison != 0) {
        return comparison;
      }

      // if the comparison matches,
      // compare by sort order
      int oneSortOrder = onePaintRepresentation.getSortOrder();
      int otherSortOrder = otherPaintRepresentation.getSortOrder();

      return Integer.compare(oneSortOrder, otherSortOrder);
    }
  }