# Trip Itinerary Import — Instructions for Populating

This file explains how to create a valid CSV or Excel file for import into the trip planning app at chriswatson.page/trips.

All three item types — **stops**, **hotels**, and **day visits** — live in the same file and are distinguished by the **Type** column.

---

## Column reference

The file must have a header row. Column names are flexible (see aliases below).

| Column | Required | Notes |
|---|---|---|
| `Day` | Yes | Integer (1, 2, 3…). |
| `Place` | Yes | Real, geocodable name. Also accepted: `Overnight`, `Location`, `Name`, `Destination`. Geocoding is biased toward the trip's own destination, so an ambiguous name (e.g. "Diamond Beach") prefers a match near it. |
| `Type` | Yes for hotels/day visits | `stop` (or blank), `hotel`, or `day visit`. See below. |
| `Activities` | No | Free text. Stops only. |
| `Hike` | No | Free text. Stops and day visits (**not** restaurants — on a `restaurant` row it is folded into Notes instead). Prefer the shape `distance · time · difficulty — detail` (e.g. `7.2 km · 2–2.5 hrs · moderate — clifftop loop from Vík`) so hover cards stay scannable. |
| `Notes` | No | Free text. Works for all three types. |
| `Things to Check` | No | Free text. Stops and day visits. |
| `Lat` / `Lng` | No | If provided, skips geocoding for that row. |
| `Drive Time (mins)` | No | Integer. Stops only — overwritten automatically by routing engine. |
| `Duration (mins)` | No | Integer. Day visits only — **total** time at the place, including any hike/tour described in Hike. Estimate it for every day visit: a blank is treated as 0 minutes by the computed schedule, silently making the day look shorter than it is. |
| `Status` | No | Means different things per row type. **Hotels:** `chosen` (default) or `candidate` — a candidate is a shortlisted option for that night, shown dimmed on the map and never part of the route or night labels until it's starred as the pick in the app. **Day visits:** `optional` (a "visit if time allows" side trip — drawn as a hollow diamond, never routed through or timed), or `arrival` / `departure` — see below. Anything else is ignored. |
| `Price` | No | Hotels only. Free text (e.g. `€240/night`, `ISK 38,000 total`) — shown in the hotel's tooltip/popup and candidate chips for comparison. |
| `Time` | No | `HH:MM` (24-hour). For a `stop` row, sets that day's start time (default 9:00 AM if left blank). For a `day visit` row, sets a **fixed** arrival time — only for a booked tour or timed slot; leave it blank for anything flexible. When a booked tour has a published start/pickup time, do set it: fixed times anchor the day's computed schedule and enable the "day doesn't fit" warning. |

---

## Type values

