Inspiration

When you move to a new city, you have to decide where to look at flats before you know the place. The same is true when you're staying somewhere for a month. The neighborhood decides what your days feel like, and once you sign a rental it is hard to change.

Rental sites show flats and prices. Guides list the same famous districts for everyone. A chat assistant gives a confident answer that you can't check: it names a district, describes its vibe, and that's it.

What I wanted to know was simpler: in this new city, where are the cafés, bars, shops and venues that the things I love point to, and which part of town would feel like the neighborhood I'm leaving? Qloo connects tastes across music, film, books, brands and places to real venues on a map, so it can answer that with places you can actually walk into. I built Homing to give that answer as a short list you can check.

What it does

Homing helps you choose where to start looking for a home in a new city.

You bring the things you love, like Radiohead, Fleabag, Wes Anderson and Patagonia, or the neighborhood you loved living in, like Alfama or Kreuzberg. You can type your loves or drop a screenshot of a playlist, watchlist or bookshelf; a genre like "jazz" works too. You pick the city you're moving to and can give each love more or less weight.

Homing gives you three areas to start with, each with:

  • its rank among the areas it checked in that city, for example #1 of 24 areas checked;
  • the love Qloo ties most to the area's places, and what sets those places apart;
  • two or three real places to visit;
  • one thing to check, like a place with no listed hours.

Around that shortlist:

  • A live taste terrain. The city turns into a 3D map of hex columns. Higher columns show where the taste signal is stronger within that city. Hover a column to see how your loves contribute and how popular the cell is. Change a love or its weight and the terrain moves in place. Open an area and it settles into a low carpet so you can see the places and streets.
  • Why this area shows what the pick rests on: a love linked to a real place by Qloo's own explanation, and the ranking redone without each love. In my run, Graça is #1 for my taste. Without Wes Anderson or without Patagonia it falls to #2, and without Radiohead it stays #1.
  • Feels like home starts from your old neighborhood. It reads the places that define it in Qloo and compares their style with every area of the new city. It shows Style overlap NN/100 for each area and a place-to-place link where Qloo connects a place there to a place here. Starting from Alfama, it puts Alfama first at 100/100. Starting from Kreuzberg, the closest Lisbon area is Santo Amaro at 25/100, and Homing calls that a weak match.
  • A crowd dial and must-haves. Slide from Popular to Local to give less weight to the city's most popular cells. Use Qloo's tags to ask for cozy places, live music, free wifi or outdoor seating, and set a budget for the places and plans. The dial uses popularity as its signal; it does not count tourists or residents.
  • Check an address takes the address of a flat you found, says how precisely it matched (street or building), which area it falls in, and what is within a short walk.
  • Places you can keep. Open an area for coffee, food, drinks and culture that fit your taste. Open a place for its listed hours, address and website, save it to a shortlist or put it in a plan. Missing hours and prices stay visible as unknown.
  • Try the neighborhood plans a short walk of three or four places in the area, at the time of day you pick, with rules like No bars or \$\$ or less, known prices only. You can swap one stop and keep the rest. In my run, No bars in Graça gave a café at 14:00 and lunch at 14:55; no culture stop fit the rules, and the walk shows that gap.
  • Plan my first days builds a longer route over 1 to 3 days, around listed opening hours and walking distance, at your pace and from the hour you get up. You can plan around your shortlist, swap a stop and export the result to your calendar. The short walk helps you inspect one area; the longer plan helps you spend your first days in the city.
  • Compare cities. Bring the same taste to up to five cities and see where you would start in each. It helps when the decision is still "Lisbon, Mexico City or Berlin". Each area's rank stays tied to the areas checked in its own city.
  • Two people, two inks. Add what your partner loves and the map prints in red and teal, with a dark overprint where both tastes are strong. Areas are ranked by the lower of the two people's scores, so a strong result for one person cannot hide a weak result for the other.
  • The assistant takes requests like "Less touristy", "I work from cafés" or "Add my partner: Succession and Peggy Gou", and changes the real state of the map. It also handles requests with several parts, like "Check Rua da Rosa 120, then plan a relaxed afternoon nearby, no museums, no bars, within \$\$". It shows each goal and tool call, checks each result, changes approach when a check fails, and leaves anything it could not do on screen with the reason. Rules stay in session memory through later turns.
  • Share. The taste and map setup lives in the URL, so someone else can open the same city, loves and weights without an account. The same engine recomputes the result.

It works on a phone with the same path: the map on top, the shortlist and the tools in a sheet below. You can explore cities beyond Lisbon and Berlin, including Tokyo, Reykjavík, Almaty and Buenos Aires, wherever Qloo has coverage, and enter city names in different languages.

How I built it

Homing is a Next.js 16 app on Vercel. A deterministic engine on top of Qloo produces the rankings and place recommendations; an assistant on Gemini 3.8 Flash (through OpenRouter) drives that engine with tools.

