Skip to content

beetlebugorg/chartplotter

Repository files navigation

chartplotter

⚓ A marine chart plotter, in Go.
Generate offline vector-tile archives from NOAA S-57 ENC cells and render them in the browser.

CI Release Go Report Card License

Try the live demo  ·  📚 Read the docs →

chartplotter rendering NOAA charts of Annapolis — click to open the live demo
Open the live, interactive demo — official NOAA charts of Annapolis, rendered in your browser. No install, no server.


Warning

Not for navigation. 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. See Known limitations for what the chart rendering does not yet do.


chartplotter turns official NOAA nautical charts into fast map tiles you can view in a web browser, online or fully offline.

It reads S-57 electronic navigational chart (ENC) cells and draws them with the S-101 Portrayal Catalogue, the modern IHO standard for how charts look. It writes the result to a single PMTiles archive of Mapbox Vector Tiles. A small <chart-plotter> web component, built on MapLibre GL JS, draws the chart.

In short: the heavy lifting happens once, up front. chartplotter reads the raw NOAA charts and renders every feature — its colors, symbols, and lines — into map tiles, saved as a single file on your machine. After that the browser only displays those tiles — panning, zooming, switching palettes — and never touches the raw charts again.

🎯 Goal

Implement the IHO chart standards — S-57 (ENC data), S-101 portrayal (the successor to S-52), and the wider S-100 / S-102 family — in pure Go, with minimal dependencies and no CGO, so the whole thing cross-compiles to a single static binary for any platform with GOOS/GOARCH and nothing else to install.

✨ Features

  • A complete chart pipeline. chartplotter does every step: ISO 8211 decode, the S-57 feature model, S-101 portrayal, web-Mercator tiling, vector-tile encode, and a streaming PMTiles writer.
  • Works offline. Generate one .pmtiles archive for a region, then serve or ship it. You do not need a tile server to view it.
  • Adjust the chart live. Switch Day, Dusk, and Night palettes and toggle mariner settings — depth shading, soundings, contours, safety-depth danger highlighting — and the map restyles at once. Colors are stored as S-101 names and settings ride along as tile attributes, so the viewer applies your changes without regenerating the tiles.
  • Ships as one binary. The S-101 catalogue and the web frontend build into the program. A self-contained chartplotter serve needs no files on disk — you supply only the ENC cells.
  • Runs a server. The built-in HTTP server downloads NOAA cells, generates tiles in the background, and serves the frontend with byte-range support.
  • Live position and AIS (early). Point a NMEA 0183 feed at the server (over TCP) and it shows your own ship and basic AIS targets on the chart. A built-in simulate command generates traffic for testing.

🧩 Beyond the chart

The chart is the foundation, not the whole app. The frontend is built from a <chart-plotter> base plus small plugins (own-ship and AIS already work this way), and the goal is a stable plugin API so you can build other things on top of the chart — instrument gauges, custom overlays, routes, and more — without forking the core. NMEA 0183 own-ship and AIS are the first slice of that; expect the surface to grow and change.

📦 Install

Pre-built binaries

Download an archive for your platform from the Releases page, extract it, and put chartplotter on your PATH. Each platform ships two builds:

  • …_s101 — self-contained: embeds the S-101 catalogue, runs with no extra files. (That catalogue is IHO material; see THIRD-PARTY-NOTICES.md.)
  • plain — needs --s101 <PortrayalCatalog dir> at runtime, pointing at your own copy of the catalogue.

With go install

Requires Go 1.26+.

go install github.com/beetlebugorg/chartplotter/cmd/chartplotter@latest

From source

git clone https://github.com/beetlebugorg/chartplotter.git
cd chartplotter
make build          # -> bin/chartplotter (embeds the catalogue if it is available)
bin/chartplotter version

🚀 Get started

The frontend is built into the binary, so one file is all you need. Start the server and open the viewer:

chartplotter serve
# open http://127.0.0.1:8080 → pick a region → it downloads and builds tiles → the chart appears

The server writes everything it generates to your cache directory (~/.cache/chartplotter), never into the binary's assets.

You can also build a standalone archive yourself with the bake command:

# Generate one archive from cells, a directory, or a NOAA ENC zip.
chartplotter bake -o charts.pmtiles US4MD81M.000

# Generate one archive per navigational band (best-available display).
chartplotter bake --bands -o charts.pmtiles US5MD_ENCs.zip

To develop the frontend, serve the assets from disk instead of the embedded bundle:

chartplotter serve --assets web

⛶ Commands

Command What it does
version Print the version and whether the S-101 catalogue is embedded.
emit-assets DIR Write the S-101 client assets (color tables, sprites, line styles, patterns) to a directory.
catalog-json IN.xml OUT.json Distil NOAA ENCProdCat.xml into a compact catalog.json.
bake -o OUT.pmtiles IN… Generate a PMTiles archive from S-57 cells, directories, or NOAA ENC zips.
serve [--host] [--port] [--assets DIR] Serve the web frontend, the baking API, and the NOAA cell proxy.
simulate Run an NMEA 0183 traffic generator over TCP (own-ship + AIS targets) for testing.

Run chartplotter <command> --help for the full flags.

🧭 How it works

S-57 ENC cell (.000)
   │  ISO 8211 decode             pkg/iso8211
   ▼
S-57 feature + geometry model     pkg/s57
   │  S-101 portrayal             pkg/s100, internal/engine/s101
   ▼
Primitive drawing list (lat/lon)  internal/engine/portrayal
   │  project + clip              internal/engine/tile
   ▼
Mapbox Vector Tiles               internal/engine/mvt
   │  dedup + streaming write     internal/engine/pmtiles
   ▼
charts.pmtiles  ───────────────▶  <chart-plotter> / MapLibre GL JS  (web/)

Read the Architecture docs for the full pipeline, and the Tile Schema for the layer and field contract the frontend depends on.

🛠️ Development

make build      # build bin/chartplotter
make test       # go test ./...
make vet        # go vet ./...
make fmt        # gofmt -w .
make serve      # build + serve web/ on :8080

CI runs gofmt, go vet, go test, and go build on every push. When you push a v* tag, GoReleaser cuts a release with binaries for Linux, macOS, and Windows on amd64 and arm64.

📚 Documentation

Full docs live at beetlebugorg.github.io/chartplotter: install, the CLI reference, the chart pipeline, and the vector-tile schema.

📄 License

chartplotter's own code is MIT © Jeremy Collins.

It bundles third-party software and data under their own licenses — all Go dependencies are permissive (MIT / BSD-3-Clause), plus MapLibre GL JS (BSD), Noto Sans (OFL), OpenBridge icons (CC BY 4.0), and a GSHHG coastline basemap (LGPL). NOAA ENC charts are U.S. public domain and not for navigation.

The IHO S-101 Portrayal & Feature Catalogue is © IHO and is not included in this repository; a draft copy is embedded only in opt-in _s101 builds, and its redistribution terms are still to be confirmed. See THIRD-PARTY-NOTICES.md for the full inventory.

About

⚓ A marine chart plotter, in Go. Generate offline vector-tile archives from NOAA S-57 ENC cells and render them in the browser.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages