/* * @Descripttion: * @version: 1.0 * @Author: zhangti * @Date: 2019-09-20 09:32:20 * @LastEditors : sueRimn * @LastEditTime : 2020-01-02 12:12:49 */ /** * 动态画实体 */ export default class entityFactory{ constructor(obj){ //初始化 this.options = null; switch(obj.type){ case 'triangleMeasure':this.createTriangleMeasure(obj.data);break; case 'createLine' :this.createLine(obj.data);break; case 'dynamicCylinder' :this.dynamicCylinder(obj.data);break; case 'createPolygon' :this.createPolygon(obj.data);break; case 'createScan' :this.createScan(obj.data);break; } return this.options; } /** * 动态创建三角形 * 应用于 三角测量 * @param {*} poly */ createTriangleMeasure(poly){ this.options = { name: poly.name, polyline: { show: true, positions: [], material: Cesium.Color.GOLD, width: 2 }, label: { font: '18px sans-serif', fillColor: Cesium.Color.GOLD, style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth: 2, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: poly.label.offset } }; this.positions = poly.positions; this.label = poly.label; //实时更新polygon.hierarchy var _self = this; var _update = function () { return _self.positions; }; var _update_label = function () { if(_self.positions.length == 1) return false; return _self.positions[1]; }; var _text = function () { if(typeof _self.label.fn == 'function'){ //fn 转换函数 scaler 换算 unit 单位 var text_temp = _self.label.fn(_self.positions); text_temp = poly.name + ' : ' + (text_temp / _self.label.scaler).toFixed(3) + ' ('+_self.label.unit +')'; return text_temp; } }; this.options.polyline.positions = new Cesium.CallbackProperty(_update, false); this.options.position = new Cesium.CallbackProperty(_update_label, false); this.options.label.text = new Cesium.CallbackProperty(_text, false); } /** * 动态创建直线 * @param {*} positions */ createLine(opt){ this.options = { name: '直线', polyline: { show: true, positions: [], material: opt.material == undefined ? Cesium.Color.CHARTREUSE : opt.material, width: opt.width == undefined ? 5 : opt.width, clampToGround:opt.clampToGround == undefined ? false : true //贴地 } }; this.positions = opt.positions; //实时更新polyline.positions var _self = this; var _update = function () { return _self.positions; }; this.options.polyline.positions = new Cesium.CallbackProperty(_update, false); } /** * 动态绑定柱体 * 应用于 卫星过境 无人机 * 扫描 * @param {*} obj */ dynamicCylinder(obj){ let c = obj.cylinder; this.options = { cylinder: { HeightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, //表示相对于地形的位置。 length: c.length, //长度 topRadius:0, //顶点半径 bottomRadius:c.bottomRadius, //底部半径 material:new Cesium.Color(0, 1, 1, .4), slices:c.slices } } this.positions = obj.positions; this.entity = obj.entity; this.v = obj.v; var _self = this; var _update = function(){ var positions = _self.entity.position.getValue(_self.v.clock.currentTime); var cartographic = _self.v.scene.globe.ellipsoid.cartesianToCartographic(positions); var lat = Cesium.Math.toDegrees(cartographic.latitude) , lng = Cesium.Math.toDegrees(cartographic.longitude) ,hei = parseFloat(cartographic.height/4); return Cesium.Cartesian3.fromDegrees(lng, lat,0); }; var _length = function(){ var positions = _self.entity.position.getValue(_self.v.clock.currentTime); var cartographic = _self.v.scene.globe.ellipsoid.cartesianToCartographic(positions); return cartographic.height * 2; } this.options.position = new Cesium.CallbackProperty(_update,false); this.options.cylinder.length = new Cesium.CallbackProperty(_length,false); } /** * 动态创建多边形 * 应用 面积量测 淹没分析 * @param {*} positions */ createPolygon(obj){ try { this.options = { name:'多边形', polygon : { hierarchy : [], // perPositionHeight : true, material : obj.material == undefined ? Cesium.Color.CHARTREUSE.withAlpha(0.3):obj.material, //Cesium.Color.CHARTREUSE.withAlpha(0.5) // heightReference:20000 } }; this.hierarchy = obj.positions; let _self = this; let _update = function(){ return new Cesium.PolygonHierarchy(_self.hierarchy); }; //实时更新polygon.hierarchy this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update,false); } catch (error) { console.log(error); } } /*** * 创建扫描实体 * opt.v * opt.positions * positions{lat,lon,alt} */ createScan(opt){ let _self = this,viewer= opt.v,length = opt.positions.alt; _self.modelMatrix = opt.modelMatrix; // 4 创建雷达放射波 var cylinderGeometry = new Cesium.CylinderGeometry({ // 4.1 先创建Geometry length:length, topRadius: 0.0, bottomRadius: length * 0.5, //vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat }); var redCone = new Cesium.GeometryInstance({ // 4.2 创建GeometryInstance geometry: cylinderGeometry, modelMatrix:_self.modelMatrix, // attributes : { // color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED) // } }); var radar = viewer.scene.primitives.add(new Cesium.Primitive({// 4.3 创建Primitive geometryInstances: [redCone], // appearance : new Cesium.PerInstanceColorAppearance({ // closed : true, // translucent: false // }) appearance: new Cesium.MaterialAppearance({ // 贴图像纹理 // material: Cesium.Material.fromType('Image', { // image: '../../SampleData/models/CesiumBalloon/CesiumBalloonPrint_singleDot.png' // }), // 贴棋盘纹理 // material: Cesium.Material.fromType('Checkerboard'), // 自定义纹理 material: new Cesium.Material({ fabric: { type: 'VtxfShader1', uniforms: { color: new Cesium.Color(0.2, 1.0, 0.0, 1.0), repeat: 30.0, offset: 0.0, thickness: 0.3, }, source: ` uniform vec4 color; uniform float repeat; uniform float offset; uniform float thickness; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); float sp = 1.0/repeat; vec2 st = materialInput.st; float dis = distance(st, vec2(0.5)); float m = mod(dis + offset, sp); float a = step(sp*(1.0-thickness), m); material.diffuse = color.rgb; material.alpha = a * color.a; return material; } ` }, translucent: false }), faceForward : false, // 当绘制的三角面片法向不能朝向视点时,自动翻转法向,从而避免法向计算后发黑等问题 closed: true // 是否为封闭体,实际上执行的是是否进行背面裁剪 }), })); // 5 动态修改雷达材质中的offset变量,从而实现动态效果。 viewer.scene.preUpdate.addEventListener(function() { var offset = radar.appearance.material.uniforms.offset; offset -= 0.001; if (offset > 1.0) { offset = 0.0; } radar.appearance.material.uniforms.offset = offset; }) let _update = function(){ return _self.modelMatrix; } radar.modelMatrix = new Cesium.CallbackProperty(_update,true); return radar; } /** * 创建移动扫描物 * createLightScan var data={ circle:[0.003,117,35,30]// 第一个参数 0.003表示半径,第二个第三个分别表示底座圆心的坐标,第四个表示切割成多少个点。组成多少个面。越多会越卡 尽量实际项目不影响效果,越少越好。 ,observer:[117.01,35.01,500]//观察点,也就是光源点 ,positionList:[ //我们这里就不加高度了。不然太麻烦了 //以圆心为参考做偏移值获取,圆心坐标 [117,35],简单点画个正方形吧 如果画圆的画,也可以多取点 [117,35],//初始位置 (圆心坐标 [117,35]要和这个初始位置统一,不然会偏移出去) [117.01,35], //下一个点 [117.01,35.01], [117,35.01], [117,35],//回来 ] ,material:Cesium.Color.RED.withAlpha(0.5)//光的材质 ,number:100//数字越小速度越快 }; */ static createLightScan(opt){ let viewer = opt.v, data = opt.data; let point = LightScanHelps.createLightScan_getCirclePoints(data.circle[0],data.circle[1],data.circle[2],data.circle[3]); //生成分割点 let entityCList =LightScanHelps.createLightScan_entityCList(viewer,point,data); //生成 entityCList 圆锥 LightScanHelps.createLightScan_changeAllPosition(data,entityCList,point); //运行 return entityCList; } /** * 灯光随着模型变化 * 模型需要播放动画 * czml * @param {*} viewer * @param {*} data * @param {*} model */ static createLightScanFollowEntity(opt){ let viewer = opt.v, data = opt.data, model = opt.model; let point = LightScanHelps.createLightScan_getCirclePoints(data.circle[0],data.circle[1],data.circle[2],data.circle[3]); //生成分割点 let entityCList=LightScanHelps.createLightScan_entityCList(viewer,point,data); //生成 entityCList 圆锥 viewer.scene.postRender.addEventListener(function () { // 实时获取模型的经纬度。 let center =model.position.getValue(viewer.clock.currentTime);//获取模型当前位置 //世界坐标(笛卡尔坐标) if(center){ let ellipsoid=viewer.scene.globe.ellipsoid; let cartographic=ellipsoid.cartesianToCartographic(center); let lon=Cesium.Math.toDegrees(cartographic.longitude); let lat=Cesium.Math.toDegrees(cartographic.latitude); //var height=cartographic.height; //console.log(lon+";"+lat+";"+height); let X0=lon-data.circle[1],Y0=lat-data.circle[2]; //差值 for(let i=0;i=Math.abs(x))&&(Math.abs(Y0)>=Math.abs(y))){ //当等分差值大于等于差值的时候 就重新计算差值和等分差值 Math.abs n=n+1; if(n==positionList.length-1){ n=0; } arr[0]= arr[0]+X0; arr[1]= arr[1]+Y0; arr[2]= arr[2]+X0; arr[3]= arr[3]+Y0; f(n);//重新赋值 x y x0 y0 } X0=a*x0;//将差值的等份逐渐递增。直到大于差值 会有精度丢失,所以扩大再加 x0=x0+0.0001 Y0=a*y0;//将差值的等份逐渐递增。直到大于差值 会有精度丢失,所以扩大再加 a++; return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights( [ data.observer[0],data.observer[1],data.observer[2], arr[0]+X0,arr[1]+Y0,0, arr[2]+X0,arr[3]+Y0,0 ])) },false) } }