代码迁移

This commit is contained in:
zh
2025-07-03 13:54:01 +08:00
parent b04de8a084
commit 2a4da33e62
985 changed files with 358292 additions and 13 deletions

View File

@ -0,0 +1,57 @@
function html() {
return `
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" type="text" @model="text">
</div>
<div class="col">
<span class="label">文字厚度</span>
<input class="input" type="number" title="" min="0" max="9999999" @model="extrudedHeight">
</div>
</div>
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
</div>
<div class="col">
<span class="label">文字颜色</span>
<div class="color"></div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
</div>
<div class="col">
<span class="label" style="flex: 0 0 70px;">高度</span>
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
</div>
</div>
`
}
function css() {
return `
.YJ-custom-base-dialog>.content {
width: 600px;
}
.YJ-custom-base-dialog>.content>div>.row .col {
margin: 0 10px;
}
.YJ-custom-base-dialog>.content>div>.row .col:first-child {
margin-left: 0;
}
.YJ-custom-base-dialog>.content>div>.row .col:last-child {
margin-right: 0;
}
.YJ-custom-base-dialog>.content>div>.row .label {
flex: 0 0 42px;
}
.YJ-custom-base-dialog>.content .DIV-cy-tab-content-pane .input-select {
width: 100px;
}
`
}
export { html, css }

View File

