OccuEVRoute is a course-demo EV charging route planner for Shenzhen. It combines road-network search, battery feasibility, station availability, route diagnostics, occupancy prediction, and nearby POI context to recommend charging stations.
The app runs locally with FastAPI and Vite. Docker is not required.
OccuEVRoute/
├── backend/ # FastAPI API schemas, routes, and response shaping
├── frontend/ # React + Vite + Leaflet map UI
├── src/
│ ├── data_processing/ # Data ingestion and generated route artifacts
│ ├── route_planning/ # BFS, UCS, A*, ALT A*, CH, scoring, constraints
│ └── waiting_prediction/ # Occupancy and waiting prediction models
├── data/ # Runtime data and generated route artifacts
├── docs/ # Reports, diagrams, and model notes
├── models/ # Runtime model artifacts
└── start-occuevroute.bat
The route planner expects generated artifacts under data/processed/, and the occupancy predictor expects a compact runtime bundle under data/runtime/occupancy_week/. These large files are published as GitHub Release assets instead of being committed.
Download:
Extract the first zip so its files sit directly under data/processed/. Extract the second zip under data/runtime/ so it creates data/runtime/occupancy_week/.
Verify the data:
python scripts/check_route_data.py
python scripts/check_runtime_data.pyImportant route artifacts include:
data/processed/shenzhen_drive_with_station_access.graphml
data/processed/station_road_access.csv
data/processed/landmark_distances.npz
data/processed/ch_index.pkl
data/processed/station_poi_features.csv
data/processed/shenzhen_boundary.geojson
Install Python dependencies first if needed:
python -m pip install -r backend/requirements.txtStart the full local demo:
.\start-occuevroute.batThe launcher:
- starts FastAPI on
http://127.0.0.1:9000 - waits for
/api/healthand/api/boundary - builds and serves the frontend with Vite preview on
http://127.0.0.1:9090 - opens
http://127.0.0.1:9090
Check that Python and npm are available without starting the app:
.\start-occuevroute.bat --checkBackend:
python -m uvicorn backend.main:app --host 127.0.0.1 --port 9000Frontend preview:
cd frontend
npm install
npm run deployOpen http://127.0.0.1:9090. Vite proxies /api requests to http://127.0.0.1:9000.
Backend health check:
Invoke-RestMethod http://127.0.0.1:9000/api/healthInstall development dependencies:
python -m pip install -r requirements-dev.txt
cd frontend
npm installBackend with reload:
python -m uvicorn backend.main:app --reload --host 127.0.0.1 --port 9000Frontend dev server:
cd frontend
npm run devOpen http://127.0.0.1:5173. The dev server also proxies /api to http://127.0.0.1:9000.
The frontend uses these backend endpoints:
GET /api/health
GET /api/boundary
GET /api/location-search
POST /api/recommendations
Recommendation responses include:
route_coordinates: true drivable route geometryroute_trace_coordinates: final parent/query path nodes for map explanationsearch_trace.candidate_route_events: timestamped candidate route snapshots shown during playbacksearch_trace.layers: search frontier nodes and trace edges
The map playback is designed for course explanation:
- regular search points show the latest visible frontier
- CH search points are emphasized, but CH shortcut trace edges are hidden
- candidate route points appear only after the search step that produced them
- final route nodes appear after search playback completes
- the thick blue route always uses true drivable road geometry
For CH, the query uses shortcut weights internally for speed. Shortcuts are not drawn as road geometry during search; the final route is reconstructed and expanded back to real road geometry.
Backend/search trace tests:
python -m pytest tests/test_search_traces.pyFrontend checks:
cd frontend
npm run lint
npm run buildInstall the full data-processing environment:
python -m pip install -r requirements.txtThen run:
python src/data_processing/build_shenzhen_boundary_geojson.py
python src/data_processing/download_road_network_tiles.py
python src/data_processing/build_station_graph.py
python src/data_processing/build_station_poi_features.py
python src/data_processing/build_landmark_distances.py
python src/route_planning/ch_preprocess.pyThe road download step includes regular drivable roads plus highway=service internal roads, filters out access=private/no edges, clips the graph to the Shenzhen boundary, and keeps the main Shenzhen road component.
The runtime occupancy bundle contains the February 6-12, 2023 simulation week plus compact station profile features. To rebuild it from the full UrbanEV source data, run:
python src/data_processing/extract_runtime_occupancy_week.pyThe current multi-horizon occupancy model is documented in docs/models/occupancy_horizon_model.md.