Skip to content

Commit

Permalink
Merge pull request #20 from xyluo25/main
Browse files Browse the repository at this point in the history
load TAZs
  • Loading branch information
xyluo25 authored Jan 24, 2024
2 parents 61993db + f7c98e2 commit b88c0f9
Show file tree
Hide file tree
Showing 15 changed files with 310 additions and 81 deletions.
24 changes: 18 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ for engaging traffic simulation games such as A/B street and DTALite?
\*How to teach our undergraduate students the important **trip generation and
trip distribution steps**, using their own beautiful campus as examples?
\*How to analyze the resident locations and other land use properties using
flexible **grid zones, based on POI data from Openstreetmap** data and using
flexible **grid zones, based on POI data from OpenStreetMap** data and using
**open transportation modeling format**

![](doc/media/9ed9631f17469d631f9dfe97e4320c10.png)
Expand All @@ -14,14 +14,22 @@ flexible **grid zones, based on POI data from Openstreetmap** data and using
If you have not used Grid2demand before, here are some advices to get started.

1. Read the user guide or watch the video at https://www.youtube.com/watch?v=EfjCERQQGTs.

2. Obtain a map.osm or map.osm.pbf file for your area of interest at https://extract.bbbike.org/ or openstreetmap.org

3. Look at the examples at Google colab environment https://github.com/asu-trans-ai-lab/grid2demand/blob/main/grid2demand_tutorial.ipynb
4. Install Python, Grid2demand and QGIS on your computer or using google colab environmentModify one of the examples to implement your own model.
5. Post your questions on the users group: groups.google.com/d/forum/grid2demand

4. Install Python, Grid2demand and QGIS on your computer or using Google Colab environment to modify one of the examples to implement your own model.

5. Post your questions on the users group:

GitHub: https://github.com/asu-trans-ai-lab/grid2demand/issues

Google: groups.google.com/d/forum/grid2demand

Open-source tool of grid2demand aims to provide an open-source quick demand
generation python package, which can work anywhere in the world, thanks to open
data from [Openstreetmap](Openstreetmap) users.
data from [OpenStreetMap](Openstreetmap) users.

