Skip to content

Extensible Metadata model

The meta data model provides facilities not normally available in languages such as C++. In C++, once a class has been defined, it is not possible to add attributes; attributes must be known at compile time and it is not possible to discover attributes at run time. Some languages do provide such functionality, and much more, for example Java through its Reflection interface.

Within Aimsun Next, scripting; the extensible meta model does allow attributes to be added to an object and for them to be discovered dynamically as scripts are run. The data model provides:

  • Extensibility: adding new attributes to any class, to allow the addition of new info to any object instance.
  • Discovery: detecting the existence of new attributes at runtime.

Types and Columns

The Meta Data model is based on Types and Columns. Type is synonymous with class, while Column is synonymous with attribute.

Creating a Type could be thought of as defining a table, whose columns represent Type Columns and whose rows represent Type instances (objects).

TypeA:
ID  Column1 Column2 Column3 Column4
1465    ####    ####    ####    ####
3566    ####    ####    ####    ####

Accessing an object’s Type informs whether the object is a section, a centroid, a vehicle, etc.

Code Example

To get the type of an object, call the method getType()

t = myObject.getType()
print t.getName()

Where t is an instance of the class GKType. If myObject is a road section, calling getName() on t will return the string “GKSection”.

To get the list of columns in a type:

cols = t.getColumns( GKType.eSearchOnlyThisType )

and to get all attribute names and values for the object:

for col in cols:
    if col.getColumnType() != GKColumn._GKTimeSerie and myObject.getDataValue(col)[0] != None:
        print col.getName()+": "+myObject.getDataValue(col)[0].toString()

If a specific get method is available to access an object’s attribute, it is more convenient to call it

speed = section.getSpeed()

rather than use the meta data model:

attr = section.getType().getColumn( "GKSection::speedAtt", GKType.eSearchThisAndParentTypes )
speed = section.getDataValueDouble( attr )

To summarize, the meta model should be accessed when:

  • a specific method to retrieve the data doesn’t exist, or
  • the data has been added at runtime, therefore no get method exists.

It should be noted that not all attributes of an object are accessible through the meta data.

Meta Editing by Script

To see which columns are available in a Type, one method would be to use a script as follows:

sectionType = model.getType( "GKSection" )
attributes  = sectionType.getColumns( GKType.eSearchOnlyThisType )
for x in attributes:
    print "Name :" + str(x.getName())
    print "External Name: " + str(x.getExternalName())
    print "Column Type: " + str(x.getColumnType())
    print "Description: " +str(x.getDescription())

To add a column:

sectionType.addColumn( "GKSection::RoadNoiseFactor", "Road Noise Factor", GKColumn.Double, GKColumn.eExternal )

Meta Editing in the Aimsun Next

An alternative method is to use the Aimsun Next Types window and Type Editor. Select the menu option Window/Windows/Type. The Types window will then shown all types in the system.


The Types Browser

Double click on a type to access its editor.


Type Editor

To add a new attribute to the type, select the Add button in the editor.


Editing a New Attribute

When defining a new unique name, use the convention TypeName::Attribute. This will ensure that it is unique throughout the model and cannot be inadvertently duplicated in different types.

Storage for attributes can be defined by the user as:

  • External: Aimsun Next will provide storage in memory and in the ANG file.
  • Temporal: Aimsun Next will provide storage in memory.
  • Function: a Python function.

While the data type can be Integer, Unsigned Integer, Boolean, Double, String, Object, or Time Series . Note however, that the Time Series type will not be saved, even if the storage is set to external, so when the ANG file is closed and re-opened, the attribute will still be present, but it will be empty.

To access the data value above, the code would be as follows:

attr = model.getColumn( "GKSection::RoadNoiseFactor" )
roadNoiseFactor = section.getDataValue( attr )

All the attributes natively defined within the Aimsun Next classes have a storage type Internal and as such are not editable. Note also External attributes cannot be deleted or edited, so when such an attribute is created, it is not possible to make any changes using the Type Editor window, however it can be edited using scripting.

The storage type Function allows an attribute to be defined whose content is dynamically calculated each time it is accessed (read via GUI or Python script). The calculation is defined by the Python function provided in the dialog code text box.

The function should be defined as:

def eval_attr( object ):
    # compute the value
    return res

Where object is a reference to the object for which the attribute is evaluated; res is the value returned by the function, that will be the value of the attribute for the object. The type must be coherent with that selected as Data Type; the current implementation only supports Integer, Unsigned Integer, Boolean, Double, and String.

For example, to compare the flows of two microsimulation scenarios, whose averages IDs are 2880 and 2890, define a new attribute as shown below.


Editing a New Attribute

Note that time series cannot be stored into an attribute defined as function, the aggregated value of the flow time series of the averages must be calculated.

The By Area option is currently not used. The Dynamic option is used to specify that the value of the attribute can change even if not manually modified by the user; only dynamic attributes can be used to define a trigger.