diff --git a/api/weather_alerts.php b/api/weather_alerts.php new file mode 100644 index 0000000..cfec368 --- /dev/null +++ b/api/weather_alerts.php @@ -0,0 +1,45 @@ + 'Polygon', + 'coordinates' => [ + [ + [-125.0, 24.0], + [-66.0, 24.0], + [-66.0, 49.0], + [-125.0, 49.0], + [-125.0, 24.0] + ] + ] +]; + +$locationJson = json_encode($location); +$apiKey = defined('OWM_API_KEY') ? OWM_API_KEY : ''; + +if (empty($apiKey)) { + echo json_encode(['error' => 'OpenWeatherMap API key not configured.']); + exit; +} + +$url = 'https://api.openweathermap.org/data/3.0/alerts?location=' . urlencode($locationJson) . '&appid=' . $apiKey; + +$ch = curl_init(); +curl_setopt($ch, CURLOPT_URL, $url); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); +curl_setopt($ch, CURLOPT_USERAGENT, 'FlatlogicCesiumApp'); + +$response = curl_exec($ch); +$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); +curl_close($ch); + +if ($httpcode !== 200) { + echo json_encode(['error' => 'Failed to fetch weather alerts.', 'http_code' => $httpcode, 'response' => $response]); + exit; +} + +echo $response; +?> \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index 8f318e5..b3a1ded 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -38,6 +38,28 @@ function initializeGlobe() { 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; + }); + // Function to load wildfire data const loadWildfireData = async () => { try { @@ -49,7 +71,7 @@ function initializeGlobe() { const geojsonData = await response.json(); console.log('Wildfire data fetched successfully.'); - const wildfireDataSource = new Cesium.GeoJsonDataSource(); + wildfireDataSource = new Cesium.GeoJsonDataSource(); await wildfireDataSource.load(geojsonData, { stroke: Cesium.Color.RED, fill: Cesium.Color.RED.withAlpha(0.5), @@ -64,8 +86,89 @@ function initializeGlobe() { } }; + 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); diff --git a/index.php b/index.php index a187236..d375c25 100644 --- a/index.php +++ b/index.php @@ -16,6 +16,15 @@ + + +