Inspiration
After dinner at a café, I like to stay out and walk the streets for a while once the crowds have gone. Coming back at 1 am, though, can feel a little scary at times. Every map app answers one question: what's the fastest way back? At that hour, that's not really what I'm asking. I want to know which way still has shops open, whether there's a police station on the way, and whether the streets will actually be lit. No map tells you that. So we built one that does, and that admits it when it doesn't have the data.
What it does
You enter where you're starting, where you're going, how you're travelling and when you're leaving. Safe Route Analyzer pulls up to five routes and checks what's along each one at the time you'd actually pass it:
- police stations within 100 m of the route
- shops, pharmacies and hospitals that will be open when you get there, based on their opening hours and when you'd reach that point
- mapped street lamps per km, from OpenStreetMap
- residential stretches and live traffic incidents
Each route gets a Night Activity Score out of 100, along with a "% of signals known" figure. A lot of places have no opening hours listed, and we didn't want to hide that. You can also type what matters to you in plain English, something like "police and well-lit streets matter, happy to pass a lake", and the routes get re-ranked. If you name a landmark, it builds a detour past it.
There's no crime data in it, and it never tells you a route is safe. It shows you what's there and you decide.
How we built it
The backend is FastAPI (Python) and the frontend is TypeScript with MapLibre, packaged in Docker and running on Render.
TomTom does most of the map work: geocoding, routing with live traffic and a departure time, searching for places along each route (with opening hours), and traffic incidents. Street lamps come from an OpenStreetMap snapshot of 5,942 lamps in Bengaluru.
Two NVIDIA Nemotron models run on Nebius Token Factory, and we picked a different size for each job.
Nemotron-3-Nano-30B-A3B reads your preference text and turns it into JSON: a 0.5–1.5× multiplier for each of nine ranking factors, plus up to three landmarks you want to pass. It's a small, quick extraction task, so the small model fits. It runs at the same time as routing, so you never wait for it, and the server checks and clamps everything it sends back.
Nemotron-3-Super-120B-A12B writes the short comparison you see on each route card. It only gets the numbers our backend calculated, and its prompt tells it not to invent anything or call a route safe. We filter its output for that too. This is the one place where the quality of the writing really matters, so it gets the bigger model.
Challenges we ran into
The biggest one was Nemotron returning nothing. Nemotron 3 reasons by default, and in JSON mode Nano would think for 37 seconds, use up its whole token budget and come back with content: null. The request still returned 200, so for a while it just looked like the AI feature did nothing. We only worked it out by printing the raw API response. We tried three ways to turn reasoning off. Only chat_template_kwargs: {"enable_thinking": false} worked, and it brought the call down to 2.7 seconds.
TomTom started rate-limiting us once we searched along several routes at once, so we added a throttle of about four requests a second, with retries. Searches that time out aren't retried any more, since that only made things slower.
The public Overpass API kept timing out on street lamp queries, so we bundled an OpenStreetMap snapshot instead.
The scoring took several rounds. Early on, one strong signal could push a route to 100/100. Min-max scaling turned a gap of 1.6 vs 1.3 lamps per km into 100 vs 0. A route one minute slower could drop from first to last. We ended up counting unknown data as neutral, scoring lighting against the best-lit route, and not penalising routes within 10% of the fastest time.
And on the last day we found that on phones, the results panel covered the search button. That's fixed now.
Accomplishments that we're proud of
It's a full, deployed app: map, ranked route cards, explanations and live GPS navigation along the route you pick. Every model output gets checked, and the app keeps working if the models are down. We're also glad it's upfront about missing data. Unknown signals count as neutral, and every card shows how much of its score comes from real data.
What we learned
Small models are great for structured extraction when speed matters, and it pays to match the model to the task instead of using the biggest one everywhere. When an API fails silently, read the raw response first. And real-world map data has a lot of gaps, so it's better to show them than to cover them up.
What's next for Safe Route Analyzer
- Street lamp data for more Indian cities, and a night-time traffic signal
- More sources for opening hours
- Letting people report lit and unlit streets
- Hosting on Nebius Serverless Endpoints
Built With
- docker
- fastapi
- httpx
- maplibre
- nebius
- nvidia-nemotron
- openstreetmap
- pydantic
- python
- render
- tomtom
- typescript
- vite
Log in or sign up for Devpost to join the conversation.