Sailing Trips
Nineteen Pins Are Not a Route
Somewhere between the first glass of wine and the decision to charter a boat, a Croatian sailing holiday exists only as a pile of saved places in Google Maps. Nineteen of them, in my case: beaches, a couple of konobas, a marina, one anchorage, and a pin optimistically labelled “Best viewpoint” with no further explanation.
A pile of pins is not a route. A route needs an order, daily distances a crew can actually sail, and — the part nobody thinks about until the sun is going down — somewhere at the end of each day where you can safely spend the night, that isn’t already full and isn’t exposed to whatever the wind is doing that week.
So I built a planner for it: a repo that takes the favourites in one end and produces a complete, shareable Törnplan out the other.
What the Planner Actually Does
1. It locates the pins
The first obstacle is delightfully stupid. The Google Takeout export of your saved places contains a URL column, and that URL contains a Google feature ID — 0x1334a…:0x6f4a2… — and no coordinates whatsoever. You export your favourite bays from a mapping service and receive a list of opaque hex strings.
So step one is locating all nineteen again by name, into places.md. Each one gets an island, a bay, coordinates, and two things that matter far more than the coordinates:
- Mooring type — marina, buoy field, konoba jetty, anchorage-only, or day-stop-only.
- Wind shelter, written in terms of the three winds that actually decide your evening: Bora from the NE, Jugo from the SE, Maestral from the NW.
Vague pins get a confidence rating instead of false precision. “Best viewpoint” was resolved to Metlina, the highest point on Kornat, marked medium confidence, with two alternative guesses written down underneath.
2. It clusters them into days
Only once every pin has a mooring rating can the route happen, because the mooring ratings are what constrain it. The house style is refreshingly unambitious and completely non-negotiable:
Leave in the morning → one or two swim bays → overnight on a konoba buoy, a buoy field, or in a marina. Anchoring overnight only in emergencies. Roughly 20–30 nm a day.
That middle clause does the heavy lifting. Ruling out overnight anchoring eliminates perhaps half the prettiest bays in the Kornati and forces the route to hop between a small number of places that have mooring buoys — most of which cannot be reserved, which means arriving early, which caps the daily distance. The route is downstream of the buoys, and getting that dependency the right way round is most of the value.
3. It writes down what it rejected, and why
My favourite feature, and the one I didn’t expect to care about. Every place that didn’t make the route gets a line explaining the reason: too far north-west for this loop, mainland side, too shallow for a keel, poor reviews, replaced by something better on the same day. The two konobas at Lojena on Smokvica Vela were cut with the note that including them would drag a 25 nm day back into the schedule.
Six months later this is the difference between a route you can trust and a route you have to re-derive from scratch. Remember Lojena, though.
4. It produces the boring, essential documents
| Output | What it’s for |
|---|---|
README.md | the route: day-by-day table plus skipper’s notes on approaches, buoy depths, reservations |
places.md | every favourite located, with mooring type and wind shelter |
toernplan.html | the shareable itinerary — self-contained, opens on a phone |
schlechtwetter-plan.md | a named fallback harbour for every single leg |
einkaufsplan.md | the provisioning plan |
The provisioning plan is where the constraints stop being nautical:
5. It ships
A small Flask app scans trips/ at runtime — each folder is a trip, an optional trip.json supplies the metadata for the overview page. Three routes, a health check, and a Markdown dependency; the app deliberately knows almost nothing. Azure Pipelines bakes the app and the trips and the favourites into a Docker image on every push to main, so the host only ever needs the one docker-compose.yml and a docker compose pull.
This is an unreasonable amount of infrastructure for one week of sailing and I regret nothing.
The Route It Drew
Six legs out of Biograd na Moru, 121 nm, up the sheltered inside of Dugi Otok to the island’s north-western tip and back down through the Kornati:
| Day | Date | Leg | nm | Night |
|---|---|---|---|---|
| 1 | Sun 19 Jul | Biograd → Mala Rava | 30 | buoy, Trattoria Mala Rava |
| 2 | Mon 20 Jul | Rava → wreck of the Michelle → Sakarun → Čuna | 28 | buoy, Veli Rat |
| 3 | Tue 21 Jul | Čuna → Sali | 24 | marina, dinner at the Maritimo |
| 4 | Wed 22 Jul | Sali → Telašćica / Uvala Mir → Vrulje | 13 | buoy, Konoba Robinson |
| 5 | Thu 23 Jul | Vrulje → Kameni Žakan | 9 | buoy field |
| 6 | Fri 24 Jul | Kameni Žakan → Murter (diesel) → Biograd | 16 | marina |
The centrepiece of day 2 is a 76-metre Italian freighter that ran aground in 1983 about a mile north of the Veli Rat lighthouse and now sits in three to five metres of water — a wreck you can snorkel on your way to a beach. Day 4 is deliberately short so there’s time for the salt lake at Uvala Mir. Every leg has a named bad-weather harbour behind it.
It’s a genuinely good plan. Read it now and you can see the reasoning behind every night.
And Here’s the Route We Sailed
115.8 nm against 121 planned. The rhythm survived exactly as designed — 13 to 27 nm days, morning departures, a buoy by evening, never anchoring overnight. The destinations moved around a fair bit.
| Night | Planned | Where we actually slept |
|---|---|---|
| 1 | Mala Rava | Mala Rava |
| 2 | Čuna, behind the Veli Rat lighthouse | Uvala Veli vodenjak, Mali Iž |
| 3 | Sali | Uvala Veli vodenjak again |
| 4 | Vrulje | Uvala Modri Bok, 0.7 nm along the coast |
| 5 | Kameni Žakan | Uvala Lojena, Smokvica Vela |
| 6 | Marina Biograd | Marina Biograd |
Why it moved
The weather took the northern loop. Monday morning we left Mala Rava and motored north-west up the channel towards Sakarun and the wreck — for about an hour, until a front coming out of the north-west made the rest of that day a bad idea. We turned round off Dragove at 09:29, came back down the same channel, took a long stop off Savar and spent the night on a buoy in Uvala Veli vodenjak instead. The northern third of the route simply didn’t happen, and the wreck of the Michelle is still out there unvisited.
Then we stayed there. The forecast kept us in Vodenjak for a second night, which is what a bad-weather plan is for. That knocked out the Sali overnight — by the time we’d have arrived the marina might well have been full anyway, and there is a strong argument, when you are already lying to a good buoy in a beautiful bay, for simply not moving. It was a much nicer place to be than a marina berth. Sali still happened, just as a Wednesday-morning stop for stores and diesel on the way south.
And some bays were just better. On the Thursday we passed 0.6 nm from Kameni Žakan — the buoy field we were supposed to sleep in — decided we liked the look of further on, rounded Rt Opat and tied up at Lojena instead. Which is, of course, precisely the place the planner had cut for being one leg too far south. It was the right call. It was also the only day of the week that was properly sailed rather than motored: four hours at two and a half to three and a half knots.
The storm, in the end, never really arrived. That’s how it goes.
What Held Up
| Part of the plan | Verdict |
|---|---|
| The daily distances | Held perfectly. 13–27 nm days, exactly as designed. |
| Locating every pin with a mooring type and a wind rating | The highest-value work in the repo. |
| A named fallback harbour for every leg | Used on day 2, and the reason day 3 was a comfortable decision rather than a scramble. |
| Writing down why places were cut | Best feature. It’s how I know Lojena was a deliberate change of mind and not an accident. |
| Committing a specific bay to a specific night | Optimistic. Four of six moved — and mostly for good reasons. |
The pattern is clear enough, and it’s a useful one for the next trip: the planner should commit hard to distances, shelter and mooring type, and offer the bays as a ranked menu rather than a schedule. Which is roughly what places.md already is — it just needs to be the primary output rather than the supporting one.
Status
Repo: sailing-trips — the planner, the Flask app, the pipeline.
Live: sailing.altbrot.at
Trips planned: two. A northern loop through the Zadar archipelago to Molat, Olib and Pag is already drawn up — built entirely from the favourites that were too far north-west for this route, because the planning pass produced more good places than one week can hold.
Trips sailed: one, and it was excellent.
The wreck is still there. It’ll keep.