function initializeGlobe() { console.log('Cesium is defined, initializing globe.'); // Set your Cesium Ion default access token Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjZTY0ZTQ1Yi0zYmYxLTQ5MjItODdkOS05ZDY0ZGRjYjQwM2QiLCJpZCI6MjA5ODgwLCJpYXQiOjE3MTM4MTY3OTB9.A-3Jt_G0K81s-A-XLpT2bn5aY2H3s-n2p-2jYf-i-g'; try { console.log('Initializing Cesium Viewer'); const viewer = new Cesium.Viewer('cesiumContainer', { imageryProvider: new Cesium.OpenStreetMapImageryProvider({ url : 'https://a.tile.openstreetmap.org/' }), animation: false, baseLayerPicker: false, fullscreenButton: false, geocoder: false, homeButton: false, infoBox: true, sceneModePicker: false, selectionIndicator: false, timeline: false, navigationHelpButton: false, scene3DOnly: true }); viewer.scene.globe.depthTestAgainstTerrain = false; console.log('Cesium Viewer initialized successfully'); // Add Weather Layer const weatherImageryProvider = new Cesium.UrlTemplateImageryProvider({ url: `api/weather.php?layer=clouds_new&z={z}&x={x}&y={y}`, credit: 'Weather data © OpenWeatherMap' }); const weatherLayer = viewer.imageryLayers.addImageryProvider(weatherImageryProvider); weatherLayer.alpha = 0.6; // UI Controls const weatherCheckbox = document.getElementById('weatherLayerCheckbox'); weatherCheckbox.addEventListener('change', function() { weatherLayer.show = this.checked; }); let wildfireDataSource; const wildfireCheckbox = document.getElementById('wildfireLayerCheckbox'); wildfireCheckbox.addEventListener('change', function() { if (wildfireDataSource) { wildfireDataSource.show = this.checked; } }); let spcDataSource = new Cesium.CustomDataSource('spcOutlook'); viewer.dataSources.add(spcDataSource); const spcCheckbox = document.getElementById('spcLayerCheckbox'); spcCheckbox.addEventListener('change', function() { spcDataSource.show = this.checked; }); let weatherAlertsDataSource = new Cesium.CustomDataSource('weatherAlerts'); viewer.dataSources.add(weatherAlertsDataSource); const weatherAlertsCheckbox = document.getElementById('weatherAlertsLayerCheckbox'); weatherAlertsCheckbox.addEventListener('change', function() { weatherAlertsDataSource.show = this.checked; }); // Wind Layer const windLayer = new WindLayer(viewer, { particleHeight: 10000, particleCount: 10000, maxAge: 120, particleSpeed: 5 }); const windCheckbox = document.getElementById('windLayerCheckbox'); windCheckbox.addEventListener('change', function() { windLayer.setVisible(this.checked); }); const windAltitudeSlider = document.getElementById('windAltitudeSlider'); const windAltitudeLabel = document.getElementById('windAltitudeLabel'); windAltitudeSlider.addEventListener('input', function() { const altitude = parseInt(this.value, 10); windAltitudeLabel.textContent = `${altitude} m`; windLayer.setOptions({ particleHeight: altitude }); }); // Function to load wildfire data const loadWildfireData = async () => { try { console.log('Fetching wildfire data...'); const response = await fetch('api/wildfires.php'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const geojsonData = await response.json(); console.log('Wildfire data fetched successfully.'); wildfireDataSource = new Cesium.GeoJsonDataSource(); await wildfireDataSource.load(geojsonData, { stroke: Cesium.Color.RED, fill: Cesium.Color.RED.withAlpha(0.5), strokeWidth: 2 }); viewer.dataSources.add(wildfireDataSource); console.log('Wildfire data source added to viewer.'); } catch (error) { console.error('Error loading wildfire data:', error); } }; const loadSpcData = async () => { try { console.log('Fetching SPC data...'); const response = await fetch('api/spc.php'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const spcData = await response.json(); console.log('SPC data fetched successfully.'); spcDataSource.entities.removeAll(); const spcColors = { 'TSTM': Cesium.Color.fromCssColorString('#00FF00').withAlpha(0.5), // General Thunderstorms 'MRGL': Cesium.Color.fromCssColorString('#00C800').withAlpha(0.5), // Marginal 'SLGT': Cesium.Color.fromCssColorString('#FFFF00').withAlpha(0.5), // Slight 'ENH': Cesium.Color.fromCssColorString('#FFA500').withAlpha(0.5), // Enhanced 'MDT': Cesium.Color.fromCssColorString('#FF0000').withAlpha(0.5), // Moderate 'HIGH': Cesium.Color.fromCssColorString('#FF00FF').withAlpha(0.5) // High }; spcData.forEach(feature => { const color = spcColors[feature.name] || Cesium.Color.GRAY.withAlpha(0.5); spcDataSource.entities.add({ name: `SPC Outlook: ${feature.name}`, polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray(feature.coordinates), material: color, outline: true, outlineColor: Cesium.Color.BLACK } }); }); console.log('SPC data source updated.'); } catch (error) { console.error('Error loading SPC data:', error); } }; const loadWeatherAlerts = async () => { try { console.log('Fetching weather alerts...'); const response = await fetch('api/weather_alerts.php'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const alertsData = await response.json(); console.log('Weather alerts fetched successfully.'); weatherAlertsDataSource.entities.removeAll(); if (alertsData.alerts) { alertsData.alerts.forEach(alert => { const alertColor = Cesium.Color.ORANGE.withAlpha(0.5); // The API provides polygons, so we need to handle them if (alert.geometry && alert.geometry.type === 'Polygon') { const coordinates = alert.geometry.coordinates[0].flat(); weatherAlertsDataSource.entities.add({ name: alert.properties.event || 'Weather Alert', description: alert.properties.description || 'No description available.', polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray(coordinates), material: alertColor, outline: true, outlineColor: Cesium.Color.BLACK } }); } }); } console.log('Weather alerts data source updated.'); } catch (error) { console.error('Error loading weather alerts:', error); } }; // Load all data sources loadWildfireData(); loadSpcData(); loadWeatherAlerts(); } catch (error) { console.error('A critical error occurred while initializing the Cesium viewer:', error); const cesiumContainer = document.getElementById('cesiumContainer'); cesiumContainer.innerHTML = '