Skip to content

Commit

Permalink
Merge pull request #67 from toruseo/develop
Browse files Browse the repository at this point in the history
Update tests and docs; Replace depreciated functions in OSMnx
  • Loading branch information
toruseo authored Apr 30, 2024
2 parents 004e5af + 6043d95 commit 24df62d
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 89 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/test-functions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Test functions

on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 6 * * 1'

jobs:
test-functions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uxsim and dependencies
run: |
python -m pip install --upgrade pip
pip install .
- name: Install pytest other dependencies
run: pip install pytest pytest-rerunfailures pytest-xdist setuptools osmnx requests
- name: Run tests with pytest
run: pytest -n auto tests/test_other_functions.py --durations=0 -v
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST.in
#MANIFEST.in

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include uxsim/files/*
6 changes: 0 additions & 6 deletions README.jp.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,8 @@ results:

- `uxsim`ディレクトリ: UXsimパッケージ
- `uxsim/uxsim.py`: UXsim本体のコード
- `uxsim/analyzer.py`: 計算結果分析用コード
- `uxsim/utils.py`: 関連コード
- `uxsim/ResultGUIViewer/ResultGUIViewer.py`: 計算結果可視化用GUIサブモジュール
- `uxsim/OSMImporter/OSMImporter.py`: OpenStreetMapからのインポート用サブモジュール
- `uxsim/files`ディレクトリ: 関連ファイル
- `demos_and_examples`ディレクトリ: チュートリアルや使用例
- `dat`ディレクトリ: サンプルシナリオファイル
- `tests``.github`ディレクトリ: 開発用ファイル

## 使用条件・ライセンス

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ UXsim is released under the MIT License. You are free to use it as long as the s

When publishing works based on UXsim, please cite:

- Toru Seo. Macroscopic Traffic Flow Simulation: Fundamental Mathematical Theory and Python Implementation. Corona Publishing Co., Ltd., 2023.
- Toru Seo. UXsim: An open source macroscopic and mesoscopic traffic simulator in Python-a technical overview. arXiv preprint arXiv: 2309.17114, 2023
- Toru Seo. [Macroscopic Traffic Flow Simulation: Fundamental Mathematical Theory and Python Implementation](https://toruseo.github.io/misc/MacroTrafficSim_English_summary.pdf). Corona Publishing Co., Ltd., 2023.
- Toru Seo. [UXsim: An open source macroscopic and mesoscopic traffic simulator in Python-a technical overview](http://dx.doi.org/10.48550/arXiv.2309.17114). arXiv preprint arXiv: 2309.17114, 2023

## Contributing and Discussion

Expand Down
75 changes: 27 additions & 48 deletions demos_and_examples/demo_notebook_04en_OpenStreetMap.ipynb

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)

#Tokyo highway
nodes, links = OSMImporter.import_osm_data(north=35.817, south=35.570, east=139.881, west=139.583, custom_filter='["highway"~"motorway"]')
nodes, links = OSMImporter.import_osm_data(bbox=(35.817, 35.570, 139.881, 139.583), custom_filter='["highway"~"motorway"]')
nodes, links = OSMImporter.osm_network_postprocessing(nodes, links, node_merge_threshold=0.005, node_merge_iteration=5, enforce_bidirectional=True) # merge threshold distance: 0.005 degree ~= 500 m. `enforce_bidirectional` makes all links bidirectional, so that network is not fragmented (but the original network topology is not preserved rigorously).
OSMImporter.osm_network_visualize(nodes, links, show_link_name=0)
OSMImporter.osm_network_to_World(W, nodes, links, default_jam_density=0.2, coef_degree_to_meter=111000)
Expand Down
13 changes: 11 additions & 2 deletions demos_and_examples/uxsim/OSMImporter/OSMImporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class OSMImporter:
OpenStreetMap importer using OSMnx.
Work in progress. Import from OSM is experimental and may not work as expected. It is functional but may produce inappropriate networks for simulation, such as too many nodes, too many deadends, fragmented networks.
"""
def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|primary"]',
def import_osm_data(north=None, south=None, east=None, west=None, bbox=None, custom_filter='["highway"~"trunk|primary"]',
default_number_of_lanes_mortorway=3, default_number_of_lanes_trunk=3,
default_number_of_lanes_primary=2, default_number_of_lanes_secondary=2,
default_number_of_lanes_residential=1, default_number_of_lanes_tertiary=1,
Expand All @@ -42,6 +42,8 @@ def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|p
----------
north, south, east, west: float
The latitudes and longitudes of the area to be imported.
bbox: list
The bounding box of the area to be imported. The order is [north, south, east, west]. This is prioritized than north, south, east, west arguments.
custom_filter: str
The filter to be used for importing the data.
The default is '["highway"~"trunk|primary"]', which means that only trunk and primary roads (usually correspond to major arterial roads) are imported.
Expand All @@ -68,7 +70,14 @@ def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|p
raise ImportError("Optional module 'osmnx' is not installed. Please install it by 'pip install osmnx' to use this function.")

print("Start downloading OSM data. This may take some time.")
G = ox.graph.graph_from_bbox(north=north, south=south, east=east, west=west, network_type="drive",
if bbox is not None:
try:
G = ox.graph.graph_from_bbox(bbox=bbox, network_type="drive", custom_filter=custom_filter)
except TypeError: #version issue?
warnings.warn("OSMnx version may be too old. Update is recommended.")
G = ox.graph.graph_from_bbox(north=bbox[0], south=bbox[1], east=bbox[2], west=bbox[3], network_type="drive", custom_filter=custom_filter)
else:
G = ox.graph.graph_from_bbox(north=north, south=south, east=east, west=west, network_type="drive",
custom_filter=custom_filter)
print("Download completed")
"""
Expand Down
23 changes: 15 additions & 8 deletions demos_and_examples/uxsim/uxsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,26 +374,32 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed=20, jam_d
Notes
-----
Traffic Flow Model:
- The link model follows a multi-lane, single-pipe approach where FIFO is guaranteed per link and no lane changing occurs.
- Fundamental diagram parameters such as free_flow_speed, jam_density (or jam_density_per_lane), and number_of_lanes determine the link's flow characteristics. Reaction time of drivers `REACTION_TIME` is a grobal parameter.
- Real-time link status for external reference is maintained with attributes `speed`, `density`, `flow`, `num_vehicles`, and `num_vehicles_queue`.
Traffic Flow Model Parameters:
- Their definition is illustrated as https://toruseo.jp/UXsim/docs/_images/fundamental_diagram.png
- If you are not familiar to the traffic flow theory, it is recommended that you adjust only `free_flow_speed` and `number_of_lanes` for the traffic flow model parameters, leaving the other parameters at their default values.
Capacity and Bottlenecks:
- The `capacity_out` and `capacity_in` parameters set the outflow and inflow capacities of the link. If not provided, the capacities are unlimited.
- These capacities can represent bottlenecks at the beginning or end of the link.
Connection to Node Model:
- At the downstream end of a sending link, vehicles in all lanes have the right to be sent out, but FIFO order is maintained.
- At the upstream end of a receiving link, all lanes can accept vehicles.
Parameter Adjustments:
- Some traffic flow model parameters like `free_flow_speed`, `jam_density`, `capacity_out`, `capacity_in`, and `merge_priority` can be altered during simulation to reflect changing conditions.
Details on Multi-lane model:
- Link model:
- Multiple lanes with single-pipe model. FIFO is guaranteed per link. No lane changing.
- Links have a `lanes` attribute representing the number of lanes.
Expand All @@ -406,22 +412,23 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed=20, jam_d
- Receiving links:
- All lanes at the upstream end of the link can accept vehicles.
Details on Fundamental diagram parameters (*: input, **: alternative input):
- *free_flow_speed (m/s)
- *jam_density (veh/m/LINK)
- **jam_density_per_lane (veh/m/lane)
- *lanes, number_of_lane (lane)
Details on Fundamental diagram parameters (+: input, ++: alternative input):
- free_flow_speed (m/s)+
- jam_density (veh/m/LINK)+
- jam_density_per_lane (veh/m/lane)++
- lanes, number_of_lane (lane)+
- tau: y-intercept of link FD (s/veh*LINK)
- REACTION_TIME (s/veh*lane)
- REACTION_TIME, World.reaction_time (s/veh*lane)
- w (m/s)
- capacity (veh/s/LINK)
- capacity_per_lane (veh/s/lane)
- delta: minimum spacing (m/veh*LINK)
- delta_per_lane: minimum spacing in lane (m/veh*lane)
- q_star: capacity (veh/s/LINK)
- k_star: critical density (veh/s/LINK)
- *capacity_in, capacity_out: bottleneck capacity at beginning/end of link (veh/s/LINK)
- *Node.flow_capacity: node flow capacity (veh/s/LINK-LIKE)
- capacity_in, capacity_out: bottleneck capacity at beginning/end of link (veh/s/LINK)+
- Node.flow_capacity: node flow capacity (veh/s/LINK-LIKE)+
"""

s.W = W
Expand Down
4 changes: 1 addition & 3 deletions tests/test_other_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ def test_analyzer():
assert True

@pytest.mark.filterwarnings("ignore::UserWarning")
@pytest.mark.filterwarnings("ignore::DeprecationWarning") #TODO: Current usage of OSMnx will be deprecated in the future. Need to update.
@pytest.mark.filterwarnings("ignore:Iteration over multi-part geometries is deprecated")
def test_osm_import():
from uxsim.OSMImporter import OSMImporter

Expand All @@ -86,7 +84,7 @@ def test_osm_import():
)

#Tokyo highway
nodes, links = OSMImporter.import_osm_data(north=35.817, south=35.570, east=139.881, west=139.583, custom_filter='["highway"~"motorway"]')
nodes, links = OSMImporter.import_osm_data(bbox=(35.817, 35.570, 139.881, 139.583), custom_filter='["highway"~"motorway"]')
nodes, links = OSMImporter.osm_network_postprocessing(nodes, links, node_merge_threshold=0.005, node_merge_iteration=5, enforce_bidirectional=True) # merge threshold distance: 0.005 degree ~= 500 m. `enforce_bidirectional` makes all links bidirectional, so that network is not fragmented (but the original network topology is not preserved rigorously).
OSMImporter.osm_network_visualize(nodes, links, show_link_name=0, show_mode=0, save_mode=0)
OSMImporter.osm_network_to_World(W, nodes, links, default_jam_density=0.2, coef_degree_to_meter=111000)
Expand Down
3 changes: 1 addition & 2 deletions tests/test_verification_taxi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""
This script verifies whether UXsim outputs plausible solutions for exceptional or uncommon situations.
The behavior of UXsim may be updated in the future.
This script verifies whether UXsim outputs reasonable solutions with taxis.
"""

import pytest
Expand Down
13 changes: 11 additions & 2 deletions uxsim/OSMImporter/OSMImporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class OSMImporter:
OpenStreetMap importer using OSMnx.
Work in progress. Import from OSM is experimental and may not work as expected. It is functional but may produce inappropriate networks for simulation, such as too many nodes, too many deadends, fragmented networks.
"""
def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|primary"]',
def import_osm_data(north=None, south=None, east=None, west=None, bbox=None, custom_filter='["highway"~"trunk|primary"]',
default_number_of_lanes_mortorway=3, default_number_of_lanes_trunk=3,
default_number_of_lanes_primary=2, default_number_of_lanes_secondary=2,
default_number_of_lanes_residential=1, default_number_of_lanes_tertiary=1,
Expand All @@ -42,6 +42,8 @@ def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|p
----------
north, south, east, west: float
The latitudes and longitudes of the area to be imported.
bbox: list
The bounding box of the area to be imported. The order is [north, south, east, west]. This is prioritized than north, south, east, west arguments.
custom_filter: str
The filter to be used for importing the data.
The default is '["highway"~"trunk|primary"]', which means that only trunk and primary roads (usually correspond to major arterial roads) are imported.
Expand All @@ -68,7 +70,14 @@ def import_osm_data(north, south, east, west, custom_filter='["highway"~"trunk|p
raise ImportError("Optional module 'osmnx' is not installed. Please install it by 'pip install osmnx' to use this function.")

print("Start downloading OSM data. This may take some time.")
G = ox.graph.graph_from_bbox(north=north, south=south, east=east, west=west, network_type="drive",
if bbox is not None:
try:
G = ox.graph.graph_from_bbox(bbox=bbox, network_type="drive", custom_filter=custom_filter)
except TypeError: #version issue?
warnings.warn("OSMnx version may be too old. Update is recommended.")
G = ox.graph.graph_from_bbox(north=bbox[0], south=bbox[1], east=bbox[2], west=bbox[3], network_type="drive", custom_filter=custom_filter)
else:
G = ox.graph.graph_from_bbox(north=north, south=south, east=east, west=west, network_type="drive",
custom_filter=custom_filter)
print("Download completed")
"""
Expand Down
Loading

0 comments on commit 24df62d

Please sign in to comment.