@ -0,0 +1,536 @@
// 3D文字(未完成)
import Base from "../../index";
import Dialog from '../../../Element/Dialog';
import { html, css } from "./_element";
import MouseEvent from '../../../../Event'
import { FontLoader } from '../../../../../static/3rdparty/three/jsm/loaders/FontLoader.js';
import { TextGeometry } from '../../../../../static/3rdparty/three/jsm/geometries/TextGeometry.js';
import * as variable from '../../../../../static/3rdparty/three/fonts/FZZongYi-M05S_regular.typeface.json'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
class Text3D extends Base {
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options);
this.options.positions = options.positions = options.positions || {}
this.options.positions.lng = options.positions.lng
this.options.positions.lat = options.positions.lat
this.options.positions.alt = options.positions.alt
this.options.color = options.color || "#00d9ff"
this.options.text = options.text || "未命名对象"
this.options.extrudedHeight = options.extrudedHeight || 10
this.operate = {}
this.Dialog = _Dialog
this._elms = {};
this.event = new MouseEvent(this.sdk)
this.sdk.addIncetance(this.options.id, this)
Text3D.create(this)
}
get text() {
return this.options.text
}
set text(v) {
this.options.text = v
this.update()
this._elms.text && this._elms.text.forEach((item) => {
item.value = v
})
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
this.entity.appearance.material = new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: Cesium.Color.fromCssColorString(this.options.color)
}
}
})
if (this._elms.color) {
this._elms.color.forEach((item, i) => {
let colorPicker = new ewPlugins('colorpicker', {
el: item.el,
size: 'mini',//颜色box类型
alpha: true,//是否开启透明度
defaultColor: v,
disabled: false,//是否禁止打开颜色选择器
openPickerAni: 'opacity',//打开颜色选择器动画
sure: (c) => {
this.color = c
},//点击确认按钮事件回调
clear: () => {
this.color = 'rgba(255,255,255,1)'
},//点击清空按钮事件回调
})
this._elms.color[i] = colorPicker
})
}
}
get extrudedHeight() {
return this.options.extrudedHeight
}
set extrudedHeight(v) {
this.options.extrudedHeight = v
this.update()
this._elms.extrudedHeight && this._elms.extrudedHeight.forEach((item) => {
item.value = v
})
}
get lng() {
return this.options.positions.lng
}
set lng(v) {
this.options.positions.lng = v
this.update()
this._elms.lng && this._elms.lng.forEach((item) => {
item.value = v
})
}
get lat() {
return this.options.positions.lat
}
set lat(v) {
this.options.positions.lat = v
this.update()
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = v
})
}
get alt() {
return this.options.positions.alt
}
set alt(v) {
this.options.positions.alt = v
this.update()
this._elms.alt && this._elms.alt.forEach((item) => {
item.value = v
})
}
static create(that) {
const loader = new FontLoader();
let textGeo = new TextGeometry(that.options.text, {
font: loader.parse(variable.default),
height: 0,
size: 1,
depth: 0,
curveSegments: 2,
bevelEnabled: false
});
if(!textGeo || !textGeo.attributes) {
return
}
let data = textGeo.attributes.position.array
let fromDegreesArray = []
for (let i = 0; i < data.length; i += 3) {
fromDegreesArray.push(data[i] + that.lng, data[i + 1] + that.lat, data[i + 2])
}
const instances = []
for (let i = 0; i < fromDegreesArray.length; i += 9) {
let instance = new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([fromDegreesArray[i], fromDegreesArray[i + 1], fromDegreesArray[i + 2], fromDegreesArray[i + 3], fromDegreesArray[i + 4], fromDegreesArray[i + 5], fromDegreesArray[i + 6], fromDegreesArray[i + 7], fromDegreesArray[i + 8]])),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
extrudedHeight: that.alt + that.extrudedHeight,
height: that.alt
})
});
instances.push(instance)
}
that.entity = that.sdk.viewer.scene.primitives.add(new Cesium.Primitive({
// allowPicking: false,
asynchronous: false,
releaseGeometryInstances: false,
geometryInstances: instances,
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: Cesium.Color.fromCssColorString(that.options.color)
}
}
})
})
}));
if(that.options.show) {
setSplitDirection(0, that.options.id)
}
// setTimeout(() => {
// let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(100, 20, 0))
// that.entity.modelMatrix = Cesium.Matrix4.multiply(that.entity.modelMatrix, m, new Cesium.Matrix4())
// }, 5000);
}
// 编辑框
async edit(state) {
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
this._element_style = null
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._element_style = document.createElement('style');
this._element_style.type = 'text/css';
this._element_style.setAttribute('data-name', 'YJ_style_dialog');
this._element_style.innerHTML = css();
this._DialogObject = await new Dialog(this.sdk, this.options, {
title: '编辑属性', left: '180px', top: '100px',
confirmCallBack: (options) => {
this.text = this.text.trim()
if (!this.text) {
this.text = '未命名对象'
}
this.originalOptions = this.deepCopyObj(this.options)
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.reset()
this.positionEditing = false
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
showCallBack: (show) => {
this.options.show = show
this.originalOptions.show = show
this.show = show
this.Dialog.showCallBack && this.Dialog.showCallBack()
},
translationalCallBack: () => {
this.positionEditing = !this.positionEditing
},
})
document.getElementsByTagName('head')[0].appendChild(this._element_style);
let contentElm = document.createElement('div');
contentElm.innerHTML = html(this)
this._DialogObject.contentAppChild(contentElm)
// setTimeout(() => {
// this.attributeLink = this.options.attribute.link.content
// this.cameraSelect()
// }, 500);
// 创建标签页
// let tabsElm = new cy_tabs('radar-scan-edit-tabs')
// 颜色组件
let colorPicker = new ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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("*")
Text3D.EventBinding(this, all_elm)
this._elms.color = [colorPicker]
this._elms.labelColor = [labelColorPicker]
this._elms.labelLineColor = [lineColorPicker]
this._elms.labelBackgroundColorStart = [labelBackgroundColorStartPicker]
this._elms.labelBackgroundColorEnd = [labelBackgroundColorEndPicker]
} else {
if (this._element_style) {
document.getElementsByTagName('head')[0].removeChild(this._element_style)
this._element_style = null
}
if (this._DialogObject && this._DialogObject.remove) {
this._DialogObject.remove()
this._DialogObject = null
}
}
}
/**@desc 打开平移功能
*
* @memberOf Source
* @param status {boolean}
*
* */
set positionEditing(status) {
if (!this.sdk || !this.sdk.viewer || !this.entity) {
return
}
this.operate.positionEditing = status
if (status === true) {
this.picking = false
this.previous = {
positions: { ...this.options.positions }
}
this.event.mouse_move((movement, cartesian) => {
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.options.positions.lng = positions.lng
this.options.positions.lat = positions.lat
this.options.positions.alt = positions.alt
})
this.event.mouse_left((movement, cartesian) => {
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.options.positions.lng = positions.lng
this.options.positions.lat = positions.lat
this.options.positions.alt = positions.alt
this.previous = {
positions: { ...this.options.positions }
}
this.update()
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.positionEditing = false
})
this.event.mouse_right((movement, cartesian) => {
this.positionEditing = false
})
}
else {
this.picking = true
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.options.positions.lng = this.previous.positions.lng
this.options.positions.lat = this.previous.positions.lat
this.options.positions.alt = this.previous.positions.alt
}
}
get positionEditing() {
return this.operate.positionEditing
}
update() {
if (this.entity) {
let modelMatrix = this.entity.modelMatrix
const loader = new FontLoader();
let textGeo = new TextGeometry(this.options.text, {
font: loader.parse(variable.default),
height: 0,
size: 1,
depth: 0,
curveSegments: 2,
bevelEnabled: false
});
if(!textGeo ||!textGeo.attributes) {
return
}
let data = textGeo.attributes.position.array
let fromDegreesArray = []
for (let i = 0; i < data.length; i += 3) {
fromDegreesArray.push(data[i] + this.lng, data[i + 1] + this.lat, data[i + 2])
}
const instances = []
for (let i = 0; i < fromDegreesArray.length; i += 9) {
var instance = new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([fromDegreesArray[i], fromDegreesArray[i + 1], fromDegreesArray[i + 2], fromDegreesArray[i + 3], fromDegreesArray[i + 4], fromDegreesArray[i + 5], fromDegreesArray[i + 6], fromDegreesArray[i + 7], fromDegreesArray[i + 8]])),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
extrudedHeight: this.alt + this.extrudedHeight,
height: this.alt
})
});
instances.push(instance)
}
this.sdk.viewer.scene.primitives.remove(this.entity)
this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({
// allowPicking: false,
asynchronous: false,
releaseGeometryInstances: false,
geometryInstances: instances,
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: new Cesium.Material({
fabric: {
type: 'Color',
uniforms: {
color: Cesium.Color.fromCssColorString(this.options.color)
}
}
})
})
}));
this.entity.modelMatrix = modelMatrix
// this.lng = this.options.positions.lng
}
}
static EventBinding(that, elements) {
for (let i = 0; i < elements.length; i++) {
let Event = []
let isEvent = false
let removeName = []
if (!elements[i] || !elements[i].attributes) {
continue;
}
for (let m of elements[i].attributes) {
switch (m.name) {
case '@model': {
isEvent = true
if (elements[i].type == 'checkbox') {
Event.push((e) => { that[m.value] = e.target.checked })
elements[i].checked = that[m.value]
}
else {
Event.push((e) => {
let value = e.target.value
if (e.target.type == 'number') {
if (e.data != '.' && (e.data != '-' || e.target.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)
}
that[m.value] = value
}
}
else {
that[m.value] = value
}
})
if (elements[i].nodeName == 'IMG') {
elements[i].src = that[m.value]
}
else {
elements[i].value = that[m.value]
}
}
if (that._elms[m.value]) {
that._elms[m.value].push(elements[i])
}
else {
that._elms[m.value] = [elements[i]]
}
removeName.push(m.name)
break;
}
case '@click': {
elements[i].addEventListener('click', (e) => {
if (typeof (that[m.value]) === 'function') {
that[m.value](e)
}
});
removeName.push(m.name)
// elements[i].attributes.removeNamedItem(m.name)
break;
}
case '@change': {
isEvent = true
Event.push((e) => {
let value = e.target.value
if (e.target.type == 'number' && value != '') {
value = Number(value)
e.target.value = value
}
if (typeof (that[m.value]) === 'function') {
that[m.value](e, value)
}
})
break;
}
}
// elements[i].attributes[m] = undefined
}
for (let n = 0; n < removeName.length; n++) {
elements[i].attributes.removeNamedItem(removeName[n])
}
if (isEvent) {
let ventType = 'input'
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
ventType = 'change'
}
elements[i].addEventListener(ventType, (e) => {
for (let t = 0; t < Event.length; t++) {
Event[t](e)
}
});
}
}
}
}
export default Text3D

