Components#

An AequilibraE project helds geometric information that can be accessed by the user in three different classes: Links, Nodes, and Zoning. We’ll first cover these classes, and then we’ll go over the project components without geo-spatial information.

project.network.nodes#

This method allows you to access the API resources to manipulate the ‘nodes’ table. Each item in the ‘nodes’ table is a Node object.

>>> from shapely.geometry import Point

>>> project_nodes = project.network.nodes

# To get one 'Node' object
>>> node = project_nodes.get(10070)

# We can check the existing fields for each node in the 'nodes' table
>>> node.data_fields()
['node_id', 'is_centroid', 'modes', 'link_types', 'geometry', 'osm_id']

# Let's renumber this node and save it
>>> node.renumber(1000)
>>> node.save()

# A node can also be used to add a special generator
# `new_centroid` returns a `Node` object that we can edit
>>> centroid = project_nodes.new_centroid(2000)

# Don't forget to add a geometry to your centroid if it's a new node
# This centroid corresponds to the Port of Coquimbo!
>>> centroid.geometry = Point(-71.32, -29.94)

# As this centroid is not associated with a zone, we must tell AequilibraE the initial area around
# the centroid to look for candidate nodes to which the centroid can connect.
>>> centroid.connect_mode(area=centroid.geometry.buffer(0.01), mode_id="c")

# Don't forget to update these changes to the nodes in memory
>>> project_nodes.refresh()

# And save them into your project
>>> project_nodes.save()

# Last but not less important, you can check your project nodes
# `project_nodes.data` returns a geopandas GeoDataFrame.
>>> nodes_data = project_nodes.data

>>> # or if you want to check the coordinate of each node in the shape of
>>> # a Pandas DataFrame
>>> coords = project_nodes.lonlat
>>> coords.head(3) 
  node_id        lon        lat
0   10037 -71.315117 -29.996804
1   10064 -71.336604 -29.949050
2   10065 -71.336517 -29.949062

See also

project.zoning#

This method allows you to access the API resources to manipulate the ‘zones’ table. Each item in the ‘zones’ table is a Zone object.

>>> from shapely.geometry import Polygon

>>> project_zones = project.zoning

# Let's start this example by adding a new field to the 'zones' table
>>> project_zones.fields.add("parking_spots", "Number of public parking spots", "INTEGER")

# We can check if the new field was indeed created
>>> project_zones.fields.all_fields() 
['area', 'employment', 'geometry', 'name', 'parking_spots', 'population', 'zone_id']

# Now let's get a zone and modifiy it
>>> zone = project_zones.get(40)

# By disconnecting the transit mode
>>> zone.disconnect_mode("t")

# Connecting the bicycle mode
>>> zone.connect_mode("b")

# And adding the number of public parking spots in the field we just created
>>> zone.parking_spots = 30

# You can save this changes if you want
>>> zone.save()

# The changes connecting / disconnecting modes reflect in the zone centroids
# and can be seen in the 'nodes' table.

# To return a dictionary with all 'Zone' objects in the model
>>> project_zones.all_zones() 
{1: ..., ..., 133: ...}

# If you want to delete a zone
>>> other_zone = project_zones.get(38)
>>> other_zone.delete()

# Or to add a new one
>>> zone_extent = Polygon([(-71.3325, -29.9473), (-71.3283, -29.9473), (-71.3283, -29.9539), (-71.3325, -29.9539)])

>>> new_zone = project_zones.new(38)
>>> new_zone.geometry = zone_extent

# We can add a centroid to the zone we just created by specifying its location or
# pass `None` to use the geometric center of the zone
>>> new_zone.add_centroid(Point(-71.33, -29.95))

# Let's refresh our fields
>>> project_zones.refresh_geo_index()

# And save the new changes in the project
>>> project_zones.save()

# Finally, to return a geopandas GeoDataFrame with the project zones
>>> zones = project_zones.data

# To get a Shapely Polygon or Multipolygon with the entire zoning coverage
>>> boundaries = project_zones.coverage()

# And to get the nearest zone to a given geometry
>>> project_zones.get_closest_zone(Point(-71.3336, -29.9490))
57

>>> project.close()

See also

project.about#

This class provides an interface for editing the ‘about’ table of a project. We can add new fields or edit the existing ones as necessary, but everytime you add or modify a field, you have to write back this information, otherwise it will be lost.

>>> project = Project()
>>> project.open("/tmp/accessing_sfalls_data")

>>> project.about.add_info_field("my_new_field")
>>> project.about.my_new_field = "add some useful information about the field"

# We can add data to an existing field
>>> project.about.author = "Your Name"

# And save our modifications
>>> project.about.write_back()

# To assert if 'my_new_field' was added to the 'about' table, we can check the characteristics
# stored in the table by returning a list with all characteristics in the 'about' table
>>> project.about.list_fields() 
['model_name', ..., 'my_new_field']

# The 'about' table is created automatically when a project is created, but if you're
# loading a project created with an older AequilibraE version that didn't contain it,
# it is possible to create one too.
>>> project.about.create()

>>> project.close()

See also

project.FieldEditor#

