Fetch
How the model turns a lake polygon and a wind forecast into a fishability score — and every source, constant, and limitation behind it.
Fetch is a self-initiated design exploration, not commissioned work. It scores eight Minnesota lakes for fishability across a seven-day forecast by running wind against real lake geometry. It is built entirely on public agency data, credited in full in section 9, and it is not affiliated with, endorsed by, or connected to onX in any way. The argument it makes — that the lake polygon is a computational input, not a pin — is offered for pressure testing, not presented as a finished product.
I built this on my own, using data anyone can download. Nobody asked me to, and I have never worked on onX. It is a point of view, offered for pressure testing.
Per shoreline point, at the block's wind bearing, the model computes a raw geometry term, an activation term, and their product. Those roll up per lake, block, and craft into a stretched ten-point score. Every constant below is stated as it ships.
Per shoreline point, at the block's wind bearing
t = normalizeFetch(fetch) raw geometry, per point
normalizeFetch(m) = clamp((ln m − ln 50) / (ln 6000 − ln 50), 0, 1), m ≤ 50 → 0
FETCH_FLOOR = 50 m FETCH_CEIL = 6000 m
activation = clamp((windMph − 3) / 7, 0, 1) no windblown effect in dead calm
e = t · activation
Per lake / block / craft
structure = percentile(e, 90) windblown exposure exists somewhere
shelterFraction = share of points with t < 0.25 lee geometry, from raw t, wind-independent
comfort = 1 − clamp(windMph / craft.gate, 0, 1)
control = comfort + (1 − comfort) · shelterFraction
base01 = craft.structure · structure + craft.control · control
stretched = clamp((base01 − 0.329) / (0.8513 − 0.329), 0, 1)
score10 = clamp(round(stretched · M · 10), 0, 10)
M conditions multiplier: pressure trend (Δ over prior 12h), cloud × light window,
solunar (low weight, labelled low-evidence). Clamped [0.6, 1.25].
The stretch bounds are derived, not guessed. 0.329 and 0.8513 are the 5th and 95th percentiles of non-gated base01 across all 448 cells × 4 craft, measured 2026-07-31 — 1535 samples, base01 range 0.1931 to 0.9760. Hardcoded, and re-derivable if the composition changes.
Protected is not good. Structure and control pull in opposite directions — windblown points concentrate bait; protection is about handling the boat — so the craft weights decide how a lake is good, not just how good. A hard gate is not a low score: wind above a craft's gust ceiling renders a distinct glyph, never a number, because bad and can't are different semantics.
A score from zero to ten for one lake at one three-hour block. It balances two opposed things: how much windblown shoreline is working, and whether your boat can handle the conditions. The formula is here so you can check it rather than trust it.
Fetch is effective fetch by the Shore Protection Manual method — Saville (1954) — not a single ray. Fifteen radials fan across the upwind bearing and terminate at plus and minus 42°, so the cone spans 84° at 6° spacing, cosine-weighted toward the center.
15 rays at 6° increments across ±42° of the upwind bearing F_eff = Σ(Xᵢ · cos θᵢ) / Σ(cos θᵢ) Ray offsets: −42 −36 −30 −24 −18 −12 −6 0 6 12 18 24 30 36 42
The shoreline is sampled at roughly 150 m intervals. Bearing is the direction the wind comes from, matching Open-Meteo's wind_direction_10m: a west wind (270°) puts long fetch on the east shore. A ray whose first 5 m leaves the polygon returns 0, not a spurious hit across the county; islands and interior rings block fetch. Fetch is precomputed at 36 bearings — 10° steps — as raw integer metres on disk, with no normalization applied until render, so the color ramp can change without regenerating data.
The 10° bearing resolution and the 36-direction precompute match the sampling used in published NOAA and University of Michigan effective-fetch work on the Great Lakes. It was arrived at independently here — as the fetch model's own angular resolution — and the convergence is noted, not borrowed.
The zero fraction is itself a proof of the geometry. F_eff is 0 only when the whole 84° ray cone lies landward, which happens over 180 − 84 = 96 degrees of 360. Predicted 26.7%; observed 26.9% to 28.0%, the deviation tracking shoreline convolution. The bearing convention was validated too: Waconia with wind from 270° puts maximum fetch at local x = +2,235 m (east); from 090° it flips to x = −2,202 m (west). The model was not adjusted to make either pass.
| Lake | Points | Median (m) | Max (m) | Zero % |
|---|---|---|---|---|
| Waconia | 106 | 424 | 3,580 | 26.9% |
| Minnetonka | 921 | 80 | 3,839 | 27.3% |
| Mille Lacs | 1,061 | 199 | 24,409 | 27.2% |
| Upper Prior | 58 | 88 | 1,085 | 28.0% |
| Big Marine | 174 | 117 | 2,342 | 27.8% |
| Lake Elmo | 45 | 127 | 952 | 27.2% |
| Forest Lake | 169 | 155 | 2,238 | 27.5% |
| White Bear | 142 | 287 | 2,734 | 27.5% |
| Totals | 2,676 | 17.2 s wall · 390 KB · minimum is 0 for every lake | ||
Fetch is how far wind travels over open water before it hits a point on the bank. Rather than measure one straight line, the published method fans fifteen rays across an eighty-four degree cone and weights them. Every point on every shoreline gets its own number, precomputed for thirty-six wind directions.
The craft selector balances the two opposed halves of the score. Caution and gate are gust thresholds in miles per hour; structure and control are the weights on the windblown and boat-handling halves.
| Craft | Caution (gust mph) | Gate (gust mph) | Structure | Control |
|---|---|---|---|---|
| Kayak | 12 | 18 | 0.35 | 0.65 |
| Tiller (default) | 18 | 25 | 0.50 | 0.50 |
| Console | 25 | 35 | 0.65 | 0.35 |
| Deep-V | 32 | 45 | 0.80 | 0.20 |
These ceilings are the author's judgment, tuned for demonstration — not a published standard. They are chosen to make the hard gate legible across a realistic range of boats, and they are concrete enough for a reader to interrogate. Nothing on this site tells anyone it is safe to go out. A score describes conditions against a chosen craft; it never implies clearance, and the "we don't know" and gated states are designed screens, not green lights.
A kayak and a twenty-foot boat do not have the same day on the same water. Each craft has a wind ceiling above which the app stops scoring and shows a hard stop instead. Those ceilings are my judgment for demonstration, not a safety standard, and nothing here means it is safe to go out.
Every value carries confidence, from two independent sources with two different visual treatments. They are never collapsed into a single number.
Measured, not assumed. It comes from the GFS ensemble — 31 members (control plus 30 perturbed) on a 0.25° grid, endpoint gfs025. For each lake and three-hour block the model takes the circular standard deviation of wind direction across members and normalizes it from 10° to 90° onto 0 to 1. Below the 10° floor — the fetch model's own 10° angular resolution — a spread is indistinguishable from none; at the 90° ceiling, a half-plane of plausible upwind bearings, the direction is unresolved and the cell is not scored.
The standard deviation must be circular because compass bearings wrap: 350° and 010° are 20° apart, not 340°. A linear standard deviation would read that pair as an enormous spread and garble the confidence of every cell near due north. So the spread is computed from the mean resultant vector of the members' bearings, which respects the wrap.
The second axis is the vintage of the depth-map fieldwork behind each lake's geometry. It runs from 1944 to 2001 across this set, and it degrades the structure terms — the geometry-derived half of the score. The framing is unverified, not inaccurate: basin shape barely moves, but littoral contours and vegetation do, and on some of these lakes nobody has checked since. Fish-survey catch data (CPUE) renders with its own survey year but does not feed the score; geometry does, so geometry's vintage is the confidence question that matters.
| Lake | DOW | Survey | Bathymetry fieldwork |
|---|---|---|---|
| Waconia | 10005900 | 2025 | 1959-08-12 |
| Minnetonka | 27013300 | 2022 | 1949-01-01 |
| White Bear | 82016700 | 2024 | 1978-05-01 |
| Upper Prior | 70007200 | 2025 | 1976-06-02 |
| Forest Lake | 82015900 | 2025 | 1958-09-03 |
| Big Marine | 82005200 | 2024 | 1981-08-03 |
| Mille Lacs | 48000200 | 2025 | 1944-07-17 |
| Lake Elmo | 82010600 | 2025 | 2001-08-16 (GPS) |
The two axes stay separate on purpose. Forecast uncertainty and geometry uncertainty come from different sources and fail in different ways — one is how predictable the wind is, the other is how old the shape is. Collapsing them into one confidence number would hide which input is uncertain, which is the only thing that tells a reader what to distrust. So they are rendered differently and never merged.
Two different kinds of not-knowing. The forecast might be uncertain, which is measured by how much the thirty-one ensemble members disagree. And the depth map might be old, which is measured by when the fieldwork was actually done. They are shown separately because averaging them would hide which one is the problem.
The full list, unsoftened.
Everything the model gets wrong, guesses at, or does not attempt. This list exists because a tool that argues for provenance has to apply that standard to itself.
One competitor ships this mechanic. Deep Dive added a wind fetch layer in June 2025 — a bass- and tournament-focused app, $79.99 a year, rated 4.7 stars on about 5,000 ratings. It computes wind fetch along with wind speed and direction, and it accumulates that exposure over time. Within a year it renamed the layer from Wind Effects to Wave Impacts — an indication that the hard part of this is legibility, not computation.
What Deep Dive does that this model does not: it accumulates exposure over roughly 12 to 24 hours, where this model is instantaneous. That is a real capability gap, stated plainly.
Nobody else in the space computes fetch. Navionics and Fishbrain are bathymetry and charting products — they map the water and the catch, but they do not run wind against shape. Everything else that treats effective fetch seriously is academic. This is a reading of the category, described as it stands, not a claim against anyone in it.
One competitor already ships wind-versus-geometry and charges eighty dollars a year for it. They do one thing this does not: track how wind builds over hours. Their limit is coverage, which is not a limit onX has.
This is offered for pressure testing. A redesign of a product I have never had internal context on can only be honest if it names what it cannot see:
The value here is not that I am right about onX. It is that the argument is inspectable enough — every constant, source, and limitation on this page — for someone inside onX to tell me exactly where I am wrong.
I have never seen the inside of this product. These are the specific things that could make my argument wrong, listed so you can tell me which ones do.
Public agency data only, non-commercial portfolio use, all credited by name.
Polygon source host. The spec credits gisdata.mn.gov, but the acquisition script actually retrieves the polygons from enterprise.gisdata.mn.gov/aghost/. That second host is the correct one, stated here so the credit matches where the data was really pulled from. Both are Minnesota Geospatial Commons endpoints; the polygons are stored at full source precision and never rounded or simplified, because they are the fetch model's input.
Where every number came from, named. The state of Minnesota made the maps, Open-Meteo made the forecast, OpenStreetMap made the basemap. None of it is mine and all of it is public.