This commit is contained in:
zh
2025-11-17 17:12:03 +08:00
parent df2c1735bc
commit 7e6b6c0fca
38 changed files with 1460 additions and 379 deletions

View File

@ -227,7 +227,7 @@ export default class DrawCircle extends Draw {
return '半径:' + radius + ' 米'
}, false),
font: '20px Microsoft YaHei',
distanceDisplayCondition: 10000000,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,

View File

@ -31,12 +31,13 @@ class DrawSector extends Draw {
this._sector_id = null; //扇形
this._positions = []; //活动点
this.points_ids = []; //脏数据
this.radius_points = []
this._entities_sector = []; //脏数据
this._radius = 0; //半径
this._startAngle = 0; //起始角度
this._endAngle = 0; //结束角度
this.event.mouse_left((movement, cartesian) => {
if(into === '2D') {
if (into === '2D') {
return
}
into = '3D'
@ -51,13 +52,17 @@ class DrawSector extends Draw {
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
}
if (this._positions.length === 2) {
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
let pointB = cartesian;
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
this.radius_points.push(cartesian)
this._radius = this.computeDistance2([this._positions[0], this._positions[1]]);
}
if (this._positions.length === 1) {
this.radius_points.push(cartesian)
let lineId = this.createRadiusLine();
this.points_ids.push(lineId);
}
})
this.event.mouse_move((movement, cartesian) => {
if(into === '2D') {
if (into === '2D') {
return
}
this.tip.setPosition(
@ -65,6 +70,11 @@ class DrawSector extends Draw {
movement.endPosition.x,
movement.endPosition.y
)
if (this._positions.length === 1) {
this.radius_points[1] = cartesian
let endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
this._radius = this.computeDistance2([this._positions[0], endpoint]);
};
if (this._positions.length < 2) return;
if (this._positions.length == 2) {
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
@ -84,7 +94,7 @@ class DrawSector extends Draw {
})
this.event.mouse_right((movement, cartesian) => {
if(into === '2D') {
if (into === '2D') {
return
}
this.end()
@ -93,12 +103,12 @@ class DrawSector extends Draw {
if (!this._is2D && this._sdk2D) {
this.event2D = new MouseEvent(this._sdk2D)
this.event2D.mouse_left((movement, cartesian) => {
if(into === '3D') {
if (into === '3D') {
return
}
into = '2D'
// if(that._positions.length == 3) return
if (this._positions.length < 3) {
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer));
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
@ -108,13 +118,12 @@ class DrawSector extends Draw {
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
}
if (this._positions.length === 2) {
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
let pointB = cartesian;
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
let endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
this._radius = this.computeDistance2([this._positions[0], endpoint]);
}
})
this.event2D.mouse_move((movement, cartesian) => {
if(into === '3D') {
if (into === '3D') {
return
}
this.tip.setPosition(
@ -133,15 +142,15 @@ class DrawSector extends Draw {
this._sector_id = this.createsector(this._sdk2D.viewer);
this.points_ids.push(this._sector_id);
}
let options = that.calculateAangle(that._positions)
that._startAngle = options.angle1;
that._endAngle = options.angle2;
}
})
this.event2D.mouse_right((movement, cartesian) => {
if(into === '3D') {
if (into === '3D') {
return
}
this.end()
@ -198,6 +207,49 @@ class DrawSector extends Draw {
that._entities_sector.push(arrowEntity);
return id
}
//创建半径线
createRadiusLine(viewer = this.viewer) {
let that = this;
let id = that.randomString()
let arrowEntity = viewer.entities.add({
id: id,
position: new Cesium.CallbackProperty((e) => {
let center = that._positions[0]
let endpoint = that.radius_points[1] ? that.cartesian3Towgs84(that.radius_points[1], that.viewer) : that._positions[0]
let c = that.computeMidpoint(center, endpoint)
return Cesium.Cartesian3.fromDegrees(c.lng, c.lat, endpoint.alt)
}, false),
polyline: {
positions: new Cesium.CallbackProperty((e) => {
return that.radius_points
}, false),
width: 2,
material:
Cesium.Color.fromCssColorString('#c1c505').withAlpha(0.5),
clampToGround: true,
zIndex: 999999999
},
label: {
text: new Cesium.CallbackProperty((e) => {
if (this._radius > 1000) {
return '半径:' + (this._radius / 1000).toFixed(2) + ' 公里'
}
return '半径:' + this._radius + ' 米'
}, false),
font: '20px Microsoft YaHei',
disableDepthTestDistance: Number.POSITIVE_INFINITY,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
fillColor: Cesium.Color.fromCssColorString('#f5ce0a'),
style: Cesium.LabelStyle.FILL_AND_OUTLINE
},
}
)
that._entities_sector.push(arrowEntity);
return id
}
cartesianToLatlng(cartesian) {
let latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);

View File

@ -14,15 +14,15 @@ function html() {
<div class="div-item">
<div class="row">
<div class="col">
<input type="checkbox" name="isTotalTime" style="width: 16px; line-height: 15px; height: 15px; cursor: pointer; width: auto; margin-right: 5px;">
<span class="label">设置总时长</span>
<div class="input-number input-number-unit-3">
<input class="input total-time" type="number" title="" min="0" max="999999.99" step="0.01" name="totalTime" value="0">
<span class="unit" style="top: 6px;">秒(s)</span>
<span class="arrow"></span>
</div>
<button class="set-total-time-btn" style="margin-left: 5px;">应用</button>
</div>
<div class="col">
<div class="col" style="justify-content: flex-end;">
<input type="checkbox" name="repeat" style="width: 16px; line-height: 15px; height: 15px; cursor: pointer; width: auto; margin-right: 5px;">
<span class="label">是否循环播放</span>
</div>

View File

@ -139,11 +139,10 @@ const open = async (sdk, options = {}, _Dialog = {}) => {
})
let totalTimeElm = contentElm.querySelector("input[name='totalTime']")
let isTotalTimeElm = contentElm.querySelector("input[name='isTotalTime']")
let repeatElm = contentElm.querySelector("input[name='repeat']")
isTotalTimeElm.addEventListener('change', () => {
let trList = tableBody.getElementsByClassName('tr')
if (isTotalTimeElm.checked && trList.length > 0) {
let setTotalTimeBtn = contentElm.getElementsByClassName('set-total-time-btn')[0]
setTotalTimeBtn.addEventListener('click', () => {
if (points.length > 0) {
let trList = tableBody.getElementsByClassName('tr')
let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2))
for (let i = 0; i < trList.length - 1; i++) {
points[i].duration = time
@ -152,20 +151,12 @@ const open = async (sdk, options = {}, _Dialog = {}) => {
trList[trList.length - 1].querySelector("input[name='time']").value = 0
}
})
let repeatElm = contentElm.querySelector("input[name='repeat']")
totalTimeElm.addEventListener('blur', () => {
let trList = tableBody.getElementsByClassName('tr')
totalTimeElm.value = Number(totalTimeElm.value)
if (totalTimeElm.value < 0) {
totalTimeElm.value = 0
}
if (isTotalTimeElm.checked && trList.length > 0) {
let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2))
for (let i = 0; i < trList.length - 1; i++) {
points[i].duration = time
trList[i].querySelector("input[name='time']").value = time
}
trList[trList.length - 1].querySelector("input[name='time']").value = 0
}
})
repeatElm.checked = (repeat === Infinity ? true : false)
repeatElm.addEventListener('change', () => {
@ -286,7 +277,6 @@ const open = async (sdk, options = {}, _Dialog = {}) => {
// }
})
e_time.addEventListener('input', (v) => {
isTotalTimeElm.checked = false
data.duration = Number(e_time.value)
if (data.duration < 0) {
data.duration = 0

View File

@ -6,7 +6,7 @@ import { getTemplateData } from './dataSource.js'
let tools = new Tools();
async function MapPrint(sdk, thumbnailImg, rectangle, originalImg) {
async function MapPrint(sdk, thumbnailImg, rectangle, originalImg, totalCanvas, scale) {
let exporting = false;
let templateData = getTemplateData(tools)
let _DialogObject
@ -290,21 +290,48 @@ async function MapPrint(sdk, thumbnailImg, rectangle, originalImg) {
let closeBtn
let exportBtn
let saveBtn
setTimeout(() => {
closeBtn = _DialogObject._element.foot.getElementsByClassName('close')[0]
exportBtn = document.createElement('button')
exportBtn.className = 'export';
exportBtn.innerHTML = '打印';
exportBtn.style.right = '150px'
leftElm.appendChild(closeBtn)
leftElm.appendChild(exportBtn)
saveBtn = document.createElement('button')
saveBtn.className = 'export';
saveBtn.innerHTML = '保存';
leftElm.appendChild(closeBtn)
leftElm.appendChild(saveBtn)
exportBtn.addEventListener('click', function () {
if (exporting) {
return
}
exporting = true
exportBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>打印'
exportMap()
saveBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>保存'
exportMap('export')
// exporting = true
// exportBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>打印'
// let imgBlobData = canvas.toDataURL();
// let downloadElement = document.createElement('a');
// downloadElement.href = imgBlobData;
// downloadElement.download = `高清出图-${getDateTimeString()}.png`;
// document.body.appendChild(downloadElement);
// downloadElement.click();
// document.body.removeChild(downloadElement);
// URL.revokeObjectURL(imgBlobData);
})
saveBtn.addEventListener('click', function () {
if (exporting) {
return
}
exporting = true
exportBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>打印'
saveBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>保存'
exportMap('save')
// exporting = true
// exportBtn.innerHTML = '<span style="position: absolute;width:100%;height:100%;top: 0;left: 0;border-radius: 3px;background-color: #6f89848f;"><svg class="icon-load"><use xlink:href="#yj-icon-load"></use></svg></span>打印'
// let imgBlobData = canvas.toDataURL();
@ -1197,12 +1224,52 @@ async function MapPrint(sdk, thumbnailImg, rectangle, originalImg) {
return `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`;
}
function exportMap() {
function exportMap(type) {
let iframeDoc = document
let unitDistance2
let canvas2 = document.createElement('canvas');
let iframe
if (type === 'export') {
iframe = document.createElement('iframe');
iframe.id = 'printIframe';
// iframe.src = 'print.html';
iframe.frameborder = '0';
iframe.style.position = 'absolute';
iframe.style.zIndex = '-9999999';
iframe.style.width = '100vw';
iframe.style.height = '100vh';
iframe.style.left = '0';
iframe.style.top = '0';
document.body.appendChild(iframe);
iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
}
let canvas2 = iframeDoc.createElement('canvas');
if (type === 'export') {
canvas2.style.width = '100%'
canvas2.style.height = '100%'
canvas2.style.objectFit = 'contain';
iframeDoc.body.appendChild(canvas2);
}
let ctx2 = canvas2.getContext('2d');
let imgElm2 = new Image();
imgElm2.src = originalImg
if (type === 'export') {
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
if(scale>=3) {
tempCanvas.width = totalCanvas.width / scale * 2
tempCanvas.height = totalCanvas.height / scale * 2
tempCtx.drawImage(totalCanvas, 0, 0, tempCanvas.width, tempCanvas.height);
imgElm2.src = tempCanvas.toDataURL('image/jpeg', 0.95)
}
else {
imgElm2.src = originalImg
}
}
else {
imgElm2.src = originalImg
}
imgElm2.onload = function () {
if (isLoad) {
return
@ -1416,17 +1483,36 @@ async function MapPrint(sdk, thumbnailImg, rectangle, originalImg) {
// 在释放资源后执行回调
canvas2.toBlob(function (blob) {
const url = URL.createObjectURL(blob);
let downloadElement = document.createElement('a');
downloadElement.href = url;
downloadElement.download = `高清出图-${getDateTimeString()}.png`;
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
}, 'image/png', 0.95);
if (type === 'export') {
const iframeWindow = iframe.contentWindow;
if (iframeWindow && typeof iframeWindow.print === 'function') {
iframeWindow.addEventListener('afterprint', function () {
document.body.removeChild(iframe)
})
iframeWindow.print();
} else {
console.error('打印失败,请手动保存截图');
}
}
else {
canvas2.toBlob(function (blob) {
const url = URL.createObjectURL(blob);
let downloadElement = document.createElement('a');
downloadElement.href = url;
downloadElement.download = `高清出图-${getDateTimeString()}.png`;
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
URL.revokeObjectURL(url);
}, 'image/png', 0.95);
}
exporting = false;
exportBtn.innerHTML = '打印';
saveBtn.innerHTML = '保存';
// canvas2.toBlob(function (blob) {
// let imgBlobData = URL.createObjectURL(blob);
// let downloadElement = document.createElement('a');

View File

@ -123,6 +123,7 @@ async function ScreenShotHD(sdk, options = {}, cd = () => { }) {
startScreenShotObject.desist()
startScreenShotObject = null
}
window.removeEventListener('resize', resize)
_DialogObject = undefined
}
})
@ -133,7 +134,7 @@ async function ScreenShotHD(sdk, options = {}, cd = () => { }) {
<div class="div-item">
<div class="row text" style="align-items: flex-start;">
<div class="col">
<span>当前窗口长宽:<span class="input-width">${sdk.viewer.canvas.width}</span>*<span class="input-height">${sdk.viewer.canvas.height}</span>像素</span>
<span>当前窗口长宽:<span class="input-width canvas-width-span">${sdk.viewer.canvas.width}</span>*<span class="input-height canvas-height-span">${sdk.viewer.canvas.height}</span>像素</span>
</div>
</div>
<div class="row scale-box" style="align-items: flex-start;">
@ -176,6 +177,17 @@ async function ScreenShotHD(sdk, options = {}, cd = () => { }) {
sdk.viewer.scene.screenSpaceCameraController.enableLook = false;
sdk.viewer._element.getElementsByClassName('compass')[0].style.pointerEvents = 'none'
window.addEventListener('resize', resize);
function resize() {
setTimeout(() => {
contentElm.getElementsByClassName('canvas-width-span')[0].innerHTML = sdk.viewer.canvas.width
contentElm.getElementsByClassName('canvas-height-span')[0].innerHTML = sdk.viewer.canvas.height
contentElm.getElementsByClassName('output-width')[0].innerHTML = sdk.viewer.canvas.width * scale
contentElm.getElementsByClassName('output-height')[0].innerHTML = sdk.viewer.canvas.height * scale
}, 500);
}
let centerResult = sdk.viewer.camera.pickEllipsoid(
new Cesium.Cartesian2(

View File

@ -166,6 +166,9 @@ function open(sdk) {
}
let isChanged = false
let rectangle = getViewExtend();
if(!rectangle) {
return
}
let minLng = Cesium.Math.toDegrees(rectangle.west)
let minLat = Cesium.Math.toDegrees(rectangle.south)

View File

@ -4,6 +4,7 @@ import DrawPolygon from "../../../Draw/drawPolygon"
import Tools from "../../../Tools";
import { closeRotateAround, closeViewFollow} from '../../../Global/global'
class Submerge extends Tools {
#_isupdate = false
/**
* @constructor
* @param sdk
@ -158,10 +159,12 @@ class Submerge extends Tools {
e_risingSpeed[0].value = that.options.risingSpeed
e_risingSpeed[1].value = that.options.risingSpeed
e_risingSpeed[0].addEventListener('input', e => {
that.#_isupdate = true
that.options.risingSpeed = Number(e.target.value);
});
e_risingSpeed[1].addEventListener('input', e => {
if (e.data != '.') {
that.#_isupdate = true
let value = Number(e.target.value)
let max = Number(e_risingSpeed[0].max)
let min = Number(e_risingSpeed[0].min)
@ -191,6 +194,7 @@ class Submerge extends Tools {
e_minWaterLevel.value = that.options.minWaterLevel
e_minWaterLevel.addEventListener('input', e => {
if (e.data != '.') {
that.#_isupdate = true
let value = Number(e.target.value)
if (value > 999999999) {
value = 999999999
@ -216,6 +220,7 @@ class Submerge extends Tools {
e_maxWaterLevel.value = that.options.maxWaterLevel
e_maxWaterLevel.addEventListener('input', e => {
if (e.data != '.') {
that.#_isupdate = true
let value = Number(e.target.value)
if (value > 999999999) {
value = 999999999
@ -250,6 +255,7 @@ class Submerge extends Tools {
e_waterVolume.value = that.options.waterVolume
e_waterVolume.addEventListener('input', e => {
if (e.data != '.') {
that.#_isupdate = true
let value = Number(e.target.value)
if (value > 99999999999999) {
value = 99999999999999
@ -319,19 +325,24 @@ class Submerge extends Tools {
if (this.TweenAnimate) {
TWEEN.remove(this.TweenAnimate)
}
let totalTime = ((this.options.maxWaterLevel - this.options.minWaterLevel) / this.options.risingSpeed) * 1000
this.TweenAnimate = new TWEEN.Tween({ waterLevel: this.options.minWaterLevel }).to({ waterLevel: this.options.maxWaterLevel }, totalTime).delay(this.delay).easing(TWEEN.Easing.Linear.None).onUpdate(async (r, a) => {
this.currentWaterLaver = r.waterLevel
}).start()
this.#_isupdate = false
let contentElm = this._DialogObject._element.body
let pauseBtn = contentElm.getElementsByClassName('pause')[0];
let startBtn = contentElm.getElementsByClassName('start')[0];
let totalTime = ((this.options.maxWaterLevel - this.options.minWaterLevel) / this.options.risingSpeed) * 1000
this.TweenAnimate = new TWEEN.Tween({ waterLevel: this.options.minWaterLevel }).to({ waterLevel: this.options.maxWaterLevel }, totalTime).delay(this.delay).easing(TWEEN.Easing.Linear.None).onUpdate(async (r, a) => {
this.currentWaterLaver = r.waterLevel
}).onComplete(()=>{
startBtn.style.display = 'flex'
pauseBtn.style.display = 'none'
}).start()
startBtn.style.display = 'none'
pauseBtn.style.display = 'flex'
}
restart() {
this.currentWaterLaver = this.options.minWaterLevel
this.#_isupdate = false
let isPaused = false
if (this.TweenAnimate) {
isPaused = this.TweenAnimate._isPaused
@ -348,7 +359,17 @@ class Submerge extends Tools {
start() {
if (this.TweenAnimate) {
this.TweenAnimate.resume()
if(this.#_isupdate) {
this.move()
}
else {
if(this.TweenAnimate._isPlaying) {
this.TweenAnimate.resume()
}
else {
this.TweenAnimate.start()
}
}
}
}
pause() {

View File

@ -397,6 +397,9 @@ class ViewShedStage extends Tools {
ctx.fillText(item.text, 44, 28 + (index * 26));
imagesLoaded++;
if (imagesLoaded === data.length) {
if (that.viewBillboardPrimitive) {
that.viewer.scene.primitives.remove(that.viewBillboardPrimitive)
}
that.viewBillboardPrimitive = that.viewer.scene.primitives.add(new Cesium.BillboardCollection())
that.viewBillboardPrimitive.add({
position: Cesium.Cartesian3.fromDegrees(that.viewPosition.lng, that.viewPosition.lat, that.viewPosition.alt + that.viewPointHeight),

View File

@ -893,7 +893,7 @@ class AttackArrowObject extends Base {
}
that.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let positionsA = that.computeAttackArrow(that.options.positions)
if (positionsA.length == 0) {
if (positionsA.length == 0 || Array.isArray(positionsA[0])) {
return
}
@ -1623,7 +1623,7 @@ class AttackArrowObject extends Base {
_addRr() {
if (this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value
})
this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value = ''
@ -1636,7 +1636,7 @@ class AttackArrowObject extends Base {
addAttributeRr(vr) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: vr
})
this.attributeVr = this.options.attribute.vr.content
@ -2189,22 +2189,23 @@ class AttackArrowObject extends Base {
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) {
// selectPoint = null
}
else if (selectPoint.index === that.options.positions.length) {
if (that.nodePoints[selectPoint.index - 1]) {
selectPoint = that.nodePoints[selectPoint.index - 1]
if (that.options.positions.length > 3) {
that.options.positions.pop()
that.sdk.viewer.entities.remove(that.nodePoints[that.nodePoints.length - 1])
that.nodePoints.pop()
if (!selectPoint.index) {
// selectPoint = null
}
else {
selectPoint.index = selectPoint.index - 1
else if (selectPoint.index === that.options.positions.length) {
if (that.nodePoints[selectPoint.index - 1]) {
selectPoint = that.nodePoints[selectPoint.index - 1]
}
else {
selectPoint.index = selectPoint.index - 1
}
}
that.renewPositions()
}
that.renewPositions()
}
})
@ -2317,7 +2318,7 @@ class AttackArrowObject extends Base {
}
}
let arr = this.computeAttackArrow(positions84)
if (arr.length == 0) {
if (arr.length == 0 || Array.isArray(arr[0])) {
return
}
this.entity.polygon.hierarchy = new Cesium.CallbackProperty(function () {
@ -2338,7 +2339,7 @@ class AttackArrowObject extends Base {
options.y = (options.y || options.y === 0) ? options.y : 10
let positions = this.computeAttackArrow(this.options.positions)
if (positions.length == 0) {
if (positions.length == 0 || Array.isArray(positions[0])) {
return
}
let points = [[]]
@ -2609,11 +2610,13 @@ class AttackArrowObject extends Base {
this.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let positionsA = this.computeAttackArrow(positions)
if (positionsA.length == 0) {
if (positionsA.length == 0 || Array.isArray(positionsA[0])) {
this.positionsH = [this.positions[0], this.positions[0], this.positions[0]]
return
}
let points = [[]]
let pos84 = []
for (let i = 0; i < positionsA.length; i++) {
let position = this.cartesian3Towgs84(positionsA[i], this.sdk.viewer)
pos84.push(position)

View File

@ -230,6 +230,17 @@ class Tileset extends BaseTileset {
else {
this.rotationEditing = true
}
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
return
}
},
translationalCallBack: () => {
if (this.positionEditing) {
@ -238,6 +249,17 @@ class Tileset extends BaseTileset {
else {
this.positionEditing = true
}
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
return
}
}
}, true)
document.getElementsByTagName('head')[0].appendChild(this._element_style);
@ -263,14 +285,14 @@ class Tileset extends BaseTileset {
//更新模型位置
updateModel(_tx, _ty, _tz, _rx = 0, _ry = 0, _rz = 0, s = 1) {
if (!this.tileset.root.transform) {
if (window.ELEMENT) {
window.ELEMENT.Message.closeAll();
window.ELEMENT.Message({
message: '该模型不支持移动和旋转!',
type: 'warning',
duration: 1500
});
}
// if (window.ELEMENT) {
// window.ELEMENT.Message.closeAll();
// window.ELEMENT.Message({
// message: '该模型不支持移动和旋转!',
// type: 'warning',
// duration: 1500
// });
// }
console.warn('该模型不支持移动和旋转!')
return
}

View File

@ -156,9 +156,9 @@ class BatchModel extends Base {
})
})
} else if (that.options.type == '点') {
let height = await that.getClampToHeight({ lng: that.options.positions.lng, lat: that.options.positions.lat })
posiArr = [{ lng: that.options.positions.lng, lat: that.options.positions.lat, alt: height }]
// posiArr = [that.options.positions]
// let height = await that.getClampToHeight({ lng: that.options.positions.lng, lat: that.options.positions.lat })
// posiArr = [{ lng: that.options.positions.lng, lat: that.options.positions.lat, alt: height }]
posiArr = [that.options.positions]
that.pointArr = posiArr
}
let params = {

View File

@ -304,17 +304,17 @@ function html(that) {
</div>
</div>
</DIV-cy-tab-pane>-->
<!-- <DIV-cy-tab-pane label="灯光控制">-->
<!-- <div>-->
<!-- <div class="row">-->
<!-- <div class="col">-->
<!-- <span class="label">指令</span>-->
<!-- <input class="input" type="text" @model="instruct">-->
<!-- <button class="primary" @click="instructSubmit">提交</button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </DIV-cy-tab-pane>-->
<!-- <DIV-cy-tab-pane label="灯光控制">
<div
<div class="row">
<div class="col">
<span class="label" style="flex: unset;">指令</span>
<input class="input" type="text" @model="instruct">
<!-- <button class="btn" style="margin-left: 10px;" @click="instructSubmit">提交</button> -->
</div>
</div>
</div>
<!-- </DIV-cy-tab-pane> -->
<!-- <DIV-cy-tab-pane label="设置操作点">-->
<!-- <div>-->
<!-- <div class="row">-->

View File

@ -175,6 +175,8 @@ class BillboardObject extends Base {
this.options.attribute.link.content || []
this.options.attribute.vr = this.options.attribute.vr || {}
this.options.attribute.vr.content = this.options.attribute.vr.content || []
this.options.attribute.rtmp = this.options.attribute.rtmp || {}
this.options.attribute.rtmp.content = this.options.attribute.rtmp.content || []
this.options.attribute.camera = this.options.attribute.camera || {}
this.options.attribute.camera.content =
this.options.attribute.camera.content || []
@ -589,6 +591,11 @@ class BillboardObject extends Base {
value: '链接',
key: 'link'
},
{
name: 'rtmp',
value: 'rtmp',
key: 'rtmp'
},
{
name: 'IP摄像头',
value: 'IP摄像头',
@ -682,7 +689,6 @@ class BillboardObject extends Base {
return this.options.heightMode ? this.options.heightMode : 0
}
set heightMode(v) {
this.options.heightMode = v ? v : 0
this.options.heightMode = v || v == 0 ? v : 3
let heightMode
let heightModeName = ''
@ -1704,6 +1710,170 @@ class BillboardObject extends Base {
}
}
get attributeRtmp() {
return this.options.attribute.rtmp.content
}
set attributeRtmp(v) {
this.options.attribute.rtmp.content = v
if (
!this._DialogObject ||
!this._DialogObject._element ||
!this._DialogObject._element.content ||
this._DialogObject._element.content.getElementsByClassName(
'attribute-content-rtmp'
).length == 0
) {
return
}
let table = this._DialogObject._element.content
.getElementsByClassName('attribute-content-rtmp')[1]
.getElementsByClassName('table')[0]
let tableContent = table.getElementsByClassName('table-body')[0]
tableContent.innerHTML = ''
if (this.options.attribute.rtmp.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.rtmp.content.length; i++) {
let tr =
`
<div class="tr">
<div class="td">` +
this.options.attribute.rtmp.content[i].name +
`</div>
<div class="td">` +
this.options.attribute.rtmp.content[i].url +
`</div>
<div class="td">
<button @click="rtmpEdit">编辑</button>
<button @click="rtmpDelete">删除</button>
</div>
</div>`
let trElm = document.createRange().createContextualFragment(tr)
tableContent.appendChild(trElm)
}
let item = tableContent.getElementsByClassName('tr')
let fun = {
rtmpEdit: async index => {
this.attributeRtmp = await this.options.attribute.rtmp.content
let table = this._DialogObject._element.content
.getElementsByClassName('attribute-content-rtmp')[1]
.getElementsByClassName('table')[0]
let tableContent = table.getElementsByClassName('table-body')[0]
let item = tableContent.getElementsByClassName('tr')
for (let i = 0; i < item.length; i++) {
if (index === i) {
let height = item[i].offsetHeight
let html = `
<div class="td">
<input class="input" type="text">
</div>
<div class="td">
<textarea class="input link-edit" type="text"></textarea>
</div>
<div class="td">
<button @click="confirmEdit">确认</button>
<button @click="cancelEdit">取消</button>
</div>`
item[i].innerHTML = html
let textareaElm = item[i].getElementsByClassName('link-edit')[0]
textareaElm.style.height = height - 10 + 'px'
let td = item[i].getElementsByClassName('td')
td[0].getElementsByClassName(
'input'
)[0].value = this.options.attribute.rtmp.content[index].name
td[1].getElementsByClassName(
'input'
)[0].value = this.options.attribute.rtmp.content[index].url
let btn = item[i].getElementsByTagName('button')
for (let n = 0; n < btn.length; n++) {
if (!btn[n] || !btn[n].attributes) {
continue
}
for (let m of btn[n].attributes) {
if (m.name === '@click') {
btn[n].addEventListener('click', e => {
if (typeof fun[m.value] === 'function') {
fun[m.value](
{
id: this.options.attribute.rtmp.content[index].id,
name: td[0].getElementsByClassName('input')[0].value,
url: td[1].getElementsByClassName('input')[0].value
},
i
)
}
})
btn[n].attributes.removeNamedItem(m.name)
break
}
}
}
break
}
}
},
rtmpDelete: i => {
this.options.attribute.rtmp.content.splice(i, 1)
this.attributeRtmp = this.options.attribute.rtmp.content
},
confirmEdit: (value, i) => {
let name = value.name && value.name.replace(/\s/g, '')
let url = value.url && value.url.replace(/\s/g, '')
if (name && url) {
this.options.attribute.rtmp.content[i] = value
} else {
window.ELEMENT &&
window.ELEMENT.Message({
message: '名称或链接不能为空!',
type: 'warning',
duration: 1500
})
}
this.attributeRtmp = this.options.attribute.rtmp.content
},
cancelEdit: () => {
this.attributeRtmp = this.options.attribute.rtmp.content
},
fileSelect: (value, i) => {
let fileElm = item[i].getElementsByClassName('file-select')[0]
fileElm.click()
fileElm.removeEventListener('change', fileSelect)
fileElm.addEventListener('change', fileSelect)
}
}
let fileSelect = event => {
if (event.target.value) {
let td = item[
event.target.getAttribute('index')
].getElementsByClassName('td')
td[1].getElementsByClassName('input')[0].value = event.target.value
event.target.value = null
}
}
for (let i = 0; i < item.length; i++) {
let btn = item[i].getElementsByTagName('button')
for (let n = 0; n < btn.length; n++) {
if (!btn[n] || !btn[n].attributes) {
continue
}
for (let m of btn[n].attributes) {
if (m.name === '@click') {
btn[n].addEventListener('click', e => {
if (typeof fun[m.value] === 'function') {
fun[m.value](i)
}
})
btn[n].attributes.removeNamedItem(m.name)
break
}
}
}
}
}
get attributeGoods() {
return this.options.attribute.goods.content
}
@ -1798,6 +1968,9 @@ class BillboardObject extends Base {
this.labelText = '未命名对象'
}
this.originalOptions = this.deepCopyObj(this.options)
this.previous = {
positions: { ...this.options.positions }
}
this._DialogObject.close()
let cdoptions = this.deepCopyObj(this.options)
cdoptions.host = ''
@ -1910,6 +2083,7 @@ class BillboardObject extends Base {
setTimeout(async () => {
this.attributeLink = this.options.attribute.link.content
this.attributeVr = this.options.attribute.vr.content
this.attributeRtmp = this.options.attribute.rtmp.content
// this.attributeCamera = this.options.attribute.camera
this.cameraSelect && this.cameraSelect()
this.ISCSelect && this.ISCSelect()
@ -2092,7 +2266,7 @@ class BillboardObject extends Base {
switch (heightMode) {
case 0:
case '0':
this.alt = Number(heightElm.value)
heightElm.value = this.alt
heightBoxElm.style.display = 'flex'
this.heightMode = 0
break
@ -2108,12 +2282,10 @@ class BillboardObject extends Base {
)
]
).then(position => {
this.alt =
Number(heightElm.value) +
Number(position[0].height.toFixed(2))
heightElm.value = Math.floor((this.alt - position[0].height) * 100) / 100
})
} else {
this.alt = Number(heightElm.value)
heightElm.value = 0
}
heightBoxElm.style.display = 'flex'
this.heightMode = 1
@ -2438,6 +2610,7 @@ class BillboardObject extends Base {
this.operatingPoint = this.originalOptions.operatingPoint
this.attributeLink = this.options.attribute.link.content
this.attributeVr = this.options.attribute.vr.content
this.attributeRtmp = this.options.attribute.rtmp.content
this.attributeCamera = this.options.attribute.camera.content
this.attributeGoods = this.options.attribute.goods.content
this.attributeISC = this.options.attribute.ISC.content
@ -2557,6 +2730,35 @@ class BillboardObject extends Base {
})
this.attributeVr = this.options.attribute.vr.content
}
_addRtmp() {
if (
this._DialogObject._element.content.getElementsByClassName('rtmp_add')[0]
.value
) {
this.options.attribute.rtmp.content.push({
id: Date.now(),
name: '地址',
url: this._DialogObject._element.content.getElementsByClassName(
'rtmp_add'
)[0].value
})
this._DialogObject._element.content.getElementsByClassName(
'rtmp_add'
)[0].value = ''
this.attributeRtmp = this.options.attribute.rtmp.content
} else {
this.Dialog.clickAddRtmp && this.Dialog.clickAddRtmp()
}
}
addAttributeRtmp(rtmp) {
this.options.attribute.rtmp.content.push({
id: Date.now(),
name: '地址',
url: rtmp
})
this.attributeRtmp = this.options.attribute.rtmp.content
}
/**
* 打开富文本框
@ -2669,9 +2871,7 @@ class BillboardObject extends Base {
)
]
).then(position => {
heightElm.value = Number(
(this.options.positions.alt - position[0].height).toFixed(2)
)
heightElm.value = Math.floor((this.alt - position[0].height) * 100) / 100
this.#_billboardHeight = this.options.positions.alt
})
} else {
@ -2989,7 +3189,7 @@ class BillboardObject extends Base {
let goodsHtml = ''
let richTextHtml = ''
for (let i = 0; i < this.options.attribute.link.content.length; i++) {
linkHtml += `<DIV-cy-tab-pane label="${this.options.attribute.link.content[i].name}"><iframe width='100%' height='100%' src="${this.options.attribute.link.content[i].url}" ></iframe></DIV-cy-tab-pane>`
linkHtml += `<DIV-cy-tab-pane label="${this.options.attribute.link.content[i].name}"><iframe width='100%' height='100%' src="${this.options.attribute.link.content[i].url}" sandbox="allow-scripts allow-same-origin"></iframe></DIV-cy-tab-pane>`
}
if (this.options.attribute.goods && this.options.attribute.goods.content && this.options.attribute.goods.content.length > 0) {
goodsHtml += `<DIV-cy-tab-pane label="物资">

View File

@ -1038,9 +1038,9 @@ class CircleDiffuse extends Base {
else if (this.options.positions) {
position = { ...this.options.positions[0] }
}
else if (this.options.center) {
position = { ...this.options.center }
}
// else if (this.options.center) {
// position = { ...this.options.center }
// }
else if (this.options.start) {
position = { ...this.options.start }
}

View File

@ -1991,7 +1991,7 @@ class CircleObject extends Base {
return '半径:' + moveRadius + ' 米'
}, false),
font: '20px Microsoft YaHei',
distanceDisplayCondition: 10000000,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,

View File

@ -83,7 +83,7 @@ class CurvelineObject extends Base {
this.options.type = options.type ? Number(options.type) : 0
this.options['nose-to-tail'] = options['nose-to-tail'] || false
this.options.extend = options.extend || false
this.options.rotate = options.rotate || true
this.options.rotate = (options.rotate || options.rotate === false) ? options.rotate : true
this.options.space = options.space || 1
this.options.speed = options.speed || 10
this.options.dashSize = options.dashSize || 0.03
@ -375,9 +375,10 @@ class CurvelineObject extends Base {
this._elms.lineWidth.forEach(item => {
item.value = this.options.width
})
this.entity &&
this.entity.polyline &&
(this.entity.polyline.width = this.options.width)
if (this.entity && this.entity.polyline) {
this.entity.polyline.width = this.entity.polyline.width + v - this.entity.polyline.oriWidth
this.entity.polyline.oriWidth = this.options.width
}
}
get lineType() {
@ -695,13 +696,13 @@ class CurvelineObject extends Base {
this.options.label.show = v
if (this.show && !this.showView || this.showView == 3) {
this.label.show = v
setTimeout(() => {
this.label.position = [
this.options.positions[0].lng,
this.options.positions[0].lat,
this.options.positions[0].alt
]
}, 0)
// setTimeout(() => {
// this.label.position = [
// this.options.positions[0].lng,
// this.options.positions[0].lat,
// this.options.positions[0].alt
// ]
// }, 0)
} else {
this.label.show = false
}
@ -1643,7 +1644,7 @@ class CurvelineObject extends Base {
// 创建标签页
let tabsElm = new cy_tabs(
'polyline-object-edit-tabs',
undefined,
tabClick,
this.sdk
)
// 颜色组件

View File

@ -47,9 +47,15 @@ class FlowLine extends Base {
this._elms = {};
this.positionArea = []
this.positions = []
this.sdk.addIncetance(this.options.id, this)
// FlowLine.create(this)
FlowLine.drawLine(this)
if (!this.options.positions || this.options.positions.length < 3) {
this._error = '最少需要绘制三个坐标!'
console.warn(this._error)
}
else {
this.sdk.addIncetance(this.options.id, this)
// FlowLine.create(this)
FlowLine.drawLine(this)
}
}
// 创建水面

View File

@ -69,7 +69,7 @@ class LabelObject extends Base {
let id = this.options.id + '-label'
let oldEntity = this.sdk.viewer.entities.getById(id)
if(oldEntity) {
if (oldEntity) {
this.sdk.viewer.entities.remove(oldEntity)
}
this.entity = this.sdk.viewer.entities.add({
@ -231,31 +231,27 @@ class LabelObject extends Base {
if (this.model.customScale.z > scale) {
scale = this.model.customScale.z
}
let pos = this.cartesian3Towgs84(this.model.position, this.sdk.viewer)
let point1 = Cesium.Cartesian3.fromDegrees(
this.options.position[0],
this.options.position[1],
this.options.position[2] +
pos.lng,
pos.lat,
pos.alt +
(this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
// 点2的位置也使用经纬高表示
let point2 = Cesium.Cartesian3.fromDegrees(
this.options.position[0],
this.options.position[1],
this.options.position[2] -
(this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
let direction = Cesium.Cartesian3.subtract(
point2,
point1,
new Cesium.Cartesian3()
)
let c = Cesium.Cartesian3.normalize(direction, direction)
let ray = new Cesium.Ray(point1, c)
// 计算该点在椭球面上的法线方向(垂直于地面的方向)
const ellipsoid = Cesium.Ellipsoid.WGS84;
const normal = ellipsoid.geodeticSurfaceNormal(point1);
let c = Cesium.Cartesian3.normalize(normal, normal)
const direction = Cesium.Cartesian3.multiplyByScalar(
c,
-1,
new Cesium.Cartesian3() // 用于存储结果的新对象
);
let ray = new Cesium.Ray(point1, direction)
let pickedObjects = this.viewer.scene.drillPickFromRay(ray, 5)
for (let i = 0; i < pickedObjects.length; i++) {
if (
pickedObjects[i].object &&
@ -440,12 +436,12 @@ class LabelObject extends Base {
this.updateBillboardImage()
}
updateBillboardImage() {
this.entity.billboard.image = this.getcanvas()
// clearTimeout(this.#updateBillboardImageTimeout)
// this.#updateBillboardImageTimeout = setTimeout(() => {
// clearTimeout(this.#updateBillboardImageTimeout)
// this.entity.billboard.image = this.getcanvas()
// }, 500)
// this.entity.billboard.image = this.getcanvas()
clearTimeout(this.#updateBillboardImageTimeout)
this.#updateBillboardImageTimeout = setTimeout(() => {
clearTimeout(this.#updateBillboardImageTimeout)
this.entity.billboard.image = this.getcanvas()
}, 500)
}
get lineColor() {
return this.options.pixelOffset

View File

@ -0,0 +1,466 @@
/**
* 标注
*/
import Base from '../index'
import MouseEvent from '../../../Event/index'
import {
getGroundCover
} from '../../../Global/global'
import { getFontFamily } from '../../Element/fontSelect'
import {
addCluster,
remove_entity_from_cluster
} from '../../../Global/cluster/cluster'
class LabelObject extends Base {
constructor(sdk, options = {}, model) {
super(sdk, options)
this.model = model
this.options.near = options.near || options.near === 0 ? options.near : 2000
this.options.far = options.far || options.far === 0 ? options.far : 100000
this.options.scaleByDistance = options.scaleByDistance || false
this.options.show =
options.show || options.show === false ? options.show : true
this.options.text = options.text
let textArray = this.options.text.split('\n')
for (let i = 0; i < textArray.length; i++) {
if (textArray[i].length > 40) {
textArray[i] = textArray[i].slice(0, 40 - textArray[i].length)
}
}
if (textArray.length > 10) {
textArray.splice(10 - textArray.length)
}
this.options.text = textArray.join('\n')
this.options.fontFamily = options.fontFamily || 0
this.font = getFontFamily(this.options.fontFamily) || 'SimHei'
this.options.fontSize = options.fontSize || 20
this.options.lineColor = options.lineColor || '#00ffff80'
this.options.color = options.color || '#ffffff'
this.options.ground =
options.ground || options.ground === false ? options.ground : true
this.options.pixelOffset =
options.pixelOffset || options.pixelOffset === 0
? options.pixelOffset
: 20
this.options.backgroundColor = options.backgroundColor || [
'#00ffff80',
'#00ffff80'
]
this.event = new MouseEvent(this.sdk)
this.entity
this.create(this.options.position)
this.picking = true
}
async create() {
let _this = this
if (!this.options.position[2] && this.options.position[2] !== 0) {
this.options.position[2] = await this.getClampToHeight({
lng: this.options.position[0],
lat: this.options.position[1]
})
}
this.originalOptions = copyObj(this.options)
let id = this.options.id + '-label'
let oldEntity = this.sdk.viewer.entities.getById(id)
if(oldEntity) {
this.sdk.viewer.entities.remove(oldEntity)
}
this.entity = this.sdk.viewer.entities.add({
show: this.options.show,
id: this.options.id + '-label',
position: new Cesium.CallbackProperty(function () {
if (_this.model) {
// return Cesium.Cartesian3.fromDegrees(_this.options.position[0], _this.options.position[1], _this.model.originalBoundingSphereRadius*2*_this.model.customScale.z + _this.options.position[2])
if (_this.model.isMove) {
let scale = _this.model.customScale.x
if (_this.model.customScale.y > scale) {
scale = _this.model.customScale.y
}
if (_this.model.customScale.z > scale) {
scale = _this.model.customScale.z
}
let point1 = Cesium.Cartesian3.fromDegrees(
_this.options.position[0],
_this.options.position[1],
_this.options.position[2] +
(_this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
// 点2的位置也使用经纬高表示
let point2 = Cesium.Cartesian3.fromDegrees(
_this.options.position[0],
_this.options.position[1],
_this.options.position[2] -
(_this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
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 pickedObjects = _this.viewer.scene.drillPickFromRay(ray, 5)
for (let i = 0; i < pickedObjects.length; i++) {
if (
pickedObjects[i].object &&
pickedObjects[i].object.id &&
pickedObjects[i].object.id === _this.model.id
) {
let pos84 = _this.cartesian3Towgs84(pickedObjects[i].position, _this.sdk.viewer)
_this.options.position[0] = pos84.lng
_this.options.position[1] = pos84.lat
_this.options.position[2] = pos84.alt
break
}
}
}
return Cesium.Cartesian3.fromDegrees(
_this.options.position[0],
_this.options.position[1],
_this.options.position[2]
)
} else {
return Cesium.Cartesian3.fromDegrees(..._this.options.position)
}
}, false),
// billboard: {
// image: this.getcanvas(),
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// disableDepthTestDistance: new Cesium.CallbackProperty(function () {
// return getGroundCover() ? undefined : Number.POSITIVE_INFINITY
// }, false),
// scaleByDistance: this.options.scaleByDistance
// ? new Cesium.NearFarScalar(this.options.near, 1, this.options.far, 0)
// : undefined,
// pixelOffsetScaleByDistance: this.options.scaleByDistance
// ? new Cesium.NearFarScalar(this.options.near, 1, this.options.far, 0)
// : undefined
// },
label: {
text: new Cesium.CallbackProperty(function () {
return _this.options.text
}, false),
font: this.options.fontSize + "px " + this.font,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: new Cesium.CallbackProperty(function () {
return getGroundCover() ? undefined : Number.POSITIVE_INFINITY
}, false),
scaleByDistance: this.options.scaleByDistance
? new Cesium.NearFarScalar(this.options.near, 1, this.options.far, 0)
: undefined,
pixelOffsetScaleByDistance: this.options.scaleByDistance
? new Cesium.NearFarScalar(this.options.near, 1, this.options.far, 0)
: undefined,
fillColor: Cesium.Color.fromCssColorString(this.options.color),
backgroundColor: Cesium.Color.fromCssColorString('#6e6e6e'),
backgroundPadding: new Cesium.Cartesian2(10, 10),
showBackground: true,
outlineWidth: 0,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
},
})
}
get position() {
return this.options.position
}
set position(v) {
// console.log(v)
this.options.position = v
if (!v[2] && v[2] !== 0) {
let objectsToExclude = [...this.sdk.viewer.entities.values]
this.getClampToHeight({
lng: v[0],
lat: v[1]
}, objectsToExclude).then(height => {
v[2] = height
this.options.position = [...v]
})
// let point1 = Cesium.Cartesian3.fromDegrees(this.options.position[0], this.options.position[1], 0);
// let point2 = Cesium.Cartesian3.fromDegrees(this.options.position[0], this.options.position[1], 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) {
// this.options.position[2] = this.cartesian3Towgs84(r.position, this.sdk.viewer).alt
// }
// else {
// try {
// let promise = Cesium.sampleTerrainMostDetailed(this.sdk.viewer.terrainProvider, [Cesium.Cartographic.fromDegrees(this.options.position[0], this.options.position[1])]);
// promise.then((p) => {
// this.options.position[2] = p[0].height
// }).catch((e)=>{
// })
// } catch (error) {
// }
// }
} else {
this.options.position = [...v]
}
}
get show() {
return this.options.show
}
set show(v) {
this.options.show = v
if (!this.entity) {
return
}
this.entity.show = v
if (this.model) {
// return Cesium.Cartesian3.fromDegrees(this.options.position[0], this.options.position[1], this.model.originalBoundingSphereRadius*2*this.model.customScale.z + this.options.position[2])
let scale = this.model.customScale.x
if (this.model.customScale.y > scale) {
scale = this.model.customScale.y
}
if (this.model.customScale.z > scale) {
scale = this.model.customScale.z
}
let point1 = Cesium.Cartesian3.fromDegrees(
this.options.position[0],
this.options.position[1],
this.options.position[2] +
(this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
// 点2的位置也使用经纬高表示
let point2 = Cesium.Cartesian3.fromDegrees(
this.options.position[0],
this.options.position[1],
this.options.position[2] -
(this.model.originalBoundingSphereRadius || 1) *
2 *
(scale || 0.01)
)
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 pickedObjects = this.viewer.scene.drillPickFromRay(ray, 5)
for (let i = 0; i < pickedObjects.length; i++) {
if (
pickedObjects[i].object &&
pickedObjects[i].object.id &&
pickedObjects[i].object.id === this.model.id
) {
let pos84 = this.cartesian3Towgs84(pickedObjects[i].position, this.sdk.viewer)
this.options.position[0] = pos84.lng
this.options.position[1] = pos84.lat
this.options.position[2] = pos84.alt
break
}
}
}
else if (this.options.ground) {
let objectsToExclude = [...this.sdk.viewer.entities.values]
this.getClampToHeight({
lng: this.options.position[0],
lat: this.options.position[1]
}, objectsToExclude).then(height => {
this.options.position[2] = height
})
}
}
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 > 40) {
textArray[i] = textArray[i].slice(0, 40 - textArray[i].length)
}
}
if (textArray.length > 10) {
textArray.splice(10 - textArray.length)
}
this.options.text = textArray.join('\n')
}
get color() {
return this.options.color
}
set color(v) {
this.options.color = v
this.entity.label.fillColor = Cesium.Color.fromCssColorString(this.options.color)
}
get scaleByDistance() {
return this.options.scaleByDistance
}
set scaleByDistance(v) {
this.options.scaleByDistance = v
if (!this.entity) {
return
}
if (this.options.scaleByDistance) {
this.entity.label.scaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
this.entity.label.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
} else {
this.entity.label.scaleByDistance = undefined
this.entity.label.pixelOffsetScaleByDistance = undefined
}
}
get near() {
return this.options.near
}
set near(v) {
let near = v
if (near > this.far) {
near = this.far
}
this.options.near = near
if (!this.entity) {
return
}
if (this.options.scaleByDistance) {
this.entity.label.scaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
this.entity.label.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
} else {
this.entity.label.scaleByDistance = undefined
this.entity.label.pixelOffsetScaleByDistance = undefined
}
}
get far() {
return this.options.far
}
set far(v) {
let far = v
if (far < this.near) {
far = this.near
}
this.options.far = far
if (!this.entity) {
return
}
if (this.options.scaleByDistance) {
this.entity.label.scaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
this.entity.label.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
this.options.near,
1,
this.options.far,
0
)
} else {
this.entity.label.scaleByDistance = undefined
this.entity.label.pixelOffsetScaleByDistance = undefined
}
}
get fontSize() {
return this.options.fontSize
}
set fontSize(v) {
this.options.fontSize = Number(v)
if (!this.entity) {
return
}
this.entity.label.font = this.options.fontSize + "px " + this.font
}
get fontFamily() {
return this.options.fontFamily
}
set fontFamily(v) {
this.options.fontFamily = v || 0
this.font = getFontFamily(this.options.fontFamily) || 'SimHei'
this.entity.label.font = this.options.fontSize + "px " + this.font
}
get ground() {
return this.options.ground
}
set ground(v) {
this.options.ground = v
}
// get backgroundColorStart() {
// return this.options.backgroundColor[0]
// }
// set backgroundColorStart(v) {
// this.options.backgroundColor[0] = v
// this.entity.billboard.image = this.getcanvas()
// }
// get backgroundColorEnd() {
// return this.options.backgroundColor[1]
// }
// set backgroundColorEnd(v) {
// this.options.backgroundColor[1] = v
// this.entity.billboard.image = this.getcanvas()
// }
remove() {
this.sdk.viewer.entities.remove(this.entity)
this.entity = null
}
flicker() { }
}
export default LabelObject
const copyObj = (obj = {}) => {
//变量先置空
let newobj = null
//判断是否需要继续进行递归
if (typeof obj == 'object' && obj !== null) {
newobj = obj instanceof Array ? [] : {} //进行下一层递归克隆
for (var i in obj) {
newobj[i] = copyObj(obj[i])
} //如果不是对象直接赋值
} else newobj = obj
return newobj
}

View File

@ -19,8 +19,8 @@ import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../Gl
class PolygonObject extends Base {
/**
* @constructor
* @description 多边形
* @param sdk
* @description 多边形
* @param options {object} 属性
* @param options.id {string} 唯一标识
* @param options.show=true {boolean} 显示/隐藏
@ -28,51 +28,11 @@ class PolygonObject extends Base {
* @param options.color='rgba(255, 0, 0, 0.5)' {string} 颜色
* @param options.height {number} 高度
* @param options.heightMode=2{number} 高度模式0海拔高度1相对地表2依附模式
* @param options.areaUnit='平方米' {string} 面积单位
* @param options.line {object} 边框
* @param options.line.width=2 {string} 边框宽
* @param options.line.color="rgba(155, 155, 124, 0.89)" {string} 边框颜色
* @param {Array.<object>} options.positions 必填,经纬度和高度的列表,值交替 [{lon,lat,alt},...]
* @param options.positions[].lng {number} 经度
* @param options.positions[].lat {number} 纬度
* @param options.positions[].alt {number} 高度
* @param options.label {object} 标签对象
* @param options.label.text {string} 标签文本
* @param options.label.show {string} 标签显隐
* @param options.label.position {string} 标签位置
* @param options.label.position {object} 标签位置
* @param options.label.position.lng {number} 经度
* @param options.label.position.lat {number} 纬度
* @param options.label.position.alt {number} 高度
* @param options.label.fontSize=20 {number} 字体大小
* @param options.label.fontFamily=0 {number} 字体项 0黑体1思源黑体2庞门正道标题体3数黑体
* @param options.label.color=#ffffff {string} 字体颜色
* @param options.label.lineWidth=4 {number} 引线宽
* @param options.label.lineColor=#00ffff80 {string} 引线颜色
* @param options.label.pixelOffset=20 {number} 字体偏移(引线长度)
* @param options.label.backgroundColor=['#00ffff80', '#00ffff80'] {array} 背景颜色
* @param options.label.scaleByDistance {boolean} 距离缩放
* @param options.label.near=2000 {number} 视野缩放最近距离
* @param options.label.far=100000 {number} 视野缩放最远距离
* @param options.attribute {object} 属性内容
* @param {object} options.attribute.link={} 链接
* @param options.attribute.link.content=[]] {array} 链接内容
* @param options.attribute.link.content[].name {string} 链接名称
* @param options.attribute.link.content[].url {string} 链接地址
* @param options.richTextContent {string} 富文本内容
* @param options.customView {object} 默认视角
* @param options.customView.orientation {object} 默认视角方位
* @param options.customView.orientation.heading {number} 航向角
* @param options.customView.orientation.pitch {number} 俯仰角
* @param options.customView.orientation.roll {number} 翻滚角
* @param options.customView.relativePosition {object} 视角相对位置
* @param options.customView.relativePosition.lng {number} 经度
* @param options.customView.relativePosition.lat {number} 纬度
* @param options.customView.relativePosition.alt {number} 高度
*
*
* @param {Array.<object>} options.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
* @param _Dialog {object} 弹框事件
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
* */
@ -1877,7 +1837,7 @@ class PolygonObject extends Base {
)[0].value
) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: this._DialogObject._element.content.getElementsByClassName(
'vr_add'
)[0].value
@ -1893,7 +1853,7 @@ class PolygonObject extends Base {
addAttributeRr(vr) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: vr
})
this.attributeVr = this.options.attribute.vr.content
@ -2276,6 +2236,7 @@ class PolygonObject extends Base {
static nodeEdit(that, cb = () => { }) {
that.positionEditing = false
setTimeout(() => {
let previous = [...that.options.positions]
if (YJ.Measure.GetMeasureStatus()) {
cb('上一次测量未结束')
} else {
@ -2338,6 +2299,9 @@ class PolygonObject extends Base {
that.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
that.previous = {
positions: [...that.positions]
}
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
let objectsToExclude = [...that.sdk.viewer.entities.values]
@ -2429,6 +2393,77 @@ class PolygonObject extends Base {
if (added) {
that.options.positions.splice(selectPoint.index, 1)
}
if (that.options.positions.length < 3) {
console.warn('多边形最少需要三个坐标!')
window.ELEMENT &&
window.ELEMENT.Message({
message: '多边形最少需要三个坐标!',
type: 'warning',
duration: 1500
})
that.options.positions = [...previous]
let positions = that.options.positions
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
that.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
newpositions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
that.previous = {
positions: [...that.positions]
}
let objectsToExclude = [...that.sdk.viewer.entities.values]
let positions2 = [[]]
for (let i = 0; i < that.options.positions.length; i++) {
positions2[0].push([
that.options.positions[i].lng,
that.options.positions[i].lat
])
}
positions2[0].push([
that.options.positions[0].lng,
that.options.positions[0].lat
])
let polygon = turf.polygon(positions2)
let centroid = turf.centroid(polygon)
that
.getClampToHeight({
lng: centroid.geometry.coordinates[0],
lat: centroid.geometry.coordinates[1]
}, objectsToExclude)
.then(height => {
that.label.position = [
centroid.geometry.coordinates[0],
centroid.geometry.coordinates[1],
height
]
})
that.options.areaByMeter = that.computeArea(that.options.positions)
switch (that.options['area-unit']) {
case '平方米':
that.area = that.options.areaByMeter
break
case '平方千米':
that.area = Number(
(that.options.areaByMeter / 1000000).toFixed(8)
)
break
case '亩':
that.area = Number(
(that.options.areaByMeter / 666.6666667).toFixed(4)
)
break
case '公顷':
that.area = Number((that.options.areaByMeter / 10000).toFixed(6))
break
default:
that.area = that.options.areaByMeter
}
}
cb(null, that.options.positions)
}

View File

@ -1468,6 +1468,7 @@ class PolyhedronObject extends Base {
let originalPosition
let added = false
let previous = [...that.options.positions]
let leftEvent = (movement, cartesian) => {
if (selectPoint) {
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
@ -1531,6 +1532,25 @@ class PolyhedronObject extends Base {
if(added) {
that.options.positions.splice(selectPoint.index, 1)
}
if (!that.options.positions || that.options.positions.length < 3) {
console.warn('多面体最少需要三个坐标!')
window.ELEMENT && window.ELEMENT.Message({
message: '多面体最少需要三个坐标!',
type: 'warning',
duration: 1500
});
that.options.positions = [...previous]
}
let labelPositions = [[]]
for (let i = 0; i < that.options.positions.length; i++) {
labelPositions[0].push([that.options.positions[i].lng, that.options.positions[i].lat])
}
labelPositions[0].push([that.options.positions[0].lng, that.options.positions[0].lat])
if (labelPositions[0].length >= 4) {
let polygon = turf.polygon(labelPositions);
let centroid = turf.centroid(polygon);
that.label.position = [centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], that.options.height + that.options.extrudedHeight]
}
that.options.areaByMeter = that.computeArea(that.options.positions);
switch (that.options['area-unit']) {
case '平方米':

View File

@ -77,7 +77,7 @@ class PolylineObject extends Base {
this.options['nose-to-tail'] = options['nose-to-tail'] || false
this.options.smooth = options.smooth || false
this.options.extend = options.extend || false
this.options.rotate = options.rotate || true
this.options.rotate = (options.rotate || options.rotate === false) ? options.rotate : true
this.options.space = options.space || 1
this.options.speed = options.speed || 10
this.options.dashSize = options.dashSize || 0.03

View File

@ -1065,9 +1065,9 @@ class RadarScan extends Base {
else if (this.options.positions) {
position = { ...this.options.positions[0] }
}
else if (this.options.center) {
position = { ...this.options.center }
}
// else if (this.options.center) {
// position = { ...this.options.center }
// }
else if (this.options.start) {
position = { ...this.options.start }
}

View File

@ -1317,9 +1317,9 @@ class RadarScanStereoscopic extends Base {
else if (this.options.positions) {
position = { ...this.options.positions[0] }
}
else if (this.options.center) {
position = { ...this.options.center }
}
// else if (this.options.center) {
// position = { ...this.options.center }
// }
else if (this.options.start) {
position = { ...this.options.start }
}

View File

@ -1889,6 +1889,7 @@ class SectorObject extends Base {
that.positionEditing = false
if (YJ.Measure.GetMeasureStatus()) {
} else {
let entity
that.event && that.event.destroy()
that.event = new MouseEvent(that.sdk)
YJ.Measure.SetMeasureStatus(true)
@ -1899,7 +1900,9 @@ class SectorObject extends Base {
let fromDegreesArray = that.calSector(that.options.center, that.options.radius, that.options.startAngle, that.options.endAngle)
let points = []
let endpoint = { ...that.options.center }
let radius = that.options.radius
let moveRadius = null
let options = {
angle1: that.options.startAngle,
angle2: that.options.endAngle
@ -2002,12 +2005,14 @@ class SectorObject extends Base {
that.sdk.viewer.entities.remove(that.nodePoints[i])
}
that.nodePoints = []
createRadiusLine()
}
}
})
that.event.mouse_move((movement, cartesian) => {
if (selectPoint) {
entity && (entity.show = true)
let pos84 = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
if (selectPoint._type === 'sector-start') {
points[1] = pos84
@ -2016,9 +2021,8 @@ class SectorObject extends Base {
points[2] = pos84
}
options = calculateAangle(points)
let pointA = Cesium.Cartesian3.fromDegrees(points[0].lng, points[0].lat, 0);
let pointB = Cesium.Cartesian3.fromDegrees(pos84.lng, pos84.lat, 0);;
radius = Cesium.Cartesian3.distance(pointA, pointB);
radius = that.computeDistance2([points[0], pos84]);
endpoint = that.cartesian3Towgs84(cartesian, that.viewer)
fromDegreesArray = that.calSector(that.options.center, radius, options.angle1, options.angle2)
}
@ -2059,6 +2063,38 @@ class SectorObject extends Base {
that.nodePoints.push(entity)
}
function createRadiusLine() {
entity = that.sdk.viewer.entities.add(
new Cesium.Entity({
show: false,
position: new Cesium.CallbackProperty((e) => {
if (endpoint) {
let c = that.computeMidpoint(that.options.center, endpoint)
return Cesium.Cartesian3.fromDegrees(c.lng, c.lat, endpoint.alt)
} else {
return Cesium.Cartesian3()
}
}, false),
label: {
text: new Cesium.CallbackProperty((e) => {
if (radius > 1000) {
return '半径:' + (radius / 1000).toFixed(2) + ' 公里'
}
return '半径:' + radius + ' 米'
}, false),
font: '20px Microsoft YaHei',
disableDepthTestDistance: Number.POSITIVE_INFINITY,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
fillColor: Cesium.Color.fromCssColorString('#f5ce0a'),
style: Cesium.LabelStyle.FILL_AND_OUTLINE
}
})
)
that.nodePoints.push(entity)
}
}
}

View File

@ -2117,7 +2117,9 @@ class StraightArrowObject extends Base {
that.event.gesture_pinck_start(() => { })
if (selectPoint) {
if (!originalPosition) {
that.options.positions.pop()
if (that.options.positions.length > 2) {
that.options.positions.pop()
}
}
else {
that.options.positions[selectPoint.index] = originalPosition

View File

@ -550,6 +550,7 @@ class StandText extends Base {
let originalPosition
let positions = that.options.positions
let previous = [...that.options.positions]
let fromDegreesArray = []
let minimumHeights = []
let maximumHeights = []
@ -625,6 +626,15 @@ class StandText extends Base {
if(isAdd) {
that.options.positions.splice(selectPoint.index, 1)
}
if (!that.options.positions || that.options.positions.length < 2) {
console.warn('最少需要两个坐标!')
window.ELEMENT && window.ELEMENT.Message({
message: '最少需要两个坐标!',
type: 'warning',
duration: 1500
});
that.options.positions = [...previous]
}
cb(null, that.options.positions)
}
let positions = that.options.positions

View File

@ -7,6 +7,7 @@ import EditGltf from "../../ModelController/EditGltf";
import Controller from "../../../Controller/index";
import MouseTip from '../../../MouseTip'
import LabelObject from '../LabelObject'
import LabelObject2 from '../LabelObject2'
import { setActiveViewer, CameraController, closeRotateAround } from '../../../Global/global'
import { syncData, get2DView, get3DView } from '../../../Global/MultiViewportMode'
import { legp } from '../../../Obj/Element/datalist';
@ -264,9 +265,9 @@ class TrajectoryMotion extends Base {
}
}
if (this.model && this.model.position) {
let heading = this.model.heading
let pitch = this.model.pitch
let roll = this.model.roll
let heading = this.options.model.heading
let pitch = this.options.model.pitch
let roll = this.options.model.roll
if (isNaN(heading) || isNaN(pitch) || isNaN(roll)) {
return
}
@ -1526,7 +1527,7 @@ class TrajectoryMotion extends Base {
static async createFuelLabel(that) {
let labelPosition = that.cartesian3Towgs84(that.model.position, that.sdk.viewer)
that.fuelLabel = new LabelObject(that.sdk, {
that.fuelLabel = new LabelObject2(that.sdk, {
show: that.options.show ? (that.options.fuelShow ? true : false) : false,
// show: true,
position: [labelPosition.lng, labelPosition.lat, labelPosition.alt],
@ -2345,7 +2346,7 @@ class TrajectoryMotion extends Base {
this.model && (this.model.show = false)
}
this.labelShow = this.originalOptions.label.show
this.fuelLabelShow = this.originalOptions.fuelShow
this.fuelShow = this.originalOptions.fuelShow
this.labelColor = this.originalOptions.label.color
this.labelFontSize = this.originalOptions.label.fontSize
this.labelFontFamily = this.originalOptions.label.fontFamily

View File

@ -1332,7 +1332,7 @@ class Vector extends Base {
return trsElm
}
flyTo(id, options = {}) {
async flyTo(id, options = {}) {
setActiveViewer(0)
closeRotateAround(this.sdk)
closeViewFollow(this.sdk)
@ -1392,33 +1392,34 @@ class Vector extends Base {
}
}
} else {
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)
this.sdk.viewer.camera.flyTo({
destination: destination,
orientation: orientation
})
} else {
if (this.range) {
if (this.range) {
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 position = { lng: this.range[0], lat: this.range[1] }
position.alt = await this.getClampToHeight(position)
let lng = this.options.customView.relativePosition.lng + position.lng
let lat = this.options.customView.relativePosition.lat + position.lat
let alt = this.options.customView.relativePosition.alt + position.alt
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
this.sdk.viewer.camera.flyTo({
destination: destination,
orientation: orientation
})
} else {
let array = []
this.getClampToHeight({
lng: this.range[0],

View File

@ -1123,23 +1123,25 @@ class WallRealStereoscopic extends Base {
let positions = []
for (let i = 0; i < optionsPositions.length - 1; i++) {
let pot1 = turf.point([optionsPositions[i].lng, optionsPositions[i].lat])
let pot2 = turf.point([optionsPositions[i + 1].lng, optionsPositions[i + 1].lat])
let bearing = turf.rhumbBearing(pot1, pot2);
let destination = turf.destination(pot1, this.options.width / 2 / 1000, bearing + 90, { units: 'kilometers' });
let destination2 = turf.destination(pot2, this.options.width / 2 / 1000, bearing + 90, { units: 'kilometers' });
let destination3 = turf.destination(pot1, this.options.width / 2 / 1000, bearing - 90, { units: 'kilometers' });
let destination4 = turf.destination(pot2, this.options.width / 2 / 1000, bearing - 90, { units: 'kilometers' });
let coordinates = destination.geometry.coordinates
let coordinates2 = destination2.geometry.coordinates
let coordinates3 = destination3.geometry.coordinates
let coordinates4 = destination4.geometry.coordinates
coordinates[2] = optionsPositions[i].alt
coordinates2[2] = optionsPositions[i + 1].alt
coordinates3[2] = optionsPositions[i].alt
coordinates4[2] = optionsPositions[i + 1].alt
if (optionsPositions[i]) {
let pot1 = turf.point([optionsPositions[i].lng, optionsPositions[i].lat])
let pot2 = turf.point([optionsPositions[i + 1].lng, optionsPositions[i + 1].lat])
let bearing = turf.rhumbBearing(pot1, pot2);
let destination = turf.destination(pot1, this.options.width / 2 / 1000, bearing + 90, { units: 'kilometers' });
let destination2 = turf.destination(pot2, this.options.width / 2 / 1000, bearing + 90, { units: 'kilometers' });
let destination3 = turf.destination(pot1, this.options.width / 2 / 1000, bearing - 90, { units: 'kilometers' });
let destination4 = turf.destination(pot2, this.options.width / 2 / 1000, bearing - 90, { units: 'kilometers' });
let coordinates = destination.geometry.coordinates
let coordinates2 = destination2.geometry.coordinates
let coordinates3 = destination3.geometry.coordinates
let coordinates4 = destination4.geometry.coordinates
coordinates[2] = optionsPositions[i].alt
coordinates2[2] = optionsPositions[i + 1].alt
coordinates3[2] = optionsPositions[i].alt
coordinates4[2] = optionsPositions[i + 1].alt
pos1.push([coordinates, coordinates2, coordinates4, coordinates3, coordinates])
pos1.push([coordinates, coordinates2, coordinates4, coordinates3, coordinates])
}
}
positions.push(pos1[0])
@ -1694,7 +1696,7 @@ class WallRealStereoscopic extends Base {
_addRr() {
if (this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value
})
this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value = ''
@ -1707,7 +1709,7 @@ class WallRealStereoscopic extends Base {
addAttributeRr(vr) {
this.options.attribute.vr.content.push({
name: '全景图' ,
name: '全景图',
url: vr
})
this.attributeVr = this.options.attribute.vr.content
@ -1830,6 +1832,7 @@ class WallRealStereoscopic extends Base {
let wallPositions = []
let topPositions = []
let previous = [...that.options.positions]
let isAdd = false
let firstMove = true
let leftEvent = (movement, cartesian) => {
@ -1883,6 +1886,15 @@ class WallRealStereoscopic extends Base {
if (isAdd) {
that.options.positions.splice(selectPoint.index, 1)
}
if (!that.options.positions || that.options.positions.length < 2) {
console.warn('最少需要两个坐标!')
window.ELEMENT && window.ELEMENT.Message({
message: '最少需要两个坐标!',
type: 'warning',
duration: 1500
});
that.options.positions = [...previous]
}
update()
cb(null, that.options.positions)
}
@ -1910,42 +1922,44 @@ class WallRealStereoscopic extends Base {
wallPositions = []
topPositions = []
for (let i = 0; i < positions.length; i++) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + that.options.extrudedHeight)
if (positions[i]) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + that.options.extrudedHeight)
}
wallPositions.push(fromDegreesArray)
topPositions.push(fromDegreesArray2)
let wall = that.sdk.viewer.entities.add({
id: that.options.id + '-' + WallRealStereoscopic.randomString(12),
polylineVolume: {
positions: isCallback ? new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i])
}, false) : Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i]),
shape: [
{ x: -0.0000001, y: -that.options.extrudedHeight / 2 },
{ x: 0.0000001, y: -that.options.extrudedHeight / 2 },
{ x: 0.0000001, y: that.options.extrudedHeight / 2 },
{ x: -0.0000001, y: that.options.extrudedHeight / 2 },
],
cornerType: Cesium.CornerType.MITERED
},
})
let top = that.sdk.viewer.entities.add({
id: that.options.id + '-' + WallRealStereoscopic.randomString(12),
polygon: {
hierarchy: isCallback ? new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i]))
}, false) : new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i])),
perPositionHeight: true,
material: Cesium.Color.fromCssColorString(that.options.color)
},
})
that.entity.add(wall)
that.entity.add(top)
wall.polylineVolume.material = that.getMaterial(wall.id)
}
wallPositions.push(fromDegreesArray)
topPositions.push(fromDegreesArray2)
let wall = that.sdk.viewer.entities.add({
id: that.options.id + '-' + WallRealStereoscopic.randomString(12),
polylineVolume: {
positions: isCallback ? new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i])
}, false) : Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i]),
shape: [
{ x: -0.0000001, y: -that.options.extrudedHeight / 2 },
{ x: 0.0000001, y: -that.options.extrudedHeight / 2 },
{ x: 0.0000001, y: that.options.extrudedHeight / 2 },
{ x: -0.0000001, y: that.options.extrudedHeight / 2 },
],
cornerType: Cesium.CornerType.MITERED
},
})
let top = that.sdk.viewer.entities.add({
id: that.options.id + '-' + WallRealStereoscopic.randomString(12),
polygon: {
hierarchy: isCallback ? new Cesium.CallbackProperty(function () {
return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i]))
}, false) : new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i])),
perPositionHeight: true,
material: Cesium.Color.fromCssColorString(that.options.color)
},
})
that.entity.add(wall)
that.entity.add(top)
wall.polylineVolume.material = that.getMaterial(wall.id)
}
}
}
@ -1959,18 +1973,19 @@ class WallRealStereoscopic extends Base {
if (selectPoint) {
let pos3 = that.sdk.viewer.scene.clampToHeight(cartesian, [...that.entity.values])
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(pos3, that.sdk.viewer)
let positions = that.calculatePositions()
for (let i = 0; i < positions.length; i++) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + that.options.extrudedHeight)
if (that.options.positions && that.options.positions.length >= 2) {
let positions = that.calculatePositions()
for (let i = 0; i < positions.length; i++) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + that.options.extrudedHeight)
}
wallPositions[i] = fromDegreesArray
topPositions[i] = fromDegreesArray2
}
wallPositions[i] = fromDegreesArray
topPositions[i] = fromDegreesArray2
}
that.label.position = [that.options.positions[0].lng, that.options.positions[0].lat, that.options.positions[0].alt + that.options.extrudedHeight]
// if (firstMove) {
// firstMove = false
@ -2052,38 +2067,40 @@ class WallRealStereoscopic extends Base {
this.entity.removeAll()
for (let i = 0; i < positions.length; i++) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + this.options.extrudedHeight)
if (positions[0]) {
let fromDegreesArray = []
let fromDegreesArray2 = []
for (let n = 0; n < positions[i].length; n++) {
fromDegreesArray.push(positions[i][n][0], positions[i][n][1], positions[i][n][2])
fromDegreesArray2.push(positions[i][n][0], positions[i][n][1], positions[i][n][2] + this.options.extrudedHeight)
}
wallPositions.push(fromDegreesArray)
topPositions.push(fromDegreesArray2)
let wall = this.sdk.viewer.entities.add({
id: this.options.id + '-' + WallRealStereoscopic.randomString(12),
polylineVolume: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i]),
shape: [
{ x: -0.0000001, y: -this.options.extrudedHeight / 2 },
{ x: 0.0000001, y: -this.options.extrudedHeight / 2 },
{ x: 0.0000001, y: this.options.extrudedHeight / 2 },
{ x: -0.0000001, y: this.options.extrudedHeight / 2 },
],
cornerType: Cesium.CornerType.MITERED
},
})
let top = this.sdk.viewer.entities.add({
id: this.options.id + '-' + WallRealStereoscopic.randomString(12),
polygon: {
hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i])),
perPositionHeight: true,
material: Cesium.Color.fromCssColorString(this.options.color)
},
})
this.entity.add(wall)
this.entity.add(top)
wall.polylineVolume.material = this.getMaterial(wall.id)
}
wallPositions.push(fromDegreesArray)
topPositions.push(fromDegreesArray2)
let wall = this.sdk.viewer.entities.add({
id: this.options.id + '-' + WallRealStereoscopic.randomString(12),
polylineVolume: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights(wallPositions[i]),
shape: [
{ x: -0.0000001, y: -this.options.extrudedHeight / 2 },
{ x: 0.0000001, y: -this.options.extrudedHeight / 2 },
{ x: 0.0000001, y: this.options.extrudedHeight / 2 },
{ x: -0.0000001, y: this.options.extrudedHeight / 2 },
],
cornerType: Cesium.CornerType.MITERED
},
})
let top = this.sdk.viewer.entities.add({
id: this.options.id + '-' + WallRealStereoscopic.randomString(12),
polygon: {
hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights(topPositions[i])),
perPositionHeight: true,
material: Cesium.Color.fromCssColorString(this.options.color)
},
})
this.entity.add(wall)
this.entity.add(top)
wall.polylineVolume.material = this.getMaterial(wall.id)
}
}
}

View File

@ -1317,6 +1317,7 @@ class WallStereoscopic extends Base {
let originalPosition
let positions = that.options.positions
let previous = [...that.options.positions]
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat, positions[i].alt)
@ -1382,6 +1383,15 @@ class WallStereoscopic extends Base {
if (isAdd) {
that.options.positions.splice(selectPoint.index, 1)
}
if (!that.options.positions || that.options.positions.length < 2) {
console.warn('最少需要两个坐标!')
window.ELEMENT && window.ELEMENT.Message({
message: '最少需要两个坐标!',
type: 'warning',
duration: 1500
});
that.options.positions = [...previous]
}
cb(null, that.options.positions)
}
let positions = that.options.positions

View File

@ -917,6 +917,32 @@ function attributeElm(that) {
</div>
</div>
</div>
<div class="row attribute-content attribute-content-rtmp">
<div class="col">
<span class="label">添加链接</span>
<div style="flex: 1;position: relative;">
<input class="input rtmp_add" type="text">
<i class="rtmp_add_btn" @click="_addRtmp"></i>
</div>
</div>
</div>
<div class="attribute-content attribute-content-rtmp">
<div class="table">
<div class="table-head">
<div class="tr">
<div class="th">名称</div>
<div class="th">链接</div>
<div class="th">操作</div>
</div>
</div>
<div class="table-body">
</div>
<div class="table-empty">
<div class="empty-img"></div>
<p>暂无数据</p>
</div>
</div>
</div>
<div class="attribute-content attribute-content-goods">
<div>
<div class="row">

View File

@ -94,6 +94,8 @@ function RadarScan() {
float falloff = length(scrPtRot);
material.alpha = pow(length(col + vec3(.5)),5.0) * transparency * 0.6;
material.diffuse = (0.5 + pow(angle, 2.0) * falloff ) * color.rgb ;
// float pattern = 0.5 + pow(angle, 2.0) * falloff; // 旋转的明暗图案
// material.diffuse = color.rgb * pattern + (1.0 - pattern) * 0.2; // 保留基础色,叠加明暗
return material;
}

View File

@ -1021,18 +1021,26 @@ class Proj {
function tenToThePowerOfN(n) {
return Math.pow(10, n);
}
let isF = false
if(degrees<0) {
isF = true
}
degrees = Math.abs(degrees)
let d = Math.floor(degrees); // 获取整度
let pow1 = tenToThePowerOfN(getDecimalPlaces(degrees))
let x = Math.floor((degrees - d) * pow1 * 60) / pow1; // 获取秒3600分之一度
let m = Math.floor(x);
if(isF) {
d = -d
}
let pow = tenToThePowerOfN(getDecimalPlaces(x))
let s = Math.floor((x - m) * pow) / pow * 60; // 获取秒3600分之一度
if (isDM) {
return d + "°" + Number(x.toFixed(4)) + "'"; // 返回度分格式
return d + "°" + (Math.floor(x * 10000) / 10000) + "'"; // 返回度分格式
}
else {
return d + "°" + m + "'" + s.toFixed(2) + '"'; // 返回度分秒格式
return d + "°" + m + "'" + (Math.floor(s * 100) / 100) + '"'; // 返回度分秒格式
}
}

View File

@ -828,39 +828,83 @@
this.uid = uid
_this.box.setAttribute("color-box-id", uid)
function clickEvent(event) {
if(!document.contains(_this.box)) {
document.removeEventListener('click', clickEvent);
}
// 检查点击事件是否发生在核心元素或其子元素之外
let boxNode
function recursion(node) {
if(!node.parentNode) {
boxNode = node
}
else {
if(node.getAttribute("color-box-id") === uid) {
boxNode = node
}
else {
recursion(node.parentNode)
}
}
}
recursion(event.target)
if(!boxNode) {
if(_this.pickerFlag) {
_this.close()
}
}
else {
if (!boxNode.getAttribute || boxNode.getAttribute("color-box-id") !== uid) {
if(_this.pickerFlag) {
_this.close()
}
}
}
console.log('------------')
}
document.addEventListener('click', clickEvent);
let mousedownEln
let mouseupEln
let flag = false
function mousedownEvent(event) {
flag = false
if(!document.contains(_this.box)) {
document.removeEventListener('mousedown', mousedownEvent);
}
// 检查点击事件是否发生在核心元素或其子元素之外
let boxNode
function recursion(node) {
if(!node.parentNode) {
boxNode = node
}
else {
if(node.getAttribute("color-box-id") === uid) {
boxNode = node
}
else {
recursion(node.parentNode)
}
}
}
recursion(event.target)
if(!boxNode) {
if(_this.pickerFlag) {
flag = true
}
}
else {
if (!boxNode.getAttribute || boxNode.getAttribute("color-box-id") !== uid) {
if(_this.pickerFlag) {
flag = true
}
}
}
}
function mouseupEvent(event) {
if(!document.contains(_this.box)) {
document.removeEventListener('mouseup', mouseupEvent);
}
// 检查点击事件是否发生在核心元素或其子元素之外
let boxNode
function recursion(node) {
if(!node.parentNode) {
boxNode = node
}
else {
if(node.getAttribute("color-box-id") === uid) {
boxNode = node
}
else {
recursion(node.parentNode)
}
}
}
recursion(event.target)
if(!boxNode) {
if(_this.pickerFlag && flag) {
_this.close()
}
}
else {
if (!boxNode.getAttribute || boxNode.getAttribute("color-box-id") !== uid) {
if(_this.pickerFlag && flag) {
_this.close()
}
}
}
flag = false
}
// document.addEventListener('click', clickEvent);
document.addEventListener('mousedown', mousedownEvent);
document.addEventListener('mouseup', mouseupEvent);
return this
}
function h(e) {

View File

@ -20096,8 +20096,8 @@
var testing =
'<div class="compass" title="拖动外圈:旋转视图,' +
'拖动内陀螺仪:自由轨道,' +
'双击:重置视图' +
'提示您还可以按住CTRL键并拖动地图来释放轨道." data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
'双击:重置视图' +
'" data-bind="visible: showCompass, event: { mousedown: handleMouseDown, dblclick: handleDoubleClick }">' +
'<div class="compass-outer-ring-background"></div>' +
" <div class=\"compass-rotation-marker\" data-bind=\"visible: isOrbiting, style: { transform: 'rotate(-' + orbitCursorAngle + 'rad)', '-webkit-transform': 'rotate(-' + orbitCursorAngle + 'rad)', opacity: orbitCursorOpacity }, cesiumSvgPath: { path: svgCompassRotationMarker, width: 145, height: 145 }\"></div>" +
" <div class=\"compass-outer-ring\" title=\"单击并拖动以旋转相机\" data-bind=\"style: { transform: 'rotate(-' + heading + 'rad)', '-webkit-transform': 'rotate(-' + heading + 'rad)' }, cesiumSvgPath: { path: svgCompassOuterRing, width: 145, height: 145 }\"></div>" +

View File

@ -426,7 +426,8 @@
}
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add_btn,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add_btn {
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add_btn,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .rtmp_add_btn {
display: inline-block;
width: 20px;
height: 20px;
@ -438,12 +439,14 @@
}
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add {
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .rtmp_add {
padding-right: 30px;
}
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .tr .td:last-child button:first-child,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .tr .td:last-child button:first-child {
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .tr .td:last-child button:first-child,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .tr .td:last-child button:first-child {
margin-right: 5px;
}
@ -477,9 +480,6 @@
border-top: none;
}
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr,
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr {}
.YJ-custom-base-dialog>.content .table .table-empty {
display: flex;
align-items: center;
@ -535,7 +535,8 @@
}
.YJ-custom-base-dialog>.content .attribute-content-link .table .table-body,
.YJ-custom-base-dialog>.content .attribute-content-vr .table .table-body {
.YJ-custom-base-dialog>.content .attribute-content-vr .table .table-body,
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .table-body {
max-height: 172px;
}
@ -578,7 +579,9 @@
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(1) {
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(1) {
width: 164px;
flex: 0 0 164px;
}
@ -586,7 +589,9 @@
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(2) {
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(2) {
width: 226px;
flex: 0 0 226px;
}
@ -594,14 +599,17 @@
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(3) {
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 150px;
width: 150px;
justify-content: center;
}
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td .input-group .input,
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td .input-group .input {
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td .input-group .input,
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td .input-group .input {
border-radius: 5px 0 0 5px;
}