Inspiration
This project was aimed to solve a problem faced by the Singapore Smart Vending Start Up, iJooz.
iJooz operates over 1,000 orange juice vending machines across the country. Replenishing them is a growing logistical nightmare. Currently, riders are handed a list of machines and left to plan routes manually, leading to wasted time, fuel, and manpower.
RouteJooz was built to solve this — generating optimal, real-world delivery routes in seconds, built on the back of the Google Maps Platform.
What it does
RouteJooz takes a CSV of vending machine postal codes and the number of available drivers, then instantly generates optimized delivery routes that reduce both total driving time and number of drivers used.
- Displays a visual, interactive map of all routes
- Filterable by driver, with hover/click popups for stop details
- Powered by Google Maps APIs for geocoding and real-world distance data
- Scalable across regions; modular and not tied to Singapore-specific logic
How I built it
Backend (FastAPI + Google Maps API + Google OR-Tools) :
- Convert raw postal codes into geo-coordinates using the Google Maps Geocoding API.
- Build a Haversine Matrix mathematically to precompute an initial distance matrix between all locations
- Update the entry nearest k neighbours for each node with the actual real time data given by Google Maps Distance API. (Note: this works on the assumption that we would only need accurate data for nearby nodes since the next hop would probably be there, and hence reduces our time complexity for api calls from O(n^2) to O(kn))
- Solve a Multi Vehicle Routing Problem (VRP) using Google OR-Tools, with constraints such as max drivers and max single driver travel time and return the list of optimal routes as well as relevant data
Frontend (Next.js + TailwindCSS):
- Users upload a CSV of postal codes, and select number of drivers.
- The CSV file and parameters are POSTed to the backend API which utilises Google Maps API
- The backend returns optimised routes — each as a sequence of postal codes per driver.
- The /route/results page renders these as multi-color Leaflet polylines and coordinate-marked pins.
Challenges and what I learned
- Balancing cost, accuracy, and speed
Calling the Distance Matrix API for every location pair (O(n²)) was too slow and costly, while pure Haversine was too inaccurate. I solved this with a hybrid: use real-time distances only for each node’s k-nearest neighbours, striking a solid balance between accuracy, speed, and cost.
- Making the output believable
Even optimal routes felt unintuitive as plain lists. I built an interactive map with filters, color-coded paths, and time breakdowns to make the results clear and trustworthy. This was a reminder that great algorithms still need great UX.
In summary, this project made me think like a product developer, not just a coder. It wasn’t enough to get something “technically correct”. I had to consider how it would scale, how much it would cost to run, and whether a non-technical user would even trust or understand the results. It pushed me to think holistically about the user experience and the real-world impact of engineering tradeoffs.
Accomplishments that I am proud of
Built and deployed the full-stack prototype in under 2 weeks. From backend algorithms to frontend integration while juggling a full-time internship. I’m proud to have created something with real-world value and impact.
What's next for RouteJooz
Migration to Google Maps JavaScript SDK for frontend We initially used Leaflet for its lightweight, cost-efficient setup as the project began primarily as a backend route generator with a minimal frontend. As we evolve RouteJooz into a driver-facing tool, we plan to transition to the Google Maps SDK for richer interactivity, smoother UX, and real-time route guidance
Real-Time Updates Add real-time traffic adaptation using the Google Maps API, enabling dynamic re-optimization during delivery. This ensures real time data not just at the point of algorithm generation but also mid drive
Additional Constraints Implement priority as a constraint in the solution. Currently we assume that all vending machines are equally in need of being replenished and that vehicle capacity is not an issue. However, we can have a more robust solution by including vehicle capacity / vending stock priority as additional constraints.
Technical Depth Heavy Explanation
For more technical explanations of how the project was implemented. Check out the git repos used to created them Frontend Backend
Acknowledgements
This problem statement was raised to me by my friend, Lee Sutton, who aided me in clarifying the problem requirements and obtaining a sample dataset for this project from iJooz
Built With
- fastapi
- google-maps
- google-or-tools
- next.js
- numpy
- python
- supabase
- tailwindcss
Log in or sign up for Devpost to join the conversation.