tui-globe

May 30, 2026 ยท View on GitHub

A ratatui Braille-canvas globe widget. Geometry buffers under assets/geo/ are baked from public domain Natural Earth data and embedded at compile time via MapData::embedded().

Demo

Demo app

cargo install tui-globe

or

make build

Regenerating the geometry

The .gl buffers are generated by tools/build_geo.py. The script fetches shapefiles from naciscdn.org on demand, caches them, and writes the five .gl blobs to --out. The buffers are checked in, so you only need to re-run the script when bumping the data set or changing the build flags.

Run it

The script is packaged as a Python project at tools/pyproject.toml, declaring pyshp, mapbox-earcut, and numpy as dependencies. Pick whichever workflow you prefer:

  • With uv
    uv run --project tools build-geo --scale 50m --out assets/geo
    
  • With pip
    cd tools
    python3 -m venv .venv
    .venv/bin/pip install -e .
    .venv/bin/build-geo --scale 50m --out ../assets/geo
    

Flags

flagdefaultmeaning
--scale {10m,50m,110m}50mNatural Earth resolution. Smaller numbers = denser mesh / larger binary.
--cultural-bordersdefaultWith borders, triangulate ne_<scale>_admin_0_countries (coastlines + country borders) and overlay ne_<scale>_admin_1_states_provinces_lines.
--no-cultural-bordersnot defaultWithout, triangulate ne_<scale>_land (coastlines only).
--data-dir PATH$XDG_CACHE_HOME/tui-globe-build-geoWhere to cache downloaded .zip/.shp files.
--out PATH(required)Output directory for the five .gl files.
--ne-countries PATHauto-fetchOverride: custom admin_0_countries .shp (cultural mode).
--ne-states PATHauto-fetchOverride: custom admin_1_states_provinces_lines .shp (cultural mode).
--ne-land PATHauto-fetchOverride: custom physical land .shp (--no-cultural-borders mode).

The override flags let you swap in locally modified shapefiles (e.g. simplified geometry, custom border tweaks). They take precedence over auto-fetch for that one input; the rest still come from the cache or are downloaded.

Examples

# Default: 50m with country and state/province borders
build-geo --scale 50m --out assets/geo

# High-detail land mesh with no borders
build-geo --scale 10m --no-cultural-borders --out assets/geo

# Tiny global-overview mesh
build-geo --scale 110m --out assets/geo

# Use custom / locally modified shapefiles (overrides auto-fetch)
build-geo --scale 50m \
    --ne-countries ./my-data/ne_50m_admin_0_countries.shp \
    --ne-states    ./my-data/ne_50m_admin_1_states_provinces_lines.shp \
    --out assets/geo

# Override just the country polygons; states still auto-fetched
build-geo --scale 50m \
    --ne-countries ./my-data/custom_countries.shp \
    --out assets/geo

# Custom physical-land shapefile, no borders
build-geo --no-cultural-borders \
    --ne-land ./my-data/custom_land.shp \
    --out assets/geo

Verify

make check

Geometry format

Five little-endian binary blobs:

filedtypemeaning
land_positions.glf32 xyzunit-sphere vertices
land_triangle_indices.glu32GL_TRIANGLES indices
land_contour_indices.glu32GL_LINE_STRIP indices, 0xFFFFFFFF between rings
ocean_positions.glf32 xyzlevel-4 icosphere vertices (2562)
ocean_indices.glu32GL_TRIANGLES indices (5120 tris)

Coordinate convention used by lib.rs::project_point:

x = cos(lat) sin(lon)
y = sin(lat)
z = cos(lat) cos(lon)

License