The FieldEditor allows the user to edit the project data tables, and it has two different purposes:

  • Managing data tables, through the addition/deletion of fields

  • Editing the tables’ metadata (aka the description of each field)

This class is directly accessed from within the corresponding module one wants to edit.

>>> project = Project()
>>> project.open("/tmp/accessing_nauru_data")

# We'll edit the fields in the 'nodes' table
>>> node_fields = project.network.nodes.fields

# To add a new field to the 'nodes' table
>>> node_fields.add("my_new_field", "this is an example of AequilibraE's funcionalities", "TEXT")

# Don't forget to save these modifications
>>> node_fields.save()

# To edit the description of a field
>>> node_fields.osm_id = "number of the osm node_id"

# Or just to access the description of a field
>>> node_fields.modes
'Modes connected to the node'

# One can also check all the fields in the 'nodes' table.
>>> node_fields.all_fields() 
['is_centroid', ..., 'my_new_field']

>>> project.close()

All field descriptions are kept in the table ‘attributes_documentation’.

See also

project.log#

Every AequilibraE project contains a log file that holds information on all the project procedures. It is possible to access the log file contents, as presented in the next code block.

>>> project = Project()
>>> project.open("/tmp/accessing_nauru_data")

>>> project_log = project.log()

# Returns a list with all entires in the log file.
>>> print(project_log.contents()) 
['2021-01-01 15:52:03,945;aequilibrae;INFO ; Created project on D:/release/Sample models/nauru', ...]

# If your project's log is getting cluttered, it is possible to clear it.
# Use this option wiesly once the deletion of data in the log file can't be undone.
>>> project_log.clear()

>>> project.close()

See also

project.matrices#

This method ia a gateway to all the matrices available in the model, which allows us to update the records in the ‘matrices’ table. Each item in the ‘matrices’ table is a MatrixRecord object.

>>> project = Project()
>>> project.open("/tmp/accessing_sfalls_data")

>>> matrices = project.matrices

# One can also check all the project matrices as a Pandas' DataFrame
>>> matrices.list() 

# We can add a naw matrix
>>> matrices.new_record() 

# To delete a matrix from the 'matrices' table, we can delete the record directly
>>> matrices.delete_record("demand_mc")

# or by selecting the matrix and deleting it
>>> mat_record = matrices.get_record("demand_omx")
>>> mat_record.delete()

# If you're unsure if you have a matrix in you project, you can check if it exists
# This function will return `True` or `False`
>>> matrices.check_exists("my_matrix")
False

# If a matrix was added or deleted by an external process, you should update or clean
# your 'matrices' table to keep your project organised.
>>> matrices.update_database()  # in case of addition

>>> matrices.clear_database()  # in case of deletion

# To reload the existing matrices in memory once again
>>> matrices.reload()

# Similar to the `get_record` function, we have the `get_matrix`, which allows you to
# get an AequilibraE matrix.
>>> matrices.get_matrix("demand_aem") 

>>> project.close()

See also

project.network.modes#

This method allows you to access the API resources to manipulate the ‘modes’ table. Each item in ‘modes’ table is a Mode object.

>>> project = Project()
>>> project.open("/tmp/accessing_coquimbo_data")

>>> modes = project.network.modes

# We create a new mode
>>> new_mode = modes.new("k")
>>> new_mode.mode_name = "flying_car"

# And add it to the modes table
>>> modes.add(new_mode)

# When we add a new mode to the 'modes' table, it is automatically saved in the table
# But we can continue editing the modes, and save them as we modify them
>>> new_mode.description = "Like the one in the cartoons"
>>> new_mode.save()

# You can also remove a Mode from a project using its ``mode_id``
>>> modes.delete("k")

# To check all `Modes` in the project as a dictionary whose keys are the `mode_id`'s
>>> modes.all_modes() 
{'b': <aequilibrae.project.network.mode.Mode object at 0x...>}

# There are two ways to get a Mode from the 'modes' table
# using the ``mode_id``
>>> get_mode = modes.get("c")

# or using the ``mode_name``
>>> get_mode = modes.get_by_name("car")

>>> project.close()

See also

project.network.periods#

This method allows you to access the API resources to manipulate the ‘periods’ table. Each item in the ‘periods’ table is a Period object.

>>> project = Project()
>>> project.open("/tmp/accessing_coquimbo_data")

>>> periods = project.network.periods

# Let's add a new field to our 'periods' table
>>> periods.fields.add("my_field", "This is field description", "TEXT")

# To save this modification, we must refresh the table
>>> periods.refresh_fields()

# Let's get our default period and change the description for our new field
>>> select_period = periods.get(1)
>>> select_period.my_field = "hello world"

# And we save this period modification
>>> select_period.save()

# To see all periods data as a Pandas' DataFrame
>>> all_periods = periods.data

# To add a new period
>>> new_period = periods.new_period(2, 21600, 43200, "6AM to noon")

# It is also possible to renumber a period
>>> new_period.renumber(9)

# And check the existing data fields for each period
>>> new_period.data_fields()
['period_id', 'period_start', 'period_end', 'period_description', 'my_field']

# Saving can be done after finishing all modifications in the table but for the sake
# of this example, we'll save the addition of a new period to our table right away
>>> periods.save()

>>> project.close()

See also