View File

@ -0,0 +1,67 @@
function html() {
return `
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<textarea @model="text"></textarea>
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
</div>
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">旋转角度</span>
<input type="range" max="360" min="0" step="1" @model="angle">
<div class="input-number input-number-unit" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="360" step="1" @model="angle">
<span class="unit">°</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">调整大小</span>
<input type="range" max="100000" min="0" step="0.01" @model="scale">
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="100000" step="0.01" @model="scale">
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">滚动速度</span>
<input type="range" max="100" min="0" step="1" @model="speed">
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="100" step="1" @model="speed">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
`
}
export { html }

View File

@ -0,0 +1,661 @@
import Dialog from '../../../Element/Dialog'
import EventBinding from '../../../Element/Dialog/eventBinding'
import { html } from './_element'
import Base from '../../index'
import MouseEvent from '../../../../Event/index'
import { syncData } from '../../../../Global/MultiViewportMode'
import MouseTip from '../../../../MouseTip'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
class GroundText extends Base {
/**
* @constructor
* @param sdk
* @description 贴地文字
* @param options {object} 属性
* @param options.show=true {boolean} 显示/隐藏
* @param options.text {string} 文字
* @param options.angle=0 {number} 旋转角度
* @param options.scale=1 {number} 比例
* @param {object} options.position 经纬度{lon,lat}
* @param {object} options.positions 经纬度集[{lon,lat}]仅在未定义 position 时有效
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options)
this.options.text = options.text || '未命名对象'
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
}
this.options.text = textArray.join('\n')
this.options.name = this.options.text
this.options.show =
options.show || options.show === false ? options.show : true
this.options.angle = options.angle || 0
this.options.scale =
options.scale || options.scale === 0 ? options.scale : 1
this.options.fontSize = options.fontSize || 20
this.options.duration =
options.duration || options.duration === 0 ? options.duration : 50000
this.options.speed =
options.speed || options.speed === 0 ? options.speed : 1
this.options.color = options.color || '#FFC107'
this.options.position = options.position
if (!this.options.position && this.options.positions) {
this.options.position = { lng: (this.options.positions[0].lng + this.options.positions[1].lng) / 2, lat: (this.options.positions[0].lat + this.options.positions[1].lat) / 2 }
let point1 = turf.point([this.options.positions[0].lng, this.options.positions[0].lat]);
let point2 = turf.point([this.options.positions[1].lng, this.options.positions[1].lat]);
let options = { units: 'miles' };
let distance1 = turf.rhumbDistance(point1, point2, options);
// 计算两点与x轴正方向的夹角弧度
function calculateAngle(pointA, pointB) {
let dx = pointB[0] - pointA[0];
let dy = pointB[1] - pointA[1];
return Math.atan2(dy, dx);
}
let angleRadians = calculateAngle([this.options.positions[0].lng, this.options.positions[0].lat], [this.options.positions[1].lng, this.options.positions[1].lat]);
this.options.angle = (360+Cesium.Math.toDegrees(angleRadians))%360
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
0.0001
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
let lng1 = this.options.position.lng - 0.0001 / ratio
let lat1 = this.options.position.lat - gap
let lng2 = this.options.position.lng + 0.0001 / ratio
let lat2 = this.options.position.lat + gap
let lng = (lng1 + lng2) / 2
let lat = (lat1 + lat2) / 2
let from = turf.point([lng1, lat]);
let to = turf.point([lng2, lat]);
let distance2 = turf.rhumbDistance(from, to, options);
let latRadians = Cesium.Math.toRadians(this.options.position.lat)
distance2 = distance2 * (1+(Math.abs(Math.sin(angleRadians)*Math.tan(latRadians)*Math.sin(latRadians)*Math.sin(latRadians))))
this.options.scale = distance1 / distance2
}
this.entity
this._positionEditing = false
this.Dialog = _Dialog
this._EventBinding = new EventBinding()
this._elms = {}
this.previous = {
position: { ...this.options.position }
}
this.event = new MouseEvent(this.sdk)
this.sdk.addIncetance(this.options.id, this)
this.create()
}
get lng() {
return this.options.position.lng
}
set lng(v) {
this.options.position.lng = v
this._elms.lng && this._elms.lng.forEach((item) => {
item.value = v
})
}
get lat() {
return this.options.position.lat
}
set lat(v) {
this.options.position.lat = v
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = v
})
}
get text() {
return this.options.text
}
set text(v) {
this.options.text = v
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
let _error = '行超过80个字符,请按回车Enter继续输入'
window.ELEMENT && window.ELEMENT.Message({
message: _error,
type: 'warning',
duration: 1000
});
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
let _error = '超过最大输入字符'
window.ELEMENT && window.ELEMENT.Message({
message: _error,
type: 'warning',
duration: 1000
});
}
this.options.text = textArray.join('\n')
if (this.entity) {
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false,
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
})
this.entity.rectangle.coordinates = new Cesium.CallbackProperty(() => {
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap,
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
]
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
}, false)
}
this._elms.text &&
this._elms.text.forEach(item => {
item.value = this.options.text
})
}
get angle() {
return this.options.angle
}
set angle(v) {
this.options.angle = v
this._elms.angle &&
this._elms.angle.forEach(item => {
item.value = v
})
}
get scale() {
return this.options.scale
}
set scale(v) {
this.options.scale = v
this._elms.scale &&
this._elms.scale.forEach(item => {
item.value = v
})
}
get duration() {
return this.options.duration
}
set duration(v) {
this.options.duration = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false,
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
})
this._elms.duration &&
this._elms.duration.forEach(item => {
item.value = v
})
}
get speed() {
return this.options.speed
}
set speed(v) {
this.options.speed = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false,
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
})
this._elms.speed &&
this._elms.speed.forEach(item => {
item.value = v
})
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false,
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
})
if (this._elms.color) {
this._elms.color.forEach((item, i) => {
let colorPicker = new ewPlugins('colorpicker', {
el: item.el,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: v,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: c => {
this.color = c
}, //点击确认按钮事件回调
clear: () => {
this.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
this._elms.color[i] = colorPicker
})
}
}
create() {
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.position.lat)) * (0.0001*this.options.scale)
// let fromDegreesArray = [
// this.options.position.lng - 0.05, this.options.position.lat - 0.05,
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
// this.options.position.lng + 0.05, this.options.position.lat + 0.05,
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
// ]
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
this.entity = this.sdk.viewer.entities.add({
id: this.options.id,
show: this.options.show,
rectangle: {
coordinates: new Cesium.CallbackProperty(() => {
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap,
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
]
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
}, false),
material: new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false,
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
}),
rotation: new Cesium.CallbackProperty(() => {
return Cesium.Math.toRadians(this.options.angle)
}, false),
stRotation: new Cesium.CallbackProperty(() => {
return Cesium.Math.toRadians(this.options.angle)
}, false)
}
})
if (this.sdk.viewer._element.className === 'cesium-viewer 2d') {
this.entity.rectangle.height = 10
}
syncData(this.sdk, this.options.id)
if (this.options.show) {
setSplitDirection(0, this.options.id)
}
}
// 编辑框
async edit(state) {
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.originalOptions,
{
title: '贴地文字属性',
left: '180px',
top: '100px',
confirmCallBack: options => {
this.text = this.text.trim()
if (!this.text) {
this.text = '未命名对象'
}
this.originalOptions = this.deepCopyObj(this.options)
this._DialogObject.close()
this.Dialog.confirmCallBack &&
this.Dialog.confirmCallBack(this.originalOptions)
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.reset()
this.positionEditing = false
// this.entity.style = new Cesium.Cesium3DTileStyle({
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
// show: true,
// });
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
showCallBack: show => {
this.show = show
this.Dialog.showCallBack && this.Dialog.showCallBack()
},
translationalCallBack: () => {
this.positionEditing = !this.positionEditing
}
},
true
)
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' ground-text'
let contentElm = document.createElement('div')
contentElm.innerHTML = html()
this._DialogObject.contentAppChild(contentElm)
let all_elm = contentElm.getElementsByTagName('*')
this._EventBinding.on(this, all_elm)
this._elms = this._EventBinding.element
// 颜色组件
let colorPicker = new ewPlugins('colorpicker', {
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)'
} //点击清空按钮事件回调
})
this._elms.color = [colorPicker]
} else {
if (this._DialogObject && this._DialogObject.remove) {
this._DialogObject.remove()
this._DialogObject = null
}
}
}
/**@desc 打开平移功能
*
* @memberOf Source
* @param status {boolean}
*
* */
set positionEditing(status) {
if (!this.sdk || !this.sdk.viewer || !this.entity) {
return
}
this._positionEditing = status
this.previous = {
position: { ...this.options.position }
}
if (status === true) {
this.tip && this.tip.destroy()
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
this.event.mouse_move((movement, cartesian) => {
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.lng = position.lng
this.lat = position.lat
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
this.event.mouse_left((movement, cartesian) => {
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.lng = position.lng
this.lat = position.lat
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.event.gesture_pinck_start(() => { })
this.event.gesture_pinck_end(() => { })
this.positionEditing = false
})
this.event.mouse_right((movement, cartesian) => {
this.lng = this.previous.position.lng
this.lat = this.previous.position.lat
this.positionEditing = false
})
this.event.gesture_pinck_start((movement, cartesian) => {
let startTime = new Date()
this.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
this.lng = this.previous.position.lng
this.lat = this.previous.position.lat
this.positionEditing = false
}
else {
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.lng = position.lng
this.lat = position.lat
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.event.gesture_pinck_start(() => { })
this.event.gesture_pinck_end(() => { })
this.positionEditing = false
}
})
})
} else {
if (this.event) {
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
this.event.gesture_pinck_start(() => { })
this.event.gesture_pinck_end(() => { })
}
this.tip && this.tip.destroy()
}
}
get positionEditing() {
return this._positionEditing
}
/**
* 飞到
*/
async flyTo(options = {}) {
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
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 gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
[
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap
],
[
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
]
]
let height = await this.getClampToHeight(this.options.position)
let positionArray = []
for (let i = 0; i < fromDegreesArray.length; i++) {
let a = Cesium.Cartesian3.fromDegrees(...fromDegreesArray[i], height)
positionArray.push(a.x, a.y, a.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)
}
})
}
}
reset() {
if (!this.entity) {
return
}
this.options = this.deepCopyObj(this.originalOptions)
this.text = this.originalOptions.text
this.angle = this.originalOptions.angle
this.scale = this.originalOptions.scale
this.color = this.originalOptions.color
}
async remove() {
this.event && this.event.destroy()
this.tip && this.tip.destroy()
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)
}
getcanvas() {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
}
this.options.text = textArray.join('\n')
let maxWidth = 0
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + 'px serif'
const width = ctx.measureText(textArray[i]).width
if (maxWidth < width) {
maxWidth = width
}
}
canvas.width = maxWidth
canvas.height = 220 * textArray.length
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + 'px serif'
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
ctx.fillRect(0, 0, maxWidth + 30, 210)
ctx.fillStyle = this.options.color
ctx.font = '200px serif'
ctx.fillText(textArray[i], 0, 210 * (i + 1))
}
return canvas
}
}
export default GroundText

