Terrain analysis add-ons

The Terrain Analysis (TEA) add-ons provide a wide range of terrain analysis functions, with matching graphical user interfaces. The TEA functionality has been implemented in six different add-ons:

TLcyContourAddOn:

computes and visualizes height lines for ILcdShape objects;

TLcyExtremePointAddOn:

computes and visualizes highest and lowest points for ILcdShape objects;

TLcyHypsometryAddon:

computes and visualizes hypsometric information for a given layer or the entire view;

TLcyLOSCoverageAddOn:

computes and visualizes line-of-sight coverages (LOS coverages). LOS coverages show the altitude under which aircraft (or helicopters) have to stay in order not to be detected by the radar;

TLcyVisibilityAddOn:

computes and visualizes what parts of one or more objects can be seen from one or more other objects;

TLcyTEAControllerAddOn:

shows a tooltip for elevation data and allows you to inspect the height of an area specified by a line segment.

TLcyViewshedAddOn:

computes and visualizes visibility for a 3D scene composed of terrain, buildings and 3D meshes.

Note that all these add-ons require the Terrain Analysis Engine component. For more information on this component, please consult the TEA developer’s guide.

TLcyLOSCoverageAddOn can make use of a Lightspeed specific technology which allows to speed-up the necessary line-of-sight calculations. It therefore uses OpenCL. Whether to use or not to use this option can be configured in the add-on’s configuration file. Note that if the platform does not meet the hardware requirements, the OpenCL functionality will not be available, independent of the option in the configuration file.

Except for the controller add-on, all TEA add-ons consist of 4 important parts:

  • a back-end class, providing access to the non-GUI related TEA functionality;

  • a GUI factory, creating all GUI elements;

  • a data format, providing persistence for the TEA analysis results;

  • the add-on class itself, which is plugged into Lucy. It binds together the previously mentioned parts.

The controller add-on only contains a back-end class and the add-on class.

Figure 1, “TEA add-on structure” shows the typical structure of a deployed TEA add-on.

tea structure
Figure 1. TEA add-on structure

The GUI actions do not depend on GUI elements, but rather on a central ALcyProperties object, in which GUI elements may freely read and write properties. The GUI actions pass the necessary properties to the back-end methods in order to compute TEA results. The computed results, as well as the GUI property values used to compute them, are then stored in the appropriate TEA layer. The structure and API of these classes gives you the possibility to customize the TEA add-ons in many different ways:

Change the back-end

plug in new algorithms, or change the behavior of the existing ones;

Change the GUI

replace, omit, and add GUI elements, or simply write an entirely new GUI;

Customize the data format

change the layer style or write out TEA results to your custom file format.

The next sections detail how to perform such customizations.

Customizing the GUI

The TEA add-on’s GUI is built around actions, components and panels. The GUI factory is built so that every existing action, component and panel can be replaced. The first step to customize the GUI consists of subclassing the add-on’s GUI factory and subclassing the add-on to return the custom factory. This way, you can easily tap into the various creation methods of the GUI factory.

Adding a GUI element simply comes down to overriding ALcyGUIFactory.createPanel to add your custom element to an existing panel. When you want to replace a GUI element, for example to change its appearance, you can override ALcyGUIFactory.createComponent and return you custom element for the respective GUI identifier. For more information, we refer to the ALcyGUIFactory's reference manual.

The add-on’s application pane tool by default instantiates the GUI using the workspace’s composite workspace preferences. This means that all GUI elements will retrieve and store their values to and from the same ALcyProperties object, as shown in Figure 1, “TEA add-on structure”. The Update action stores a selection of these properties for the selected layer (see the reference documentation for more information). Conversely, the application pane tool updates the properties if a different TEA layer is selected by the user. If you want your GUI value to be linked in this way, simply define a property name for it, store it in the composite workspace preferences, and make sure that your GUI element is updated upon any change of the property. If your GUI value is to be stored in the workspace or if it must be parsed from the add-on’s configuration file, you might have to register a ILcyPropertyConverter for it. For the TEA add-ons, you can add a custom property converter by overriding the createPreferencesTool method.

Customizing the back-end

Every TEA add-on has a specific method that creates its back-end. For example, for TLcyExtremePointAddOn this is createExtremePointBackEnd. You can override this method to return a subclassed implementation of the add-on’s back-end. It is a good idea to pass the addon’s composite workspace preferences to your back-end. This way, you can easily access your custom GUI values, as well as the existing ones.

As an example, sometimes it is insufficient to use the height provider factories registered in the ILcyLucyEnv to retrieve the height data used for the TEA calculations. For example when buildings are added that are placed upon the terrain. In that case, it is possible to use a custom altitude provider in TEA by overriding the createAltitudeProvider method in the back-end.

Customizing the data format

The add-on creates the format by calling its createBaseFormat method. The latter method’s reference documentation describes the model content. The format is easily customized by creating a wrapper for it. For example, to add reading from and writing to your own custom format, you can add your own model decoder and encoder. To change the layer style of a created layer, you could wrap the format’s layer factory and perform your changes after the former finished the creation.

An extension example

As an example, we create a custom line-of-sight coverage add-on that adds a propagation function to the existing list. The actual propagation function is beyond the scope of this sample, so we will just make it return a fixed visibility value. Figure 2, “Adding a custom propagation” shows the desired result of our TEA customization.

custom propagation
Figure 2. Adding a custom propagation

The sample works as follows:

Program: A TEA line-of-sight back-end extension adding a custom propagation function (from samples/lucy/gxy/tea/LOSCoverageBackEnd)
public class LOSCoverageBackEnd extends TLcyLOSCoverageBackEnd {

  /**
   * The property name for our custom propagation function.
   */
  public static final String PROPAGATION_CUSTOM_ID = "customPropagation";
  @Override
  public ILcdLOSPropagationFunction createPropagationFunction(ALcyProperties aProperties) {
    if (PROPAGATION_CUSTOM_ID.equals(aProperties.getString(PROPAGATION_FUNCTION_KEY, ""))) {
      return new LOSPropagationFunction();
    }
    return super.createPropagationFunction(aProperties);
  }
Program: A TEA line-of-sight GUI factory extension replacing the style panel (from samples/lucy/gxy/tea/LOSCoverageGUIFactory)
public class LOSCoverageGUIFactory extends TLcyLOSCoverageGUIFactory {

  public LOSCoverageGUIFactory(ILcyLucyEnv aLucyEnv) {
    super(aLucyEnv);
  }

  @Override
  protected Component createPanel(int aID, ALcyProperties aProperties) {
    if (aID == STYLE_PANEL) {
      return createStylePanel(super.createPanel(aID, aProperties), aProperties);
    }
    return super.createPanel(aID, aProperties);
  }
}
Program: A TEA line-of-sight add-on extension returning our own back-end (from samples/lucy/gxy/tea/LOSCoverageAddOn)
public class LOSCoverageAddOn extends TLcyLOSCoverageAddOn {
  @Override
  protected TLcyLOSCoverageBackEnd createLOSCoverageBackEnd() {
    return new LOSCoverageBackEnd(getLucyEnv());
  }

  @Override
  protected ALcyGUIFactory<Component> createGUIFactory() {
    return new LOSCoverageGUIFactory(getLucyEnv());
  }
}

Further information

To learn more about terrain analysis, we refer to the TEA Developer’s Guide. Also, each add-on’s reference documentation goes deeper into the provided back-end functionality, GUI elements and the associated preferences.