/** * @description 水面 */ import Dialog from '../../Element/Dialog'; import { html } from "./_element"; import EventBinding from '../../Element/Dialog/eventBinding'; import Base from "../index"; import { syncData } from '../../../Global/MultiViewportMode' import DrawRect from '../../../Draw/drawRect' import drawPolygon from '../../../Draw/drawPolygon' import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen' import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../Global/global' import FlowLineMaterialProperty from "../../Materail/FlowLineMaterialProperty"; class FlowLine extends Base { /** * @constructor * @param sdk * @description 流光飞线 * @param options {object} 流光飞线属性 * @param options.name=未命名对象 {string} 名称 * @param options.pointNumber=300 {number} 线数量 * @param options.height=200 {number} 线高度 * @param options.heightDifference=3000 {number} 线高度差 * @param options.width=2 {number} 线宽 * @param options.duration=10.0 {number} 单次运动时间 * @param options.color=rgba(255,255,255,1) {string} 颜色 * @param options.lineBackAlpha=0.05 {number} 轨迹颜色(不能为0) * @param Dialog {object} 弹框对象 * @param Dialog.confirmCallBack {function} 弹框确认时的回调 * */ constructor(sdk, options = {}, _Dialog = {}) { super(sdk, options); this.viewer = this.sdk.viewer this.options.name = options.name || '飞线' this.options.pointNumber = options.pointNumber || 200 this.options.height = options.height || 200 this.options.heightDifference = options.heightDifference || 3000 this.options.width = options.width || 2 this.options.duration = options.duration || 10.0 this.options.color = options.color || "rgba(255,255,255,1)" this.options.lineBackAlpha = options.lineBackAlpha || 0.05 this.options.show = (options.show || options.show === false) ? options.show : true this.Dialog = _Dialog this._EventBinding = new EventBinding() this._elms = {}; this.positionArea = [] this.positions = [] this.sdk.addIncetance(this.options.id, this) FlowLine.create(this) } // 创建水面 static create(that) { // let Draw = new DrawRect(that.sdk) // Draw.start((a, positions) => { // that.positions = positions // that.getLine(that, that.positions) // that.edit(true) // }) let Draw = new drawPolygon(that.sdk) Draw.start((a, positions) => { that.positionArea = positions let posis = that.getRandomPointsInCesiumPolygon(positions, that.options.pointNumber) that.positions = posis that.getLine(that, posis) that.edit(true) }) } getRandomPointsInCesiumPolygon(positions, count) { let lons = [], lats = [], posi = [] positions.forEach(item => { lons.push(item.lng) lats.push(item.lat) posi.push([item.lng, item.lat]) }) posi.push([posi[0][0], posi[0][1]]) const minLon = Math.min(...lons), maxLon = Math.max(...lons); const minLat = Math.min(...lats), maxLat = Math.max(...lats); const points = []; while (points.length < count) { const lon = minLon + Math.random() * (maxLon - minLon); const lat = minLat + Math.random() * (maxLat - minLat); // const cartesian = Cesium.Cartesian3.fromDegrees(lon, lat); let point = turf.point([lon, lat]); const polygon = turf.polygon([ posi ]); const isInside = turf.booleanPointInPolygon(point, polygon); if (isInside) { points.push([ lon, lat ]); } } return points; } getLine(that, positions) { let num = 0 let celiangEntity = null if (that.viewer.entities.getById(that.options.id)) { that.viewer.entities.getById(that.options.id)._children.forEach((item) => { that.viewer.entities.remove(item); }); that.viewer.entities.remove(that.viewer.entities.getById(that.options.id)) } celiangEntity = that.viewer.entities.add(new Cesium.Entity({ id: that.options.id, show: that.options.show })) positions.forEach((item, index) => { let point = item //根据点设置起始点位置 let start = Cesium.Cartesian3.fromDegrees(point[0], point[1], 0) //根据点设置结束点位置 let end = Cesium.Cartesian3.fromDegrees(point[0], point[1], that.options.height + Math.random() * that.options.heightDifference) //创建线 that.viewer.entities.add({ parent: celiangEntity, polyline: { positions: [start, end], width: 2, // material:Cesium.Color.RED material: new Cesium.FlowLineMaterialProperty({ color: that.options.color, duration: that.options.duration, lineBackAlpha: that.options.lineBackAlpha, num: num }) } }) }); } get color() { return this.options.color } set color(v) { this.options.color = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { entity._children.forEach(item => { item.polyline.material.color = Cesium.Color.fromCssColorString(v) }) } if (this._elms.color) { this._elms.color.forEach((item, i) => { let picker = new ewPlugins('colorpicker', { el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: v, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (c) => { this.color = c },//点击确认按钮事件回调 clear: () => { this.color = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.color[i] = picker }) } } get pointNumber() { return this.options.pointNumber } set pointNumber(v) { this.options.pointNumber = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { let posis = this.getRandomPointsInCesiumPolygon(this.positionArea, this.options.pointNumber) this.positions = posis this.getLine(this, posis) } } get height() { return this.options.height } set height(v) { this.options.height = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { this.getLine(this, this.positions) } } get heightDifference() { return this.options.heightDifference } set heightDifference(v) { this.options.heightDifference = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { this.getLine(this, this.positions) } } get width() { return this.options.width } set width(v) { this.options.width = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { entity._children.forEach(item => { item.polyline.width = v }) } } get duration() { return this.options.duration } set duration(v) { this.options.duration = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { entity._children.forEach(item => { item.polyline.material.duration = v }) } } get lineBackAlpha() { return this.options.lineBackAlpha } set lineBackAlpha(v) { this.options.lineBackAlpha = v let entity = this.viewer.entities.getById(this.options.id) if (entity) { entity._children.forEach(item => { item.polyline.material.lineBackAlpha = v }) } } /** * @description 编辑框 * @param state=false {boolean} 状态: true打开, false关闭 */ async edit(state = false) { let _this = this this.originalOptions = this.deepCopyObj(this.options) // let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog') // for (let i = elms.length - 1; i >= 0; i--) { // this.sdk.viewer._container.removeChild(elms[i]) // } if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } if (state) { this._DialogObject = await new Dialog(this.sdk, this.originalOptions, { title: '飞线属性', left: '180px', top: '100px', confirmCallBack: (options) => { this.name = this.name.trim() if (!this.name) { // this.name = '未命名对象' this.name = '飞线' } this.originalOptions = this.deepCopyObj(this.options) this._DialogObject.close() this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions) syncData(this.sdk, this.options.id) syncSplitData(this.sdk, this.options.id) }, resetCallBack: () => { this.reset() this.Dialog.resetCallBack && this.Dialog.resetCallBack() }, // removeCallBack: () => { // this.Dialog.removeCallBack && this.Dialog.removeCallBack() // }, closeCallBack: () => { this.reset() // this.entity.style = new Cesium.Cesium3DTileStyle({ // color: "color('rgba(255,255,255," + this.newData.transparency + ")')", // show: true, // }); this.Dialog.closeCallBack && this.Dialog.closeCallBack() }, showCallBack: (show) => { this.show = show this.Dialog.showCallBack && this.Dialog.showCallBack() } }, true) this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' flow-line-surface' let contentElm = document.createElement('div'); contentElm.innerHTML = html() this._DialogObject.contentAppChild(contentElm) // 颜色组件 let waterColorPicker = new ewPlugins('colorpicker', { el: contentElm.getElementsByClassName("flowLine-color")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.color, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.color = color },//点击确认按钮事件回调 clear: () => { this.color = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) let all_elm = contentElm.getElementsByTagName("*") this._EventBinding.on(this, all_elm) this._elms = this._EventBinding.element this._elms.color = [waterColorPicker] } else { // if (this._element_style) { // document.getElementsByTagName('head')[0].removeChild(this._element_style) // this._element_style = null // } // if (this._DialogObject && this._DialogObject.remove) { // this._DialogObject.remove() // this._DialogObject = null // } } } reset() { if (!this.viewer.entities.getById(this.options.id)) { return } this.name = this.originalOptions.name this.pointNumber = this.originalOptions.pointNumber this.height = this.originalOptions.height this.heightDifference = this.originalOptions.heightDifference this.width = this.originalOptions.width this.duration = this.originalOptions.duration this.color = this.originalOptions.color this.lineBackAlpha = this.originalOptions.lineBackAlpha } /** * 飞到对应实体 */ async flyTo(options = {}) { setActiveViewer(0) closeRotateAround(this.sdk) closeViewFollow(this.sdk) if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) { let orientation = { heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0), pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0), roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0) } let lng = this.options.customView.relativePosition.lng let lat = this.options.customView.relativePosition.lat let alt = this.options.customView.relativePosition.alt let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) let position = { lng: 0, lat: 0 } if (this.options.position) { position = { ...this.options.position } } else if (this.options.positions) { position = { ...this.options.positions[0] } } else if (this.options.center) { position = { ...this.options.center } } else if (this.options.start) { position = { ...this.options.start } } else { if (this.options.hasOwnProperty('lng')) { position.lng = this.options.lng } if (this.options.hasOwnProperty('lat')) { position.lat = this.options.lat } if (this.options.hasOwnProperty('alt')) { position.alt = this.options.alt } } // 如果没有高度值,则获取紧贴高度计算 // if (!position.hasOwnProperty('alt')) { // position.alt = await this.getClampToHeight(position) // } lng = this.options.customView.relativePosition.lng + position.lng lat = this.options.customView.relativePosition.lat + position.lat alt = this.options.customView.relativePosition.alt + position.alt destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) this.sdk.viewer.camera.flyTo({ destination: destination, orientation: orientation }) } else { let positionArray = [] for (let i = 0; i < this.positions.length; i++) { let a = Cesium.Cartesian3.fromDegrees( this.positions[i][0], this.positions[i][1], this.options.height + this.options.heightDifference / 2 ) positionArray.push(a.x, a.y, a.z) } let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray) this.viewer.camera.flyToBoundingSphere(BoundingSphere, { offset: { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-20.0), roll: Cesium.Math.toRadians(0.0) } }) } } getSphere() { return new Promise((resolve) => { // entity没有加载完成时 state 不会等于0 所以设置定时器直到获取到为止 const interval = setInterval(() => { const sphere = new Cesium.BoundingSphere() const state = this.sdk.viewer._dataSourceDisplay.getBoundingSphere( this.viewer.entities.getById(this.options.id), false, sphere ) if (state === Cesium.BoundingSphereState.DONE) { clearInterval(interval) } }, 1000) }) } /** * 删除 */ async remove() { if (this.viewer.entities.getById(this.options.id)) { this.viewer.entities.getById(this.options.id)._children.forEach((item) => { this.viewer.entities.remove(item); }); this.viewer.entities.remove(this.viewer.entities.getById(this.options.id)) } this.positions = [] this.entity = null if (this._DialogObject && !this._DialogObject.isDestroy) { this._DialogObject.close() this._DialogObject = null } await this.sdk.removeIncetance(this.options.id) await syncData(this.sdk, this.options.id) } flicker() { } } export default FlowLine