The Real-time Engine component includes support for the visualization of radar video feeds in any format in a Lightspeed view. The following figure shows an example:

radar
Figure 1. Example of a radar video feed shown in a Lightspeed view

The package samples.realtime.lightspeed.radarvideo demonstrates the functionality discussed in this section.

Connecting to a custom radar feed

To visualize a radar feed, you need to connect to radar raw data and decode it. The radar source can be either a UDP stream or a sample-formatted file. The raw data for each radar sweep is parsed and converted to the input format that is necessary to call the addRadarSweep method of the TLcdRadar class.

Radar raw data includes at least the following fields to represent a radar sweep.

  • Start Azimuth - The azimuth at which the sweep starts, in degrees clock-wise from the up-direction.

  • End Azimuth - The azimuth at which the sweep ends, in degrees clock-wise from the up-direction.

  • Start Cell - The offset in number of cells at which the given sweep starts. You need this when the data of a single sweep line is split over multiple messages, for instance.

  • Cell Length - The radial size of the radar cells, in meters.

  • Amplitudes - The amplitudes of the cells.

radarSweep
Figure 2. Radar sweep representation

Creating a radar layer

The main API class used for radar visualization is TLspRadarVideoLayerBuilder. This builder creates an ILspLayer for models decoded from the raw radar data.

Program: Creating a radar layer using builder (from samples/realtime/lightspeed/radarvideo/RadarVideoLayerFactory)
public ILspEditableStyledLayer createLayer(ILcdModel aRadarModel) {

  ILspEditableStyledLayer radarLayer = TLspRadarVideoLayerBuilder
      .newBuilder()
      .selectable(false)
      .model(aRadarModel)
      .build();

  return radarLayer;

Radar video layers work with live data, and update automatically as new data is received. You can customize the appearance of the radar feed using TLspRadarVideoStyle. See the API reference documentation for this class for more detail about the available settings.

TLspRadarVideoLayerBuilder supports the same styling constructs as TLspShapeLayerBuilder. As such, you can paint decorations, range rings for example, on top of the radar feed without having to create an additional layer.

Creating a radar model

TLcdRadar is used to display radar data composed of radar sweeps. The position of the radar is defined by an ILcdModelReference in the model. The distance out from the center of the radar position indicates range, and the angle around the center is the azimuth to the target.

Program: Creating a radar model shows how to create a radar model by using an instance of TLcdRadar.

Program: Creating a radar model (from samples/realtime/lightspeed/radarvideo/format/SampleRadarVideoConnector)
ILcdModelReference modelReference = new TLcdGridReference(
    new TLcdGeodeticDatum(),
    new TLcdAzimuthalEquidistant(fRadarPosition.getX(), fRadarPosition.getY()),
    0, 0,
    1, 1,
    Math.toRadians(0)
);
TLcdDataType radarType = TLcdRadarVideoDataTypes.RADAR_VIDEO_DATA_TYPE;
TLcdVectorModel model = new TLcdVectorModel(
    modelReference,
    new TLcdDataModelDescriptor(fSourceName, "Radar", "Radar",
                                radarType.getDataModel(), Collections.singleton(radarType), Collections.singleton(radarType))
);

TLcdRadar radar = new TLcdRadar(radarType);
model.addElement(radar, ILcdModel.NO_EVENT);

Adding radar sweeps

You can use the addRadarSweep method to provide the radar sweeps decoded from the raw radar data to TLcdRadar. The API reference documentation for this class provides more detail about the method parameters. You must call this method within a write lock, using TLcdLockUtil.writeLock(model) and event mode ILcdModel.FIRE_LATER.

You can re-use the amplitudes array because TLcdRadar makes a copy of the data in the array. It is recommended to re-use the amplitudes array in the decoder after calling the addRadarSweep method to prevent excessive memory allocation.

Program: Adding a radar sweep shows how to add a radar sweep to the instance of TLcdRadar.

Program: Adding a radar sweep (from samples/realtime/lightspeed/radarvideo/format/SampleRadarVideoRecordDecoder)
aRadar.addRadarSweep(timeStamp,
                     startAzimuth,
                     endAzimuth,
                     startRange,
                     cellLength,
                     bitResolution,
                     fAmplitudesIntArray,
                     intArrayLength);

Handling variable data resolutions

As outlined in the API reference documentation of TLspRadarVideoLayerBuilder, radar layers assume by default that the resolution of the radar data is fixed in both the angular and radial directions. To summarize those assumptions:

  • The azimuth interval—​the difference between the start and end azimuth—​must be the same for every data record, and all records must be aligned to multiples of this interval.

  • The cell size must be the same in all records, or must be integer multiples of the smallest cell size encountered.

The radar layer infers the required number of angular and radial steps by looking at the first data records it receives.

Although the resolution of the visualization in the Lightspeed view is always fixed and uniform, the incoming data may not meet the assumptions outlined above. The data may be visualized incorrectly in such a case, but you can mitigate these problems by overriding the inferred resolution and setting the resolution explicitly. To do so, call the displayResolution() method on TLspRadarVideoLayerBuilder. This allows you to specify the number of angular and radial steps the visualization must use. To get the best results, choose settings that can accommodate the highest-resolution records expected in the data.

When you have set the resolution, the layer resamples the incoming data to the specified angular and radial resolution on-the-fly. The resolution of the visualization is therefore effectively decoupled from the resolution of the data, and the radar display becomes fully robust against all variations in the resolution of the incoming data.