Edmonton Route Finder
Crafted by Bob Bu · Winter 2022
This project is a lightweight client/server route finder for Edmonton: a pygame map client lets you pick a start and end point, and a C++ server returns waypoint coordinates for the shortest path on a road graph built from the Edmonton roads dataset.

# edmonton-roads-2.0.1.txt (excerpt)...E,30233210,276310831,Connors Road NWE,561041104,276310830,Connors Road NWE,225520313,299403402,76 Street North-westE,251435422,247105314,Kingsway Avenue NWE,247105314,251435422,Kingsway Avenue NWE,778537675,304465226,160 Avenue NWE,304465239,304465240,91 Street NW...
The client and server communicate through a pair of named pipes, so you can inspect exactly what gets sent and received while keeping the system close to a real routing backend.
The server loads edmonton-roads-2.0.1.txt into a weighted directed graph: each road segment becomes a directed edge, and each vertex stores its latitude and longitude as integers in 100,000-ths of a degree.
Edge weights use Manhattan distance in this scaled coordinate space.
When you click on the map, the selected latitude/longitude usually does not land exactly on a graph vertex, so the server snaps the start and end to the nearest vertices before running Dijkstra.
Dijkstra's algorithm computes a shortest-path tree from the snapped start vertex by repeatedly relaxing edges.
The protocol is strictly line-based: the client writes exactly two lines to (start then end), and the server streams waypoint lines to . The final line is a single to signal completion. Closing the client sends to request shutdown.
Pipe protocol# client -> inpipe (exactly two lines per request)53.530870 -113.53297253.530870 -113.514991# server -> outpipe (N waypoint lines, then terminator)53.53087 -113.5329753.51620 -113.5329753.51620 -113.5149953.53087 -113.51499E
The server must read the request exactly as two newline-terminated lines. In earlier iterations, using fixed-size reads could desynchronize the stream under timing/OS buffering, causing occasional “hangs”. Switching to line-based reads ( / parsing) makes the server follow the protocol deterministically.
The project also includes a one-command launcher script that builds the server, waits for FIFO pipes to exist, starts the client, and writes separate server/client logs for debugging.
# recommended: run inside WSL/Linux filesystem (FIFO support)chmod +x run.sh./run.sh# logs# logs/server.log# logs/client.log
This demonstrates a simple navigation loop, starting with clicks of two points, snapping to the nearest vertices, computing the shortest path, and streaming waypoints back to the client for rendering. Code is available on the corresponding GitHub repository.
University of Alberta · Edmonton, AB, Canada