vxe-table踩坑记录
2026/1/16 17:34:35
SampledPositionProperty深度解析与动态航线实现SampledPositionProperty核心定义与用途SampledPositionProperty是 Cesium 中用于描述随时间变化的三维位置属性的核心类,支持通过采样点插值生成平滑的动态轨迹。它通过存储多个时间戳对应的笛卡尔坐标,自动在时间区间内进行插值计算,实现位置的连续变化。
SampledPositionProperty使用方式| 方法/属性 | 功能 | 示例 |
|---|---|---|
new Cesium.SampledPositionProperty() | 创建空的位置属性 | const position = new Cesium.SampledPositionProperty(); |
addSample(time, position) | 添加时间-位置采样点 | position.addSample(Cesium.JulianDate.fromDate(new Date('2024-01-01T00:00:00Z')), Cesium.Cartesian3.fromDegrees(116.4, 39.9)); |
setInterpolationOptions(options) | 设置插值算法 | position.setInterpolationOptions({ interpolationDegree: 3, interpolationAlgorithm: Cesium.HermitePolynomialApproximation }); |
getValue(time) | 获取指定时间的位置 | const currentPos = position.getValue(Cesium.JulianDate.now()); |
// 初始化位置属性,使用埃尔米特插值(平滑带速度)constposition=newCesium.SampledPositionProperty();position.setInterpolationOptions({interpolationDegree:3,interpolationAlgorithm:Cesium.HermitePolynomialApproximation});// 添加采样点(时间+位置)conststartTime=Cesium.JulianDate.fromDate(newDate('2024-01-01T00:00:00Z'));position.addSample(startTime,Cesium.Cartesian3.fromDegrees(116.4,39.9,1000));position.addSample(Cesium.JulianDate.addSeconds(startTime,30,newCesium.JulianDate()),Cesium.Cartesian3.fromDegrees(116.5,39.95,1500));position.addSample(Cesium.JulianDate.addSeconds(startTime,60,newCesium.JulianDate()),Cesium.Cartesian3.fromDegrees(116.6,40.0,2000));// 步骤1:初始化Viewer与时间范围constviewer=newCesium.Viewer('cesiumContainer',{timeline:true,animation:true});conststartTime=Cesium.JulianDate.fromDate(newDate('2024-01-01T00:00:00Z'));constendTime=Cesium.JulianDate.addSeconds(startTime,60,newCesium.JulianDate());viewer.clock.startTime=startTime.clone();viewer.clock.stopTime=endTime.clone();viewer.clock.currentTime=startTime.clone();viewer.clock.multiplier=1;// 时间速度(1=真实速度)// 步骤2:创建SampledPositionProperty与采样点constpositionProperty=newCesium.SampledPositionProperty();positionProperty.setInterpolationOptions({interpolationAlgorithm:Cesium.HermitePolynomialApproximation,interpolationDegree:3});// 添加北京→天津→唐山的轨迹点positionProperty.addSample(startTime,Cesium.Cartesian3.fromDegrees(116.4,39.9,1000));positionProperty.addSample(Cesium.JulianDate.addSeconds(startTime,20,newCesium.JulianDate()),Cesium.Cartesian3.fromDegrees(117.2,39.1,1500));positionProperty.addSample(endTime,Cesium.Cartesian3.fromDegrees(118.1,39.6,2000));// 步骤3:创建动态航线实体constrouteEntity=viewer.entities.add({// 绑定动态位置属性position:positionProperty,// 航线样式:发光渐变线polyline:{width:4,material:newCesium.PolylineGlowMaterialProperty({glowPower:0.15,color:Cesium.Color.BLUE}),// 航线随时间增长(仅显示当前时间之前的轨迹)clampToGround:false,followSurface:false},// 飞机模型:随轨迹自动旋转方向model:{uri:'https://raw.githubusercontent.com/CesiumGS/cesium/master/Apps/SampleData/models/CesiumAir/Cesium_Air.gltf',scale:20,minimumPixelSize:128},// 自动计算模型朝向(沿轨迹前进方向)orientation:newCesium.VelocityOrientationProperty(positionProperty)});// 步骤4:添加轨迹点标记(可选)constpointEntity=viewer.entities.add({position:positionProperty,billboard:{image:'https://cesium.com/downloads/cesiumjs/releases/1.100/Build/Cesium/Widgets/Images/pin.png',scale:0.5,color:Cesium.Color.RED}});// 步骤5:缩放到航线范围viewer.zoomTo(routeEntity);SampledPositionProperty.fromArray()批量创建viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOPCesium.GeoJsonDataSource.load('https://raw.githubusercontent.com/cesiumjs/cesium/master/Apps/SampleData/ne_10m_us_states.topojson').then(dataSource=>{viewer.dataSources.add(dataSource);// 批量设置样式dataSource.entities.values.forEach(entity=>{entity.polygon.material=Cesium.Color.fromRandom({alpha:0.6});entity.polygon.outlineColor=Cesium.Color.WHITE;});}).catch(error=>console.error('加载失败:',error));// 初始化CZML数据源constczmlDataSource=newCesium.CzmlDataSource();viewer.dataSources.add(czmlDataSource);// 模拟实时推送数据(每2秒更新一次位置)setInterval(()=>{constnow=Cesium.JulianDate.now();constlon=116.4+Math.random()*0.1;constlat=39.9+Math.random()*0.1;// 增量添加CZML数据czmlDataSource.process([{id:'drone',position:{epoch:now.toIso8601(),cartesian:[0,Cesium.Cartesian3.toArray(Cesium.Cartesian3.fromDegrees(lon,lat,500))]}}]);},2000);then()或async/await处理,避免未加载完成就操作实体Cesium.Transforms转换Cesium.CzmlDataSource的增量加载,避免一次性加载所有数据dataSource.entities.suspendEvents()暂停事件监听,提升渲染性能dataSource.destroy()释放内存dataSource.entities.values批量设置样式,避免循环调用viewer.entities.add()dataSource.clampToGround统一设置所有实体贴地渲染constviewer=newCesium.Viewer('cesiumContainer',{// 加载Cesium Ion全球地形(需配置Ion Token)terrainProvider:Cesium.createWorldTerrain({requestVertexNormals:true,// 启用法线,支持光照效果requestWaterMask:true// 启用水面mask,实现真实水面渲染})});// 调整地形夸张(默认1,值越大地形起伏越明显)viewer.scene.globe.terrainExaggeration=2.0;// 启用大气散射效果viewer.scene.globe.showGroundAtmosphere=true;constterrainProvider=newCesium.CesiumTerrainProvider({url:'/terrain',// 本地地形服务地址(需部署Quantized Mesh格式地形)requestVertexNormals:true,requestWaterMask:false});viewer.scene.terrainProvider=terrainProvider;// 缩放到地形范围viewer.camera.setView({destination:Cesium.Cartesian3.fromDegrees(116.4,39.9,5000),orientation:{pitch:Cesium.Math.toRadians(-60)}});// 定义通视分析起点与终点conststartPosition=Cesium.Cartesian3.fromDegrees(116.4,39.9,1000);constendPosition=Cesium.Cartesian3.fromDegrees(116.5,39.95,1000);// 执行通视分析constvisibility=viewer.scene.globe.computeVisibilityBetweenPoints(startPosition,endPosition);console.log(`两点间是否可见:${visibility.visible}`);// 绘制通视线与遮挡点viewer.entities.add({polyline:{positions:[startPosition,endPosition],width:2,material:visibility.visible?Cesium.Color.GREEN:Cesium.Color.RED}});// 绘制遮挡点(若存在)if(!visibility.visible){viewer.entities.add({position:visibility.occlusionPoint,billboard:{image:'https://cesium.com/downloads/cesiumjs/releases/1.100/Build/Cesium/Widgets/Images/pin.png',color:Cesium.Color.RED}});}viewer.scene.globe.terrainOffset=newCesium.Cartesian3(0,0,10);// Z轴偏移10米requestWaterMask)可提升加载速度Cesium.Transforms转换地形数据