To know more about this tool, please check out the 3rd mini teaching lesson in
our podcast series, [https://www.youtube.com/watch?v=EfjCERQQGTs](https://www.youtube.com/watch?v=EfjCERQQGTs).
Expand All @@ -47,7 +55,7 @@ which is also accessible through Google Colab.

Mini teaching lesson: [https://www.youtube.com/watch?v=EfjCERQQGTs](https://www.youtube.com/watch?v=EfjCERQQGTs)

**IIntroduction and Background Knowledge**
**I. Introduction and Background Knowledge**

Trip generation and trip distribution are the first 2 steps in the larger
context of the 4-step process in transportation planning. The standard four
Expand Down Expand Up @@ -382,7 +390,11 @@ node_dict, poi_dict = gd.load_network.values()
zone_dict = gd.net2zone(node_dict, num_x_blocks=10,num_y_blocks=10)

# Generate zone based on grid size with 10 km width and 10km height for each zone
# zone_dict = gd.net2zone(node_dict, cell_width=10, cell_height=10)
# zone_dict = gd.net2zone(node_dict, cell_width=10, cell_height=10, unit="km")

# if you have your own zone.csv(TAZs), we can generate zones from your personal TAZs
# zone_dict = gd.taz2zone()


# Synchronize geometry info between zone, node and poi
# add zone_id to node and poi dictionaries
Expand Down
7 changes: 5 additions & 2 deletions README_pkg.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ if __name__ == "__main__":
# Step 2: Generate zone dictionary from node dictionary by specifying number of x blocks and y blocks
zone_dict = gd.net2zone(node_dict, num_x_blocks=10, num_y_blocks=10)

# # Generate zone based on grid size with 10 km width and 10km height for each zone
# Step 2: Generate zone based on grid size with 10 km width and 10km height for each zone
# zone_dict = gd.net2zone(node_dict, cell_width=10, cell_height=10)

# Step 2: Generate zone dictionary from zone.cvs(TAZs) prepared from users.
# zone_dict = gd.taz2zone()

# Step 3: synchronize geometry info between zone, node and poi
# add zone_id to node and poi dictionaries
# also add node_list and poi_list to zone dictionary
Expand Down Expand Up @@ -98,7 +101,7 @@ The grid2demand project welcomes your expertise and enthusiasm!
Small improvements or fixes are always appreciated. If you are considering larger contributions to the source code, please contact us through email:

Xiangyong Luo : [email protected]

Dr. Xuesong Simon Zhou : [email protected]

Writing code isn't the only way to contribute to grid2demand. You can also:
Expand Down
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@
7. Advanced Traffic Assignment: Alternative or user-defined volume delay function; HOV assignment; Multi-modal multi-class assignment(MMA); Volume-Dependent Turning delays and signal opeimization traffic assignment; Combined trip distribution- assignment model; Create volume delay function DDLs
8. Good source: https://github.com/joshchea/python-tdm/tree/master
9. Link performance functions t = $t_f [1 + \alpha(\dfrac{v}{c})^\beta)] $
10. Add save node and poi function
11. user can update trip rate
12. for zone file, change change column id to zone_id
13. change file name from zone.csv to zone_grid2demand.csv
14.
2 changes: 1 addition & 1 deletion grid2demand/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .utils_lib.pkg_settings import pkg_settings
from ._grid2demand import GRID2DEMAND

print('grid2demand, version 0.3.8')
print('grid2demand, version 0.3.9')


__all__ = ["read_node", "read_poi", "read_network",
Expand Down
44 changes: 41 additions & 3 deletions grid2demand/_grid2demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
check_required_files_exist,
gen_unique_filename,
path2linux)
from grid2demand.func_lib.read_node_poi import read_node, read_poi, read_network
from grid2demand.func_lib.read_node_poi import read_node, read_poi, read_network, read_zone
from grid2demand.func_lib.gen_zone import (net2zone,
sync_zone_and_node_geometry,
sync_zone_and_poi_geometry,
Expand All @@ -31,13 +31,17 @@ def __init__(self, input_dir: str = "", output_dir: str = "") -> None:
# check input directory
if not input_dir:
self.input_dir = path2linux(os.getcwd())
print(f" : Input directory is not specified. Use current working directory {self.input_dir} as input directory. Please make sure node.csv and poi.csv are in {self.input_dir}.")
print(f" : Input directory is not specified. \
Use current working directory {self.input_dir} as input directory. \
Please make sure node.csv and poi.csv are in {self.input_dir}.")
else:
self.input_dir = path2linux(input_dir)
self.output_dir = path2linux(output_dir) if output_dir else self.input_dir

# check input directory
self.__check_input_dir()

# load default package settings, user can modify the settings before running the model
self.__load_pkg_settings()

def __check_input_dir(self) -> None:
Expand All @@ -50,6 +54,7 @@ def __check_input_dir(self) -> None:
Returns:
None: will generate self.path_node and self.path_poi for class instance.
"""

print(" : Checking input directory...")
if not os.path.isdir(self.input_dir):
raise NotADirectoryError(f"Error: Input directory {self.input_dir} does not exist.")
Expand All @@ -63,10 +68,21 @@ def __check_input_dir(self) -> None:

self.path_node = path2linux(os.path.join(self.input_dir, "node.csv"))
self.path_poi = path2linux(os.path.join(self.input_dir, "poi.csv"))
self.path_zone = ""

# check optional files in input directory (zone.csv)
optional_files = pkg_settings.get("optional_files", [])
is_optional_files_exist = check_required_files_exist(optional_files, dir_files)

if is_optional_files_exist:
print(f" : Optional files: {optional_files} are found in {self.input_dir}.")
print( " : Optional files could be used in the following steps.")
self.path_zone = path2linux(os.path.join(self.input_dir, "zone.csv"))

print(" : Input directory is valid.\n")

def __load_pkg_settings(self) -> None:
print(" : Loading package settings...")
print(" : Loading default package settings...")
self.pkg_settings = pkg_settings
print(" : Package settings loaded successfully.\n")

Expand Down Expand Up @@ -151,10 +167,32 @@ def net2zone(self, node_dict: dict[int, Node], num_x_blocks: int = 10, num_y_blo
Returns:
dict[str, Zone]: zone_dict {zone_name: Zone}
"""
print(" : Note: This method will generate grid-based zones from node_dict. \
\n : If you want to use your own zones(TAZs), \
\n : please skip this method and use taz2zone() instead. \n")

print(" : Generating zone dictionary...")
self.zone_dict = net2zone(node_dict, num_x_blocks, num_y_blocks, cell_width, cell_height, unit)
return self.zone_dict

def taz2zone(self) -> dict[str, Zone]:

print(" : Note: This method will generate zones from zone.csv (TAZs). \
\n : If you want to use grid-based zones (generate zones from node_dict) , \
\n : please skip this method and use net2zone() instead. \n")

if self.path_zone:
print(" : Generating zone dictionary...")
self.zone_dict = read_zone(self.path_zone, self.pkg_settings.get("set_cpu_cores"))

return self.zone_dict

print(" : zone.csv does not exist in your input directory. \
\n Please check your input directory. \
\n Or you can use net2zone() to generate grid-based zones from node_dict.")
return None


def sync_geometry_between_zone_and_node_poi(self, zone_dict: dict = "",
node_dict: dict = "", poi_dict: dict = "") -> dict[str, dict]:
"""synchronize geometry between zone and node/poi.
Expand Down
Binary file modified grid2demand/func_lib/__pycache__/gen_zone.cpython-310.pyc
Binary file not shown.
Binary file modified grid2demand/func_lib/__pycache__/read_node_poi.cpython-310.pyc
Binary file not shown.
3 changes: 2 additions & 1 deletion grid2demand/func_lib/gen_zone.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ def generate_polygon(x_min, x_max, y_min, y_max) -> shapely.geometry.Polygon:
geometry=points_lst[i]
)
zone_id_flag += 1
print(f" : Successfully generated zone dictionary: {len(zone_dict) - 4 * len(zone_upper_row)} Zones generated, plus {4 * len(zone_upper_row)} boundary gates (points))")
print(f" : Successfully generated zone dictionary: {len(zone_dict) - 4 * len(zone_upper_row)} Zones generated, \
\n plus {4 * len(zone_upper_row)} boundary gates (points))")
return zone_dict


Expand Down
Loading

0 comments on commit b88c0f9

Please sign in to comment.