Resolving what you love. Qloo's /search resolves each name to an entity, using exact name and popularity and preferring the cultural thing over a café with the same name. Each chip lets you switch to the right match. Genre words go through /v2/tags for music genres, then artist insights by that tag, so "techno" is carried by its leading artists rather than treated as an artist's name.

Fixed areas first. For each city I ask Qloo for places with no taste signal (coffee, food, nightlife, culture) within 7.5 km of the centre, and put circles of about 650 m around their medians. Lisbon gets 24 areas, Berlin 19. These are the same for every person, so a rank means the same thing for everyone, and your taste can never invent or move an area.

One heatmap per love, read around each area. For each love I ask Qloo's /v2/insights for a urn:heatmap around the city centre using filter.location=POINT(...), and fold it into roughly 1 km cells. Each cell's affinity is set against its popularity with a small prior and ranked among that love's cells in the city. Every cell belongs to the nearest area centre within 1.6 km, and an area's score is the weighted mean over its cells, shrunk toward the middle when few cells have data. So the rank reads about 1.6 km around an area, while its places and walks are checked inside the 650 m circle. It is a heuristic with limited coverage: only cells where Qloo returned data count, thin areas are marked Limited data, and I show the result only as a rank, never as a percentage.

Places that pass a gate before taste. Inside each circle I ask Qloo for places signalled by your loves, with category tags and feature.explainability. Each place first passes an eligibility check by its primary role: a dance venue must be classified as a night club, a café must be a café, adult venues, hotels and shops are rejected, and your hard rules apply. Only then does Qloo's explanation decide which love the place is linked to. Tag insights for ambience and decor supply descriptions like calm, intimate and vintage; generic categories such as "Restaurant" do not become the area's personality.

Why this area ranks all the city's fixed areas again without each love, reusing the per-love heatmaps. A change within the tie band is reported as stable. The place explanation shows a specific connection in Qloo, while the recalculation shows whether that love changes the area's position.

Feels like home asks Qloo for the places within 650 m of the old neighborhood, keeps their distinctive ambience and decor tags, weighs them on one fixed Berlin/Lisbon/Reykjavík reference, and compares that signature with every area. I tried adding inferred music to the signature; it failed my Alfama holdout test, so the shipped version is style only.

Two people keep separate taste fields. The shared ranking uses the lower score for each area:

$$ s_{\text{shared}}(a) = \min\left(s_{\text{you}}(a),\,s_{\text{them}}(a)\right) $$

Areas are ranked by this value, with the highest first. The red and teal layers stay visible on the map so you can see where each person's taste is strong and where they overlap.

The plan solver builds a chain of stops from the start hour, with lunch never before 12:30, dinner never before 19:00, and more or fewer daytime stops by pace. It scores eligible candidates by affinity minus a walking penalty, uses listed hours to skip places that are closed, and applies the budget and other hard rules. It reserves requested places that pass those checks first and never repeats a place. If no stop fits a part of the walk, that gap stays visible. A swap changes one stop and keeps the others.

The assistant turns a request into typed goals and rules, calls tools that use the same engine, audits each result (address precision, every rule of a walk, the strength of a home match) and re-plans within fixed limits: a 40 second deadline, 8 tool decisions, 2 recovery decisions. Its tools resolve entities and place tags, change the state and read the engine's results; recommended places come from Qloo. Rules like No bars live in session memory and survive every later turn. Everything streams to the UI as goals, steps, observations and re-plans.

The map is MapLibre on a quiet paper style. It interpolates the Qloo field onto a 130 m hex grid with inverse distance weighting and renders extruded columns. That is the drawing grid; it does not add detail to the underlying data. Columns rise from the strongest cell outward, morph when a weight changes and settle when you open an area. Numbered areas, the selected area's walking circle and the route of a walk are drawn on the same map.

Keeping Qloo requests under control. Per-love heatmaps multiply requests, especially when comparing cities or adding a second person. The client limits concurrency, deduplicates requests already in flight, caches by city and entity, and backs off on 429 responses. Counterfactual rankings reuse those heatmaps rather than fetching them again.

