Files
rfcp/RFCP-Iteration10.4-Fix-Stadia-Maps-401.md
2026-01-30 19:17:37 +02:00

4.3 KiB

RFCP Iteration 10.4 — Fix Stadia Maps 401 Error on Mobile

Date: 2025-01-30
Status: Ready for Implementation
Priority: Medium
Estimated Effort: 10-15 minutes


Problem Statement

On mobile Safari (iOS), the Topo/Elev map tiles show:

401 Error
Invalid Authentication
docs.stadiamaps.com/authentication

Root Cause: Stadia Maps requires API key authentication for production use. Desktop browsers may work due to referrer/caching, but mobile Safari enforces stricter policies.

Affected Features:

  • Topo button (topographic map layer)
  • Elev button (elevation/terrain layer)

Solution

Replace Stadia Maps tiles with OpenTopoMap — a free, open-source topographic map that requires no authentication.

Why OpenTopoMap?

Feature Stadia (Stamen) OpenTopoMap
API Key Required Yes No
Rate Limits 200k/month None (fair use)
Mobile Support Requires auth Works everywhere
Contour Lines Stylized More detailed
Style Artistic Technical/Professional
Best For Design RF Planning

OpenTopoMap is actually better suited for RF coverage planning — more technical appearance with detailed elevation contours.


Implementation

File to Modify

/opt/rfcp/frontend/src/components/map/Map.tsx

Find Current Stadia URLs

Look for URLs containing:

  • tiles.stadiamaps.com
  • stamen_terrain
  • stamen_toner

Replace With OpenTopoMap

Before (Stadia Maps):

const topoLayer = L.tileLayer(
  'https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png',
  {
    attribution: '© Stamen Design, © OpenMapTiles, © OpenStreetMap',
    maxZoom: 18,
  }
);

After (OpenTopoMap):

const topoLayer = L.tileLayer(
  'https://tile.opentopomap.org/{z}/{x}/{y}.png',
  {
    attribution: 'Map data: &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)',
    maxZoom: 17,  // OpenTopoMap max zoom is 17
  }
);

Also Check for Elevation Layer

If there's a separate elevation/terrain layer, replace similarly:

Before:

'https://tiles.stadiamaps.com/tiles/stamen_terrain_background/{z}/{x}/{y}{r}.png'

After:

'https://tile.opentopomap.org/{z}/{x}/{y}.png'

Alternative: Keep Both Options

If you want to keep Stadia as an option (for desktop users who like the style), you could:

  1. Try OpenTopoMap first
  2. Fallback to Stadia if user has API key configured
  3. Or just replace completely (simpler)

Recommendation: Just replace completely — OpenTopoMap is better for this use case anyway.


Testing Checklist

  • Desktop Chrome: Topo button shows OpenTopoMap tiles
  • Desktop Chrome: Elev button works (if separate from Topo)
  • Mobile Safari: No 401 errors
  • Mobile Safari: Topo/terrain tiles load correctly
  • Mobile Chrome: Same tests
  • Zoom levels 1-17 work correctly
  • Attribution displays properly
  • Coverage heatmap overlays correctly on new tiles

Verification Commands

After implementation:

cd /opt/rfcp/frontend

# Check for any remaining Stadia references
grep -r "stadiamaps" src/

# Should return empty (no matches)

# Build and deploy
npm run build
sudo systemctl reload caddy

Rollback Plan

If OpenTopoMap has issues (unlikely), can switch to other free providers:

  1. Esri World Topo:

    https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}
    
  2. CartoDB Voyager:

    https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png
    

Notes

  • OpenTopoMap maxZoom is 17 (not 18 like Stadia)
  • OpenTopoMap servers are in Germany — may be slightly slower for Ukraine, but still fast
  • Fair use policy: don't hammer the servers with excessive requests
  • HTTPS required (already using it)

Reference