Files
sdk4.0_new/src/Obj/Base/PolygonObject/index.js
2025-12-17 18:06:13 +08:00

2352 lines
80 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 LabelObject from '../LabelObject'
import MouseEvent from '../../../Event/index'
import MouseTip from '../../../MouseTip'
import { syncData } from '../../../Global/MultiViewportMode'
import { legp } from '../../Element/datalist'
import { getFontList, getFontFamilyName } from '../../Element/fontSelect'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../Global/global'
// import EditParticle from "../../ModelController/EditParticle";
class PolygonObject extends Base {
/**
* @constructor
* @description 多边形
* @param sdk
* @param options {object} 属性
* @param options.id {string} 唯一标识
* @param options.show=true {boolean} 显示/隐藏
* @param options.name {string} 名称
* @param options.color='rgba(255, 0, 0, 0.5)' {string} 颜色
* @param options.height {number} 高度
* @param options.heightMode=2{number} 高度模式0海拔高度1相对地表2依附模式
* @param options.line {object} 边框
* @param options.line.width=2 {string} 边框宽
* @param options.line.color="rgba(155, 155, 124, 0.89)" {string} 边框颜色
* @param {Array.<object>} options.positions 必填,经纬度和高度的列表,值交替 [{lon,lat,alt},...]
* @param options.positions[].lng {number} 经度
* @param options.positions[].lat {number} 纬度
* @param options.positions[].alt {number} 高度
* @param options.label {object} 标签对象
* @param options.label.text {string} 标签文本
* @param options.label.show {string} 标签显隐
* @param options.label.position {string} 标签位置
* @param options.label.position {object} 标签位置
* @param options.label.position.lng {number} 经度
* @param options.label.position.lat {number} 纬度
* @param options.label.position.alt {number} 高度
* @param options.label.fontSize=20 {number} 字体大小
* @param options.label.fontFamily=0 {number} 字体项 0黑体1思源黑体2庞门正道标题体3数黑体
* @param options.label.color=#ffffff {string} 字体颜色
* @param options.label.lineWidth=4 {number} 引线宽
* @param options.label.lineColor=#00ffff80 {string} 引线颜色
* @param options.label.pixelOffset=20 {number} 字体偏移(引线长度)
* @param options.label.backgroundColor=['#00ffff80', '#00ffff80'] {array} 背景颜色
* @param options.label.scaleByDistance {boolean} 距离缩放
* @param options.label.near=2000 {number} 视野缩放最近距离
* @param options.label.far=100000 {number} 视野缩放最远距离
* @param options.attribute {object} 属性内容
* @param {object} options.attribute.link={} 链接
* @param options.attribute.link.content=[]] {array} 链接内容
* @param options.attribute.link.content[].name {string} 链接名称
* @param options.attribute.link.content[].url {string} 链接地址
* @param options.richTextContent {string} 富文本内容
* @param options.customView {object} 默认视角
* @param options.customView.orientation {object} 默认视角方位
* @param options.customView.orientation.heading {number} 航向角
* @param options.customView.orientation.pitch {number} 俯仰角
* @param options.customView.orientation.roll {number} 翻滚角
* @param options.customView.relativePosition {object} 视角相对位置
* @param options.customView.relativePosition.lng {number} 经度
* @param options.customView.relativePosition.lat {number} 纬度
* @param options.customView.relativePosition.alt {number} 高度
*
*
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options)
this.options.name = options.name || '未命名对象'
this.options.color = options.color || 'rgba(255, 0, 0, 0.5)'
this.options.show =
options.show || options.show === false ? options.show : true
this.options.heightMode = (options.heightMode || options.heightMode == 0) ? options.heightMode : 2
this.options.positions = options.positions || []
this.options.line = options.line || {}
this.options.line.width = ((this.options.line.width || this.options.line.width === 0) ? this.options.line.width : 3)
this.options.line.color =
this.options.line.color || 'rgba(255, 0, 0, 1)'
this.entity
this.event = new MouseEvent(this.sdk)
this.operate = {}
this._elms = {}
this.Dialog = _Dialog
this.nodePoints = []
options.label = options.label || {}
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,
fontFamily: options.label.fontFamily ? options.label.fontFamily : 0,
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.attribute.camera.content =
// this.options.attribute.camera.content || []
// this.options.attribute.vr = this.options.attribute.vr || {}
// this.options.attribute.vr.content =
// this.options.attribute.vr.content || []
// this.options.attribute.goods = this.options.attribute.goods || {}
// this.options.attribute.goods.content =
// this.options.attribute.goods.content || []
delete this.options.attribute.camera
delete this.options.attribute.vr
delete this.options.attribute.goods
this.options.richTextContent = options.richTextContent || ''
if (!this.options.positions || this.options.positions.length < 3) {
this._error = '多边形最少需要三个坐标!'
console.warn(this._error)
} else {
if (!this.options.height && this.options.height !== 0) {
let height = this.options.positions[0].alt
for (let i = 1; i < this.options.positions.length; i++) {
if (height < this.options.positions[i].alt) {
height = this.options.positions[i].alt
}
}
this.options.height = height
}
this.sdk.addIncetance(this.options.id, this)
this._zIndex = this.sdk.entityMap.size
PolygonObject.create(this)
}
}
get type() {
return 'PolygonObject'
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v || 'rgba(255, 0, 0, 0.5)'
if (!this.sdk || !this.sdk.viewer || !this.entity || !this.entity.polygon) {
return
}
if (!this.sdk || !this.sdk.viewer || !this.entity || !this.entity.polygon) {
return
}
let material = Cesium.Color.fromCssColorString(this.options.color)
if (this.sdk.viewer.scene.mode === 2) {
this.heightMode = 0
material = new Cesium.CustomColorMaterialSource({
color: this.options.color
})
}
this.entity.polygon.material = material
if (this._elms.color) {
this._elms.color.forEach((item, i) => {
let colorPicker = new YJColorPicker({
el: item.el,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: this.options.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: c => {
this.color = c
}, //点击确认按钮事件回调
clear: () => {
this.color = 'rgba(255,0,0,0.5)'
} //点击清空按钮事件回调
})
this._elms.color[i] = colorPicker
})
}
}
get heightMode() {
return this.options.heightMode ? this.options.heightMode : 0
}
set heightMode(v) {
this.entity.polygon.hierarchy = []
setTimeout(() => {
this.options.heightMode = (v || v == 0) ? v : 2
this.positionEditing = false
if (!this.entity) {
return
}
let positions = this.options.positions
let heightModeName = ''
this.closeNodeEdit()
let ground = false
let disabled = false
this.renewPositions()
this.entity.polyline.positions = [
...this.positions,
this.positions[0],
this.positions[1]
]
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(
this.positions
)
switch (this.options.heightMode) {
case '0':
case 0:
heightModeName = '海拔高度'
break
case '1':
case 1:
heightModeName = '相对地表'
break
case '2':
case 2:
ground = true
disabled = true
heightModeName = '依附模型'
break
}
this.label.ground = ground
this.entity.polyline.clampToGround = ground
this.entity.polyline.arcType = !ground ? Cesium.ArcType.NONE : Cesium.ArcType.GEODESIC,
this.entity.polygon.perPositionHeight = !ground ? true : false
this._elms.heightMode && (this._elms.heightMode.value = heightModeName)
this._elms.heightModeObject && (this._elms.heightModeObject.legp_searchActive(
heightModeName
))
}, 50);
}
get height() {
return this.options.height
}
set height(v) {
if (!v || isNaN(Number(v))) {
this.options.height = 0
}
else {
this.options.height = Number(Number(v).toFixed(2))
}
let ground
if (this.heightMode == 2) {
ground = true
} else {
ground = false
}
this.renewPositions()
setTimeout(() => {
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(this.positions)
this.entity.polygon.perPositionHeight = !ground ? true : false
this.entity.polyline.positions = [
...this.positions,
this.positions[0],
this.positions[1]
]
this.entity.polyline.clampToGround = !ground ? false : true
this.entity.polyline.arcType = !ground ? Cesium.ArcType.NONE : Cesium.ArcType.GEODESIC
}, 0);
this._elms.alt &&
this._elms.alt.forEach(item => {
item.innerHTML = this.options.height
})
}
get lineColor() {
return this.options.line.color
}
set lineColor(v) {
this.options.line.color = v || 'rgba(255, 0, 0, 0.5)'
if (!this.sdk || !this.sdk.viewer || !this.entity || !this.entity.polyline) {
return
}
this.entity.polyline.material = Cesium.Color.fromCssColorString(this.options.line.color)
if (this._elms.lineColor) {
this._elms.lineColor.forEach((item, i) => {
let lineColorPicker = new YJColorPicker({
el: item.el,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: this.options.line.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: c => {
this.lineColor = c
}, //点击确认按钮事件回调
clear: () => {
this.lineColor = 'rgba(255,0,0,0.5)'
} //点击清空按钮事件回调
})
this._elms.lineColor[i] = lineColorPicker
})
}
}
get lineWidth() {
return this.options.line.width
}
set lineWidth(v) {
this.options.line.width = ((v || v === 0) ? v : 3)
this.entity.polyline.width = this.options.line.width
this._elms.lineWidth &&
this._elms.lineWidth.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 labelFontFamily() {
return this.options.label.fontFamily
}
set labelFontFamily(v) {
this.options.label.fontFamily = v || 0
this.label && (this.label.fontFamily = this.options.label.fontFamily)
let name = getFontFamilyName(this.labelFontFamily) || ''
this._elms.labelFontFamily &&
this._elms.labelFontFamily.forEach(item => {
item.value = name
})
}
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
})
}
}
static create(that) {
let ground
if (that.heightMode == 2) {
ground = true
} else {
ground = false
}
that.renewPositions()
let material = Cesium.Color.fromCssColorString(that.options.color)
if (that.sdk.viewer.scene.mode === 2) {
that.options.heightMode = 0
ground = false
material = new Cesium.CustomColorMaterialSource({
color: that.options.color
})
}
that.entity = that.sdk.viewer.entities.add({
show: that.options.show,
id: that.options.id,
polygon: {
hierarchy: new Cesium.PolygonHierarchy(that.positions),
perPositionHeight: !ground ? true : false,
material: material,
zIndex: that.sdk._entityZIndex
},
polyline: {
positions: [...that.positions, that.positions[0], that.positions[1]],
width: that.options.line.width,
arcType: Cesium.ArcType.NONE,
material: Cesium.Color.fromCssColorString(that.options.line.color),
clampToGround: !ground ? false : true,
arcType: !ground ? Cesium.ArcType.NONE : Cesium.ArcType.GEODESIC,
zIndex: that.sdk._entityZIndex
}
})
that.sdk._entityZIndex++
PolygonObject.createLabel(that)
syncData(that.sdk, that.options.id)
if (that.options.show) {
setSplitDirection(0, that.options.id)
}
}
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.centroid(polygon);
let centroid = turf.pointOnFeature(polygon)
let height = 0
let ground
switch (that.heightMode) {
case 0:
case '0':
ground = false
break
case 1:
case '1':
for (let i = 0; i < positions.length; i++) {
height = that.sdk.viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(positions[i].lng, positions[i].lat))
}
ground = false
break
case 2:
case '2':
ground = true
break
}
if (!ground) {
height = that.options.height + height
} else {
let objectsToExclude = [...that.sdk.viewer.entities.values]
height = await that.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
}
// if (!that.options.label.position) {
// that.options.label.position = {
// lng: centroid.geometry.coordinates[0],
// lat: centroid.geometry.coordinates[1],
// alt: height
// }
// }
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,
fontFamily: that.options.label.fontFamily,
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,
ground: ground
})
}
// 编辑框
async edit(state) {
return
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
function createSpatialInfoTableContent() {
let tableElm = contentElm.getElementsByClassName('spatial-info-table')[0]
let tBodyElm = tableElm.getElementsByClassName('table-body')[0]
tBodyElm.innerHTML = ''
_this._elms.lng = []
_this._elms.lngInput = []
_this._elms.lat = []
_this._elms.latInput = []
_this._elms.alt = []
_this._elms.altInput = []
for (let i = 0; i < _this.options.positions.length; i++) {
let tr = document.createElement('div')
tr.className = 'tr'
tr.innerHTML = `
<div class="td">${i + 1}</div>
<div class="td lng align-center"></div>
<div class="td lat align-center"></div>
<div class="td alt align-center"></div>
`
let lngBox = tr.getElementsByClassName('lng')[0]
let lng = document.createElement('span')
lng.innerHTML = (_this.options.positions[i].lng).toFixed(8)
lngBox.appendChild(lng)
let lngInput = document.createElement('input')
lngInput.className = 'input'
lngInput.type = 'number'
lngInput.title = ''
lngInput.min = -180
lngInput.max = 180
lngInput.value = (_this.options.positions[i].lng).toFixed(8)
let latBox = tr.getElementsByClassName('lat')[0]
let lat = document.createElement('span')
lat.innerHTML = (_this.options.positions[i].lat).toFixed(8)
latBox.appendChild(lat)
let latInput = document.createElement('input')
latInput.className = 'input'
latInput.type = 'number'
latInput.title = ''
latInput.min = -90
latInput.max = 90
latInput.value = (_this.options.positions[i].lat).toFixed(8)
let altBox = tr.getElementsByClassName('alt')[0]
let alt = document.createElement('span')
alt.innerHTML = (_this.height).toFixed(2)
altBox.appendChild(alt)
let altInput = document.createElement('input')
altInput.className = 'input'
altInput.type = 'number'
altInput.title = ''
altInput.min = -9999999
altInput.max = 999999999
altInput.value = (_this.height).toFixed(2)
lngBox.addEventListener('dblclick', () => {
lngBox.innerHTML = ''
lngInput.value = Number((_this.options.positions[i].lng).toFixed(8))
lngBox.appendChild(lngInput)
lngInput.focus()
if (_this.operate.positionEditing) {
_this.positionEditing = false
}
PolygonObject.closeNodeEdit(_this)
_this.heightMode = _this.heightMode
})
lngInput.addEventListener('blur', () => {
lngInput.value = Number((_this.options.positions[i].lng).toFixed(8))
lngBox.innerHTML = ''
lngBox.appendChild(lng)
})
lngInput.addEventListener('input', () => {
_this.options.positions[i].lng = Number(Number(lngInput.value).toFixed(8))
lng.innerHTML = _this.options.positions[i].lng.toFixed(8)
_this.height = _this.height
})
latBox.addEventListener('dblclick', () => {
latBox.innerHTML = ''
latInput.value = Number((_this.options.positions[i].lat).toFixed(8))
latBox.appendChild(latInput)
latInput.focus()
if (_this.operate.positionEditing) {
_this.positionEditing = false
}
PolygonObject.closeNodeEdit(_this)
_this.heightMode = _this.heightMode
})
latInput.addEventListener('blur', () => {
latInput.value = Number((_this.options.positions[i].lat).toFixed(8))
latBox.innerHTML = ''
latBox.appendChild(lat)
})
latInput.addEventListener('input', () => {
_this.options.positions[i].lat = Number(Number(latInput.value).toFixed(8))
lat.innerHTML = _this.options.positions[i].lat.toFixed(8)
_this.height = _this.height
})
altBox.addEventListener('dblclick', () => {
if (_this.heightMode == 2) {
return;
}
altBox.innerHTML = ''
altInput.value = Number((_this.height).toFixed(2))
altBox.appendChild(altInput)
altInput.focus()
if (_this.operate.positionEditing) {
_this.positionEditing = false
}
PolygonObject.closeNodeEdit(_this)
_this.heightMode = _this.heightMode
})
altInput.addEventListener('blur', () => {
altInput.value = Number((_this.height).toFixed(2))
altBox.innerHTML = ''
altBox.appendChild(alt)
})
altInput.addEventListener('input', () => {
_this.height = Number(Number(altInput.value).toFixed(2))
alt.innerHTML = Number(_this.height.toFixed(2))
})
_this._elms.lng.push(lng)
_this._elms.lngInput.push(lngInput)
_this._elms.lat.push(lat)
_this._elms.latInput.push(latInput)
_this._elms.alt.push(alt)
_this._elms.altInput.push(altInput)
tBodyElm.appendChild(tr)
}
}
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)
syncSplitData(this.sdk, this.options.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.previous = null
this.reset()
this.positionEditing = false
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.event && this.event.destroy()
this.tip && this.tip.destroy()
},
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: () => {
PolygonObject.nodeEdit(this, () => {
createSpatialInfoTableContent()
})
}
})
this._DialogObject._element.body.className =
this._DialogObject._element.body.className + ' polygon'
let contentElm = document.createElement('div')
contentElm.innerHTML = html(this)
this._DialogObject.contentAppChild(contentElm)
this.attributeType = this.options.attributeType
this.attributeCamera = this.options.attribute.camera.content
// 创建标签页
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 linecolorPicker = new YJColorPicker({
el: contentElm.getElementsByClassName('lineColor')[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 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 heightElm = this._DialogObject._element.body.getElementsByClassName(
// 'height'
// )[0]
// heightElm.value = this.height
// heightElm.addEventListener('input', e => {
// let value = e.target.value
// if (
// (e.data === '.' && value.indexOf('.') === -1) ||
// (e.data === '-' && value.indexOf('-') === -1)
// ) {
// } else {
// if (value) {
// value = Number(value)
// if (e.target.max && value > Number(e.target.max)) {
// value = Number(e.target.max)
// }
// if (e.target.min && value < Number(e.target.min)) {
// value = Number(e.target.min)
// }
// }
// this.height = value
// }
// })
let all_elm = contentElm.getElementsByTagName('*')
PolygonObject.EventBinding(this, all_elm)
// this._elms.height = [heightElm]
this._elms.color = [colorPicker]
this._elms.lineColor = [linecolorPicker]
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.attributeVr = this.options.attribute.vr.content
this.cameraSelect && this.cameraSelect()
this.goodsSelect && this.goodsSelect()
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.getElementsByClassName(
'input-select-unit-box'
)[0],
'.input-select-unit'
)
if (unitDataLegpObject) {
unitDataLegpObject.legp_search(unitData)
let unitDataLegpElm = this._DialogObject._element.content
.getElementsByClassName('input-select-unit')[0]
.getElementsByTagName('input')[0]
unitDataLegpElm.value = this.options['area-unit']
for (let i = 0; i < unitData.length; i++) {
if (unitData[i].value === unitDataLegpElm.value) {
unitDataLegpObject.legp_searchActive(unitData[i].value)
break
}
}
unitDataLegpElm.addEventListener('input', () => {
for (let i = 0; i < unitData.length; i++) {
if (unitData[i].value === unitDataLegpElm.value) {
this.areaUnit = unitData[i].value
break
}
}
})
}
let heightBoxElm = this._DialogObject._element.content.getElementsByClassName('height-box')[0]
let heightElm = heightBoxElm.getElementsByClassName('height')[0]
let heightConfirmElm = this._DialogObject._element.content.getElementsByClassName('height-confirm')[0]
heightElm.value = 10
if (this.heightMode == 2) {
heightBoxElm && (heightBoxElm.className = 'input-number input-number-unit-1 height-box disabled');
heightConfirmElm && heightConfirmElm.setAttribute('disabled', 'disabled');
}
else {
heightBoxElm && (heightBoxElm.className = 'input-number input-number-unit-1 height-box');
heightConfirmElm && heightConfirmElm.removeAttribute('disabled');
}
let heightModeData = [
{
name: '海拔高度',
value: '海拔高度',
key: '0',
},
{
name: '相对地表',
value: '相对地表',
key: '1',
},
{
name: '依附模型',
value: '依附模型',
key: '2',
}
]
let heightModeObject = legp(
this._DialogObject._element.content.getElementsByClassName(
'height-mode-box'
)[0],
'.height-mode'
)
if (heightModeObject) {
heightModeObject.legp_search(heightModeData)
let heightModeDataLegpElm = this._DialogObject._element.content
.getElementsByClassName('height-mode')[0]
.getElementsByTagName('input')[0]
for (let i = 0; i < heightModeData.length; i++) {
if (heightModeData[i].key == this.heightMode) {
heightModeDataLegpElm.value = heightModeData[i].value
heightModeObject.legp_searchActive(
heightModeData[i].value
)
break
}
}
heightModeDataLegpElm.addEventListener('input', () => {
for (let i = 0; i < heightModeData.length; i++) {
if (heightModeData[i].value === heightModeDataLegpElm.value) {
this.heightMode = heightModeData[i].key
break
}
}
})
heightElm.addEventListener('input', () => {
switch (this.heightMode) {
case 0:
case '0':
break;
case 1:
case '1':
break;
case 2:
case '2':
break;
}
})
this._elms.height = heightElm
this._elms.heightBox = heightBoxElm
this._elms.heightMode = heightModeDataLegpElm
this._elms.heightConfirm = heightConfirmElm
this._elms.heightModeObject = heightModeObject
heightConfirmElm.addEventListener('click', () => {
if (this.operate.positionEditing) {
this.positionEditing = false
this.height = this.height + Number(heightElm.value)
}
else {
PolygonObject.closeNodeEdit(this)
this.heightMode = this.heightMode
setTimeout(() => {
this.height = this.height + Number(heightElm.value)
}, 100);
}
// this.positionEditing = false
// for (let i = 0; i < this.options.positions.length; i++) {
// this.options.positions[i].alt = Number((this.options.positions[i].alt + Number(heightElm.value)).toFixed(2))
// this._elms.alt[i].innerHTML = this.options.positions[i].alt
// }
// this.renewPositions(this.options.positions)
// this.entity.polyline.positions = [
// ...this.positions,
// this.positions[0],
// this.positions[1]
// ]
// this.positionEditing = false
// PolygonObject.closeNodeEdit(this)
})
}
let fontData = getFontList()
let fontObject = legp(
this._DialogObject._element.content.getElementsByClassName(
'font-select-box'
)[0],
'.font-select'
)
if (fontObject) {
fontObject.legp_search(fontData)
let fontDataLegpElm = this._DialogObject._element.content
.getElementsByClassName('font-select')[0]
.getElementsByTagName('input')[0]
fontDataLegpElm.value = fontData[this.labelFontFamily].value
for (let i = 0; i < fontData.length; i++) {
if (fontData[i].value == fontDataLegpElm.value) {
fontObject.legp_searchActive(fontData[i].value)
break
}
}
fontDataLegpElm.addEventListener('input', () => {
for (let i = 0; i < fontData.length; i++) {
if (fontData[i].value === fontDataLegpElm.value) {
this.labelFontFamily = fontData[i].key
break
}
}
})
this._elms.labelFontFamily = [fontDataLegpElm]
}
createSpatialInfoTableContent()
}, 0)
} else {
if (this._DialogObject && this._DialogObject.remove) {
this._DialogObject.remove()
this._DialogObject = null
}
}
}
reset() {
if (!this.entity && !this._DialogObject) {
return
}
this.options = this.deepCopyObj(this.originalOptions)
this.name = this.originalOptions.name
this.color = this.originalOptions.color
this.lineColor = this.originalOptions.line.color
this.lineWidth = this.originalOptions.line.width
this.height = this.originalOptions.height
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.heightMode = this.options.heightMode
let positions = this.options.positions
let positions2 = [[]]
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
)
positions2[0].push([positions[i].lng, positions[i].lat])
}
positions2[0].push([positions[0].lng, positions[0].lat])
this.positions = Cesium.Cartesian3.fromDegreesArrayHeights(
fromDegreesArray
)
} else {
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
positions2[0].push([positions[i].lng, positions[i].lat])
}
positions2[0].push([positions[0].lng, positions[0].lat])
this.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
}
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(this.positions)
this.entity.polyline.positions = [
...this.positions,
this.positions[0],
this.positions[1]
]
}
/**
* 飞到
*/
async flyTo(options = {}) {
if (this._error) {
return
}
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 = []
let ground
switch (this.heightMode) {
case 0:
case '0':
ground = false
break
case 1:
case '1':
ground = false
break
case 2:
case '2':
ground = true
break
}
if (ground) {
for (let i = 0; i < this.options.positions.length; i++) {
let height = await this.getClampToHeight(this.options.positions[i])
let a = Cesium.Cartesian3.fromDegrees(
this.options.positions[i].lng,
this.options.positions[i].lat,
height
)
positionArray.push(a.x, a.y, a.z)
}
} else {
if (this.positions) {
for (let i = 0; i < this.positions.length; i++) {
positionArray.push(this.positions[i].x, this.positions[i].y, this.positions[i].z)
}
}
}
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
offset: options.orientation || {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-90.0),
roll: Cesium.Math.toRadians(0.0)
}
})
}
}
/**
* 删除
*/
async remove() {
this.event && this.event.destroy()
this.tip && this.tip.destroy()
this.sdk.viewer.entities.remove(this.entity)
this.label && this.label.remove()
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)
}
/**@desc 打开平移功能
*
* @memberOf Source
* @param status {boolean}
*
* */
set positionEditing(status) {
this.closeNodeEdit()
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
if (status === true) {
this.previous = {
positions: [...this.positions]
}
this.tip && this.tip.destroy()
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
this.label &&
(this.label.entity.billboard.color = Cesium.Color.fromCssColorString(
`rgba(255,255,255,0.9)`
))
this.picking = false
let array = []
let positions = [...this.positions]
let positions84 = this.deepCopyObj(this.options.positions)
let fromDegreesArray = []
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++) {
disparity.push({
x: center.x - positions[i].x,
y: center.y - positions[i].y,
z: center.z - positions[i].z
})
}
let newpositions = []
let leftEvent = (movement, cartesian) => {
let position84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
newpositions = []
for (let i = 0; i < disparity.length; i++) {
let pos3 = {
x: cartesian.x - disparity[i].x,
y: cartesian.y - disparity[i].y,
z: cartesian.z - disparity[i].z
}
newpositions.push(pos3)
this.options.positions[i] = this.cartesian3Towgs84(
pos3,
this.sdk.viewer
)
if (_this._elms.lng && _this._elms.lng[i]) {
_this._elms.lng[i].innerHTML = this.options.positions[i].lng.toFixed(8)
}
if (_this._elms.lat && _this._elms.lat[i]) {
_this._elms.lat[i].innerHTML = this.options.positions[i].lat.toFixed(8)
}
}
this.previous = null
fromDegreesArray = []
this.heightMode = this.heightMode
if (this._positionEditingCallback) {
this._positionEditingCallback()
this._positionEditingCallback = null
}
}
this.event.mouse_move((movement, cartesian) => {
let position84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
newpositions = []
for (let i = 0; i < disparity.length; i++) {
let pos3 = {
x: cartesian.x - disparity[i].x,
y: cartesian.y - disparity[i].y,
z: cartesian.z - disparity[i].z
}
newpositions.push(pos3)
positions84[i] = this.cartesian3Towgs84(
pos3,
this.sdk.viewer
)
}
let ground = false
let array = []
for (let i = 0; i < positions84.length; i++) {
array.push([positions84[i].lng, positions84[i].lat])
}
array.push([positions84[0].lng, positions84[0].lat])
let height = 0
let polygon = turf.polygon([array])
let centroid = turf.centroid(polygon)
switch (this.options.heightMode) {
case '0':
case 0:
ground = false
break
case '1':
case 1:
height = this.sdk.viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1]))
ground = false
break
case '2':
case 2:
ground = true
break
}
fromDegreesArray = []
if (!ground) {
for (let i = 0; i < positions84.length; i++) {
fromDegreesArray.push(
positions84[i].lng,
positions84[i].lat,
this.height + height
)
}
this.positions = Cesium.Cartesian3.fromDegreesArrayHeights(
fromDegreesArray
)
this.label.position = [position84.lng, position84.lat, this.height + height]
} else {
for (let i = 0; i < positions84.length; i++) {
fromDegreesArray.push(positions84[i].lng, positions84[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let objectsToExclude = [...this.sdk.viewer.entities.values]
this.getClampToHeight({
lng: position84.lng,
lat: position84.lat
}, objectsToExclude).then(height => {
this.label.position = [position84.lng, position84.lat, height]
})
}
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
this.event.mouse_left(leftEvent)
this.event.mouse_right((movement, cartesian) => {
this.heightMode = this.heightMode
})
this.event.gesture_pinck_start((movement, cartesian) => {
let startTime = new Date()
let pos = {
position: {
x: (movement.position1.x + movement.position2.x) / 2,
y: (movement.position1.y + movement.position2.y) / 2
}
}
this.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
this.positionEditing = false
} else {
leftEvent(pos, cartesian)
}
})
})
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(_this.positions)
}, false)
this.entity.polyline.positions = new Cesium.CallbackProperty(function () {
return [..._this.positions, _this.positions[0], _this.positions[1]]
}, false)
} else {
if (!this.previous) {
this.previous = {
positions: [...this.positions]
}
}
else {
this.positions = [...this.previous.positions]
}
if (!this.sdk || !this.sdk.viewer || !this.label || !this.label.entity) {
this.label.entity.billboard.color = Cesium.Color.fromCssColorString(
`rgba(255,255,255,1)`
)
}
this.picking = true
if (this.event) {
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.event.destroy()
}
this.tip && this.tip.destroy()
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)
let ground = false
let height = 0
switch (this.options.heightMode) {
case '0':
case 0:
ground = false
break
case '1':
case 1:
height = this.sdk.viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1]))
ground = false
break
case '2':
case 2:
ground = true
break
}
if (!ground) {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
this.height + height
]
} else {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1]
]
}
this.entity.polygon.hierarchy = new Cesium.PolygonHierarchy(_this.previous.positions)
this.entity.polyline.positions = [
..._this.previous.positions,
_this.previous.positions[0],
_this.previous.positions[1]
]
this.previous = null
}
}
get positionEditing() {
return this.operate.positionEditing
}
openPositionEditing(cd) {
this.positionEditing = true
this._positionEditingCallback = cd
}
get areaChangeCallBack() {
return this._areaChangeCallBack
}
set areaChangeCallBack(cd) {
this._areaChangeCallBack = cd
}
nodeEdit(cb = () => { }) {
this.positionEditing = false
setTimeout(() => {
let previous = [...this.options.positions]
if (YJ.Measure.GetMeasureStatus()) {
cb('上一次测量未结束')
} else {
YJ.Measure.SetMeasureStatus(true)
this.picking = false
this.tip = new MouseTip('左键单击选择控制点,右键单击取消编辑', this.sdk)
this.event = new MouseEvent(this.sdk)
this.nodePoints = []
let _this = this
let selectPoint
let originalPosition
let newpositions = []
let fromDegreesArray = []
for (let i = 0; i < this.options.positions.length; i++) {
fromDegreesArray.push(
this.options.positions[i].lng,
this.options.positions[i].lat
)
}
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let added = false
let leftEvent = async (movement, cartesian) => {
let objectsToExclude = [...this.sdk.viewer.entities.values]
if (selectPoint) {
this.options.positions[selectPoint.index] = this.cartesian3Towgs84(
cartesian,
this.sdk.viewer
)
originalPosition = this.options.positions[selectPoint.index]
added = true
let potHeight = await this.getClampToHeight(
this.options.positions[selectPoint.index], objectsToExclude
)
let entity = this.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
position: Cesium.Cartesian3.fromDegrees(
this.options.positions[selectPoint.index].lng,
this.options.positions[selectPoint.index].lat,
potHeight
),
billboard: {
image: this.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
}
})
this.nodePoints.splice(selectPoint.index, 0, entity)
this.options.positions.splice(
selectPoint.index,
0,
this.options.positions[selectPoint.index]
)
let positions = this.options.positions
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
if (this.options.positions.length < 3) {
this
.getClampToHeight({
lng: this.options.positions[0].lng,
lat: this.options.positions[0].lat
}, objectsToExclude)
.then(height => {
this.label.position = [
this.options.positions[0].lng,
this.options.positions[0].lat,
height
]
})
} else {
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
.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
.then(height => {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
]
})
}
this.areaByMeter = this.computeArea(this.options.positions)
this.areaChangeCallBack && this.areaChangeCallBack()
cb(null, this.options.positions, this.areaByMeter)
// switch (this.options['area-unit']) {
// 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
// }
} else {
var pick = this.sdk.viewer.scene.pick(movement.position)
if (
pick &&
pick.id &&
pick.id.name &&
pick.id.name === 'node-secondary-edit-point'
) {
selectPoint = pick.id
this.nodePoints.splice(pick.id.index, 1)
this.sdk.viewer.entities.remove(pick.id)
this.tip.set_text('左键单击确定控制点位置,右键单击结束编辑! CTRL+右键单击撤销上一个控制点')
originalPosition = this.cartesian3Towgs84(
selectPoint.position.getValue(),
this.sdk.viewer
)
}
}
}
let rightEvent = (movement, cartesian) => {
if (selectPoint) {
this.options.positions[selectPoint.index] = originalPosition
// this.options.positions.splice(selectPoint.index, 1)
if (added) {
this.options.positions.splice(selectPoint.index, 1)
}
if (this.options.positions.length < 3) {
this.options.positions = [...previous]
let positions = this.options.positions
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
this.previous = {
positions: [...this.positions]
}
let objectsToExclude = [...this.sdk.viewer.entities.values]
let positions2 = [[]]
for (let i = 0; i < this.options.positions.length; i++) {
positions2[0].push([
this.options.positions[i].lng,
this.options.positions[i].lat
])
}
positions2[0].push([
this.options.positions[0].lng,
this.options.positions[0].lat
])
let polygon = turf.polygon(positions2)
let centroid = turf.centroid(polygon)
this
.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
.then(height => {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
]
})
this.areaByMeter = this.computeArea(this.options.positions)
this.areaChangeCallBack && this.areaChangeCallBack()
}
cb(null, this.options.positions)
}
YJ.Measure.SetMeasureStatus(false)
this.event.destroy()
this.tip.destroy()
this.heightMode = this.heightMode
}
this.entity.polyline.clampToGround = true
this.entity.polyline.arcType = Cesium.ArcType.GEODESIC
this.entity.polygon.perPositionHeight = false
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(newpositions)
}, false)
this.entity.polyline.positions = new Cesium.CallbackProperty(function () {
if (newpositions.length >= 3) {
return [
...newpositions,
newpositions[0],
newpositions[1],
newpositions[2]
]
} else {
return newpositions
}
}, false)
let objectsToExclude = [...this.sdk.viewer.entities.values]
if (this.options.positions.length < 3) {
this
.getClampToHeight({
lng: this.options.positions[0].lng,
lat: this.options.positions[0].lat
}, objectsToExclude)
.then(height => {
this.label.position = [
this.options.positions[0].lng,
this.options.positions[0].lat,
height
]
})
} else {
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)
setTimeout(() => {
this
.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
.then(height => {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
]
})
}, 200);
}
setTimeout(() => {
this.event.mouse_left(leftEvent)
this.event.mouse_right(rightEvent)
this.event.mouse_move((movement, cartesian) => {
if (selectPoint) {
this.options.positions[selectPoint.index] = this.cartesian3Towgs84(
cartesian,
this.sdk.viewer
)
let positions = this.options.positions
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let objectsToExclude = [...this.sdk.viewer.entities.values]
if (this.options.positions.length < 3) {
this
.getClampToHeight({
lng: this.options.positions[0].lng,
lat: this.options.positions[0].lat
}, objectsToExclude)
.then(height => {
this.label.position = [
this.options.positions[0].lng,
this.options.positions[0].lat,
height
]
})
} else {
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
.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
.then(height => {
this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
]
})
}
}
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
this.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
if (selectPoint) {
this.options.positions.pop()
this.sdk.viewer.entities.remove(
this.nodePoints[this.nodePoints.length - 1]
)
if (selectPoint.index === this.options.positions.length) {
if (this.nodePoints[selectPoint.index - 1]) {
selectPoint = this.nodePoints[selectPoint.index - 1]
} else {
selectPoint.index = 0
}
}
this.nodePoints.pop()
if(this.options.positions.length < 3) {
this.tip.set_text('左键单击确定控制点位置,右键单击取消编辑! CTRL+右键单击撤销上一个控制点')
}
}
})
this.event.gesture_pinck_start((movement, cartesian) => {
let startTime = new Date()
let pos = {
position: {
x: (movement.position1.x + movement.position2.x) / 2,
y: (movement.position1.y + movement.position2.y) / 2
}
}
this.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
rightEvent(pos, cartesian)
} else {
leftEvent(pos, cartesian)
}
})
})
createNodePoints()
}, 200);
async function createNodePoints() {
// sdk.viewer.scene.primitives
let objectsToExclude = [..._this.sdk.viewer.entities.values]
for (let i = 0; i < _this.options.positions.length; i++) {
let height = await _this.getClampToHeight(_this.options.positions[i], objectsToExclude)
let entity = _this.sdk.viewer.entities.add({
name: 'node-secondary-edit-point',
index: i,
position: Cesium.Cartesian3.fromDegrees(
_this.options.positions[i].lng,
_this.options.positions[i].lat,
height
),
billboard: {
image: _this.getSourceRootPath() + '/img/point.png',
width: 15,
height: 15,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
color: Cesium.Color.WHITE.withAlpha(0.99)
}
})
_this.nodePoints.push(entity)
}
}
}
}, 50);
}
closeNodeEdit() {
if (!this.sdk || !this.sdk.viewer) {
return
}
YJ.Measure.SetMeasureStatus(false)
this.event && this.event.destroy()
this.tip && this.tip.destroy()
this.tip = null
for (let i = 0; i < this.nodePoints.length; i++) {
this.sdk.viewer.entities.remove(this.nodePoints[i])
}
this.nodePoints = []
this.picking = true
}
setPosition(v) {
let cartesian = Cesium.Cartesian3.fromDegrees(
v.position.lng,
v.position.lat,
v.position.alt
)
let positions = [...this.positions]
let array = []
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++) {
disparity.push({
x: center.x - positions[i].x,
y: center.y - positions[i].y,
z: center.z - positions[i].z
})
}
let newpositions = []
for (let i = 0; i < disparity.length; i++) {
newpositions.push({
x: cartesian.x - disparity[i].x,
y: cartesian.y - disparity[i].y,
z: cartesian.z - disparity[i].z
})
}
let ground = false
let height = 0
switch (this.options.heightMode) {
case '0':
case 0:
ground = false
break
case '1':
case 1:
height = this.sdk.viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1]))
ground = false
break
case '2':
case 2:
ground = true
break
}
if (!ground) {
this.label.position = [v.position.lng, v.position.lat, v.position.alt + height]
} else {
let objectsToExclude = [...this.sdk.viewer.entities.values]
this.getClampToHeight({ lng: v.position.lng, lat: v.position.lat }, objectsToExclude).then(
height => {
this.label.position = [v.position.lng, v.position.lat, height]
}
)
}
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
if (newpositions.length > 0) {
return new Cesium.PolygonHierarchy(newpositions)
} else {
return new Cesium.PolygonHierarchy(positions)
}
}, false)
this.entity.polyline.positions = new Cesium.CallbackProperty(function () {
if (newpositions.length > 0) {
return [...newpositions, newpositions[0], newpositions[1]]
} else {
return [...positions, positions[0], positions[1]]
}
}, false)
}
// 更新坐标
renewPositions() {
if (this._error) {
return
}
let ground = false
let array = []
let positions = this.options.positions
for (let i = 0; i < positions.length; i++) {
array.push([positions[i].lng, positions[i].lat])
}
array.push([positions[0].lng, positions[0].lat])
let height = 0
let polygon = turf.polygon([array])
let centroid = turf.centroid(polygon)
switch (this.options.heightMode) {
case '0':
case 0:
ground = false
break
case '1':
case 1:
height = this.sdk.viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1])) || 0
ground = false
break
case '2':
case 2:
ground = true
break
}
let fromDegreesArray = []
if (!ground && this.nodePoints.length == 0) {
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(
positions[i].lng,
positions[i].lat,
this.height + height
)
}
this.positions = Cesium.Cartesian3.fromDegreesArrayHeights(
fromDegreesArray
)
this.label && (this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
this.height + height
])
} else {
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
this.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
setTimeout(() => {
if (!this.sdk.viewer) {
return
}
let objectsToExclude = [...this.sdk.viewer.entities.values]
this.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude).then(height => {
this.label && (this.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
])
})
}, 100)
}
// 计算投影面积
this.areaByMeter = this.computeArea(positions)
this.areaChangeCallBack && this.areaChangeCallBack()
return fromDegreesArray
}
async 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 height
if (!ground) {
height = this.options.height
} else {
let objectsToExclude = [...this.sdk.viewer.entities.values]
height = await this.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
}
let siteInfoDom = document.getElementById(options.domid)
let siteInfoPosition = Cesium.Cartesian3.fromDegrees(
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
)
this.sdk.viewer.scene.postRender.addEventListener(percentage => {
//转换到屏幕坐标
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 PolygonObject