import * as Cesium from 'cesium' // id generator export function uid(prefix) { const p = prefix || 'id' return p + ':' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 7) } // angle helpers export const toRad = Cesium.Math.toRadians // color normalization export function toCesiumColor(input, alpha) { const a = typeof alpha === 'number' ? alpha : 1 if (!input) return Cesium.Color.WHITE.withAlpha(a) if (input instanceof Cesium.Color) return input.withAlpha(a) if (typeof input === 'string') return Cesium.Color.fromCssColorString(input).withAlpha(a) if (Array.isArray(input)) { const r = input[0] || 1, g = input[1] || 1, b = input[2] || 1, al = input[3] || a return new Cesium.Color(r, g, b, al) } return Cesium.Color.WHITE.withAlpha(a) } // coordinate conversions export function degToCartesian(arr) { return Cesium.Cartesian3.fromDegrees(arr[0], arr[1], arr[2] || 0) } export function degsToCartesians(positions) { return (positions || []).map(degToCartesian) } export function cartesianToDegrees(cartesian) { const c = Cesium.Cartographic.fromCartesian(cartesian) return { lon: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude), height: c.height || 0, } } // simple zoom-height heuristic const EARTH = 40075016.68557849 const TILE = 256 export function heightToZoom(height, lat) { const la = typeof lat === 'number' ? lat : 0 const z = Math.log2((EARTH * Math.cos(toRad(la))) / (TILE * Math.max(height || 1, 1))) + 8 return Math.max(0, z) } export function zoomToHeight(zoom, lat) { const la = typeof lat === 'number' ? lat : 0 const h = (EARTH * Math.cos(toRad(la))) / (TILE * Math.pow(2, Math.max((zoom || 0) - 8, 0))) return Math.max(1, h) } export const DEFAULT_VECTOR_LAYER_ID = 'vector:default'