Photo trip planner · runs in your browser
Plan a photo trip anywhere with your own AI
Tell PhotoRouter where you are going, for how long and how you shoot. It writes the prompt; your own AI picks the cities, the photo spots and the travel between them and returns one JSON answer. PhotoRouter checks that answer against your trip and plays the route on a 3D map. No account, no backend, nothing to install.
- Any destination
- 6 demo trips
- No account
- MIT licence
How it works
Four steps from brief to route
PhotoRouter has no built-in agent. It writes the prompt, your own AI plans the trip, and PhotoRouter checks the answer and shows it on the map.
- 01
Describe the trip
Enter where you are going (a country, a region or a list of cities), the first day and the number of days. Add your gear, the photography you like, the pace, how much walking you want, whether you work on weekdays, whether to avoid crowds, must-see places and places to skip by name, and a description in your own words.
- 02
Build the prompt
Pick a preset, a voice and weighted priorities for light, style, walking, crowds, variety and famous views. Add optional rules, the answer language and extra instructions. The prompt holds your brief and every trip date with the time slots and the number of stops that day allows, worked out from your pace and working hours.
Chat puts the JSON Schema inside the prompt, ready to paste into any assistant. API leaves it out so the schema can go into your provider's structured-output option.
- 03
Run it in your own AI
Copy the prompt into any AI assistant, or send it through an API. Your AI picks the cities with a base in each, the photo spots with coordinates, light, focal ranges, tripod needs, effort and crowd levels, the travel between cities by train, flight, ferry, bus or car, and the spot for each time slot of each day. Paste the JSON it returns back into PhotoRouter, which validates it. Errors block the import; warnings are shown with the plan.
- 04
Play the route
The plan opens on a 3D map with a timeline that scrubs day by day. The camera rides each travel leg, walks between stops and orbits each one on arrival. Day sheets list every stop's light window, the kit to pack and the local name to show a driver.
Validation
Every answer is checked before it loads
An AI can return a plan that reads well and still breaks the trip. PhotoRouter validates the pasted JSON against the schema and against the same rules the prompt describes. Errors block the import and name the day, slot or spot to fix. Warnings are shown, and the plan still loads.
Every date, day by day
The dates run with no gaps and one entry each, even a day with no slots. An answer for other dates than your brief loads as its own trip, with your brief's rules as warnings.
A consistent chain of cities
A day that changes city needs travel from the previous night's city. A day without travel stays put, or makes a day trip out and back.
Spots near their city
Every spot sits within 150 km of the city it is filed under, which catches wrong coordinates.
Light fits the slot
Dawn spots go in early slots, golden and blue hour spots at sunset, night spots after dark.
Slots and stops per day
Each day uses only the slots it allows and stays within its stop limit, both set by your pace and working hours.
Tripod
A spot that needs a tripod is rejected when the kit has neither a tripod nor a clamp.
Crowds and walking
The busiest spots are rejected when you avoid crowds, real hikes when you ask for easy walking.
Must-see and skip
Places on the skip list are never planned. Every must-see is planned or listed as left out with a reason.
Import report
Blockederror
2027-04-15: the night is in Porto but the day before was in Lisbon, with no "travel" between them.
error
spots[18] (Jardim do Morro) is 274 km from Lisbon; check its coordinates or its city.
error
2027-04-10 slot 1: São Pedro de Alcântara Viewpoint is shot at night, which a "Morning" slot doesn't have.
warning
Must-see "Belem Tower" is not in the plan.
Map and playback
Play the route on a 3D map
An imported plan becomes a route you can watch. Travel animations move the camera the way you will move on the trip, and each day opens a sheet with what to shoot, when, and with what.
- 3D map
- MapLibre GL with OpenFreeMap vector tiles, extruded 3D buildings and optional terrain, in Detailed or Clean style, light or dark.
- Timeline
- Scrub the trip day by day, or play it through from arrival to departure.
- Day sheets
- Each stop's light window from sun times in the destination's time zone, the kit to pack from your gear and the local name to show a driver.
- Spot cards
- Every spot opens a card with its light, a tip, the local name to copy and a link to the place on OpenStreetMap.
Day 2 of 10 · Sat 10 Apr
LisbonBelém: monastery, river and tower
- Morning · 07:09-11:00Daylight
Jerónimos MonasteryMosteiro dos Jerónimos
16-35 f/424-70 f/2.8No tripods here. Leave it at the hotel.
- Afternoon · 13:00-16:00Daylight
MAATMuseu de Arte, Arquitetura e Tecnologia
16-35 f/470-200 f/2.8 - Sunset · 19:32-20:34Golden / blue hour
Belém TowerTorre de Belém
16-35 f/424-70 f/2.8Tripod6-stop ND
Travel animations
Chase camera
Rides each travel leg between cities behind a marker that matches the mode: train, plane, boat or car.
Walker
Walks the route from one stop to the next within a city.
Arrive and orbit
Flies in to each stop and circles it so you can read the setting.
Demo trips
Six trips, one per continent
Each demo is a ready-made answer: a brief and the JSON plan returned for it. It goes through the same importer as a pasted answer, so the map, the day sheets and playback work without running a prompt.
The planner opens on the demo for your part of the world, picked from your browser's time zone with no network request. A time zone of America/Sao_Paulo opens Rio de Janeiro and Paraty; zones outside the six regions open Lisbon and Porto. A picker switches between them.
Spots are coloured by their best light and spread out around each city so every one stays visible.
- Dawn
- Daylight
- Golden / blue hour
- Night
Europe
Lisbon and Porto
10 days in April: tiled streets, river light, two cities by train.
10 days · 2 cities · 28 spotsTravel: flight, train
Open this tripNorth America
San Francisco to Los Angeles
11 days in October: fog, cliffs and city lights by car.
11 days · 3 cities · 31 spotsTravel: flight, car
Open this tripSouth America
Rio de Janeiro and Paraty
9 days in May: granite peaks, beaches and a colonial town.
9 days · 2 cities · 25 spotsTravel: flight, bus
Open this tripAfrica
Marrakesh, Fes and Chefchaouen
10 days in March: medinas, souks and the blue town.
10 days · 3 cities · 18 spotsTravel: flight, train, bus
Open this tripAsia
Tokyo and Kyoto
13 days in November: neon after work, temples and maples on weekends.
13 days · 2 cities · 33 spotsTravel: flight, train
Open this tripOceania
Sydney, Melbourne and the Great Ocean Road
12 days in March: harbour light, laneways and limestone stacks.
12 days · 3 cities · 33 spotsTravel: flight, car
Open this trip
Privacy
Runs in your browser
The planner is a set of static files. Once loaded, it does its work in the browser tab.
- No account
- Nothing to sign up for. Your last brief and plan are kept in this browser, so the planner reopens where you left off.
- No backend
- The brief, the prompt, the validator and the map all run in the browser.
- No built-in agent
- You choose the AI. The prompt and the answer leave the browser only when you copy them there.
- Map tiles only
- Map tiles are the only network requests the planner makes. The demo trips ship with the page, and the default one comes from the time zone setting, not a location lookup.
Your browser
- Brief
- Prompt
- Validator
- Map
- Day sheets
- Demo trips
Your own AI
You copy the prompt into a chat assistant or an API call.
You paste the JSON back.
For developers
A published schema for structured output
The plan format is a JSON Schema served at /plan.schema.json. It keeps to the subset that the structured-output modes of the major AI APIs accept, so the same file works as the response format for any of them.
The published file is generic. The planner also gives a copy pinned to your trip, where date is an enum of the trip dates: 10 of them, from 2027-04-09 to 2027-04-18 for the Lisbon and Porto demo.
With the API target, the prompt leaves the schema out and you pass it to your provider's structured-output option. With the Chat target, the schema travels inside the prompt.
- Closed objects
- Every object sets additionalProperties to false.
- Every key required
- Optional values are present and null, never missing.
- Nullable as anyOf
- A nullable field is anyOf its type and null.
- Enums, not limits
- Lights, focal ranges, tripod needs, travel modes, slot labels, effort and crowd levels are enums. There are no numeric or length limits.
PhotoRouter is open source under the MIT licence and maintained by AMPQ.Source on GitHub
GET /plan.schema.json
application/schema+json{
"type": "object",
"additionalProperties": false,
"required": [
"version", "title", "summary", "timezone",
"cities", "spots", "days", "skipped"
],
"properties": {
"version": {
"type": "string",
"const": "photorouter.plan/v2"
},
…,
"spots": {
"type": "array",
"items": { …
"light": { "enum": ["dawn", "day", "golden", "night"] }
}
},
"days": {
"type": "array",
"items": {
"required": [
"date", "cityId", "title", "travel", "dayTrip", "slots"
],
"properties": {
"date": { "type": "string" },
"travel": { "anyOf": [
{ … "mode": { "enum": [
"train", "ferry", "flight", "bus", "car"
] } },
{ "type": "null" }
] },
"slots": …
}
}
},
…
}
}Try it with a demo trip
Six ready-made trips, one per continent, load without running a prompt. Or describe your own trip and run the prompt in your AI.