aequilibrae.project.network package¶
Subpackages¶
Submodules¶
aequilibrae.project.network.connector_creation module¶
- aequilibrae.project.network.connector_creation.connector_creation(geo, zone_id: int, srid: int, mode_id: str, link_types='', connectors=1)¶
aequilibrae.project.network.haversine module¶
- aequilibrae.project.network.haversine.haversine(lon1, lat1, lon2, lat2)¶
Calculate the great circle distance between two points on the earth (specified in decimal degrees)
aequilibrae.project.network.link module¶
- class aequilibrae.project.network.link.Link(dataset)¶
Bases:
aequilibrae.project.network.safe_class.SafeClass
A Link object represents a single record in the links table
from aequilibrae import Project proj = Project() proj.open('path/to/project/folder') all_links = proj.network.links # Let's get a mode to work with modes = proj.network.modes car_mode = modes.get('c') # We can just get one link in specific link1 = all_links.get(4523) link2 = all_links.get(3254) # We can find out which fields exist for the links which_fields_do_we_have = link1.data_fields() # And edit each one like this link1.lanes_ab = 3 link1.lanes_ba = 2 # we can drop a mode from the link link1.drop_mode(car_mode) # or link1.drop_mode('c') # we can add a mode to the link link2.add_mode(car_mode) # or link2.add_mode('c') # Or set all modes at once link2.set_modes('cmtw') # We can just save the link link1.save() link2.save()
- __init__(dataset)¶
- delete()¶
Deletes link from database
- save()¶
Saves link to database
- set_modes(modes: str)¶
Sets the modes acceptable for this link
- Args:
modes (
str
): string with all mode_ids to be assigned to this link
- add_mode(mode: [<class 'str'>, <class 'aequilibrae.project.network.mode.Mode'>])¶
Adds a new mode to this link
Raises a warning if mode is already allowed on the link, and fails if mode does not exist
- Args:
mode_id (
str
or Mode): Mode_id of the mode or mode object to be added to the link
- drop_mode(mode: [<class 'str'>, <class 'aequilibrae.project.network.mode.Mode'>])¶
Removes a mode from this link
Raises a warning if mode is already NOT allowed on the link, and fails if mode does not exist
- Args:
mode_id (
str
or Mode): Mode_id of the mode or mode object to be removed from the link
- data_fields() list ¶
lists all data fields for the link, as available in the database
- Returns:
data fields (
list
): list of all fields available for editing
aequilibrae.project.network.link_type module¶
- class aequilibrae.project.network.link_type.LinkType(data_set: dict)¶
Bases:
aequilibrae.project.network.safe_class.SafeClass
A link_type object represents a single record in the link_types table
- delete()¶
- save()¶
aequilibrae.project.network.link_types module¶
- class aequilibrae.project.network.link_types.LinkTypes(net)¶
Bases:
object
Access to the API resources to manipulate the link_types table in the network
from aequilibrae import Project p = Project() p.open('path/to/project/folder') link_types = p.network.link_types # We can get a dictionary of link types in the model all_link_types = link_types.all_types() #And do a bulk change and save it for link_type_id, link_type_obj in all_link_types.items(): link_type_obj.beta = 1 # We can save changes for all link types in one go all_link_types.save() # or just get one link_type in specific default_link_type = link_types.get('y') # or just get it by name default_link_type = link_types.get_by_name('default') # We can change the description of the link types default_link_type.description = 'My own new description' # Let's say we are using alpha to store lane capacity during the night as 90% of the standard default_link_type.alpha =0.9 * default_link_type.lane_capacity # To save this link types we can simply default_link_type.save() # We can also create a completely new link_type and add to the model new_type = link_types.new('a') new_type.link_type = 'Arterial' # Only ASCII letters and *_* allowed # other fields are not mandatory # We then save it to the database new_type.save() # we can even keep editing and save it directly once we have added it to the project new_type.lanes = 3 new_type.lane_capacity = 1100 new_type.save()
- __init__(net)¶
- new(link_type_id: str) aequilibrae.project.network.link_type.LinkType ¶
- delete(link_type_id: str) None ¶
Removes the link_type with link_type_id from the project
- get(link_type_id: str) aequilibrae.project.network.link_type.LinkType ¶
Get a link_type from the network by its link_type_id
- get_by_name(link_type: str) aequilibrae.project.network.link_type.LinkType ¶
Get a link_type from the network by its link_type (i.e. name)
- fields() aequilibrae.project.field_editor.FieldEditor ¶
Returns a FieldEditor class instance to edit the Link_Types table fields and their metadata
- all_types() dict ¶
Returns a dictionary with all LinkType objects available in the model. link_type_id as key
- save()¶
aequilibrae.project.network.links module¶
- class aequilibrae.project.network.links.Links¶
Bases:
aequilibrae.project.basic_table.BasicTable
Access to the API resources to manipulate the links table in the network
from aequilibrae import Project proj = Project() proj.open('path/to/project/folder') all_links = proj.network.links # We can just get one link in specific link = all_links.get(4523) # We can save changes for all links we have edited so far all_links.save()
- sql = ''¶
Query sql for retrieving links
- __init__()¶
- get(link_id: int) aequilibrae.project.network.link.Link ¶
Get a link from the network by its link_id
It raises an error if link_id does not exist
- Args:
link_id (
int
): Id of a link to retrieve- Returns:
link (
Link
): Link object for requested link_id
- new() aequilibrae.project.network.link.Link ¶
Creates a new link
- Returns:
link (
Link
): A new link object populated only with link_id (not saved in the model yet)
- copy_link(link_id: int) aequilibrae.project.network.link.Link ¶
Creates a copy of a link with a new id
It raises an error if link_id does not exist
- Args:
link_id (
int
): Id of the link to copy- Returns:
link (
Link
): Link object for requested link_id
- delete(link_id: int) None ¶
Removes the link with link_id from the project
- Args:
link_id (
int
): Id of a link to delete
- refresh_fields() None ¶
After adding a field one needs to refresh all the fields recognized by the software
- property data: pandas.core.frame.DataFrame¶
Returns all links data as a Pandas dataFrame
- Returns:
table (
DataFrame
): Pandas dataframe with all the links, complete with Geometry
- refresh()¶
Refreshes all the links in memory
- save()¶
aequilibrae.project.network.mode module¶
aequilibrae.project.network.modes module¶
- class aequilibrae.project.network.modes.Modes(net)¶
Bases:
object
Access to the API resources to manipulate the modes table in the network
from aequilibrae import Project p = Project() p.open('path/to/project/folder') modes = p.network.modes # We can get a dictionary of all modes in the model all_modes = modes.all_modes() #And do a bulk change and save it for mode_id, mode_obj in all_modes.items(): mode_obj.beta = 1 mode_obj.save() # or just get one mode in specific car_mode = modes.get('c') # or just get this same mode by name car_mode = modes.get_by_name('c') # We can change the description of the mode car_mode.description = 'personal autos only' # Let's say we are using alpha to store the PCE for a future year with much smaller cars car_mode.alpha = 0.95 # To save this mode we can simply car_mode.save() # We can also create a completely new mode and add to the model new_mode = modes.new('k') new_mode.mode_name = 'flying_car' # Only ASCII letters and *_* allowed # other fields are not mandatory # We then explicitly add it to the network modes.add(new_mode) # we can even keep editing and save it directly once we have added it to the project new_mode.description = 'this is my new description' new_mode.save()
- __init__(net)¶
- add(mode: aequilibrae.project.network.mode.Mode) None ¶
We add a mode to the project
- delete(mode_id: str) None ¶
Removes the mode with mode_id from the project
- property fields: aequilibrae.project.field_editor.FieldEditor¶
Returns a FieldEditor class instance to edit the Modes table fields and their metadata
- get(mode_id: str) aequilibrae.project.network.mode.Mode ¶
Get a mode from the network by its mode_id
- get_by_name(mode: str) aequilibrae.project.network.mode.Mode ¶
Get a mode from the network by its mode_name
- all_modes() dict ¶
Returns a dictionary with all mode objects available in the model. mode_id as key
- new(mode_id: str) aequilibrae.project.network.mode.Mode ¶
Returns a new mode with mode_id that can be added to the model later
aequilibrae.project.network.network module¶
- class aequilibrae.project.network.network.Network(project)¶
Bases:
aequilibrae.utils.worker_thread.WorkerThread
Network class. Member of an AequilibraE Project
- netsignal¶
- req_link_flds = ['link_id', 'a_node', 'b_node', 'direction', 'distance', 'modes', 'link_type']¶
- req_node_flds = ['node_id', 'is_centroid']¶
- protected_fields = ['ogc_fid', 'geometry']¶
- __init__(project) None ¶
- conn: sqlc¶
- source: sqlc¶
- link_types: aequilibrae.project.network.link_types.LinkTypes = None¶
- skimmable_fields()¶
Returns a list of all fields that can be skimmed
- Returns:
list
: List of all fields that can be skimmed
- list_modes()¶
Returns a list of all the modes in this model
- Returns:
list
: List of all modes
- create_from_osm(west: Optional[float] = None, south: Optional[float] = None, east: Optional[float] = None, north: Optional[float] = None, place_name: Optional[str] = None, modes=['car', 'transit', 'bicycle', 'walk']) None ¶
Downloads the network from Open-Street Maps
- Args:
west (
float
, Optional): West most coordinate of the download bounding boxsouth (
float
, Optional): South most coordinate of the download bounding boxeast (
float
, Optional): East most coordinate of the download bounding boxplace_name (
str
, Optional): If not downloading with East-West-North-South boundingbox, this is requiredmodes (
list
, Optional): List of all modes to be downloaded. Defaults to the modes in the parameter filep = Project() p.new(nm)
from aequilibrae import Project, Parameters p = Project() p.new('path/to/project') # We now choose a different overpass endpoint (say a deployment in your local network) par = Parameters() par.parameters['osm']['overpass_endpoint'] = "http://192.168.1.234:5678/api" # Because we have our own server, we can set a bigger area for download (in M2) par.parameters['osm']['max_query_area_size'] = 10000000000 # And have no pause between successive queries par.parameters['osm']['sleeptime'] = 0 # Save the parameters to disk par.write_back() # And do the import p.network.create_from_osm(place_name=my_beautiful_hometown) p.close()
- signal_handler(val)¶
- build_graphs(fields: Optional[list] = None, modes: Optional[list] = None) None ¶
Builds graphs for all modes currently available in the model
When called, it overwrites all graphs previously created and stored in the networks’ dictionary of graphs
- Args:
- fields (
list
, optional): When working with very large graphs with large number of fields in the database, it may be useful to specify which fields to use
- modes (
list
, optional): When working with very large graphs with large number of fields in the database, it may be useful to generate only those we need
- fields (
To use the fields parameter, a minimalistic option is the following
p = Project() p.open(nm) fields = ['distance'] p.network.build_graphs(fields, modes = ['c', 'w'])
- set_time_field(time_field: str) None ¶
Set the time field for all graphs built in the model
- Args:
time_field (
str
): Network field with travel time information
- count_links() int ¶
Returns the number of links in the model
- Returns:
int
: Number of links
- count_centroids() int ¶
Returns the number of centroids in the model
- Returns:
int
: Number of centroids
- count_nodes() int ¶
Returns the number of nodes in the model
- Returns:
int
: Number of nodes
- extent()¶
Queries the extent of the network included in the model
- Returns:
model extent (
Polygon
): Shapely polygon with the bounding box of the model network.
- convex_hull() shapely.geometry.polygon.Polygon ¶
Queries the model for the convex hull of the entire network
- Returns:
model coverage (
Polygon
): Shapely (Multi)polygon of the model network.
- refresh_connection()¶
Opens a new database connection to avoid thread conflict
aequilibrae.project.network.node module¶
- class aequilibrae.project.network.node.Node(dataset)¶
Bases:
aequilibrae.project.network.safe_class.SafeClass
A Node object represents a single record in the nodes table
from aequilibrae import Project from shapely.geometry import Point proj = Project() proj.open('path/to/project/folder') all_nodes = proj.network.nodes # We can just get one link in specific node1 = all_nodes.get(7890) # We can find out which fields exist for the links which_fields_do_we_have = node1.data_fields() # And edit each one like this node1.comment = 'This node is important' # It success if the node_id already does not exist node1.renumber(998877) node.geometry = Point(1,2) # We can just save the node node1.save()
- __init__(dataset)¶
- save()¶
Saves node to database
- data_fields() list ¶
lists all data fields for the node, as available in the database
- Returns:
data fields (
list
): list of all fields available for editing
- renumber(new_id: int)¶
Renumbers the node in the network
Raises a warning if another node already exists with this node_id
- Args:
new_id (
int
): New node_id
- connect_mode(area: shapely.geometry.polygon.Polygon, mode_id: str, link_types='', connectors=1)¶
Adds centroid connectors for the desired mode to the network file
Centroid connectors are created by connecting the zone centroid to one or more nodes selected from all those that satisfy the mode and link_types criteria and are inside the provided area.
The selection of the nodes that will be connected is done simply by computing running the KMeans2 clustering algorithm from SciPy and selecting the nodes closest to each cluster centroid.
When there are no node candidates inside the provided area, is it progressively expanded until at least one candidate is found.
If fewer candidates than required connectors are found, all candidates are connected.
Args:
area (
Polygon
): Initial area where AequilibraE will look for nodes to connectmode_id (
str
): Mode ID we are trying to connectlink_types (
str
, Optional): String with all the link type IDs that can be considered. eg: yCdR. Defaults to ALL link typesconnectors (
int
, Optional): Number of connectors to add. Defaults to 1
aequilibrae.project.network.nodes module¶
- class aequilibrae.project.network.nodes.Nodes¶
Bases:
aequilibrae.project.basic_table.BasicTable
Access to the API resources to manipulate the links table in the network
from aequilibrae import Project proj = Project() proj.open('path/to/project/folder') all_nodes = proj.network.nodes # We can just get one link in specific node = all_nodes.get(7894) # We can save changes for all nodes we have edited so far all_nodes.save()
- sql = ''¶
Query sql for retrieving nodes
- __init__()¶
- get(node_id: int) aequilibrae.project.network.node.Node ¶
Get a node from the network by its node_id
It raises an error if node_id does not exist
- Args:
node_id (
int
): Id of a node to retrieve- Returns:
node (
Node
): Node object for requested node_id
- refresh_fields() None ¶
After adding a field one needs to refresh all the fields recognized by the software
- refresh()¶
Refreshes all the nodes in memory
- new_centroid(node_id: int) aequilibrae.project.network.node.Node ¶
Creates a new centroid with a given ID
- Args:
node_id (
int
): Id of the centroid to be created
- save()¶
- property data: pandas.core.frame.DataFrame¶
Returns all nodes data as a Pandas dataFrame
- Returns:
table (
DataFrame
): Pandas dataframe with all the nodes, complete with Geometry
aequilibrae.project.network.osm_builder module¶
- class aequilibrae.project.network.osm_builder.OSMBuilder(osm_items: List, path: str, node_start=10000)¶
Bases:
aequilibrae.utils.worker_thread.WorkerThread
- building¶
- __init__(osm_items: List, path: str, node_start=10000) None ¶
- doWork()¶
- data_structures()¶
- importing_links(node_count)¶
- static unique_count(a)¶
- static get_link_fields()¶
- static get_link_field_type(field_name)¶
- static field_osm_source()¶
- modes_per_link_type()¶
- static get_node_fields()¶
aequilibrae.project.network.osm_downloader module¶
” Large portions of this code were adopted from OSMNx, by Geoff Boeing.
Although attempts to use OSMNx were made (including refactoring its entire code base as a contribution to that package), it became clear that its integration with libraries not available with QGIS’ Python distribution was too tight, and was therefore not practical to detach them in order to use OSMNx as a dependency or submodule
For the original work, please see https://github.com/gboeing/osmnx
- class aequilibrae.project.network.osm_downloader.OSMDownloader(polygons, modes)¶
Bases:
aequilibrae.utils.worker_thread.WorkerThread
- downloading¶
- __init__(polygons, modes)¶
- doWork()¶
- overpass_request(data, pause_duration=None, timeout=180, error_pause_duration=None)¶
Send a request to the Overpass API via HTTP POST and return the JSON response.
- datadict or OrderedDict
key-value pairs of parameters to post to the API
- pause_durationint
how long to pause in seconds before requests, if None, will query API status endpoint to find when next slot is available
- timeoutint
the timeout interval for the requests library
- error_pause_durationint
how long to pause in seconds before re-trying requests if error
dict
- get_osm_filter(modes: list) str ¶
loosely adapted from http://www.github.com/gboeing/osmnx