Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions gis/GIS-Based Traffic Simulation with Mesa/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# agent.py

import mesa


class VehicleAgent(mesa.Agent):
def __init__(self, unique_id, model, vehicle_type, route=None):
super().__init__(unique_id, model)
self.vehicle_type = vehicle_type # Assign vehicle type (car, truck, bike)
self.route = route # Assign the route for the vehicle
self.current_step = 0 # Initialize the current step in the route

def step(self):
if self.route and self.current_step < len(self.route):
next_node = self.route[self.current_step]
x = self.model.space.G.nodes[next_node]["x"] - self.model.min_x
y = self.model.space.G.nodes[next_node]["y"] - self.model.min_y
self.model.space.move_agent(self, (x, y))
self.current_step += 1 # Move to the next step in the route
else:
pass # Optionally, handle reaching the end of the route
63 changes: 63 additions & 0 deletions gis/GIS-Based Traffic Simulation with Mesa/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import random

import mesa
import networkx as nx
import osmnx as ox
from agent import VehicleAgent


class TrafficGeoSpace(mesa.space.ContinuousSpace):
def __init__(self, G, min_x, min_y, max_x, max_y, crs="EPSG:3857"):
x_max = max_x - min_x
y_max = max_y - min_y
super().__init__(x_max, y_max, False)
self.G = G # Assign the OSMnx graph to the space
self.crs = crs # Coordinate Reference System


class TrafficModel(mesa.Model):
def __init__(self, G, num_vehicles, min_x, min_y, max_x, max_y):
super().__init__()
self.schedule = mesa.time.RandomActivation(self)
self.space = TrafficGeoSpace(G, min_x, min_y, max_x, max_y)
self.min_x = min_x
self.min_y = min_y
self.max_x = max_x
self.max_y = max_y
self.create_vehicles(num_vehicles)

def create_vehicles(self, num_vehicles):
vehicle_types = ["car", "truck", "bike"]
for i in range(num_vehicles):
start_point = (
random.uniform(self.min_y, self.max_y),
random.uniform(self.min_x, self.max_x),
)
end_point = (
random.uniform(self.min_y, self.max_y),
random.uniform(self.min_x, self.max_x),
)
start_node = ox.distance.nearest_nodes(
self.space.G, X=start_point[1], Y=start_point[0]
)
end_node = ox.distance.nearest_nodes(
self.space.G, X=end_point[1], Y=end_point[0]
)

try:
route = nx.shortest_path(
self.space.G, source=start_node, target=end_node, weight="length"
)
vehicle_type = random.choice(vehicle_types)
vehicle = VehicleAgent(i, self, vehicle_type=vehicle_type, route=route)
start_position = (
self.space.G.nodes[start_node]["x"] - self.min_x,
self.space.G.nodes[start_node]["y"] - self.min_y,
) # Adjust coordinates
self.space.place_agent(vehicle, start_position)
self.schedule.add(vehicle)
except nx.NetworkXNoPath:
pass # Skip this vehicle if no route is found

def step(self):
self.schedule.step()
90 changes: 90 additions & 0 deletions gis/GIS-Based Traffic Simulation with Mesa/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@


# GIS-Based Traffic Simulation with Mesa



## Overview

This project simulates urban traffic congestion using the Mesa agent-based modeling framework and OSMnx for extracting road network data from OpenStreetMap. It visualizes traffic patterns and congestion in a critical urban area in Bangalore, India. The simulation includes different vehicle types and their movement on the road network, and the results are animated into a GIF to showcase the traffic dynamics over time.

## Why We Need This

### Problem Definition

High vehicle density and complex road networks are significant contributors to traffic congestion in Indian cities, especially in densely populated urban areas. This issue affects millions of travelers, leading to:

- Increased travel duration
- Higher fuel consumption
- Elevated pollution levels

In cities like Bangalore, also known as the Tech Hub or Silicon Valley of India, these problems are exacerbated by rapid urbanization and technological growth.

### Objective

By developing and refining this traffic simulation project, we aim to deliver more effective and adaptable solutions for managing traffic congestion in Indian cities. The project has the potential to:

- Improve traffic flow and reduce congestion
- Decrease travel time and fuel consumption
- Lower pollution levels
- Enhance the overall quality of life for urban residents

## Features

- **Urban Traffic Simulation**: Models traffic flow using various vehicle types (cars, trucks, bikes).
- **OSMnx Integration**: Utilizes OSMnx to extract and visualize road networks from OpenStreetMap.
- **Animated Visualization**: Generates an animated GIF showing traffic patterns and vehicle movements.
- **Dynamic Visualization**: Updates the visualization in real-time to reflect vehicle positions on the map.

## Mesa is Playing a Main Role in This Model
Mesa provides a straightforward and efficient framework to create, manage, and simulate the movement of vehicles on a road network. It allows for the simple creation of agents (vehicles) that follow predefined paths, interact within a given space, and produce simulation results without unnecessary complexity.

