AI-assisted running route recommendation system for Boston. Generates diverse candidate routes using A* search and ranks them across six scoring dimensions: elevation, road type, weather (Markov prediction), crime, traffic, and scenery.
Ripandeep Kaur, Deen Khan, Armaan Mehra, Stefan Lachenmann
CS4100-group10/
├── main.py # CLI entry point
├── api.py # Flask API server for the demo UI
├── demo.html # Browser-based demo UI (Leaflet map + scoring dashboard)
├── config.py # API keys, file paths, scoring weights
├── routing/
│ ├── graph.py # Boston graph generation and caching (OSMnx)
│ └── route_generator.py # A* search, edge penalization, scoring pipeline
├── scoring/
│ ├── elevation.py # Elevation gain scoring
│ ├── crime.py # KD-tree crime density scoring
│ ├── traffic.py # TomTom traffic flow scoring
│ ├── scenery.py # Google Places scenery scoring
│ └── weather.py # Markov chain weather prediction and scoring
└── data/ # Generated at runtime (cached graph, model, snapshots)
├── boston_graph.pkl
├── markov_model.json
├── crime_data.csv
└── traffic_snapshot.json
pip install osmnx networkx numpy pandas scipy requests folium flask flask-corsThis downloads the full Boston pedestrian network (51,683 nodes, 148,546 edges), adds elevation data, computes edge grades, and bakes in crime scores. Takes about 10 minutes on first run due to elevation API rate limits. The result is cached as a pickle file so subsequent loads are instant.
python3 -m routing.graph --regenerateTo verify the graph loaded correctly:
python3 -m routing.graph --verifyThe weather model trains automatically on first run if no saved model exists. To train it manually:
python3 -c "from scoring.weather import MarkovWeatherPredictor; p = MarkovWeatherPredictor(); p.train(days_back=730); p.save('data/markov_model.json')"This pulls 2 years of hourly Boston weather from Open-Meteo and builds the transition matrices. The trained model is saved as JSON and loaded automatically on future runs.
python3 main.pyDefault route is Northeastern to Boston Common. Customize with flags:
python3 main.py --start "fenway park" --end "harvard square"
python3 main.py --start-coords 42.3398 -71.0892 --end-coords 42.3551 -71.0657
python3 main.py --candidates 8 --flat
python3 main.py --hillyAvailable preset locations: boston common, fenway park, harvard square, mit, back bay, seaport, north end, south station, northeastern, charles river.
- Start the API server:
python3 api.py- Open in your browser:
http://127.0.0.1:8080
Note: on macOS, port 5000 is used by AirPlay. The API runs on port 8080 by default. If you changed the port in api.py, use that port instead.
The UI lets you pick start/end locations from dropdowns, choose terrain preference (flat/neutral/hilly), set the number of candidates, and hit Generate Routes. Routes are drawn on a Leaflet map with score breakdowns and a Markov weather forecast panel.
The green "API connected" dot in the top right confirms the UI is talking to the backend. If it says "API offline", make sure api.py is running in another terminal.
Default weights in config.py:
| Factor | Weight | Description |
|---|---|---|
| Road type | 0.25 | Footpath = 1.0, motorway = 0.05 |
| Elevation | 0.20 | Deviation from preferred gain |
| Crime | 0.20 | KD-tree spatial density, severity tiers |
| Traffic | 0.15 | TomTom flow ratio, distance-decay |
| Weather | 0.10 | Markov expected score across run window |
| Scenery | 0.10 | Google Places scenic type + rating |
Weights are configurable in config.py under WEIGHTS.
Set in config.py:
- OpenWeather (required for live weather): included
- TomTom (required for traffic): included
- The
data/folder is created automatically on first run - Crime data CSV must be downloaded and placed at
data/crime_data.csvbefore generating the graph. Download it from Boston Crime Incident Reports (August 2015 to date). Click "Explore" on the CSV resource and download the file, then rename it tocrime_data.csvand move it to thedata/folder. - Here is a download link that has a snapshot of the traffic graph so that you do not have to run it for an hour. Maybe if you remove that from running by commenting it out it will prevent you from waiting an eternity. The file can be found here and will exist for 1 week: https://limewire.com/d/6Dzkz#KdgJug1MTX
- Traffic snapshot is cached at
data/traffic_snapshot.json - The Markov model saves to
data/markov_model.jsonafter first training