# 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):** ```typescript 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):** ```typescript const topoLayer = L.tileLayer( 'https://tile.opentopomap.org/{z}/{x}/{y}.png', { attribution: 'Map data: © OpenStreetMap contributors, SRTM | Map style: © OpenTopoMap (CC-BY-SA)', maxZoom: 17, // OpenTopoMap max zoom is 17 } ); ``` ### Also Check for Elevation Layer If there's a separate elevation/terrain layer, replace similarly: **Before:** ```typescript 'https://tiles.stadiamaps.com/tiles/stamen_terrain_background/{z}/{x}/{y}{r}.png' ``` **After:** ```typescript '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: ```bash 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 - OpenTopoMap: https://opentopomap.org/ - Leaflet Providers: https://leaflet-extras.github.io/leaflet-providers/preview/ - Previous iteration: RFCP-Iteration10.3.2-Fix-Boundary-Rendering.md