Files
sdk4.0/src/Obj/Base/FlowLine/index.js

505 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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.positions = options.positions || []
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)
FlowLine.drawLine(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)
})
}
static drawLine(that) {
that.positionArea = that.options.positions
let posis = that.getRandomPointsInCesiumPolygon(that.options.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 = [];
let that = this
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) {
let posi = Cesium.Cartesian3.fromDegrees(lon, lat);
const cartographic = that.viewer.scene.globe.ellipsoid.cartesianToCartographic(posi);
const height = cartographic.height;
points.push([
lon,
lat,
height
]);
}
}
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 start = Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2])
//根据点设置结束点位置
let end = Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] + that.options.height + Math.random() * that.options.heightDifference)
//创建线
that.viewer.entities.add({
parent: celiangEntity,
id: that.options.id + '-' + new Date().getTime() + index,
polyline: {
positions: [start, end],
width: that.options.width,
// 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 YJColorPicker({
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 show() {
return this.options.show
}
set show(v) {
this.options.show = v
let entity = this.viewer.entities.getById(this.options.id)
if (entity) {
entity.show = v
}
}
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 YJColorPicker({
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.positions[i][2] + 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