Michigan and Great Lakes tools built by Chris Izworski, with the methods and public code behind them.
I build tools that turn conditions into practical decisions: where to see fall color, when to watch a ship at the Soo Locks, and what the official bridge report means for a drive across the Straits. This portfolio connects those public tools to their methods, source code, and related work. — Chris Izworski
Featured Michigan and Great Lakes tools
Four starting points for exploring my work, each built around a specific decision.
I built a statewide map and regional planning system that brings color timing, weather context, and named destinations together. It helps readers compare places instead of relying on one statewide peak date.
The model blends regional seasonal timing with available weather and vegetation inputs, accounting for source age. Estimates and AI-written regional summaries are identified as interpretation, with dates and sources to inspect.
I brought vessel positions, a local map, and viewing context into a planning tool for Sault Ste. Marie. Its next-ship engine uses fresh AIS reports to identify approaching freighters and estimate arrival windows along the shipping channel.
The geometry distinguishes upbound and downbound channels around the river’s islands. A planning window remains an estimate; lock operations and incomplete AIS coverage can change what a visitor sees.
I built a lake-wide viewing page with quick choices for the Soo, Mackinac, Duluth, Port Huron, Detroit River, and Saginaw Bay. Vessel reports, corridor views, passage-source links, and nearby NOAA observations give shoreside watchers a useful starting point.
The public AIS providers supply the positions; my contribution is the interface and regional context. A missing vessel does not mean empty water, and nearby weather observations are not measurements aboard a ship.
I combined the Bridge Authority’s current status, vehicle-specific guidance, cameras, and approach-weather context in one crossing tool. Drivers can distinguish an open bridge from an advisory, escort requirement, or closure that matters to their vehicle.
The official Bridge Authority report takes priority. Nearby NOAA observations and forecasts are labeled separately so off-bridge weather does not become a claimed deck measurement or an invented restriction.
These two worked examples explain choices I made in the tools. Their inputs are hypothetical, checked against the implementation reviewed on October 8, 2026. They are not current color readings or a ship schedule.
Fall Color: an older satellite reading gets less influence
Suppose regional seasonal timing, recent weather, and any canopy-camera adjustment produce a model score of 80, while the satellite-derived score is 60. Hold those inputs fixed and change only the satellite reading's age:
Effect of satellite age on this hypothetical model score
Reading age
Satellite share
Blended score
5 days
40%
72
32.5 days
20%
76
45 days
0%
80
The satellite-age weight is 1 through day 20, declines linearly to 0 at day 45, and scales a maximum 40% blend share. In the middle row, the weight is 0.5: the blend is 80 × 0.8 + 60 × 0.2 = 76. A stale image therefore cannot pull the estimate toward an old canopy state.
The output is a modeled seasonal-progression score, not a count of trees observed in color. The response records the inputs that actually influenced it and the satellite's date and weight. A traveler can use the regional comparison to choose where to investigate next, then check current sources and destination conditions. The AI-written regional note summarizes the model; it is not a firsthand field report.
Soo Locks: a ship slows before it reaches the chamber
Suppose a commercial ship has passed the freshness, channel, course, and destination checks. Its reported speed is 10 knots and its remaining distance along the modeled shipping channel is 11 nautical miles. Simply dividing the distance by the speed gives 66 minutes, but that misses the slow final approach:
Hypothetical arrival calculation from an accepted vessel snapshot
Part of approach
Model assumption
Time
First 10 nautical miles
10 knots
60 minutes
Final nautical mile
2.5 knots
24 minutes
Total to the locks
Slower final approach
84 minutes
At 84 minutes, the code applies a 30% uncertainty margin: 25.2 minutes on either side. The resulting window is approximately 59 to 109 minutes after the snapshot, with an 84-minute midpoint. It is a window for planning a viewing visit, not an authority-issued chamber appointment.
Positions older than 30 minutes are excluded before candidate selection. The route follows the channel around the islands, and ships traveling away from the locks or with a contradictory destination do not qualify. Waiting, changes in speed, lock operations, and incomplete AIS reception can still move the real arrival. The tests check the geometry and the 84-minute approach calculation; they cannot guarantee a particular ship's transit today.
The NYC Crossing Decision Engine separates crossing cost from crossing conditions. Its cost model accounts for payment, vehicle class, destination-zone entry, and applicable credits. Its traffic layer identifies the source and scope of each reading. A fixed crossing probe is presented as a crossing observation rather than a complete address-to-address journey.
The reliability work is inspectable in traffic.js. Routing calls have bounded timeouts and limited retries; failed or partial routing results do not receive the normal successful-result cache lifetime. The regression tests exercise recovery, cache behavior, invalid responses, and source priority. The production smoke script checks the page and API together and reports degraded coverage when a source is unavailable.
Why a failed request must not become a cached answer
A traffic timeout is evidence about a request, not evidence that a bridge is clear or congested. The implementation starts five fixed Mapbox crossing probes concurrently. Each attempt has an eight-second deadline, with at most one retry for a timeout or server error. A known client error is not retried. The routing budget is therefore bounded at sixteen seconds, plus the separate bounded cache read; it is not a promise about total page load time.
Before accepting a route, the code checks its duration and distance against the intended crossing, and rejects supplied waypoints that snap too far from an anchor. A response that cannot be normalized or fails those checks does not become a live observation. Only a complete, usable LIVE probe set receives the normal cache lifetimes: sixty seconds in memory and ninety seconds in Redis. PARTIAL and UNAVAILABLE results remain eligible to recover on the next request. Older cached failure documents are ignored too.
For example, if one of five probes times out while four return usable routes, the result is partial coverage. It must not hide the failed probe behind a successful-result cache. If the next request obtains all five usable routes, it can return live coverage immediately. This is an illustrative failure sequence, not a claim that an outage occurred at a particular time.
What the tests prove, and what production still has to show
The tests use controlled responses and a simulated clock to verify the timeout budget, one-retry limit, recovery, and absence of cache writes for failures. They also verify that official agency observations take priority where available. Passing those tests establishes the software contract; it does not establish that every outside feed is healthy today. The production smoke check separately reads the deployed page and API, validates the returned crossing records, and reports a temporary feed outage as degraded coverage.
Traffic observations also retain their scope. An approach segment, a crossing probe, and an address-to-address trip answer different questions. Mixing them into a “fastest route” ranking would imply a comparison the evidence cannot support. The tool keeps the cost decision useful while showing where current traffic evidence is incomplete.
The Niagara Border Crossing Planner compares crossings for a particular direction, traveler, and lane. It incorporates the additional travel involved in a diversion, checks whether observations are fresh enough to support a recommendation, and exposes material disagreements between federal and operator reports.
Its comparison implementation can return insufficient evidence instead of naming a winner. The tests cover stale observations, source conflicts, traveler restrictions, and the public page's integration with the API. This is a concrete example of a product decision encoded in software: a detour recommendation needs better evidence than a lower number in one feed.
Michigan Trout Report
The Michigan Trout Report brings stream flows, water temperatures, and weather context together for Michigan anglers. Named river pages, technique guides, hatch references, and the daily report support planning around a particular river. Chris's founder profile describes his connection to the project.
The report methodology follows an observation through freshness checks, the daily historical flow comparison, software ratings, and the written summary. It explains which parts are measurements and which are interpretation.
Michigan Outdoors Now
Michigan Outdoors Now brings Michigan day-trip planning, trail and access information, current conditions, and travel context into one project. It extends the same interest in place-specific decisions to a day outside.
Michigan Birding Report
The Michigan Birding Report covers Michigan bird sightings, county-level birding context, and notable species pages built around live observation data. The daily birding report publishes a fresh Michigan birding briefing each day. Both sites are designed around the rhythm of a working Michigan birder rather than the more generic checklist style of larger national platforms.
Great Lakes Levels Intelligence
Great Lakes Levels places current water levels in historical and shoreline context. It organizes information by lake and named regions, including Saginaw Bay, for people trying to understand their shoreline. Chris's connection to the bay and his Save Our Shoreline civic work explain the project's focus.
The public repository contains deployed HTML and compiled JavaScript assets, rather than the original React source. Its README explains that boundary and the static deployment workflow. The page verification script checks canonical URLs and consistent creator attribution across the published HTML.
Perfect Lawn Advisor
The Perfect Lawn Advisor at lawn.chrisizworski.com generates a graded lawn plan from a single Michigan address. The tool combines soil, weather, and turfgrass context with a Claude-generated plan, then caches the result so identical addresses return instantly. Cornerstone articles, a city directory, and a curated shop layer support the core planning workflow.
Great Lakes Gazette
The Great Lakes Gazette is a Great Lakes maritime publication connecting vessel movement, lake conditions, and regional weather context. It gives the region's shipping and water information a place in the broader publishing work.
Freighter View Farms
Freighter View Farms is the seed-saving and Great Lakes gardening blog. The site focuses on heirloom vegetables, Zone 6a Michigan gardening, and the slow accumulation of a place-based seed library on the western shore of Saginaw Bay. Writing on the site is intentionally literary and grounded in a specific garden rather than generic gardening advice.
Related pages
The full personal hub is at chrisizworski.com. The professional 911 page covers the public safety career these projects sit alongside. The writing page lists the publishing surfaces. The Saginaw Bay page covers the place-based work that ties the network together.