View File

@ -0,0 +1,486 @@
import Dialog from '../../../Element/Dialog'
import EventBinding from '../../../Element/Dialog/eventBinding'
import { html, css } from './_element'
import Base from '../../index'
import MouseEvent from '../../../../Event/index'
import { syncData } from '../../../../Global/MultiViewportMode'
import MouseTip from '../../../../MouseTip'
import { setSplitDirection } from '../../../../Global/SplitScreen'
class GroundText extends Base {
/**
* @constructor
* @param sdk
* @description 贴地文字
* @param options {object} 属性
* @param options.show=true {boolean} 显示/隐藏
* @param options.text {string} 文字
* @param options.angle=0 {number} 旋转角度
* @param options.scale=1 {number} 比例
* @param {object} options.position 经纬度和高度{lon,lat,alt}
* @param {Array.<object>} options.positions 矩形坐标数组 [最西端的经度,最南端的纬度,最东经度,最北纬度]
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options)
this.options.text = options.text || '未命名对象'
this.options.name = this.options.text
this.options.show =
options.show || options.show === false ? options.show : true
this.options.angle = options.angle || 0
this.options.scale =
options.scale || options.scale === 0 ? options.scale : 1
this.options.fontSize = options.fontSize || 20
this.options.duration =
options.duration || options.duration === 0 ? options.duration : 50000
this.options.speed =
options.speed || options.speed === 0 ? options.speed : 1
this.options.color = options.color || '#FFC107'
this.options.position = options.position
this.entity
this._positionEditing = false
this.Dialog = _Dialog
this._EventBinding = new EventBinding()
this._elms = {}
this.previous = {
position: { ...this.options.position }
}
this.event = new MouseEvent(this.sdk)
this.sdk.addIncetance(this.options.id, this)
this.create()
}
get text() {
return this.options.text
}
set text(v) {
this.options.text = v
if (this.entity) {
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false
})
this.entity.rectangle.coordinates = new Cesium.CallbackProperty(() => {
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap,
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
]
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
}, false)
}
this._elms.text &&
this._elms.text.forEach(item => {
item.value = v
})
}
get angle() {
return this.options.angle
}
set angle(v) {
this.options.angle = v
this._elms.angle &&
this._elms.angle.forEach(item => {
item.value = v
})
}
get scale() {
return this.options.scale
}
set scale(v) {
this.options.scale = v
this._elms.scale &&
this._elms.scale.forEach(item => {
item.value = v
})
}
get duration() {
return this.options.duration
}
set duration(v) {
this.options.duration = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false
})
this._elms.duration &&
this._elms.duration.forEach(item => {
item.value = v
})
}
get speed() {
return this.options.speed
}
set speed(v) {
this.options.speed = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false
})
this._elms.speed &&
this._elms.speed.forEach(item => {
item.value = v
})
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
let canvas = this.getcanvas()
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL('image/png'),
color: this.options.color,
repeat: new Cesium.Cartesian2(1.0, 1.0),
duration: this.options.duration / this.options.speed,
fltr: false
})
if (this._elms.color) {
this._elms.color.forEach((item, i) => {
let colorPicker = new ewPlugins('colorpicker', {
el: item.el,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: v,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: c => {
this.color = c
}, //点击确认按钮事件回调
clear: () => {
this.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
this._elms.color[i] = colorPicker
})
}
}
create() {
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.position.lat)) * (0.0001*this.options.scale)
// let fromDegreesArray = [
// this.options.position.lng - 0.05, this.options.position.lat - 0.05,
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
// this.options.position.lng + 0.05, this.options.position.lat + 0.05,
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
// ]
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
let height = ((this.options.positions[2] - this.options.positions[0])/2) * ratio
this.options.positions[1] = this.options.positions[3] - height
this.entity = this.sdk.viewer.entities.add({
id: this.options.id,
show: this.options.show,
rectangle: {
coordinates: new Cesium.CallbackProperty(() => {
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap,
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
]
return Cesium.Rectangle.fromDegrees(...this.options.positions)
}, false),
outline: true,
outlineColor: Cesium.Color.RED,
outlineWidth: 10,
rotation: new Cesium.CallbackProperty(() => {
return Cesium.Math.toRadians(this.options.angle)
}, false),
stRotation: new Cesium.CallbackProperty(() => {
return Cesium.Math.toRadians(this.options.angle)
}, false)
}
})
if (this.sdk.viewer._element.className === 'cesium-viewer 2d') {
this.entity.rectangle.height = 1000000
}
syncData(this.sdk, this.options.id)
if(this.options.show) {
setSplitDirection(0, this.options.id)
}
}
// 编辑框
async edit(state) {
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
this._element_style = null
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._element_style = document.createElement('style')
this._element_style.type = 'text/css'
this._element_style.setAttribute('data-name', 'YJ_style_dialog')
this._element_style.innerHTML = css()
this._DialogObject = await new Dialog(
this.sdk,
this.originalOptions,
{
title: '编辑属性',
left: '180px',
top: '100px',
confirmCallBack: options => {
this.text = this.text.trim()
if (!this.text) {
this.text = '未命名对象'
}
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.positionEditing = false
// this.entity.style = new Cesium.Cesium3DTileStyle({
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
// show: true,
// });
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
},
showCallBack: show => {
this.show = show
this.Dialog.showCallBack && this.Dialog.showCallBack()
},
translationalCallBack: () => {
this.positionEditing = !this.positionEditing
}
},
true
)
document.getElementsByTagName('head')[0].appendChild(this._element_style)
let contentElm = document.createElement('div')
contentElm.innerHTML = html()
this._DialogObject.contentAppChild(contentElm)
let all_elm = contentElm.getElementsByTagName('*')
this._EventBinding.on(this, all_elm)
this._elms = this._EventBinding.element
// 颜色组件
let colorPicker = new ewPlugins('colorpicker', {
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)'
} //点击清空按钮事件回调
})
this._elms.color = [colorPicker]
} else {
if (this._element_style) {
document
.getElementsByTagName('head')[0]
.removeChild(this._element_style)
this._element_style = null
}
if (this._DialogObject && this._DialogObject.remove) {
this._DialogObject.remove()
this._DialogObject = null
}
}
}
/**@desc 打开平移功能
*
* @memberOf Source
* @param status {boolean}
*
* */
set positionEditing(status) {
if (!this.sdk || !this.sdk.viewer || !this.entity) {
return
}
this._positionEditing = status
this.previous = {
position: { ...this.options.position }
}
if (status === true) {
this.tip && this.tip.destroy()
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
this.event.mouse_move((movement, cartesian) => {
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.options.position.lng = position.lng
this.options.position.lat = position.lat
this.options.position.alt = position.alt
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
this.event.mouse_left((movement, cartesian) => {
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.options.position.lng = position.lng
this.options.position.lat = position.lat
this.options.position.alt = position.alt
this.event.mouse_move(() => {})
this.event.mouse_left(() => {})
this.event.mouse_right(() => {})
this.positionEditing = false
})
this.event.mouse_right((movement, cartesian) => {
this.options.position.lng = this.previous.position.lng
this.options.position.lat = this.previous.position.lat
this.options.position.alt = this.previous.position.alt
this.positionEditing = false
})
} else {
if (this.event) {
this.event.mouse_move(() => { })
this.event.mouse_left(() => { })
this.event.mouse_right(() => { })
}
this.tip && this.tip.destroy()
}
}
get positionEditing() {
return this._positionEditing
}
/**
* 飞到
*/
async flyTo(options = {}) {
let canvas = this.getcanvas()
let ratio = canvas.height / canvas.width
if (this.options.customView) {
this.sdk.viewer.camera.flyTo({
destination: this.options.customView.position,
orientation: this.options.customView.orientation
})
} else {
let gap =
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
(0.0001 * this.options.scale)
let fromDegreesArray = [
[
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
this.options.position.lat - gap
],
[
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
this.options.position.lat + gap
]
]
let height = await this.getClampToHeight(this.options.position)
let positionArray = []
for (let i = 0; i < fromDegreesArray.length; i++) {
let a = Cesium.Cartesian3.fromDegrees(...fromDegreesArray[i], height)
positionArray.push(a.x, a.y, a.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)
}
})
}
}
reset() {
if (!this.entity) {
return
}
this.options = this.deepCopyObj(this.originalOptions)
this.text = this.originalOptions.text
this.angle = this.originalOptions.angle
this.scale = this.originalOptions.scale
this.color = this.originalOptions.color
}
async remove() {
this.event && this.event.destroy()
this.tip && this.tip.destroy()
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)
}
getcanvas() {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let textArray = this.options.text.split('\n')
let maxWidth = 0
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + 'px serif'
const width = ctx.measureText(textArray[i]).width
if (maxWidth < width) {
maxWidth = width
}
}
canvas.width = maxWidth
canvas.height = 220 * textArray.length
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + 'px serif'
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
ctx.fillRect(0, 0, maxWidth + 30, 210)
ctx.fillStyle = this.options.color
ctx.font = '200px serif'
ctx.fillText(textArray[i], 0, 210 * (i + 1))
}
return canvas
}
}
export default GroundText

