
曲线管道 ·Curve Pipe· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么Cesium Entity 高层实体 API效果说明本案例演示曲线管道效果基于 WebGL 实现「曲线管道」可视化效果附完整可运行源码核心用到 Cesium。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Viewer聚合 Scene、Camera、Clock 与渲染循环是 Cesium 应用入口。Entity面向点线面/模型/标签的高层 API与 Primitive 相比更适合交互与属性驱动。阅读下方完整源码时建议从init/load/animate三条主线入手再深入 shader 与工具函数。实现步骤创建 Viewer配置地形/影像若案例需要并设置初始相机在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as Cesium from cesiumimport { Color, defined, Event, Material, Property } from cesiumconst box document.getElementById(box)const viewer new Cesium.Viewer(box, {animation: false,//是否创建动画小器件左下角仪表baseLayerPicker: false,//是否显示图层选择器右上角图层选择按钮baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl(GLOBAL_CONFIG.getLayerUrl())),fullscreenButton: false,//是否显示全屏按钮右下角全屏选择按钮timeline: false,//是否显示时间轴infoBox: false,//是否显示信息框})viewer._cesiumWidget._creditContainer.style.display noneviewer.clock.shouldAnimate true//定位北京 viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(116.41, 36.91, 1000000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-90),roll: 0}})/飞线材质类/ class PolylineTrailLinkMaterialProperty {constructor(image, color Color.WHITE, duration 1000, repeat 60) {this._definitionChanged new Event()this._color undefinedthis.color colorthis.duration durationthis._time new Date().getTime()this.image imageMaterial._materialCache.addMaterial(PolylineTrailLink, {fabric: {type: PolylineTrailLink,uniforms: {color: color.withAlpha(1.0),image: image,time: 0,repeat},source:czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material czm_getDefaultMaterial(materialInput); vec2 st materialInput.st; vec4 sampledColor texture(image, vec2(fract(repeat*st.s - time), st.t)); material.alpha sampledColor.a * color.a; material.diffuse (sampledColor.rgb color.rgb) / 2.0; return material; }},translucent: () true})}get isConstant() { return false }get definitionChanged() { return this._definitionChanged }getType(_) { return PolylineTrailLink }getValue(time, result) {if (!defined(result)) result {}result.color Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color)result.image this.imageresult.time (new Date().getTime() - this._time) % this.duration / this.durationreturn result}equals(other) { return this other || Property.equals(this._color, other._color) }}// 生成一组飞线动画 [ [[116.41, 36.91], [130.40, 45.39]], [[116.41, 36.91], [114.11, 39.44]], [[116.41, 36.91], [109.62, 25.72]], [[116.41, 36.91], [121.48, 31.22]], [[116.41, 36.91], [13.78, 12.31]], [[116.41, 36.91], [74.12, 33.50]], ].forEach(([p1, p2]) createPlaneCurve(p1, p2))// 组合 function createPlaneCurve(p1, p2) {const { curvePoints } getGenerateCurve(p1, p2, { maxHeight: 100000 })viewer.entities.add({ polylineVolume: createCurvePipe(curvePoints)})}/生成曲线/ function getGenerateCurve(start, end, params {}) {const [startLongitude, startLatitude] startconst [endLongitude, endLatitude] endconst startCartographic Cesium.Cartographic.fromDegrees(startLongitude, startLatitude)const endCartographic Cesium.Cartographic.fromDegrees(endLongitude, endLatitude)const geodesic new Cesium.EllipsoidGeodesic(startCartographic, endCartographic)const curvePoints []for (let t 0; t 1; t (params.step || 0.01)) {const pointCartographic geodesic.interpolateUsingFraction(t)pointCartographic.height (params.maxHeight || 400000)Math.sin(Math.PIt)const pointCartesian Cesium.Cartographic.toCartesian(pointCartographic)curvePoints.push(pointCartesian)}endCartographic.height 0const endPointCartesian Cesium.Cartographic.toCartesian(endCartographic)curvePoints.push(endPointCartesian)function getCurvePointAtTime(t) {const pointCartographic geodesic.interpolateUsingFraction(t)pointCartographic.height (params.maxHeight || 400000)Math.sin(Math.PIt)return Cesium.Cartographic.toCartesian(pointCartographic)}return { curvePoints, getCurvePointAtTime }}function createCurvePipe(curvePoints, params {}) {const getShape (radius) {const positions [];for (let i 0; i 360; i) {if (i % 1 0) {const radians Cesium.Math.toRadians(i);positions.push(new Cesium.Cartesian2((radius / 2) * Math.cos(radians),(radius / 2) * Math.sin(radians)));}}return positions;}const radius 16000.0const _ps curvePoints.map(i {const [longitude, latitude, height] cartesian3ToDegrees(i)return Cesium.Cartesian3.fromDegrees(longitude, latitude, height - radius)})return {positions: _ps,shape: getShape(2 * radius),cornerType: Cesium.CornerType.ROUNDED,material: new PolylineTrailLinkMaterialProperty(FILE_HOST images/channels/lmap.png, Cesium.Color.RED, 2000)}}function cartesian3ToDegrees(cartesian3, type Array) {const cartographic Cesium.Cartographic.fromCartesian(cartesian3) // 笛卡尔坐标转经纬度const longitude Cesium.Math.toDegrees(cartographic.longitude) // 弧度转度const latitude Cesium.Math.toDegrees(cartographic.latitude) // 弧度转度const height cartographic.height // 高度return type Array ? [longitude, latitude, height] : { longitude, latitude, height }}完整源码GitHub小结本文提供曲线管道完整 Cesium.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Cesium.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库