// Infrastructure overlay (SPEC §6.5): static vector context for the theater — // maritime choke points, major oil pipelines, and key facilities. No time // dynamics. All coordinates are approximate and every description says so. export default function create(ctx) { const { viewer, CONFIG, lib, ui, Cesium } = ctx; const C = CONFIG.colors; const infraDS = new Cesium.CustomDataSource('infra'); viewer.dataSources.add(infraDS); const ents = infraDS.entities; const APPROX = 'Location approximate — illustrative reference geometry, not survey-grade.'; // Shared label defaults: readable at range, fades in as you zoom. const labelBase = { font: '12px "Segoe UI", system-ui, sans-serif', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.fromCssColorString('#0a0f14'), outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, disableDepthTestDistance: 50000, translucencyByDistance: new Cesium.NearFarScalar(2.0e6, 1.0, 1.2e7, 0.0), }; // ---- choke points: red ring + label ---- const chokepoints = [ { name: 'Strait of Hormuz', lon: 56.5, lat: 26.6 }, { name: 'Bab el-Mandeb', lon: 43.33, lat: 12.58 }, { name: 'Suez Canal', lon: 32.35, lat: 30.45 }, { name: 'Strait of Malacca', lon: 101.0, lat: 2.5 }, ]; for (const cp of chokepoints) { ents.add({ name: `Choke point — ${cp.name}`, position: Cesium.Cartesian3.fromDegrees(cp.lon, cp.lat), ellipse: { semiMajorAxis: 80000, semiMinorAxis: 80000, material: Cesium.Color.fromCssColorString('rgba(255,0,60,1)').withAlpha(0.06), outline: true, outlineColor: lib.cz(C.chokepoint), height: 0, }, label: { ...labelBase, text: cp.name, fillColor: lib.cz(C.chokepoint), pixelOffset: new Cesium.Cartesian2(0, -6), }, description: `
Maritime choke point.
` + `${cp.name} — a strategic strait for global energy and trade flows.
` + `${APPROX} The ring is a fixed ~80 km radius marker, not the true channel.
`, }); } // ---- pipelines: amber dashed polylines clamped to ground + midpoint label ---- const pipelines = [ { name: 'East–West (Petroline) crude pipeline', note: 'Abqaiq → Yanbu', coords: [49.68, 25.94, 46.7, 24.6, 44.5, 24.3, 41.5, 24.2, 38.06, 24.09], }, { name: 'Habshan–Fujairah crude pipeline', note: 'bypasses the Strait of Hormuz', coords: [53.61, 23.75, 54.6, 24.2, 55.5, 24.8, 56.33, 25.12], }, ]; for (const pl of pipelines) { ents.add({ name: `Pipeline — ${pl.name}`, polyline: { positions: Cesium.Cartesian3.fromDegreesArray(pl.coords), width: 2, clampToGround: true, material: new Cesium.PolylineDashMaterialProperty({ color: lib.cz(C.pipeline) }), }, description: `Oil pipeline. ${pl.note}.
` + `${pl.name}.
` + `${APPROX} The route is a simplified schematic between endpoints.
`, }); // Midpoint label at the middle vertex of the schematic route. const mid = pipelineMidpoint(pl.coords); ents.add({ name: `${pl.name} (label)`, position: Cesium.Cartesian3.fromDegrees(mid[0], mid[1]), label: { ...labelBase, text: pl.name, fillColor: lib.cz(C.pipeline) }, }); } // ---- facilities: small square markers + type-annotated labels ---- const facilities = [ { name: 'Ras Tanura', type: 'oil terminal', lon: 50.16, lat: 26.64 }, { name: 'Abqaiq', type: 'oil processing plant', lon: 49.68, lat: 25.94 }, { name: 'Yanbu', type: 'port / oil terminal', lon: 38.06, lat: 24.09 }, { name: 'Kharg Island', type: 'oil export terminal', lon: 50.32, lat: 29.23 }, { name: 'Fujairah', type: 'oil terminal', lon: 56.37, lat: 25.18 }, { name: 'Jebel Ali', type: 'desalination plant', lon: 55.02, lat: 25.01 }, { name: 'Ras Al-Khair', type: 'desalination plant', lon: 49.19, lat: 27.55 }, { name: 'Al Udeid', type: 'air base', lon: 51.32, lat: 25.12 }, { name: 'Haifa', type: 'refinery', lon: 35.05, lat: 32.79 }, ]; const squareGlyph = facilitySquare(Cesium, C.facility); for (const f of facilities) { ents.add({ name: `Facility — ${f.name} ${f.type}`, position: Cesium.Cartesian3.fromDegrees(f.lon, f.lat), billboard: { image: squareGlyph, width: 9, height: 9, disableDepthTestDistance: 50000, }, label: { ...labelBase, text: f.name, fillColor: lib.cz(C.facility), pixelOffset: new Cesium.Cartesian2(0, -8), }, description: `${f.name} — ${f.type}.
` + `${APPROX}
`, }); } // ---- HUD row + status ---- ui.addLayer('infra', 'Infrastructure', true, (on) => { infraDS.show = on; }); ui.setStatus( 'infra', `${chokepoints.length} choke points · ${pipelines.length} pipelines · ${facilities.length} facilities`, 'ok', ); return { id: 'infra' }; } // Geographic midpoint = the middle vertex of the route's [lon,lat,...] array. function pipelineMidpoint(coords) { const n = coords.length / 2; const i = Math.floor(n / 2) * 2; return [coords[i], coords[i + 1]]; } // Tiny filled square canvas for facility markers (billboard image). function facilitySquare(Cesium, hex) { const s = 16; const c = document.createElement('canvas'); c.width = s; c.height = s; const g = c.getContext('2d'); g.fillStyle = hex; g.strokeStyle = '#0a0f14'; g.lineWidth = 2; g.fillRect(2, 2, s - 4, s - 4); g.strokeRect(2, 2, s - 4, s - 4); return c; }