View File

@ -0,0 +1,30 @@
function html(that) {
return `
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<textarea @model="text"></textarea>
</div>
<div class="col" style="margin-right: 20px;">
<span class="label">颜色</span>
<div class="color"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">滚动速度</span>
<input type="range" max="100" min="0" step="1" @model="speed">
<input style="font-size: 13px;width: 100px;margin-left: 10px;" type="number" title="" min="0" max="100" @model="speed">
</div>
</div>
</div>
<span class="custom-divider"></span>
`
}
export { html }

View File

@ -0,0 +1,783 @@
import Dialog from '../../../Element/Dialog';
import EventBinding from '../../../Element/Dialog/eventBinding';
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'
import MouseTip from '../../../../MouseTip'
import { syncData } from '../../../../Global/MultiViewportMode'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
class StandText extends Base {
/**
* @constructor
* @param sdk
* @description 立体文字
* @param options {object}
* @param options.text {string} 文字
* @param options.color="#FFC107" {string} 颜色
* @param options.speed=1 {number} 文字移动速度
* @param {Array.<object>} positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
constructor(sdk, options, _Dialog = {}) {
super(sdk, options);
this.options.text = options.text || "未命名对象"
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
}
this.options.text = textArray.join('\n')
this.options.color = options.color || "#FFC107"
// this.options.cornerType = options.cornerType || 'MITERED'
this.options.positions = options.positions
// this.options.material = Number(options.material) || 0
this.options.speed = (options.speed || options.speed === 0) ? options.speed : 1
// this.options.duration = (options.duration || options.duration === 0) ? options.duration : 50000
this.options.show = (options.show || options.show === false) ? options.show : true
this.nodePoints = []
this.entity
this.options.instruct = options.instruct || ""
this.options.operatingPoint = options.operatingPoint || ""
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.extrudedHeight
this._EventBinding = new EventBinding()
this.Dialog = _Dialog
this._elms = {};
this.sdk.addIncetance(this.options.id, this)
StandText.create(this)
}
get text() {
return this.options.text
}
set text(v) {
this.options.text = v
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
let _error = '行超过80个字符,请按回车Enter继续输入'
window.ELEMENT && window.ELEMENT.Message({
message: _error,
type: 'warning',
duration: 1000
});
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
let _error = '超过最大输入字符'
window.ELEMENT && window.ELEMENT.Message({
message: _error,
type: 'warning',
duration: 1000
});
}
this.options.text = textArray.join('\n')
if (this.entity) {
let positions = this.options.positions
let fromDegreesArray = []
let minimumHeights = []
let maximumHeights = []
let material = this.getMaterial()
let width = this.computeDistance(positions)
let extrudedHeight = this.aspectRatio ? (width / this.aspectRatio) : 0
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
this.entity.wall.material = material
this.entity.wall.maximumHeights = maximumHeights
this.entity.wall.minimumHeights = minimumHeights
}
this._elms.text && this._elms.text.forEach((item) => {
item.value = v
})
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
this.entity.wall.material = this.getMaterial()
if (this._elms.color) {
this._elms.color.forEach((item, i) => {
let colorPicker = new ewPlugins('colorpicker', {
el: item.el,
size: 'mini',//颜色box类型
alpha: true,//是否开启透明度
defaultColor: v,
disabled: false,//是否禁止打开颜色选择器
openPickerAni: 'opacity',//打开颜色选择器动画
sure: (c) => {
this.color = c
},//点击确认按钮事件回调
clear: () => {
this.color = 'rgba(255,255,255,1)'
},//点击清空按钮事件回调
})
this._elms.color[i] = colorPicker
})
}
}
// get material() {
// return this.options.material
// }
// set material(v) {
// this.options.material = Number(v)
// this.entity.wall.material = this.getMaterial()
// this._elms.material && this._elms.material.forEach((item) => {
// item.value = v
// })
// }
get speed() {
return this.options.speed
}
set speed(v) {
this.options.speed = v
this.entity.wall.material = this.getMaterial()
this._elms.speed && this._elms.speed.forEach((item) => {
item.value = v
})
}
// 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) {
// 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 class="text" @click="linkEdit">编辑</button>
// <button class="text" @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 html = `
// <div class="td">
// <input class="input" type="text">
// </div>
// <div class="td">
// <div class="input-group">
// <input class="input" type="text" style="width: 140px;">
// <input type="file" accept=".mp4, .pdf" class="file-select" index="`+ i + `" style="display:none">
// <button @click="fileSelect">...</button>
// </div>
// </div>
// <div class="td">
// <button class="text" @click="confirmEdit">确认</button>
// <button class="text" @click="cancelEdit">取消</button>
// </div>`
// item[i].innerHTML = html
// 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) => {
// this.options.attribute.link.content[i] = value
// 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
}
//创建
static async create(that) {
// console.log(new Cesium.CustomMaterialSource(), new Cesium.PolylineTrailLinkMaterialProperty())
let positions = that.options.positions
let fromDegreesArray = []
let minimumHeights = []
let maximumHeights = []
let material = that.getMaterial()
let width = that.computeDistance(positions)
let extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
// aspectRatio
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
that.entity = that.sdk.viewer.entities.add({
id: that.options.id,
show: that.options.show,
wall: {
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
cornerType: Cesium.CornerType.MITERED,
maximumHeights: maximumHeights,
minimumHeights: minimumHeights,
material: material,
},
// wall: {
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray),
// maximumHeights: maximumHeights,
// minimumHeights: minimumHeights,
// material: new Cesium.PolylineTrailLinkMaterialProperty({duration: 1500}),
// outline: true,
// outlineColor: Cesium.Color.BLACK,
// }
})
syncData(that.sdk, that.options.id)
if(that.options.show) {
setSplitDirection(0, that.options.id)
}
}
// 编辑框
async edit(state) {
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.text = this.text.trim()
if (!this.text) {
this.text = '未命名对象'
}
this.originalOptions = this.deepCopyObj(this.options)
this._DialogObject.close()
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
},
resetCallBack: () => {
this.reset()
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
},
removeCallBack: () => {
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
},
closeCallBack: () => {
this.reset()
this.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()
},
secondaryEditCallBack: () => {
StandText.nodeEdit(this)
}
})
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' stand-text'
let contentElm = document.createElement('div');
contentElm.innerHTML = html(this)
this._DialogObject.contentAppChild(contentElm)
this.attributeType = this.options.attributeType
this.attributeCamera = this.options.attribute.camera
// setTimeout(() => {
// this.attributeLink = this.options.attribute.link.content
// this.cameraSelect()
// }, 500);
// 创建标签页
// let tabsElm = new cy_tabs('radar-scan-edit-tabs')
// 颜色组件
let colorPicker = new ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
el: contentElm.getElementsByClassName("labelBackgroundColorEnd")[0],
size: 'mini',
alpha: true,
defaultColor: this.labelBackgroundColorEnd,
disabled: false,
openPickerAni: 'opacity',
sure: (color) => {
this.labelBackgroundColorEnd = color
},
clear: () => {
this.labelBackgroundColorEnd = 'rgba(255,255,255,1)'
},
})
let all_elm = contentElm.getElementsByTagName("*")
this._EventBinding.on(this, all_elm)
this._elms = this._EventBinding.element
this._elms.color = [colorPicker]
this._elms.labelColor = [labelColorPicker]
this._elms.labelLineColor = [lineColorPicker]
this._elms.labelBackgroundColorStart = [labelBackgroundColorStartPicker]
this._elms.labelBackgroundColorEnd = [labelBackgroundColorEndPicker]
} 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.text = this.originalOptions.text
this.color = this.originalOptions.color
this.speed = this.originalOptions.speed
let positions = this.options.positions
let fromDegreesArray = []
let minimumHeights = []
let maximumHeights = []
let width = this.computeDistance(positions)
let extrudedHeight = this.aspectRatio ? (width / this.aspectRatio) : 0
// aspectRatio
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
this.entity.wall.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
}
async remove() {
this.event && this.event.destroy()
this.tip && this.tip.destroy()
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)
}
getMaterial() {
let material
let canvas = this.getcanvas()
material = new Cesium.CustomMaterialSource({
image: canvas.toDataURL("image/png"),
color: this.options.color,
repeat: new Cesium.Cartesian2(1, 1.0),
duration: 50000 / this.options.speed,
fltr: false
})
return material
}
getcanvas() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d')
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 80) {
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
}
}
if (textArray.length > 70) {
textArray.splice(70 - textArray.length)
}
this.options.text = textArray.join('\n')
let maxWidth = 0
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + "px serif";
const width = ctx.measureText(textArray[i]).width;
if(maxWidth<width) {
maxWidth = width
}
}
canvas.width = maxWidth
canvas.height = 220 * textArray.length
for (let i = 0; i < textArray.length; i++) {
ctx.font = 200 + "px serif";
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
ctx.fillRect(0, 0, maxWidth + 30, 210)
ctx.fillStyle = this.options.color;
ctx.font = "200px serif";
ctx.fillText(textArray[i], 0, 210 * (i+1));
}
this.aspectRatio = this.options.text ? (canvas.width / canvas.height) : 0
return canvas
}
/**
* 打开富文本框
*/
openRichTextEditor(e) {
richText.open(this.options.id, this.options.text, this.options.richTextContent)
richText.primaryCallBack = (content) => {
this.options.richTextContent = content
}
}
static nodeEdit(that, cb = () => { }) {
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
let positions = that.options.positions
let fromDegreesArray = []
let minimumHeights = []
let maximumHeights = []
let width = that.computeDistance(positions)
let extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
let isAdd = false
let leftEvent = (movement, cartesian) => {
if (selectPoint) {
isAdd = true
let pos3 = that.sdk.viewer.scene.clampToHeight(cartesian, [that.entity])
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(pos3, 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.positions[selectPoint.index].alt),
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])
let positions = that.options.positions
fromDegreesArray = []
minimumHeights = []
maximumHeights = []
width = that.computeDistance(positions)
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
that.tip.setPosition(
cartesian,
movement.position.x,
movement.position.y
)
}
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.entity.wall.positions = new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
}, false)
that.entity.wall.maximumHeights = new Cesium.CallbackProperty(function () {
return maximumHeights
}, false)
that.entity.wall.minimumHeights = new Cesium.CallbackProperty(function () {
return minimumHeights
}, false)
}
}
}
let rightEvent = (movement, cartesian) => {
if (selectPoint) {
that.options.positions[selectPoint.index] = originalPosition
if(isAdd) {
that.options.positions.splice(selectPoint.index, 1)
}
cb(null, that.options.positions)
}
let positions = that.options.positions
fromDegreesArray = []
minimumHeights = []
maximumHeights = []
width = that.computeDistance(positions)
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + extrudedHeight)
}
that.entity.wall.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
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_left(leftEvent)
that.event.mouse_right(rightEvent)
that.event.mouse_move((movement, cartesian) => {
if (selectPoint) {
let pos3 = that.sdk.viewer.scene.clampToHeight(cartesian, [that.entity])
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(pos3, that.sdk.viewer)
let positions = that.options.positions
fromDegreesArray = []
minimumHeights = []
maximumHeights = []
width = that.computeDistance(positions)
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
minimumHeights.push(positions[i].alt)
maximumHeights.push(positions[i].alt + 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
}
}
}
})
that.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
}
}
that.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
rightEvent(pos, cartesian)
}
else {
leftEvent(pos, cartesian)
}
})
})
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.positions[i].alt),
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)
}
}
}
}
export default StandText