import { countriesData, getColorByPenetration, getRegionColor } from './data/countries-data.js'; import { citiesData, getCityRadius, getCityColor, getConnections } from './data/cities-data.js'; // Mapbox access token mapboxgl.accessToken = 'pk.eyJ1IjoibGludXhpc2Nvb2wiLCJhIjoiY2w3ajM1MnliMDV4NDNvb2J5c3V5dzRxZyJ9.wJukH5hVSiO74GM_VSJR3Q'; // Initialize map with globe projection const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/dark-v11', projection: 'globe', center: [20, 20], zoom: 1.5 }); // Layer state management const layerState = { countries: true, cities: true, connections: true, labels: true }; // Add atmosphere styling map.on('style.load', () => { map.setFog({ color: 'rgb(186, 210, 235)', 'high-color': 'rgb(36, 92, 223)', 'horizon-blend': 0.02, 'space-color': 'rgb(11, 11, 25)', 'star-intensity': 0.6 }); }); // Load and display data map.on('load', () => { // Add country data source map.addSource('countries', { type: 'geojson', data: countriesData }); // Add cities data source map.addSource('cities', { type: 'geojson', data: citiesData }); // Add connections data source const connections = getConnections(); map.addSource('connections', { type: 'geojson', data: connections }); // Layer 1: Country fill layer (choropleth) - Internet penetration map.addLayer({ id: 'country-fills', type: 'circle', source: 'countries', paint: { 'circle-radius': [ 'interpolate', ['linear'], ['zoom'], 1, ['/', ['get', 'population'], 2000000], 5, ['/', ['get', 'population'], 500000] ], 'circle-color': [ 'interpolate', ['linear'], ['get', 'internetPenetration'], 0, '#cc0000', 30, '#ff3300', 40, '#ff6600', 50, '#ff9900', 60, '#ffcc00', 70, '#33cc33', 80, '#00b300', 90, '#004d00' ], 'circle-opacity': 0.7, 'circle-stroke-width': 1, 'circle-stroke-color': '#ffffff', 'circle-stroke-opacity': 0.3 } }); // Layer 2: Tech hub circles - sized by importance map.addLayer({ id: 'tech-hubs', type: 'circle', source: 'cities', paint: { 'circle-radius': [ 'interpolate', ['linear'], ['get', 'importance'], 45, 4, 60, 6, 75, 9, 90, 13, 100, 18 ], 'circle-color': [ 'match', ['get', 'type'], 'Internet Exchange', '#ff6b6b', 'Tech Hub', '#4ecdc4', '#95e1d3' ], 'circle-opacity': 0.85, 'circle-stroke-width': 2, 'circle-stroke-color': '#ffffff', 'circle-blur': 0.2 } }); // Layer 3: Connection lines between major hubs map.addLayer({ id: 'hub-connections', type: 'line', source: 'connections', layout: { 'line-join': 'round', 'line-cap': 'round' }, paint: { 'line-color': '#00d4ff', 'line-width': [ 'interpolate', ['linear'], ['get', 'strength'], 400, 0.5, 600, 1, 800, 1.5, 1000, 2 ], 'line-opacity': 0.4, 'line-gradient': [ 'interpolate', ['linear'], ['line-progress'], 0, '#00d4ff', 0.5, '#00ffaa', 1, '#00d4ff' ] } }); // Layer 4: City labels for top tech hubs map.addLayer({ id: 'city-labels', type: 'symbol', source: 'cities', filter: ['>=', ['get', 'importance'], 75], layout: { 'text-field': ['get', 'city'], 'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'], 'text-size': [ 'interpolate', ['linear'], ['get', 'importance'], 75, 10, 90, 12, 100, 14 ], 'text-offset': [0, 1.5], 'text-anchor': 'top' }, paint: { 'text-color': '#ffffff', 'text-halo-color': '#000000', 'text-halo-width': 1.5 } }); // Add interactivity setupInteractivity(); // Initialize UI controls setupUIControls(); // Add legend createLegend(); // Add info panel createInfoPanel(); // Rotate globe let userInteracting = false; const spinGlobe = () => { if (!userInteracting) { const center = map.getCenter(); center.lng += 0.05; map.easeTo({ center, duration: 1000, easing: t => t }); } }; map.on('mousedown', () => { userInteracting = true; }); map.on('mouseup', () => { userInteracting = false; }); map.on('dragend', () => { userInteracting = false; }); map.on('pitchend', () => { userInteracting = false; }); map.on('rotateend', () => { userInteracting = false; }); setInterval(spinGlobe, 1000); }); // Setup interactivity function setupInteractivity() { // Change cursor on hover map.on('mouseenter', 'country-fills', () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', 'country-fills', () => { map.getCanvas().style.cursor = ''; }); map.on('mouseenter', 'tech-hubs', () => { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', 'tech-hubs', () => { map.getCanvas().style.cursor = ''; }); // Click on countries map.on('click', 'country-fills', (e) => { const properties = e.features[0].properties; new mapboxgl.Popup() .setLngLat(e.lngLat) .setHTML(`
Internet Penetration: ${properties.internetPenetration}%
Digital Index: ${properties.digitalIndex}
Region: ${properties.region}
Population: ${(properties.population / 1000000).toFixed(1)}M
Type: ${properties.type}
Importance Score: ${properties.importance}
Connections: ${properties.connections}
Data Centers: ${properties.datacenters}