import { getHost } from "../../../../../on"; import { html, css } from "./_element"; import Dialog from '../../../../Element/Dialog'; import EventBinding from '../../../../Element/Dialog/eventBinding'; import cy_tabs from "../../../../Element/cy_html_tabs"; import Controller from "../../../../../Controller/index"; import LabelObject from "../../../LabelObject"; import { openLeftClick, closeLeftClick, openRightClick, closeRightClick, getLeftClickState, getRightClickState } from "../../../../../Global/ClickCallback" import BaseModel from "../index"; import { legp } from '../../../../Element/datalist'; import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../../Global/global' class Model2 extends BaseModel { /** * @constructor * @description 加载模型 * @param sdk {object} sdk * @param options {object} 模型参数 * @param options.id {string} 对象id * @param options.show=true {boolean} 模型显隐 * @param options.name {string} 名称 * @param options.url {string} 资源地址 * @param options.positions {Array.} 坐标数组 [{lng,lat,alt},...] * @param options.height {number} 高程,为空时取坐标中最低高程 * @param options.type=0 {number} 类型 0:点;1:线;2:多边形;3:矩形 * @param options.interval=1 {number} 间隔(米),type=0时不生效 * @param options.quantity {object} 数量,type=3时生效 * @param options.quantity.x {number} x轴方向数量,type=3时生效 * @param options.quantity.y {number} y轴方向数量,type=3时生效 * @param options.scale=1 {number} 比例 * @param options.maximumScale=100 {number} 最大比例 * @param options.minimumPixelSize=60 {number} 最小像素 * @param options.scaleByDistance=true {boolean} 随视野缩放 * @param options.rotate {object} 旋转角度 * @param options.rotate.x {number} x轴旋转度数 * @param options.rotate.y {number} y轴旋转度数 * @param options.rotate.z {number} z轴旋转度数 * */ constructor(earth, options = {}, _Dialog = {}) { super(earth, options, _Dialog = {}) this.picking = true this.options.name = options.name || '未命名对象' this.options.color = options.color || '#ffffff' this.options.scale = (options.scale || options.scale === 0) ? options.scale : 1 this.options.url = options.url this.options.maximumScale = (options.maximumScale || options.maximumScale === 0) ? options.maximumScale : 100 this.options.minimumPixelSize = (options.minimumPixelSize || options.minimumPixelSize === 0) ? options.minimumPixelSize : 60 this.options.positions = options.positions || [] this.options.type = options.type || 0 this.options.interval = (options.interval || options.interval === 0) ? options.interval : 1 this.options.quantity = options.quantity this.options.scaleByDistance = (options.scaleByDistance || options.scaleByDistance === false) ? options.scaleByDistance : true this.options.rotate = options.rotate = (options.rotate || {}) this.options.rotate.x = options.rotate.x || 0 this.options.rotate.y = options.rotate.y || 0 this.options.rotate.z = options.rotate.z || 0 this.options.label = options.label = (options.label || {}) this.options.label.show = (options.label.show || options.label.show === false) ? options.label.show : false this.options.label.fontSize = options.label.fontSize || 20 this.options.label.color = options.label.color || '#ffffff' this.options.label.near = (options.label.near || options.label.near === 0) ? options.label.near : 2000 this.options.label.far = (options.label.far || options.label.far === 0) ? options.label.far : 100000 this.options.label.scaleByDistance = options.label.scaleByDistance || false this.options.label.backgroundColor = options.label.backgroundColor || ['#42c6ef', '#42c6ef'] this.options.line = options.line = (options.line || {}) this.options.line.width = options.line.width || 2 this.options.line.length = options.line.length || 20 this.options.line.color = options.line.color || '#fff000' this.options.attribute = options.attribute || {} this.options.attribute.link = this.options.attribute.link || {} this.options.attribute.link.content = this.options.attribute.link.content || [] this.options.attribute.camera = this.options.attribute.camera || [] this.options.attributeType = options.attributeType || 'richText' this.ModelPositions = [] this._elms = {}; this.positionCallBack = null this.rotationCallback = null this.onClickCallback = null this._DialogObject = null this._element_style = null this.ControllerObject = new Controller(this.sdk) this.ControllerObject.controllerCallBack = (params) => { this.lng = params.position.lng this.lat = params.position.lat this.alt = params.position.alt // this.rotateX = params.rotate.x // this.rotateY = params.rotate.y // this.rotateZ = params.rotate.z // this.updateModel(params.position.lng, params.position.lat, params.position.alt, params.rotate.x, params.rotate.y, params.rotate.z, this.options.scale) } this.Dialog = _Dialog this._EventBinding = new EventBinding() this.on() } get type() { return "glb" } async loadModel(url) { if (!url.startsWith("http")) { //说明是本地的json,在磁盘中存在的 if (!url.includes(":")) { if (this.options.host) { let o = new URL(url, this.options.host) url = o.href } } } this.originalOptions = this.deepCopyObj(this.options) const collection = new Cesium.PrimitiveCollection(); let positions = [[]] let height = this.options.positions[0].alt for (let i = 0; i < this.options.positions.length; i++) { positions[0].push([this.options.positions[i].lng, this.options.positions[i].lat]) if (this.options.positions[i].alt > this.options.height) { height = this.options.positions[i].alt } } if (positions[0].length > 2) { positions[0].push([this.options.positions[0].lng, this.options.positions[0].lat]) let polygon = turf.polygon(positions); let centroid = turf.pointOnFeature(polygon); this.center = { lng: centroid.geometry.coordinates[0], lat: centroid.geometry.coordinates[1] } } else if (positions[0].length == 2) { this.center = { lng: (this.options.positions[0].lng + this.options.positions[1].lng) / 2, lat: (this.options.positions[0].lat + this.options.positions[1].lat) / 2 } } else { this.center = { lng: this.options.positions[0].lng, lat: this.options.positions[0].lat } } let ModelPositions = [] if (!this.options.height && this.options.height !== 0) { this.options.height = height } let grid let scripts = document.scripts; let turfUrl = '' for (let i = 0; i < scripts.length; i++) { if (scripts[i].src && scripts[i].src.includes('turf.min.js')) { turfUrl = scripts[i].src && scripts[i].src break } } let params = { type: this.options.type, interval: this.options.interval, positions: positions, optionsPositions: this.options.positions, quantity: this.options.quantity, turfUrl: turfUrl } function threadFn({ type, interval, positions, optionsPositions, quantity, turfUrl }) { importScripts(turfUrl); let ModelPositions = [] switch (type) { case 1: let line = turf.lineString(positions[0]); let chunk = turf.lineChunk(line, interval / 1000, { units: 'kilometers' }); ModelPositions.push({ lng: chunk.features[0].geometry.coordinates[0][0], lat: chunk.features[0].geometry.coordinates[0][1] }) for (let i = 0; i < chunk.features.length; i++) { ModelPositions.push({ lng: chunk.features[i].geometry.coordinates[1][0], lat: chunk.features[i].geometry.coordinates[1][1] }) } break; case 2: let polygon = turf.polygon(positions); let bbox = turf.bbox(polygon); grid = turf.pointGrid(bbox, interval / 1000, { units: 'kilometers' }); let ptsWithin = turf.pointsWithinPolygon(grid, polygon); for (let i = 0; i < ptsWithin.features.length; i++) { ModelPositions.push({ lng: ptsWithin.features[i].geometry.coordinates[0], lat: ptsWithin.features[i].geometry.coordinates[1] }) } break; case 3: if (quantity) { let minX = optionsPositions[0].lng let minY = optionsPositions[0].lat let maxX = optionsPositions[2].lng let maxY = optionsPositions[2].lat let fromX = turf.point([minX, maxY]); let toX = turf.point([maxX, maxY]); let distanceX = turf.distance(fromX, toX, { units: 'kilometers' }); let x = distanceX / quantity.x let fromY = turf.point([minX, maxY]); let toY = turf.point([minX, minY]); let distanceY = turf.distance(fromY, toY, { units: 'kilometers' }); let y = distanceY / quantity.y let lineX = turf.lineString([[minX, maxY], [maxX, maxY]]); let chunkX = turf.lineChunk(lineX, x, { units: 'kilometers' }); let lineY = turf.lineString([[minX, maxY], [minX, minY]]); let chunkY = turf.lineChunk(lineY, y, { units: 'kilometers' }); for (let i = 0; i < chunkX.features.length; i++) { let Xcoordinates = chunkX.features[i].geometry.coordinates for (let m = 0; m < chunkY.features.length; m++) { let Ycoordinates = chunkY.features[m].geometry.coordinates ModelPositions.push( { lng: (Xcoordinates[0][0] + Xcoordinates[1][0]) / 2, lat: (Ycoordinates[0][1] + Ycoordinates[1][1]) / 2, } ) } } } else { grid = turf.pointGrid([optionsPositions[0].lng, optionsPositions[0].lat, optionsPositions[2].lng, optionsPositions[2].lat], interval / 1000, { units: 'kilometers' }); for (let i = 0; i < grid.features.length; i++) { ModelPositions.push({ lng: grid.features[i].geometry.coordinates[0], lat: grid.features[i].geometry.coordinates[1] }) } } break; default: ModelPositions = [...optionsPositions] } self.postMessage(ModelPositions); } function createWorker(fn) { const worker = new Worker(`data:,(${fn.toString()})(${JSON.stringify(params)})`) return worker } const worker = createWorker(threadFn) worker.onmessage = e => { this.ModelPositions = ModelPositions = e.data let instances = [] for (let i = 0; i < ModelPositions.length; i++) { let heading = 0 let pitch = 0 let roll = 0 let scale = 1 // let cartographic = Cesium.Cartographic.fromDegrees(ModelPositions[i].lng, ModelPositions[i].lat, this.options.height); let position = Cesium.Cartesian3.fromDegrees( ModelPositions[i].lng, ModelPositions[i].lat, this.options.height ); var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( position, new Cesium.HeadingPitchRoll(heading, pitch, roll) ); Cesium.Matrix4.multiplyByUniformScale( modelMatrix, scale, modelMatrix ); instances.push({ modelMatrix: modelMatrix }) } this.label = new LabelObject(this.sdk, { show: this.options.show ? this.options.label.show : false, position: [this.center.lng, this.center.lat, this.options.height], text: this.options.name, fontSize: this.options.label.fontSize, color: this.options.label.color, pixelOffset: this.options.line.length, backgroundColor: this.options.label.backgroundColor, lineColor: this.options.line.color, lineWidth: this.options.line.width, scaleByDistance: this.options.label.scaleByDistance, near: this.options.label.near, far: this.options.label.far }) // this.entity = collection this.entity = new Cesium2.ModelInstanceCollection({ url: url, instances: instances }) this.entity.position = new Cesium.Cartesian3.fromDegrees(this.center.lng, this.center.lat, this.options.height) this.entity.rotate = { x: this.options.rotate.x, y: this.options.rotate.y, z: this.options.rotate.z }; this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this.sdk.viewer.scene.primitives.add(this.entity); } } remove() { super.remove() this.label.remove() this.positionEditing = false this.sdk.viewer.scene.primitives.remove(this.entity); this.entity = null if (this._DialogObject) { this._DialogObject.close() this._DialogObject = null } } async flyTo() { 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 { this.sdk.viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(this.center.lng, this.center.lat, this.options.height + 500) }) } // this.sdk.viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(this.center.lng, this.center.lat, this.options.height)}) } on() { return this.add() } setDefaultValue() { super.setDefaultValue() this.options.host = this.options.host || getHost() this.options.url = this.options.url || "" } get color() { return this.options.color } set color(v) { this.options.color = v this.entity.color = Cesium.Color.fromCssColorString(v) if (this._elms.color) { this._elms.color.forEach((item, i) => { let colorPicker = 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] = colorPicker }) } } get lng() { return this.center.lng } set lng(v) { this.center.lng = v this._ControllerChangePosition(50) this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this.label.position = [this.center.lng, this.center.lat, this.options.height] this._elms.lng && this._elms.lng.forEach((item) => { item.value = v }) } get lat() { return this.center.lat } set lat(v) { this.center.lat = v this._ControllerChangePosition(50) this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this.label.position = [this.center.lng, this.center.lat, this.options.height] this._elms.lat && this._elms.lat.forEach((item) => { item.value = v }) } get alt() { return this.options.height } set alt(v) { this.center.alt = v this.options.height = v this._ControllerChangePosition(50) this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this.label.position = [Number(this.center.lng), Number(this.center.lat), Number(this.options.height)] this._elms.alt && this._elms.alt.forEach((item) => { item.value = v }) } _ControllerChangePosition(delay) { let _this = this clearTimeout(_this._ControllerChangePositionEvent); _this._ControllerChangePositionEvent = setTimeout(() => { _this.ControllerObject.position = { lng: _this.center.lng, lat: _this.center.lat, alt: _this.options.height } }, delay); } get maximumScale() { return this.options.maximumScale } set maximumScale(v) { this.options.maximumScale = v this.entity.maximumScale = this.scaleByDistance ? undefined : v this._elms.maximumScale && this._elms.maximumScale.forEach((item) => { item.value = v }) } get minimumPixelSize() { return this.options.minimumPixelSize } set minimumPixelSize(v) { this.options.minimumPixelSize = v this.entity.minimumPixelSize = this.scaleByDistance ? undefined : v this._elms.minimumPixelSize && this._elms.minimumPixelSize.forEach((item) => { item.value = v }) } get scaleByDistance() { return this.options.scaleByDistance } set scaleByDistance(v) { this.options.scaleByDistance = v this.entity.maximumScale = v ? undefined : this.maximumScale this.entity.minimumPixelSize = v ? undefined : this.minimumPixelSize this._elms.scaleByDistance && this._elms.scaleByDistance.forEach((item) => { item.checked = v }) } get rotateX() { return this.options.rotate.x } set rotateX(v) { this.options.rotate.x = v this.updateModelRotate(this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) // this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this._elms.rotateX && this._elms.rotateX.forEach((item) => { item.value = v }) } get rotateY() { return this.options.rotate.y } set rotateY(v) { this.options.rotate.y = v this.updateModelRotate(this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) // this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this._elms.rotateY && this._elms.rotateY.forEach((item) => { item.value = v }) } get rotateZ() { return this.options.rotate.z } set rotateZ(v) { this.options.rotate.z = v this.updateModelRotate(this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) // this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this._elms.rotateZ && this._elms.rotateZ.forEach((item) => { item.value = v }) } get scale() { return this.options.scale } set scale(v) { this.options.scale = v this.updateModelRotate(this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) // this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this._elms.scale && this._elms.scale.forEach((item) => { item.value = v }) } get labelShow() { return this.options.label.show } set labelShow(v) { this.options.label.show = v if (this.show && !this.showView || this.showView == 3) { this.label.show = v } else { this.label.show = false } this._elms.labelShow && this._elms.labelShow.forEach((item) => { item.checked = v }) } get labelFontSize() { return this.options.label.fontSize } set labelFontSize(v) { this.options.label.fontSize = v this.label.fontSize = v this._elms.labelFontSize && this._elms.labelFontSize.forEach((item) => { item.value = v }) } get labelColor() { return this.options.label.color } set labelColor(v) { this.options.label.color = v this.label.color = v if (this._elms.labelColor) { this._elms.labelColor.forEach((item, i) => { let labelColorPicker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelColor = color },//点击确认按钮事件回调 clear: () => { this.labelColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.labelColor[i] = labelColorPicker }) } } get labelScaleByDistance() { return this.options.label.scaleByDistance } set labelScaleByDistance(v) { this.options.label.scaleByDistance = v this.label.scaleByDistance = v this._elms.labelScaleByDistance && this._elms.labelScaleByDistance.forEach((item) => { item.checked = v }) } get labelNear() { return this.options.label.near } set labelNear(v) { let near = v if (near > this.labelFar) { near = this.labelFar } this.options.label.near = near this.label.near = near this._elms.labelNear && this._elms.labelNear.forEach((item) => { item.value = near }) } get labelFar() { return this.options.label.far } set labelFar(v) { let far = v if (far < this.labelNear) { far = this.labelNear } this.options.label.far = far this.label.far = far this._elms.labelFar && this._elms.labelFar.forEach((item) => { item.value = far }) } get lineWidth() { return this.options.line.width } set lineWidth(v) { this.options.line.width = v this.label.lineWidth = v this._elms.lineWidth && this._elms.lineWidth.forEach((item) => { item.value = v }) } get lineLength() { return this.options.line.length } set lineLength(v) { this.options.line.length = v this.label.pixelOffset = v this._elms.lineLength && this._elms.lineLength.forEach((item) => { item.value = v }) } get lineColor() { return this.options.line.color } set lineColor(v) { this.options.line.color = v this.label.lineColor = v if (this._elms.lineColor) { this._elms.lineColor.forEach((item, i) => { let lineColorPicker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.lineColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.lineColor = color },//点击确认按钮事件回调 clear: () => { this.lineColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.lineColor[i] = lineColorPicker }) } } get labelBackgroundColorStart() { return this.options.label.backgroundColor[0] } set labelBackgroundColorStart(v) { this.options.label.backgroundColor[0] = v this.label.backgroundColor = [v, this.labelBackgroundColorEnd] if (this._elms.labelBackgroundColorStart) { this._elms.labelBackgroundColorStart.forEach((item, i) => { let labelBackgroundColorStartPicker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelBackgroundColorStart, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelBackgroundColorStart = color },//点击确认按钮事件回调 clear: () => { this.labelBackgroundColorStart = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.labelBackgroundColorStart[i] = labelBackgroundColorStartPicker }) } } get labelBackgroundColorEnd() { return this.options.label.backgroundColor[1] } set labelBackgroundColorEnd(v) { this.options.label.backgroundColor[1] = v this.label.backgroundColor = [this.labelBackgroundColorStart, v] if (this._elms.labelBackgroundColorEnd) { this._elms.labelBackgroundColorEnd.forEach((item, i) => { let labelBackgroundColorEndPicker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelBackgroundColorEnd, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelBackgroundColorEnd = color },//点击确认按钮事件回调 clear: () => { this.labelBackgroundColorEnd = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.labelBackgroundColorEnd[i] = labelBackgroundColorEndPicker }) } } get attributeType() { return this.options.attributeType } set attributeType(v) { this.options.attributeType = v this._elms.attributeType && this._elms.attributeType.forEach((item) => { item.value = v }) let attributeContent = this._DialogObject._element.content.getElementsByClassName('attribute-content') for (let i = 0; i < attributeContent.length; i++) { if (attributeContent[i].className.indexOf('attribute-content-' + v) > -1) { attributeContent[i].style.display = 'block'; } else { attributeContent[i].style.display = 'none'; } } } get attributeLink() { return this.options.attribute.link.content } set attributeLink(v) { this.options.attribute.link.content = v if (!this._DialogObject || !this._DialogObject._element || !this._DialogObject._element.content || this._DialogObject._element.content.getElementsByClassName('attribute-content-link').length == 0) { return } let table = this._DialogObject._element.content.getElementsByClassName('attribute-content-link')[1].getElementsByClassName('table')[0] let tableContent = table.getElementsByClassName('table-body')[0] tableContent.innerHTML = '' if (this.options.attribute.link.content.length > 0) { table.getElementsByClassName('table-empty')[0].style.display = 'none' } else { table.getElementsByClassName('table-empty')[0].style.display = 'flex' } for (let i = 0; i < this.options.attribute.link.content.length; i++) { let tr = `
` + this.options.attribute.link.content[i].name + `
` + this.options.attribute.link.content[i].url + `
` let trElm = document.createRange().createContextualFragment(tr) tableContent.appendChild(trElm) } let item = tableContent.getElementsByClassName('tr') let fun = { linkEdit: async (index) => { this.attributeLink = await this.options.attribute.link.content let table = this._DialogObject._element.content.getElementsByClassName('attribute-content-link')[1].getElementsByClassName('table')[0] let tableContent = table.getElementsByClassName('table-body')[0] let item = tableContent.getElementsByClassName('tr') for (let i = 0; i < item.length; i++) { if (index === i) { let height = item[i].offsetHeight let html = `
` item[i].innerHTML = html let textareaElm = item[i].getElementsByClassName('link-edit')[0] textareaElm.style.height = (height - 10) + 'px' let td = item[i].getElementsByClassName('td') td[0].getElementsByClassName('input')[0].value = this.options.attribute.link.content[index].name td[1].getElementsByClassName('input')[0].value = this.options.attribute.link.content[index].url let btn = item[i].getElementsByTagName('button') for (let n = 0; n < btn.length; n++) { if (!btn[n] || !btn[n].attributes) { continue } for (let m of btn[n].attributes) { if (m.name === '@click') { btn[n].addEventListener('click', (e) => { if (typeof (fun[m.value]) === 'function') { fun[m.value]({ name: td[0].getElementsByClassName('input')[0].value, url: td[1].getElementsByClassName('input')[0].value }, i) } }); btn[n].attributes.removeNamedItem(m.name) break } } } break } } }, linkDelete: (i) => { this.options.attribute.link.content.splice(i, 1) this.attributeLink = this.options.attribute.link.content }, confirmEdit: (value, i) => { let name = value.name && value.name.replace(/\s/g, "") let url = value.url && value.url.replace(/\s/g, "") if(name && url) { this.options.attribute.link.content[i] = value } else { window.ELEMENT && window.ELEMENT.Message({ message: '名称或链接不能为空!', type: 'warning', duration: 1500 }); } this.attributeLink = this.options.attribute.link.content }, cancelEdit: () => { this.attributeLink = this.options.attribute.link.content }, fileSelect: (value, i) => { let fileElm = item[i].getElementsByClassName('file-select')[0] fileElm.click() fileElm.removeEventListener('change', fileSelect) fileElm.addEventListener('change', fileSelect) } } let fileSelect = (event) => { if (event.target.value) { let td = item[event.target.getAttribute('index')].getElementsByClassName('td') td[1].getElementsByClassName('input')[0].value = event.target.value event.target.value = null } } for (let i = 0; i < item.length; i++) { let btn = item[i].getElementsByTagName('button') for (let n = 0; n < btn.length; n++) { if (!btn[n] ||!btn[n].attributes) { continue } for (let m of btn[n].attributes) { if (m.name === '@click') { btn[n].addEventListener('click', (e) => { if (typeof (fun[m.value]) === 'function') { fun[m.value](i) } }); btn[n].attributes.removeNamedItem(m.name) break } } } } } get attributeCamera() { return this.options.attribute.camera } set attributeCamera(v) { this.options.attribute.camera = v } // get position() { // let cartographic = Cesium.Cartographic.fromCartesian(this.entity.position); // let lng = Cesium.Math.toDegrees(cartographic.longitude + 0.00000000663814); // let lat = Cesium.Math.toDegrees(cartographic.latitude + 0.00000025137835); // return { lng: lng, lat: lat, alt: cartographic.height - 2.19104611043234 } // } // set position(p) { // } /** * @desc 打开模型旋转功能 * @param status {boolean} * @methodOf Source * */ set rotationEditing(status) { if (status) { this.ControllerObject.editRtation() } else { this.ControllerObject.destroy() } } /** * @desc 获取模型旋转状态 * @method rotationEditing * @return boolean * @methodOf Source * */ get rotationEditing() { if (this.ControllerObject.getActiveState() === 'rtation') { return true } return false } /**@desc 打开平移模型功能 * * @memberOf Source *@param status {boolean} * * */ set positionEditing(status) { if (YJ.Measure.GetMeasureStatus() || !this.sdk || !this.sdk.viewer) { return } if (status) { this.leftClickState = getLeftClickState() this.ControllerObject.position = { lng: this.center.lng, lat: this.center.lat, alt: this.options.height } this.ControllerObject.editTranslational() new closeLeftClick(this.sdk) } else { if (this.leftClickState && !getLeftClickState()) { new openLeftClick(this.sdk) } this.ControllerObject.destroy() } } get positionEditing() { if (this.ControllerObject.getActiveState() === 'translational') { return true } return false } //平移时,坐标信息变化的回调 set positionEditingCallBack(callback) { return } get positionEditingCallBack() { } //旋转时,坐标信息变化的回调 set rotationEditingCallBack(callback) { this._rotationEditingCallBack = callback } get rotationEditingCallBack() { return (params) => { // let params = this.ControllerObject._params // this.center = { // lng: params.tx, // lat: params.ty, // alt: params.tz, // } this.lng = params.tx this.lat = params.ty this.alt = params.tz this.rotateX = params.rx this.rotateY = params.ry this.rotateZ = params.rz this._rotationEditingCallBack && this._rotationEditingCallBack(this.ControllerObject._params) } } /** * @description 编辑框 * @param state=false {boolean} 状态: true打开, false关闭 */ async edit(state = false) { let _this = this this.originalOptions = this.deepCopyObj(this.options) this._element_style = null // 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._element_style = document.createElement('style'); this._element_style.type = 'text/css'; this._element_style.setAttribute('data-name', 'YJ_style_dialog'); this._element_style.innerHTML = css(); this._DialogObject = await new Dialog(this.sdk, this.originalOptions, { title: '编辑属性', left: '180px', top: '100px', confirmCallBack: (options) => { this.name = this.options.name || '未命名对象' this.originalOptions = this.deepCopyObj(this.options) this._DialogObject.close() this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions) }, 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.positionEditing = false this.ControllerObject && this.ControllerObject.destroy() this.Dialog.closeCallBack && this.Dialog.closeCallBack() }, showCallBack: (show) => { this.show = show this.Dialog.showCallBack && this.Dialog.showCallBack() }, translationalCallBack: () => { if (this.positionEditing) { this.positionEditing = false } else { this.positionEditing = true } } }, true) document.getElementsByTagName('head')[0].appendChild(this._element_style); let contentElm = document.createElement('div'); contentElm.innerHTML = html(this) this._DialogObject.contentAppChild(contentElm) this.attributeType = this.options.attributeType this.attributeCamera = this.options.attribute.camera // 创建标签页 let tabsElm = new cy_tabs('model-edit-tabs', undefined, this.sdk) // 颜色组件 let colorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("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 labelColorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("label_color")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.labelColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.labelColor = color },//点击确认按钮事件回调 clear: () => { this.labelColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) let lineColorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("line_color")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.lineColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.lineColor = color },//点击确认按钮事件回调 clear: () => { this.lineColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) let labelBackgroundColorStartPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("labelBackgroundColorStart")[0], size: 'mini', alpha: true, defaultColor: this.labelBackgroundColorStart, disabled: false, openPickerAni: 'opacity', sure: (color) => { this.labelBackgroundColorStart = color }, clear: () => { this.labelBackgroundColorStart = 'rgba(255,255,255,1)' }, }) let labelBackgroundColorEndPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("labelBackgroundColorEnd")[0], size: 'mini', alpha: true, defaultColor: this.labelBackgroundColorEnd, disabled: false, openPickerAni: 'opacity', sure: (color) => { this.labelBackgroundColorEnd = color }, clear: () => { this.labelBackgroundColorEnd = 'rgba(255,255,255,1)' }, }) let all_elm = contentElm.getElementsByTagName("*") this._EventBinding.on(this, all_elm) this._elms = this._EventBinding.element this._elms.color = [colorPicker] this._elms.labelColor = [labelColorPicker] this._elms.lineColor = [lineColorPicker] this._elms.labelBackgroundColorStart = [labelBackgroundColorStartPicker] this._elms.labelBackgroundColorEnd = [labelBackgroundColorEndPicker] setTimeout(() => { this.attributeLink = this.options.attribute.link.content this.cameraSelect && this.cameraSelect() let tagData = this.attributeSelect let attributeElm = this._DialogObject._element.content.getElementsByClassName('attribute-select-box')[0] if (attributeElm) { let legpObject = legp(attributeElm, ".attribute-select") legpObject.legp_search(tagData) let attributeSelectElm = this._DialogObject._element.content.getElementsByClassName('attribute-select')[0].getElementsByTagName('input')[0] for (let i = 0; i < tagData.length; i++) { if (tagData[i].key === this.options.attributeType) { attributeSelectElm.value = tagData[i].value legpObject.legp_searchActive(tagData[i].value) break } } attributeSelectElm.addEventListener('input', () => { for (let i = 0; i < tagData.length; i++) { if (tagData[i].value === attributeSelectElm.value) { this.attributeType = tagData[i].key break } } }) } }, 0); } else { // if (this._element_style) { // document.getElementsByTagName('head')[0].removeChild(this._element_style) // this._element_style = null // } // if (this._DialogObject && this._DialogObject.close) { // this._DialogObject.close() // this._DialogObject = null // } } } //更新模型位置 updateModel(_tx, _ty, _tz, _rx = 0, _ry = 0, _rz = 0, _scale) { _tx = parseFloat(_tx) _ty = parseFloat(_ty) _tz = parseFloat(_tz) _rx = parseFloat(_rx) _ry = parseFloat(_ry) _rz = parseFloat(_rz) _scale = parseFloat(_scale) this.entity.rotate = { x: _rx, y: _ry, z: _rz }; let mx = Cesium.Matrix3.fromRotationX( Cesium.Math.toRadians(_rx) ) let my = Cesium.Matrix3.fromRotationY( Cesium.Math.toRadians(_ry) ) let mz = Cesium.Matrix3.fromRotationZ( Cesium.Math.toRadians(_rz) ) // 平移 let position = new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz) let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(position.x - this.entity._center.x, position.y - this.entity._center.y, position.z - this.entity._center.z)) // 旋转 let rotationX = Cesium.Matrix4.fromRotationTranslation(mx) let rotationY = Cesium.Matrix4.fromRotationTranslation(my) let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz) let originalMatrix = new Cesium.Matrix4() Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(position.x - this.entity._center.x, position.y - this.entity._center.y, position.z - this.entity._center.z), this.entity.modelMatrix) // console.log(position.z, this.entity._center.z) // Cesium.Matrix4.multiply(this.entity.modelMatrix, rotationX, originalMatrix) // Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix) // Cesium.Matrix4.multiply(originalMatrix, rotationZ, this.entity.modelMatrix) // 缩放 // Cesium.Matrix4.multiplyByScale(this.entity.modelMatrix, new Cesium.Cartesian3(_scale, _scale, _scale), this.entity.modelMatrix) this.ControllerObject.update() this.entity.position = new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz) } updateModelRotate(_rx = 0, _ry = 0, _rz = 0, _scale) { _rx = parseFloat(_rx) _ry = parseFloat(_ry) _rz = parseFloat(_rz) _scale = parseFloat(_scale) this.sdk.viewer.scene.primitives.remove(this.entity); let url = this.options.url if (!url.startsWith("http")) { //说明是本地的json,在磁盘中存在的 if (!url.includes(":")) { if (this.options.host) { let o = new URL(url, this.options.host) url = o.href } } } let instances = [] for (let i = 0; i < this.ModelPositions.length; i++) { let scale = _scale // let cartographic = Cesium.Cartographic.fromDegrees(ModelPositions[i].lng, ModelPositions[i].lat, this.options.height); let position = Cesium.Cartesian3.fromDegrees( this.ModelPositions[i].lng, this.ModelPositions[i].lat, this.options.height ); var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( position, new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(_rz), Cesium.Math.toRadians(_ry), Cesium.Math.toRadians(_rx)) ); Cesium.Matrix4.multiplyByUniformScale( modelMatrix, scale, modelMatrix ); instances.push({ modelMatrix: modelMatrix }) } this.entity = new Cesium.ModelInstanceCollection({ url: url, instances: instances }) this.entity.position = new Cesium.Cartesian3.fromDegrees(this.center.lng, this.center.lat, this.options.height) this.entity.rotate = { x: this.options.rotate.x, y: this.options.rotate.y, z: this.options.rotate.z }; this.updateModel(this.center.lng, this.center.lat, this.options.height, this.options.rotate.x, this.options.rotate.y, this.options.rotate.z, this.options.scale) this.sdk.viewer.scene.primitives.add(this.entity); } reset() { if (!this.entity) { return } this.options = this.deepCopyObj(this.originalOptions) this.name = this.originalOptions.name this.color = this.originalOptions.color this.lng = this.originalOptions.position.lng this.lat = this.originalOptions.position.lat this.alt = this.originalOptions.position.alt this.maximumScale = this.originalOptions.maximumScale this.minimumPixelSize = this.originalOptions.minimumPixelSize this.scaleByDistance = this.originalOptions.scaleByDistance this.rotateX = this.originalOptions.rotate.x this.rotateY = this.originalOptions.rotate.y this.rotateZ = this.originalOptions.rotate.z this.scale = this.originalOptions.scale this.labelShow = this.originalOptions.label.show this.labelColor = this.originalOptions.label.color this.labelFontSize = this.originalOptions.label.fontSize this.labelFontFamily = this.originalOptions.label.fontFamily this.labelScaleByDistance = this.originalOptions.label.scaleByDistance this.labelNear = this.originalOptions.label.near this.labelFar = this.originalOptions.label.far this.labelLineWidth = this.originalOptions.label.lineWidth this.labelPixelOffset = this.originalOptions.label.pixelOffset this.labelLineColor = this.originalOptions.label.lineColor this.labelBackgroundColorStart = this.originalOptions.label.backgroundColor[0] this.labelBackgroundColorEnd = this.originalOptions.label.backgroundColor[1] this.attributeLink = this.options.attribute.link.content this.attributeCamera = this.options.attribute.camera this.cameraSelect && this.cameraSelect() } } export default Model2