Files
sdk4.0/src/Obj/Base/PolyhedronObject2/index.js
2025-07-16 15:02:18 +08:00

1333 lines
50 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.

/**
* 多面体
*/
import Dialog from '../../Element/Dialog';
import cy_tabs from "../../Element/cy_html_tabs";
import richText from "../../Element/richText";
import { html } from "./_element";
import Base from "../index";
import MouseEvent from '../../../Event/index'
import LabelObject from '../LabelObject'
import EventBinding from './eventBinding'
import MouseTip from '../../../MouseTip'
import { syncData } from '../../../Global/MultiViewportMode'
import { legp } from '../../Element/datalist';
import PolylineImageTrailMaterialProperty from "../../Materail/PolylineImageTrailMaterialProperty";
import { init_material } from "../Road/RoadMaterialProperty";
class PolyhedronObject extends Base {
/**
* @constructor
* @param sdk
* @description 多面体
* @param options {object} 属性
* @param options.id {string} 唯一标识
* @param options.show=true {boolean} 显示/隐藏
* @param options.name {string} 名称
* @param options.color="#0df7f8" {string} 颜色
* @param options.height=10 {number} 高
* @param {Array.<object>} options.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options);
this.options.color = options.color || "#0df7f8"
this.options.show = (options.show || options.show === false) ? options.show : true
this.options.topImg = options.topImg
this.options.lateralImg = options.lateralImg
this.options.height = (options.height || options.height === 0) ? options.height : 10
// this.options.extrudedHeight = (options.extrudedHeight || options.extrudedHeight === 0) ? options.extrudedHeight : this.options.height + 5
this.options.extrudedHeight = (options.extrudedHeight || options.extrudedHeight === 0) ? options.extrudedHeight : 0
this.entity
this.nodePoints = []
this.operate = {}
this.options['area-unit'] = options['area-unit'] || '平方米'
options.label = options.label || {}
init_material()
this.options.label = {
text: this.options.name,
show: options.label.show || false,
position: options.label.position,
fontSize: (options.label.fontSize || options.label.fontSize === 0) ? options.label.fontSize : 20,
color: options.label.color || '#ffffff',
lineWidth: (options.label.lineWidth || options.label.lineWidth === 0) ? options.label.lineWidth : 4,
pixelOffset: (options.label.pixelOffset || options.label.pixelOffset === 0) ? options.label.pixelOffset : 20,
backgroundColor: options.label.backgroundColor || ['#00ffff80', '#00ffff80'],
lineColor: options.label.lineColor || '#00ffff80',
scaleByDistance: options.label.scaleByDistance || false,
near: (options.label.near || options.label.near === 0) ? options.label.near : 2000,
far: (options.label.far || options.label.far === 0) ? options.label.far : 100000,
}
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._elms = {};
this.Dialog = _Dialog
if (!this.options.positions || this.options.positions.length < 3) {
this._error = '多面体最少需要三个坐标!'
console.warn(this._error)
window.ELEMENT && window.ELEMENT.Message({
message: this._error,
type: 'warning',
duration: 1500
});
}
else {
this.sdk.addIncetance(this.options.id, this)
PolyhedronObject.create(this)
}
}
static elms = {}
static async createLabel(that) {
let positions = [[]]
for (let i = 0; i < that.options.positions.length; i++) {
positions[0].push([that.options.positions[i].lng, that.options.positions[i].lat])
}
positions[0].push([that.options.positions[0].lng, that.options.positions[0].lat])
let polygon = turf.polygon(positions);
let centroid = turf.pointOnFeature(polygon);
let height = await that.getClampToHeight({ lng: centroid.geometry.coordinates[0], lat: centroid.geometry.coordinates[1] })
if (!that.options.label.position) {
that.options.label.position = { lng: centroid.geometry.coordinates[0], lat: centroid.geometry.coordinates[1], alt: height }
}
// 标签
that.label = new LabelObject(that.sdk, {
id: that.options.id,
show: that.options.show ? that.options.label.show : false,
position: [that.options.label.position.lng, that.options.label.position.lat, that.options.label.position.alt],
text: that.options.name,
fontSize: that.options.label.fontSize,
color: that.options.label.color,
pixelOffset: that.options.label.pixelOffset,
backgroundColor: that.options.label.backgroundColor,
lineColor: that.options.label.lineColor,
lineWidth: that.options.label.lineWidth,
scaleByDistance: that.options.label.scaleByDistance,
near: that.options.label.near,
far: that.options.label.far
})
}
/**
* 创建多面体
*/
static create(that) {
let positions = that.options.positions
let fromDegreesArray = []
let extrudedHeight = positions[0].alt
for (let i = 0; i < positions.length; i++) {
if (extrudedHeight > positions[i].alt) {
extrudedHeight = positions[i].alt
}
}
that.options.extrudedHeight = extrudedHeight
let minimumHeights = [extrudedHeight]
for (let i = 0; i < positions.length; i++) {
minimumHeights.push(extrudedHeight)
fromDegreesArray.push(positions[i].lng, positions[i].lat, that.options.height + extrudedHeight)
}
that.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
for (let i = 0; i < that.positions.length; i++) {
let distance = Cesium.Cartesian3.distance(that.positions[i], that.positions[i + 1]);
}
that.entity = that.sdk.viewer.entities.add({
id: that.options.id,
show: that.options.show,
polygon: {
hierarchy: new Cesium.PolygonHierarchy(that.positions),
// perPositionHeight: true,
height: that.options.height + extrudedHeight,
material: that.options.topImg && new Cesium.ImageMaterialProperty({
image: that.options.topImg, // 贴图的URL
repeat: new Cesium.Cartesian2(10, 10)
}),
zIndex: 1
},
wall: {
positions: [...that.positions, that.positions[0]],
minimumHeights: minimumHeights,
material: that.options.lateralImg && new Cesium.ImageMaterialProperty({
image: that.options.lateralImg,
repeat: new Cesium.Cartesian2(1, 1),
})
// material: new Cesium.RoadMaterialProperty({
// image: that.options.lateralImg,
// repeat: new Cesium.CallbackProperty(() => {
// let positionProperty = that.entity.wall.positions;
// let positions = positionProperty.getValue(that.sdk.viewer.clock.currentTime);
// if (!Cesium.defined(positions)) {
// return new Cesium.Cartesian2(1.0, 1.0);
// }
// let distance = 0;
// for (let i = 0; i < positions.length - 1; ++i) {
// distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
// }
// let imgProportion = 945 / 411 // 图片长宽比例
// let repeatX = distance / 2;
// repeatX = repeatX / imgProportion
// return new Cesium.Cartesian2(repeatX, 1.0);
// }, false),
// duration: 0,
// rotate: 0,
// })
},
})
PolyhedronObject.createLabel(that)
that.options.areaByMeter = that.computeArea(positions);
switch (that.options['area-unit']) {
case '平方米':
that.options.area = that.options.areaByMeter
break;
case '平方千米':
that.options.area = Number((that.options.areaByMeter / 1000000).toFixed(8))
break;
case '亩':
that.options.area = Number((that.options.areaByMeter / 666.6666667).toFixed(4))
break;
case '公顷':
that.options.area = Number((that.options.areaByMeter / 10000).toFixed(6))
break;
default:
that.options.area = that.options.areaByMeter
}
syncData(that.sdk, that.options.id)
}
/**@desc 打开平移功能
*
* @memberOf Source
* @param status {boolean}
*
* */
set positionEditing(status) {
if (YJ.Measure.GetMeasureStatus() || !this.sdk || !this.sdk.viewer || !this.entity) {
return
}
let _this = this
this.event && this.event.destroy()
this.event = new MouseEvent(this.sdk)
this.operate.positionEditing = status
this.previous = {
positions: [...this.positions]
}
if (status === true) {
this.picking = false
let array = []
let positions = this.positions
let disparity = []
for (let i = 0; i < positions.length; i++) {
let position = this.cartesian3Towgs84(positions[i], this.sdk.viewer)
array.push([position.lng, position.lat])
}
let firstposition = this.cartesian3Towgs84(positions[0], this.sdk.viewer)
array.push([firstposition.lng, firstposition.lat])
var polygon = turf.polygon([array]);
var centroid = turf.centroid(polygon);
let center = Cesium.Cartesian3.fromDegrees(...centroid.geometry.coordinates)
for (let i = 0; i < positions.length; i++) {
center.x - positions[i].x
disparity.push({
x: center.x - positions[i].x,
y: center.y - positions[i].y,
z: center.z - positions[i].z,
})
}
let newpositions = []
this.event.mouse_move((movement, cartesian) => {
let ray = this.sdk.viewer.camera.getPickRay(movement.endPosition);//获取一条射线
let cartesian2 = this.sdk.viewer.scene.globe.pick(ray, this.sdk.viewer.scene);
let position84 = this.cartesian3Towgs84(cartesian2, this.sdk.viewer)
let cartesian3 = Cesium.Cartesian3.fromDegrees(position84.lng, position84.lat)
newpositions = []
for (let i = 0; i < disparity.length; i++) {
newpositions.push({
x: cartesian3.x - disparity[i].x,
y: cartesian3.y - disparity[i].y,
z: cartesian3.z - disparity[i].z,
})
}
// let position84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.label.position = [position84.lng, position84.lat, this.options.height + this.options.extrudedHeight]
})
this.event.mouse_left((movement, cartesian) => {
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
let ray = this.sdk.viewer.camera.getPickRay(movement.position);//获取一条射线
let cartesian2 = this.sdk.viewer.scene.globe.pick(ray, this.sdk.viewer.scene);
let position84 = this.cartesian3Towgs84(cartesian2, this.sdk.viewer)
let cartesian3 = Cesium.Cartesian3.fromDegrees(position84.lng, position84.lat)
newpositions = []
this.options.positions = []
for (let i = 0; i < disparity.length; i++) {
newpositions.push({
x: cartesian3.x - disparity[i].x,
y: cartesian3.y - disparity[i].y,
z: cartesian3.z - disparity[i].z,
})
this.options.positions.push(this.cartesian3Towgs84({
x: cartesian3.x - disparity[i].x,
y: cartesian3.y - disparity[i].y,
z: cartesian3.z - disparity[i].z,
}, this.sdk.viewer))
}
this.positions = newpositions
this.previous.positions = newpositions
this.positionEditing = false
})
this.event.mouse_right((movement, cartesian) => {
this.positionEditing = false
})
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
if (newpositions.length > 0) {
return new Cesium.PolygonHierarchy(JSON.parse(JSON.stringify(newpositions)))
}
else {
return new Cesium.PolygonHierarchy(JSON.parse(JSON.stringify(positions)))
}
}, false)
this.entity.wall.positions = new Cesium.CallbackProperty(function () {
if (newpositions.length > 0) {
return [...newpositions, newpositions[0]]
}
else {
return [...positions, positions[0]]
}
}, false)
}
else {
this.picking = true
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
let positions = [[]]
for (let i = 0; i < this.previous.positions.length; i++) {
let positions84 = this.cartesian3Towgs84(this.previous.positions[i], this.sdk.viewer)
positions[0].push([positions84.lng, positions84.lat])
}
let positions84 = this.cartesian3Towgs84(this.previous.positions[0], this.sdk.viewer)
positions[0].push([positions84.lng, positions84.lat])
let polygon = turf.polygon(positions);
let centroid = turf.centroid(polygon);
this.label.position = [centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], this.options.height + this.options.extrudedHeight]
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(JSON.parse(JSON.stringify(_this.previous.positions)))
}, false)
this.entity.wall.positions = new Cesium.CallbackProperty(function () {
return [..._this.previous.positions, _this.previous.positions[0]]
}, false)
}
}
get positionEditing() {
return this.operate.positionEditing
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
this.entity.polygon.material = 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 height() {
return this.options.height
}
set height(v) {
this.options.height = v
let positions = [[]]
for (let i = 0; i < this.options.positions.length; i++) {
positions[0].push([this.options.positions[i].lng, this.options.positions[i].lat, this.options.height + this.options.extrudedHeight])
}
positions[0].push([this.options.positions[0].lng, this.options.positions[0].lat, this.options.height + this.options.extrudedHeight])
let polygon = turf.polygon(positions);
let centroid = turf.centroid(polygon);
this.label.position = [centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], this.options.extrudedHeight + this.options.height]
let position
if (this.entity.polygon.hierarchy._value) {
position = this.entity.polygon.hierarchy._value.positions
}
else {
position = this.entity.polygon.hierarchy._callback().positions
}
let newPosition = []
// this.entity.polygon.perPositionHeight = true
for (let i = 0; i < position.length; i++) {
let cartographic = Cesium.Cartographic.fromCartesian(position[i]);
let longitude = Cesium.Math.toDegrees(cartographic.longitude);
let latitude = Cesium.Math.toDegrees(cartographic.latitude);
let cartesian = new Cesium.Cartesian3.fromDegrees(longitude, latitude, this.options.extrudedHeight + v);
newPosition.push(cartesian)
}
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(newPosition)
this.entity.polygon.height = this.options.height + this.options.extrudedHeight
this.entity.wall.positions = [...newPosition, newPosition[0]]
this.positions = newPosition
this.previous = {
positions: [...this.positions]
}
this._elms.height && this._elms.height.forEach((item) => {
item.value = v
})
}
get extrudedHeight() {
return this.options.extrudedHeight
}
set extrudedHeight(v) {
this.options.extrudedHeight = v
let positions = [[]]
for (let i = 0; i < this.options.positions.length; i++) {
positions[0].push([this.options.positions[i].lng, this.options.positions[i].lat])
}
positions[0].push([this.options.positions[0].lng, this.options.positions[0].lat])
let polygon = turf.polygon(positions);
let centroid = turf.centroid(polygon);
this.label.position = [centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], this.options.extrudedHeight + this.options.height]
this._elms.extrudedHeight && this._elms.extrudedHeight.forEach((item) => {
item.value = v
})
}
get area() {
return this.options.area
}
set area(v) {
this.options.area = v
this._elms.area && this._elms.area.forEach((item) => {
item.value = v
})
}
get areaUnit() {
return this.options['area-unit']
}
set areaUnit(v) {
this.options['area-unit'] = v
this._elms.areaUnit && this._elms.areaUnit.forEach((item) => {
item.value = v
})
if (this.options.areaByMeter) {
switch (v) {
case '平方米':
this.area = this.options.areaByMeter
break;
case '平方千米':
this.area = Number((this.options.areaByMeter / 1000000).toFixed(8))
break;
case '亩':
this.area = Number((this.options.areaByMeter / 666.6666667).toFixed(4))
break;
case '公顷':
this.area = Number((this.options.areaByMeter / 10000).toFixed(6))
break;
default:
this.area = this.options.areaByMeter
}
}
}
get labelShow() {
return this.options.label.show
}
set labelShow(v) {
this.options.label.show = v
if (this.show) {
this.label.show = v
}
else {
this.label.show = false
}
this._elms.labelShow && this._elms.labelShow.forEach((item) => {
item.checked = 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 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 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 labelLineWidth() {
return this.options.label.lineWidth
}
set labelLineWidth(v) {
this.options.label.lineWidth = v
this.label.lineWidth = v
this._elms.labelLineWidth && this._elms.labelLineWidth.forEach((item) => {
item.value = v
})
}
get labelPixelOffset() {
return this.options.label.pixelOffset
}
set labelPixelOffset(v) {
this.options.label.pixelOffset = v
this.label.pixelOffset = v
this._elms.labelPixelOffset && this._elms.labelPixelOffset.forEach((item) => {
item.value = v
})
}
get labelLineColor() {
return this.options.label.lineColor
}
set labelLineColor(v) {
this.options.label.lineColor = v
this.label.lineColor = v
if (this._elms.labelLineColor) {
this._elms.labelLineColor.forEach((item, i) => {
let lineColorPicker = new YJColorPicker({
el: item.el,
size: 'mini',//颜色box类型
alpha: true,//是否开启透明度
defaultColor: this.labelLineColor,
disabled: false,//是否禁止打开颜色选择器
openPickerAni: 'opacity',//打开颜色选择器动画
sure: (color) => {
this.labelLineColor = color
},//点击确认按钮事件回调
clear: () => {
this.labelLineColor = 'rgba(0,255,255,0.5)'
},//点击清空按钮事件回调
})
this._elms.labelLineColor[i] = lineColorPicker
})
}
}
get labelBackgroundColorStart() {
return this.options.label.backgroundColor[0]
}
set labelBackgroundColorStart(v) {
this.options.label.backgroundColor[0] = v
this.label.backgroundColor = [v, this.label.backgroundColor[1]]
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.label.backgroundColor[0], 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 = `
<div class="tr">
<div class="td">` + this.options.attribute.link.content[i].name + `</div>
<div class="td">` + this.options.attribute.link.content[i].url + `</div>
<div class="td">
<button @click="linkEdit">编辑</button>
<button @click="linkDelete">删除</button>
</div>
</div>`
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 = `
<div class="td">
<input class="input" type="text">
</div>
<div class="td">
<textarea class="input link-edit" type="text"></textarea>
</div>
<div class="td">
<button @click="confirmEdit">确认</button>
<button @click="cancelEdit">取消</button>
</div>`
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++) {
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++) {
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
}
// 编辑框
async edit(state) {
if (this._error) {
return
}
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._DialogObject = await new Dialog(this.sdk, this.options, {
title: '编辑属性', left: '180px', top: '100px',
confirmCallBack: (options) => {
this.name = this.name.trim()
if (!this.name) {
this.name = '未命名对象'
}
this.options.label.position = { lng: this.label.position[0], lat: this.label.position[1], alt: this.label.position[2] }
this.originalOptions = this.deepCopyObj(this.options)
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
syncData(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.Dialog.closeCallBack && this.Dialog.closeCallBack()
for (let i = 0; i < this.nodePoints.length; i++) {
this.sdk.viewer.entities.remove(this.nodePoints[i])
}
this.nodePoints = []
YJ.Measure.SetMeasureStatus(false)
this.positionEditing = false
},
showCallBack: (show) => {
this.options.show = show
this.originalOptions.show = show
this.show = show
this.Dialog.showCallBack && this.Dialog.showCallBack()
},
translationalCallBack: () => {
this.positionEditing = !this.positionEditing
},
// 二次编辑回调
secondaryEditCallBack: () => {
PolyhedronObject.nodeEdit(this)
}
})
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' polyhedron'
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('polygon-object-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("labelColor")[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("labelLineColor")[0],
size: 'mini',//颜色box类型
alpha: true,//是否开启透明度
defaultColor: this.labelLineColor,
disabled: false,//是否禁止打开颜色选择器
openPickerAni: 'opacity',//打开颜色选择器动画
sure: (color) => {
this.labelLineColor = color
},//点击确认按钮事件回调
clear: () => {
this.labelLineColor = '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("*")
EventBinding.on(this, all_elm)
this._elms = EventBinding.element
this._elms.color = [colorPicker]
this._elms.labelColor = [labelColorPicker]
this._elms.labelLineColor = [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
}
}
})
}
let unitData = [{
name: '平方米',
value: '平方米'
},
{
name: '平方千米',
value: '平方千米'
},
{
name: '亩',
value: '亩'
},
{
name: '公顷',
value: '公顷'
},
]
let unitDataLegpObject = legp(this._DialogObject._element.content, ".input-select-unit")
unitDataLegpObject.legp_search(unitData)
let unitDataLegpElm = this._DialogObject._element.content.getElementsByClassName('input-select-unit')[0].getElementsByTagName('input')[0]
unitDataLegpElm.value = this.options['area-unit']
unitDataLegpElm.addEventListener('input', () => {
for (let i = 0; i < unitData.length; i++) {
if (unitData[i].value === unitDataLegpElm.value) {
this.areaUnit = unitData[i].value
break
}
}
})
}, 0);
} else {
if (this._DialogObject && this._DialogObject.remove) {
this._DialogObject.remove()
this._DialogObject = null
}
}
}
reset() {
if (!this.entity) {
return
}
this.options = this.deepCopyObj(this.originalOptions)
this.name = this.originalOptions.name
this.color = this.originalOptions.color
this.height = this.originalOptions.height
this.extrudedHeight = this.originalOptions.extrudedHeight
this.area = this.originalOptions.area
this.areaUnit = this.originalOptions['area-unit']
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()
let positions = this.options.positions
let fromDegreesArray = []
if (this.options.height || this.options.height === 0) {
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat, this.options.height + this.options.extrudedHeight)
}
this.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
}
else {
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
}
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(this.positions)
this.entity.wall.positions = [...this.positions, this.positions[0]]
}
async remove() {
this.event && this.event.destroy()
this.tip && this.tip.destroy()
this.label && this.label.remove()
this.sdk.viewer.entities.remove(this.entity)
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)
}
_addLink() {
if (this._DialogObject._element.content.getElementsByClassName('link_add')[0].value) {
this.options.attribute.link.content.push({
name: '链接',
url: this._DialogObject._element.content.getElementsByClassName('link_add')[0].value
})
this._DialogObject._element.content.getElementsByClassName('link_add')[0].value = ''
this.attributeLink = this.options.attribute.link.content
}
else {
this.Dialog.clickAddLink && this.Dialog.clickAddLink()
}
}
addAttributeLink(link) {
this.options.attribute.link.content.push({
name: '链接',
url: link
})
this.attributeLink = this.options.attribute.link.content
}
/**
* 打开富文本框
*/
openRichTextEditor(e) {
richText.open(this.options.id, this.options.name, this.options.richTextContent)
richText.primaryCallBack = (content) => {
this.options.richTextContent = content
}
}
static nodeEdit(that, cb = () => { }) {
// that.positionEditing = false
// that.event && that.event.destroy()
if (YJ.Measure.GetMeasureStatus()) {
cb('上一次测量未结束')
} else {
YJ.Measure.SetMeasureStatus(true)
that.tip = new MouseTip('请选择一个顶点,右键取消', that.sdk)
that.event = new MouseEvent(that.sdk)
that.nodePoints = []
let selectPoint
let originalPosition
that.event.mouse_left((movement, cartesian) => {
if (selectPoint) {
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
originalPosition = that.options.positions[selectPoint.index]
let entity = that.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
position: Cesium.Cartesian3.fromDegrees(that.options.positions[selectPoint.index].lng, that.options.positions[selectPoint.index].lat, that.options.extrudedHeight),
billboard: {
image: that.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
},
})
that.nodePoints.splice(selectPoint.index, 0, entity)
that.options.positions.splice(selectPoint.index, 0, that.options.positions[selectPoint.index])
that.options.areaByMeter = that.computeArea(that.options.positions);
switch (that.options['area-unit']) {
case '平方米':
that.area = that.options.areaByMeter
break;
case '平方千米':
that.area = Number((that.options.areaByMeter / 1000000).toFixed(8))
break;
case '亩':
that.area = Number((that.options.areaByMeter / 666.6666667).toFixed(4))
break;
case '公顷':
that.area = Number((that.options.areaByMeter / 10000).toFixed(6))
break;
default:
that.area = that.options.areaByMeter
}
}
else {
var pick = that.sdk.viewer.scene.pick(movement.position);
if (pick && pick.id && pick.id.name && pick.id.name === 'node-secondary-edit-point') {
selectPoint = pick.id
that.nodePoints.splice(pick.id.index, 1)
that.sdk.viewer.entities.remove(pick.id)
that.tip.set_text('左键开始右键结束CTRL+右键撤销')
originalPosition = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
}
}
})
that.event.mouse_right((movement, cartesian) => {
if (selectPoint) {
that.options.positions[selectPoint.index] = originalPosition
that.options.areaByMeter = that.computeArea(that.options.positions);
switch (that.options['area-unit']) {
case '平方米':
that.area = that.options.areaByMeter
break;
case '平方千米':
that.area = Number((that.options.areaByMeter / 1000000).toFixed(8))
break;
case '亩':
that.area = Number((that.options.areaByMeter / 666.6666667).toFixed(4))
break;
case '公顷':
that.area = Number((that.options.areaByMeter / 10000).toFixed(6))
break;
default:
that.area = that.options.areaByMeter
}
let positions = that.options.positions
let fromDegreesArray = []
let minimumHeights = [that.options.extrudedHeight]
for (let i = 0; i < positions.length; i++) {
minimumHeights.push(that.options.extrudedHeight)
fromDegreesArray.push(positions[i].lng, positions[i].lat, that.options.height + that.options.extrudedHeight)
}
that.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
that.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(that.positions)
that.entity.wall.positions = [...that.positions, that.positions[0]]
that.entity.wall.minimumHeights = minimumHeights
// let positions = []
// cache_positions.forEach((item) => {
// positions.push(this.cartesian3Towgs84(item, this.viewer))
// })
cb(null, that.options.positions)
}
for (let i = 0; i < that.nodePoints.length; i++) {
that.sdk.viewer.entities.remove(that.nodePoints[i])
}
that.nodePoints = []
YJ.Measure.SetMeasureStatus(false)
that.event.destroy()
that.tip.destroy()
})
that.event.mouse_move((movement, cartesian) => {
if (selectPoint) {
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
let positions = that.options.positions
let fromDegreesArray = []
let minimumHeights = [that.options.extrudedHeight]
for (let i = 0; i < positions.length; i++) {
minimumHeights.push(that.options.extrudedHeight)
fromDegreesArray.push(positions[i].lng, positions[i].lat, that.options.height + that.options.extrudedHeight)
}
that.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
that.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(that.positions)
that.entity.wall.positions = [...that.positions, that.positions[0]]
that.entity.wall.minimumHeights = minimumHeights
let labelPositions = [[]]
for (let i = 0; i < that.options.positions.length; i++) {
labelPositions[0].push([that.options.positions[i].lng, that.options.positions[i].lat])
}
labelPositions[0].push([that.options.positions[0].lng, that.options.positions[0].lat])
if (labelPositions[0].length >= 4) {
let polygon = turf.polygon(labelPositions);
let centroid = turf.centroid(polygon);
that.label.position = [centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], that.options.height + that.options.extrudedHeight]
}
}
that.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
that.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
if (selectPoint) {
that.options.positions.pop()
that.sdk.viewer.entities.remove(that.nodePoints[that.nodePoints.length - 1])
that.nodePoints.pop()
if (selectPoint.index === that.options.positions.length) {
if (that.nodePoints[selectPoint.index - 1]) {
selectPoint = that.nodePoints[selectPoint.index - 1]
}
else {
selectPoint.index = 0
}
}
}
})
for (let i = 0; i < that.options.positions.length; i++) {
let entity = that.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
index: i,
position: Cesium.Cartesian3.fromDegrees(that.options.positions[i].lng, that.options.positions[i].lat, that.options.extrudedHeight),
billboard: {
image: that.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
},
})
that.nodePoints.push(entity)
}
}
}
setDIV(options = { domid: "", x: 10, y: 10 }) {
options.x = (options.x || options.x === 0) ? options.x : 10
options.y = (options.y || options.y === 0) ? options.y : 10
let positions = [[]]
for (let i = 0; i < this.options.positions.length; i++) {
positions[0].push([this.options.positions[i].lng, this.options.positions[i].lat])
}
positions[0].push([this.options.positions[0].lng, this.options.positions[0].lat])
let polygon = turf.polygon(positions);
let centroid = turf.pointOnFeature(polygon);
let siteInfoDom = document.getElementById(options.domid)
// let siteInfoPosition = Cesium.Cartesian3.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], this.options.extrudedHeight + this.options.height)
this.sdk.viewer.scene.postRender.addEventListener((percentage) => {
let siteInfoPosition = Cesium.Cartesian3.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], this.options.extrudedHeight + this.options.height)
//转换到屏幕坐标
if (siteInfoDom.style.display === 'block' || siteInfoDom.style.display === '') {
let winpos = this.sdk.viewer.scene.cartesianToCanvasCoordinates(siteInfoPosition);
if (winpos) {
siteInfoDom.style.left = (winpos.x + options.x).toFixed(0) + 'px';
siteInfoDom.style.top = (winpos.y + options.y).toFixed(0) + 'px';
}
}
});
}
}
export default PolyhedronObject