211 lines
8.9 KiB
JavaScript
211 lines
8.9 KiB
JavaScript
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 = '<div class="alert alert-danger">Error: Could not load the 3D scene. Please check the console for details.</div>';
|
|
}
|
|
}
|
|
|
|
function waitForCesium() {
|
|
if (typeof Cesium !== 'undefined') {
|
|
initializeGlobe();
|
|
} else {
|
|
console.log('Waiting for Cesium to load...');
|
|
setTimeout(waitForCesium, 100);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', waitForCesium);
|