School busses, shuttles, as well as carpooling are very popular nowadays. Those transportation methods help to organize convenient, environment-friendly, and cost-efficient ways to collect and transport a large numbers of people.
However, all the advantages can be lost when bus routes are not planned well and optimized.
Optimizing school bus routes enhances cost efficiency, safety, environmental sustainability, and the student commuting experience. It reduces fuel usage, vehicle wear, and emissions while ensuring shorter rides and better scalability for growing school populations.
Route optimization involves methods such as rearranging inefficient paths, combining schools for shared routes, considering bus capacities, addressing accessibility needs, and adhering to precise time windows for pick-ups and drop-offs.
In this article, we would like to show you how to solve the bus route optimization problem for busses and carpooling, how to add special requirements, and visualize results on a map.
Playground: optimize routes for shuttle services and carpooling
We emulate carpooling in the Bus Route Planner Playground below. The task simulated can be described the following way:
Five drivers provide carpooling services to university students. The students live in twenty different locations, one-two students in each location.
Drivers start their route from a parking place and finish in the university where they bring the students.
The cars have four people or seven people capacity. One pickup stop takes five minutes.
In short terms, the Route Optimization API get the following data as input:
- 5 drivers, that have 4 and 7 capacity cars and different starting locations
- 20 locations which drivers should visit and pick up students. One pickup stop takes 5 minutes
- Locations, car capacities, and number of students to pickup are chosen randomly
The solution shows optimized routes for drivers. Show/hide separate routes with an "eye" button. Get information about locations and waypoints by hovering them.
Some students might be not served because of car capacity. You can see them on the map as orange points.
Try to generate the task for different visible areas.
How to Utilize Route Planner API for Bus Route Optimization
Optimizing bus routes efficiently requires an understanding of how to map real-world scenarios to API terms. Below, we break down how to structure your bus route optimization task using the Route Planner API and outline the key parameters involved.
Task Description in Terms of the Route Planner API
To effectively leverage the Route Planner API for bus route optimization, it’s important to understand how specific components map to the API's parameters:
- Agents: Represent the drivers providing the carpooling or bus service. The vehicle’s capacity is managed through the agent’s pickup_capacity parameter.
- Jobs: Define the pickup locations. Each job includes a location and a pickup_amount that indicates the number of passengers to be picked up.
- Mode: Specifies the transportation mode for agents and can be set to "drive," "bus," "truck," "walk," or "bicycle."
Defining Specific Transport Requirements
To set particular requirements for transport, use the requirements parameter in the job object and the capability parameter in the agent object. These parameters can be any custom string value that helps match jobs with agents based on unique needs.
Recalculating Routes When New Passengers Join
To adjust routes when new passengers need to be accommodated, you can recalculate routes from scratch to generate a new optimized plan. Alternatively, you can maintain links between agents and jobs from previous calculations to keep the existing connections between buses and passengers intact.
Limiting Bus Travel Time
To set a limit on the travel time for buses, use the time_windows parameter. This parameter helps define the allowable time range for completing the route, ensuring that buses adhere to schedules and service constraints.
Solve the Bus Route Optimization task and visualize results
The Route Planner API works via HTTP POST. It's cross-platform and can be used with any programming language. Learn more about Route Planner API specification on the API documentation page >>
We've prepared JavaScript code samples for you to help you implement a custom solution.
Here is a JSFiddle containing the code samples.
Build a request object
- The task input JSON object contains agents and jobs lists, and mode;
- The agents have pickup_capacity parameter;
- The jobs have pickup_amount and duration parameters;
const busRouteOptimizationInput = {
"mode": "drive",
"agents": [
{
"start_location": [
7.4474023,
46.9467234
],
"end_location": [
7.438684130809055,
46.95097255
],
"pickup_capacity": 4
},
...
],
"jobs": [
{
"location": [
7.450493219453888,
46.9399672
],
"duration": 300,
"pickup_amount": 1
},
...
]
}
Call Route Planner API
Make an HTTP POST call with the "Content-Type=application/json" header:
fetch(`https://api.geoapify.com/v1/routeplanner?apiKey=${myAPIKey}`, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(busRouteOptimizationInput),
})
.then((res) => res.json())
.then((res) => console.log(res));
Analyze results
The Route Planner API result contains an extended by properties GeoJSON.FeatureCollection object where every feature represents an agent execution plan.
The feature properties contain information that describes the agent waypoints and way legs, route time and distance, as well as actions:
- action - single operations. The type parameter of the action contains the type of the action - start, job, or end.
{
"index": 1,
"type": "job",
"start_time": 116,
"duration": 300,
"job_index": 9,
"waypoint_index": 1
}
- waypoints - route stops, required to perform one or multiple actions:
{
"original_location": [
7.468804378881785,
46.9444164
],
"location": [
7.468804,
46.944416
],
"start_time": 116,
"duration": 300,
"actions": [
{
"index": 1,
"type": "job",
"start_time": 116,
"duration": 300,
"job_index": 9,
"waypoint_index": 1
}
],
"prev_leg_index": 0,
"next_leg_index": 1
}
- legs - routes between waypoints:
{
"time": 116,
"distance": 1069,
"from_waypoint_index": 0,
"to_waypoint_index": 1,
"steps": [
{
"from_index": 0,
"to_index": 1,
"time": 116,
"distance": 1069
}
]
}
Besides, the FeatureCollection object is extended by the properties. The properties contain the task input and may have issues. The issues indicate problems that appeared by solving the task - unassigned agents and unassigned jobs:
"issues": {
"unassigned_jobs": [
3
]
}
Visualize the results with MapLibre GL (an open-source fork of Mapbox GL)
Here is a JSFiddle that shows how to visualize the results with MapLibre GL map library:
What's next
- Learn more about Route Planner API >>
- Learn how to optimize delivery routes >>
- Learn more examples of solving route optimization tasks >>
- Try more optimization scenarios on the Playground page >>
- Check the Route Planner API specification >>