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.comstamen_terrainstamen_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: © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: © <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:
- Try OpenTopoMap first
- Fallback to Stadia if user has API key configured
- 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:
-
Esri World Topo:
https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x} -
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
- OpenTopoMap: https://opentopomap.org/
- Leaflet Providers: https://leaflet-extras.github.io/leaflet-providers/preview/
- Previous iteration: RFCP-Iteration10.3.2-Fix-Boundary-Rendering.md