chartplotter
This project is coded almost entirely with AI (Claude). It is an experiment in building a large, complex specification (IHO S-101) with AI, and a personal learning tool — not a certified or tested product. Do not rely on it for real-world navigation.
chartplotter is a marine chart plotter: a Go application built around tile57, a native chart engine written in Zig. It turns official NOAA nautical charts into fast, offline map tiles that you can view in a web browser.
The chart below is live — official NOAA charts of Annapolis, Maryland, running right here in your browser. Pan, zoom from the whole Chesapeake to the docks, and switch Day / Dusk / Night. It is the read-only widget build: static, embeddable, no server.
It reads S-57 electronic navigational chart (ENC) cells, draws them with the S-101 Portrayal Catalogue — the modern IHO standard for how charts look — and writes the result to PMTiles archives of vector tiles. A small web component built on MapLibre GL JS draws the chart.
Goal
Implement the IHO chart standards — S-57 (ENC data) and S-101 portrayal (the successor to S-52), with the wider S-100 / S-102 family planned — as a fast, low-memory native engine (libtile57, from the tile57 repo) wrapped by a small Go server, so one locally-built binary bakes and serves real charts on anything from a laptop to a Raspberry Pi on a boat.
What it does
- Turns charts into tiles. Give it one or more S-57 cells. It produces a
.pmtilesarchive you can serve or copy to another machine. - Works offline. Once you generate a region, you do not need a tile server or an internet connection to view it.
- Switches Day, Dusk, and Night instantly. The engine stores colors as S-101 color names, not fixed RGB values. The browser looks up the right palette and restyles the map. You never regenerate the tiles to change the lighting mode.
- Applies chart settings in the browser. Depth shading, soundings, depth contours, and danger highlights all come from data baked into the tiles. You generate the tiles once and adjust these settings live.
- Ships as one self-contained binary. The S-101 catalogue and the web frontend are built into the program, so it runs from a single file. Download a per-platform build from the releases page, or build it yourself; see Installation.
- Shows live position and AIS (early). Point a NMEA 0183 feed at the server
over TCP and it draws your own ship and basic AIS targets on the chart; a
simulatecommand generates traffic for testing. - Draws the whole symbol set. It renders the complete S-52 Presentation Library ECDIS Chart 1 reference sheet — every symbol, line style, area fill, and colour — drawn by the same pipeline that bakes real NOAA charts and diffed against the spec's own plots.
Beyond the chart
The chart is the foundation, not the whole app. The frontend is a <chart-plotter>
base plus small plugins — own-ship and AIS already work this way — and the goal
is a stable plugin API for building other things on top of the chart:
instrument gauges, custom overlays, routes, and more, without forking the core.
The NMEA 0183 own-ship and AIS support is the first slice of that, so expect the
plugin surface to grow and change.
Who it is for
Use chartplotter if you want to:
- Build a web app that shows NOAA ENC charts.
- Serve nautical charts that work without a network connection.
- Generate vector tiles from S-57 data in a backend pipeline.
How to read these docs
- Install the program.
- Follow the Getting Started guide to bake your first chart and view it.
- Look up any command in the CLI Reference.
- Learn how the pipeline works in Architecture.
- See the exact tile layers and fields in the Tile Schema.
A note on terms
| Term | What it means |
|---|---|
| S-57 | The international file format for electronic navigational charts. NOAA distributes U.S. charts as S-57 cells. |
| ENC cell | One S-57 chart file, named like US4MD81M.000. |
| S-101 | The IHO standard that defines how to draw an ENC: colors, symbols, and line styles. Its Portrayal Catalogue holds those rules. |
| libtile57 | The native chart engine (from the tile57 repo, written in Zig) that does all decoding, portrayal, and tiling. It is statically linked into the Go binary. |
| MLT | MapLibre Tile. The compact binary tile format chartplotter bakes by default; MapLibre GL JS 5.12+ decodes it. |
| MVT | Mapbox Vector Tile. The older vector-tile format, available with bake --format mvt. |
| PMTiles | A single-file archive that holds many vector tiles. You can serve it with simple byte-range requests. |