Implements the three open PRs, with OpenStreetMap kept as the shipping default and OpenTopoMap added as a user toggle (the deploy PRs flipped the default to topo — this keeps OSM default and makes topo opt-in). PR #61 (@Yazutsu) — persist the map 'Show link lines' toggle across reboots: TouchCfg gains map_show_links (cfg v20, default 1); saved in mapOptLinesCb, loaded in begin(). PR #52/#53 (@samuelcoustet) — OpenTopoMap tile proxy, adapted: - deploy: tiles.wadamesh.com.conf keeps the default /{z}/{x}/{y}.jpg on OSM and adds /opentopo/ (OpenTopoMap) + an explicit /osm/ alias; tile-transcode.py grows _fetch_tile_png/_tile_response_from_png helpers feeding /osm + /opentopo while the root route stays OSM. - firmware: new map_style pref (cfg v21, 0=OSM default, 1=OpenTopoMap) + a 'Topographic map' switch in Map → Options. Topo tiles are namespaced on disk (/tiles/topo) and fetched via the proxy's /opentopo route, so the OSM and topo caches never collide and toggling is instant for already-cached tiles. Topo bypasses the OSM-only microSD packs and always fetches online; the shared (z,x,y) fetch-dedup ring is cleared on toggle so the new style re-queues. Legal: OpenTopoMap map tiles are © OpenTopoMap (CC-BY-SA) over © OpenStreetMap contributors (ODbL) + SRTM. The on-map © attribution and the Options → Info credits sheet switch to that text when topo is active; the proxy keeps a contactable User-Agent + 14-day cache per OpenTopoMap's tile-usage policy. Topo needs the VPS deploy (restart wadamesh-tile-transcode + reload nginx) before the /opentopo route serves; until then topo tiles 404 (handled as a permanent miss, no retry hammer). OSM default is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-Authored-By: Yazutsu <andrzej@gruziel.pl>
150 lines
6.7 KiB
Plaintext
150 lines
6.7 KiB
Plaintext
# tiles.wadamesh.com — map-tile proxy for the wadamesh map tab. Default style is
|
|
# OpenStreetMap; an opt-in OpenTopoMap topographic style is served from /opentopo/.
|
|
#
|
|
# The firmware fetches plain HTTP (on-device HTTPS isn't workable: mbedTLS wants
|
|
# ~30 KB heap for a handshake and only ~5 KB is free after Wi-Fi associates), so
|
|
# this vhost is HTTP-only by design. Cloudflare sits in front and caches results
|
|
# at the edge; this origin keeps a second 14-day disk cache.
|
|
#
|
|
# The device also can only decode JPEG cheaply (SJPG/TJpgDec -> RGB565 in
|
|
# stripes); PNG decode (lodepng) needs a 256 KB ARGB8888 buffer per tile. OSM
|
|
# only serves PNG, so the device requests `.jpg` and a local transcode service
|
|
# (tile-transcode.py on 127.0.0.1:5005) fetches the OSM PNG and re-encodes it as
|
|
# JPEG. The legacy `.png` passthrough (used by the website / older callers) is
|
|
# kept alongside it.
|
|
#
|
|
# device --HTTP--> CF --HTTP--> nginx (this) --> 127.0.0.1:5005 --HTTPS--> OSM
|
|
# PNG -> JPEG (Pillow)
|
|
#
|
|
# Deploy:
|
|
# sudo systemctl enable --now wadamesh-tile-transcode # the :5005 service
|
|
# sudo cp deploy/nginx/tiles.wadamesh.com.conf /etc/nginx/sites-available/
|
|
# sudo ln -sf /etc/nginx/sites-available/tiles.wadamesh.com.conf /etc/nginx/sites-enabled/
|
|
# sudo mkdir -p /var/cache/nginx/wadamesh-tiles && sudo chown www-data: /var/cache/nginx/wadamesh-tiles
|
|
# sudo nginx -t && sudo systemctl reload nginx
|
|
# Cloudflare: tiles.wadamesh.com proxied (orange cloud), SSL/TLS "Flexible",
|
|
# Cache Rule: Eligible for cache + Edge TTL ~14d for "/*". Do NOT enable
|
|
# "Always Use HTTPS" on this hostname. Purge the CF cache after first deploy
|
|
# so any negatively-cached `.jpg` 404s clear.
|
|
|
|
proxy_cache_path /var/cache/nginx/wadamesh-tiles levels=1:2
|
|
keys_zone=wadamesh_tiles:10m max_size=4g inactive=14d use_temp_path=off;
|
|
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name tiles.wadamesh.com;
|
|
|
|
# Re-resolve the OSM upstream (for the .png passthrough) at request time. A
|
|
# literal hostname in proxy_pass fails with "no resolver defined" on a fresh
|
|
# box; a variable + resolver works.
|
|
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
|
resolver_timeout 5s;
|
|
|
|
# Primary path the firmware uses: /{z}/{x}/{y}.jpg -> local transcode service
|
|
# (fetches the OSM PNG, re-encodes as JPEG). The regex is DOUBLE-QUOTED on
|
|
# purpose: nginx's lexer otherwise treats { and } (quantifiers) as block
|
|
# delimiters and refuses to start.
|
|
location ~ "^/(?<z>[0-9]{1,2})/(?<x>[0-9]{1,7})/(?<y>[0-9]{1,7})\.jpg$" {
|
|
proxy_pass http://127.0.0.1:5005/$z/$x/$y.jpg;
|
|
proxy_set_header Host "tiles.wadamesh.com";
|
|
|
|
proxy_cache wadamesh_tiles;
|
|
proxy_cache_key "jpg:$z/$x/$y";
|
|
proxy_cache_valid 200 14d;
|
|
proxy_cache_valid 404 1d;
|
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
|
proxy_cache_lock on;
|
|
add_header X-Cache-Status $upstream_cache_status always;
|
|
add_header Cache-Control "public, max-age=2592000" always;
|
|
|
|
proxy_buffering on;
|
|
proxy_read_timeout 20s;
|
|
proxy_connect_timeout 5s;
|
|
}
|
|
|
|
# OpenTopoMap (topographic) — OPT-IN alternate style. The firmware requests
|
|
# this path only when the user enables "Topographic map"; the default
|
|
# /{z}/{x}/{y}.jpg above stays OpenStreetMap. Legal: map © OpenTopoMap
|
|
# (CC-BY-SA), data © OpenStreetMap contributors + SRTM — the touch UI shows
|
|
# that attribution when topo is selected. The 14-day disk cache means each
|
|
# tile hits OpenTopoMap at most once per fortnight (their tile policy asks it).
|
|
location ~ "^/opentopo/(?<z>[0-9]{1,2})/(?<x>[0-9]{1,7})/(?<y>[0-9]{1,7})\.jpg$" {
|
|
proxy_pass http://127.0.0.1:5005/opentopo/$z/$x/$y.jpg;
|
|
proxy_set_header Host "tiles.wadamesh.com";
|
|
|
|
proxy_cache wadamesh_tiles;
|
|
proxy_cache_key "opentopo-jpg:$z/$x/$y";
|
|
proxy_cache_valid 200 14d;
|
|
proxy_cache_valid 404 1d;
|
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
|
proxy_cache_lock on;
|
|
add_header X-Cache-Status $upstream_cache_status always;
|
|
add_header Cache-Control "public, max-age=2592000" always;
|
|
|
|
proxy_buffering on;
|
|
proxy_read_timeout 20s;
|
|
proxy_connect_timeout 5s;
|
|
}
|
|
|
|
# Explicit OpenStreetMap alias (identical to the default root path above).
|
|
location ~ "^/osm/(?<z>[0-9]{1,2})/(?<x>[0-9]{1,7})/(?<y>[0-9]{1,7})\.jpg$" {
|
|
proxy_pass http://127.0.0.1:5005/osm/$z/$x/$y.jpg;
|
|
proxy_set_header Host "tiles.wadamesh.com";
|
|
|
|
proxy_cache wadamesh_tiles;
|
|
proxy_cache_key "osm-jpg:$z/$x/$y";
|
|
proxy_cache_valid 200 14d;
|
|
proxy_cache_valid 404 1d;
|
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
|
proxy_cache_lock on;
|
|
add_header X-Cache-Status $upstream_cache_status always;
|
|
add_header Cache-Control "public, max-age=2592000" always;
|
|
|
|
proxy_buffering on;
|
|
proxy_read_timeout 20s;
|
|
proxy_connect_timeout 5s;
|
|
}
|
|
|
|
# Elevation profile for the line-of-sight analyzer (same local service).
|
|
location = /elev {
|
|
proxy_pass http://127.0.0.1:5005;
|
|
proxy_set_header Host "tiles.wadamesh.com";
|
|
proxy_cache wadamesh_tiles;
|
|
proxy_cache_key "elev:$args";
|
|
proxy_cache_valid 200 30d;
|
|
proxy_cache_valid 400 404 1h;
|
|
proxy_cache_lock on;
|
|
add_header X-Cache-Status $upstream_cache_status always;
|
|
proxy_buffering on;
|
|
proxy_read_timeout 20s;
|
|
proxy_connect_timeout 5s;
|
|
}
|
|
|
|
# Legacy direct PNG passthrough -> OSM (kept for the website / older callers).
|
|
location ~ "^/(\d{1,2})/(\d{1,7})/(\d{1,7})\.png$" {
|
|
set $osm_upstream "tile.openstreetmap.org";
|
|
proxy_pass https://$osm_upstream/$1/$2/$3.png;
|
|
proxy_ssl_server_name on;
|
|
proxy_set_header Host tile.openstreetmap.org;
|
|
proxy_set_header User-Agent "wadamesh-tile-proxy/1.0 (+https://wadamesh.com)";
|
|
proxy_set_header Referer "https://wadamesh.com/";
|
|
|
|
proxy_cache wadamesh_tiles;
|
|
proxy_cache_valid 200 302 14d;
|
|
proxy_cache_valid 404 1h;
|
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
|
proxy_cache_lock on;
|
|
add_header X-Cache-Status $upstream_cache_status;
|
|
expires 14d;
|
|
}
|
|
|
|
# Tiny landing so a human hitting the bare hostname isn't met with 404.
|
|
location = / {
|
|
default_type text/plain;
|
|
return 200 "wadamesh tile proxy (HTTP only)\n\n /{z}/{x}/{y}.jpg -> OpenStreetMap (default)\n /osm/{z}/{x}/{y}.jpg -> OpenStreetMap\n /opentopo/{z}/{x}/{y}.jpg -> OpenTopoMap (CC-BY-SA)\n\nUpstream PNG transcoded to JPEG.\n";
|
|
}
|
|
|
|
location / { return 404; }
|
|
}
|