代码迁移
This commit is contained in:
558
src/Obj/Base/GroundImage/index.js
Normal file
558
src/Obj/Base/GroundImage/index.js
Normal file
@ -0,0 +1,558 @@
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import cy_slider from "../../Element/cy_html_slider";
|
||||
import { html } from "./_element";
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
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 GroundImage extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 贴地图片
|
||||
* @param options {object} 属性
|
||||
* @param options.id {string} 唯一标识
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.angle=0 {number} 旋转角度
|
||||
* @param options.scale=1 {number} 比例
|
||||
* @param options.flipe {object} 翻转
|
||||
* @param options.flipe.x=false {boolean} 绕X轴翻转
|
||||
* @param options.flipe.y=false {boolean} 绕Y轴翻转
|
||||
* @param options.url {string} 图片地址
|
||||
* @param {Array.<object>} options.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.name = options.name || '未命名对象'
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.options.url = options.url
|
||||
this.options.angle = options.angle || 0
|
||||
this.options.scale = (options.scale || options.scale === 0) ? options.scale : 1
|
||||
this.options.positions = options.positions
|
||||
|
||||
this.options.flipe = options.flipe || {}
|
||||
this.options.flipe.x = this.options.flipe.x || false
|
||||
this.options.flipe.y = this.options.flipe.y || false
|
||||
|
||||
this.entity = {
|
||||
id: this.options.id
|
||||
}
|
||||
this._positionEditing = false
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this.previous = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
this._EventBinding = new EventBinding()
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.create()
|
||||
}
|
||||
|
||||
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 flipeY() {
|
||||
return this.options.flipe.y
|
||||
}
|
||||
set flipeY(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.flipe.y = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
this.entity && (this.entity.rectangle.material = new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
get flipeX() {
|
||||
return this.options.flipe.x
|
||||
}
|
||||
set flipeX(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.flipe.x = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
this.entity.rectangle.material = new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async create() {
|
||||
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.positions.lat)) * (0.0001*this.options.scale)
|
||||
// let fromDegreesArray = [
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat - 0.05,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat - 0.05,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat + 0.05,
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat + 0.05,
|
||||
// ]
|
||||
let response = await fetch(this.options.url, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
if (response.ok) {
|
||||
// let data = await response.blob()
|
||||
// let arrayBuffer = await data.arrayBuffer()
|
||||
// const str = String.fromCharCode(...new Uint8Array(arrayBuffer));
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
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.positions.lat)) * (0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.positions.lng - (0.0001 * this.options.scale), this.options.positions.lat - gap,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat - 0.05,
|
||||
this.options.positions.lng + (0.0001 * this.options.scale), this.options.positions.lat + gap,
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat + 0.05,
|
||||
]
|
||||
|
||||
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
|
||||
}, false),
|
||||
material: new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
}),
|
||||
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 = 0
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// if (data.code === 200 || data.code === 0) {
|
||||
// this.$message({
|
||||
// message: '添加成功!',
|
||||
// type: 'success',
|
||||
// duration: 1500
|
||||
// });
|
||||
// this.close()
|
||||
// // this.$emit('getBuildingList')
|
||||
// // this.$emit('onSubmitCallBack')
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = { ...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.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
},
|
||||
resetCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
},
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
this.positionEditing = false
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
this.positionEditing = !this.positionEditing
|
||||
},
|
||||
addFootElm: [
|
||||
{
|
||||
tagName: 'button',
|
||||
className: 'flipe-over-y',
|
||||
innerHTML: 'Y轴翻转',
|
||||
event: [
|
||||
'click',
|
||||
() => {
|
||||
this.flipeY = !this.flipeY
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
tagName: 'button',
|
||||
className: 'flipe-over-x',
|
||||
innerHTML: 'X轴翻转',
|
||||
event: [
|
||||
'click',
|
||||
() => {
|
||||
this.flipeX = !this.flipeX
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' ground-image'
|
||||
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
|
||||
|
||||
} 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 = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
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.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
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.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.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
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.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
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_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()
|
||||
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._positionEditing
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到
|
||||
*/
|
||||
async flyTo(options = {}) {
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else if (this.options.start) {
|
||||
position = { ...this.options.start }
|
||||
}
|
||||
else {
|
||||
if (this.options.hasOwnProperty('lng')) {
|
||||
position.lng = this.options.lng
|
||||
}
|
||||
if (this.options.hasOwnProperty('lat')) {
|
||||
position.lat = this.options.lat
|
||||
}
|
||||
if (this.options.hasOwnProperty('alt')) {
|
||||
position.alt = this.options.alt
|
||||
}
|
||||
}
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
if (!position.hasOwnProperty('alt')) {
|
||||
position.alt = await this.getClampToHeight(position)
|
||||
}
|
||||
lng = this.options.customView.relativePosition.lng + position.lng
|
||||
lat = this.options.customView.relativePosition.lat + position.lat
|
||||
alt = this.options.customView.relativePosition.alt + position.alt
|
||||
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation
|
||||
})
|
||||
}
|
||||
else {
|
||||
let gap = Math.abs(Math.cos(Math.PI / 180 * this.options.positions.lat)) * (0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
[this.options.positions.lng - (0.0001 * this.options.scale), this.options.positions.lat - gap],
|
||||
[this.options.positions.lng + (0.0001 * this.options.scale), this.options.positions.lat + gap],
|
||||
]
|
||||
let positionArray = []
|
||||
let height = 0
|
||||
let position = this.options.positions
|
||||
let point1 = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 0);
|
||||
let point2 = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 10000000);
|
||||
let direction = Cesium.Cartesian3.subtract(point2, point1, new Cesium.Cartesian3());
|
||||
let c = Cesium.Cartesian3.normalize(direction, direction);
|
||||
let ray = new Cesium.Ray(point1, c);
|
||||
let r = {}
|
||||
let pickedObjects = this.sdk.viewer.scene.drillPickFromRay(ray);
|
||||
for (let i = 0; i < pickedObjects.length; i++) {
|
||||
if (pickedObjects[i].position) {
|
||||
r = pickedObjects[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (r && r.position) {
|
||||
height = this.cartesian3Towgs84(r.position, this.sdk.viewer).alt
|
||||
}
|
||||
else {
|
||||
try {
|
||||
var promise = await Cesium.sampleTerrainMostDetailed(this.sdk.viewer.terrainProvider, [Cesium.Cartographic.fromDegrees(position.lng, position.lat)]);
|
||||
height = promise[0].height
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
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.name = this.originalOptions.name
|
||||
this.angle = this.originalOptions.angle
|
||||
this.scale = this.originalOptions.scale
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
setPosition(v) {
|
||||
this.options.positions.lng = v.position.lng
|
||||
this.options.positions.lat = v.position.lat
|
||||
this.options.positions.alt = v.position.alt
|
||||
}
|
||||
}
|
||||
|
||||
export default GroundImage
|
Reference in New Issue
Block a user