fix: replace OSM tiles with ArcGIS for China network compatibility
- Switch primary tile provider from OpenStreetMap (blocked in China) to ArcGIS World Street Map (certified working) - Add fallback chain: ArcGIS -> ArcGIS Gray -> OSM - Auto-detect tile failures and fall back to next provider - Clean up init sequence for reliable map rendering Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -664,10 +664,29 @@ function renderClusterCards(clusters) {
|
||||
}
|
||||
|
||||
/* ── Step 4: Map & Visualization ──────────────────────── */
|
||||
|
||||
// Tile providers in priority order — ArcGIS works in China
|
||||
const TILE_PROVIDERS = [
|
||||
{
|
||||
name: 'ArcGIS',
|
||||
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
|
||||
attr: 'Tiles © Esri — Source: Esri, DeLorme, NAVTEQ'
|
||||
},
|
||||
{
|
||||
name: 'ArcGIS Gray',
|
||||
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
|
||||
attr: 'Tiles © Esri — Esri, DeLorme, NAVTEQ'
|
||||
},
|
||||
{
|
||||
name: 'OSM',
|
||||
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
attr: '© OpenStreetMap contributors'
|
||||
},
|
||||
];
|
||||
|
||||
function initMap() {
|
||||
const container = document.getElementById('saMap');
|
||||
if (SA.map) {
|
||||
// Ensure container is visible and properly sized
|
||||
container.style.height = '550px';
|
||||
setTimeout(() => {
|
||||
SA.map.invalidateSize();
|
||||
@@ -675,7 +694,6 @@ function initMap() {
|
||||
}, 200);
|
||||
return;
|
||||
}
|
||||
// Wait for container to be visible, then init map
|
||||
setTimeout(() => {
|
||||
container.style.height = '550px';
|
||||
// Start with global view [0, 0] zoom 2 as required
|
||||
@@ -684,15 +702,35 @@ function initMap() {
|
||||
zoom: 2,
|
||||
worldCopyJump: true,
|
||||
});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors',
|
||||
maxZoom: 18,
|
||||
}).addTo(SA.map);
|
||||
// Try each tile provider in order until one loads
|
||||
tryTileProvider(0);
|
||||
setTimeout(() => SA.map.invalidateSize(), 300);
|
||||
renderMapData();
|
||||
}, 250);
|
||||
}
|
||||
|
||||
function tryTileProvider(idx) {
|
||||
if (idx >= TILE_PROVIDERS.length || !SA.map) return;
|
||||
const provider = TILE_PROVIDERS[idx];
|
||||
const tileLayer = L.tileLayer(provider.url, {
|
||||
attribution: provider.attr,
|
||||
maxZoom: 18,
|
||||
});
|
||||
tileLayer.addTo(SA.map);
|
||||
|
||||
// Detect if tiles fail to load, try next provider
|
||||
let tileError = false;
|
||||
tileLayer.on('tileerror', () => {
|
||||
if (!tileError) {
|
||||
tileError = true;
|
||||
console.warn('Tile provider failed:', provider.name);
|
||||
SA.map.removeLayer(tileLayer);
|
||||
tryTileProvider(idx + 1);
|
||||
}
|
||||
});
|
||||
SA._tileLayer = tileLayer;
|
||||
}
|
||||
|
||||
function renderMapData() {
|
||||
if (!SA.map) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user