How naina-sriv/routeiq works
1. Overall shape
RouteIQ is a single Python backend with a browser-based, map-driven frontend. The core runtime is FastAPI in routeiq/main.py, which sits between the UI and the optimization services. The app solves two distinct problems: single-vehicle trip ordering (TSP) and multi-vehicle fleet routing with constraints (VRP).
2. Frontend boundary
The browser UI is a single-page experience rendered from templates/index.html and powered by vanilla JS in static/js/. app.js owns shared map state, stop management, and geocoding interactions; trip.js handles trip-planner mode; fleet.js handles fleet mode, vehicle lists, and route rendering. Leaflet is the map layer, and the frontend talks to the backend only through HTTP fetch() calls.
3. API layer
main.py exposes the service boundary: GET /health, POST /optimize, POST /optimize/fleet, POST /geocode, and POST /reverse-geocode. models.py defines the request/response contracts using Pydantic, while config.py centralizes environment-driven settings such as OSRM, Redis, stop limits, and solver timeouts.
4. Trip optimization flow (TSP)
POST /optimize sends the stop list through a road-distance matrix lookup, then into utils/solver.py. That solver uses Google OR-Tools for a single-vehicle route with fixed start and end nodes. The output is an ordered stop sequence plus per-leg travel times and polylines; if OR-Tools fails or times out, it falls back to a nearest-neighbor route.
5. Fleet optimization flow (VRP)
POST /optimize/fleet follows the same matrix acquisition path, then passes the data to utils/vrp_solver.py. This solver adds the fleet-specific constraints: one route per vehicle, vehicle capacity limits, optional per-stop time windows, and penalties for dropping stops when the fleet cannot cover everything. The response is grouped by vehicle and includes unassigned stops.
6. Road-network dependency
utils/osrm.py is the road-travel layer. It queries OSRM’s /table endpoint for the travel-time matrix and /route for leg polylines. This is the main external dependency that gives the app real road times instead of straight-line estimates. If OSRM is unavailable, the system can fall back to haversine-based estimates, and the response marks that fallback.
7. Caching boundary
utils/cache.py wraps Redis and caches the distance matrix, not the full optimization result. The cache key is derived from the stop coordinates in an order-independent way, so the same set of points reuses the same matrix even if the request order changes. This cache is the main performance boundary: it turns repeated route requests for the same stop set from OSRM-bound to near-instant.
8. Geocoding path
utils/geocoder.py handles forward and reverse geocoding through Nominatim. This is a separate flow from routing: user-entered addresses become coordinates before optimization, and dragged map pins can be converted back into display names. It supports the map UX but does not affect the solver logic.
9. Deployment topology
The repo is designed to run as a small containerized stack defined in docker-compose.yml: the FastAPI app, Redis, and an OSRM backend. In Docker, the app points to the internal OSRM service; outside Docker it can use a public OSRM endpoint. The OSRM container depends on preprocessed map data mounted into a volume, which is an operational prerequisite for routing.
10. Supporting quality and analysis subsystems
tests/ contains unit and integration coverage for the solvers and API behavior, especially route ordering, capacity limits, time windows, and error handling. benchmarks/compare_algorithms.py is a separate analysis tool that compares OR-Tools against a nearest-neighbor baseline using synthetic points and haversine distances. These are not part of the request path, but they validate solver quality and runtime claims.
Main entry points: main.py API server · osrm.py Road matrix · app.js Shared map · solver.py TSP solver
Components 19
Frontend
Browser UI, map state, and mode-specific interaction layers.
- UI shell · Single-page HTML entrypoint for the browser app.
routeiq/templates/index.html - Shared map · Owns shared map state, stop management, and geocoding interactions.
routeiq/static/js/app.js - Trip mode · Trip-planner interactions and route display for single-vehicle routing.
routeiq/static/js/trip.js - Fleet mode · Fleet-routing UI, vehicle lists, and multi-route rendering.
routeiq/static/js/fleet.js - Styles · Visual styling for the browser experience.
routeiq/static/css/style.css
Backend
FastAPI service, request models, settings, and optimization pipeline.
- API server · HTTP boundary exposing health, optimization, geocoding, and reverse-geocoding endpoints.
routeiq/main.py - Contracts · Request and response schemas for the API.
routeiq/models.py - Settings · Environment-driven settings for OSRM, Redis, limits, and solver timeouts.
routeiq/config.py - TSP solver · Single-vehicle route optimizer with fallback ordering.
routeiq/utils/solver.py - VRP solver · Multi-vehicle optimizer with capacity, time windows, and drop penalties.
routeiq/utils/vrp_solver.py - Matrix cache · Caches distance matrices keyed by coordinate sets.
routeiq/utils/cache.py
External services
Third-party and runtime dependencies used by the app.
- Road matrix · Queries OSRM table and route endpoints for travel times and polylines.
routeiq/utils/osrm.py - Geocoder · Forward and reverse geocoding for addresses and map pins.
routeiq/utils/geocoder.py
Ops
Container and deployment topology.
- Compose stack · Defines the app, Redis, and OSRM service topology.
routeiq/docker-compose.yml - App image · Container build for the FastAPI application.
routeiq/Dockerfile
Quality
Tests and benchmarking support.
- Benchmark · Compares OR-Tools against a nearest-neighbor baseline.
routeiq/benchmarks/compare_algorithms.py - API tests · Coverage for HTTP behavior and endpoint contracts.
routeiq/tests/test_api.py - Solver tests · Coverage for trip ordering and solver behavior.
routeiq/tests/test_solver.py - VRP tests · Coverage for fleet constraints and unassigned stops.
routeiq/tests/test_vrp_solver.py
Connections 25
- UI shell → Shared map: loads · The page shell bootstraps shared frontend state.
- Shared map → Trip mode: delegates · Trip mode builds on the shared map and stop state.
- Shared map → Fleet mode: delegates · Fleet mode builds on the shared map and stop state.
- Shared map → API server: fetch · Frontend calls backend HTTP endpoints for optimization and geocoding.
- Trip mode → API server: optimize · Trip planner submits stops to the single-route endpoint.
- Fleet mode → API server: optimize fleet · Fleet UI submits vehicles and stops to the VRP endpoint.
- API server → Contracts: uses · API handlers serialize and validate with Pydantic schemas.
- API server → Settings: reads · Service behavior is driven by environment settings.
- API server → Matrix cache: matrix cache · Optimization requests reuse cached distance matrices when possible.
- API server → Road matrix: routes · Service fetches road-time matrices and route polylines.
- API server → Geocoder: geocodes · API exposes address lookup and reverse lookup endpoints.
- API server → TSP solver: trip flow · Single-vehicle optimization is delegated to the TSP solver.
- API server → VRP solver: fleet flow · Multi-vehicle optimization is delegated to the VRP solver.
- TSP solver → Road matrix: depends on · Trip optimization uses road-time matrices and leg polylines.
- VRP solver → Road matrix: depends on · Fleet optimization uses road-time matrices and leg polylines.
- Matrix cache → Road matrix: misses · Cache misses trigger fresh OSRM matrix requests.
- Compose stack → API server: runs · Compose brings up the application service.
- Compose stack → Matrix cache: runs · Compose includes Redis for matrix caching.
- Compose stack → Road matrix: runs · Compose includes the routing backend service.
- App image → API server: builds · The application image packages the FastAPI backend.
- API tests → API server: validates · API tests exercise endpoint behavior and error handling.
- Solver tests → TSP solver: validates · Solver tests cover trip ordering and fallback behavior.
- VRP tests → VRP solver: validates · VRP tests cover constraints and assignment outcomes.
- Benchmark → TSP solver: compares · Benchmark script compares the solver against a baseline.
- Benchmark → VRP solver: compares · Benchmark script can be extended to fleet-style comparisons.