ASTERIX formats
ASTERIX data can be decoded from file or from a live stream of radar data. These file formats are supported:
-
ASTERIX format: concatenated blocks of ASTERIX data, possibly of different categories. The file extension is by default assumed to be
.asterix
or.ast
. -
ASTERIX Final format: blocks of ASTERIX data, possibly of different categories, surrounded by headers and footers. The format is described in the ASTERIX Final format guide. The file extension is assumed to be
.astfin
by default. -
PCAP files: ASTERIX data captured from a network with capturing tools such as Wireshark. The LuciadLightspeed decoder supports a specific subset of ASTERIX PCAP files: it only supports captures of raw Ethernet packages (version II, LLC, LLC+SNAP blocks), with additional support for UDP over (fragmented) IPv4 network protocol. The file extension is assumed to be
.pcap
by default.
How to decode ASTERIX data
Decoders
In the com.luciad.format.asterix
package two decoders are available. Use the TLcdASTERIXModelDecoder
to decode ASTERIX data from file and the TLcdASTERIXLiveDecoder
to decode ASTERIX data from a live stream of data.
The TLcdASTERIXModelDecoder
is an ILcdModelDecoder
. The decode
method produces an ILcdModel
which is in fact a TLcdModelList
containing an ILcdModel
for every combination of category and User Application Profile (UAP) encountered. You can also use the decodeSource
method of its ILcdModelDecoder
interface to decode multiple ASTERIX files at once. Using this method, a trajectory that is split across multiple files can
still be decoded as a single trajectory.
The TLcdASTERIXLiveDecoder
on the other hand is not an ILcdModelDecoder
. It has a method decodeSFCT(InputStream aInputStream, int aFireEventMode, TLcdModelList aModelSFCT)
, which must be called to start reading data from a live stream. Here you must create a ILcdModelContainer
yourself and pass it as an argument to the decodeSFCT
method. During the decode an ILcdModel
is added for every combination of category and UAP encountered. The aInputStream
argument of the decodeSFCT
method specifies the stream from which data is read. For the TLcdASTERIXLiveDecoder
the reading must be started from a dedicated thread. It can then be stopped by calling the interrupt
method on the thread.
TLcdASTERIXLiveModelDecoder
offers the functionality if the TLcdASTERIXLiveDecoder
as an ILcdModelDecoder
. This is useful when your application uses the TLcdServiceLoader
to find all model decoders, or when you have another centralized list of model decoders. Since there are no standard protocols
for live ASTERIX data, you need to set your own ILcdInputStreamFactory
on the TLcdASTERIXLiveModelDecoder
that can create an InputStream
based on your needs.
The decoders group data of one category and UAP into one ILcdModel
. The objects of the individual models are domain objects that reflect the type of data the category or more specific the
UAP represents. The objects also depend on the type of decoder : TLcdASTERIXModelDecoder
and TLcdASTERIXLive(Model)Decoder
will create different domain objects, each containing the same UAP data, but in another representation. The following table
describes which type of domain objects are contained in which model, and also mentions the data item that is used as ID for
the domain objects:
Cat |
UAP |
ASTERIX data item used for ID |
Domain objects created by TLcdASTERIXModelDecoder |
Domain Objects created by TLcdASTERIXLiveDecoder and TLcdASTERIXLiveModelDecoder |
1 |
Track |
Track Plot Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
8 |
/ |
Not applicable |
TLcdASTERIXWeatherPicture |
TLcdASTERIXWeatherPicture |
11 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
21 |
Track |
Target Identification |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
21 v0.23 |
Track |
Target Address |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
30 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
30 v2.5 ter |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
34 |
/ |
Data Source Identifier |
ILcdDataObject and ILcdTimeBounded |
ILcdDataObject and ILcdTimeBounded |
48 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
62 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
240 |
Radar video |
Data Source Identifier |
TLcdRadar |
TLcdRadar |
244 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
10 |
Track |
Track Number |
TLcdASTERIXTrajectory TLcdASTERIXPlot |
TLcdASTERIXTrack TLcdASTERIXPlot |
The model descriptors of the individual models depend on the type of domain object in the model. They can be used to check the type of domain object in the model. Refer to Model descriptors for more information on model descriptors.
The decoders can be configured in several ways:
-
By default the decoders decode the ASTERIX data from all categories that are supported. The
setCategories(ALcdASTERIXCategory[] aCategories)
method can be used to limit the categories that are processed to a well defined subset.
-
All times in ASTERIX are relative to midnight. Refer to Domain object times for more information on ASTERIX times. By default the decoders create absolute times from these relative times by adding the current day as time offset. This behavior can be overwritten for the
TLcdASTERIXModelDecoder
. It has a methodsetTimeOffset
that allows to specify a day offset manually.
-
A transformation provider
ALcdASTERIXTransformationProvider
can be specified for both decoders using thesetTransformationProvider
method. The provided transformations are used to convert the relative ASTERIX coordinates to absolute ASTERIX WGS84 latitude longitude coordinates. Refer to Model references for more information on transformation providers. Note that for category 240 radar video data, anALcdASTERIXReferenceProvider
is used instead. This provider supplies anILcdModelReference
that encapsulates the position and orientation of the radar platform.
-
A scaling factor provider
ALcdASTERIXScalingFactorProvider
can be specified for both decoders using thesetScalingFactorProvider
method. The provided factors are used to scale the values in the ASTERIX data fields when those factors are not available from the data itself. Refer to Scaling factors for more information on scaling factor providers. -
For the
TLcdASTERIXModelDecoder
the methodsetInputStreamFactory(com.luciad.io. ILcdInputStreamFactory aInputStreamFactory)
can be used to specify the input stream factory for creating input streams from source file names. By default thecom.luciad.io.TLcdInputStreamFactory
is used. -
The
ILcdModelContainer
filled by theTLcdASTERIXLiveDecoder
always represents the situation at the current time. You can use thesetHistoryLength
method to specify the maximum history to keep in memory. Note that if more history is available as the specified maximum , the oldest information is purged. For instance forTLcdASTERIXTrack
domain objects you can use thesetHistoryLength
method to specify the maximum number of tracks that must be kept in memory for the encapsulated trajectory (TLcdASTERIXTrack.getTrajectory
).
Samples
Decoding from file
The sample class samples.decoder.asterix.file.MainPanel
implements a sample that allows to decode ASTERIX data from file and display that data on a map. It starts with creating
a TLcdASTERIXModelDecoder
and registering it as one of the ILcdModelDecoder
objects that must be checked when a file is opened.
samples/decoder/asterix/file/MainPanel
)
public TLcdASTERIXModelDecoder createAsterixModelDecoder(
ILcdInputStreamFactory aInputStreamFactory,
ALcdASTERIXTransformationProvider aTransformationProvider
) {
TLcdASTERIXModelDecoder decoder = new TLcdASTERIXModelDecoder();
decoder.setInputStreamFactory(aInputStreamFactory);
if (aTransformationProvider != null) {
decoder.setTransformationProvider(aTransformationProvider);
}
return decoder;
}
Program: Creating an ASTERIX model decoder shows the implementation of the method createAsterixModelDecoder
that is used to create the TLcdASTERIXModelDecoder
. The argument aInputStreamFactory
represents the ILcdInputStreamFactory
that the decoder must use for creating input streams from source file names. It is customized in this sample to inform the
user about decoding progress. The method first creates a TLcdASTERIXModelDecoder
. Then it attaches the aInputStreamFactory
and aTransformationProvider
arguments to it.
samples/decoder/asterix/file/MainPanel
)
//create and initialize the ASTERIX model decoder.
fModelDecoder = createAsterixModelDecoder(new TLcdInputStreamFactory(), transformationProvider);
OpenSupport openSupport = new OpenSupport(this, Collections.singletonList(fModelDecoder));
openSupport.addModelProducerListener(new ASTERIXModelProducerListener());
OpenAction openAction = new OpenAction(openSupport);
Since the TLcdASTERIXModelDecoder
is an ILcdModelDecoder
it can be assigned to a com.luciad.model.TLcdOpenAction
. A TLcdOpenAction
is a java.awt.event.ActionListener
that can be attached to a menu item for loading a file. To load a file the TLcdOpenAction
tries to find the correct ILcdModelDecoder
for the file by calling the canDecode
method on all registered ILcdModelDecoder
. If a ILcdModelDecoder
is found, its decode
method is called to load the file.
Program: Using an action to load ASTERIX files shows how an ILcdAction
can be used to load ASTERIX files..
The complete sample code can be found in the packages samples.decoder.asterix.file
and samples.decoder.asterix
.
Decoding from a live stream
The sample class samples.decoder.asterix.live.MainPanel
implements a sample that loads live ASTERIX data and displays it continuously on a map. The code for creating the TLcdASTERIXLiveDecoder
and to start reading data from the live stream is explained below.
samples/decoder/asterix/LiveDecodedModel
)
private void startLiveDecoder(
ALcdASTERIXTransformationProvider aTransformationProvider,
int aHistoryLength,
final InputStream aInputStream) {
final TLcdASTERIXLiveDecoder liveDecoder = new TLcdASTERIXLiveDecoder();
liveDecoder.setHistoryLength(aHistoryLength);
if (aTransformationProvider != null) {
liveDecoder.setTransformationProvider(aTransformationProvider);
}
liveDecoder.initDecode(aInputStream);
fTimer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
int decodedMessages = 0;
while (liveDecoder.blockAvailable()) {
liveDecoder.decodeBlockSFCT(ILcdModel.FIRE_LATER, LiveDecodedModel.this);
decodedMessages++;
}
if (decodedMessages > 0) {
fireCollectedModelChanges();
fCallback.update(LiveDecodedModel.this);
}
} catch (EOFException ex) {
((Timer) e.getSource()).stop();
fCallback.finished(LiveDecodedModel.this);
} catch (IOException ex) {
((Timer) e.getSource()).stop();
LOGGER.error(ex.getMessage(), ex);
fCallback.error(LiveDecodedModel.this);
}
}
});
fTimer.setCoalesce(true);
fTimer.setRepeats(true);
fTimer.start();
}
Program: Starting an ASTERIX live decoder shows the implementation of the method startLiveDecoder
that is used to create and start a TLcdASTERIXLiveDecoder
. The argument aInputStream
represents the input stream with live data. The argument aModelList
is the ILcdModelContainer
that must be filled by this live decoder. The method first creates a TLcdASTERIXLiveDecoder
. Then it attaches the aTransformationProvider
and aHistoryLength
arguments to it. The decoder is now configured and can be started. The TLcdASTERIXLiveDecoder
is not an ILcdModelDecoder
, hence there is no decode
method. A ILcdModelContainer
must be created before the decoder can be started. In the sample the TLcdModelList
to fill is offered as an input parameter aModelList
. Since we need to update the models on the application toolkit thread, we use a javax.swing.Timer
to regularly check whether new ASTERIX data is available on the input stream. If so, the method decodes that data and fires
the necessary model events when the available data is decoded. To make the labels of the tracks move more fluently, the track
layer is also refreshed every time, using the method invalidateGXYLayer
. For instance, if the user dragged a label away, it will gently move back
The complete sample code can be found in the packages samples.decoder.asterix.live
and samples.decoder.asterix
.
Decoding category 240 radar video
The package samples.decoder.asterix.lightspeed.radarvideo
demonstrates how raw radar video data can be visualized in a Lightspeed view. The sample sets up a TLcdASTERIXLiveDecoder
in a similar way as the other samples described above. It then uses the class TLspRadarVideoLayerBuilder
to create a layer that visualizes the data. Program: Creating a radar video layer illustrates this.
samples/realtime/lightspeed/radarvideo/RadarVideoLayerFactory
)
public ILspEditableStyledLayer createLayer(ILcdModel aRadarModel) {
ILspEditableStyledLayer radarLayer = TLspRadarVideoLayerBuilder
.newBuilder()
.selectable(false)
.model(aRadarModel)
.build();
return radarLayer;
Category 240 data requires an |
Domain object times
All ASTERIX domain objects are time-aware, except for category 240 for which the time information is optional. The time information is extracted from one of the time related data items. The following table summarizes the time mapping for the available categories and UAP:
Cat | UAP | ASTERIX data item used for property Time |
---|---|---|
1 |
Track Plot |
Truncated Time of Day |
8 |
/ |
Time of Day |
11 |
/ |
Time of Track Information |
21 |
/ |
Time of Applicability for Position or Time of Message Reception for Position (depends on record data) |
21 v0.23 |
/ |
Time of Day |
30 |
/ |
Time of Last Update |
30 v2.5 ter |
/ |
Time of Last Update |
34 |
/ |
Time of Day |
48 |
/ |
Time of Day |
62 |
/ |
Time of Day |
240 |
Radar |
Time Of Day |
244 |
/ |
Time of Day |
10 |
/ |
Time of Day |
All time-related ASTERIX data items contain relative times. Usually these are times since midnight. However, the time properties
of the domain objects need to reflect absolute times. Therefore, a time offset needs to be added to the ASTERIX times. The
ASTERIX decoders take care of this. For the TLcdASTERIXModelDecoder
, a day offset can be configured manually. For the TLcdASTERIXLiveDecoder
and TLcdASTERIXLiveModelDecoder
, the actual time is taken as offset. See ASTERIX Decoder Time for more information.
Some categories only have so-called truncated times. These are times since midnight that are truncated at the most significant side. For instance, only two bytes are available for representing the time for category 1, where in fact three would be required to represent all times to midnight. This means that for category 1, only relative times up to approximately eight minutes are available. The times in the headers of the ASTERIX Final Format files or PCAP files are used here to derive a time to midnight.
The decoders can read files with the .asterix extension, which do not have any headers, but keep in mind that this can lead to incorrect times for categories that contain truncated times (category 1). |
Domain Object Properties
Track properties mapped from ASTERIX data items
In the ASTERIX specification, each UAP of each category contains a number of data items. Refer to ASTERIX domain object modeling for more information on the ASTERIX data structure.
Data items in ASTERIX are mapped to values of properties (represented by ILcdDataObject
) of ASTERIX tracks or plots in LuciadLightspeed . This is visualized in the diagram shown in Figure 1, “Mapping of data items to the LuciadLightspeed data object interface”. Note that ILcdDataObject
is mentioned twice to simplify the diagram layout.
A data record for a category can contain information for all or part of the data items. Data items that are not present in
the data records are returned as null
values.
A data item can be described by a data field, but can also have a more complex structure. Depending on its structure a data item can be mapped to a property in different ways:
-
A data item that contains only one data field is mapped to a value of a simple type:
-
This can be any standard data type like
java.lang.String
,java.lang.Boolean
,java.lang.Number
,java.lang.Double
, …​ -
A numeric data field that contains a measured value expressed in a certain unit, is mapped to a property of the LuciadLightspeed
com.luciad.util.iso19103.TLcdISO19103Measure
. This class is an extension of the standardjava.lang.Number
class . It has a methodILcdISO19103UnitOfMeasure getUnitOfMeasure()
to retrieve the unit associated with the value. The unit is anILcdISO19103UnitOfMeasure
object, which has various methods to retrieve the (short) name, type, conversion to a standard unit, and so on. The data type for this class isTLcdASTERIXDataTypes.ISO_19103_MEASURE_TYPE
. -
Often a data field contains an integer value that can be chosen from a list of possibilities, each described by a
String
. Such values are mapped toTLcdASTERIXMappedInteger
properties. TheTLcdASTERIXMappedInteger
class is an extension from the standardNumber
class. The methodintValue
returns the actual integer value. The methodsgetValueDescription
andtoString
on the other hand return the descriptiveString
that corresponds with the integer value. The data type for this class isTLcdASTERIXDataTypes.ABSTRACT_ASTERIX_MAPPED_INTEGER_TYPE
. This type is defined to be abstract. The data types that define this as a supertype will also include a list of possible values.
-
-
A data item that consists of a list of data fields is mapped to a property that is of type
ILcdDataObject
itself. All properties of theILcdDataObject
will be primitive. For instance, a data item that represents a location in the longitude/latitude format, has two data fields: longitude and latitude. It is mapped to a property of typeILcdDataObject
that contains two properties, each of the typeTLcdASTERIXDataTypes.ISO_19103_MEASURE_TYPE
, one for the longitude value and one for the latitude value. -
A data item that consists of a list of data fields is mapped to a list of
ILcdDataObject
instances. EachILcdDataObject
will have the given list of data fields as its properties. -
A data item can also be compound: it can consist of a list of data items, of which each contained data item can be present or not in a concrete data record. Such a data item is mapped to a property of type
ILcdDataObject
where all properties are as described in the previous points.
Trajectory properties
All trajectories have at least an 'ID' property.
Depending on the UAP of the data, trajectories may have more properties. These extra properties represent the track properties that usually remain the same for the entire trajectory. For instance, trajectories of category 30 have a property 'Departure Airport' as each track of a trajectory usually describes the same departure airport.
The actual value of the trajectory property is the last track-value that is not null
, or null
if all track-values are null
.
This is the list of available trajectory properties per category and UAP:
- category 1, track UAP
-
no extra properties
- category 1, plot UAP
-
no extra properties
- category 10
-
-
TargetIdentification
: compound property, corresponds to the compoundTargetIdentification
track property.
-
- category 11
-
-
TargetIdentification
: compound property, corresponds to the compoundTargetIdentification
track-property. -
Callsign
: simple property, corresponds to theCallsign
property of the compoundFlightPlanRelatedData
track-property. -
IFPS_FLIGHT_ID
: compound property, corresponds to theIFPS_FLIGHT_ID
property of the compoundFlightPlanRelatedData
track-property. -
FlightCategory
: compound property, corresponds to theFlightCategory
property of the compoundFlightPlanRelatedData
track-property. -
TypeOfAircraft
: simple property, corresponds to theTypeOfAircraft
property of the compoundFlightPlanRelatedData
track-property. -
WakeTurbulenceCategory
: simple property, corresponds to theWakeTurbulenceCategory
property of the compoundFlightPlanRelatedData
track-property. -
DepartureAirport
: simple property, corresponds to theDepartureAirport
property of the compoundFlightPlanRelatedData
track-property. -
DestinationAirport
: simple property, corresponds to theDestinationAirport
property of the compoundFlightPlanRelatedData
track-property.
-
- category 21
-
-
EmitterCategory
: simple property, corresponds to the simpleEmitterCategory
track-property. -
TargetIdentification
: simple property, corresponds to the simpleTargetIdentification
track-property.
-
- category 21, version 0.23
-
-
EmitterCategory
: simple property, corresponds to the simpleEmitterCategory
track-property. -
TargetIdentification
: simple property, corresponds to the simpleTargetIdentification
track-property.
-
- category 30
-
-
Callsign
: simple property, corresponds to the simpleCallsign
track-property. -
PLNNumber
: simple property, corresponds to the simplePLNNumber
track-property. -
DepartureAirport
: simple property, corresponds to the simpleDepartureAirport
track-property. -
DestinationAirport
: simple property, corresponds to the simpleDestinationAirport
track-property. -
CategoryOfTurbulence
: simple property, corresponds to the simpleCategoryOfTurbulence
track-property. -
TypeOfAircraft
: simple property, corresponds to the simpleTypeOfAircraft
track-property. -
FlightCategory
: compound property, corresponds to the compoundFlightCategory
track-property.
-
- category 30, version 2.5 ter
-
-
Callsign
: simple property, corresponds to the simpleCallsign
track-property. -
PLNNumber
: simple property, corresponds to the simplePLNNumber
track-property. -
DepartureAirport
: simple property, corresponds to the simpleDepartureAirport
track-property. -
DestinationAirport
: simple property, corresponds to the simpleDestinationAirport
track-property. -
CategoryOfTurbulence
: simple property, corresponds to the simpleCategoryOfTurbulence
track-property. -
TypeOfAircraft
: simple property, corresponds to the simpleTypeOfAircraft
track-property. -
FlightCategory
: compound property, corresponds to the compoundFlightCategory
track-property.
-
- category 48
-
-
AircraftIdentification
: simple property, corresponds to the simpleAircraftIdentification
track-property.
-
- category 62
-
-
TargetIdentification
: compound property, corresponds to the compoundTargetIdentification
track-property. -
Callsign
: simple property, corresponds to theCallsign
property of the compoundFlightPlanRelatedData
track-property. -
IFPSFlightId
: compound property, corresponds to theIFPSFlightId
property of the compoundFlightPlanRelatedData
track-property. -
FlightCategory
: compound property, corresponds to theFlightCategory
property of the compoundFlightPlanRelatedData
track-property. -
TypeOfAircraft
: simple property, corresponds to theTypeOfAircraft
property of the compoundFlightPlanRelatedData
track-property. -
WakeTurbulenceCategory
: simple property, corresponds to theWakeTurbulenceCategory
property of the compoundFlightPlanRelatedData
track-property. -
DepartureAirport
: simple property, corresponds to theDepartureAirport
property of the compoundFlightPlanRelatedData
track-property. -
DestinationAirport
: simple property, corresponds to theDestinationAirport
property of the compoundFlightPlanRelatedData
track-property.
-
- category 244
-
-
TargetIdentification
: simple property, corresponds to the simpleTargetIdentification
track-property. -
AircraftType
: simple property, corresponds to the simpleAircraftIdentification
track-property. -
ADSBEmitterCategory
: simple property, corresponds to the simpleADSBEmitterCategory
track-property.
-
The TLcdDataType
of a trajectory describes which properties are available. These TLcdDataType
instances are available as Java constants in the TLcdASTERIXDataTypes
class. The constants for the trajectory data types all end in *TrajectoryType
. You can inspect the trajectory-related TLcdDataType
instances for each UAP with the datamodelviewer
sample.
Weather pictures and precipitation zones properties
The TLcdDataType
of the weather picture contains the following properties :
-
DataSourceIdentifier
: anILcdDataObject
that contains theSystem Area code
andSystem Identifier Code
of the sensor that took the weather picture. -
PrecipitationZones
: aCollection
of the precipitation zones. -
BeginTime
: the begin time of the weather picture,null
if the time is undefined. -
EndTime
: the end time of the weather picture,null
if the time is undefined.
The TLcdDataType
for precipitation zone contains only one property : Intensity
, which is the intensity of the precipitation.
Like the TLcdDataType
of trajectory, you can inspect the TLcdDataType
of the weather picture with the datamodelviewer
sample.
Radar service message properties
The TLcdDataType
of the radar service message contains these properties amongst others:
-
DataSourceIdentifier
: anILcdDataObject
that contains theSystem Area code
andSystem Identifier Code
of the sensor that sent out the service message. -
MessageType
: the type of service message, for exampleSector crossing message
. -
SystemConfigurationAndStatus
: compound property containing information on the configuration and status of the radar system. -
SystemProcessingMode
: compound property containing information on the processing mode of the radar system.
Like the TLcdDataType
of trajectory, you can inspect the TLcdDataType
of the radar service message with the datamodelviewer
sample.
Data types and properties
Category data items are mapped to properties of tracks or plots in LuciadLightspeed . You can inspect which properties are
available by running the datamodelviewer
sample.
The data type for each of the categories can be retrieved through the TLcdASTERIXDataTypes.getTrackModelElementDataType(ALcdASTERIXUserApplicationProfile)
method. This method takes a UAP as an argument to determine the data type used by the elements of any given ASTERIX track
or plot model.
The data models for the different tracks can be obtained through the TLcdASTERIXDataTypes.getDataModel(ALcdASTERIXUserApplicationProfile aUserApplicationProfile)
method.
The data type used by TLcdASTERIXTrajectory
domain objects can be retrieved using the static TLcdASTERIXDataTypes.getTrajectoryDataType(ALcdASTERIXUserApplicationProfile)
method. To retrieve the data model, use the same method, and call the getDataModel()
on the resulting TLcdDataType
.
Changing the value of properties
The object type determines whether you can change the value of the object properties:
TLcdASTERIXTrajectory
-
you can change all properties that correspond to a track-property that can change. Any other properties, such as the 'ID' of the trajectory cannot be changed. When you change a property of a trajectory, the property is changed for all points in time. How the properties of the trajectories correspond the those of the tracks is detailed in Trajectory properties.
TLcdASTERIXTrack
-
the properties that can be changed depend on the category and UAP. They are listed below. The property is only changed at the specific time of the track.
TLcdASTERIXPlot
-
the properties that can be changed for
TLcdASTERIXTrack
can also be changed forTLcdASTERIXPlot
. TLcdASTERIXWeatherPicture
-
the properties cannot be changed.
Radar Service Message
-
the properties cannot be changed.
This is the list of track and plot properties that can be changed:
- category 1, track UAP
-
none of the properties can be changed.
- category 1, plot UAP
-
none of the properties can be changed.
- category 10
-
-
TargetIdentification
: this is a compound property, all its sub-properties can be changed as well.
-
- category 11
-
-
TargetIdentification
: this is a compound property, all its sub-properties can be changed as well. -
FlightPlanRelatedData.Callsign
-
FlightPlanRelatedData.IFPS_FLIGHT_ID
: this is a compound property, all its sub-properties can be changed as well. -
FlightPlanRelatedData.FlightCategory
: this is a compound property, all its sub-properties can be changed as well. -
FlightPlanRelatedData.TypeOfAircraft
-
FlightPlanRelatedData.WakeTurbulenceCategory
-
FlightPlanRelatedData.DepartureAirport
-
FlightPlanRelatedData.DestinationAirport
-
- category 21
-
-
EmitterCategory
-
TargetIdentification
-
- category 21, version 0.23
-
-
EmitterCategory
-
TargetIdentification
-
- category 30
-
-
Callsign
-
PLNNumber
-
DepartureAirport
-
DestinationAirport
-
CategoryOfTurbulence
-
TypeOfAircraft
-
FlightCategory
: this is a compound property, all its sub-properties can be changed as well.
-
- category 30, version 2.5 ter
-
-
Callsign
-
PLNNumber
-
DepartureAirport
-
DestinationAirport
-
CategoryOfTurbulence
-
TypeOfAircraft
-
FlightCategory
: this is a compound property, all its sub-properties can be changed as well.
-
- category 48
-
-
AircraftIdentification
-
- category 62
-
-
TargetIdentification
: this is a compound property, all its sub-properties can be changed as well.
-
- category 244
-
-
TargetIdentification
-
AircraftType
-
ADSBEmitterCategory
-
You can change the value of the properties by calling the setValue
method on the domain object. This method is part of the ILcdDataObject
interface. See the Working with domain object properties page for more information.
Note that you cannot change the geometry or the timing information of a trajectory, track or plot.
Support for the ILcdFeatured interface
Since LuciadLightspeed V10.1, the ILcdDataObject
interface is used to represent the data of a domain object in ASTERIX. This interface contains all the information of the
previous ILcdFeatured
interface and more. The older ILcdFeatured
interface is still supported for reasons of backward compatibility, but it is advised that you use ILcdDataObject
where possible.
For more information on how to use the ILcdFeatured
interface, consult the API documentation of the ALcdASTERIXModelDescriptor
class.
Model descriptors
The model descriptors of the category and UAP models depend on the type of domain objects in the model. They however all extend
from ALcdASTERIXModelDescriptor
. Following table gives an overview of the model descriptors that are currently used:
Domain Object | Model Descriptor |
---|---|
TLcdASTERIXTrajectory |
TLcdASTERIXTrajectoryModelDescriptor |
TLcdASTERIXTrack |
TLcdASTERIXTrackModelDescriptor |
TLcdASTERIXPlot |
TLcdASTERIXPlotModelDescriptor |
TLcdASTERIXWeatherPicture |
TLcdASTERIXWeatherModelDescriptor |
TLcdRadar |
TLcdASTERIXRadarVideoModelDescriptor |
Radar Service Message (ILcdDataObject) |
TLcdASTERIXRadarServiceMessageModelDescriptor |
ALcdASTERIXModelDescriptor
Following information is always available through the interfaces and methods implemented by
the class ALcdASTERIXModelDescriptor
:
-
An
ALcdASTERIXModelDescriptor
is anILcdDataModelDescriptor
. It allows you to retrieve the data model of the model it represents, as well as a list of the data types used by the elements of the model. -
The methods
getCategory
andgetUAP
can be used to retrieve the category and UAP that corresponds with the data. This can for instance be used in theILcdGXYLayerFactory
to distinct between the different categories and UAP. -
The methods
getTransformationProvider
andgetScalingFactorProvider
can be used to retrieve the providers used to extract the domain objects in the model from the ASTERIX data. For more info on these providers refer to Transformation to WGS84 and Scaling factors -
TLcdASTERIXRadarVideoModelDescriptor
, which is used for category 240 radar video, has a methodgetReferenceProvider
. It returns the provider for the model reference of the decoded ASTERIX data. See Model references for more details.
Model references
Transformation to WGS84
With the exception of category 240, which will be discussed below, all ASTERIX domain objects have a shape which allows to
visualize them on a map. The points that define the shape are extracted from the data items that represent coordinates. The
models containing the ASTERIX domain objects must be assigned an ILcdModelReference
which corresponds to the ASTERIX coordinates. Two things must be considered here:
-
ASTERIX coordinates can be in various formats (polar, Cartesian) and can be expressed with respect to different reference systems. Typically a local coordinate system is used. Locations are specified in coordinates relative to the radar location, for example.
-
Since the ASTERIX decoders group category and UAP models (containing the ASTERIX domain objects) in a
TLcdModelList
, and allILcdModel
objects of aTLcdModelList
need to have the same model reference, all category and UAP models must have the same model reference. This is chosen to be a WGS84 geodetic reference (TLcdGeodeticReference
).
This implies that the coordinates of the ASTERIX data items must be transformed to express WGS84 geodetic coordinates. That’s
where the ALcdASTERIXTransformationProvider
comes in: it handles the coordinate transformations between the decoded ASTERIX coordinates and WGS84. An ASTERIX decoder
can be assigned an ALcdASTERIXTransformationProvider
that it then uses for the necessary transformations. (Refer to ASTERIX Transformation Provider.)
The ALcdASTERIXTransformationProvider
is an abstract class. Make an extension of it and implement the provideModelModelTransformation(int aSacSic, ILcdModel aModel, Object aObject)
method to provide the correct ILcdModelModelTransformation
for the data you want to decode. The argument aSacSic
represents the System Area Code (SAC) and System Identification Code (SIC). These codes define which radar surveillance system
is used. The aModel
argument can be used to retrieve the data category or UAP the data belongs to, so you can use it to implement a transformation
per radar system and per data category.
For instance, for locations specified relative to the radar location, you need to know the position of the radar and also
the exact definition of the radar-dependent grid reference. This extra information is not present in the data. You must therefore
provide it by implementing a ALcdASTERIXTransformationProvider
.
Georeferencing of category 240 data
As mentioned above, ASTERIX category 240 is an exception to the rule that all model elements must be transformed to a WGS84
geodetic reference. For category 240 data, the decoder uses an ALcdASTERIXReferenceProvider
to assign a model reference to the model. As a consequence, category 240 data cannot be decoded into a single TLcdModelList
together with other data categories. Use a TLcdModelTreeNode
instead of a TLcdModelList
if you expect to decode category 240 data as well as other categories.
ALcdASTERIXReferenceProvider
must return a model reference that encapsulates the position and orientation of the radar platform. Typically, this is an
azimuthal equidistant reference. Its origin is the position of the radar and its rotation is the orientation of the radar
platform. TLcdASTERIXReferenceProvider
can be used for static radar platforms, where the model reference never needs to change. If the radar is on a moving platform
such as a ship, however, the provider should return a model reference that reflects the current position and heading of the
ship.
Scaling factors
ASTERIX categories specify floating point data in fixed point notation, that is an integer value together with a factor. The factors are normally fixed for specific data items. However for some data items these factors are relative to a 'scaling factor' (f-value), for example one factor is specified as \(2^{-6+f}\). That scaling factor is to be found elsewhere in the data, or from an external source.
The ALcdASTERIXScalingFactorProvider
serves the purpose of providing the scaling factor
to the ASTERIX decoders when it cannot be retrieved from the data source because it
is not specified where to retrieve the scaling factor from, or if it is
specified, but the actual data doesn’t contain a value for it.
Different data items can have different scaling factors. Constants are defined for all existing scaling factors. For instance
the constant TLcdASTERIXCategory1.CAT_1_CARTESIAN_COORDINATES
identifies the scaling factor for the Cartesian coordinates of category 1 data.
To implement a ALcdASTERIXScalingFactorProvider
create a class that extends from ALcdASTERIXScalingFactorProvider
and implement the scalingFactor(ILcdModel aModel, int aID)
method to provide the correct scaling factor. The aModel
argument represents the model containing the data for which the scaling factors are needed. The aID
represents the id of the scaling factor to retrieve. It is one of the constants mentioned above. Finally attach your ALcdASTERIXScalingFactorProvider
class to the decoder.
Replaying recorded ASTERIX data
Replay ASTERIX data with the LuciadLightspeed Real-Time Engine
The sample class samples.decoder.asterix.file.MainPanel
demonstrates how to use ASTERIX data with the Real-Time Engine option for two types of models: ASTERIX trajectory models
and ASTERIX weather models. In both cases, a samples.decoder.asterix.ASTERIXTrackSimulatorModelFactory
first tries to create an instance of ILcdSimulatorModel
for the ASTERIX model.
For trajectory models, the implementation of ILcdSimulatorModel
creates and keeps track models that hold the simulated trajectory data. This data changes dynamically, in function of the
time set by the simulator.
The sample class samples.decoder.asterix.SimulatorGXYLayerFactory
creates a layer for such dynamic models.
The ILcdSimulatorModel
treats weather data differently. Instead of making track models, it filters the layer created from the weather model: only
the weather pictures that are active for the given time are displayed. If there are no active weather pictures, the most recent
previous weather pictures are shown.
Replay input stream
It is also possible to replay the data from files in ASTERIX Final format or PCAP format as if it came from a live stream of data.
For this purpose, a class TLcdASTERIXFinalReplayInputStream
is introduced. It reads an .astfin
file in the ASTERIX Final Format or a .pcap
file in the PCAP format, and uses the time information in the headers to replay the data: the data is only made available
after the time between 2 headers has passed.
Using the TLcdASTERIXLiveDecoder
with a TLcdASTERIXFinalReplayInputStream
allows to replay ASTERIX data.
The TLcdASTERIXFinalReplayInputStream
can be configured through the following classes and methods:
-
Constructors with
InputStream
: unless the format is explicitly specified, it is assumed that the data is in the ASTERIX final format. So when you are reading PCAP files, you need to specify the PCAP format in the constructor. Please refer to the reference documentation for more details. -
Constructors with
TLcdASTERIXDataSource
: the extension of the source names in theTLcdASTERIXDataSource
are used to determine the format of the file. Again. only files in ASTERIX final format and PCAP format are supported. -
The
TLcdASTERIXFinalReplayInputStream
is an extension ofjava.io.PipedInputStream
, so it offers all methods that are available here. -
The
void setExceptionHandler( ILcdExceptionHandler aExceptionHandler )
method allows to specify an exception handler that is called whenever a non recoverable exception occurs. It can for example be used to pop up a dialog that informs the user about the problem.
Sample
The sample class samples.decoder.asterix.live.MainPanel
implements a sample that creates a TLcdASTERIXLiveDecoder
using a TLcdASTERIXFinalReplayInputStream
.
samples/decoder/asterix/LiveDecodedModel
)
private InputStream createFinalReplayInputStream(String aAsterixFile, int aFileFormat) throws IOException {
try {
TLcdInputStreamFactory inputStreamFactory = new TLcdInputStreamFactory();
InputStream inputStream = inputStreamFactory.createInputStream(aAsterixFile);
return new TLcdASTERIXFinalReplayInputStream(inputStream, 20, aFileFormat);
} catch (IOException e) {
LOGGER.error(TLcdASTERIXFinalReplayInputStream.class.getName() + ".<init>", "The file [" + aAsterixFile + "] could not be found.", e);
throw e;
}
}
Program: Create a replay stream shows the implementation of the method createFinalReplayInputStream(String aASTERIXFinalFormatFile)
that is used to create the TLcdASTERIXFinalReplayInputStream
. It has an argument aASTERIXFinalFormatFile
that is the name of the Final Format file containing the ASTERIX data to replay. The method first creates a InputStream
on the specified file using the createInputStream
method of the TLcdInputStreamFactory
. In the next step a TLcdASTERIXFinalReplayInputStream
is created for this InputStream
, and is returned as result of the method.
The resulting InputStream
can then be used in the startLiveDecoder
of Program: Starting an ASTERIX live decoder.
The complete sample code can be found in the packages samples.decoder.asterix.live
and samples.decoder.asterix
.
Filtering ASTERIX data
When decoding ASTERIX data by reading a live stream, files, or when using the replay facility, you may need to filter the
data. You may want to ignore data from a certain radar system, for example, or ignore all coasted tracks. To that end, all
ASTERIX decoders can filter data on a record level (see ASTERIX domain object modeling for what a data record is). For every record, the filter can inspect the values of every data item and decide to keep or
reject the record. Such a data record is provided as an ILcdDataObject
, bringing the power of the data model API, for example its expression language to select the required data properties.
The API conveniently provides a TLcdASTERIXSacSicRecordFilter
to filter data based on its originating radar systems, defined by its SAC/SIC code. This could for example be useful to remove
zig-zag effects caused by two radar systems reporting on the same tracks in turn, but with slightly different locations.
The API also provides a TLcdASTERIXAltitudeRecordFilter
to filter tracks and plots based on their altitude. This can be useful when your data contains tracks with an invalid altitude.
Typically in those cases the altitude of such a track is unrealistically high.
Next to that, a dedicated filter sample demonstrates how to implement a custom record filter. A record filter should be set to the decoder as shown in Program: Set a record filter to an ASTERIX decoder.
samples/decoder/asterix/filter/MainPanel
)
private void initializeRecordFilter(ALcdASTERIXDecoder aDecoder) {
// Specify the filter that should be used during decoding
aDecoder.setRecordFilter(new TrackNumberRecordFilter());
}
The custom record filter implementation is shown in Program: Record filter implementation. In the accept
method, it first verifies the data type of the given record with the expected category 62 track type. Other data, for example
from other categories, is left untouched and true
is returned.
It then requests the data property TrackNumber
using a data model expression. The expression was generated using the datamodelviewer
sample: start the sample, click the Category62Type
button and browse for TrackNumber
. It shows the return type is an Integer
, and it generates the expression as shown in Program: Track number expression generated by datamodelviewer sample.. Because our filter constantly reuses the same expression, it was restructured to be precompiled, which is slightly more
efficient. Please refer to the data model API for more information.
new TLcdDataObjectExpressionLanguage().evaluate(
"TrackNumber",
category62 //specify the actual domain object instance here
);
Finally if the track number is present, and if the track number is less than 30, the record is accepted. Otherwise it is rejected. This is of course not a real-world scenario, mostly because fake data is used that does not specify other data items. But this filter does show the potential possibilities, and can easily be adapted to match specific needs.
samples/decoder/asterix/filter/MainPanel
)
private static class TrackNumberRecordFilter implements ILcdASTERIXRecordFilter {
// Expression was created using the datamodelviewer sample: select Category62Type and
// browse for the track number property. It is specified to be an integer.
private final ILcdDataObjectExpression fTrackNumberExpression =
new TLcdDataObjectExpressionLanguage().compile("TrackNumber");
@Override
public boolean accept(ILcdDataObject aASTERIXRecord) {
// If we have tracks from category 62
if (TLcdASTERIXDataTypes.Category62TrackType.equals(aASTERIXRecord.getDataType())) {
// Fetch the track number if available
Integer trackNumber = (Integer) fTrackNumberExpression.evaluate(
new TLcdDataObjectExpressionContext(aASTERIXRecord));
// Only keep tracks that specify their track number to be less than 30
return trackNumber != null && trackNumber < 30;
} else {
// Accept other data, for example other categories
return true;
}
}
}
Supported versions of category 21
For category 21, two versions are supported:
-
Version 2.1: the final version from 2011 (default)
-
Version 0.23 : a draft version from 2003
Data in either of these two versions cannot be automatically distinguished: only the category number is available from the
data, not the version number. Although both versions are fairly similar, the binary data is incompatible. You must therefore
explicitly enable version 0.23 if you want to use it. Please refer to TLcdASTERIXCategory21Version0Dot23
for more information. If an attempt is made to read data from version 0.23 with the decoder assuming the default v2.1, the
behavior is unpredictable. Typically, these attempts result in runtime errors such as ArrayIndexOutOfBoundsException
instances or IllegalArgumentException
instances.
Supported versions of category 30
For category 30, two versions are supported:
-
Version 6.1: the final version from 2000 (default)
-
Version 2.5 ter: a draft version from 1997
Data in either of these two versions cannot be automatically distinguished: only the category number is available from the
data, not the version number. Although both versions are fairly similar, the binary data is incompatible. You must therefore
explicitly enable version 2.5 ter if you want to use it. Please refer to TLcdASTERIXCategory30Version2Dot5Ter
for more information. If an attempt is made to read data from version 2.5 ter with the decoder assuming the default v6.1,
the behavior is unpredictable. Typically, these attempts result in runtime errors such as ArrayIndexOutOfBoundsException
instances or IllegalArgumentException
instances.