GIS · Python · Transit Planning

Bus Network Optimization Using Road-Based Routing

A data-driven system that identifies underserved areas, generates realistic bus routes along actual roads, and evaluates coverage improvement over time.

Trong Phuc Nguyen · Texas Wesleyan University

Project Overview

This project improves bus network accessibility using GIS data, population data, and graph algorithms.

The system identifies underserved residential areas, then generates new realistic bus routes using actual roads instead of straight-line connections.

Problem Statement

Underserved Areas

Some residential zones have many people but limited access to bus stops.

Inefficient Routing

Existing routes may not connect underserved neighborhoods effectively.

Planning Challenge

Transit planners need a data-driven method for route expansion.

Technologies Used

GeoPandas

Used to process GIS datasets, create buffers, and perform spatial overlay operations.

NetworkX

Used to build the road graph and perform shortest path routing.

SciPy KDTree

Used to quickly find nearest road nodes and bus stops.

Shapely

Used for geometry operations such as points, lines, and buffers.

Matplotlib

Used to generate visualization maps for each optimization step.

How the System Works

  1. Load routes, stops, population polygons, and roads.
  2. Create a 400-meter walking buffer around stops.
  3. Find underserved population areas.
  4. Select the highest-priority underserved area.
  5. Snap the target area to the nearest road node.
  6. Find the nearest existing bus stop.
  7. Use Dijkstra’s shortest path algorithm.
  8. Create a realistic road-based route.
  9. Add stops along the generated route.
  10. Repeat the optimization process over iterations.

How Pathfinding Works

The road network is converted into a graph. Intersections become nodes while roads become weighted edges.

The system searches this graph using Dijkstra’s algorithm to find the shortest realistic road-based path between underserved areas and existing stops.

Shortest Path = Minimum Total Edge Distance

Main Code Functions

__init__()

Loads GIS datasets, converts coordinate systems, and builds the road graph.

self.routes = gpd.read_file(FILES["routes"])
self.stops = gpd.read_file(FILES["stops"])
self.pop_gdf = gpd.read_file(FILES["population"])

snap_to_road(point)

Finds the nearest road node using KDTree.

dist, idx = self.tree.query([point.x, point.y])

propose_route()

Core optimization function that generates new routes.

path_coords = nx.shortest_path(
    self.road_graph,
    start_node,
    end_node,
    weight='weight'
)

Results and Iteration Comparison

These images show how the network improves over time.

Step 0 — Baseline

Step 0

Initial network before optimization.

Step 25 — Early Improvement

Step 25

New routes begin connecting underserved areas.

Step 40 — Intermediate Network

Step 40

Coverage improves with additional route generation.

Step 85 — Later Optimization

Step 85

The network reaches a more optimized state.

Add final coverage percentages and statistics here later.

Presentation and Project Files

The ZIP file below contains:

Download bus.zip

Conclusion

This project demonstrates how GIS analysis and graph algorithms can support public transportation planning.

By using real road networks and underserved population data, the system creates realistic and data-driven route proposals.