// Submarine cables — TeleGeography routes + landing points, bundled in // assets/cables/ (CC BY-NC-SA 3.0, © TeleGeography; see assets/README.md). // Static context like infra.js: no time dynamics, loaded once at boot. export default function create(ctx) { const { viewer, lib, ui, Cesium } = ctx; const ds = new Cesium.CustomDataSource('cables'); viewer.dataSources.add(ds); let enabled = true; ui.addLayer('cables', 'Submarine cables', true, (on) => { enabled = on; ds.show = on; }, 'Context'); ui.setStatus('cables', 'loading…', 'warn'); const CREDIT = '
© TeleGeography — submarinecablemap.com (CC BY-NC-SA 3.0). Routes are schematic.
'; // Landing-point labels only appear zoomed well in; the dots a bit earlier. const labelFade = new Cesium.NearFarScalar(2.0e5, 1.0, 1.2e6, 0.0); const dotFade = new Cesium.NearFarScalar(1.0e6, 1.0, 8.0e6, 0.0); async function load() { let cables, landings; try { [cables, landings] = await Promise.all([ fetch('assets/cables/cable-geo.json').then((r) => r.json()), fetch('assets/cables/landing-point-geo.json').then((r) => r.json()), ]); } catch (err) { ui.setStatus('cables', 'failed to load bundled data', 'err'); return; } let nCables = 0; for (const f of cables.features || []) { const g = f.geometry; if (!g || g.type !== 'MultiLineString') continue; const p = f.properties || {}; const color = lib.cz(p.color || '#5aa7d0', 0.85); const name = p.name || 'Submarine cable'; for (const line of g.coordinates) { if (!Array.isArray(line) || line.length < 2) continue; ds.entities.add({ name: `Cable — ${name}`, polyline: { positions: Cesium.Cartesian3.fromDegreesArray(line.flat()), width: 1.4, material: color, }, description: `${lib.escapeHtml(name)} — international submarine cable system.
` + CREDIT, }); } nCables++; } let nLandings = 0; for (const f of landings.features || []) { const g = f.geometry; if (!g || g.type !== 'Point') continue; const [lon, lat] = g.coordinates; if (!isFinite(lon) || !isFinite(lat)) continue; const name = (f.properties || {}).name || 'Landing point'; ds.entities.add({ name: `Landing — ${name}`, position: Cesium.Cartesian3.fromDegrees(lon, lat), point: { pixelSize: 4, color: lib.cz('#8fd8ff'), outlineColor: Cesium.Color.BLACK, outlineWidth: 1, translucencyByDistance: dotFade, disableDepthTestDistance: Number.POSITIVE_INFINITY, }, label: { text: name, font: '10px "Segoe UI", system-ui, sans-serif', fillColor: lib.cz('#8fd8ff'), outlineColor: Cesium.Color.fromCssColorString('#0a0f14'), outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -6), translucencyByDistance: labelFade, disableDepthTestDistance: Number.POSITIVE_INFINITY, }, description: `${lib.escapeHtml(name)} — cable landing point.
` + CREDIT, }); nLandings++; } ds.show = enabled; ui.setStatus('cables', `${nCables} cables · ${nLandings} landings`, 'ok'); } load(); return { id: 'cables' }; }