Challenges I ran into

  • My first ranking didn't hold up. The earlier version found areas from the places Qloo returned for each person, so the geography itself changed with taste, and a mixed internal score was shown as "Match 46". I rebuilt it on fixed areas and show only a rank among them.
  • A method that failed its own test. I set a diversity test before building the new ranking: different people should not all get the same leader. A ranking on Qloo's native signals put Mitte first for all six Berlin reference profiles, so I didn't ship it. The version I shipped gives five different leaders in each city across six profiles.
  • A city that looked like one plateau. Qloo's affinity is rank-like over a whole metro area, so the first heatmaps made the whole of central Lisbon look equally good. Different loves also came back with very different coverage: a film could have 25 cells while a person had 800. Ranking each love's cells inside the city and handling thin areas explicitly made those differences usable without pretending every area had the same evidence.
  • Explanations that meant too little. My first drivers said almost every neighborhood was "pulled up by Radiohead". I now show a love connected to a specific place by Qloo and rerun the ranking without each love. That lets the explanation say both what the connection is and whether it changes the choice.
  • Feels like home sorted by the wrong thing. The earlier version showed one similarity number but ordered by another. Now the order follows the number on screen, and Alfama has to find Alfama first, also when 20% of its places are held out.
  • Names and genres collide. "Holiday" can be a film, a song or a café. "Jazz" resolved to a bar called Jazz, and "techno" to a streamer called Technoblade. Cultural entity preferences, editable matches, and music genre tags carried by artists fixed these cases without a hand-made list.
  • Different cities returned different grids. Asked by city name, Qloo gave me cells of about 1.2 km in Lisbon, 150 m in Paris and 5 km across Tokyo's prefecture. Asking around the city's centre and folding the response into one cell size made the engine usable beyond the first cities I built it for.
  • The wrong kind of place. Taste alone happily suggested a strip club for techno and a supermarket for coffee. The eligibility gate now runs before taste and again in the final audit. I also separated ambience and decor from generic place categories so a description says something more useful than "Restaurant".
  • An assistant that dropped half the request. In long requests the model sometimes planned one goal and silently forgot the other. Now every goal it announced has to end with a result or a reason, and a guard adds goals the planner left out.
  • Latency and quota. A cold assistant turn can take 10–20 seconds because the first look at a city fetches fresh Qloo data and the model plans. Warm turns finished in about 1.4–3.6 seconds in my runs. Caching and request limits keep repeated work down; the UI shows steps as they happen and says when a first look takes longer.

Accomplishments that I'm proud of

  • Taste really moves the ranking, and I checked it. On twelve reference profiles in Berlin and Lisbon, each city got five different leaders across six profiles, and cutting the first love's weight by 10% kept at least two of the top three in every case, so the order follows the person without jumping at small changes.
  • The first screen is the live product. Change a chip or its weight and the terrain over the city re-forms. You can go from that map to an area, a real place, an address check and a walk.
  • A real counterfactual for every love. "Without Wes Anderson, this area moves from #1 to #2" comes from ranking all areas again without that love. When nothing moves outside the tie band, the screen says the choice is stable.
  • Feels like home finds Alfama from Alfama. Starting from Alfama, Lisbon, Alfama comes first at 100/100, and it stays first in all five tests with 20% of its places held out. From Kreuzberg, Homing says the closest Lisbon area is a weak match and offers to mix in what you love.
  • Two people can see both tastes. The map keeps the two fields visible, and the shared ranking uses the lower score for each area. An area cannot rank well just because it fits one person.
  • Strict venues. Dance venues have to be night clubs by their primary role, with no adult clubs and no hotel bars, and a café is never a supermarket. No bars also excludes places with an onsite bar.
  • An assistant that keeps track of its goals. It shows each goal, notices a weak result, re-plans within limits and ends every goal with a result or a reason. In my last test runs of five dialogues with follow-ups (30 turns), every goal ended with a final status: done, partly done, or an error with a reason. Several results were partial, and no walk broke a hard rule. It is a small test set, so I don't treat it as proof of reliability.
  • Rules that survive every re-plan. No bars or a budget stays through swaps, a new start time, a re-plan and later questions to the assistant. A swap keeps every other stop.
  • A setup you can share. Someone else can open the same taste and city from a link, explore the map and check the places without making an account.
  • Honest numbers. A rank among the areas checked, a style overlap out of 100, unknown hours and prices shown as unknown, and an address matched at street level labelled as street level. No "% alike", no percentages of people.

What I learned

Cultural taste can give you a way into a city through real places. A quiet reader and a night owl can start in different parts of the same city, and Qloo gives me connections I can show them and test.

Fixing what the numbers mean mattered more than any new feature. Once the areas were fixed, I could test the ranking against reference profiles, and the tests told me which method to keep. I also learned that an assistant becomes trustworthy when it has useful tools, a state it can change, and a requirement to report on every goal it accepted, including the ones it couldn't finish.

What's next for Homing

  • Rental and stay listings inside the suggested areas, each checked like an address.
  • Building-level geocoding, so a typed address is checked at the house.
  • Opening hours and event schedules from more sources, so a walk can be planned around what is open.
  • Saved trips with notes, and a group mode for friends beyond two people.
  • More detail inside each area, using more of Qloo's place signals.
  • A review by people who live in Lisbon and Berlin, to see whether they would start where Homing starts.

Built With

  • ai-agents
  • gemini
  • geospatial
  • maplibre
  • motion
  • nextjs
  • node.js
  • openfreemap
  • openrouter
  • qloo
  • qloo-taste-ai
  • react
  • server-sent-events
  • tailwindcss
  • typescript
  • vercel
  • vitest
  • zod
Share this project:

Updates

Submission history