**Mesa** is used because it enables you to build a functional and effective traffic simulation without overcomplicating the model. Its integration with other libraries like **OSMnx** and **NetworkX** ensures that the model remains easy to understand and maintain, focusing on delivering practical insights rather than adding complexity.

## Requirements

- **Python 3.11**
- **OSMnx**: `pip install osmnx`
- **NetworkX**: `pip install networkx`
- **Folium**: `pip install folium`
- **Mesa**: `pip install mesa`
- **PIL**: `pip install pillow`



1. **Update Bounding Box Coordinates**

Modify the `north`, `south`, `east`, and `west` variables in the script to reflect the area you want to simulate.

2. **Run the Simulation**

Execute the script to run the traffic simulation and generate the animated GIF:



3. **View the Results**

The resulting animated GIF will be saved in the `Data` directory. You can view it directly from your file explorer or display it within a Jupyter Notebook using:



## Code Overview

- **TrafficGeoSpace**: Defines the space in which the agents move, based on the road network graph.
- **VehicleAgent**: Represents individual vehicles, including their routes and movement.
- **TrafficModel**: Manages the simulation, creating vehicles and stepping through the simulation.
- **Visualization**: Uses Folium to create maps and convert HTML maps to PNG images, which are then compiled into an animated GIF.

## Future Work

The project can be extended to address the following aspects:

- **Advanced Traffic Management**: Incorporate real-time traffic data and predictive analytics for dynamic traffic management.
- **Integration with Smart City Solutions**: Connect with IoT sensors and smart traffic lights for a more integrated approach.
- **Scenario Testing**: Simulate various scenarios such as road closures, construction, or major events to evaluate their impact on traffic.

## Acknowledgments

- **OSMnx**: For providing easy access to OpenStreetMap data.
- **Mesa**: For the agent-based modeling framework.
- **Folium**: For interactive map visualizations.
89 changes: 89 additions & 0 deletions gis/GIS-Based Traffic Simulation with Mesa/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import io
import os

import folium
import networkx as nx
import osmnx as ox
from model import TrafficModel, VehicleAgent
from PIL import Image

# Bounding box coordinates for Bangalore
# Note that OSMnx 2.0 uses (north, south, east, west) order, so OSMnx < 2 is required (tested on 1.9.4)
# See https://github.com/gboeing/osmnx/pull/1196
north, south, east, west = 12.976, 12.961, 77.599, 77.579
bbox = (north, south, east, west)

# Create a graph from the bounding box using the bbox parameter
G = ox.graph_from_bbox(bbox=bbox, network_type="drive")

# Extract graph bounds for the TrafficGeoSpace
min_x = min(nx.get_node_attributes(G, "x").values())
max_x = max(nx.get_node_attributes(G, "x").values())
min_y = min(nx.get_node_attributes(G, "y").values())
max_y = max(nx.get_node_attributes(G, "y").values())

# Running the TrafficModel simulation
num_vehicles = 51
model = TrafficModel(G, num_vehicles, min_x, min_y, max_x, max_y)

# Ensure the directory exists
gif_dir = "Data/"
os.makedirs(gif_dir, exist_ok=True)

# Running the simulation and updating the Folium map
map_images = []
for step in range(10): # Run for 10 steps
model.step()

# Create a new map for each step
temp_map = folium.Map(
location=[(north + south) / 2, (east + west) / 2], zoom_start=15
)

# Add the road network to the map
edges = ox.graph_to_gdfs(G, nodes=False, edges=True)
for _, row in edges.iterrows():
points = [
(row["geometry"].coords[i][1], row["geometry"].coords[i][0])
for i in range(len(row["geometry"].coords))
]
folium.PolyLine(points, color="blue", weight=2.5, opacity=1).add_to(temp_map)

# Add vehicles to the map
for vehicle in model.schedule.agents:
if isinstance(vehicle, VehicleAgent):
if vehicle.current_step > 0:
# Ensure vehicle has moved
position_node = vehicle.route[vehicle.current_step - 1]
vehicle_position = (
model.space.G.nodes[position_node]["y"],
model.space.G.nodes[position_node]["x"],
)
color = (
"red"
if vehicle.vehicle_type == "car"
else "blue"
if vehicle.vehicle_type == "truck"
else "green"
)
folium.CircleMarker(
location=vehicle_position, radius=5, color=color, fill=True
).add_to(temp_map)
else:
print(f"Vehicle {vehicle.unique_id} has not started its route yet.")

# Save the map state as an image
img_data = temp_map._to_png(5)
img = Image.open(io.BytesIO(img_data))
map_images.append(img)
print(f"Step {step} image captured.")

# Create an animated GIF from the saved map images
gif_path = os.path.join(gif_dir, "bangalore_traffic_congestion.gif")
map_images[0].save(
gif_path, save_all=True, append_images=map_images[1:], duration=500, loop=0
)

print(
"Simulation complete. Check the Data/ directory for the Bangalore traffic congestion animation."
)