A Django REST API that calculates a driving route between two locations within the USA and recommends cost-aware fuel stops along the route using a provided fuel price CSV.
This project was built as part of a backend coding assessment.
- Accepts start and finish locations within the USA
- Geocodes input locations using Nominatim / OpenStreetMap
- Calculates driving route using OSRM
- Returns route distance, duration, map preview URL, and GeoJSON route geometry
- Uses the provided fuel price CSV to select cost-effective fuel stops
- Supports routes longer than 500 miles with multiple fuel segments
- Calculates estimated fuel cost assuming the vehicle achieves 10 miles per gallon
- Uses a maximum vehicle range of 500 miles
- Keeps external map/routing API calls low:
- geocode start location
- geocode finish location
- calculate route
- Python
- Django 5.2 LTS
- Django REST Framework
- Nominatim / OpenStreetMap
- OSRM Routing API
- python-dotenv
- requests
- Python built-in csv module
POST /api/fuel-route/
{
"start": "New York, NY",
"finish": "Chicago, IL"
}{
"message": "Fuel route calculated successfully.",
"start": {
"input": "New York, NY",
"label": "New York, United States",
"latitude": 40.7127281,
"longitude": -74.0060152,
"coordinates": [-74.0060152, 40.7127281]
},
"finish": {
"input": "Chicago, IL",
"label": "Chicago, Cook County, Illinois, United States",
"latitude": 41.8755616,
"longitude": -87.6244212,
"coordinates": [-87.6244212, 41.8755616]
},
"vehicle": {
"max_range_miles": 500,
"miles_per_gallon": 10
},
"route": {
"distance_miles": 794.73,
"duration_hours": 14.85,
"provider": "OSRM",
"map_preview_url": "https://www.openstreetmap.org/directions?...",
"geojson": {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": []
},
"properties": {
"distance_miles": 794.73,
"duration_hours": 14.85
}
}
},
"fuel_plan": {
"fuel_stops": [
{
"stop_number": 1,
"stop_type": "start_or_initial_fill",
"approx_route_mile": 0,
"candidate_states": ["NY", "PA"],
"station": {
"name": "Example Truck Stop",
"address": "Example Address",
"city": "Example City",
"state": "PA",
"retail_price": 2.899
},
"leg_distance_miles": 500,
"gallons_needed": 50,
"estimated_cost": 144.95
}
],
"total_fuel_cost": 230.39,
"assumptions": {
"vehicle_range_miles": 500,
"miles_per_gallon": 10,
"routing_api_calls_per_request": 3
}
}
}The vehicle is assumed to have:
- Maximum range: 500 miles
- Fuel efficiency: 10 miles per gallon
The provided CSV contains fuel station names, addresses, cities, states, and retail fuel prices. It does not include latitude and longitude coordinates for the stations.
To keep the API fast and avoid geocoding thousands of fuel stations during each request, the optimizer uses a practical route-state approximation:
- The API calculates the driving route and total route distance.
- The route is divided into fuel segments of up to 500 miles.
- For each fuel segment, the system samples nearby route points.
- It estimates candidate states near that route segment using built-in state centroid coordinates.
- It selects the cheapest available fuel station from those candidate states.
- It calculates gallons needed and estimated fuel cost for each segment.
This is a practical cost-aware solution rather than a perfect mathematical optimizer.
For each request, the application makes only three external map/routing calls:
- Geocode start location
- Geocode finish location
- Calculate driving route
Fuel station selection is handled locally from the CSV.
The API returns route geometry as GeoJSON. This can be rendered on a map using frontend map libraries such as Leaflet, Mapbox, or OpenLayers.
A human-friendly OpenStreetMap preview URL is also included in the response so the route can be opened directly in a browser.
fuel-route-optimizer/
│
├── config/
│ ├── settings.py
│ ├── urls.py
│ └── ...
│
├── routes/
│ ├── serializers.py
│ ├── urls.py
│ ├── views.py
│ └── services/
│ ├── __init__.py
│ ├── routing_service.py
│ ├── fuel_service.py
│ ├── fuel_optimizer.py
│ └── distance_utils.py
│
├── data/
│ └── fuel_prices.csv
│
├── manage.py
├── requirements.txt
├── .env.example
├── .gitignore
└── README.md
git clone https://github.com/your-username/fuel-route-optimizer.git
cd fuel-route-optimizerpython -m venv .venvFor Windows PowerShell:
.\.venv\Scripts\Activate.ps1pip install -r requirements.txtPlace the provided fuel price file at:
data/fuel_prices.csv
The expected CSV columns are:
OPIS Truckstop ID
Truckstop Name
Address
City
State
Rack ID
Retail Price
Create a .env file using .env.example as a template:
FUEL_CSV_PATH=data/fuel_prices.csv
VEHICLE_RANGE_MILES=500
MILES_PER_GALLON=10python manage.py runserverThe API will be available at:
http://127.0.0.1:8000/api/fuel-route/
Use the following request:
POST http://127.0.0.1:8000/api/fuel-route/
Set the request body to raw JSON:
{
"start": "New York, NY",
"finish": "Chicago, IL"
}You can also test longer routes, for example:
{
"start": "Los Angeles, CA",
"finish": "Dallas, TX"
}or:
{
"start": "Miami, FL",
"finish": "Atlanta, GA"
}- The public Nominatim and OSRM services are suitable for this assessment and demo, but not for high-volume production traffic.
- The provided fuel price CSV does not include station coordinates.
- Because station latitude and longitude are not available, this implementation selects fuel stations using a route-state approximation rather than exact station distance from the route.
- A production version would preprocess the fuel station file, geocode station addresses once, store coordinates in a database, and then perform exact distance-to-route filtering.
- The route geometry is returned as GeoJSON so a frontend client can render it on a map.