Skip to content

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
Six demo trips at their real positions, each drawn at three times its size around its centre. Dotted lines are flights between cities.

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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

Blocked
  • error

    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.

Importer messages for edited copies of the Lisbon and Porto demo: a travel leg removed, a spot filed under the wrong city, an evening spot put in a morning slot and a must-see left out.

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

Lisbon

Belém: monastery, river and tower

  1. Morning · 07:09-11:00Daylight

    Jerónimos MonasteryMosteiro dos Jerónimos

    16-35 f/424-70 f/2.8

    No tripods here. Leave it at the hotel.

  2. Afternoon · 13:00-16:00Daylight

    MAATMuseu de Arte, Arquitetura e Tecnologia

    16-35 f/470-200 f/2.8
  3. Sunset · 19:32-20:34Golden / blue hour

    Belém TowerTorre de Belém

    16-35 f/424-70 f/2.8Tripod6-stop ND
Day 2 of the Lisbon and Porto demo, simplified. Light windows come from sun times for Lisbon on 10 Apr 2027, in Europe/Lisbon time.

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

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.

What crosses the browser boundary: the prompt and the answer, by your hand, and map tiles.

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": …
        }
      }
    },
    …
  }
}
An excerpt of the published schema, descriptions left out.

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.

Open the planner