Sign inSign up

stevenlafl/meshtile

By stevenlafl

•Updated 7 months ago

RF coverage tile server for Meshtastic networks

Image
Web servers
0

1.5K

stevenlafl/meshtile repository overview

⁠Meshtile

C++ HTTP tile server that computes RF signal coverage for Meshtastic mesh network nodes using the NTIA ITM (Longley-Rice)⁠ propagation model and SRTM elevation data, then serves blended signal-strength tiles as 256x256 PNGs.

Meshtile screenshot

⁠Build

Requires: libcurl, zlib, a C++17 compiler.

mkdir build && cd build
cmake ..
make -j$(nproc)

CMake auto-downloads all third-party dependencies via FetchContent (NTIA ITM, cpp-httplib, nlohmann/json, lodepng).

⁠Usage

./meshtile [options]
⁠Server Options
FlagDefaultDescription
--host0.0.0.0Bind address
--port8080Listen port
--regiondenMeshMapper⁠ region prefix (see below)
--nodesmeshmapper APIOverride node source with a URL or local JSON file
--noise-datameshmapper APIOverride noise floor data with a URL or local file
--max-range30Max propagation range per node (km)
⁠MeshMapper Regions

Node and noise floor data are fetched from MeshMapper⁠ regional instances. Each instance uses a short prefix as its subdomain (e.g. den.meshmapper.net, oma.meshmapper.net). Use --region to select which instance to pull from:

./meshtile --region den    # Denver (default)
./meshtile --region oma    # Omaha
./meshtile --region pnw    # Pacific Northwest
./meshtile --region yyc    # Calgary

The full list of available regions is at meshmapper.net⁠. The --nodes and --noise-data flags override the region-based URLs if you need a custom source.

⁠ITM Propagation Parameters
FlagDefaultDescription
--climate5ITM climate code (1=Equatorial, 2=Continental Subtropical, 3=Maritime Tropical, 4=Desert, 5=Continental Temperate, 6=Maritime Temperate Over Land, 7=Maritime Temperate Over Sea)
--refractivity301.0Surface refractivity (N-units)
--ground-dielectric15.0Ground dielectric constant
--ground-conductivity0.005Ground conductivity (S/m)
--clutter-height0.0Ground clutter height in meters (trees, buildings)
--time-pct50.0ITM time variability (0-100%)
--location-pct50.0ITM location variability (0-100%)
--situation-pct50.0ITM situation variability (0-100%)
⁠Display Options
FlagDefaultDescription
--colormapplasmaTile colormap: plasma, red_yellow_green, viridis, turbo, inferno
⁠Example
./meshtile --port 9090 --climate 6 --clutter-height 2 --colormap plasma

All effective parameters are logged at startup, whether set explicitly or left at defaults.

⁠Endpoints

EndpointDescription
GET /tiles/{z}/{x}/{y}.pngSignal coverage + node markers (256x256 RGBA PNG)
GET /signal/{z}/{x}/{y}.pngSignal coverage only
GET /nodes/{z}/{x}/{y}.pngNode markers only
GET /overlay.kmlKML network link for Google Earth
GET /healthHealth check

⁠Google Earth

In Google Earth: hamburger menu > Map Style > Add Tile Overlay > http://host:port/tiles/{z}/{x}/{y}.png

⁠Caching

  • Per-node signal grids are cached to disk at ~/.cache/meshtile/<region>/grids/
  • Rendered tile PNGs are cached to disk + memory at ~/.cache/meshtile/<region>/tiles/
  • HGT elevation tiles are cached at ~/.cache/mesh3d/hgt/ (shared with mesh3d)
  • Changing any ITM or RF parameter automatically invalidates cached grids on next run

⁠Docker

docker build -t meshtile .
docker run -v meshtile-cache:/data/.cache -p 8080:8080 meshtile --region den

Or with Docker Compose:

services:
  meshtile:
    image: stevenlafl/meshtile
    ports:
      - "8080:8080"
    volumes:
      - meshtile-cache:/data/.cache
    command: ["--region", "den"]

volumes:
  meshtile-cache:
docker compose up

The cache volume persists signal grids and HGT elevation data across container restarts, avoiding expensive recomputation. Each region gets its own cache namespace within the volume.

⁠How It Works

  1. Fetches the node list from the meshmapper API (or local JSON)
  2. For each node, loads SRTM HGT elevation data and runs ITM point-to-point propagation for every grid cell within max_range km
  3. Signal grids are cached per-node; when a new node appears, only its grid is computed and only overlapping tiles are invalidated
  4. At render time, overlapping grids are blended (strongest signal wins) and mapped through the selected colormap
  5. Tiles are served as standard XYZ slippy map PNGs with CORS headers

⁠Dependencies

LibraryPurpose
NTIA ITM⁠Longley-Rice propagation model
cpp-httplib⁠HTTP server
nlohmann/json⁠JSON parsing
lodepng⁠PNG encoding
libcurlHTTP client
zlibGzip decompression

⁠License

MIT. See LICENSE⁠ for details.

Third-party dependency licenses are listed in THIRD_PARTY_LICENSES⁠.

Tag summary

Content type

Image

Digest

sha256:ca506cba6…

Size

32.6 MB

Last updated

7 months ago

docker pull stevenlafl/meshtile