Cesium 实战 - OD 通信线 - 移动连接线
- OD 通信线 - 移动连接线核心代码
- 完整代码
- 在线示例
在项目中,实现完卫星通信线之后,又有一个新需求,需要通信线根据火箭移动而移动,相当于追踪效果,思考之后通过 Entity CallbackProperty
实现。
实际上是通过自定义材质类,通过着色器代码实现。
本文包含移动连接线核心代码、完整代码以及在线示例三部分。
OD 通信线 - 移动连接线核心代码
// 获取火箭模型实体
const entity = dataSource.entities.getById("Vulcan");// 模型视角跟随
viewer.trackedEntity = entity;// 设置观察角度
entity.viewFrom = new Cesium.Cartesian3(-1000, 100,-1000);// 添加通信线
viewer.entities.add({polyline: {// 回调更新连接线.positions: new Cesium.CallbackProperty(function (time, result) {const position1 = entity.position.getValue(time);return [position,position1];}, false),width: 5,material: new SatelliteMaterialProperty({color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),speed: 50,count: 10,gradient: 0.2}),},
});
完整代码
<!DOCTYPE html>
<html lang="en">
<head><!-- Use correct character set. --><meta charset="utf-8"/><!-- Tell IE to use the latest, best version. --><meta http-equiv="X-UA-Compatible" content="IE=edge"/><!-- Make the application on mobile take up the full browser screen and disable user scaling. --><metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/><title>Cesium dynamic line</title><script src="http://openlayers.vip/examples/csdn/Cesium.js"></script><script src="./cesium_init.js"></script><script src="http://www.openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script><style>@import url(./Widgets/widgets.css);html,body,#cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}</style><script>var _hmt = _hmt || [];(function () {var hm = document.createElement("script");hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";var s = document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm, s);})();</script>
</head>
<body>
<div id="cesiumContainer"></div>
<script>// 创建三维球const viewer = init();// 火箭模拟发射数据const czml = [{"id": "document","name": "SpaceX","version": "1.0","clock": {"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z","currentTime": "2023-06-14T10:00:00Z","multiplier": 10,"range": "CLAMPED","step": "SYSTEM_CLOCK_MULTIPLIER"}},{"id": "Vulcan","availability": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z","name": "Vulcan","billboard": {"show": true,"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAjSURBVChTYyAa/EcDUGEIgIphAKg0XRSAAFQMDqDChAADAwDC13+BJ+0oDwAAAABJRU5ErkJgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","scale": 1,"pixelOffset": {"cartesian2": [0, 0]},"eyeOffset": {"cartesian": [0, 0, 0]},"horizontalOrigin": "CENTER","verticalOrigin": "CENTER","color": [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z","rgba": [0, 255, 0, 255]},{"interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z","rgba": [255, 255, 0, 255]},{"interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z","rgba": [255, 0, 255, 255]}]},"label": {"show": false,"text": "Vulcan","font": "21pt Lucida Console","style": "FILL_AND_OUTLINE","scale": 0.5,"pixelOffset": {"cartesian2": [5, -4]},"horizontalOrigin": "LEFT","verticalOrigin": "CENTER","fillColor": [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z","rgba": [0, 255, 0, 255]},{"interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z","rgba": [255, 255, 0, 255]},{"interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z","rgba": [255, 0, 255, 255]}],"outlineColor": {"rgba": [0, 0, 0, 255]},"outlineWidth": 2},"path": {"show": [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z","boolean": true}],"width": 5,"resolution": 1,"leadTime": [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z","epoch": "2023-06-14T10:00:00Z","number": [0, 1053,1053, 0]}],"trailTime": [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z","epoch": "2023-06-14T10:00:00Z","number": [0, 0,1053, 1053]}],"material": {polylineGlow: {color: [{"interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z",rgba: [255, 0, 0, 255],},{"interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z",rgba: [0, 0, 255, 255],},{"interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z",rgba: [255, 0, 255, 255],}],glowPower: 0.25,// taperPower: 0.5,},},},"model": {"show": true,"gltf": [{"interval": "2023-06-14T10:00:00Z/9999-12-31T23:59:59.9999999Z","uri": "https://cesium.com/public/SandcastleSampleData/launchvehicle.glb"}],"minimumPixelSize": 128,"scale": 3,"runAnimations": false,},"position": {"interpolationAlgorithm": "LAGRANGE","interpolationDegree": 2,"referenceFrame": "FIXED","epoch": "2023-06-14T10:00:00Z","cartesian": [0.000, -2174195.199042614, 4389988.019058515, 4070606.7900844226,250.000, -2828836.74243954, 4527941.384141082, 4322899.592600973,750.000, -3812052.7676919936, 3910960.7948377975, 4168079.0591541207,1053.000, -3929362.40133975, 3277792.786767426, 3795371.463871257,]},"orientation": {"velocityReference": "#position"},},];// 添加火箭车const launchCar = viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(127.69435837574487,38.808381761124146,0.0),model: {uri: "https://openlayers.vip/examples/resources/model/car.glb",scale: 3.0,minimumPixelSize: 128},});const clock = viewer.clock;// 获取当前时刻位置const position = launchCar.position.getValue(clock.currentTime);const dataSourcePromise = viewer.dataSources.add(Cesium.CzmlDataSource.load(czml));dataSourcePromise.then(function (dataSource) {// 获取火箭模型实体const entity = dataSource.entities.getById("Vulcan");// 模型视角跟随viewer.trackedEntity = entity;// 设置观察角度entity.viewFrom = new Cesium.Cartesian3(-1000, 100,-1000);// 添加通信线viewer.entities.add({polyline: {// 回调更新连接线.positions: new Cesium.CallbackProperty(function (time, result) {const position1 = entity.position.getValue(time);return [position,position1];}, false),width: 5,material: new SatelliteMaterialProperty({color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),speed: 50,count: 10,gradient: 0.2}),},});viewer.zoomTo(viewer.entities);}).catch(function (error) {console.error(error);});/*** @description:卫星通信材质* @date: 2023年6月17日10:43:18*/function SatelliteMaterialProperty(options) {// 默认参数设置this._definitionChanged = new Cesium.Event();this.color = options.color;}Object.defineProperties(SatelliteMaterialProperty.prototype, {isConstant: {get: function() {return false;}},definitionChanged: {get: function() {return this._definitionChanged;}},color: Cesium.createPropertyDescriptor('color')});SatelliteMaterialProperty.prototype.getType = function(time) {return 'SatelliteMaterial';};SatelliteMaterialProperty.prototype.getValue = function(time, result) {if (!Cesium.defined(result)) {result = {};}result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);viewer.scene.requestRender();return result;};SatelliteMaterialProperty.prototype.equals = function(other) {return this === other ||(other instanceof SatelliteMaterialProperty &&Cesium.Property.equals(this._color, other._color));};Cesium.Material.SatelliteType = 'SatelliteMaterial';Cesium.Material.SatelliteSource = `uniform vec4 color;uniform float speed;uniform float percent;uniform float gradient;uniform float count;czm_material czm_getMaterial(czm_materialInput materialInput){czm_material material = czm_getDefaultMaterial(materialInput);vec2 st = materialInput.st;float t =fract(czm_frameNumber * speed / 1000.0);float v = 1.0-(1.0-smoothstep(gradient,0.0,fract(st.x*count-t)))*0.95;material.diffuse = color.rgb/10.0 + vec3(v)*9.0;material.alpha = color.a;return material;}`;Cesium.Material._materialCache.addMaterial(Cesium.Material.SatelliteType, {fabric: {type: Cesium.Material.SatelliteType,uniforms: {color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),speed: 30.0,gradient: 0.2,count: 15,},source: Cesium.Material.SatelliteSource},translucent: function(material) {return true;}});</script>
</body>
</html>
示例创建小车模型以及火箭发射,模拟小车追踪火箭通信效果。
在线示例
Cesium OD 通信线 - 移动连接线