New model supply#
Creating new models supply files is not a trivial task, so you should not underestimate the time it takes to do it.
During the creation of the supply model, you should also refer to the network data model, which is described in detail in Network Data Model.
Note: This section presents a general guide for creating the supply components for new models. Automated tools are available whenever possible, but substantial manual work is still required.
From existing data#
More often than not, transport models are created from components of existing models, particularly networks and zoning systems. For this reason, we list below some important points to note when importing networks and zoning systems from existing data sources.
Links and Nodes#
Creating tables for nodes and links from existing data involves multiple steps, but they will vary substantially depending on the source of the data. Networks coming from Cube or Emme are usually more involved to import than those coming from TransCAD, for example.
Instead of attempting to describe the process for each possible source of data, we provide below the most important points to consider when importing networks into a Polaris supply model.
Links are bi-directional, so all information for both flow directions are contained in separate fields. This is particularly important when importing networks from software that represent link directions separately.
The AB direction of the link is the link topology. This means that the A node is the first node in the link as drawn, and the B node is the second node as drawn.
The node_a and node_b fields in the links table are filled automatically and correspond to the appropriate nodes from the Node layer. New nodes are created when no node is in the exact coordinates the link starts/ends at.
Links that have a positive number of lanes for a given direction (lanes_ab/ba) should have a positive speed for that direction (fspd_ab/ba).
There are other fields that are filled automatically. Refer to Link for details.
No two nodes can have the exact same coordinates.
Note: If maintaining node numbers is important to you, then you MUST import network nodes before importing links, and must ensure that the geometry of nodes and links match PERFECTLY.
Zoning#
Polaris has a substantial number of fields that are required for proper model operation, but they are not necessary at the time of the model build. For a full documentation of these fields, please refer to zone table structure.
The most important points to consider when importing zone systems are:
zone is The zone ID and a required field
area_type: The area type of the zone and a required field, but the user can use the value of 1 as the default value.
SocioEc data: Fields with population, employment and area fields are required by the demand model to work properly
Geometries are strictly required for Zones.
Transit#
Transit systems are not mandatory for Polaris to work.
Adding Public transport data to a Polaris Supply model can be done by importing GTFS zipped files, and multiple options are available to customize the results of the importing process. Among these customizations are:
Map-match the transit routes onto the roadway network. This is only relevant when simulating bus in traffic or when results need to be mapping precisely
Correcting schedules to ensure that time between consecutive stops don’t imply unrealistic speeds
Importing the route shapes as included in the GTFS feed (a.k.a. raw shapes)
A lengthy description of the mechanics of the GTFS importer and all its options are all available in the Public Transport section of this documentation.
Programmatically adding public transport routes is also possible, and is described in an example at Editing Public Transport Route System.
Locations#
Adding locations is a quite demanding task, and it is unlikely that you will have that data from other models. If you do, then it is critical to pay attention to the land_use field, which is intimately tied to the inner workings of Polaris. Please refer to the documentation of location table structure for acceptable values for this field.
Also remember that the Land_Use table will have to be populated with the adequate data before adding locations to the Supply file. See land use table structure for documentation on that table.
Note: The fields census_zone must be filled with the census tract ID for each location, assuming that that is the level of aggregation used in the sf1 file, described in Population Synthesis. Each zone must have at least one location of residential or ALL type if there is population for this zone. Each zone should also have at least one location.
Automated table creation#
If you want to boot strap the creation of a new model from public data sources, Polaris-Studio includes a set of tools that will get you a long way to a working model but there are a number of additional pieces of setup that will have to be done manually after following that example.
Examples of applications of these tools can also be found in our examples Building Models.
Zoning#
Adding a zone system from Polaris Studio is a simple task, and it supports using both census tracts and census block groups as the zoning system. This is the first step when creating a new model from scratch, and we recommend using census tracts as the zoning system as to limit memory requirements during model run.
You will also have to obtain a Census API key use this method.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
net.populate.add_zoning_system(model_area=gdf, zone_level="tracts", census_api_key="GETONEFROMCENSUS", year=2021)
Roadway Network (links and nodes) and transit#
Adding a zone system from Polaris Studio is a simple task, and it supports using both census tracts and census block groups as the zoning system. This is the first step when creating a new model from scratch, and we recommend using census tracts as the zoning system as to limit memory requirements during model run.
To use GTFS during the network build, the user can either provide the GTFS feed (see example_model_from_scratch) automatically search the Mobility Database API for available GTFS feeds. To use the Mobility Database API, the user must obtain an API key.
simpli_par = { "simplify": True,
"keep_transit_links": True,
"accessibility_level": "block-groups",
"maximum_network_capacity": False,
}
imput_par = {"algorithm": "knn",
"fields_to_impute": ("speed_ab", "speed_ba", "lanes_ab", "lanes_ba"),
}
net_constructor = net.populate.create_network(simplification_parameters=simpli_par, imputation_parameters=imput_par)
mobility_database_api_key = "GETONEFROMPROVIDER"
feed_count = net_constructor.download_gtfs(mobility_database_api_key=mobility_database_api_key)
net_constructor.build_network()
net_constructor.import_transit(map_match=False, date="")
Counties#
The counties layer is only necessary in Polaris for the use of the freight model, and therefore can be skipped if the user prefers. The documentation for this table can be found at counties table structure.
Note: The county data must be added to the model AFTER the zones have been added, and it is crucial that the year chosen corresponds to the data planned to be used in the freight model.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
net.populate.add_counties(year=2021)
Locations#
If you have no data for locations, you can follow the examples in Building Models on how to create these locations automatically. Documentation on the API is below.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
# We need control totals for each non-residential land use type for each location
# The Polaris development team currently maintains control totals for the US at census tract level
# A census API key is required to download control totals for residential locations
control_totals = gpd.read_file(rootdir / "control_totals.parquet")
net.populate.add_locations(
control_totals=control_totals,
census_api_key=os.environ.get("CENSUS_API_KEY"),
residential_sample_rate=0.25,
other_sample_rate=1.0,
)
Parking#
The Parking table is detailed on parking table structure in case you have data to add to it manually. 3If you don’t have data, you can follow the examples in Building Models on how to create these facilities automatically.
Note: Filling this table is not required, as it will be populated with a parking per location by default when the Location_Parking table is filled if no suitable parking facility is found.
Below there is an example for the API use.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
# We add location facilities from Open-Street Maps
# The default OSM parking tags downloaded are ("surface", "underground", "multi-storey", "rooftop")
control_totals = gpd.read_file(rootdir / "control_totals.parquet")
net.populate.add_parking()
EV Chargers#
It is likely that you also don’t have data on EV chargers to add to the model. In that case, you can resort to the automatic data shown in the Building Models and in the code excerpt below.
If adding EV chargers manually, please refer to the table’s documentation at ev charging stations table structure.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
# Polaris-Studio has a heuristic to cluster EV chargers into single stations whenever they are
# too close to each other. The default parameters are 5 clustering attempts and a maximum distance
# of 50 meters between chargers. An API key from NREL is required to download the data.
net.populate.add_ev_chargers(os.environ.get("EV_API_KEY"), max_dist=50, clustering_attempts=5)
See also: polaris.prepare.supply_tables.populate_tables.Populator The Documentation of the supply populator class
Micro-mobility#
Micro-mobility systems are not mandatory for Polaris to work, and there are no automated tools for collecting data on these systems. The user is encouraged to look into the documentation for the two tables required for this data: micromobility docks table structure and micromobility agencies table structure.
Internal consistency components#
There are multiple tables in the Supply database that do not depend on external data, but which are still required by Polaris. Polaris-Studio has a set of tools to build these tables, but the user is required to execute these procedures manually. Polaris is great, but it can’t read its users’ minds (yet) to realize they are done with external data inputs.
Transit_Walk and Transit_bike#
Active transport networks (walk and bike) are represented in separate tables in the supply database, but are currently exactly the same, as no Polaris model included walk-only or bike-only links. Polaris-Studio has a tool to build these tables that is accessible from both the QGIS plugin and from Python, which is exemplified below.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
active = net.active
# We can set a maximum length for walk links if we would like. This would break links longer than this
# active.set_max_link_dist(200)
active.build()
See also: polaris.network.active.active_networks.ActiveNetworks The Documentation of the ActiveNetworks class
Connections#
The Connections table is a strict requirement of Polaris, as links are not considered connected if there are no turns listed on this table. Intersection control is not mandatory to exist, as Polaris defaults to 4-way stops, but it is recommended that you have appropriate signal and stop information, which is codified on a series of tables, documented on signal table structure and sign table structure.
Adding connections to the supply model is fairly simple, as there is a tool for such, which is exemplified below. When setting signals to “osm”, the tool will retrieve traffic light location information from OpenStreet-Maps, and setting signs to [] tells the software to put stop signs on each intersection after analyzing potential rights of way to decide if those stop signs should be of the 4-way or 2-way kind.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
tools = net.tools
tools.rebuild_intersections(signals="osm", signs=[])
More detailed documentation on the traffic components can be found at Traffic elements.
Location-Links#
The Location_Links table is strictly required by Polaris, and specifies through which link can the trips originated/destinated at each location can access the network. The user can specify the maximum distance from the location to the network, and whether multiple links are allowed.
It is highly recommended to stick to the default parameters for this function.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
tools = net.tools
tools.rebuild_location_links()
# Can be parameterized as below
# tools.rebuild_location_links(maximum_distance=300, multiple_links=True)
Note: Regardless of the maximum distance parameter, Polaris-Studio will always add at least one link per location to this table.
Location-Parking#
The Location_Parking table is strictly required by Polaris, and specifies the parking location to be used for accessing each specific Location. The user must provide a maximum distance for parking facilities to be considered.
Note: In the event a Parking facility within the acceptable distance is not found, a new parking facility dedicated to the specific Location will be added to the Parking table and a record linking that parking facility to the location will be added to the Location_Parking table.
from polaris.network.network import Network
net = Network.from_file(path/to/supply-model.sqlite, run_consistency=False)
tools = net.tools
tools.rebuild_location_parking(maximum_distance=300)
See also: polaris.network.tools.tools.Tools The Documentation of the supply tools class