| Type value | What it creates | Notes |
|---|---|---|
| blank or `stop` | **The day's anchor** — one row per day in the active itinerary | This is the day record, not a sight: the town you're based in, the day's overall plan in `Activities`, day-level advice in `Notes`, and the day's start time in `Time`. It appears in the **Days** panel and names the day everywhere else. **One per day** — a second `stop` row on the same day is shown but ignored by the computed schedule, which reads the first. Individual sights and meals belong in `day visit` / `restaurant` rows. (Legacy: in an itinerary with no `day visit` rows at all, `stop` rows still shape the driving route — see "What shapes the route" below.) |
| `hotel` | A trip-level Hotel + assignment to this itinerary on that day | Notes becomes the hotel's notes. Re-importing a row with the same name won't duplicate the hotel — it reuses it and just adds the assignment. A thumbnail image is looked up automatically from Wikipedia (best-effort — edit it afterward in the app if it's wrong or missing). ⚠ Hotels frequently aren't in OpenStreetMap under their brand/marketing name — if you have coordinates (Google Maps, a booking confirmation), fill Lat/Lng on hotel rows to skip geocoding entirely; otherwise use the property's exact official name. |
| `day visit` | A trip-level Day Visit (POI) visible on all itineraries | Notes, Hike, and Things to Check are all shown in the map popup. Duration and Time (as a fixed arrival) feed the Days panel's computed schedule. Re-importing a row with the same name + day won't duplicate it. Same Wikipedia thumbnail lookup as hotels. A day visit has no Activities field, so if that column is filled in on a `day visit` row, it's appended into Notes instead of being discarded. |
| `restaurant` | A trip-level Restaurant (also accepted: `food`, `cafe`, `dinner`, `lunch`) | Planned exactly like a `day visit` — same Day, visiting order, `Duration (mins)`, fixed `Time`, `Notes`, `Things to Check` — and it routes and is timed the same way, so a dinner stop counts toward the day. It just draws as an **amber circle** instead of a cyan diamond. There is **no Hike field**: a Hike cell on a restaurant row is appended to Notes rather than discarded. |
| `day visit` + `Status = arrival` / `departure` | The same, marked as where the trip flies in or out | Draws that place as a **plane** instead of a diamond, and the playback animation flies in before day 1 and out after the last day. Put the SAME airport on both rows (identical `Place`, and ideally identical `Lat`/`Lng`) — one POI assigned twice is the intended shape, and it avoids the near-duplicate that an accented-vs-plain spelling would otherwise create. Roles are presentational: they do **not** change the driving route. |
| `candidate` | Same as `hotel`, but the assignment is created with `Status = candidate` | Shorthand for a shortlisted hotel — equivalent to `Type = hotel` + `Status = candidate`. Use `Notes` for the pros/cons comparison text and `Price` for the nightly rate; both show up where candidates are compared in the app. |

### What shapes the driving route

Once an itinerary has **any `day visit` rows**, the real driving route (roads, drive times,
playback animation) is built from its **Hotels + Day Visits only**, in day/chronological order
— `stop` rows become landmarks: still shown on the map and in the table with all their fields,
but no longer part of the route and never get a drive time. This is the recommended way to plan
now: use `hotel` for where you sleep and `day visit` for everything you'll actually drive to
and see; reserve `stop` for a landmark you want tracked but don't want the route to detour
through.

Itineraries with **no `day visit` rows** keep the older behavior: `stop` rows (in row order,
same-day rows in driving order) are what shapes the route, exactly as described below.

---

## Blank template

```
Day,Place,Type,Activities,Hike,Notes,Things to Check,Duration (mins),Time,Status,Price
1,,,,,,,,,,
2,,,,,,,,,,
```

---

## Rules

1. **Day and Place are the only required fields.** Leave Type blank for regular stops.
2. **Place names must be geocodable.** The importer calls OpenStreetMap Nominatim. Use real town, landmark, or region names.
   - ✓ `Höfn` `Reykjavík` `Þórsmörk` `Vík` `Mývatn` `Skógafoss` `Geysir`
   - ✗ `Departure` `TBD` `—` `Home base` (these rows are skipped)
3. **Lat/Lng columns skip geocoding.** Exported files include coordinates, so re-importing an export is fast (no geocoding needed).
4. **Multiple nights in the same place**: for a `hotel`, repeat that hotel on consecutive rows with consecutive day numbers (one row per night). For a `stop`-only itinerary, do the same with `stop` rows.
   - **Prefer `hotel` + `day visit` over `stop`.** See "What shapes the driving route" above — once an itinerary has any `day visit` rows, that's what the route (and drive times, and the playback animation) is built from, in each day's visit order. `stop` rows in that itinerary are landmarks only.
   - **If you're doing a `stop`-only itinerary** (no day visits at all — the older style): same-day `stop` rows must be listed in driving order, since the route follows row order and out-of-order rows produce back-and-forth detours.
5. **Same-day `day visit` rows must be listed in visiting order.** Their row order within a day becomes the visit sequence — the driving route and the computed day schedule both follow it. (It can be reordered in the app afterward, but getting it right in the file saves that step.)
6. **Fields containing commas must be wrapped in double quotes.** Spreadsheet apps do this automatically.
7. **Save as UTF-8 CSV** (`.csv`) or `.xlsx`. For Excel, use "CSV UTF-8 (Comma delimited)" to preserve special characters.
8. **Geocoding is biased toward the trip's destination**, not just taken as Nominatim's first global hit — an ambiguous name (e.g. "Diamond Beach") prefers the match near your trip over a same-named place elsewhere in the world. If a row still resolves implausibly far away, the import summary flags it (e.g. "⚠ Diamond Beach → Florida, USA — 5,800 km from Iceland") so you can fix it with the app's "Fix location" button instead of it silently being wrong. A row that can't be located at all is skipped and flagged in the same summary.
9. **Don't invent extra columns.** The importer silently ignores any column it doesn't recognize, so information in a made-up column is lost. Extra detail (costs, booking references, best time of day) belongs inside `Notes` or `Things to Check`.

---

## Converting a spreadsheet you already have

If your trip already lives in your own Excel sheet — one row per day, notes in
whatever columns made sense at the time — you don't need to retype it. Hand this
file and your spreadsheet to an AI chat and have it do the conversion.

**Step 1.** Download this file (the **Instructions** button next to the import bar,
or `chriswatson.page/trips/import-instructions/`).

**Step 2.** Open an AI chat that accepts file attachments (Claude, ChatGPT, Gemini)
and attach **both**: this file *and* your own `.xlsx`/`.csv`.

**Step 3.** Paste the prompt below.

**Step 4.** Save the AI's output as a `.csv` file and import it. If the chat can't
give you a file to download, copy the CSV text into a blank spreadsheet
(Data → Text to Columns, comma-delimited) and save as **CSV UTF-8**.

---

> Attached are two files:
>
> 1. `import_instructions.md` — the import format for a trip planning app
> 2. my own trip spreadsheet
>
> Convert my spreadsheet into a CSV that matches the format in
> `import_instructions.md`. Read its column reference and Type table first, and
> follow them exactly.
>
> How to interpret my file:
> - **Work out the `Day` number yourself.** If my sheet has dates rather than day
>   numbers, day 1 is the earliest date, and every later date counts on from it
>   (including days I left blank). If it has neither, use row order.
> - **One of my rows may need to become several of yours.** A row like "Day 3 —
>   Skógafoss, Reynisfjara, overnight in Vík at Guesthouse Carina" becomes a `stop`
>   row for Vík, two `day visit` rows, and a `hotel` row. Split on that basis:
>   somewhere I slept = `hotel`, somewhere I stopped to see = `day visit`, the
>   town/base that anchors the day = `stop`.
> - **Keep same-day `day visit` rows in the order I'd actually visit them** — that
>   order becomes the driving route.
> - **Map my columns onto yours by meaning, not by name.** My "Accommodation" is a
>   hotel row; my "To book"/"Don't forget" is `Things to Check`; my "Walk"/"Trail"
>   is `Hike`. Anything that doesn't map to one of the format's columns goes into
>   `Notes` — do not invent new columns, and do not silently drop the text.
> - **If I already have coordinates**, latitude/longitude/GPS/"pin" columns, put
>   them in `Lat`/`Lng` — that skips geocoding and is always more reliable than a
>   name lookup, especially for hotels.
> - **Estimate `Duration (mins)` for every `day visit`** even if my sheet doesn't
>   have it — a rough number beats a blank, which counts as 0 in the app's day
>   schedule. Only set `Time` where I recorded a genuinely fixed time (a booked
>   tour, a ferry, a timed entry slot).
>
> Rules for your output:
> - **Do not invent places.** Only rows that exist in my file. If something is too
>   vague to geocode ("drive south", "free day", "TBD"), drop the row and list it
>   for me at the end instead of guessing a location.
> - **Do not lose my text.** Every note in my sheet should land in some column of
>   yours.
> - Wrap any field containing a comma in double quotes. Leave fields blank rather
>   than writing "—" or "N/A".
> - Output the CSV in a single code block, then — **after** it — a short list of:
>   any rows you dropped and why, any `Day` numbers you inferred, and any place
>   names you think may not geocode cleanly.

---

### Check the output before importing

The AI is reading a sheet only you fully understand, so skim its CSV first:

- Does every day of your trip appear, with no off-by-one in the `Day` numbers?
- Does each night have a `hotel` row (repeated per night for multi-night stays)?
- Are the `day visit` rows for each day in visiting order?
- Did anything you cared about get dropped? Check the AI's list at the end.

Nothing here is destructive — importing **adds to** the itinerary rather than
replacing it, and re-importing the same place won't duplicate it. A place that
can't be geocoded is flagged in the "Unresolved imports" strip, so it isn't lost.
The one thing that *is* silent is a row with a blank or non-numeric `Day`, or a
blank `Place` — those are skipped without a warning, which is why the day-number
check above is worth thirty seconds.

---

## Building a file from scratch with an AI (e.g. Claude)

If you have no spreadsheet at all — just notes, or nothing yet — paste this prompt
into your planning session and paste your itinerary notes after it:

---

> I have a trip itinerary. Please output it as a CSV using exactly these column headers:
>
> `Day,Place,Type,Activities,Hike,Notes,Things to Check,Duration (mins),Time`
>
> Rules:
> - `Day` = integer day number
> - `Place` = the real place name (must be a geocodable town, landmark, or hotel — no "Departure", "TBD", or vague labels)
> - `Type` = one of:
>   - `stop` (or blank) — the day's anchor: one per day, named after the overnight town or base. Put the day's overall plan in `Activities`, day-level advice ("keep it light, jet lag") in `Notes`, and the day's start time in `Time` as `HH:MM` 24-hour (leave blank for the 9:00 default)
>   - `hotel` — the hotel or accommodation for that night. If staying multiple nights, repeat the hotel on consecutive rows with consecutive day numbers. Hotels often aren't geocodable by brand name — if coordinates are available (Google Maps, booking site), fill `Lat`/`Lng` on hotel rows; otherwise use the property's exact official name
>   - `day visit` — a point of interest actually visited that day (waterfall, geyser, museum, booked tour). Day visits + hotels ARE the driving route, built in day order — so list each day's `day visit` rows in the order they'll be visited
> - For `day visit` rows, also fill in when known:
>   - `Hike` = only if reaching or doing it involves a hike, formatted `distance · time · difficulty — detail` (e.g. "7.2 km · 2–2.5 hrs · moderate — clifftop loop from Vík")
>   - `Things to Check` = bookings to make, age limits, seasonal closures — anything to verify before travel
>   - `Duration (mins)` = estimated **total** minutes at the place as a plain integer (e.g. `45`), including any hike/tour time from `Hike`. Estimate it for EVERY day visit — a rough number beats a blank, because a blank counts as 0 minutes in the computed day schedule
>   - `Time` = a fixed arrival time (`HH:MM`, 24-hour) ONLY for a booked tour or timed slot; leave blank for anything flexible. If a booked tour has a published start/pickup time, do set it — it anchors the day's schedule
> - Use only these nine columns — anything else is ignored by the importer; put extra detail (costs, booking references) in `Notes` or `Things to Check`
> - Wrap any field containing a comma in double quotes
> - Leave fields blank rather than writing "—" or "N/A"
> - Output only the CSV — no explanation, no markdown fences

---

## Import steps (once the file is ready)

1. Open your trip at chriswatson.page/trips/
2. Select the itinerary tab you want to import into (stops and hotel assignments go to this itinerary; day visits go to the whole trip)
3. Click **Choose file** in the import bar and select your CSV or Excel file
4. Wait while any un-geocoded place names are looked up — roughly one second per
   row (a 40-row file takes about a minute). Rows that already have Lat/Lng are instant
5. Stops, hotels, and day visits all appear on the map and in their panels automatically

---

## Export

Click **Export** (top right) → Excel or CSV. The exported file includes:
- All stops for the selected itinerary (Type = `stop`), including Drive Time (mins) and Time (day start)
- Hotels assigned to that itinerary (Type = `hotel`), including Status (`chosen`/`candidate`) and Price
- All day visits for the trip (Type = `day visit`), including Hike, Things to Check, Duration (mins), and Time (fixed arrival)

This file can be re-imported as-is — coordinates are included so no geocoding is needed. Image/video
URLs are not part of the export/import format — set those in the app after import.

---

## Example rows

```
Day,Place,Type,Activities,Hike,Notes,Things to Check,Duration (mins),Time
1,Reykjavík,stop,"Arrive airport, grocery run, Hallgrímskirkja",,Recovery day — keep it light,Confirm visa before travel,,10:00
1,Fosshotel Reykjavík,hotel,,,Near BSÍ bus terminal,,,
2,Reykjavík,stop,"Golden Circle: Þingvellir, Geysir, Gullfoss",,Bring swimwear for the hot-spring hike,,,08:30
2,Þingvellir National Park,day visit,,,Walk the rift valley between the tectonic plates,,60,
2,Geysir,day visit,,,Strokkur erupts every 5–10 min,,45,
2,Gullfoss,day visit,,,Bring a rain jacket — spray gets heavy,,45,
2,Reykjadalur,day visit,,6 km · 2.5 hrs · moderate — hot-spring river at the top,Bathe in the river — swimwear under hiking layers,,150,
2,Fosshotel Reykjavík,hotel,,,Second night,,,
3,Vík,stop,South coast waterfalls and black sand beaches,,,,,09:00
3,Skógafoss,day visit,,0.5 km · 20 min · easy — optional staircase to the clifftop,Right off the Ring Road — no walk needed,,40,
3,Sólheimasandur,day visit,,,DC-3 plane wreck by ATV tour,"Book ahead; 17+ with full driver's license required",120,13:00
3,Guesthouse Carina,hotel,,,Well-rated guesthouse in Vík,,,
```

Note the shape: one `stop` row anchors each day (town name, day summary, start time), the
day's `day visit` rows follow **in visiting order** (with a `Duration` estimate each, and a
fixed `Time` only on the booked ATV tour), and the night's `hotel` row closes the day —
repeated on both nights for a multi-night stay.
