This guide contains general information about the Aeronautical Information System (AIS) functionality and concepts in LuciadLightspeed. Each AIS format (Dafif, AIXM, ARINC, …​) has more format-specific documentation available as well. |
Overview
This guide deals with the creation and handling of the aeronautical domain objects that are provided in AIS. In this overview, a number of general properties of AIS domain objects are explained. Subsequent sections give details about specific domain objects.
All AIS domain objects are located in the package
com.luciad.ais.model
and its sub-packages. In this overview, an
aerodrome will be used as an example to demonstrate the general domain
object modeling principles.
Program: This code creates a model with a single aerodrome inside. It demonstrates a number of general AIS domain object principles, which are discussed in this article. shows code to create a model with aerodromes. It is taken from the sample source file 'ais/model/ModelFactory.java'. It shows the use of (editable) interface, custom data types, model descriptors, and object factories as explained in subsequent sections.
samples/ais/model/ModelFactory
)
/**
* Creates a model containing an aerodrome with a few features.
*
* @return a model containing an aerodrome with a few features.
*/
public ILcd2DBoundsIndexedModel createAerodromeModel() {
TLcd2DBoundsIndexedModel aerodrome_model
= new TLcd2DBoundsIndexedModel();
// WGS 84 reference
aerodrome_model.setModelReference(WGS_84);
// Create a number of aerodromes with a custom type that is declared in our
// own data model
ILcdEditableAerodrome aerodrome = fObjectFactory.createAerodrome(CustomAISDataTypes.MyAerodromeType);
aerodrome.move2D(4.5, 50.9);
aerodrome.setValue(CustomAISDataTypes.MyAerodromeType.getProperty("Identification"), "EBBR");
aerodrome.setValue(CustomAISDataTypes.MyAerodromeType.getProperty("Name"), "BRUSSELS NATIONAL");
aerodrome_model.addElement(aerodrome, ILcdFireEventMode.NO_EVENT);
// Create an aerodrome model descriptor that describes this model
TLcdAerodromeModelDescriptor descriptor = new TLcdAerodromeModelDescriptor(
"Hardcoded", "Aerodrome", "Aerodrome", CustomAISDataTypes.MyAerodromeType
);
aerodrome_model.setModelDescriptor(descriptor);
return aerodrome_model;
}
Interfaces
All AIS domain objects are modeled using Java interfaces. One advantage of interfaces is that aeronautical objects already defined in an existing system, can be fitted into LuciadLightspeed by making them implement the corresponding AIS interface.
A basic aerodrome is defined in the ILcdAerodrome
interface.
This interface defines the geometry of the object:
ILcdAerodrome
is an extension of ILcdPoint
, which means
all aerodromes are represented by a point. Other methods defined in
ILcdAerodrome
determine attributes and relationships of an
aerodrome.
In AIS, the number of attributes and relationships in the domain object interfaces is kept to a minimum. This is done to facilitate the use of the AIS domain objects in diverse applications. There is no need to implement lots of attributes if an application does not require these. When AIS domain objects do need extra attributes in an application, the domain objects can be extended easily by inheritance or, even easier, by using custom data types (see next section).
ILcdAerodrome
defines the necessary geometry and properties
of an aerodrome, but it cannot be edited. The ILcdEditableAerodrome
interface extends ILcdAerodrome
with editing functionality.
It allows moving the location of the aerodrome, because it extends
ILcd3DEditablePoint
, and it also provided methods to change
the attributes of an aerodrome (for example setAerodromeType
).
Summarized, each AIS domain object is defined by an interface that specifies the geometry and a few important attributes or relationships. An editable interface is provided for most domain objects and allows changing the geometry or attributes of an object.
Custom data types
As mentioned in the previous section, AIS domain objects contain as few explicit attributes in their interfaces as possible.
The most common way to add attributes is through the use of custom data types.
In LuciadLightspeed, data types are handled by the
ILcdDataObject
interface. Each object
implementing this interface, defines a number of properties. A
TLcdDataType
defines names and classes of specific
properties of an object. See the LuciadLightspeed developer’s guide for
more information.
AIS allows the use of this standard data object mechanism. Custom data
types can be easily created by extending a predefined type. A number of
predefined types that are common between different AIS formats can be found in
TLcdAISDataTypes
. These types correspond to classes in the AIS domain model, as such
these classes can only be used with extensions of these base types.
The sample class samples.ais.model.ModelFactory
contains
code which demonstrates the use of data types in AIS.
Program: This code creates a model with a single aerodrome inside. It demonstrates a number of general AIS domain object principles,
which are discussed in this article. shows the
creation of an aerodrome with a few properties.
Implementations
AIS provides a number of standard implementations of the domain object interfaces.
ILcdFeatured versus ILcdDataObject based implementations
AIS provides generic access to the attributes of objects with two different mechanisms.
For new applications, the use of the ILcdDataObject
interface is recommended.
Existing implementations can choose to keep on working with the ILcdFeatured
interface
but can also use the ILcdDataObject
interface and still remain compatible with the ILcdFeatured
interface.
The only thing to keep in mind when using API based on ILcdFeatured
is that the predefined names of features do not map directly to
the names of properties. The reason for this is that property names have certain restrictions
like the fact that cannot contain spaces, while the feature names do contain spaces.
Whenever an API method has to be used that uses feature names instead of property names, you
can easily convert property names to feature names and back using the methods TLcdAISDataTypes.getProperty(TLcdDataType, String)
and TLcdAISDataTypes.getFeatureName(TLcdDataProperty)
.
Note that this only applies to feature names and properties that are predefined in the LuciadLightspeed domain models. When working with custom data types, you can define your own mapping to the featured interfaces.
Featured versus non-featured implementations
For each domain object in AIS, two implementations are provided, a
non-featured and a featured implementation. For aerodromes,
these classes are: TLcdAerodrome
and TLcdFeaturedAerodrome
.
The featured implementations allow you to set and add properties (or features). When no properties are required, the non-featured implementation is preferred, as it takes up less memory.
Note that the 'Featured' prefix comes from the use of the ILcdFeatured
interface.
This naming has been maintained for backwards compatibility but the classes should also be used
for ILcdDataObject
based applications.
Geodetic versus grid references
Most AIS domain object implementations can be configured for use in both grid (Cartesian) or geodetic references. LuciadLightspeed shapes, such as points and polylines, normally have both a Cartesian implementation (TLcdXYZPoint for example) and a geodetic implementation (TLcdLonLatHeightPoint). Doing the same for AIS, would require two versions of each domain object implementation, which would amount up to 4 implementation classes per domain object (Featured, non-featured and for both LonLatHeight and XYZ). To prevent an excessive number of classes, AIS domain object implementations delegate to a specific shape implementation.
For example, a TLcdAerodrome
extends TLcdAISPoint
,
which allows to set the concrete implementation of the point
to delegate to through the method setLocation
. Creating
a new TLcdAerodrome
for use with a geodetic reference
can be done in two steps:
TLcdAerodrome aerodrome = new TLcdAerodrome();
aerodrome.setLocation(new TLcdLonLatHeightPoint(4.5, 50.9, 0) );
TLcdAISPoint
and other AIS shapes that allow to set a
delegate implementation are defined in the package com.luciad.ais.shape
.
Models and model descriptors
Domain objects are typically put in ILcdModel
instances. A model has a
model reference and a model descriptor (an ILcdModelDescriptor
implementation) that describes the contents of a model and its data objects.
In LuciadLightspeed, all elements in an ILcdModel
must have the
same geographical reference, called the model reference. All geometry
of the elements in the model is specified with respect to this reference.
Model descriptors
In AIS, model descriptors are provided for most common domain objects.
For aerodromes there is a TLcdAerodromeModelDescriptor
which
allows to define which data type the aerodromes in the model have.
Layer factories often check the class type of the model descriptor,
using an instanceof
test, to determine whether they can handle
a model.
The model descriptor used by AIS models also implement ILcdDataModelDescriptor
and thus
describe the types of the objects in the model. All objects
should have one of the types returned by ILcdDataModelDescriptor.getModelElementTypes()
. It is
very common for AIS models to have only one type of element in a given model.
Domain object factories
A domain object factory is a class the can create a number of
different domain objects. TLcdAISDataObjectFactory
is an implementation
of such a class that will create objects of specific types. Methods of this
class can be overridden in case you want to change the class that is used when creating
instances for certain data types.
This class delegates the creation of geometry to an instance of an ALcdAISGeometryFactory
.
This is an abstract class that can create geometries for use with specific types
of model references. Two implementations are provided: TLcdAISLonLatHeightGeometryFactory
for creating geometry with a geodetic reference, and
TLcdAISXYZGeometryFactory
for creating geometry for use in a
grid reference.
Type safe enumerations
Often an attribute or feature of a domain object has a limited number
of values. For example the type of an aerodrome can be an airport, a
heliport or both. In AIS such enumerations are modeled using type safe
enumerations, a common java design pattern. These enumerations are
usually placed under a type
sub-package. For example the
TLcdAerodromeType
is located in the
com.luciad.ais.model.aerodrome.type
package.
AIS Specific shapes: com.luciad.ais.shape
The geometry of domain objects is represented by shapes. This section details shapes specific for AIS.
Geo-Paths
Several domain objects in AIS are modeled using geo-paths. A geo-path
is defined as a (circular) list of geo-path legs. Each geo-path leg is a
point but has additional information on how to construct a
path from the current leg to the next leg;
this is determined by the type of the geo-path leg (defined in
ILcdGeoPathLeg
).
For example a geo-path leg of type GEODESIC_LINE
indicates
that a geodesic line must be constructed from the current leg to
the next leg.
The main interfaces for geo-paths are: ILcdGeoPath
,
ILcdGeoPathLeg
, ILcdEditableGeoPath
,
ILcdEditableGeoPathLeg
. The main implementations are:
TLcdGeoPath
and TLcdGeoPathLeg
.
AIS also provides support for the discretization of geo-paths.
Currently this is only supported for geodetic references, through the
class TLcdDiscretizedLonLatGeoPath
.
Delegating shapes
AIS provides several shapes that delegate to a specific implementation. As mentioned before, this is to accommodate both geodetic and grid references with a single object.
Currently AIS provides: TLcdAISPoint
, TLcdAISPolygon
,
TLcdAISPolyline
. See the reference documentation for more
information.
Aerodrome related objects: com.luciad.ais.model.aerodrome
The following aerodrome related objects are supported in AIS:
-
Aerodromes: The aerodromes, including both airports and heliports, themselves are modeled as a point and support a type and collocated aerodromes.
-
Runways: Runways are modeled as a polyline, which represents the centerline of the runway. The width of the runway is a required attribute. Together they determine the geometry of the runway. A runway can have two runway directions.
-
Runway directions: An
ILcdRunwayDirection
models some additional information of a runway direction such a the threshold point, and an arresting gear. -
Helipads: the area of a helipad is modeled using a geo-path.
-
Arresting gear: An arresting gear or arresting device is modeled as a point.
Navaids and waypoints: com.luciad.ais.model.navaid
AIS supports the following navaids and related objects:
-
VOR, DME, TACAN, NDB: all are modeled as a point and support all possible collocations.
-
Waypoints: also modeled as a point
-
ILS: An
ILcdILS
is an instrument landing system that can contain a glide slope, a localizer and markers. All these are modeled as points.
Air spaces: com.luciad.ais.model.airspace
Air spaces are generally modeled as an ILcdShape
, through the interface
ILcdGenericAirspace
. This interface is the basis of more specific
air space interfaces that differ in the way they are constructed:
-
ILcdAirspace
: this interface represents an air space as a polygon, constructed from a closedILcdGeoPath
. This is the way most air spaces are modeled in AIXM, ARINC, and DAFIF. Such an air space consists of a number ofILcdAirspaceSegment
instances, which are individual legs of a geo-path with a sequence number added. These segments are combined into a polygon. -
ILcdAirspaceCorridor
: this interface represents an air space as a buffer, constructed from an axis and a width. The resulting shape is a polygon, that represents the contour of the buffer. The axis of the buffer is modeled as an openILcdGeoPath
: likeILcdAirspace
, it also consists of a number ofILcdAirspaceSegment
instances, which are individual legs of the geo-path. These segments are combined into a polyline, which is used as axis for the buffer. The width of the buffer can be specified separately. This type of airspaces is only used in AIXM, versions 4.0 and 4.5. -
ILcdAssociationBasedAirspace
: this interface represents an air space that is built up from other air spaces. These air spaces can be combined in several ways and are related to the association-based air space using an airspace association. An airspace association is modeled by the interfaceILcdAirspaceAssociation
, and consists of an air space, an association type and a sequence number. The geometry of an association-based air space is a shape list, where each of the shapes in the shape list is a polygon or a complex polygon. AIS provides support for the discretization of association-based airspaces, through the classTLcdAssociationBasedAirspace
.
Note that any altitudes that may be part of an air space are not explicitly modeled. In the AIXM, ARINC and DAFIF decoders they are modeled using features.
Routes: com.luciad.ais.model.route
Routes or air ways are modeled using ILcdRouteSegment
instances.
Each route segment connects 2 points.
The geometry of a route is a shape list, where each of the shapes in the shape list must be a polyline. This is done to accommodate routes made up of separate parts, where each part is a polyline containing a set of segments. Most often, however, a route will contain just a single shape (a single polyline).
Several different types of routes are provided in AIS (ATS routes,
military training routes). All of these are simply derived from
ILcdRoute
.
Procedures: com.luciad.ais.model.procedure
AIS provides comprehensive support for terminal procedures. Standard instrument departures (SID), Standard terminal arrival route (STAR) and instrument approach procedures (IAP).
The main domain object for procedure modeling is an ILcdProcedure
.
An ILcdProcedure
models a SID, STAR, or IAP as a number
of procedure legs according to the ARINC 424 standard.
An ILcdProcedureLeg
is the main interface for a procedure
leg. It defines the main attributes of a leg, such as the
leg type (for example: IF, TF, CA, CF, …​ ), a fix, the
fix overfly type, and so on.
Note that an ILcdProcedure
does not support branches. An example
of a branched procedure is a SID that has two or more runway transitions
(for instance starting at different runways) which are followed by a single
common part, which in turn may be followed by one or more en-route transitions.
Such a branched procedure does not define a single path from the start to the
end of the procedure, and complicates generating trajectories from a procedure.
A procedure in AIS is a single sequence of procedure legs. Branches can be modeled easily as a number of separate procedures. Each transition can be seen as a separate procedure, or different combinations of in, common, and out transitions can be modeled as separate procedures (which is the way it is done in the ARINC and DAFIF decoders).
A procedure in itself does not define a unique trajectory, because that depends on a number of settings such as the aircraft performance (turn radius, speed, …​ ). In AIS a number of support classes are provided to compute a geometry (or a trajectory) from a procedure:
-
TLcdProcedureGeometryCalculator: this class can process a procedure and produce an actual geometry representing this procedure. It contains a lot of complex logic and geodetic computations to do so.
The main method is
calculateProcedureGeometry
which requires anILcdProcedure
and anILcdProcedureGeometryHandler
as parameters.The geometry of the procedure is passed piece by piece to the
ILcdProcedureGeometryHandler
. The supplied handler can do anything it wants with the produced geometry: drawing, storing, computing statistics, …​The geometry calculator has
set/getAircraftPerformanceSettings
methods, which allow to query or specify the aircraft performance settings with which the geometry is computed.The geometry calculator does not require that all attributes of a procedure leg are filled in. The reference guide contains information on which attributes are required for which types of procedure legs.
-
TLcdProcedure3DGeometryCalculator: this extension of
TLcdProcedureGeometryCalculator
tries to compute a trajectory with more realistic altitudes along the procedure. -
ILcdProcedureGeometryHandler: this interface defines the way procedure geometry is built by the calculator. A procedure geometry is built up of points (
handlePoint
), line segments (handleLine
), and arcs (beginAngleArc
,endAngleArc
). Arc geometry is also passed in discretized form to thehandleArcSegment
method.Each geometry primitive passed to the handler has a type defined in
TLcdProcedureGeometryType
. This allows special handling of decorations, errors, and connector segments.The
ILcdProcedureGeometryHandler
is demonstrated inTLcdGXYProcedureTrajectoryLegLabelPainter
, which is supplied with the sample source code of AIS underais/view/gxy
. -
TLcdAircraftPerformanceSettings: this class defines a number of aircraft performance settings used by the procedure geometry calculators.
-
TLcdProcedureTrajectory: this is an AIS domain object that represents an actual procedure trajectory. It is related to a single
ILcdProcedure
that must be specified in its constructor. The trajectory has two properties,procedureGeometryCalculator
andaircraftPerformanceSettings
, which can be changed with a setter method. These properties determine how the procedure is turned into geometry.The geometry of the trajectory is a polyline (
TLcdProcedureTrajectory
implementsILcdPolyline
). This geometry is cached in the object, which prevents costly re-computation of the procedure geometry. However, when theILcdProcedure
related to this trajectory is changed, theinvalidate
method must be called on the trajectory in order to have the geometry updated. The same holds when the aircraft performance settings are changed.The
processProcedureGeometry(ILcdProcedureGeometryHandler aHandler)
method allows to replay the procedure geometry to a geometry handler. This can be useful for special handling of decorations, errors or just to know which part of the trajectory corresponds to a specific leg in the procedure.It is recommended to always use
TLcdProcedureTrajectory
objects inILcdModel
instances instead ofILcdProcedure
instances, because they have a defined geometry and defined bounds.
Program: This code creates a model with a single procedure inside. shows code to create a model with a single procedure. It is taken from the sample source file 'ais/model/ModelFactory.java'.
samples/ais/model/ModelFactory
)
/**
* Creates a model containing a procedure. Fixes used in procedures can be any ILcdPoint instance.
* In this sample, waypoints and aerodromes from the supplied models
* are used, as well as on the fly created points.
*
* @param aAerodromeModel An aerodrome model.
* @param aWayPointModel A waypoint model.
* @return a model containing a procedure.
*/
public ILcd2DBoundsIndexedModel createProcedureModel(
ILcd2DBoundsIndexedModel aAerodromeModel,
ILcd2DBoundsIndexedModel aWayPointModel
) {
TLcd2DBoundsIndexedModel procedure_model =
new TLcd2DBoundsIndexedModel();
// WGS 84 reference
procedure_model.setModelReference(WGS_84);
/*
* Find waypoints based on the identifier.
*/
ILcd3DEditablePoint helen = null;
Enumeration elements = aWayPointModel.elements();
TLcdDataProperty identifierProperty = CustomAISDataTypes.MyWaypointType.getProperty("Identifier");
while (elements.hasMoreElements()) {
ILcdDataObject object = (ILcdDataObject) elements.nextElement();
if ("HELEN".equals(object.getValue(identifierProperty))) {
helen = (ILcd3DEditablePoint) object;
break;
}
}
if (helen == null) {
System.out.println("Error: cannot find HELEN in waypoints model");
return null;
}
// Find the EBBR aerodrome, but this time the model elements are enumerated explicitly
Enumeration aerodromes = aAerodromeModel.elements();
TLcdAerodromeModelDescriptor ad_descriptor =
(TLcdAerodromeModelDescriptor) aAerodromeModel.getModelDescriptor();
TLcdDataProperty aerodromeIdentifierProperty = ad_descriptor.getModelElementTypes().iterator().next().getProperty("Identification");
ILcdAerodrome ebbr = null;
while (ebbr == null && aerodromes.hasMoreElements()) {
ILcdDataObject aerodrome = (ILcdDataObject) aerodromes.nextElement();
String identification = (String) aerodrome.getValue(aerodromeIdentifierProperty);
if (identification.equalsIgnoreCase("EBBR")) {
ebbr = (ILcdAerodrome) aerodrome;
}
}
if (ebbr == null) {
System.out.println("Error: cannot find EBBR in aerodromes model");
return null;
}
// Create a runway point on the fly
TLcdLonLatHeightPoint runway_point = new TLcdLonLatHeightPoint(4.51, 50.91, 0);
// Create an intermediate fix on the fly
TLcdLonLatHeightPoint nicky = new TLcdLonLatHeightPoint(4.15, 51.15, 0);
samples/ais/model/ModelFactory
)
// Create the procedure
ILcdEditableProcedure procedure = fObjectFactory.createProcedure(CustomAISDataTypes.MyProcedureType);
// Initial fix
ILcdEditableProcedureLeg leg = fObjectFactory.createProcedureLeg(TLcdAISDataTypes.ProcedureLeg);
leg.setType(TLcdProcedureLegType.IF);
leg.setFix(runway_point);
leg.setCourse(70);
leg.setSequenceNumber(10);
procedure.addLeg(leg);
// Course to an altitude
leg = fObjectFactory.createProcedureLeg(TLcdAISDataTypes.ProcedureLeg);
leg.setType(TLcdProcedureLegType.CA);
leg.setRho(133);
leg.setCourse(66);
leg.setSequenceNumber(20);
procedure.addLeg(leg);
// Direct to fix
leg = fObjectFactory.createProcedureLeg(TLcdAISDataTypes.ProcedureLeg);
leg.setType(TLcdProcedureLegType.DF);
leg.setFix(nicky);
leg.setSequenceNumber(30);
procedure.addLeg(leg);
// Track to fix
leg = fObjectFactory.createProcedureLeg(TLcdAISDataTypes.ProcedureLeg);
leg.setType(TLcdProcedureLegType.TF);
leg.setFixOverflyType( TLcdProcedureLegFixOverflyType.FLY_OVER );
leg.setFix(helen);
leg.setSequenceNumber(40);
procedure.addLeg(leg);
// Track to fix
leg = fObjectFactory.createProcedureLeg(TLcdAISDataTypes.ProcedureLeg);
leg.setType(TLcdProcedureLegType.TF);
leg.setFix(ebbr);
leg.setSequenceNumber(50);
procedure.addLeg(leg);
// Create a procedure trajectory model descriptor that describes this model.
TLcdProcedureTrajectoryModelDescriptor descriptor = new TLcdProcedureTrajectoryModelDescriptor(
"Hardcoded", "Procedures", "Procedures",
CustomAISDataTypes.MyProcedureType);
procedure_model.setModelDescriptor(descriptor);
// Add the procedure to a proceduretrajectory, set the designator value and add it to the model
TLcdProcedureTrajectory trajectory = fObjectFactory.createProcedureTrajectory(procedure);
trajectory.setValue(CustomAISDataTypes.MyProcedureType.getProperty("Designator"), "BE12345");
procedure_model.addElement(trajectory, ILcdFireEventMode.NO_EVENT);
return procedure_model;
}
Other domain objects
AIS also provides other domain objects, which are handled similarly to the previously described domain objects. Other domain objects in AIS are:
-
Geoborders (
com.luciad.ais.model.geoborder
): Geographical borders are modeled as polylines. -
Services (
com.luciad.ais.model.service
): A general service is defined by the interfaceILcdService
and does not contain any geometry related information. This domain object can be used to model any kind of service that is provided by an AIS related domain object, such as an airport or a heliport. An extension of this interface exists,ILcdLocationBasedService
, that models a service as a point. A common example of a location-based service is an Air Traffic Control service at an airport. -
Area Minimum Altitudes (
com.luciad.ais.model.ama
): An area, usually a rectangle, for which a minimum safe flying altitude is defined. This type can be used to model any area-based, cell-based, or quadrangle-based minimum safety altitude, such as MORA (Minimum Off-Route Altitude), MEF (Maximum Elevation Figure) or AMA (Area Minimum Altitude). There is a specific sub-type ORTCA (com.luciad.ais.model.ortca
) that models Off-route terrain clearance altitudes. -
Obstacles (
com.luciad.ais.model.obstacle
): Obstacles are modeled as points. -
Parachute jump areas (
com.luciad.ais.model.parachutejumparea
): these areas are modeled as a geo-path. -
Refueling tracks (
com.luciad.ais.model.refuelingtrack
): Refueling tracks determine an air space and a route where refueling in air can take place. It is modeled after the DAFIF concept of refueling tracks. -
VFR routes (
com.luciad.ais.model.vfr
): Visual Flight Rules routes and offset routes are modeled as polylines.