init
This commit is contained in:
93
src/Obj/Base/AssembleObject/_element.js
Normal file
93
src/Obj/Base/AssembleObject/_element.js
Normal file
@ -0,0 +1,93 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="assemble-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2419
src/Obj/Base/AssembleObject/index.js
Normal file
2419
src/Obj/Base/AssembleObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
115
src/Obj/Base/AttackArrowObject/_element.js
Normal file
115
src/Obj/Base/AttackArrowObject/_element.js
Normal file
@ -0,0 +1,115 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 56px;">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">动画时长</span>
|
||||
<div class="input-number input-number-unit-3">
|
||||
<input class="input blur" type="number" title="" min="500" max="9999999" @model="spreadTime">
|
||||
<span class="unit">ms</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">动画</span>
|
||||
<input class="btn-switch" type="checkbox" @model="spreadState">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">动画重复</span>
|
||||
<input class="btn-switch" type="checkbox" @model="loop">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="attack-arrow-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2689
src/Obj/Base/AttackArrowObject/index.js
Normal file
2689
src/Obj/Base/AttackArrowObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
74
src/Obj/Base/BaseSource/BaseLayer/ArcgisImagery/index.js
Normal file
74
src/Obj/Base/BaseSource/BaseLayer/ArcgisImagery/index.js
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 19:00
|
||||
* @description:index
|
||||
* @update: 2023-11-20 19:00
|
||||
*/
|
||||
|
||||
import BaseLayer from "../index";
|
||||
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
|
||||
|
||||
class ArcgisLayer extends BaseLayer {
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "layer"
|
||||
}
|
||||
|
||||
async createArcGis(url) {
|
||||
let imageryProvider
|
||||
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
|
||||
imageryProvider = await Cesium.ArcGisMapServerImageryProvider.fromUrl(url);
|
||||
}
|
||||
else {
|
||||
imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
|
||||
url
|
||||
});
|
||||
}
|
||||
if (this.options.hasOwnProperty("layer_index")) {
|
||||
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(imageryProvider, this.options.layer_index)
|
||||
} else {
|
||||
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(imageryProvider,)
|
||||
}
|
||||
this.entity._id = this.options.id
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.show = this.options.show
|
||||
this.alpha = this.options.alpha
|
||||
this.brightness = this.options.brightness
|
||||
|
||||
if(this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ArcgisWXImagery extends ArcgisLayer {
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options);
|
||||
this.createArcGis("https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer")
|
||||
}
|
||||
}
|
||||
|
||||
class ArcgisBLUEImagery extends ArcgisLayer {
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options);
|
||||
this.createArcGis("https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer")
|
||||
}
|
||||
}
|
||||
|
||||
class ArcgisLWImagery extends ArcgisLayer {
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options);
|
||||
this.createArcGis("https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")
|
||||
}
|
||||
}
|
||||
|
||||
export {ArcgisWXImagery, ArcgisBLUEImagery, ArcgisLWImagery}
|
||||
72
src/Obj/Base/BaseSource/BaseLayer/GdImagery/index.js
Normal file
72
src/Obj/Base/BaseSource/BaseLayer/GdImagery/index.js
Normal file
@ -0,0 +1,72 @@
|
||||
import BaseLayer from "../index";
|
||||
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
|
||||
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 19:18
|
||||
* @description:index
|
||||
* @update: 2023-11-20 19:18
|
||||
*/
|
||||
class GdImagery extends BaseLayer {
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "layer"
|
||||
}
|
||||
|
||||
createGD(url) {
|
||||
let gdLayer = new Cesium.UrlTemplateImageryProvider({
|
||||
url,
|
||||
minimumLevel: 3,
|
||||
maximumLevel: 18,
|
||||
tilingScheme: this.amapMercatorTilingScheme()
|
||||
})
|
||||
|
||||
if (this.options.hasOwnProperty("layer_index")) {
|
||||
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(gdLayer, this.options.layer_index)
|
||||
} else {
|
||||
this.entity = this.sdk.viewer.imageryLayers.addImageryProvider(gdLayer,)
|
||||
}
|
||||
this.entity._id = this.options.id
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.show = this.options.show
|
||||
this.alpha = this.options.alpha
|
||||
this.brightness = this.options.brightness
|
||||
|
||||
if(this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GDLWImagery extends GdImagery {
|
||||
constructor(earth, options = {}) {
|
||||
super(earth, options);
|
||||
this.createGD("https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8")
|
||||
}
|
||||
}
|
||||
|
||||
class GDWXImagery extends GdImagery {
|
||||
constructor(earth, options = {}) {
|
||||
super(earth, options);
|
||||
this.createGD("https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}")
|
||||
}
|
||||
}
|
||||
|
||||
class GDSLImagery extends GdImagery {
|
||||
constructor(earth, options = {}) {
|
||||
super(earth, options);
|
||||
this.createGD("https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}")
|
||||
}
|
||||
}
|
||||
|
||||
export {GDLWImagery, GDWXImagery, GDSLImagery}
|
||||
147
src/Obj/Base/BaseSource/BaseLayer/Layer/index.js
Normal file
147
src/Obj/Base/BaseSource/BaseLayer/Layer/index.js
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 15:51
|
||||
* @description:index
|
||||
* @update: 2023-11-20 15:51
|
||||
*/
|
||||
import { getHost } from "../../../../../on";
|
||||
import { syncData } from '../../../../../Global/MultiViewportMode'
|
||||
import BaseLayer from "../index";
|
||||
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
|
||||
|
||||
|
||||
class Layer extends BaseLayer {
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
this.object = {}
|
||||
this.options.host = this.options.host || getHost()
|
||||
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "layer"
|
||||
}
|
||||
|
||||
on() {
|
||||
return this.add()
|
||||
}
|
||||
|
||||
|
||||
async add() {
|
||||
let res = await this.requestResource()
|
||||
let text = await res.text()
|
||||
text = JSON.parse(text)
|
||||
if ([0, 200].includes(text.code)) {
|
||||
return this.loadLayer(text.data)
|
||||
} else {
|
||||
return new Promise((res, reject) => {
|
||||
reject(text.msg || text.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async loadLayer(data) {
|
||||
this.object = { ...data }
|
||||
let url = ""
|
||||
if (this.object.url.startsWith("http"))
|
||||
url = this.object.url
|
||||
else {
|
||||
if (this.options.host) {
|
||||
let o = new URL(this.object.url, this.options.host)
|
||||
url = o.href
|
||||
} else
|
||||
url = this.object.url
|
||||
}
|
||||
let params = {
|
||||
url: url,
|
||||
mimmumLevel: this.object.minimumLevel,
|
||||
maximumLevel: this.object.maximumLevel,
|
||||
rectangle: new Cesium.Rectangle(
|
||||
Cesium.Math.toRadians(this.object.west),
|
||||
Cesium.Math.toRadians(this.object.south),
|
||||
Cesium.Math.toRadians(this.object.east),
|
||||
Cesium.Math.toRadians(this.object.north)
|
||||
),
|
||||
}
|
||||
// if (this.object.scheme_name === "GeographicTilingScheme") {
|
||||
// console.log("添加GeographicTilingScheme")
|
||||
// params.tilingScheme = new Cesium.GeographicTilingScheme()
|
||||
// }
|
||||
// if (this.object.scheme_name === "amapMercatorTilingScheme") {
|
||||
// console.log("添加amapMercatorTilingScheme")
|
||||
// params.tilingScheme = this.amapMercatorTilingScheme()
|
||||
// }
|
||||
|
||||
let layer
|
||||
// if (this.object.tiletrans === 'tms') {
|
||||
// params.url = params.url.substr(0, params.url.indexOf('{'))
|
||||
// tms = new Cesium.TileMapServiceImageryProvider(params)
|
||||
// } else {
|
||||
// tms = new Cesium.UrlTemplateImageryProvider(params)
|
||||
// }
|
||||
switch (this.object.scheme_name) {
|
||||
case "amapMercatorTilingScheme":
|
||||
params.tilingScheme = this.amapMercatorTilingScheme()
|
||||
break;
|
||||
case "":
|
||||
break;
|
||||
default:
|
||||
params.tilingScheme = new Cesium[this.object.scheme_name]()
|
||||
break;
|
||||
}
|
||||
switch (this.object.load_method) {
|
||||
case "tms":
|
||||
if(this.object.url.endsWith("tilemapresource.xml")){
|
||||
let arr = this.object.url.split("/")
|
||||
arr.pop()
|
||||
let url = arr.join("/")
|
||||
params.url = url
|
||||
}
|
||||
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
|
||||
layer = await Cesium.TileMapServiceImageryProvider.fromUrl(params.url, params);
|
||||
}
|
||||
else {
|
||||
layer = new Cesium.TileMapServiceImageryProvider(params)
|
||||
}
|
||||
break;
|
||||
case "xyz":
|
||||
layer = new Cesium.UrlTemplateImageryProvider(params)
|
||||
break;
|
||||
case "wmts":
|
||||
layer = new Cesium.WebMapTileServiceImageryProvider(params)
|
||||
break;
|
||||
default:
|
||||
layer = new Cesium.UrlTemplateImageryProvider(params)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!this.sdk || !this.sdk.viewer) {
|
||||
return
|
||||
}
|
||||
if (this.options.hasOwnProperty("layer_index")) {
|
||||
this.entity =
|
||||
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer, this.options.layer_index)
|
||||
} else {
|
||||
this.entity =
|
||||
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer,)
|
||||
}
|
||||
this.entity._id = this.options.id
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.show = this.options.show
|
||||
this.alpha = this.options.alpha
|
||||
this.brightness = this.options.brightness
|
||||
|
||||
if(this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Layer
|
||||
58
src/Obj/Base/BaseSource/BaseLayer/Layer3rdparty/index.js
vendored
Normal file
58
src/Obj/Base/BaseSource/BaseLayer/Layer3rdparty/index.js
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 15:51
|
||||
* @description:index
|
||||
* @update: 2023-11-20 15:51
|
||||
*/
|
||||
import BaseLayer from "../index";
|
||||
import { setSplitDirection, setActiveId } from '../../../../../Global/SplitScreen'
|
||||
|
||||
|
||||
class Layer3rdparty extends BaseLayer {
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
this.loadLayer()
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "layer"
|
||||
}
|
||||
|
||||
loadLayer(data) {
|
||||
let params = {
|
||||
url: this.options.url,
|
||||
mimmumLevel: this.options.minimumLevel || 0,
|
||||
maximumLevel: this.options.maximumLevel || 20,
|
||||
subdomains: ['0','1','2','3','4','5','6','7'],
|
||||
}
|
||||
|
||||
let layer
|
||||
|
||||
layer = new Cesium.UrlTemplateImageryProvider(params)
|
||||
if (this.options.hasOwnProperty("layer_index")) {
|
||||
this.entity =
|
||||
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer, this.options.layer_index)
|
||||
} else {
|
||||
this.entity =
|
||||
this.sdk.viewer.scene.imageryLayers.addImageryProvider(layer,)
|
||||
}
|
||||
this.entity._id = this.options.id
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.show = this.options.show
|
||||
this.alpha = this.options.alpha
|
||||
this.brightness = this.options.brightness
|
||||
|
||||
if(this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Layer3rdparty
|
||||
322
src/Obj/Base/BaseSource/BaseLayer/index.js
Normal file
322
src/Obj/Base/BaseSource/BaseLayer/index.js
Normal file
@ -0,0 +1,322 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 18:06
|
||||
* @description:index
|
||||
* @update: 2023-11-20 18:06
|
||||
*/
|
||||
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import CoordTransform from "../../../../transform/CoordTransform";
|
||||
import BaseSource from "../index";
|
||||
import { syncData, get2DView } from '../../../../Global/MultiViewportMode'
|
||||
import { setSplitDirection, syncSplitData } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
|
||||
|
||||
class BaseLayer extends BaseSource {
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.name = options.name || '未命名对象'
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue();
|
||||
this.options.alpha = this.options.alpha ?? 1
|
||||
this.options.brightness = this.options.brightness ?? 1
|
||||
}
|
||||
|
||||
get layerIndex() {
|
||||
return this.entity ? this.entity._layerIndex : undefined
|
||||
}
|
||||
|
||||
get layer_index() {
|
||||
return this.entity ? this.entity._layerIndex : undefined
|
||||
}
|
||||
|
||||
get brightness() {
|
||||
return this.options.brightness
|
||||
}
|
||||
|
||||
set brightness(v) {
|
||||
this.options.brightness = v
|
||||
this.entity.brightness = v
|
||||
}
|
||||
|
||||
get alpha() {
|
||||
return this.options.alpha
|
||||
}
|
||||
|
||||
|
||||
set alpha(v) {
|
||||
if (Number(v) > 1) v = 1
|
||||
if (Number(v) < 0) v = 0
|
||||
this.entity.alpha = v
|
||||
this.options.alpha = v
|
||||
this._elms.alpha && this._elms.alpha.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
/**@description 提高图层的一层层级
|
||||
* @method layerRaise
|
||||
* @param id {string} 图层id
|
||||
*@memberOf Layer
|
||||
* */
|
||||
layerRaise(id) {
|
||||
this.sdk.viewer.imageryLayers.raise(this.entity)
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.options.layer_index = this.entity._layerIndex
|
||||
return this.entity._layerIndex
|
||||
}
|
||||
|
||||
/**@description 降低图层的一层层级
|
||||
* @method layerLower
|
||||
* @memberOf Layer
|
||||
|
||||
* */
|
||||
layerLower() {
|
||||
this.sdk.viewer.imageryLayers.lower(this.entity)
|
||||
this.options.layer_index = this.entity._layerIndex
|
||||
return this.entity._layerIndex
|
||||
}
|
||||
|
||||
/**@description 置顶
|
||||
* @method layerToTop
|
||||
* @memberOf Layer
|
||||
|
||||
* */
|
||||
layerToTop() {
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(this.entity)
|
||||
for (let i = 0; i < this.sdk.viewer.imageryLayers._layers.length; i++) {
|
||||
if (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider && this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && (this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw' || this.sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww')) {
|
||||
let layer = this.sdk.viewer.imageryLayers._layers[i]
|
||||
this.sdk.viewer.imageryLayers.raiseToTop(layer)
|
||||
}
|
||||
}
|
||||
this.options.layer_index = this.entity._layerIndex
|
||||
return this.entity._layerIndex
|
||||
}
|
||||
|
||||
/**@description 置底
|
||||
* @method lowerToBottom
|
||||
* @memberOf Layer
|
||||
|
||||
* */
|
||||
layerToBottom() {
|
||||
this.sdk.viewer.imageryLayers.lowerToBottom(this.entity)
|
||||
this.options.layer_index = this.entity._layerIndex
|
||||
return this.entity._layerIndex
|
||||
}
|
||||
|
||||
remove() {
|
||||
super.remove()
|
||||
this.sdk.viewer.scene.imageryLayers.remove(this.entity)
|
||||
this.entity = null
|
||||
}
|
||||
|
||||
/**@description 定位
|
||||
* @method flyTo
|
||||
* @memberOf Layer
|
||||
|
||||
* */
|
||||
async flyTo(options = {}) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else if (this.options.start) {
|
||||
position = { ...this.options.start }
|
||||
}
|
||||
else {
|
||||
if (this.options.hasOwnProperty('lng')) {
|
||||
position.lng = this.options.lng
|
||||
}
|
||||
if (this.options.hasOwnProperty('lat')) {
|
||||
position.lat = this.options.lat
|
||||
}
|
||||
if (this.options.hasOwnProperty('alt')) {
|
||||
position.alt = this.options.alt
|
||||
}
|
||||
}
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
if (!position.hasOwnProperty('alt')) {
|
||||
position.alt = await this.getClampToHeight(position)
|
||||
}
|
||||
lng = this.options.customView.relativePosition.lng + position.lng
|
||||
lat = this.options.customView.relativePosition.lat + position.lat
|
||||
alt = this.options.customView.relativePosition.alt + position.alt
|
||||
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation
|
||||
})
|
||||
}
|
||||
else {
|
||||
this.sdk.viewer.flyTo(this.entity)
|
||||
}
|
||||
}
|
||||
|
||||
/*高德的纠偏*/
|
||||
amapMercatorTilingScheme(options) {
|
||||
class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
|
||||
constructor(options) {
|
||||
super(options)
|
||||
let projection = new Cesium.WebMercatorProjection()
|
||||
this._projection.project = function (cartographic, result) {
|
||||
result = CoordTransform.WGS84ToGCJ02(
|
||||
Cesium.Math.toDegrees(cartographic.longitude),
|
||||
Cesium.Math.toDegrees(cartographic.latitude)
|
||||
)
|
||||
result = projection.project(
|
||||
new Cesium.Cartographic(
|
||||
Cesium.Math.toRadians(result[0]),
|
||||
Cesium.Math.toRadians(result[1])
|
||||
)
|
||||
)
|
||||
return new Cesium.Cartesian2(result.x, result.y)
|
||||
}
|
||||
this._projection.unproject = function (cartesian, result) {
|
||||
let cartographic = projection.unproject(cartesian)
|
||||
result = CoordTransform.GCJ02ToWGS84(
|
||||
Cesium.Math.toDegrees(cartographic.longitude),
|
||||
Cesium.Math.toDegrees(cartographic.latitude)
|
||||
)
|
||||
return new Cesium.Cartographic(
|
||||
Cesium.Math.toRadians(result[0]),
|
||||
Cesium.Math.toRadians(result[1])
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AmapMercatorTilingScheme(options)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '底图属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.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)
|
||||
let sdk2D = get2DView()
|
||||
if (sdk2D && sdk2D != this.sdk) {
|
||||
for(let i=0;i<sdk2D.viewer.imageryLayers._layers.length;i++) {
|
||||
let layer = sdk2D.viewer.imageryLayers._layers[i]
|
||||
if(layer._id && layer._id == this.options.id) {
|
||||
layer.alpha = this.options.alpha
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
// resetCallBack: () => {
|
||||
// this.name = this.originalOptions.name
|
||||
// this.alpha = this.originalOptions.alpha
|
||||
// this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
// },
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
}, true)
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.style.width = '300px'
|
||||
let html = `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">名称:</span>
|
||||
<input class="input name" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">透明度:</span>
|
||||
<input type="range" class="alpha" min="0" max="1" step="0.01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
contentElm.innerHTML = html
|
||||
let nameElm = contentElm.getElementsByClassName('name')[0]
|
||||
let alphaElm = contentElm.getElementsByClassName('alpha')[0]
|
||||
nameElm.value = this.name
|
||||
alphaElm.value = this.alpha
|
||||
nameElm.addEventListener('input', () => {
|
||||
this.name = nameElm.value
|
||||
})
|
||||
alphaElm.addEventListener('input', () => {
|
||||
this.alpha = alphaElm.value
|
||||
})
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
this._elms.name = [nameElm]
|
||||
this._elms.alpha = [alphaElm]
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity && !this._DialogObject) {
|
||||
return
|
||||
}
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.name = this.options.name
|
||||
this.alpha = this.options.alpha
|
||||
this.brightness = this.options.brightness
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default BaseLayer
|
||||
196
src/Obj/Base/BaseSource/BaseModel/Model/_element.js
Normal file
196
src/Obj/Base/BaseSource/BaseModel/Model/_element.js
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">最大比例</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0.1" max="99999" step="0.1" @model="maximumScale">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">最小像素</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999" @model="minimumPixelSize">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-99999" max="9999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 60px;">固定大小</span>
|
||||
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="model-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="方向信息">
|
||||
<div>
|
||||
<div class="row">
|
||||
<p class="lable-left-line">旋转</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">x 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateX">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateX">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">y 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateY">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateY">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">z 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="360" min="0" step="0.01" @model="rotateZ">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="360" @model="rotateZ">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="lable-left-line">
|
||||
<span>缩放</span>
|
||||
<div class="checkbox-box">
|
||||
<input type="checkbox">
|
||||
<span>是否等比例缩放</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-equal" style="display: none;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">x 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleX">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleX">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">y 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleY">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleY">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">z 轴</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1" @model="scaleZ">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="99999" @model="scaleZ">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row equal" style="display: none;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">等比例缩放</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="99999" min="0" step="1">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="0" max="99999" step="1">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p class="lable-left-line">高度</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<input style="flex: 1;margin-right: 15px;" type="range" max="999999" min="-99999" step="0.01" @model="alt">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input style="width: 100px;" type="number" title="" min="-99999" max="999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
1715
src/Obj/Base/BaseSource/BaseModel/Model/index.js
Normal file
1715
src/Obj/Base/BaseSource/BaseModel/Model/index.js
Normal file
File diff suppressed because it is too large
Load Diff
123
src/Obj/Base/BaseSource/BaseModel/Model2/_element.js
Normal file
123
src/Obj/Base/BaseSource/BaseModel/Model2/_element.js
Normal file
@ -0,0 +1,123 @@
|
||||
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最大比例</span>
|
||||
<input class="input" type="number" title="" min="0.1" max="99999" step="0.1" @model="maximumScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最小像素</span>
|
||||
<input class="input" type="number" title="" min="1" max="99999" @model="minimumPixelSize">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">视野缩放</span>
|
||||
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="model-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="方向信息">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">x轴</span>
|
||||
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateX">
|
||||
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateX">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">y轴</span>
|
||||
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateY">
|
||||
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateY">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">z轴</span>
|
||||
<input style="width: 332px;" type="range" max="360" min="0" step="0.01" @model="rotateZ">
|
||||
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="360" @model="rotateZ">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<input style="width: 332px;" type="range" max="999999" min="-99999" step="0.01" @model="alt">
|
||||
<input style="font-size: 13px;width: 100px;" type="number" title="" min="-99999" max="999999" @model="alt">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">缩放</span>
|
||||
<input style="width: 332px;" type="range" max="999" min="0" step="1" @model="scale">
|
||||
<input style="font-size: 13px;width: 100px;" type="number" title="" min="0" max="999" step="1" @model="scale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
function css() {
|
||||
return `
|
||||
.YJ-custom-base-dialog>.content {
|
||||
width: 600px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .label {
|
||||
flex: 0 0 74px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .DIV-cy-tab-content-pane .input-select {
|
||||
width: 100px;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export { html, css }
|
||||
1349
src/Obj/Base/BaseSource/BaseModel/Model2/index.js
Normal file
1349
src/Obj/Base/BaseSource/BaseModel/Model2/index.js
Normal file
File diff suppressed because it is too large
Load Diff
74
src/Obj/Base/BaseSource/BaseModel/index.js
Normal file
74
src/Obj/Base/BaseSource/BaseModel/index.js
Normal file
@ -0,0 +1,74 @@
|
||||
import richText from "../../../Element/richText";
|
||||
import BaseSource from "../index";
|
||||
|
||||
class BaseModel extends BaseSource {
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
}
|
||||
|
||||
async add() {
|
||||
if (this.options.url) {
|
||||
return this.loadModel(this.options.url)
|
||||
}
|
||||
}
|
||||
|
||||
_addLink() {
|
||||
// document.getElementsByClassName
|
||||
if (this._DialogObject._element.content.getElementsByClassName('link_add')[0].value) {
|
||||
this.options.attribute.link.content.push({
|
||||
name: '链接',
|
||||
url: this._DialogObject._element.content.getElementsByClassName('link_add')[0].value
|
||||
})
|
||||
this._DialogObject._element.content.getElementsByClassName('link_add')[0].value = ''
|
||||
this.attributeLink = this.options.attribute.link.content
|
||||
}
|
||||
else {
|
||||
this.Dialog.clickAddLink && this.Dialog.clickAddLink()
|
||||
}
|
||||
}
|
||||
|
||||
addAttributeLink(link) {
|
||||
this.options.attribute.link.content.push({
|
||||
name: '链接',
|
||||
url: link
|
||||
})
|
||||
this.attributeLink = this.options.attribute.link.content
|
||||
}
|
||||
|
||||
_addRr() {
|
||||
if (this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value) {
|
||||
this.options.attribute.vr.content.push({
|
||||
name: '全景图' ,
|
||||
url: this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value
|
||||
})
|
||||
this._DialogObject._element.content.getElementsByClassName('vr_add')[0].value = ''
|
||||
this.attributeVr = this.options.attribute.vr.content
|
||||
}
|
||||
else {
|
||||
this.Dialog.clickAddVr && this.Dialog.clickAddVr()
|
||||
}
|
||||
}
|
||||
|
||||
addAttributeRr(vr) {
|
||||
this.options.attribute.vr.content.push({
|
||||
name: '全景图' ,
|
||||
url: vr
|
||||
})
|
||||
this.attributeVr = this.options.attribute.vr.content
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开富文本框
|
||||
*/
|
||||
openRichTextEditor(e) {
|
||||
// var ue = UE.getEditor('app');
|
||||
richText.open(this.options.id, this.options.name, this.options.richTextContent)
|
||||
richText.primaryCallBack = (content) => {
|
||||
this.options.richTextContent = content
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BaseModel
|
||||
|
||||
293
src/Obj/Base/BaseSource/BaseTerrain/index.js
Normal file
293
src/Obj/Base/BaseSource/BaseTerrain/index.js
Normal file
@ -0,0 +1,293 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 17:54
|
||||
* @description:index
|
||||
* @update: 2023-11-20 17:54
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { getHost } from "../../../../on";
|
||||
import BaseSource from "../index";
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
|
||||
import { setSplitDirection, syncSplitData } from '../../../../Global/SplitScreen'
|
||||
|
||||
class BaseTerrain extends BaseSource {
|
||||
#updateModelTimeout;
|
||||
constructor(sdk, options = {}, object = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.object = JSON.parse(JSON.stringify(object))
|
||||
this.object.west || (this.object.west = 40)
|
||||
this.object.south || (this.object.south = 30)
|
||||
this.object.east || (this.object.east = 160)
|
||||
this.object.north || (this.object.north = 50)
|
||||
this.show = this.options.show
|
||||
this._elms = {};
|
||||
this.Dialog = _Dialog
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "terrain"
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.options.name
|
||||
}
|
||||
set name(v) {
|
||||
this.options.name = v
|
||||
this._elms.name && this._elms.name.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get show() {
|
||||
return !(
|
||||
this.sdk.viewer.scene.terrainProvider instanceof
|
||||
Cesium.EllipsoidTerrainProvider
|
||||
)
|
||||
}
|
||||
|
||||
set show(status) {
|
||||
status ? this.open() : this.close()
|
||||
}
|
||||
|
||||
async open() {
|
||||
if (this.options.url) {
|
||||
return this.loadTerrain({
|
||||
url: this.options.url
|
||||
})
|
||||
} else {
|
||||
let res = await this.requestResource()
|
||||
let text = await res.text()
|
||||
text = JSON.parse(text)
|
||||
if ([0, 200].includes(text.code)) {
|
||||
if (text.data.url.length)
|
||||
return this.loadTerrain(text.data)
|
||||
else
|
||||
return new Promise((res, reject) => {
|
||||
reject('资源不存在')
|
||||
})
|
||||
} else {
|
||||
return new Promise((res, reject) => {
|
||||
reject(text.msg || text.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//关闭地形
|
||||
close() {
|
||||
this.sdk.viewer.scene.terrainProvider =
|
||||
new Cesium.EllipsoidTerrainProvider({})
|
||||
for (let i = 0; i < YJ.Analysis.AnalysesResults.length; i++) {
|
||||
if (YJ.Analysis.AnalysesResults[i].type === 'ContourAnalysis') {
|
||||
YJ.Analysis.AnalysesResults[i].destroy()
|
||||
}
|
||||
}
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.#updateModelTimeout = setTimeout(() => {
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && (entity.heightMode == 1 || entity.heightMode == 3)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
else {
|
||||
if (entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async loadTerrain(options) {
|
||||
let object = { ...options }
|
||||
let url = ""
|
||||
if (object.url.startsWith("http"))
|
||||
url = object.url
|
||||
else {
|
||||
//说明是本地的json,在磁盘中存在的
|
||||
if (object.url.includes(":")) {
|
||||
url = object.url
|
||||
} else {
|
||||
if (this.options.host) {
|
||||
let o = new URL(object.url, this.options.host)
|
||||
url = o.href
|
||||
} else
|
||||
url = object.url
|
||||
}
|
||||
}
|
||||
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
|
||||
this.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(url)
|
||||
}
|
||||
else {
|
||||
this.terrainProvider = new Cesium.CesiumTerrainProvider({
|
||||
url: url
|
||||
})
|
||||
}
|
||||
if (!this.sdk || !this.sdk.viewer) {
|
||||
return
|
||||
}
|
||||
this.sdk.viewer.terrainProvider = this.terrainProvider;
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.#updateModelTimeout = setTimeout(() => {
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.terrainProvider.readyPromise.then(() => {
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && (entity.heightMode == 1 || entity.heightMode == 3)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
else {
|
||||
if (entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}, 1000);
|
||||
|
||||
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.close()
|
||||
}
|
||||
|
||||
async flyTo(duration = 3) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else if (this.options.start) {
|
||||
position = { ...this.options.start }
|
||||
}
|
||||
else {
|
||||
if (this.options.hasOwnProperty('lng')) {
|
||||
position.lng = this.options.lng
|
||||
}
|
||||
if (this.options.hasOwnProperty('lat')) {
|
||||
position.lat = this.options.lat
|
||||
}
|
||||
if (this.options.hasOwnProperty('alt')) {
|
||||
position.alt = this.options.alt
|
||||
}
|
||||
}
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
if (!position.hasOwnProperty('alt')) {
|
||||
position.alt = await this.getClampToHeight(position)
|
||||
}
|
||||
lng = this.options.customView.relativePosition.lng + position.lng
|
||||
lat = this.options.customView.relativePosition.lat + position.lat
|
||||
alt = this.options.customView.relativePosition.alt + position.alt
|
||||
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation,
|
||||
duration
|
||||
})
|
||||
}
|
||||
else {
|
||||
let rectangle = new Cesium.Rectangle(
|
||||
Cesium.Math.toRadians(this.object.west),
|
||||
Cesium.Math.toRadians(this.object.south),
|
||||
Cesium.Math.toRadians(this.object.east),
|
||||
Cesium.Math.toRadians(this.object.north)
|
||||
)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: rectangle,
|
||||
duration,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue()
|
||||
this.options.host = this.options.host || getHost()
|
||||
this.options.url = this.options.url || ""
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '地形属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._DialogObject.close()
|
||||
let cdoptions = this.deepCopyObj(this.options)
|
||||
cdoptions.host = ''
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(cdoptions)
|
||||
},
|
||||
// resetCallBack: () => {
|
||||
// this.name = this.originalOptions.name
|
||||
// this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
// },
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
}, true)
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.style.width = '300px'
|
||||
let html = `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称:</span>
|
||||
<input class="input name" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
contentElm.innerHTML = html
|
||||
let nameElm = contentElm.getElementsByClassName('name')[0]
|
||||
nameElm.value = this.name
|
||||
nameElm.addEventListener('input', () => {
|
||||
this.name = nameElm.value
|
||||
})
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
this._elms.name = [nameElm]
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default BaseTerrain
|
||||
93
src/Obj/Base/BaseSource/BaseTileset/BIM/_element.js
Normal file
93
src/Obj/Base/BaseSource/BaseTileset/BIM/_element.js
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">x轴</span>
|
||||
<input type="number" title="" min="-180" max="180" @model="roll">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">y轴</span>
|
||||
<input type="number" title="" min="-180" max="180" @model="heading">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="height">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">z轴</span>
|
||||
<input type="number" title="" min="-180" max="180" @model="pitch">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">大小</span>
|
||||
<input type="range" max="10" min="0.1" step="0.1" @model="scale">
|
||||
<div class="input-number" style="width: 100px;margin-left: 10px;">
|
||||
<input type="number" title="" min="0" max="10" step="0.1" @model="scale">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divide">
|
||||
<div class="line"></div>
|
||||
<p>BIM属性导出选项</p>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div style="display: flex;">
|
||||
<div class="checkbox-box" @click="exportState">
|
||||
<input type="checkbox" value="3">
|
||||
<span>修建中</span>
|
||||
</div>
|
||||
<div class="checkbox-box" @click="exportState">
|
||||
<input type="checkbox" value="2">
|
||||
<span>未完成</span>
|
||||
</div>
|
||||
<div class="checkbox-box" @click="exportState">
|
||||
<input type="checkbox" value="1">
|
||||
<span>已完成</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button @click="exportProperty">导 出</button>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
82
src/Obj/Base/BaseSource/BaseTileset/BIM/_element2.js
Normal file
82
src/Obj/Base/BaseSource/BaseTileset/BIM/_element2.js
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
function html2() {
|
||||
return `
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">构件名称</span>
|
||||
<input class="input" name="name" disabled="disabled">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">选择状态</span>
|
||||
<select class="input input-select" name="state-select">
|
||||
<option value="0" style="color: #000;">重置</option>
|
||||
<option value="1" style="color: #f00;">已完成</option>
|
||||
<option value="2" style="color: #0f0;">未完成</option>
|
||||
<option value="3" style="color: #00f;">修建中</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divide">
|
||||
<div class="line"></div>
|
||||
<p>自定义属性</p>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="property">
|
||||
</div>
|
||||
`
|
||||
}
|
||||
function css2() {
|
||||
return `
|
||||
.YJ-custom-base-dialog>.content {
|
||||
width: 440px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .row .label {
|
||||
flex: 0 0 110px;
|
||||
}
|
||||
.col:first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.col:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .divide {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .divide .line{
|
||||
height: 1px;
|
||||
background: #ddd;
|
||||
flex: 1;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .divide p{
|
||||
margin: 0 10px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .property .property-item .btn{
|
||||
font-size: 24px;
|
||||
line-height: 20px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .property .property-item .input_lable {
|
||||
flex: 0 0 115px;
|
||||
border: none;
|
||||
margin-right: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .property .property-item:first-child .delete{
|
||||
display: none
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .property .property-item .add{
|
||||
display: none;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .property .property-item:last-child .add{
|
||||
display: inline-block;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export { html2, css2 }
|
||||
877
src/Obj/Base/BaseSource/BaseTileset/BIM/index.js
Normal file
877
src/Obj/Base/BaseSource/BaseTileset/BIM/index.js
Normal file
@ -0,0 +1,877 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 16:05
|
||||
* @description:index
|
||||
* @update: 2023-11-20 16:05
|
||||
*/
|
||||
import BaseTileset from "../index";
|
||||
import { html } from "./_element";
|
||||
import { html2, css2 } from "./_element2";
|
||||
import Dialog from '../../../../Element/Dialog';
|
||||
import EventBinding from '../../../../Element/Dialog/eventBinding';
|
||||
import BaseDialog from '../../../../../BaseDialog'
|
||||
import { syncData } from '../../../../../Global/MultiViewportMode'
|
||||
import { syncSplitData } from '../../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../../Global/global'
|
||||
|
||||
class BIM extends BaseTileset {
|
||||
#updateModelTimeout
|
||||
/**
|
||||
* @constructor
|
||||
* @description 加载BIM模型
|
||||
* @param sdk {object} sdk
|
||||
* @param options {object} 模型参数
|
||||
* @param options.id {string} 对象id
|
||||
* @param options.show=true {boolean} 模型显隐
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 资源地址
|
||||
* @param options.position {object} 模型位置
|
||||
* @param options.position.lng {number} 经度
|
||||
* @param options.position.lat {number} 纬度
|
||||
* @param options.position.alt {number} 高度
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options)
|
||||
this.picking = false
|
||||
this.features = options.features || []
|
||||
this.exportStateArray = []
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this._EventBinding = new EventBinding()
|
||||
this.Dialog.exportState = (e) => {
|
||||
this.exportState(e)
|
||||
}
|
||||
this.Dialog.exportProperty = (e) => {
|
||||
this.exportProperty(this.exportStateArray)
|
||||
}
|
||||
this.features = new Map()
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "bim"
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.newData.name
|
||||
}
|
||||
|
||||
set name(v) {
|
||||
this.newData.name = v
|
||||
this._elms.name && this._elms.name.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.newData.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.newData.lng = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.newData.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.newData.lat = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.newData.height
|
||||
}
|
||||
|
||||
set height(v) {
|
||||
this.newData.height = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.height && this._elms.height.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get roll() {
|
||||
return this.newData.roll
|
||||
}
|
||||
|
||||
set roll(v) {
|
||||
this.newData.roll = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.roll && this._elms.roll.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get heading() {
|
||||
return this.newData.heading
|
||||
}
|
||||
|
||||
set heading(v) {
|
||||
this.newData.heading = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.heading && this._elms.heading.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get pitch() {
|
||||
return this.newData.pitch
|
||||
}
|
||||
|
||||
set pitch(v) {
|
||||
this.newData.pitch = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.pitch && this._elms.pitch.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get scale() {
|
||||
return this.newData.scale
|
||||
}
|
||||
|
||||
set scale(v) {
|
||||
this.newData.scale = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
this._elms.scale && this._elms.scale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
// get transparency() {
|
||||
// return this.newData.transparency
|
||||
// }
|
||||
|
||||
// set transparency(v) {
|
||||
// this.newData.transparency = v
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
// this.entity.transparency = Number(this.newData.transparency)
|
||||
// this._elms.transparency && this._elms.transparency.forEach((item) => {
|
||||
// item.value = v
|
||||
// })
|
||||
// }
|
||||
|
||||
async loadSceneTree(url) {
|
||||
|
||||
// Cesium.ExperimentalFeatures.enableModelExperimental = true;
|
||||
let array = url.split('/')
|
||||
array[array.length - 1] = 'scenetree.json'
|
||||
|
||||
|
||||
await Cesium.Resource.fetchJson({
|
||||
url: array.join('/')
|
||||
}).then(res => {
|
||||
this.scenetree = res
|
||||
|
||||
const initData = (array) => {
|
||||
array.forEach(item => {
|
||||
if (this.features.has(item.id)) {
|
||||
this.features.get(item.id).sphere = item.sphere
|
||||
}
|
||||
else {
|
||||
this.features.set(item.id, { sphere: item.sphere })
|
||||
}
|
||||
if (item.children) {
|
||||
initData(item.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
initData(res.scenes[0].children)
|
||||
|
||||
// res.scenes[0].children.forEach(item => {
|
||||
// if (this.features.has(item.id)) {
|
||||
// this.features.get(item.id).sphere = item.sphere
|
||||
// }
|
||||
// else {
|
||||
// this.features.set(item.id, {sphere: item.sphere})
|
||||
// }
|
||||
// })
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
|
||||
this._DialogObject = await new Dialog(this.sdk, this.newData, {
|
||||
title: 'BIM模型属性', left: '180px', top: '100px',
|
||||
resetCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
},
|
||||
confirmCallBack: (info) => {
|
||||
this.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.oldData.name = this.newData.name
|
||||
this.oldData.height = this.newData.height
|
||||
this.oldData.lng = this.newData.lng
|
||||
this.oldData.lat = this.newData.lat
|
||||
// this.oldData.transparency = this.newData.transparency
|
||||
this.oldData.scale = this.newData.scale
|
||||
this.oldData.roll = this.newData.roll
|
||||
this.oldData.heading = this.newData.heading
|
||||
this.oldData.pitch = this.newData.pitch
|
||||
this._DialogObject.close()
|
||||
let features = new Map()
|
||||
this.features.forEach((item, key) => {
|
||||
let data = { ...item }
|
||||
delete data.features
|
||||
features.set(key, data)
|
||||
})
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.oldData, features: features, type: this.type })
|
||||
syncSplitData(this.sdk, this.oldData.id)
|
||||
},
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
// this.newData.transparency = this.oldData.transparency
|
||||
// this.newData.name = this.oldData.name
|
||||
// this.newData.height = this.oldData.height
|
||||
// this.newData.lng = this.oldData.lng
|
||||
// this.newData.lat = this.oldData.lat
|
||||
// this.newData.scale = this.oldData.scale
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
this.editObj.destroy()
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.newData.show = show
|
||||
this.entity && (this.entity.show = show)
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
rotateCallBack: () => {
|
||||
if (this.rotationEditing) {
|
||||
this.rotationEditing = false
|
||||
}
|
||||
else {
|
||||
this.rotationEditing = true
|
||||
}
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
if (this.positionEditing) {
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
this.positionEditing = true
|
||||
}
|
||||
}
|
||||
})
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' tileset-bim'
|
||||
// 内容部分
|
||||
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.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async featureEdit(state, feature) {
|
||||
let _this = this
|
||||
this._element_style = null
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
// console.log(this.entity)
|
||||
// console.log(this.entity.root.children[0].content)
|
||||
// console.log(feature.getProperty('id'), feature.getProperty('name'), feature.getProperty('state'))
|
||||
let name = feature.getProperty('name')
|
||||
// console.log(feature.getProperty('descriptions'))
|
||||
let data = {
|
||||
id: feature.getProperty('id'),
|
||||
name: name,
|
||||
state: feature.getProperty('state') || 0,
|
||||
descriptions: feature.getProperty('descriptions') || [
|
||||
{
|
||||
id: this.randomString(),
|
||||
key: "点击此处可编辑",
|
||||
value: ""
|
||||
}
|
||||
]
|
||||
}
|
||||
switch (feature.getProperty('state')) {
|
||||
case '0': data.stateCH = ''
|
||||
break
|
||||
case '1': data.stateCH = '已完成'
|
||||
break
|
||||
case '2': data.stateCH = '未完成'
|
||||
break
|
||||
case '3': data.stateCH = '修建中'
|
||||
break
|
||||
}
|
||||
// let feature = this.entity.root.children[0].content.getFeature(0)
|
||||
// console.log(id,feature, this.entity)
|
||||
// return
|
||||
this._element_style = document.createElement('style');
|
||||
this._element_style.type = 'text/css';
|
||||
this._element_style.setAttribute('data-name', 'YJ_style_dialog');
|
||||
this._element_style.innerHTML = css2();
|
||||
|
||||
|
||||
this._DialogObject = await new BaseDialog(this.sdk.viewer._container, {
|
||||
title: this.oldData.name + '-----设置状态', left: 'calc(50% - 200px)', top: 'calc(50% - 200px)',
|
||||
closeCallBack: () => {
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
}
|
||||
})
|
||||
await this._DialogObject.init()
|
||||
document.getElementsByTagName('head')[0].appendChild(this._element_style);
|
||||
// 内容部分
|
||||
let content = document.createElement('div');
|
||||
content.innerHTML = html2()
|
||||
// 名称
|
||||
let e_name = content.querySelector("input[name='name']")
|
||||
e_name.value = name
|
||||
//状态
|
||||
let e_state = content.querySelector("select[name='state-select']")
|
||||
e_state.value = data.state
|
||||
e_state.addEventListener('change', (e) => {
|
||||
data.state = e.target.value
|
||||
switch (data.state) {
|
||||
case '0': data.stateCH = ''
|
||||
break
|
||||
case '1': data.stateCH = '已完成'
|
||||
break
|
||||
case '2': data.stateCH = '未完成'
|
||||
break
|
||||
case '3': data.stateCH = '修建中'
|
||||
break
|
||||
}
|
||||
});
|
||||
//自定义属性
|
||||
let e_property = content.getElementsByClassName('property')[0]
|
||||
for (let i = 0; i < data.descriptions.length; i++) {
|
||||
createPropertyItem(data.descriptions[i], i)
|
||||
}
|
||||
function createPropertyItem(item) {
|
||||
let html = `<div class="row property-item">
|
||||
<div class="col">
|
||||
<input class="input_lable" name="key" value="${item.key}">
|
||||
<input class="input" name="value" value="${item.value}">
|
||||
<button class="btn add">+</button>
|
||||
<button class="btn delete">-</button>
|
||||
</div>
|
||||
</div>`
|
||||
// document.createRange().createContextualFragment(html)
|
||||
let newElement = document.createElement("div");
|
||||
newElement.innerHTML = html
|
||||
let itemElm = newElement.getElementsByClassName('property-item')[0]
|
||||
let e_key = itemElm.querySelector("input[name='key']")
|
||||
let e_value = itemElm.querySelector("input[name='value']")
|
||||
let e_add = itemElm.getElementsByClassName('add')[0]
|
||||
let e_delete = itemElm.getElementsByClassName('delete')[0]
|
||||
e_key.addEventListener('input', (e) => {
|
||||
item.key = e.target.value
|
||||
})
|
||||
e_value.addEventListener('input', (e) => {
|
||||
item.value = e.target.value
|
||||
})
|
||||
e_add.addEventListener('click', () => {
|
||||
let newItem = {
|
||||
id: _this.randomString(),
|
||||
key: "点击此处可编辑",
|
||||
value: ""
|
||||
}
|
||||
data.descriptions.push(newItem)
|
||||
createPropertyItem(newItem)
|
||||
})
|
||||
e_delete.addEventListener('click', (e) => {
|
||||
for (let i = 0; i < data.descriptions.length; i++) {
|
||||
if (data.descriptions[i].id === item.id) {
|
||||
data.descriptions.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
e_property.removeChild(itemElm)
|
||||
// let item = {
|
||||
// key: "点击此处可编辑",
|
||||
// value: ""
|
||||
// }
|
||||
// createPropertyItem(item)
|
||||
})
|
||||
e_property.appendChild(itemElm)
|
||||
}
|
||||
let target = this._DialogObject._element.foot.getElementsByClassName('translational')[0]
|
||||
this._DialogObject.contentAppChild(content)
|
||||
// foot部分
|
||||
let confirmBtn = document.createElement('button');
|
||||
confirmBtn.className = 'confirm';
|
||||
confirmBtn.innerHTML = '确认'
|
||||
this._DialogObject.footAppChild(confirmBtn, target)
|
||||
confirmBtn.addEventListener('click', () => {
|
||||
let flag = false
|
||||
for (let i = 0; i < this.features.length; i++) {
|
||||
if (this.features[i].id == data.id) {
|
||||
this.features[i] = data
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
this.features.push(data)
|
||||
}
|
||||
feature.setProperty('state', data.state)
|
||||
feature.setProperty('descriptions', data.descriptions)
|
||||
let color = '#fff'
|
||||
switch (data.state) {
|
||||
case '0':
|
||||
color = '#fff'
|
||||
break;
|
||||
case '1':
|
||||
color = '#f00'
|
||||
break;
|
||||
case '2':
|
||||
color = '#0f0'
|
||||
break;
|
||||
case '3':
|
||||
color = '#00f'
|
||||
break;
|
||||
default:
|
||||
}
|
||||
feature.color = Cesium.Color.fromCssColorString(color)
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.newData, features: this.features })
|
||||
});
|
||||
} else {
|
||||
if (this._element_style) {
|
||||
document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
this._element_style = null
|
||||
}
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
// this.transparency = this.oldData.transparency
|
||||
this.name = this.oldData.name
|
||||
this.height = this.oldData.height
|
||||
this.lng = this.oldData.lng
|
||||
this.lat = this.oldData.lat
|
||||
this.roll = this.oldData.roll
|
||||
this.heading = this.oldData.heading
|
||||
this.pitch = this.oldData.pitch
|
||||
this.scale = this.oldData.scale
|
||||
}
|
||||
|
||||
//更新模型位置
|
||||
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
|
||||
});
|
||||
}
|
||||
console.warn('该模型不支持移动和旋转!')
|
||||
return
|
||||
}
|
||||
if ((!_tx && _tx!==0) || (!_ty && _ty!==0) || (!_tz && _tz!==0)) {
|
||||
return
|
||||
}
|
||||
let mx = Cesium.Matrix3.fromRotationX(
|
||||
Cesium.Math.toRadians(_rx)
|
||||
)
|
||||
let my = Cesium.Matrix3.fromRotationY(
|
||||
Cesium.Math.toRadians(_ry)
|
||||
)
|
||||
let mz = Cesium.Matrix3.fromRotationZ(
|
||||
Cesium.Math.toRadians(_rz)
|
||||
)
|
||||
// 平移
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz))
|
||||
// 旋转
|
||||
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz)
|
||||
let originalMatrix = new Cesium.Matrix4()
|
||||
Cesium.Matrix4.multiply(m, rotationX, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationZ, originalMatrix)
|
||||
const scale = Cesium.Matrix4.fromUniformScale(s);
|
||||
Cesium.Matrix4.multiply(originalMatrix, scale, this.entity._root.transform)
|
||||
if (!this.editObj.activeAxis) {
|
||||
this.editObj.position = { lng: _tx, lat: _ty, alt: _tz }
|
||||
}
|
||||
if (!this.editObj.activeCircle) {
|
||||
this.editObj.rotate = { x: _rx, y: _ry, z: _rz }
|
||||
}
|
||||
this.editObj && this.editObj.update()
|
||||
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.#updateModelTimeout = setTimeout(() => {
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
let center = this.cartesian3Towgs84(this.entity.boundingSphere.center, this.sdk.viewer)
|
||||
let circle = turf.circle([center.lng, center.lat], this.entity.boundingSphere.radius / 1000, { steps: 360, units: 'kilometers' });
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && entity.heightMode == 3) {
|
||||
let pt = turf.point([entity.lng, entity.lat]);
|
||||
if (turf.booleanPointInPolygon(pt, circle)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
|
||||
// exportProperty(states) {
|
||||
// console.log(this.features)
|
||||
// let fieldKeys = ['name', '', '', '', '', '', '', '', '', '', '', '', 'stateCH', 'descriptions']
|
||||
// let fieldLabels = ['构件名称', '体积', '墩全高H', '墩身高h', '底部高程', '承台宽', '承台长', '承台高', '族', '桩径', '桩长', '结构材质', '完成情况', '自定义属性']
|
||||
|
||||
// let dataStr = fieldLabels.toString() + '\r\n';
|
||||
// for (let i = 0; i < this.features.length; i++) {
|
||||
// for (let j = 0; j < states.length; j++) {
|
||||
// if (this.features[i].state == states[j]) {
|
||||
// fieldKeys.forEach(key => {
|
||||
// if (Array.isArray(this.features[i][key])) {
|
||||
// let str = ''
|
||||
// for (let k in this.features[i][key]) {
|
||||
// str += `${this.features[i][key][k].key + ':' + this.features[i][key][k].value}\n`
|
||||
// }
|
||||
// dataStr += `"${str}"\t`
|
||||
// }
|
||||
// else {
|
||||
// // 加引号是为了使换行符在单元格内正常显示
|
||||
// dataStr += `"${this.features[i][key] ? this.features[i][key] : ''}"\t,`;
|
||||
// }
|
||||
// });
|
||||
// dataStr += '\r\n';
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // encodeURIComponent 解决中文乱码
|
||||
// const url = "data:text/xls;charset=utf-8,\ufeff" + encodeURIComponent(dataStr);
|
||||
// console.log(url)
|
||||
// // const link = document.createElement("a");
|
||||
// // link.href = url;
|
||||
// // link.download = this.oldData.name + "--构件属性.xls";
|
||||
// // link.style.display = 'none';
|
||||
// // document.body.appendChild(link);
|
||||
// // link.click();
|
||||
// // document.body.removeChild(link); //释放标签
|
||||
// }
|
||||
|
||||
getScenetree() {
|
||||
return this.scenetree
|
||||
}
|
||||
|
||||
// 设置feature颜色
|
||||
featureColor(id, color) {
|
||||
if (this.features.has(id)) {
|
||||
let features = this.features.get(id).features
|
||||
for (let key in features) {
|
||||
if (features[key].content._model) {
|
||||
features[key].color = Cesium.Color.fromCssColorString(color)
|
||||
}
|
||||
features[key].customColor = Cesium.Color.fromCssColorString(color)
|
||||
}
|
||||
this.features.get(id).customColor = Cesium.Color.fromCssColorString(color)
|
||||
}
|
||||
}
|
||||
|
||||
getFeatureColor(id) {
|
||||
if (this.features.has(id)) {
|
||||
if (this.features.get(id).customColor) {
|
||||
return this.features.get(id).customColor
|
||||
}
|
||||
let features = this.features.get(id).features
|
||||
for (let key in features) {
|
||||
if (features[key].content._model) {
|
||||
return features[key].customColor || features[key].color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置feature显隐
|
||||
featureShow(id, show) {
|
||||
if (this.features.has(id)) {
|
||||
let features = this.features.get(id).features
|
||||
for (let key in features) {
|
||||
if (features[key].content._model) {
|
||||
features[key].show = show
|
||||
}
|
||||
features[key].customShow = show
|
||||
}
|
||||
this.features.get(id).customShow = show
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//飞到feature位置
|
||||
async featureFlyto(id) {
|
||||
if (this.features.has(id)) {
|
||||
let sphere = this.features.get(id).sphere
|
||||
let center = new Cesium.Cartesian3(
|
||||
sphere[0],
|
||||
sphere[1],
|
||||
sphere[2]
|
||||
)
|
||||
let srcMatInv = this.entity._root.originalTransform
|
||||
srcMatInv = Cesium.Matrix4.inverse(srcMatInv, new Cesium.Matrix4())
|
||||
let curMat = this.entity._root.transform
|
||||
let mat = Cesium.Matrix4.multiply(curMat, srcMatInv, new Cesium.Matrix4())
|
||||
let center2 = Cesium.Matrix4.multiplyByPoint(
|
||||
mat,
|
||||
center,
|
||||
new Cesium.Cartesian3()
|
||||
)
|
||||
let wgs84 = this.cartesian3Towgs84(center2, this.sdk.viewer)
|
||||
let cartesian3 = Cesium.Cartesian3.fromDegrees(
|
||||
wgs84.lng,
|
||||
wgs84.lat,
|
||||
wgs84.alt + sphere[3]
|
||||
)
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: cartesian3
|
||||
})
|
||||
// this.entity.style = await new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255,0.2)')"
|
||||
// });
|
||||
this.features.forEach((item, key) => {
|
||||
if (key === id) {
|
||||
let color = this.getFeatureColor(id)
|
||||
if (this.features.has(id) && color) {
|
||||
let features = this.features.get(id).features
|
||||
for (let k in features) {
|
||||
if (features[k].content._model) {
|
||||
features[k].color = color
|
||||
}
|
||||
features[k].customAlpha = 1
|
||||
}
|
||||
this.features.get(id).customAlpha = 1
|
||||
}
|
||||
// this.featureColor(id, `rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha})`)
|
||||
}
|
||||
else {
|
||||
let color = this.getFeatureColor(key)
|
||||
if (this.features.has(key) && color) {
|
||||
let features = this.features.get(key).features
|
||||
for (let k in features) {
|
||||
if (features[k].content._model) {
|
||||
features[k].color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha * 0.2})`)
|
||||
}
|
||||
features[k].customAlpha = color.alpha * 0.2
|
||||
}
|
||||
this.features.get(key).customAlpha = color.alpha * 0.2
|
||||
}
|
||||
// this.featureColor(key, `rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha * 0.2})`)
|
||||
}
|
||||
})
|
||||
// this.entity.readyPromise.then(()=>{
|
||||
// this.featureColor(id, '#ffffff')
|
||||
// })
|
||||
}
|
||||
else {
|
||||
this.features.forEach((item, key) => {
|
||||
let features = this.features.get(key).features
|
||||
let color = this.getFeatureColor(key)
|
||||
if (color) {
|
||||
for (let k in features) {
|
||||
if (features[k].content._model) {
|
||||
features[k].color = color
|
||||
}
|
||||
features[k].customAlpha = 1
|
||||
}
|
||||
this.features.get(key).customAlpha = color.alpha * 0.2
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导出属性
|
||||
exportProperty(states) {
|
||||
if (this.exportStateArray.length === 0) {
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: '未选择属性导出选项!',
|
||||
type: 'warning',
|
||||
duration: 1500
|
||||
});
|
||||
return
|
||||
}
|
||||
let fieldKeys = ['name', '', '', '', '', '', '', '', '', '', '', '', 'stateCH', 'descriptions']
|
||||
let fieldLabels = ['构件名称', '体积', '墩全高H', '墩身高h', '底部高程', '承台宽', '承台长', '承台高', '族', '桩径', '桩长', '结构材质', '完成情况', '自定义属性']
|
||||
var url = 'data:application/vnd.ms-excel;base64,',
|
||||
tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
|
||||
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
|
||||
+ '<Styles>'
|
||||
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
|
||||
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
|
||||
+ '</Styles>'
|
||||
+ '{worksheets}</Workbook>'
|
||||
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="120"/><ss:Column ss:Width="240"/>{rows}</Table></Worksheet>'
|
||||
, tmplCellXML = '<Cell><Data ss:Type="{nameType}">{data}</Data></Cell>'
|
||||
, base64 = function (s) {
|
||||
return window.btoa(unescape(encodeURIComponent(s)))
|
||||
}
|
||||
, format = function (s, c) {
|
||||
return s.replace(/{(\w+)}/g, function (m, p) {
|
||||
return c[p];
|
||||
})
|
||||
}
|
||||
|
||||
var ctx = "";
|
||||
var workbookXML = "";
|
||||
var worksheetsXML = "";
|
||||
var rowsXML = "";
|
||||
|
||||
var pil = 0;
|
||||
for (var i = 0; i < this.features.length; i++) {
|
||||
for (let j = 0; j < states.length; j++) {
|
||||
if (this.features[i].state == states[j]) {
|
||||
if (i == 0) {
|
||||
rowsXML += '<Row>' +
|
||||
'<Cell><Data ss:Type="String">构件名称</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">体积</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">墩全高H</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">墩身高h</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">底部高程</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台宽</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台长</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台高</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">族</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">桩径</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">桩长</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">结构材质</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">完成情况</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">自定义属性</Data></Cell>' +
|
||||
'</Row>';
|
||||
}
|
||||
rowsXML += '<Row>';
|
||||
for (var key in fieldKeys) {
|
||||
if (Array.isArray(this.features[i][fieldKeys[key]])) {
|
||||
let str = ''
|
||||
for (let k in this.features[i][fieldKeys[key]]) {
|
||||
str += `${this.features[i][fieldKeys[key]][k].key + ':' + this.features[i][fieldKeys[key]][k].value} `
|
||||
}
|
||||
ctx = {
|
||||
nameType: 'String',
|
||||
data: str
|
||||
};
|
||||
}
|
||||
else {
|
||||
ctx = {
|
||||
nameType: 'String',
|
||||
data: this.features[i][fieldKeys[key]] || "0"
|
||||
};
|
||||
}
|
||||
rowsXML += format(tmplCellXML, ctx);
|
||||
}
|
||||
rowsXML += '</Row>';
|
||||
if (i > 0 && (i / 60000) % 1 === 0) {
|
||||
pil++;
|
||||
ctx = { rows: rowsXML, nameWS: 'Sheet' + i };
|
||||
worksheetsXML += format(tmplWorksheetXML, ctx);
|
||||
rowsXML = "";
|
||||
rowsXML += '<Row>' +
|
||||
'<Cell><Data ss:Type="String">构件名称</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">体积</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">墩全高H</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">墩身高h</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">底部高程</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台宽</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台长</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">承台高</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">族</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">桩径</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">桩长</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">结构材质</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">完成情况</Data></Cell>' +
|
||||
'<Cell><Data ss:Type="String">自定义属性</Data></Cell>' +
|
||||
'</Row>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx = { rows: rowsXML, nameWS: 'Sheet' };
|
||||
worksheetsXML += format(tmplWorksheetXML, ctx);
|
||||
rowsXML = "";
|
||||
ctx = { created: (new Date()).getTime(), worksheets: worksheetsXML };
|
||||
workbookXML = format(tmplWorkbookXML, ctx);
|
||||
var link = document.createElement("A");
|
||||
link.href = url + base64(workbookXML);
|
||||
link.download = this.oldData.name + "--构件属性.xls"
|
||||
link.target = '_blank';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
exportState(e) {
|
||||
let checkbox = e.target.getElementsByTagName('input')[0]
|
||||
checkbox.checked = !checkbox.checked
|
||||
if (checkbox.checked) {
|
||||
this.exportStateArray.push(checkbox.value)
|
||||
this.exportStateArray = Array.from(new Set(this.exportStateArray))
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < this.exportStateArray.length; i++) {
|
||||
if (this.exportStateArray[i] == checkbox.value) {
|
||||
this.exportStateArray.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default BIM
|
||||
54
src/Obj/Base/BaseSource/BaseTileset/Tileset/_element.js
Normal file
54
src/Obj/Base/BaseSource/BaseTileset/Tileset/_element.js
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" @model="name">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-3">
|
||||
<input class="input" type="number" title="" @model="height">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">精度</span>
|
||||
<div class="input-number input-number-unit-3">
|
||||
<input class="input" type="number" title="" min="0.1" max="10" step="0.1" @model="accuracy">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">透视</span>
|
||||
<input type="range" min="0" max="1" step="0.01" @model="transparency">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
function css() {
|
||||
return `
|
||||
.YJ-custom-base-dialog>.content {
|
||||
width: 420px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .row .label {
|
||||
flex: 0 0 45px;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export { html, css }
|
||||
87
src/Obj/Base/BaseSource/BaseTileset/Tileset/eventBinding.js
Normal file
87
src/Obj/Base/BaseSource/BaseTileset/Tileset/eventBinding.js
Normal file
@ -0,0 +1,87 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue;
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
this.element[m.value] = elements[i]
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
373
src/Obj/Base/BaseSource/BaseTileset/Tileset/index.js
Normal file
373
src/Obj/Base/BaseSource/BaseTileset/Tileset/index.js
Normal file
@ -0,0 +1,373 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 16:05
|
||||
* @description:index
|
||||
* @update: 2023-11-20 16:05
|
||||
*/
|
||||
import BaseTileset from "../index";
|
||||
import cy_slider from "../../../../Element/cy_html_slider";
|
||||
import { html, css } from "./_element";
|
||||
import EventBinding from '../../../../Element/Dialog/eventBinding';
|
||||
import { syncSplitData } from '../../../../../Global/SplitScreen'
|
||||
import Dialog from '../../../../Element/Dialog';
|
||||
|
||||
class Tileset extends BaseTileset {
|
||||
#updateModelTimeout;
|
||||
/**
|
||||
* @constructor
|
||||
* @description 加载Tileset模型
|
||||
* @param sdk {object} sdk
|
||||
* @param options {object} 模型参数
|
||||
* @param options.id {string} 对象id
|
||||
* @param options.show=true {boolean} 模型显隐
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 资源地址
|
||||
* @param options.accuracy=1 {number} 精度(倍)
|
||||
* @param options.position {object} 模型位置
|
||||
* @param options.position.lng {number} 经度
|
||||
* @param options.position.lat {number} 纬度
|
||||
* @param options.position.alt {number} 高度
|
||||
* */
|
||||
constructor(earth, options = {}, _Dialog = {}) {
|
||||
super(earth, options)
|
||||
this.picking = false
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this._EventBinding = new EventBinding()
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "tileset"
|
||||
}
|
||||
|
||||
on() {
|
||||
return this.add()
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.newData.name
|
||||
}
|
||||
|
||||
set name(v) {
|
||||
this.newData.name = v
|
||||
this._elms.name && this._elms.name.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.newData.height
|
||||
}
|
||||
|
||||
set height(v) {
|
||||
this.newData.height = v
|
||||
this.options.position.alt = v
|
||||
this._elms.height && this._elms.height.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
|
||||
}
|
||||
|
||||
get accuracy() {
|
||||
return this.newData.accuracy
|
||||
}
|
||||
|
||||
set accuracy(v) {
|
||||
this.newData.accuracy = Number(v.toFixed(1))
|
||||
if(this.newData.accuracy<0.1) {
|
||||
this.newData.accuracy = 0.1
|
||||
}
|
||||
if(this.entity) {
|
||||
this.entity.maximumScreenSpaceError = 32/this.newData.accuracy
|
||||
}
|
||||
this._elms.accuracy && this._elms.accuracy.forEach((item) => {
|
||||
item.value = this.newData.accuracy
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.newData.lng
|
||||
}
|
||||
set lng(v) {
|
||||
this.newData.lng = v
|
||||
this.options.position.lng = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.newData.lat
|
||||
}
|
||||
set lat(v) {
|
||||
this.newData.lat = v
|
||||
this.options.position.lat = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch)
|
||||
}
|
||||
|
||||
get roll() {
|
||||
return this.newData.roll
|
||||
}
|
||||
|
||||
set roll(v) {
|
||||
this.newData.roll = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
}
|
||||
|
||||
get heading() {
|
||||
return this.newData.heading
|
||||
}
|
||||
|
||||
set heading(v) {
|
||||
this.newData.heading = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
}
|
||||
|
||||
get pitch() {
|
||||
return this.newData.pitch
|
||||
}
|
||||
|
||||
set pitch(v) {
|
||||
this.newData.pitch = v
|
||||
this.updateModel(this.newData.lng, this.newData.lat, this.newData.height, this.newData.roll, this.newData.heading, this.newData.pitch, this.newData.scale)
|
||||
}
|
||||
|
||||
get transparency() {
|
||||
return this.newData.transparency
|
||||
}
|
||||
|
||||
set transparency(v) {
|
||||
if (!this.newData) {
|
||||
return
|
||||
}
|
||||
this.newData.transparency = Number(v)
|
||||
this._elms.transparency && this._elms.transparency.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
let transparency = this.newData.transparency
|
||||
// if (transparency == 1) {
|
||||
// transparency = 0.99
|
||||
// }
|
||||
this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
color: {
|
||||
"conditions": [
|
||||
//有size属性表示为点云,需要与点颜色融合
|
||||
["Boolean(${SIZE})", "${COLOR} * color('rgba(255,255,255)', " + transparency + ")"],
|
||||
["true", "color('rgba(255,255,255," + transparency + ")')"]
|
||||
]
|
||||
},
|
||||
show: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this._element_style = null
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
|
||||
if (state) {
|
||||
this._element_style = document.createElement('style');
|
||||
this._element_style.type = 'text/css';
|
||||
this._element_style.setAttribute('data-name', 'YJ_style_dialog');
|
||||
this._element_style.innerHTML = css();
|
||||
|
||||
this._DialogObject = await new Dialog(this.sdk, this.newData, {
|
||||
title: '倾斜模型属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.oldData.name = this.newData.name
|
||||
this.oldData.height = this.newData.height
|
||||
this.oldData.lng = this.newData.lng
|
||||
this.oldData.lat = this.newData.lat
|
||||
this.oldData.transparency = this.newData.transparency
|
||||
this.oldData.scale = this.newData.scale
|
||||
this.oldData.roll = this.newData.roll
|
||||
this.oldData.heading = this.newData.heading
|
||||
this.oldData.pitch = this.newData.pitch
|
||||
this.oldData.type = this.type
|
||||
this.oldData.accuracy = this.newData.accuracy
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack({ ...this.oldData, type: this.type })
|
||||
syncSplitData(this.sdk, this.oldData.id)
|
||||
},
|
||||
resetCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
},
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
if (this.positionEditing) {
|
||||
this.positionEditing = false
|
||||
}
|
||||
if (this.rotationEditing) {
|
||||
this.rotationEditing = false
|
||||
}
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.newData.show = show
|
||||
this.entity && (this.entity.show = show)
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
rotateCallBack: () => {
|
||||
if (this.rotationEditing) {
|
||||
this.rotationEditing = false
|
||||
}
|
||||
else {
|
||||
this.rotationEditing = true
|
||||
}
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
if (this.positionEditing) {
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
this.positionEditing = true
|
||||
}
|
||||
}
|
||||
}, true)
|
||||
document.getElementsByTagName('head')[0].appendChild(this._element_style);
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
//更新模型位置
|
||||
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
|
||||
});
|
||||
}
|
||||
console.warn('该模型不支持移动和旋转!')
|
||||
return
|
||||
}
|
||||
if ((!_tx && _tx!==0) || (!_ty && _ty!==0) || (!_tz && _tz!==0)) {
|
||||
return
|
||||
}
|
||||
let mx = Cesium.Matrix3.fromRotationX(
|
||||
Cesium.Math.toRadians(_rx)
|
||||
)
|
||||
let my = Cesium.Matrix3.fromRotationY(
|
||||
Cesium.Math.toRadians(_ry)
|
||||
)
|
||||
let mz = Cesium.Matrix3.fromRotationZ(
|
||||
Cesium.Math.toRadians(_rz)
|
||||
)
|
||||
// 平移
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz))
|
||||
// 旋转
|
||||
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||
let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz)
|
||||
let originalMatrix = new Cesium.Matrix4()
|
||||
Cesium.Matrix4.multiply(m, rotationX, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix)
|
||||
Cesium.Matrix4.multiply(originalMatrix, rotationZ, originalMatrix)
|
||||
const scale = Cesium.Matrix4.fromUniformScale(s);
|
||||
Cesium.Matrix4.multiply(originalMatrix, scale, this.entity._root.transform)
|
||||
// console.log(_tx, _ty, _tz)
|
||||
if (!this.editObj.activeAxis) {
|
||||
this.editObj.position = { lng: _tx, lat: _ty, alt: _tz }
|
||||
}
|
||||
if (!this.editObj.activeCircle) {
|
||||
this.editObj.rotate = { x: _rx, y: _ry, z: _rz }
|
||||
}
|
||||
this.editObj && this.editObj.update()
|
||||
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.#updateModelTimeout = setTimeout(() => {
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
let center = this.cartesian3Towgs84(this.entity.boundingSphere.center, this.sdk.viewer)
|
||||
let circle = turf.circle([center.lng, center.lat], this.entity.boundingSphere.radius / 1000, { steps: 360, units: 'kilometers' });
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && entity.heightMode == 3) {
|
||||
let pt = turf.point([entity.lng, entity.lat]);
|
||||
if (turf.booleanPointInPolygon(pt, circle)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// flyTo() {
|
||||
// this.entity.readyPromise.then(() => {
|
||||
// console.log(this.entity)
|
||||
// let boundingSphere
|
||||
// if(!this.lng || !this.lat) {
|
||||
// boundingSphere = new Cesium.BoundingSphere(this.entity.boundingSphere)
|
||||
// }
|
||||
// else {
|
||||
// boundingSphere = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(this.lng, this.lat, this.height), this.entity.boundingSphere.radius)
|
||||
// }
|
||||
// this.sdk.viewer.camera.flyToBoundingSphere(boundingSphere)
|
||||
// })
|
||||
// }
|
||||
|
||||
reset() {
|
||||
this.editObj.destroy()
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.transparency = this.oldData.transparency
|
||||
this.name = this.oldData.name
|
||||
this.height = this.oldData.height
|
||||
this.lng = this.oldData.lng
|
||||
this.lat = this.oldData.lat
|
||||
this.roll = this.oldData.roll
|
||||
this.heading = this.oldData.heading
|
||||
this.pitch = this.oldData.pitch
|
||||
this.scale = this.oldData.scale
|
||||
this.accuracy = this.oldData.accuracy
|
||||
|
||||
this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
color: {
|
||||
"conditions": [
|
||||
["Boolean(${SIZE})", "${COLOR} * color('rgba(255,255,255)', " + this.transparency + ")"],
|
||||
["true", "color('rgba(255,255,255," + this.transparency + ")')"]
|
||||
]
|
||||
},
|
||||
show: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Tileset
|
||||
650
src/Obj/Base/BaseSource/BaseTileset/index.js
Normal file
650
src/Obj/Base/BaseSource/BaseTileset/index.js
Normal file
@ -0,0 +1,650 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 17:54
|
||||
* @description:index
|
||||
* @update: 2023-11-20 17:54
|
||||
*/
|
||||
import { getHost } from "../../../../on";
|
||||
import BaseSource from "../index";
|
||||
import { regLeftClickCallback, regRightClickCallback, regMoveCallback } from "../../../../Global/ClickCallback";
|
||||
import Controller from "../../../../Controller/index";
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
|
||||
class BaseTileset extends BaseSource {
|
||||
#updateModelTimeout;
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 模型
|
||||
* @param options {object}
|
||||
* @param options.id{string} id
|
||||
* @param options.name{string} 名称
|
||||
* @param options.url{string} 模型地址
|
||||
* @param options.lng{number} 经度
|
||||
* @param options.lat{number} 纬度
|
||||
* @param options.height=0{number} 高度
|
||||
* @param options.scale=1{number} 模型比例
|
||||
* @param options.roll=0{number} 模型x旋转
|
||||
* @param options.heading=0{number} 模型z轴旋转角度
|
||||
* @param options.pitch=0{number} 模型y轴旋转角度
|
||||
* */
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options);
|
||||
this.setDefaultValue()
|
||||
this.watchs = []
|
||||
this.positionCallBack = null
|
||||
this.rotationCallback = null
|
||||
this.onClickCallback = null
|
||||
this._DialogObject = null
|
||||
this._element_style = null
|
||||
this.options.accuracy = options.accuracy ? Number(options.accuracy.toFixed(1)) : 1
|
||||
this.options.position = this.options.position || {}
|
||||
this.oldData = {
|
||||
id: this.options.id,
|
||||
transparency: (this.options.transparency || this.options.transparency === 0) ? this.options.transparency : 1,
|
||||
name: this.options.name,
|
||||
accuracy: this.options.accuracy,
|
||||
url: this.options.url,
|
||||
height: this.options.position.alt || 0,
|
||||
lng: this.options.position.lng,
|
||||
lat: this.options.position.lat,
|
||||
scale: (this.options.scale || this.options.scale === 0) ? this.options.scale : 1,
|
||||
roll: this.options.roll || 0,
|
||||
heading: this.options.heading || 0,
|
||||
pitch: this.options.pitch || 0
|
||||
}
|
||||
this.newData = {
|
||||
id: this.options.id,
|
||||
transparency: (this.options.transparency || this.options.transparency === 0) ? this.options.transparency : 1,
|
||||
name: this.options.name,
|
||||
accuracy: this.options.accuracy,
|
||||
url: this.options.url,
|
||||
height: this.options.position.alt || 0,
|
||||
lng: this.options.position.lng,
|
||||
lat: this.options.position.lat,
|
||||
scale: (this.options.scale || this.options.scale === 0) ? this.options.scale : 1,
|
||||
roll: this.options.roll || 0,
|
||||
heading: this.options.heading || 0,
|
||||
pitch: this.options.pitch || 0
|
||||
}
|
||||
this.tileset = undefined
|
||||
this.editObj = new Controller(this.sdk)
|
||||
this.editObj.controllerCallBack = this.rotationEditingCallBack
|
||||
}
|
||||
|
||||
async add() {
|
||||
if (this.options.url) {
|
||||
return this.loadTileset({
|
||||
url: this.options.url
|
||||
})
|
||||
} else {
|
||||
let res = await this.requestResource()
|
||||
let text = await res.text()
|
||||
text = JSON.parse(text)
|
||||
if ([0, 200].includes(text.code)) {
|
||||
if (text.data.url.length)
|
||||
return this.loadTileset(text.data)
|
||||
else
|
||||
return new Promise((res, reject) => {
|
||||
reject('资源不存在')
|
||||
})
|
||||
} else {
|
||||
return new Promise((res, reject) => {
|
||||
reject(text.msg || text.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadSceneTree() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
async loadTileset(options) {
|
||||
let object = { ...options }
|
||||
let url = ""
|
||||
if (object.url.startsWith("http"))
|
||||
url = object.url
|
||||
else {
|
||||
//说明是本地的json,在磁盘中存在的
|
||||
if (object.url.includes(":")) {
|
||||
url = object.url
|
||||
} else {
|
||||
if (this.options.host) {
|
||||
let o = new URL(object.url, this.options.host)
|
||||
url = o.href
|
||||
} else
|
||||
url = object.url
|
||||
}
|
||||
}
|
||||
|
||||
let response = await fetch(url, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
if (response.status === 200) {
|
||||
this.tileset = await response.json()
|
||||
}
|
||||
let params = {
|
||||
show: this.options.show,
|
||||
skipLevelOfDetail: true,
|
||||
baseScreenSpaceError: 1024,
|
||||
maximumScreenSpaceError: 32, // 数值加大,能让最终成像变模糊
|
||||
skipScreenSpaceErrorFactor: 16,
|
||||
skipLevels: 1,
|
||||
immediatelyLoadDesiredLevelOfDetail: false,
|
||||
loadSiblings: true, // 如果为true则不会在已加载完概况房屋后,自动从中心开始超清化房屋
|
||||
cullWithChildrenBounds: true,
|
||||
cullRequestsWhileMoving: true,
|
||||
cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
|
||||
preloadWhenHidden: false,
|
||||
preferLeaves: true,
|
||||
maximumCacheOverflowBytes: 128, // 内存分配变小有利于倾斜摄影数据回收,提升性能体验
|
||||
progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
|
||||
dynamicScreenSpaceErrorDensity: 0.1, // 数值加大,能让周边加载变快
|
||||
dynamicScreenSpaceErrorFactor: 1,
|
||||
dynamicScreenSpaceError: true // 有了这个后,会在真正的全屏加载完之后才清晰化房屋
|
||||
}
|
||||
let tileset
|
||||
if (Number(Cesium.VERSION.split('.')[1]) >= 107) {
|
||||
tileset = await Cesium.Cesium3DTileset.fromUrl(url, params);
|
||||
this.entity = tileset
|
||||
this.entity.imageBasedLighting.luminanceAtZenith = 0.1
|
||||
}
|
||||
else {
|
||||
params.url = url
|
||||
tileset = new Cesium.Cesium3DTileset(params);
|
||||
this.entity = await tileset.readyPromise
|
||||
this.entity.imageBasedLighting.luminanceAtZenith = 0.1
|
||||
}
|
||||
|
||||
// syncData(this.sdk, this.options.id)
|
||||
|
||||
|
||||
await this.loadSceneTree(url)
|
||||
const initData = (tile) => {
|
||||
if (tile._contents) {
|
||||
for (let i = 0; i < tile._contents.length; i++) {
|
||||
initData(tile._contents[i])
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < tile.featuresLength; i++) {
|
||||
let feature = tile.getFeature(i)
|
||||
let file = feature.content.url
|
||||
let id = feature.getProperty('id')
|
||||
if (this.features.has(id)) {
|
||||
if (this.features.get(id).features) {
|
||||
if (this.features.get(id).features[file]) {
|
||||
// feature = this.features.get(id).features[feature.featureId]
|
||||
if (this.features.get(id).features[file].customColor) {
|
||||
feature.color = this.features.get(id).features[file].customColor
|
||||
feature.customColor = this.features.get(id).features[file].customColor
|
||||
}
|
||||
if (this.features.get(id).features[file].customAlpha) {
|
||||
let color = feature.color
|
||||
feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).features[file].customAlpha})`)
|
||||
feature.customAlpha = this.features.get(id).features[file].customAlpha
|
||||
}
|
||||
if (this.features.get(id).features[file].customShow) {
|
||||
feature.show = this.features.get(id).features[file].customShow
|
||||
feature.customShow = this.features.get(id).features[file].customShow
|
||||
}
|
||||
}
|
||||
this.features.get(id).features[file] = feature
|
||||
}
|
||||
else {
|
||||
let object = {}
|
||||
if (this.features.get(id).customColor) {
|
||||
feature.color = this.features.get(id).customColor
|
||||
feature.customColor = this.features.get(id).customColor
|
||||
}
|
||||
if (this.features.get(id).customAlpha) {
|
||||
let color = feature.color
|
||||
feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).customAlpha})`)
|
||||
feature.customAlpha = this.features.get(id).customAlpha
|
||||
}
|
||||
if (this.features.get(id).customShow) {
|
||||
feature.show = this.features.get(id).customShow
|
||||
feature.customShow = this.features.get(id).customShow
|
||||
}
|
||||
object[file] = feature
|
||||
this.features.get(id).features = object
|
||||
}
|
||||
}
|
||||
else {
|
||||
let object = {}
|
||||
object[file] = feature
|
||||
this.features.set(id, { features: object })
|
||||
}
|
||||
if (!feature.customColor) {
|
||||
feature.customColor = Cesium.Color.fromCssColorString('#ffffff')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for (let i = 0; i < tile._content.featuresLength; i++) {
|
||||
// let feature = tile._content.getFeature(i)
|
||||
// feature.show = false
|
||||
// }
|
||||
// if (tile._content._contents) {
|
||||
// for (let i = 0; i < tile._content._contents.length; i++) {
|
||||
// for (let m = 0; m < tile._content._contents[i].featuresLength; m++) {
|
||||
// let feature = tile._content._contents[i].getFeature(m)
|
||||
// feature.show = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (!this.sdk || !this.sdk.viewer || !this.sdk.viewer.scene) {
|
||||
return
|
||||
}
|
||||
tileset.tileLoad.addEventListener(tile => {
|
||||
// this.test()
|
||||
initData(tile._content)
|
||||
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
this.#updateModelTimeout = setTimeout(() => {
|
||||
clearTimeout(this.#updateModelTimeout)
|
||||
let center = this.cartesian3Towgs84(tileset.boundingSphere.center, this.sdk.viewer)
|
||||
let circle = turf.circle([center.lng, center.lat], tileset.boundingSphere.radius / 1000, { steps: 360, units: 'kilometers' });
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && entity.heightMode == 3) {
|
||||
let pt = turf.point([entity.lng, entity.lat]);
|
||||
if (turf.booleanPointInPolygon(pt, circle)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
|
||||
// if (tile._content._contents) {
|
||||
// for (let i = 0; i < tile._content._contents.length; i++) {
|
||||
// for (let m = 0; m < tile._content._contents[i].featuresLength; m++) {
|
||||
// let feature = tile._content._contents[i].getFeature(m)
|
||||
// console.log(feature)
|
||||
// feature.show = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// for (let i = 0; i < tile._content.featuresLength; i++) {
|
||||
// let feature = tile._content.getFeature(i)
|
||||
// let file = feature.content.url
|
||||
// let id = feature.getProperty('id')
|
||||
// if (this.features.has(id)) {
|
||||
// if (this.features.get(id).features) {
|
||||
// if (this.features.get(id).features[file]) {
|
||||
// // feature = this.features.get(id).features[feature.featureId]
|
||||
// if (this.features.get(id).features[file].customColor) {
|
||||
// feature.color = this.features.get(id).features[file].customColor
|
||||
// feature.customColor = this.features.get(id).features[file].customColor
|
||||
// }
|
||||
// if (this.features.get(id).features[file].customAlpha) {
|
||||
// let color = feature.color
|
||||
// feature.color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${this.features.get(id).features[file].customAlpha})`)
|
||||
// feature.customAlpha = this.features.get(id).features[file].customAlpha
|
||||
// }
|
||||
// if (this.features.get(id).features[file].customShow) {
|
||||
// feature.show = this.features.get(id).features[file].customShow
|
||||
// feature.customShow = this.features.get(id).features[file].customShow
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// this.features.get(id).features[file] = feature
|
||||
// }
|
||||
// else {
|
||||
// let object = {}
|
||||
// object[file] = feature
|
||||
// this.features.get(id).features = object
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// let object = {}
|
||||
// object[file] = feature
|
||||
// this.features.set(id, { features: object })
|
||||
// }
|
||||
// if (!feature.customColor) {
|
||||
// feature.customColor = Cesium.Color.fromCssColorString('#ffffff')
|
||||
// }
|
||||
// }
|
||||
})
|
||||
// // console.log(tileset)
|
||||
// if (this.type === 'bim') {
|
||||
// const setTilesetStyle = (f) => {
|
||||
// if (tileset.style) {
|
||||
// // tileset.style = new Cesium.Cesium3DTileStyle({
|
||||
// // color: {
|
||||
// // conditions: [
|
||||
// // ['${name} ==="对象074" ', 'color("red")'], //符合条件项
|
||||
// // ['true', 'rgba(255,255,255,1)'] //其他项
|
||||
// // ]
|
||||
// // }
|
||||
// // })
|
||||
// // tileset.tileLoad.removeEventListener(setTilesetStyle)
|
||||
// }
|
||||
// console.log(f)
|
||||
// }
|
||||
// tileset.tileLoad.addEventListener(setTilesetStyle)
|
||||
// }
|
||||
|
||||
this.entity._root.originalTransform = { ...this.entity._root.transform }
|
||||
this.entity.id = this.options.id || this.randomString()
|
||||
this.entity.type = this.type
|
||||
// this.editObj = new EditB3DM(this.sdk, this.entity)
|
||||
|
||||
this.sdk.viewer.scene.primitives.add(tileset);
|
||||
if (this.options.position && JSON.stringify(this.options.position) != "{}"
|
||||
&& (this.options.position.lng || this.options.position.lng === 0) && (this.options.position.lat || this.options.position.lat === 0)) {
|
||||
this.options.position.alt == this.options.position.alt || 0
|
||||
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
|
||||
if (this.tileset.root.transform) {
|
||||
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
|
||||
}
|
||||
this.entity.original = {
|
||||
lng: Cesium.Math.toDegrees(cartographic.longitude), // 经度
|
||||
lat: Cesium.Math.toDegrees(cartographic.latitude), // 纬度
|
||||
height: cartographic.height
|
||||
}
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt))
|
||||
const scale = Cesium.Matrix4.fromUniformScale(this.oldData.scale);
|
||||
if (this.tileset.root.transform) {
|
||||
Cesium.Matrix4.multiply(m, scale, this.entity._root.transform)
|
||||
}
|
||||
this.lng = this.oldData.lng
|
||||
this.lat = this.oldData.lat
|
||||
this.height = this.oldData.height
|
||||
}
|
||||
else {
|
||||
this.options.position = {}
|
||||
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
|
||||
if (this.tileset.root.transform) {
|
||||
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
|
||||
}
|
||||
this.entity.original = {
|
||||
lng: Cesium.Math.toDegrees(cartographic.longitude),
|
||||
lat: this.oldData.lat = Cesium.Math.toDegrees(cartographic.latitude),
|
||||
height: cartographic.height,
|
||||
}
|
||||
this.lng = this.oldData.lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
|
||||
this.lat = this.oldData.lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
|
||||
this.height = this.oldData.height = cartographic.height; // 高度
|
||||
|
||||
}
|
||||
|
||||
this.scale = this.oldData.scale
|
||||
this.roll = this.oldData.roll
|
||||
this.heading = this.oldData.heading
|
||||
this.pitch = this.oldData.pitch
|
||||
this.transparency = this.oldData.transparency
|
||||
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
|
||||
regMoveCallback(this.entity.id, this.mouseMoveCB, this)
|
||||
|
||||
|
||||
// this.entity = this.sdk.viewer.scene.primitives.add(tileset);
|
||||
// if (this.options.position && JSON.stringify(this.options.position) != "{}") {
|
||||
// let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt))
|
||||
// const scale = Cesium.Matrix4.fromUniformScale(this.oldData.scale);
|
||||
// Cesium.Matrix4.multiply(m, scale, this.entity._root.transform)
|
||||
// }
|
||||
// else {
|
||||
// this.options.position = {}
|
||||
// }
|
||||
// this.lng = this.oldData.lng
|
||||
// this.lat = this.oldData.lat
|
||||
// this.height = this.oldData.height
|
||||
// this.scale = this.oldData.scale
|
||||
// this.roll = this.oldData.roll
|
||||
// this.heading = this.oldData.heading
|
||||
// this.pitch = this.oldData.pitch
|
||||
// this.transparency = this.oldData.transparency
|
||||
|
||||
// regMoveCallback(this.entity.id, this.mouseMoveCB, this)
|
||||
|
||||
// this.editObj = new EditB3DM(this.sdk, this.entity)
|
||||
// this.editObj.transformCallBack = this.rotationEditingCallBack
|
||||
// tileset.readyPromise.then(() => {
|
||||
// this.entity = this.sdk.viewer.scene.primitives.add(tileset);
|
||||
|
||||
// })
|
||||
// let x = this.sdk.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
|
||||
// url: url
|
||||
// }));
|
||||
// setTimeout(() => {
|
||||
// console.log(x)
|
||||
// this.sdk.viewer.flyTo(this.entity)
|
||||
// }, 3000);
|
||||
}
|
||||
|
||||
// test() {
|
||||
// let heightstyle = new Cesium.Cesium3DTileStyle({
|
||||
// color: {
|
||||
// conditions: [
|
||||
// ["Number(${height})>=300", "rgba(45,0,75,0.5)"],
|
||||
// ["Number(${height})>=200", "rgb(102,71,151)"],
|
||||
// ["Number(${height})>=100", "rgb(170,162,204)"],
|
||||
// ["Number(${height})>=50", "rgb(224,226,238)"],
|
||||
// ["Number(${height})>=25", "rgb(252,230, 200)"],
|
||||
// ["Number(${height})>=10", "rgb(248,176,87)"],
|
||||
// ["Number(${height})>=5", "rgb(198, 106,11)"],
|
||||
// ["isNaN(Number(${height}))", "rgb(255, 255, 255)"],
|
||||
// ["true", "rgb(127,59,8)"]
|
||||
// ]
|
||||
// }
|
||||
// });
|
||||
// this.entity.style = heightstyle;
|
||||
// }
|
||||
|
||||
|
||||
remove() {
|
||||
super.remove()
|
||||
this.editObj.destroy()
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity);
|
||||
this.entity = null
|
||||
if (this._DialogObject) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
|
||||
flyTo() {
|
||||
super.flyTo()
|
||||
}
|
||||
|
||||
|
||||
on() {
|
||||
return this.add()
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue()
|
||||
this.options.host = this.options.host || getHost()
|
||||
this.options.url = this.options.url || ""
|
||||
}
|
||||
|
||||
get position() {
|
||||
let cartographic = Cesium.Cartographic.fromCartesian(this.entity.boundingSphere.center);
|
||||
if (this.tileset.root.transform) {
|
||||
cartographic = Cesium.Cartographic.fromCartesian({ x: this.tileset.root.transform[12], y: this.tileset.root.transform[13], z: this.tileset.root.transform[14] })
|
||||
}
|
||||
let lng = Cesium.Math.toDegrees(cartographic.longitude + 0.00000000663814);
|
||||
let lat = Cesium.Math.toDegrees(cartographic.latitude + 0.00000025137835);
|
||||
if (this.newData.lng && this.newData.lat && this.newData.height) {
|
||||
return { lng: this.newData.lng, lat: this.newData.lat, height: this.newData.height }
|
||||
}
|
||||
else {
|
||||
return { lng: lng, lat: lat, height: cartographic.height - 2.19104611043234 }
|
||||
}
|
||||
}
|
||||
|
||||
set position(p) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 打开模型旋转功能
|
||||
* @param status {boolean}
|
||||
* @methodOf Source
|
||||
* */
|
||||
set rotationEditing(status) {
|
||||
if (!this.tileset.root.transform) {
|
||||
if (window.ELEMENT) {
|
||||
window.ELEMENT.Message.closeAll();
|
||||
window.ELEMENT.Message({
|
||||
message: '该模型不支持移动和旋转!',
|
||||
type: 'warning',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
console.warn('该模型不支持移动和旋转!')
|
||||
return
|
||||
}
|
||||
if (status) {
|
||||
this.editObj.position = { lng: this.newData.lng, lat: this.newData.lat, alt: this.newData.height }
|
||||
this.editObj.update()
|
||||
this.editObj.editRtation()
|
||||
}
|
||||
else {
|
||||
this.editObj.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 获取模型旋转状态
|
||||
* @method rotationEditing
|
||||
* @return boolean
|
||||
* @methodOf Source
|
||||
|
||||
* */
|
||||
get rotationEditing() {
|
||||
if (this.editObj.getActiveState() === 'rtation') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**@desc 打开平移模型功能
|
||||
*
|
||||
* @memberOf Source
|
||||
*@param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
if (!this.tileset.root.transform) {
|
||||
if (window.ELEMENT) {
|
||||
window.ELEMENT.Message.closeAll();
|
||||
window.ELEMENT.Message({
|
||||
message: '该模型不支持移动和旋转!',
|
||||
type: 'warning',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
console.warn('该模型不支持移动和旋转!')
|
||||
return
|
||||
}
|
||||
if (status) {
|
||||
this.editObj.position = { lng: this.newData.lng, lat: this.newData.lat, alt: this.newData.height }
|
||||
this.editObj.update()
|
||||
this.editObj.editTranslational()
|
||||
}
|
||||
else {
|
||||
this.editObj.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
if (this.editObj.getActiveState() === 'translational') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//平移时,坐标信息变化的回调
|
||||
set positionEditingCallBack(callback) {
|
||||
return
|
||||
}
|
||||
|
||||
get positionEditingCallBack() {
|
||||
}
|
||||
|
||||
//旋转时,坐标信息变化的回调
|
||||
set rotationEditingCallBack(callback) {
|
||||
this._rotationEditingCallBack = callback
|
||||
}
|
||||
|
||||
get rotationEditingCallBack() {
|
||||
return (params, state) => {
|
||||
this.lng = params.position.lng
|
||||
this.lat = params.position.lat
|
||||
this.height = params.position.alt
|
||||
this.roll = params.rotate.x
|
||||
this.heading = params.rotate.y
|
||||
this.pitch = params.rotate.z
|
||||
// this._rotationEditingCallBack && this._rotationEditingCallBack(this.editObj._params)
|
||||
}
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
|
||||
// 编辑框
|
||||
async edit(state) { }
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.show = v
|
||||
this.entity && (this.entity.show = v)
|
||||
if (this._DialogObject && this._DialogObject.showBtn) {
|
||||
this._DialogObject.showBtn.checked = v
|
||||
}
|
||||
if (this.options.label && this.options.label.show && this.label) {
|
||||
this.label.show = v
|
||||
}
|
||||
setTimeout(() => {
|
||||
let center = this.cartesian3Towgs84(this.entity.boundingSphere.center, this.sdk.viewer)
|
||||
let circle = turf.circle([center.lng, center.lat], this.entity.boundingSphere.radius / 1000, { steps: 360, units: 'kilometers' });
|
||||
for (let [key, entity] of this.sdk.entityMap) {
|
||||
if (entity.type === 'BillboardObject' && entity.heightMode == 3) {
|
||||
let pt = turf.point([entity.lng, entity.lat]);
|
||||
if (turf.booleanPointInPolygon(pt, circle)) {
|
||||
entity.updateHeight()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (entity.label) {
|
||||
entity.label.show = entity.label.show
|
||||
}
|
||||
}
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
}, 300);
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseTileset
|
||||
45
src/Obj/Base/BaseSource/index.js
Normal file
45
src/Obj/Base/BaseSource/index.js
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-11-20 18:31
|
||||
* @description:index
|
||||
* @update: 2023-11-20 18:31
|
||||
*/
|
||||
import Base from "../index";
|
||||
import {getHost, getToken} from "../../../on";
|
||||
import { setSplitDirection } from "../../../Global/SplitScreen";
|
||||
|
||||
class BaseSource extends Base {
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options);
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
if (this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue();
|
||||
this.options.host = this.options.host || getHost()
|
||||
}
|
||||
|
||||
requestResource() {
|
||||
let url = ""
|
||||
if (this.options.host.endsWith("yjearth4.0"))
|
||||
url = this.options.host + '/data/service/load-compact-service'
|
||||
else
|
||||
url = this.options.host + '/yjearth4.0/data/service/load-compact-service'
|
||||
return fetch(url, {
|
||||
method: 'post',
|
||||
body: JSON.stringify({source_id: this.options.id}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"token": getToken(),
|
||||
"Authorization": "Bearer " + getToken(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BaseSource
|
||||
24
src/Obj/Base/BatchModel/_element.js
Normal file
24
src/Obj/Base/BatchModel/_element.js
Normal file
@ -0,0 +1,24 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col add-type-box">
|
||||
<span class="label" style="flex: 0 0 56px;">添加方式</span>
|
||||
<div class="add-type"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">间距</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999" @model="spacing">
|
||||
<span class="unit">米</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
229
src/Obj/Base/BatchModel/_element_拓展.js
Normal file
229
src/Obj/Base/BatchModel/_element_拓展.js
Normal file
@ -0,0 +1,229 @@
|
||||
import { attributeElm } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div style="width: 46%;">
|
||||
<div class="row add-type-box">
|
||||
<div class="lable-left-line">添加方式
|
||||
<div class="input input-select add-type" style="margin-left: 20px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 50%;">
|
||||
<div class="row" style="margin-bottom: 5px;">
|
||||
<div class="col">
|
||||
<span class="label">朝向偏移</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="deviation">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4>模型间隔</h4>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">自定义距离</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">固定距离</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">模型间隔</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="spacing">
|
||||
<span class="unit">米</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4>线型选择</h4>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">折线</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">曲线</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">线条数量</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="lineNum">
|
||||
<span class="unit">条</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">线条间隔</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="lineSpacing">
|
||||
<span class="unit">米</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">随机采样</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">随机数量</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="lineNum">
|
||||
<span class="unit">个</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">网格采样</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">首边间隔</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="fistLineSpacing">
|
||||
<span class="unit">米</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">次边间隔</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="360" @model="secondLineSpacing">
|
||||
<span class="unit">米</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="point-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div style="width: 46%;">
|
||||
<div class="row add-type-box">
|
||||
<div class="lable-left-line">缩放
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">是否等比例缩放</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
<div>
|
||||
<div class="row" style="margin-bottom: 10px;">
|
||||
<div class="col">
|
||||
<span class="label">新增模型风格设置</span>
|
||||
<button @click="openRichTextEditor">初始风格</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button @click="openRichTextEditor">当前风格</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-bottom: 10px;">
|
||||
<div class="col" style="flex: 0 0 80px;">
|
||||
<span class="label" style="flex: none;">显隐</span>
|
||||
<input class="btn-switch" type="checkbox" @model="billboardShow">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 90px;">
|
||||
<span class="label" style="flex: none;">图标</span>
|
||||
<div class="image-box" @click="clickChangeImage">
|
||||
<img class="image" src="" alt="" @model="billboardImage">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 90px;">
|
||||
<span class="label" style="flex: none;">默认图标</span>
|
||||
<div class="image-box" @click="clickChangeDefaultImage">
|
||||
<img class="image" src="" alt="" @model="billboardDefaultImage">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">图标倍数</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="0.1" max="99" @model="billboardScale">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4>文字设置</h4>
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 0 0 80px;">
|
||||
<span class="label" style="flex: none;">显隐</span>
|
||||
<input class="btn-switch" type="checkbox" @model="labelShow">
|
||||
</div>
|
||||
<div class="col font-select-box">
|
||||
<span class="label" style="flex: none;">字体选择</span>
|
||||
<div class="input input-select font-select"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">文字大小</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="1" max="99" @model="labelFontSize" style="width: 70px;">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">文字颜色</span>
|
||||
<div class="labelColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
92
src/Obj/Base/BatchModel/eventBinding.js
Normal file
92
src/Obj/Base/BatchModel/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue;
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if (elements[i].nodeName == 'IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if (this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for (let n = 0; n < removeName.length; n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
713
src/Obj/Base/BatchModel/index.js
Normal file
713
src/Obj/Base/BatchModel/index.js
Normal file
@ -0,0 +1,713 @@
|
||||
/**
|
||||
* @description 批量模型
|
||||
*/
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import Base from "../index";
|
||||
import Tools from "../../../Tools";
|
||||
import { syncData } from '../../../Global/MultiViewportMode'
|
||||
import Model from '../BaseSource/BaseModel/Model'
|
||||
import { legp } from '../../Element/datalist'
|
||||
|
||||
import DrawPolyline from '../../../Draw/drawPolyline'
|
||||
import DrawPolygon from '../../../Draw/drawPolygon'
|
||||
import DrawThreeRect from '../../../Draw/drawThreeRect'
|
||||
import DrawPoint from '../../../Draw/drawPoint'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow, CesiumContainer } from '../../../Global/global'
|
||||
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen'
|
||||
|
||||
class BatchModel extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 批量模型
|
||||
* @param options {object} 批量模型属性
|
||||
* @param options.name=未命名对象 {string} 名称
|
||||
* @param options.type=polygon {string} 线类型(line,polygon)
|
||||
* @param options.url=polygon {string} 线类型(line,polygon,point)
|
||||
* @param options.spacing= {number} 间距
|
||||
* @param options.show=true {boolean}
|
||||
* @param Dialog {object} 弹框对象
|
||||
* @param Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, callback = null, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.viewer = this.sdk.viewer
|
||||
this.options.name = options.name || '批量模型'
|
||||
this.options.type = options.type || '面'
|
||||
this.options.url = options.url || ''
|
||||
this.options.spacing = options.spacing * 1 || 50
|
||||
this.options.positions = options.positions || []
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.callback = callback
|
||||
this.Dialog = _Dialog
|
||||
this._EventBinding = new EventBinding()
|
||||
this._elms = {};
|
||||
this.pointArr = []
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
let tools = new Tools(sdk)
|
||||
// BatchModel.computeDis(this)
|
||||
// if (this.options.positions.length > 0 || this.options.positions.lng) {
|
||||
if (this.options.spacing < 0 || options.spacing * 1 === 0) {
|
||||
tools.message({ type: 'warning', text: '请输入正确的间距!' })
|
||||
return;
|
||||
}
|
||||
if ((options.type && options.spacing != undefined) || options.type == '点') {
|
||||
// BatchModel.computeDis(this)
|
||||
|
||||
let Draw
|
||||
switch (options.type) {
|
||||
case '点':
|
||||
Draw = new DrawPoint(this.sdk)
|
||||
break;
|
||||
case '线':
|
||||
Draw = new DrawPolyline(this.sdk)
|
||||
break;
|
||||
case '面':
|
||||
Draw = new DrawThreeRect(this.sdk)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Draw && Draw.start((a, positions) => {
|
||||
this.options.positions = positions;
|
||||
//判断范围是否过大
|
||||
if (options.type == '面') {
|
||||
let posi = positions.map(v => {
|
||||
return Cesium.Cartesian3.fromDegrees(v.lng, v.lat)
|
||||
})
|
||||
let dis1 = Cesium.Cartesian3.distance(posi[0], posi[1])
|
||||
let dis2 = Cesium.Cartesian3.distance(posi[1], posi[2])
|
||||
let num1 = dis1 / this.options.spacing
|
||||
let num2 = dis2 / this.options.spacing
|
||||
if (num1 * num2 > 100) {
|
||||
tools.message({ type: 'warning', text: '数量大于100,请重新绘制' })
|
||||
return;
|
||||
}
|
||||
} else if (options.type == '线') {
|
||||
let posi = positions.map(v => {
|
||||
return Cesium.Cartesian3.fromDegrees(v.lng, v.lat)
|
||||
})
|
||||
let dis = 0
|
||||
for (let i = 0; i < posi.length - 2; i++) {
|
||||
dis += Cesium.Cartesian3.distance(posi[i], posi[i + 1])
|
||||
}
|
||||
if (dis / this.options.spacing > 100) {
|
||||
tools.message({ type: 'warning', text: '数量大于100,请重新绘制' })
|
||||
return;
|
||||
}
|
||||
}
|
||||
// this.callback(this.options);
|
||||
(this.options.positions.length || this.options.positions.lng) && BatchModel.computeDis(this)
|
||||
})
|
||||
|
||||
} else {
|
||||
this.edit(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算距离
|
||||
static async computeDis(that) {
|
||||
let fromDegreesArray = []
|
||||
let arr
|
||||
let posiArr = []
|
||||
let array = []
|
||||
if (that.options.type == '面') {
|
||||
that.options.positions.forEach(item => {
|
||||
fromDegreesArray.push(item.lng, item.lat)
|
||||
})
|
||||
// arr = that.generateInterpolatedPoints(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray), that.options.spacing)
|
||||
arr = await that.computedArea(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray), that.options.spacing)
|
||||
array[0] = arr
|
||||
array[1] = that.calculateRoadAngle(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)[0], Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)[3])
|
||||
arr.forEach((item, index) => {
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(
|
||||
item // Cartesian3对象 {x, y, z}
|
||||
);
|
||||
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
||||
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
||||
const height = cartographic.height;
|
||||
posiArr.push({
|
||||
lng: longitude,
|
||||
lat: latitude,
|
||||
alt: height
|
||||
})
|
||||
})
|
||||
} else if (that.options.type == '线') {
|
||||
that.options.positions.forEach(item => {
|
||||
fromDegreesArray.push(item.lng, item.lat)
|
||||
})
|
||||
array = await that.linePoint(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray), that.options.spacing)
|
||||
arr = array[0]
|
||||
that.pointArr = arr
|
||||
arr.forEach((item, index) => {
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(
|
||||
item // Cartesian3对象 {x, y, z}
|
||||
);
|
||||
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
||||
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
||||
const height = cartographic.height;
|
||||
posiArr.push({
|
||||
lng: longitude,
|
||||
lat: latitude,
|
||||
alt: height
|
||||
})
|
||||
})
|
||||
} 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]
|
||||
that.pointArr = posiArr
|
||||
}
|
||||
let params = {
|
||||
type: that.options.type,
|
||||
positions: posiArr,
|
||||
rotate: that.options.type == '点' ? undefined : array[1]
|
||||
}
|
||||
that.callback(params)
|
||||
// posiArr.forEach((item, index) => {
|
||||
// let model = new Model(that.sdk, {
|
||||
// id: 'model' + index,
|
||||
// show: that.options.show,
|
||||
// url: that.options.url,
|
||||
// position: item,
|
||||
// rotate: that.options.type == '点' ? undefined : { x: 0, y: 0, z: array[1] && (array[1][index] || array[1]) }
|
||||
// })
|
||||
// that.pointArr.push(model)
|
||||
// })
|
||||
}
|
||||
async linePoint(polygonPositions, spacing) {
|
||||
let boundaryPoints = [];
|
||||
let boundaryAngle = [];
|
||||
for (let i = 0; i < polygonPositions.length - 1; i++) {
|
||||
|
||||
const start = polygonPositions[i];
|
||||
const end = polygonPositions[(i + 1) % polygonPositions.length];
|
||||
const segmentLength = Cesium.Cartesian3.distance(start, end);
|
||||
const segments = Math.ceil(segmentLength / spacing);
|
||||
|
||||
for (let j = 0; j <= segments; j++) {
|
||||
const ratio = j / segments;
|
||||
let point = Cesium.Cartesian3.lerp(
|
||||
start, end, ratio, new Cesium.Cartesian3()
|
||||
);
|
||||
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(
|
||||
point // Cartesian3对象 {x, y, z}
|
||||
);
|
||||
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
||||
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
||||
|
||||
|
||||
let height = await this.getClampToHeight({ lng: longitude, lat: latitude })
|
||||
point = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
|
||||
|
||||
boundaryPoints.push(point);
|
||||
if (j != segments || i == polygonPositions.length - 2) {
|
||||
boundaryAngle.push(this.calculateRoadAngle(start, end))
|
||||
}
|
||||
}
|
||||
}
|
||||
return [[...new Set(boundaryPoints
|
||||
.map(p => `${p.x},${p.y},${p.z}`))]
|
||||
.map(str => {
|
||||
const [x, y, z] = str.split(',').map(Number);
|
||||
return new Cesium.Cartesian3(x, y, z);
|
||||
}), boundaryAngle];
|
||||
}
|
||||
calculateRoadAngle(startPoint, endPoint) {
|
||||
const normal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(startPoint);
|
||||
const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(startPoint, undefined, normal);
|
||||
const inverseMatrix = Cesium.Matrix4.inverse(enuMatrix, new Cesium.Matrix4());
|
||||
|
||||
const localEnd = Cesium.Matrix4.multiplyByPoint(inverseMatrix, endPoint, new Cesium.Cartesian3());
|
||||
const horizontalVec = new Cesium.Cartesian2(localEnd.x, localEnd.y);
|
||||
Cesium.Cartesian2.normalize(horizontalVec, horizontalVec);
|
||||
|
||||
const north = new Cesium.Cartesian2(1, 0);
|
||||
|
||||
let angle = Cesium.Cartesian2.angleBetween(north, horizontalVec);
|
||||
angle = Cesium.Math.toDegrees(angle)
|
||||
const cross = Cesium.Cartesian2.cross(north, horizontalVec, new Cesium.Cartesian2());
|
||||
// return cross < 0 ? angle : - angle;
|
||||
return cross < 0 ? -angle : angle;
|
||||
}
|
||||
generateInterpolatedPoints(polygonPositions, spacing) {
|
||||
// 1. 边界点插值
|
||||
const boundaryPoints = [];
|
||||
|
||||
for (let i = 0; i < polygonPositions.length; i++) {
|
||||
|
||||
const start = polygonPositions[i];
|
||||
const end = polygonPositions[(i + 1) % polygonPositions.length];
|
||||
const segmentLength = Cesium.Cartesian3.distance(start, end);
|
||||
const segments = Math.ceil(segmentLength / spacing);
|
||||
|
||||
for (let j = 0; j <= segments; j++) {
|
||||
const ratio = j / segments;
|
||||
const point = Cesium.Cartesian3.lerp(
|
||||
start, end, ratio, new Cesium.Cartesian3()
|
||||
);
|
||||
boundaryPoints.push(point);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 内部网格生成
|
||||
const extent = this.computePolygonExtent(polygonPositions);
|
||||
let result = this.createGridFromBBox(extent, this.options.spacing)
|
||||
// const extent = Cesium.Rectangle.fromCartesianArray(polygonPositions);
|
||||
|
||||
const gridPoints = [];
|
||||
// const polygon = new Cesium.PolygonHierarchy(polygonPositions);
|
||||
var polygon = []
|
||||
this.options.positions.forEach(item => {
|
||||
polygon.push([item.lng, item.lat])
|
||||
})
|
||||
polygon.push(polygon[0])
|
||||
for (let x = extent.west; x <= extent.east; x += result.lonStep) {
|
||||
for (let y = extent.south; y <= extent.north; y += result.latStep) {
|
||||
const position = Cesium.Cartesian3.fromDegrees(x, y);
|
||||
const point = turf.point([x, y]);
|
||||
const polygonTurf = turf.polygon([polygon]);
|
||||
const isInside = turf.booleanPointInPolygon(point, polygonTurf);
|
||||
isInside && gridPoints.push(position)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 合并结果并去重
|
||||
// return [...new Set([...boundaryPoints, ...gridPoints]
|
||||
return [...new Set([...gridPoints]
|
||||
.map(p => `${p.x},${p.y},${p.z}`))]
|
||||
.map(str => {
|
||||
const [x, y, z] = str.split(',').map(Number);
|
||||
return new Cesium.Cartesian3(x, y, z);
|
||||
});
|
||||
}
|
||||
|
||||
createGridFromBBox(bbox, spacing) {
|
||||
const earthRadius = 6378137; // WGS84椭球体长半轴
|
||||
// 计算经度方向网格数
|
||||
const lonDistance = Cesium.Cartesian3.distance(
|
||||
Cesium.Cartesian3.fromDegrees(bbox.west, (bbox.south + bbox.north) / 2, 0),
|
||||
Cesium.Cartesian3.fromDegrees(bbox.east, (bbox.south + bbox.north) / 2, 0)
|
||||
);
|
||||
const lonCount = Math.ceil(lonDistance / spacing);
|
||||
|
||||
// 计算纬度方向网格数
|
||||
const latDistance = Cesium.Cartesian3.distance(
|
||||
Cesium.Cartesian3.fromDegrees((bbox.west + bbox.east) / 2, bbox.south, 0),
|
||||
Cesium.Cartesian3.fromDegrees((bbox.west + bbox.east) / 2, bbox.north, 0)
|
||||
);
|
||||
const latCount = Math.ceil(latDistance / spacing);
|
||||
// 生成网格线
|
||||
const lonStep = (bbox.east - bbox.west) / lonCount;
|
||||
const latStep = (bbox.north - bbox.south) / latCount;
|
||||
return { lonStep, latStep }
|
||||
}
|
||||
|
||||
computePolygonExtent(positions) {
|
||||
// 计算多边形经纬度范围
|
||||
const cartographics = positions.map(p =>
|
||||
Cesium.Cartographic.fromCartesian(p));
|
||||
const lons = cartographics.map(c => Cesium.Math.toDegrees(c.longitude));
|
||||
const lats = cartographics.map(c => Cesium.Math.toDegrees(c.latitude));
|
||||
return {
|
||||
west: Math.min(...lons),
|
||||
east: Math.max(...lons),
|
||||
south: Math.min(...lats),
|
||||
north: Math.max(...lats)
|
||||
};
|
||||
}
|
||||
async computedArea(polygonPositions, spacing) {
|
||||
let dis12 = Cesium.Cartesian3.distance(polygonPositions[0], polygonPositions[1]);
|
||||
let dis23 = Cesium.Cartesian3.distance(polygonPositions[1], polygonPositions[2]);
|
||||
let vec12 = Cesium.Cartesian3.subtract(polygonPositions[1], polygonPositions[0], new Cesium.Cartesian3());
|
||||
let vec23 = Cesium.Cartesian3.subtract(polygonPositions[2], polygonPositions[1], new Cesium.Cartesian3());
|
||||
|
||||
let num12 = Math.ceil(dis12 / spacing);
|
||||
let num23 = Math.ceil(dis23 / spacing);
|
||||
|
||||
let line1 = []
|
||||
for (let i = 0; i < num12; i++) {
|
||||
line1.push(await this.calculatePointB(polygonPositions[0], polygonPositions[1], i * spacing))
|
||||
}
|
||||
let line2 = []
|
||||
for (let i = 0; i < num12; i++) {
|
||||
line2.push(await this.calculatePointB(polygonPositions[3], polygonPositions[2], i * spacing))
|
||||
}
|
||||
|
||||
let allPoints = []
|
||||
for (let i = 0; i < line1.length; i++) {
|
||||
for (let j = 0; j < num23; j++) {
|
||||
allPoints.push(await this.calculatePointB(line1[i], line2[i], j * spacing))
|
||||
}
|
||||
}
|
||||
return allPoints
|
||||
}
|
||||
async calculatePointB(pointA, pointC, distance) {
|
||||
// 将输入坐标转换为Cartesian3类型
|
||||
// const pointA = Cesium.Cartesian3.fromDegrees(a.longitude, a.latitude, a.height);
|
||||
// const pointC = Cesium.Cartesian3.fromDegrees(c.longitude, c.latitude, c.height);
|
||||
|
||||
// 计算向量AC
|
||||
const vectorAC = Cesium.Cartesian3.subtract(pointC, pointA, new Cesium.Cartesian3());
|
||||
|
||||
// 计算向量AC的长度
|
||||
const lengthAC = Cesium.Cartesian3.magnitude(vectorAC);
|
||||
|
||||
// 归一化向量AC
|
||||
const unitVector = Cesium.Cartesian3.normalize(vectorAC, new Cesium.Cartesian3());
|
||||
|
||||
// 计算点B坐标
|
||||
const scaledVector = Cesium.Cartesian3.multiplyByScalar(unitVector, distance, new Cesium.Cartesian3());
|
||||
const pointB = Cesium.Cartesian3.add(pointA, scaledVector, new Cesium.Cartesian3());
|
||||
|
||||
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(
|
||||
pointB // Cartesian3对象 {x, y, z}
|
||||
);
|
||||
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
|
||||
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
|
||||
|
||||
|
||||
let height = await this.getClampToHeight({ lng: longitude, lat: latitude })
|
||||
let point = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
|
||||
// 转换回经纬度
|
||||
// const cartographic = Cesium.Cartographic.fromCartesian(pointB);
|
||||
// return {
|
||||
// longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
||||
// latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
||||
// height: cartographic.height
|
||||
// };
|
||||
// return pointB
|
||||
return point
|
||||
}
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
this.options.show = v
|
||||
for (let i = 0; i < this.pointArr.length; i++) {
|
||||
this.pointArr[i].show = v
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return this.options.type
|
||||
}
|
||||
|
||||
set type(v) {
|
||||
this.options.type = v
|
||||
this._elms.type &&
|
||||
this._elms.type.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
get spacing() {
|
||||
return this.options.spacing
|
||||
}
|
||||
|
||||
set spacing(v) {
|
||||
this.options.spacing = v
|
||||
this._elms.spacing &&
|
||||
this._elms.spacing.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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.name = '飞线'
|
||||
}
|
||||
|
||||
let Draw
|
||||
switch (this.options.type) {
|
||||
case '点':
|
||||
Draw = new DrawPoint(this.sdk)
|
||||
break;
|
||||
case '线':
|
||||
Draw = new DrawPolyline(this.sdk)
|
||||
break;
|
||||
case '面':
|
||||
Draw = new DrawThreeRect(this.sdk)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Draw && Draw.start((a, positions) => {
|
||||
this.options.positions = positions;
|
||||
// this.callback(this.options);
|
||||
(this.options.positions.length || this.options.positions.lng) && BatchModel.computeDis(this)
|
||||
})
|
||||
|
||||
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()
|
||||
// console.log('22222')
|
||||
// this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
// },
|
||||
// removeCallBack: () => {
|
||||
// console.log('33333')
|
||||
// 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.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
addFootElm: [
|
||||
{
|
||||
tagName: 'button',
|
||||
className: 'flipe-over-y',
|
||||
innerHTML: '重置',
|
||||
event: [
|
||||
'click',
|
||||
() => {
|
||||
this.reset()
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
// showCallBack: (show) => {
|
||||
// this.show = show
|
||||
// this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
// }
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' flow-line-surface'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
// let waterColorPicker = new YJColorPicker({
|
||||
// el: contentElm.getElementsByClassName("flowLine-color")[0],
|
||||
// size: 'mini',//颜色box类型
|
||||
// alpha: true,//是否开启透明度
|
||||
// defaultColor: this.color,
|
||||
// disabled: false,//是否禁止打开颜色选择器
|
||||
// openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
// sure: (color) => {
|
||||
// this.color = color
|
||||
// },//点击确认按钮事件回调
|
||||
// clear: () => {
|
||||
// this.color = 'rgba(255,255,255,1)'
|
||||
// },//点击清空按钮事件回调
|
||||
// })
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
|
||||
let nameData = [
|
||||
{
|
||||
name: '点',
|
||||
value: '点',
|
||||
},
|
||||
{
|
||||
name: '线',
|
||||
value: '线',
|
||||
},
|
||||
{
|
||||
name: '面',
|
||||
value: '面',
|
||||
}
|
||||
]
|
||||
|
||||
let nameDataLegpObject = legp(
|
||||
this._DialogObject._element.content.getElementsByClassName(
|
||||
'add-type-box'
|
||||
)[0],
|
||||
'.add-type'
|
||||
)
|
||||
if (nameDataLegpObject) {
|
||||
nameDataLegpObject.legp_search(nameData)
|
||||
let nameDataLegpElm = this._DialogObject._element.content
|
||||
.getElementsByClassName('add-type')[0]
|
||||
.getElementsByTagName('input')[0]
|
||||
this._elms.type = [nameDataLegpElm]
|
||||
nameDataLegpElm.value = this.options.type
|
||||
for (let i = 0; i < nameData.length; i++) {
|
||||
if (nameData[i].value === nameDataLegpElm.value) {
|
||||
nameDataLegpObject.legp_searchActive(nameData[i].value)
|
||||
break
|
||||
}
|
||||
}
|
||||
nameDataLegpElm.addEventListener('input', () => {
|
||||
for (let i = 0; i < nameData.length; i++) {
|
||||
if (nameData[i].value === nameDataLegpElm.value) {
|
||||
this.type = nameData[i].value
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// this._elms.color = [waterColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
drawArea() {
|
||||
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.name = this.originalOptions.name
|
||||
this.type = this.originalOptions.type
|
||||
this.spacing = this.originalOptions.spacing
|
||||
this.show = this.originalOptions.show
|
||||
this.options.spacing = this.originalOptions.spacing
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到对应实体
|
||||
*/
|
||||
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 positionArray = []
|
||||
if (this.options.positions.length > 0) {
|
||||
for (let i = 0; i < this.options.positions.length; i++) {
|
||||
let a = Cesium.Cartesian3.fromDegrees(
|
||||
this.options.positions[i].lng,
|
||||
this.options.positions[i].lat,
|
||||
this.options.positions[i].alt
|
||||
)
|
||||
positionArray.push(a.x, a.y, a.z)
|
||||
}
|
||||
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||
this.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||
offset: {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-20.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
} else if (this.options.positions.lng) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-60.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.positions.lng, this.options.positions.lat, this.options.positions.alt + 100),
|
||||
// orientation: orientation
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
async remove() {
|
||||
for (let i = 0; i < this.pointArr.length; i++) {
|
||||
this.pointArr[i].remove()
|
||||
}
|
||||
|
||||
this.pointArr = []
|
||||
this.positions = []
|
||||
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)
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default BatchModel
|
||||
335
src/Obj/Base/BillboardObject/_element.js
Normal file
335
src/Obj/Base/BillboardObject/_element.js
Normal file
@ -0,0 +1,335 @@
|
||||
import { attributeElm } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: unset;">名称</span>
|
||||
<input class="input" type="text" @model="labelText">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div style="width: 46%;">
|
||||
<div class="row">
|
||||
<p class="lable-left-line">WGS84坐标</p>
|
||||
</div>
|
||||
<div class="row" style="margin-bottom: 5px;">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-bottom: 5px;">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">海拔高度</span>
|
||||
<div class="input-number input-number-unit-1 alt-box">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 50%;">
|
||||
<div class="row coordinate-select-box">
|
||||
<div class="lable-left-line">转换坐标选择
|
||||
<div class="input input-select coordinate-select" style="margin-left: 20px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-bottom: 5px;">
|
||||
<div class="col">
|
||||
<span class="label">X轴:</span>
|
||||
<input style="border: none;background: none;" class="input convert-x" readonly="readonly">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-bottom: 5px;">
|
||||
<div class="col">
|
||||
<span class="label">Y轴:</span>
|
||||
<input style="border: none;background: none;" class="input convert-y" readonly="readonly">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">Z轴:</span>
|
||||
<input style="border: none;background: none;" class="input convert-z" readonly="readonly">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 0 0 120px;">
|
||||
<span class="label">视野缩放</span>
|
||||
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最近距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="near">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最远距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="far">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="point-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col height-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">小数格式</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分格式</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;">
|
||||
<input type="checkbox" class="YJ-custom-checkbox">
|
||||
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分秒格式</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div style="flex: 1;">
|
||||
<div class="proj-input-box">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span style="flex: 0 0 40px;">经度</span>
|
||||
<input class="input lng" readonly="readonly">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span style="flex: 0 0 40px;">纬度</span>
|
||||
<input class="input lat" readonly="readonly">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proj-input-box" style="width: 56%;">
|
||||
<div class="row">
|
||||
<div class="col" style="flex-direction: column;">
|
||||
<div class="row" style="margin-bottom: 15px;">
|
||||
<span style="flex: 0 0 40px;">经度</span>
|
||||
<input class="input lng-dm-d" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
|
||||
<input class="input lng-dm-m" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
|
||||
<span class="top-line"></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span style="flex: 0 0 40px;">纬度</span>
|
||||
<input class="input lat-dm-d" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
|
||||
<input class="input lat-dm-m" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
|
||||
<span class="bottom-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proj-input-box" style="width: 70%;">
|
||||
<div class="row">
|
||||
<div class="col" style="flex-direction: column;">
|
||||
<div class="row" style="margin-bottom: 15px;">
|
||||
<span style="flex: 0 0 40px;">经度</span>
|
||||
<input class="input lng-dms-d" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
|
||||
<input class="input lng-dms-m" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
|
||||
<input class="input lng-dms-s" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">秒</span>
|
||||
<span class="top-line"></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span style="flex: 0 0 40px;">纬度</span>
|
||||
<input class="input lat-dms-d" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
|
||||
<input class="input lat-dms-m" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
|
||||
<input class="input lat-dms-s" style="flex: 1;" readonly="readonly">
|
||||
<span class="label" style="flex: 0 0 14px;margin: 0 10px;">秒</span>
|
||||
<span class="bottom-line"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
<div>
|
||||
<h4>图标设置</h4>
|
||||
<div class="row" style="margin-bottom: 10px;">
|
||||
<div class="col" style="flex: 0 0 80px;">
|
||||
<span class="label" style="flex: none;">显隐</span>
|
||||
<input class="btn-switch" type="checkbox" @model="billboardShow">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 90px;">
|
||||
<span class="label" style="flex: none;">图标</span>
|
||||
<div class="image-box" @click="clickChangeImage">
|
||||
<img class="image" src="" alt="" @model="billboardImage">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 90px;">
|
||||
<span class="label" style="flex: none;">默认图标</span>
|
||||
<div class="image-box" @click="clickChangeDefaultImage">
|
||||
<img class="image" src="" alt="" @model="billboardDefaultImage">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">图标倍数</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="0.1" max="99" @model="billboardScale">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4>文字设置</h4>
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 0 0 80px;">
|
||||
<span class="label" style="flex: none;">显隐</span>
|
||||
<input class="btn-switch" type="checkbox" @model="labelShow">
|
||||
</div>
|
||||
<div class="col font-select-box">
|
||||
<span class="label" style="flex: none;">字体选择</span>
|
||||
<div class="input input-select font-select"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">文字大小</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="1" max="99" @model="labelFontSize" style="width: 70px;">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">文字颜色</span>
|
||||
<div class="labelColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<!-- <DIV-cy-tab-pane label="效果">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">扩散</span>
|
||||
<input class="btn-switch" type="checkbox" @model="diffuseShow">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">半径</span>
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="diffuseRadius">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">时间</span>
|
||||
<input class="input" type="number" title="" min="100" max="99999" @model="diffuseDuration">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="diffuseColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">雷达</span>
|
||||
<input class="btn-switch" type="checkbox" @model="scanShow">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">半径</span>
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="scanRadius">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">时间</span>
|
||||
<input class="input" type="number" title="" min="100" max="99999" @model="scanDuration">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="scanColor"></div>
|
||||
</div>
|
||||
</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">设置操作点</span>-->
|
||||
<!-- <input class="input" type="text" @model="operatingPoint">-->
|
||||
<!-- <button class="primary" @click="operatingPointSubmit">提交</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </DIV-cy-tab-pane>-->
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
3175
src/Obj/Base/BillboardObject/index.js
Normal file
3175
src/Obj/Base/BillboardObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
85
src/Obj/Base/CircleDiffuse/_element.js
Normal file
85
src/Obj/Base/CircleDiffuse/_element.js
Normal file
@ -0,0 +1,85 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">透明度</span>
|
||||
<input type="range" min="0" max="1" step="0.01" @model="transparency">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">波纹层数</span>
|
||||
<div class="input-number input-number-unit">
|
||||
<input class="input" type="number" title="" min="1" max="10" @model="count">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扩散速度</span>
|
||||
<div class="input-number input-number-unit">
|
||||
<input class="input" type="number" title="" min="0" max="20" @model="speed">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col input-radius-unit-box" style="margin: 0;">
|
||||
<span class="label">半径单位</span>
|
||||
<div class="input-radius-unit"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;">
|
||||
</div>
|
||||
<div class="col" style="margin: 0;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row circle-content-box">
|
||||
<div class="col">
|
||||
<span class="label"></span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="circle-diffuse-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
1614
src/Obj/Base/CircleDiffuse/index.js
Normal file
1614
src/Obj/Base/CircleDiffuse/index.js
Normal file
File diff suppressed because it is too large
Load Diff
87
src/Obj/Base/CircleObject/_element.js
Normal file
87
src/Obj/Base/CircleObject/_element.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="circle-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2214
src/Obj/Base/CircleObject/index.js
Normal file
2214
src/Obj/Base/CircleObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
64
src/Obj/Base/Corridor/index.js
Normal file
64
src/Obj/Base/Corridor/index.js
Normal file
@ -0,0 +1,64 @@
|
||||
// /**
|
||||
// * 走廊
|
||||
// */
|
||||
// import Base from "../index";
|
||||
|
||||
// class Corridor extends Base {
|
||||
// /**
|
||||
// * @constructor
|
||||
// * @param sdk
|
||||
// * @param options {object} 线属性
|
||||
// * @param options.name{string} 名称
|
||||
// * @param options.image{string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL、Canvas 或 Video 的属性
|
||||
// * @param options.width=10{number} 宽度
|
||||
// * @param options.height=0{number} 高度
|
||||
// * */
|
||||
// constructor(sdk, options = {}) {
|
||||
// super(sdk, options);
|
||||
// this.options.name = options.name || ''
|
||||
// this.options.image = options.image
|
||||
// this.options.width = options.width || 10
|
||||
// this.options.height = options.height || 0
|
||||
// }
|
||||
|
||||
// create(positions) {
|
||||
// let fromDegreesArray = []
|
||||
// for (let i = 0; i < positions.length; i++) {
|
||||
// fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
// }
|
||||
// this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({//GroundPrimitive贴地
|
||||
// geometryInstances: new Cesium.GeometryInstance({
|
||||
// geometry: new Cesium.CorridorGeometry({
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// width: this.options.width,
|
||||
// height: this.options.height,
|
||||
// cornerType: Cesium.CornerType.MITERED,
|
||||
// vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
|
||||
// }),
|
||||
// attributes: {
|
||||
// color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 0.5))
|
||||
// }
|
||||
// }),
|
||||
// appearance: new Cesium.MaterialAppearance({
|
||||
// material: Cesium.Material.fromType('Image', {
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(100, 1.0)
|
||||
// }),
|
||||
// faceForward: true,
|
||||
// renderState: {
|
||||
// blending: Cesium.BlendingState.ALPHA_BLEND
|
||||
// }
|
||||
// })
|
||||
// }));
|
||||
// }
|
||||
|
||||
// // 编辑框
|
||||
// async edit(state) { }
|
||||
|
||||
// remove() {
|
||||
// this.sdk.viewer.scene.primitives.remove(this.entity)
|
||||
// this.entity = null
|
||||
// }
|
||||
// }
|
||||
|
||||
// export default Corridor
|
||||
167
src/Obj/Base/CurvelineObject/_element.js
Normal file
167
src/Obj/Base/CurvelineObject/_element.js
Normal file
@ -0,0 +1,167 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 56%;">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<div class="input-select-unit"></div>
|
||||
<input class="input input-text" readonly="readonly" type="text" style="flex: 0 0 130px;" @model="length">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="polyline-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="线条风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">线条颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">线条宽度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="1" max="999" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col input-select-line-type-box" style="flex: 0 0 37%;">
|
||||
<span class="label">线条形式</span>
|
||||
<div class="input-select-line-type"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">线段缓冲</span>
|
||||
<input class="btn-switch" type="checkbox" @model="extend">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">缓冲宽度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" data-min="0.01" max="999999" @model="extendWidth">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
<span class="label">缓冲颜色</span>
|
||||
<div class="extendColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="dashTextureDom">
|
||||
<div class="col">
|
||||
<span class="label">动画顺向</span>
|
||||
<input class="btn-switch" type="checkbox" @model="rotate">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">流动速率</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="999999" step="1" @model="speed">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
<span class="label lineSpace">间距</span>
|
||||
<div class="input-number input-number-unit-1 lineSpace" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="4.5" step="0.1" @model="space">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">首尾相连</span>
|
||||
<input class="btn-switch" type="checkbox" @model="noseToTail">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</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">设置操作点</span>-->
|
||||
<!-- <input class="input" type="text" @model="operatingPoint">-->
|
||||
<!-- <button class="primary" @click="operatingPointSubmit">提交</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </DIV-cy-tab-pane>-->
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
120
src/Obj/Base/CurvelineObject/eventBinding.js
Normal file
120
src/Obj/Base/CurvelineObject/eventBinding.js
Normal file
@ -0,0 +1,120 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] ||!elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
if (e.data != '.' && (e.data != '-' || e.target.value)) {
|
||||
value = Number(value)
|
||||
if((e.target.max) && value>Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
}
|
||||
if((e.target.min) && value<Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
}
|
||||
if((e.target.dataset.min) && value<Number(e.target.dataset.min)) {
|
||||
value = Number(e.target.dataset.min)
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
}
|
||||
else {
|
||||
that[m.value] = value
|
||||
}
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
case '@change': {
|
||||
isEvent = true
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' && value!='') {
|
||||
value = Number(value)
|
||||
e.target.value = value
|
||||
}
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e, value)
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
3322
src/Obj/Base/CurvelineObject/index.js
Normal file
3322
src/Obj/Base/CurvelineObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
87
src/Obj/Base/EllipseObject/_element.js
Normal file
87
src/Obj/Base/EllipseObject/_element.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="circle-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2205
src/Obj/Base/EllipseObject/index.js
Normal file
2205
src/Obj/Base/EllipseObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
51
src/Obj/Base/Explosion/_element.js
Normal file
51
src/Obj/Base/Explosion/_element.js
Normal file
@ -0,0 +1,51 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">随地图缩放</span>
|
||||
<input class="btn-switch" type="checkbox" @model="scaleByDistance">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">爆炸范围</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="999999" @model="size">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
391
src/Obj/Base/Explosion/index.js
Normal file
391
src/Obj/Base/Explosion/index.js
Normal file
@ -0,0 +1,391 @@
|
||||
import Base from "../index";
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import { html } from "./_element";
|
||||
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, getGroundCover} from '../../../Global/global'
|
||||
class Explosion extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 爆炸
|
||||
* @param sdk
|
||||
* @param options {object} 爆炸属性
|
||||
* @param options.id {string} 唯一标识
|
||||
* @param options.show=true {boolean} 显隐
|
||||
* @param options.name {string} 名称
|
||||
* @param {object} options.position={} 位置
|
||||
* @param {number} options.position.lng 经度
|
||||
* @param {number} options.position.lat 纬度
|
||||
* @param {number} options.position.alt 高度
|
||||
* @param options.scaleByDistance=true {boolean} 是否开启跟随视野缩放
|
||||
* @param options.size=80 {number} 大小(爆炸范围)
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.viewer = sdk.viewer
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.options.name = this.options.name || '未命名对象'
|
||||
this.options.size = (this.options.size || this.options.size === 0) ? this.options.size : 80
|
||||
this.options.scaleByDistance = (options.scaleByDistance || options.scaleByDistance === false) ? options.scaleByDistance : true
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.Dialog = _Dialog
|
||||
this.operate = {}
|
||||
this._elms = {};
|
||||
this._EventBinding = new EventBinding()
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
Explosion.create(this)
|
||||
}
|
||||
|
||||
get type() {
|
||||
return 'Explosion'
|
||||
}
|
||||
|
||||
// 创建
|
||||
static create(that) {
|
||||
let img_bz = []
|
||||
for (let i = 10001; i <= 10120; i++) {
|
||||
let src = that.getSourceRootPath() + `/img/frameAnimation/explosion/b${i}.png`
|
||||
img_bz.push(src)
|
||||
}
|
||||
let i = 0
|
||||
let flyEntity = new Cesium.Entity({
|
||||
id: that.options.id,
|
||||
show: that.options.show,
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Cartesian3.fromDegrees(that.options.position.lng, that.options.position.lat, that.options.position.alt)
|
||||
}, false),
|
||||
billboard: {
|
||||
image: new Cesium.CallbackProperty(() => {
|
||||
let img = img_bz[flyEntity.imgIndex]
|
||||
flyEntity.imgIndex++
|
||||
if (flyEntity.imgIndex >= img_bz.length) {
|
||||
flyEntity.imgIndex = 0
|
||||
}
|
||||
return img
|
||||
}, false),
|
||||
// scale: that.options.size,
|
||||
disableDepthTestDistance: new Cesium.CallbackProperty(function () {
|
||||
return getGroundCover() ? undefined : Number.POSITIVE_INFINITY
|
||||
}, false),
|
||||
width: that.options.size,
|
||||
height: that.options.size,
|
||||
sizeInMeters: that.options.scaleByDistance,
|
||||
pixelOffset: { x: 0, y: -20 }
|
||||
},
|
||||
});
|
||||
flyEntity.imgIndex = 0
|
||||
that.entity = that.viewer.entities.add(flyEntity)
|
||||
syncData(that.sdk, that.options.id)
|
||||
if(that.options.show) {
|
||||
setSplitDirection(0, that.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '爆炸属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.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.positionEditing = false
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.options.show = show
|
||||
this.originalOptions.show = show
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
this.positionEditing = !this.positionEditing
|
||||
},
|
||||
})
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' explosion'
|
||||
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
|
||||
this.scaleByDistance = this.options.scaleByDistance
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt + (this.options.size * 8)),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-85.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.previous = null
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.name = this.originalOptions.name
|
||||
this.size = this.originalOptions.size
|
||||
this.scaleByDistance = this.originalOptions.scaleByDistance
|
||||
this.lng = this.options.position.lng
|
||||
this.lat = this.options.position.lat
|
||||
}
|
||||
|
||||
get scaleByDistance() {
|
||||
return this.options.scaleByDistance
|
||||
}
|
||||
set scaleByDistance(v) {
|
||||
this.options.scaleByDistance = v
|
||||
this.entity.billboard.sizeInMeters = v
|
||||
this._elms.scaleByDistance && this._elms.scaleByDistance.forEach((item) => {
|
||||
item.checked = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.position.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.position.lng = v
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.position.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.position.lat = v
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.position.alt
|
||||
}
|
||||
|
||||
set alt(v) {
|
||||
this.options.position.alt = v
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.options.size
|
||||
}
|
||||
set size(v) {
|
||||
this.options.size = v
|
||||
this.entity.billboard.width = this.options.size
|
||||
this.entity.billboard.height = this.options.size
|
||||
this._elms.size && this._elms.size.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (YJ.Measure.GetMeasureStatus() || !this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.operate.positionEditing = status
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.lng = positions.lng
|
||||
this.lat = positions.lat
|
||||
this.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.lng = positions.lng
|
||||
this.lat = positions.lat
|
||||
this.alt = positions.alt
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
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.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.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.lng = positions.lng
|
||||
this.lat = positions.lat
|
||||
this.alt = positions.alt
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
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()
|
||||
if (this.previous) {
|
||||
this.lng = this.previous.position.lng
|
||||
this.lat = this.previous.position.lat
|
||||
this.alt = this.previous.position.alt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
async remove() {
|
||||
this.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
flicker() {}
|
||||
}
|
||||
|
||||
export default Explosion
|
||||
76
src/Obj/Base/FlowLine/_element.js
Normal file
76
src/Obj/Base/FlowLine/_element.js
Normal file
@ -0,0 +1,76 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="flowLine-color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">飞线数量</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999" @model="pointNumber">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">飞线宽度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" max="99999" min="1" step="1" @model="width">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
<span class="label">飞线高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="999999" step="1" @model="height">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">飞线高度差</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" max="99999" min="0" step="1" @model="heightDifference">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">单次运动时长(s)</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" max="999999999" min="1" step="1" @model="duration">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">轨迹透明度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" max="1" min="0.01" step="0.01" @model="lineBackAlpha">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
92
src/Obj/Base/FlowLine/eventBinding.js
Normal file
92
src/Obj/Base/FlowLine/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue;
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if (elements[i].nodeName == 'IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if (this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for (let n = 0; n < removeName.length; n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
504
src/Obj/Base/FlowLine/index.js
Normal file
504
src/Obj/Base/FlowLine/index.js
Normal file
@ -0,0 +1,504 @@
|
||||
/**
|
||||
* @description 水面
|
||||
*/
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import Base from "../index";
|
||||
import { syncData } from '../../../Global/MultiViewportMode'
|
||||
import DrawRect from '../../../Draw/drawRect'
|
||||
import drawPolygon from '../../../Draw/drawPolygon'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../Global/global'
|
||||
import FlowLineMaterialProperty from "../../Materail/FlowLineMaterialProperty";
|
||||
|
||||
class FlowLine extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 流光飞线
|
||||
* @param options {object} 流光飞线属性
|
||||
* @param options.name=未命名对象 {string} 名称
|
||||
* @param options.pointNumber=300 {number} 线数量
|
||||
* @param options.height=200 {number} 线高度
|
||||
* @param options.heightDifference=3000 {number} 线高度差
|
||||
* @param options.width=2 {number} 线宽
|
||||
* @param options.duration=10.0 {number} 单次运动时间
|
||||
* @param options.color=rgba(255,255,255,1) {string} 颜色
|
||||
* @param options.lineBackAlpha=0.05 {number} 轨迹颜色(不能为0)
|
||||
* @param Dialog {object} 弹框对象
|
||||
* @param Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.viewer = this.sdk.viewer
|
||||
this.options.name = options.name || '飞线'
|
||||
this.options.pointNumber = options.pointNumber || 200
|
||||
this.options.height = options.height || 200
|
||||
this.options.heightDifference = options.heightDifference || 3000
|
||||
this.options.width = options.width || 2
|
||||
this.options.duration = options.duration || 10.0
|
||||
this.options.color = options.color || "rgba(255,255,255,1)"
|
||||
this.options.lineBackAlpha = options.lineBackAlpha || 0.05
|
||||
this.options.positions = options.positions || []
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.Dialog = _Dialog
|
||||
this._EventBinding = new EventBinding()
|
||||
this._elms = {};
|
||||
this.positionArea = []
|
||||
this.positions = []
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
// FlowLine.create(this)
|
||||
FlowLine.drawLine(this)
|
||||
}
|
||||
|
||||
// 创建水面
|
||||
static create(that) {
|
||||
// let Draw = new DrawRect(that.sdk)
|
||||
// Draw.start((a, positions) => {
|
||||
// that.positions = positions
|
||||
// that.getLine(that, that.positions)
|
||||
// that.edit(true)
|
||||
// })
|
||||
|
||||
let Draw = new drawPolygon(that.sdk)
|
||||
Draw.start((a, positions) => {
|
||||
that.positionArea = positions
|
||||
let posis = that.getRandomPointsInCesiumPolygon(positions, that.options.pointNumber)
|
||||
that.positions = posis
|
||||
that.getLine(that, posis)
|
||||
that.edit(true)
|
||||
})
|
||||
}
|
||||
static drawLine(that) {
|
||||
that.positionArea = that.options.positions
|
||||
let posis = that.getRandomPointsInCesiumPolygon(that.options.positions, that.options.pointNumber)
|
||||
that.positions = posis
|
||||
that.getLine(that, posis)
|
||||
// that.edit(true)
|
||||
}
|
||||
getRandomPointsInCesiumPolygon(positions, count) {
|
||||
let lons = [], lats = [], posi = []
|
||||
positions.forEach(item => {
|
||||
lons.push(item.lng)
|
||||
lats.push(item.lat)
|
||||
posi.push([item.lng, item.lat])
|
||||
})
|
||||
posi.push([posi[0][0], posi[0][1]])
|
||||
const minLon = Math.min(...lons), maxLon = Math.max(...lons);
|
||||
const minLat = Math.min(...lats), maxLat = Math.max(...lats);
|
||||
|
||||
const points = [];
|
||||
let that = this
|
||||
while (points.length < count) {
|
||||
const lon = minLon + Math.random() * (maxLon - minLon);
|
||||
const lat = minLat + Math.random() * (maxLat - minLat);
|
||||
// const cartesian = Cesium.Cartesian3.fromDegrees(lon, lat);
|
||||
let point = turf.point([lon, lat]);
|
||||
const polygon = turf.polygon([
|
||||
posi
|
||||
]);
|
||||
|
||||
const isInside = turf.booleanPointInPolygon(point, polygon);
|
||||
if (isInside) {
|
||||
let posi = Cesium.Cartesian3.fromDegrees(lon, lat);
|
||||
const cartographic = that.viewer.scene.globe.ellipsoid.cartesianToCartographic(posi);
|
||||
const height = cartographic.height;
|
||||
|
||||
points.push([
|
||||
lon,
|
||||
lat,
|
||||
height
|
||||
]);
|
||||
}
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
getLine(that, positions) {
|
||||
let num = 0
|
||||
let celiangEntity = null
|
||||
if (that.viewer.entities.getById(that.options.id)) {
|
||||
that.viewer.entities.getById(that.options.id)._children.forEach((item) => {
|
||||
that.viewer.entities.remove(item);
|
||||
});
|
||||
that.viewer.entities.remove(that.viewer.entities.getById(that.options.id))
|
||||
}
|
||||
celiangEntity = that.viewer.entities.add(new Cesium.Entity({ id: that.options.id, show: that.options.show }))
|
||||
|
||||
positions.forEach((item, index) => {
|
||||
let point = item
|
||||
//根据点设置起始点位置
|
||||
// let start = Cesium.Cartesian3.fromDegrees(point[0], point[1], 0)
|
||||
let start = Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2])
|
||||
//根据点设置结束点位置
|
||||
let end = Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] + that.options.height + Math.random() * that.options.heightDifference)
|
||||
//创建线
|
||||
that.viewer.entities.add({
|
||||
parent: celiangEntity,
|
||||
id: that.options.id + '-' + new Date().getTime() + index,
|
||||
polyline: {
|
||||
positions: [start, end],
|
||||
width: that.options.width,
|
||||
// material:Cesium.Color.RED
|
||||
material: new Cesium.FlowLineMaterialProperty({
|
||||
color: that.options.color,
|
||||
duration: that.options.duration,
|
||||
lineBackAlpha: that.options.lineBackAlpha,
|
||||
num: num
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
entity._children.forEach(item => {
|
||||
item.polyline.material.color = Cesium.Color.fromCssColorString(v)
|
||||
})
|
||||
}
|
||||
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.color = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
get pointNumber() {
|
||||
return this.options.pointNumber
|
||||
}
|
||||
set pointNumber(v) {
|
||||
this.options.pointNumber = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
let posis = this.getRandomPointsInCesiumPolygon(this.positionArea, this.options.pointNumber)
|
||||
this.positions = posis
|
||||
this.getLine(this, posis)
|
||||
}
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.options.height
|
||||
}
|
||||
|
||||
set height(v) {
|
||||
this.options.height = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
this.getLine(this, this.positions)
|
||||
}
|
||||
}
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
this.options.show = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
entity.show = v
|
||||
}
|
||||
}
|
||||
|
||||
get heightDifference() {
|
||||
return this.options.heightDifference
|
||||
}
|
||||
|
||||
set heightDifference(v) {
|
||||
this.options.heightDifference = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
this.getLine(this, this.positions)
|
||||
}
|
||||
}
|
||||
|
||||
get width() {
|
||||
return this.options.width
|
||||
}
|
||||
|
||||
set width(v) {
|
||||
this.options.width = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
entity._children.forEach(item => {
|
||||
item.polyline.width = v
|
||||
})
|
||||
}
|
||||
}
|
||||
get duration() {
|
||||
return this.options.duration
|
||||
}
|
||||
set duration(v) {
|
||||
this.options.duration = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
entity._children.forEach(item => {
|
||||
item.polyline.material.duration = v
|
||||
})
|
||||
}
|
||||
}
|
||||
get lineBackAlpha() {
|
||||
return this.options.lineBackAlpha
|
||||
}
|
||||
set lineBackAlpha(v) {
|
||||
this.options.lineBackAlpha = v
|
||||
let entity = this.viewer.entities.getById(this.options.id)
|
||||
if (entity) {
|
||||
entity._children.forEach(item => {
|
||||
item.polyline.material.lineBackAlpha = v
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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.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.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
}
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' flow-line-surface'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let waterColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("flowLine-color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.color,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.color = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
this._elms.color = [waterColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.viewer.entities.getById(this.options.id)) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.pointNumber = this.originalOptions.pointNumber
|
||||
this.height = this.originalOptions.height
|
||||
this.heightDifference = this.originalOptions.heightDifference
|
||||
this.width = this.originalOptions.width
|
||||
this.duration = this.originalOptions.duration
|
||||
this.color = this.originalOptions.color
|
||||
this.lineBackAlpha = this.originalOptions.lineBackAlpha
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到对应实体
|
||||
*/
|
||||
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 positionArray = []
|
||||
for (let i = 0; i < this.positions.length; i++) {
|
||||
let a = Cesium.Cartesian3.fromDegrees(
|
||||
this.positions[i][0],
|
||||
this.positions[i][1],
|
||||
this.positions[i][2] + this.options.height + this.options.heightDifference / 2
|
||||
)
|
||||
positionArray.push(a.x, a.y, a.z)
|
||||
}
|
||||
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||
this.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||
offset: {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-20.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getSphere() {
|
||||
return new Promise((resolve) => {
|
||||
// entity没有加载完成时 state 不会等于0 所以设置定时器直到获取到为止
|
||||
const interval = setInterval(() => {
|
||||
const sphere = new Cesium.BoundingSphere()
|
||||
const state = this.sdk.viewer._dataSourceDisplay.getBoundingSphere(
|
||||
this.viewer.entities.getById(this.options.id),
|
||||
false,
|
||||
sphere
|
||||
)
|
||||
if (state === Cesium.BoundingSphereState.DONE) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
async remove() {
|
||||
if (this.viewer.entities.getById(this.options.id)) {
|
||||
this.viewer.entities.getById(this.options.id)._children.forEach((item) => {
|
||||
this.viewer.entities.remove(item);
|
||||
});
|
||||
this.viewer.entities.remove(this.viewer.entities.getById(this.options.id))
|
||||
}
|
||||
this.positions = []
|
||||
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)
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default FlowLine
|
||||
67
src/Obj/Base/FlyRoam/_element.js
Normal file
67
src/Obj/Base/FlyRoam/_element.js
Normal file
@ -0,0 +1,67 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" type="text" name="name">
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="add-point"><svg class="icon-add"><use xlink:href="#yj-icon-add"></use></svg>增加视点</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="modify-point"><svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>调整视点</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="afreshPlay"><svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>播放</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="cease"><svg class="icon-pause"><use xlink:href="#yj-icon-pause"></use></svg>结束</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th">序号</div>
|
||||
<div class="th">时长(s)</div>
|
||||
<div class="th">操作</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<div class="table-empty">
|
||||
<div class="empty-img"></div>
|
||||
<p>暂无数据</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
438
src/Obj/Base/FlyRoam/index.js
Normal file
438
src/Obj/Base/FlyRoam/index.js
Normal file
@ -0,0 +1,438 @@
|
||||
|
||||
/**
|
||||
* @description 飞行漫游
|
||||
*/
|
||||
import Dialog from '../../../BaseDialog';
|
||||
import { html } from "./_element";
|
||||
import Base from "../index";
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
class FlyRoam extends Base {
|
||||
#clickHandler = undefined
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 飞行漫游
|
||||
* @param options {object}
|
||||
* @param options.id {string} 标注id
|
||||
* @param options.name {string} 名称
|
||||
* @param options.repeat=0 {number} 重复次数
|
||||
* @param options.points=[]] {array} 视点列表
|
||||
* @param options.points[].position {object} 视点位置
|
||||
* @param options.points[].position.lng {number} 经度
|
||||
* @param options.points[].position.lat {number} 纬度
|
||||
* @param options.points[].position.alt {number} 高度
|
||||
* @param options.points[].orientation {object} 视点方向
|
||||
* @param options.points[].orientation.heading=0 {number} 视点航向角
|
||||
* @param options.points[].orientation.pitch=0 {number} 视点俯仰角
|
||||
* @param options.points[].orientation.roll=0 {number} 视点翻滚角
|
||||
* @param options.points[].duration=0 {number} 持续时间
|
||||
**/
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options)
|
||||
this.options.id = options.id || this.randomString()
|
||||
this.options.name = options.name || '漫游路径'
|
||||
this.options.points = options.points || []
|
||||
if(this.options.repeat) {
|
||||
this.options.repeat = Number(this.options.repeat)
|
||||
}
|
||||
this.Dialog = _Dialog
|
||||
}
|
||||
|
||||
get repeat() {
|
||||
return this.options.repeat
|
||||
}
|
||||
|
||||
/**设置循环次数 (Infinity: 无限循环)*/
|
||||
set repeat(v) {
|
||||
if (this.options.repeat != Number(v)) {
|
||||
this.options.repeat = Number(v)
|
||||
if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) {
|
||||
let repeatElm = this._DialogObject._element.content.querySelector("input[name='repeat']")
|
||||
if (v === Infinity) {
|
||||
repeatElm.checked = true
|
||||
}
|
||||
else {
|
||||
repeatElm.checked = false
|
||||
}
|
||||
this.Dialog.changeRepeatStateCallBack && this.Dialog.changeRepeatStateCallBack(repeatElm.checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
let viewer = this.sdk.viewer
|
||||
let active = 0
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._DialogObject = await new Dialog(viewer._container, {
|
||||
title: '飞行漫游', left: '180px', top: '100px',
|
||||
closeCallBack: () => {
|
||||
this.cease()
|
||||
},
|
||||
})
|
||||
await this._DialogObject.init()
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.className = 'fly-roam'
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
// EventBinding(all_elm)
|
||||
|
||||
let tableBody = contentElm.getElementsByClassName('table-body')[0];
|
||||
let tableEmpty = contentElm.getElementsByClassName('table-empty')[0]
|
||||
|
||||
let handler = {
|
||||
set: function (target, prop, value) {
|
||||
target[prop] = value;
|
||||
if (target.length > 0) {
|
||||
tableEmpty.style.display = 'none'
|
||||
}
|
||||
else {
|
||||
tableEmpty.style.display = 'flex'
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
let i = 0
|
||||
let points = new Proxy([], handler);
|
||||
for (i = 0; i < this.options.points.length; i++) {
|
||||
points.push(this.options.points[i])
|
||||
addTrElm(this.options.points[i])
|
||||
}
|
||||
|
||||
|
||||
// let nameImputBoxElm = contentElm.getElementsByClassName('input-box')[0]
|
||||
// check(nameImputBoxElm, { validator: 'notEmpty', message: '名称不能为空!', trigger: 'input' })
|
||||
let nameElm = contentElm.querySelector("input[name='name']")
|
||||
nameElm.value = this.name
|
||||
nameElm.addEventListener('input', () => {
|
||||
this.name = nameElm.value
|
||||
})
|
||||
|
||||
let addListBtn = document.createElement('button');
|
||||
addListBtn.innerHTML = '保存'
|
||||
addListBtn.addEventListener('click', () => {
|
||||
if (!this.name) {
|
||||
this.name = '漫游路径'
|
||||
nameElm.value = this.name
|
||||
}
|
||||
let newPoints = []
|
||||
points.map((item) => {
|
||||
newPoints.push(item)
|
||||
})
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(
|
||||
{
|
||||
id: this.options.id,
|
||||
name: this.name,
|
||||
points: newPoints,
|
||||
repeat: this.repeat+''
|
||||
}
|
||||
)
|
||||
})
|
||||
this._DialogObject.footAppChild(addListBtn)
|
||||
|
||||
let endBtn = contentElm.getElementsByClassName('cease')[0]
|
||||
endBtn.addEventListener('click', () => {
|
||||
viewer.camera.cancelFlight()
|
||||
})
|
||||
|
||||
let flyBtn = contentElm.getElementsByClassName('afreshPlay')[0]
|
||||
flyBtn.addEventListener('click', () => {
|
||||
if (points.length > 0) {
|
||||
this.flyTo(0)
|
||||
}
|
||||
})
|
||||
|
||||
let addBtn = contentElm.getElementsByClassName('add-point')[0]
|
||||
addBtn.addEventListener('click', () => {
|
||||
let position = this.cartesian3Towgs84(viewer.camera.position, viewer)
|
||||
let time = 0
|
||||
let data = {
|
||||
duration: time,
|
||||
position: position,
|
||||
orientation: {
|
||||
heading: viewer.camera.heading,
|
||||
pitch: viewer.camera.pitch,
|
||||
roll: viewer.camera.roll
|
||||
}
|
||||
}
|
||||
points.splice(active, 0, data)
|
||||
this.options.points.splice(active, 0, data)
|
||||
addTrElm(data)
|
||||
i++
|
||||
})
|
||||
let modifyBtn = contentElm.getElementsByClassName('modify-point')[0]
|
||||
modifyBtn.addEventListener('click', () => {
|
||||
if (!active) {
|
||||
return
|
||||
}
|
||||
let position = this.cartesian3Towgs84(viewer.camera.position, viewer)
|
||||
this.options.points[active - 1].position = points[active - 1].position = position
|
||||
this.options.points[active - 1].orientation = points[active - 1].orientation = {
|
||||
heading: viewer.camera.heading,
|
||||
pitch: viewer.camera.pitch,
|
||||
roll: viewer.camera.roll
|
||||
}
|
||||
this.message({text: '操作成功'})
|
||||
})
|
||||
|
||||
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 time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2))
|
||||
for (let i = 0; i < trList.length - 1; i++) {
|
||||
points[i].duration = time
|
||||
this.options.points[i].duration = time
|
||||
trList[i].querySelector("input[name='time']").value = time
|
||||
}
|
||||
trList[trList.length - 1].querySelector("input[name='time']").value = 0
|
||||
}
|
||||
})
|
||||
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
|
||||
this.options.points[i].duration = time
|
||||
trList[i].querySelector("input[name='time']").value = time
|
||||
}
|
||||
trList[trList.length - 1].querySelector("input[name='time']").value = 0
|
||||
}
|
||||
})
|
||||
repeatElm.checked = (this.repeat === Infinity ? true : false)
|
||||
repeatElm.addEventListener('change', () => {
|
||||
if (repeatElm.checked) {
|
||||
this.repeat = Infinity
|
||||
}
|
||||
else {
|
||||
this.repeat = 0
|
||||
}
|
||||
})
|
||||
|
||||
// Object.defineProperty(options, 'points', {
|
||||
// get() {
|
||||
// return e_allArea.value
|
||||
// },
|
||||
// set(value) {
|
||||
// e_allArea.value = value
|
||||
// }
|
||||
// })
|
||||
|
||||
function addTrElm(data) {
|
||||
let trList = tableBody.getElementsByClassName('tr')
|
||||
if (trList.length > 0) {
|
||||
trList[trList.length - 1].querySelector("input[name='time']").disabled = undefined
|
||||
}
|
||||
let tr_active = tableBody.getElementsByClassName('tr active')[0]
|
||||
tr_active && (tr_active.className = 'tr')
|
||||
let tr = document.createElement('div');
|
||||
tr.className = 'tr active'
|
||||
tr.innerHTML = `
|
||||
<div class="td" style="justify-content: center;">视点${i + 1}</div>
|
||||
<div class="td">
|
||||
<input class="input time" type="number" title="" min="0" max="999.99" step="0.01" name="time" value="${data.duration}">
|
||||
</div>
|
||||
<div class="td action">
|
||||
<button class="play">播放</span>
|
||||
<button class="delete">删除</span>
|
||||
</div>
|
||||
`
|
||||
tr.addEventListener('click', (v) => {
|
||||
if (v.target.parentNode === tr) {
|
||||
let tr_active = tableBody.getElementsByClassName('tr active')[0]
|
||||
tr_active && (tr_active.className = 'tr')
|
||||
tr.className = 'tr active'
|
||||
for (let m = 0; m < trList.length; m++) {
|
||||
if (trList[m] === tr) {
|
||||
active = m + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
tr.addEventListener('dblclick', (v) => {
|
||||
if (v.target.parentNode === tr) {
|
||||
for (let m = 0; m < trList.length; m++) {
|
||||
if (trList[m] === tr) {
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(points[m].position.lng, points[m].position.lat, points[m].position.alt),
|
||||
orientation: points[m].orientation,
|
||||
duration: 1
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
let e_play = tr.getElementsByClassName('play')[0]
|
||||
let e_delete = tr.getElementsByClassName('delete')[0]
|
||||
let e_time = tr.querySelector("input[name='time']")
|
||||
e_play.addEventListener('click', () => {
|
||||
for (let m = 0; m < trList.length; m++) {
|
||||
if (trList[m] === e_delete.parentNode.parentNode) {
|
||||
_this.flyTo(m)
|
||||
}
|
||||
}
|
||||
})
|
||||
e_delete.addEventListener("click", (v) => {
|
||||
for (let m = 0; m < trList.length; m++) {
|
||||
if (trList[m] === e_delete.parentNode.parentNode) {
|
||||
points.splice(m, 1)
|
||||
points[points.length-1].duration = 0
|
||||
_this.options.points.splice(m, 1)
|
||||
tableBody.removeChild(tr)
|
||||
if (active > m + 1) {
|
||||
active--
|
||||
trList[active - 1].className = 'tr active'
|
||||
}
|
||||
else if (active == m + 1) {
|
||||
if (trList.length == m) {
|
||||
active -= 1
|
||||
}
|
||||
if (trList.length != 0) {
|
||||
trList[active - 1].className = 'tr active'
|
||||
}
|
||||
}
|
||||
// else if(active == m) {
|
||||
// console.log(trList.length-1, active)
|
||||
// if (trList.length == active-1) {
|
||||
// trList[active-2].className = 'tr active'
|
||||
// }
|
||||
// else {
|
||||
// trList[active-1].className = 'tr active'
|
||||
// }
|
||||
// }
|
||||
if (trList.length > 0) {
|
||||
let lastElm = trList[trList.length - 1].querySelector("input[name='time']")
|
||||
lastElm.disabled = 'disabled'
|
||||
lastElm.value = 0
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
// points.splice(i, 1)
|
||||
// tableBody.removeChild(tr)
|
||||
// if (trList.length > 0) {
|
||||
// trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled'
|
||||
// }
|
||||
})
|
||||
e_time.addEventListener('input', (v) => {
|
||||
isTotalTimeElm.checked = false
|
||||
data.duration = Number(e_time.value)
|
||||
if (data.duration < 0) {
|
||||
data.duration = 0
|
||||
}
|
||||
})
|
||||
e_time.addEventListener('blur', () => {
|
||||
e_time.value = Number(Number(e_time.value).toFixed(2))
|
||||
if (e_time.value < 0) {
|
||||
e_time.value = 0
|
||||
}
|
||||
});
|
||||
tableBody.insertBefore(tr, trList[active])
|
||||
active++
|
||||
trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flyTo(i = 0) {
|
||||
setActiveViewer(0)
|
||||
let _this = this
|
||||
let points = this.options.points
|
||||
let currentRepeat = this.repeat
|
||||
|
||||
closeRotateAround(_this.sdk)
|
||||
const executeFlyTo = (index = 0, noStart) => {
|
||||
if (this.#clickHandler) {
|
||||
this.#clickHandler.destroy()
|
||||
}
|
||||
let _this = this
|
||||
this.#clickHandler = new Cesium.ScreenSpaceEventHandler(_this.sdk.viewer.canvas)
|
||||
this.#clickHandler.setInputAction((movement) => {
|
||||
this.cease()
|
||||
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
||||
let viewer = _this.sdk.viewer
|
||||
setActiveViewer(0)
|
||||
viewer.camera.cancelFlight()
|
||||
// function pauseExecution(seconds) {
|
||||
// return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
||||
// }
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(points[index].position.lng, points[index].position.lat, points[index].position.alt),
|
||||
orientation: points[index].orientation,
|
||||
duration: noStart ? points[index - 1].duration : 0.5,
|
||||
maximumHeight: points[index].position.alt,
|
||||
complete: async () => {
|
||||
// if (!noStart) {
|
||||
// // await pauseExecution(2)
|
||||
// }
|
||||
index++
|
||||
|
||||
if (this.repeat === Infinity) {
|
||||
currentRepeat = Infinity
|
||||
}
|
||||
else if (currentRepeat === Infinity) {
|
||||
currentRepeat = this.repeat
|
||||
}
|
||||
if (index <= points.length - 1) {
|
||||
executeFlyTo(index, true)
|
||||
}
|
||||
else if (currentRepeat) {
|
||||
currentRepeat--
|
||||
executeFlyTo(0)
|
||||
}
|
||||
else {
|
||||
if (this.#clickHandler) {
|
||||
this.#clickHandler.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
easingFunction: noStart ? Cesium.EasingFunction.LINEAR_NONE : Cesium.EasingFunction.EXPONENTIAL_OUT
|
||||
})
|
||||
}
|
||||
|
||||
executeFlyTo(i)
|
||||
|
||||
}
|
||||
|
||||
/** 停止 */
|
||||
cease() {
|
||||
this.sdk && this.sdk.viewer && this.sdk.viewer.camera.cancelFlight()
|
||||
if (this.#clickHandler) {
|
||||
this.#clickHandler.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
else {
|
||||
this.cease()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export default FlyRoam
|
||||
216
src/Obj/Base/GeoJson/index.js
Normal file
216
src/Obj/Base/GeoJson/index.js
Normal file
@ -0,0 +1,216 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-03-04 10:39
|
||||
* @description:index
|
||||
* @update: 2023-03-04 10:39
|
||||
*/
|
||||
import { getHost, getToken } from "../../../on";
|
||||
import Base from '../index'
|
||||
import Tools from '../../../Tools'
|
||||
import { syncSplitData } from "../../../Global/SplitScreen";
|
||||
import { syncData, getSdk as get2DSdk } from '../../../Global/MultiViewportMode'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
class GeoJson extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @param options {object} 参数
|
||||
* @param options.id {string} id
|
||||
* @param options.url {string} geojson地址
|
||||
* @param [options.color=#ef0606] {string} 线条颜色
|
||||
* @param [options.width=1] {number} 线条宽度
|
||||
* @example new YJ.Obj.GeoJson(earth,{id:"123",url:""})
|
||||
* */
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
|
||||
this.primitive = undefined
|
||||
this.positions = []
|
||||
|
||||
|
||||
this.loading = true
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue()
|
||||
this.options.host = this.options.host || getHost()
|
||||
// let url = this.options.url
|
||||
// if (this.options.host) {
|
||||
// let o = new URL(this.options.url, this.options.host)
|
||||
// url = o.href
|
||||
// }
|
||||
|
||||
// this.options.url = url
|
||||
this.options.color = this.options.color || 'rgb(239, 6, 6, 1)'
|
||||
this.options.width = this.options.width || 1
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
// set show(status) {
|
||||
// let sdkD = get2DSdk().sdkD
|
||||
// if (!this.isShowView || !sdkD) {
|
||||
// this.options.show = status
|
||||
// }
|
||||
// if (this.entity) {
|
||||
// if (!this.showView || this.showView == 3 || !sdkD) {
|
||||
// for (let i = 0; i < this.entity.entities.values.length; i++) {
|
||||
// this.entity.entities.values[i].show = this.options.show
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// for (let i = 0; i < this.entity.entities.values.length; i++) {
|
||||
// this.entity.entities.values[i].show = false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// syncData(this.sdk, this.options.id)
|
||||
// syncSplitData(this.sdk, this.options.id)
|
||||
// this.isShowView = false
|
||||
// }
|
||||
set show(status) {
|
||||
this.options.show = status
|
||||
if (this.entity) {
|
||||
for (let i = 0; i < this.entity.entities.values.length; i++) {
|
||||
this.entity.entities.values[i].show = status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async on() {
|
||||
let url = ""
|
||||
if (this.options.host.endsWith("yjearth4.0"))
|
||||
url = this.options.host + '/data/service/getFile'
|
||||
else
|
||||
url = this.options.host + '/yjearth4.0/data/service/getFile'
|
||||
url = url + '?path=' + encodeURIComponent(this.options.url)
|
||||
let rsp = await fetch(url, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"token": getToken(),
|
||||
"Authorization": "Bearer " + getToken(),
|
||||
}
|
||||
})
|
||||
let json = await rsp.json()
|
||||
this.geojson = json
|
||||
// this.sdk.addIncetance(this.options.id, this)
|
||||
return GeoJson.addDataToGlobe(this, json.features)
|
||||
}
|
||||
|
||||
/*geojosn暂时只用线的形式*/
|
||||
static addDataToGlobe(that) {
|
||||
const geoJsonDataSource = new Cesium.GeoJsonDataSource();
|
||||
let geojson = that.deepCopyObj(that.geojson)
|
||||
for (let i = 0; i < geojson.features.length; i++) {
|
||||
if (!geojson.features[i].id) {
|
||||
geojson.features[i].id = that.options.id + '_' + i
|
||||
}
|
||||
}
|
||||
// console.log(geojson)
|
||||
let promise = geoJsonDataSource.load(geojson, {
|
||||
clampToGround: true,
|
||||
});
|
||||
return promise.then(datasource => {
|
||||
that.entity = datasource
|
||||
datasource.entities.values.forEach(enetity => {
|
||||
// console.log(enetity)
|
||||
let color = Cesium.Color.fromCssColorString(that.options.color)
|
||||
let colorPolygon = color.withAlpha(0.2)
|
||||
enetity.show = that.options.show
|
||||
that.sdk.viewer.entities.add(enetity)
|
||||
if (enetity.billboard) {
|
||||
enetity.billboard.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
enetity.point = new Cesium.PointGraphics({
|
||||
show: true,
|
||||
color: color, // 点的颜色
|
||||
pixelSize: 10, // 点的大小
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY // 不应用深度测试
|
||||
})
|
||||
}
|
||||
|
||||
if (enetity.polyline) {
|
||||
enetity.polyline.material = color
|
||||
enetity.polyline.zIndex = that.sdk._entityZIndex
|
||||
that.sdk._entityZIndex++
|
||||
}
|
||||
|
||||
if (enetity.polygon) {
|
||||
enetity.polygon.perPositionHeight = false
|
||||
enetity.polygon.material = colorPolygon
|
||||
enetity.polygon.zIndex = that.sdk._entityZIndex
|
||||
|
||||
enetity.polyline = new Cesium.PolylineGraphics({
|
||||
positions: enetity.polygon.hierarchy._value.positions,
|
||||
width: 1,
|
||||
clampToGround: true,
|
||||
material: color,
|
||||
zIndex: that.sdk._entityZIndex
|
||||
})
|
||||
that.sdk._entityZIndex++
|
||||
}
|
||||
})
|
||||
that.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (this.entity) {
|
||||
this.entity.entities.values.forEach(enetity => {
|
||||
this.sdk.viewer.entities.remove(enetity)
|
||||
})
|
||||
this.entity = null
|
||||
this.geojson = {}
|
||||
}
|
||||
}
|
||||
|
||||
async flyTo() {
|
||||
if (!this.loading) {
|
||||
if (this.geojson) {
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
let range = turf.bbox(this.geojson);
|
||||
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: range[0], lat: range[1] }
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
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 {
|
||||
this.viewer.camera.flyTo({
|
||||
destination: Cesium.Rectangle.fromDegrees(...range)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default GeoJson
|
||||
145
src/Obj/Base/GeoJson/index2.js
Normal file
145
src/Obj/Base/GeoJson/index2.js
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-03-04 10:39
|
||||
* @description:index
|
||||
* @update: 2023-03-04 10:39
|
||||
*/
|
||||
import { getHost } from "../../../on";
|
||||
import Base from '../index'
|
||||
import Tools from '../../../Tools'
|
||||
|
||||
class GeoJson extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @param options {object} 参数
|
||||
* @param options.id {string} id
|
||||
* @param options.url {string} geojson地址
|
||||
* @param [options.color=#ef0606] {string} 线条颜色
|
||||
* @param [options.width=1] {number} 线条宽度
|
||||
* @example new YJ.Obj.GeoJson(earth,{id:"123",url:""})
|
||||
* */
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
|
||||
this.primitive = undefined
|
||||
this.positions = []
|
||||
|
||||
this.loading = true
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue()
|
||||
this.options.host = this.options.host || getHost()
|
||||
let url = this.options.url
|
||||
if(this.options.host) {
|
||||
let o = new URL(this.options.url, this.options.host)
|
||||
url = o.href
|
||||
}
|
||||
|
||||
this.options.url = url
|
||||
this.options.color = this.options.color || '#ef0606'
|
||||
this.options.width = this.options.width || 1
|
||||
}
|
||||
|
||||
get show() {
|
||||
if (this.primitive) return this.primitive.show
|
||||
return undefined
|
||||
}
|
||||
|
||||
set show(status) {
|
||||
if (this.primitive) {
|
||||
this.primitive.show = status
|
||||
}
|
||||
}
|
||||
|
||||
async on() {
|
||||
let rsp = await fetch(this.options.url)
|
||||
let json = await rsp.json()
|
||||
return GeoJson.addDataToGlobe(this, json.features)
|
||||
}
|
||||
|
||||
/*geojosn暂时只用线的形式*/
|
||||
static addDataToGlobe(that, features) {
|
||||
const instances = []
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let positions = []
|
||||
if ('LineString' === features[i].geometry.type) {
|
||||
features[i].geometry.coordinates.forEach(c => {
|
||||
that.positions.push({ lng: c[0], lat: c[1] })
|
||||
positions.push(c[0], c[1])
|
||||
})
|
||||
}
|
||||
if ('Polygon' === features[i].geometry.type) {
|
||||
features[i].geometry.coordinates.forEach(polygon => {
|
||||
polygon.forEach(c => {
|
||||
that.positions.push({ lng: c[0], lat: c[1] })
|
||||
positions.push(c[0], c[1])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const polyline = new Cesium.GroundPolylineGeometry({
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(positions),
|
||||
width: that.options.width //线宽
|
||||
// vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT
|
||||
})
|
||||
// let geometry = Cesium.PolylineGeometry.createGeometry(polyline)
|
||||
instances.push(
|
||||
new Cesium.GeometryInstance({
|
||||
geometry: polyline
|
||||
// attributes: {
|
||||
// color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE),
|
||||
// },
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
that.primitive = new Cesium.GroundPolylinePrimitive({
|
||||
geometryInstances: instances,
|
||||
// appearance: new Cesium.PerInstanceColorAppearance({ // 为每个instance着色
|
||||
// translucent: true,
|
||||
// closed: false
|
||||
// }),
|
||||
appearance: new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType('Color', {
|
||||
color: Cesium.Color.fromCssColorString(that.options.color)
|
||||
})
|
||||
}),
|
||||
asynchronous: false, // 确定基元是异步创建还是阻塞直到准备就绪
|
||||
show: that.options.show ?? true
|
||||
})
|
||||
that.viewer.scene.primitives.add(that.primitive)
|
||||
that.loading = false
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (this.primitive) {
|
||||
super.remove()
|
||||
this.viewer.scene.primitives.remove(this.primitive)
|
||||
this.primitive = null
|
||||
}
|
||||
}
|
||||
|
||||
flyTo() {
|
||||
if (!this.loading) {
|
||||
if (this.positions) {
|
||||
let arr = new Tools().cal_envelope(this.positions)
|
||||
var rectangle = new Cesium.Rectangle.fromDegrees(
|
||||
arr[0][0],
|
||||
arr[0][1],
|
||||
arr[2][0],
|
||||
arr[2][1]
|
||||
)
|
||||
this.viewer.camera.flyTo({
|
||||
destination: rectangle
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flicker() {}
|
||||
}
|
||||
|
||||
export default GeoJson
|
||||
185
src/Obj/Base/GeoJson/index3.js
Normal file
185
src/Obj/Base/GeoJson/index3.js
Normal file
@ -0,0 +1,185 @@
|
||||
/**
|
||||
* @name: index
|
||||
* @author: Administrator
|
||||
* @date: 2023-03-04 10:39
|
||||
* @description:index
|
||||
* @update: 2023-03-04 10:39
|
||||
*/
|
||||
import { getHost } from "../../../on";
|
||||
import Base from '../index'
|
||||
import Tools from '../../../Tools'
|
||||
|
||||
class GeoJson extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @param options {object} 参数
|
||||
* @param options.id {string} id
|
||||
* @param options.url {string} geojson地址
|
||||
* @param [options.color=#ef0606] {string} 线条颜色
|
||||
* @param [options.width=1] {number} 线条宽度
|
||||
* @example new YJ.Obj.GeoJson(earth,{id:"123",url:""})
|
||||
* */
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
|
||||
this.primitive = undefined
|
||||
this.positions = []
|
||||
|
||||
this.loading = true
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
super.setDefaultValue()
|
||||
this.options.host = this.options.host || getHost()
|
||||
let url = this.options.url
|
||||
if (this.options.host) {
|
||||
let o = new URL(this.options.url, this.options.host)
|
||||
url = o.href
|
||||
}
|
||||
|
||||
this.options.url = url
|
||||
this.options.color = this.options.color || 'rgb(239, 6, 6, 0.2)'
|
||||
this.options.width = this.options.width || 1
|
||||
}
|
||||
|
||||
get show() {
|
||||
if (this.primitive) return this.primitive.show
|
||||
return undefined
|
||||
}
|
||||
|
||||
set show(status) {
|
||||
if (this.primitive) {
|
||||
this.primitive.show = status
|
||||
}
|
||||
}
|
||||
|
||||
async on() {
|
||||
let rsp = await fetch(this.options.url)
|
||||
let json = await rsp.json()
|
||||
this.geojson = json
|
||||
return GeoJson.addDataToGlobe(this, json.features)
|
||||
}
|
||||
|
||||
/*geojosn暂时只用线的形式*/
|
||||
static addDataToGlobe(that, features) {
|
||||
const instancesList = []
|
||||
const instancesPolygon = []
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let color = Cesium.Color.fromRandom().withAlpha(0.2)
|
||||
if(features[i].geometry.type === 'LineString' || features[i].geometry.type === 'MultiLineString') {
|
||||
let coordinates = features[i].geometry.coordinates
|
||||
if(features[i].geometry.type === 'LineString') {
|
||||
coordinates = [features[i].geometry.coordinates]
|
||||
}
|
||||
for (let m = 0; m < coordinates.length; m++) {
|
||||
let item = coordinates[i]
|
||||
let positions = []
|
||||
item.forEach(c => {
|
||||
positions.push(c[0], c[1])
|
||||
})
|
||||
const polyline = new Cesium.GroundPolylineGeometry({
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(positions),
|
||||
width: that.options.width //线宽
|
||||
})
|
||||
instancesList.push(
|
||||
new Cesium.GeometryInstance({
|
||||
geometry: polyline
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if(features[i].geometry.type === 'Polygon' || features[i].geometry.type === 'MultiPolygon') {
|
||||
let coordinates = features[i].geometry.coordinates
|
||||
if(features[i].geometry.type === 'Polygon') {
|
||||
coordinates = [features[i].geometry.coordinates]
|
||||
}
|
||||
for (let m = 0; m < coordinates.length; m++) {
|
||||
let item = coordinates[m]
|
||||
item.forEach(p => {
|
||||
let positions = []
|
||||
p.forEach(c => {
|
||||
positions.push(c[0], c[1])
|
||||
})
|
||||
let polygon = new Cesium.PolygonGeometry({
|
||||
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(positions)),
|
||||
});
|
||||
instancesPolygon.push(
|
||||
new Cesium.GeometryInstance({
|
||||
geometry: polygon,
|
||||
attributes: {
|
||||
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||
Cesium.Color.fromRandom().withAlpha(0.2)
|
||||
),
|
||||
show: new Cesium.ShowGeometryInstanceAttribute(that.options.show ?? true), //显示或者隐藏
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
const polyline = new Cesium.GroundPolylineGeometry({
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(positions),
|
||||
width: 2
|
||||
})
|
||||
instancesList.push(
|
||||
new Cesium.GeometryInstance({
|
||||
geometry: polyline
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instancesList.length > 0) {
|
||||
that.primitive = new Cesium.GroundPolylinePrimitive({
|
||||
geometryInstances: instancesList,
|
||||
appearance: new Cesium.PolylineMaterialAppearance({
|
||||
material: Cesium.Material.fromType('Color', {
|
||||
color: Cesium.Color.fromCssColorString(that.options.color)
|
||||
})
|
||||
}),
|
||||
asynchronous: false, // 确定基元是异步创建还是阻塞直到准备就绪
|
||||
show: that.options.show ?? true
|
||||
})
|
||||
that.viewer.scene.primitives.add(that.primitive)
|
||||
}
|
||||
if (instancesPolygon.length > 0) {
|
||||
that.primitive = new Cesium.GroundPrimitive({
|
||||
geometryInstances: instancesPolygon,
|
||||
appearance: new Cesium.PerInstanceColorAppearance({
|
||||
translucent: true, //false时透明度无效
|
||||
closed: false,
|
||||
}),
|
||||
asynchronous: false, // 确定基元是异步创建还是阻塞直到准备就绪
|
||||
show: that.options.show ?? true
|
||||
})
|
||||
that.viewer.scene.primitives.add(that.primitive)
|
||||
}
|
||||
|
||||
that.loading = false
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (this.primitive) {
|
||||
super.remove()
|
||||
this.viewer.scene.primitives.remove(this.primitive)
|
||||
this.primitive = null
|
||||
}
|
||||
}
|
||||
|
||||
flyTo() {
|
||||
if (!this.loading) {
|
||||
if(this.geojson) {
|
||||
let range = turf.bbox(this.geojson);
|
||||
this.viewer.camera.flyTo({
|
||||
destination: Cesium.Rectangle.fromDegrees(...range)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default GeoJson
|
||||
22
src/Obj/Base/Graffiti/_element.js
Normal file
22
src/Obj/Base/Graffiti/_element.js
Normal file
@ -0,0 +1,22 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">涂鸦颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">线条宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="1" max="99" step="1" @model="width">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
export { html }
|
||||
227
src/Obj/Base/Graffiti/index.js
Normal file
227
src/Obj/Base/Graffiti/index.js
Normal file
@ -0,0 +1,227 @@
|
||||
/**
|
||||
* 涂鸦
|
||||
*/
|
||||
import Draw from '../../../Draw/draw'
|
||||
import MouseTip from '../../../MouseTip'
|
||||
import MouseEvent from '../../../Event'
|
||||
import Dialog from '../../../BaseDialog';
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import { html } from "./_element";
|
||||
import { CameraController } from '../../../Global/global'
|
||||
|
||||
class Graffiti extends Draw {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 涂鸦
|
||||
* @param options {object} 线属性
|
||||
* @param options.width=10{number} 宽度
|
||||
* @param options.color=#ff0000{string} 宽度
|
||||
* */
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options);
|
||||
this.options.width = options.width || 1
|
||||
this.options.color = options.color || '#ff0000'
|
||||
this._elms = {};
|
||||
this._EventBinding = new EventBinding()
|
||||
Graffiti.edit(this, true)
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
if(!this.options.color) {
|
||||
return
|
||||
}
|
||||
this.options.color = v
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let colorPicker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.color = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get width() {
|
||||
return this.options.width
|
||||
}
|
||||
set width(v) {
|
||||
this.options.width = v
|
||||
this._elms.width && this._elms.width.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
static async edit(that, state) {
|
||||
if (state) {
|
||||
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||
title: '涂鸦参数',
|
||||
})
|
||||
await that._DialogObject.init()
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
that._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let colorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: that.color,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
that.color = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
that.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' graffiti'
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
that._EventBinding.on(that, all_elm)
|
||||
that._elms = that._EventBinding.element
|
||||
that._elms.color = [colorPicker]
|
||||
|
||||
let confirmBtn = document.createElement('button');
|
||||
confirmBtn.className = 'confirm';
|
||||
confirmBtn.innerHTML = '确认'
|
||||
that._DialogObject.footAppChild(confirmBtn)
|
||||
confirmBtn.addEventListener('click', () => {
|
||||
that.start()
|
||||
Graffiti.edit(that, false)
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (that._DialogObject && that._DialogObject.close) {
|
||||
that._DialogObject.close()
|
||||
that._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 开始动态获绘制线
|
||||
* @method start
|
||||
* })
|
||||
* */
|
||||
start() {
|
||||
let _this = this
|
||||
if (YJ.Measure.GetMeasureStatus()) {
|
||||
console.log('上一次测量未结束')
|
||||
} else {
|
||||
let viewer = this.sdk.viewer
|
||||
CameraController(this.sdk, false)
|
||||
super.start()
|
||||
YJ.Measure.SetMeasureStatus(true)
|
||||
this.tip = new MouseTip('长按左键,拖动鼠标进行涂鸦,右键结束涂鸦', this.sdk)
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.positions = []
|
||||
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||
let polylineArray = []
|
||||
let positions = []
|
||||
|
||||
this.event.mouse_left_down((movement, cartesian) => {
|
||||
positions = []
|
||||
let line = this.sdk.viewer.entities.add({
|
||||
name: '涂鸦',
|
||||
polyline: {
|
||||
positions: new Cesium.CallbackProperty(function () {
|
||||
return positions
|
||||
}, false),
|
||||
width: this.width,
|
||||
clampToGround: true,
|
||||
material: Cesium.Color.fromCssColorString(this.color),
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
polylineArray.push(line)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
positions.push(cartesian)
|
||||
})
|
||||
})
|
||||
this.event.mouse_left_up((movement, cartesian) => {
|
||||
polylineArray[polylineArray.length-1].polyline.positions = positions
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
})
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.end()
|
||||
})
|
||||
|
||||
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.end()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 结束制线
|
||||
* @method end
|
||||
* })
|
||||
* */
|
||||
end() {
|
||||
YJ.Measure.SetMeasureStatus(false)
|
||||
this.event && this.event.destroy()
|
||||
this.event = undefined
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = undefined
|
||||
CameraController(this.sdk, true)
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.end()
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
let entities = this.sdk.viewer.entities.values
|
||||
for (let i = entities.length - 1; i >= 0; i--) {
|
||||
if (entities[i].name === '涂鸦') {
|
||||
this.sdk.viewer.entities.remove(entities[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flicker() {}
|
||||
}
|
||||
|
||||
export default Graffiti
|
||||
119
src/Obj/Base/GroundImage/_element.js
Normal file
119
src/Obj/Base/GroundImage/_element.js
Normal file
@ -0,0 +1,119 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="anchor btn">调整锚点</button>
|
||||
</div>
|
||||
<div class="col mode-box">
|
||||
<span class="label" style="flex: unset;">军标模式</span>
|
||||
<div class="mode"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" mode="0">
|
||||
<div class="col">
|
||||
<span class="label">旋转角度</span>
|
||||
<input type="range" max="360" min="0" step="0.1" @model="angle">
|
||||
<div class="input-number input-number-unit" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="360" step="0.1" @model="angle">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" mode="0">
|
||||
<div class="col">
|
||||
<span class="label">调整大小</span>
|
||||
<input type="range" max="40000" min="0" step="0.1" @model="scale">
|
||||
<div class="input-number input-number-unit-1" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="40000" step="0.1" @model="scale">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" mode="1">
|
||||
<div class="col height-mode-box" style="flex: 0 0 155px;margin-right: 10px;">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0 10px;">
|
||||
<div class="height-box" style="display: flex; align-items: center;">
|
||||
<span class="label" style="flex: 0 0 56px;">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="margin-left: 10px;">
|
||||
<span class="label">图标倍数</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" data-min="0.1" max="99" @model="billboardScale">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" mode="1">
|
||||
<div class="col" style="flex: 0 0 155px;margin-right: 10px;">
|
||||
<span class="label">视野缩放</span>
|
||||
<input class="btn-switch" type="checkbox" @model="billboardScaleByDistance">
|
||||
</div>
|
||||
<div class="col" style="margin: 0 10px;">
|
||||
<span class="label">最近距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="billboardNear">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="margin-left: 10px;">
|
||||
<span class="label">最远距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="billboardFar">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 mode="1">文字设置</h4>
|
||||
<div class="row" mode="1">
|
||||
<div class="col" style="flex: 0 0 80px;margin: 0 10px;">
|
||||
<span class="label" style="flex: none;">显隐</span>
|
||||
<input class="btn-switch" type="checkbox" @model="labelShow">
|
||||
</div>
|
||||
<div class="col font-select-box" style="margin: 0 0px;flex: 0 0 150px;">
|
||||
<span class="label" style="flex: none;">字体选择</span>
|
||||
<div class="input input-select font-select"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0 10px;">
|
||||
<span class="label">文字大小</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="1" max="99" @model="labelFontSize" style="width: 70px;">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="margin-left: 10px;">
|
||||
<span class="label">文字颜色</span>
|
||||
<div class="labelColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
1979
src/Obj/Base/GroundImage/index.js
Normal file
1979
src/Obj/Base/GroundImage/index.js
Normal file
File diff suppressed because it is too large
Load Diff
113
src/Obj/Base/GroundSvg/_element.js
Normal file
113
src/Obj/Base/GroundSvg/_element.js
Normal file
@ -0,0 +1,113 @@
|
||||
import { attributeElm } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">旋转角度</span>
|
||||
<input type="range" max="360" min="0" step="0.1" @model="angle">
|
||||
<div class="input-number input-number-unit" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="360" step="0.1" @model="angle">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col x-scale">
|
||||
<span class="label">X 轴大小</span>
|
||||
<input type="range" max="200" min="0.001" step="0.001">
|
||||
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0.001" max="200" step="0.001">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col y-scale">
|
||||
<span class="label">Y 轴大小</span>
|
||||
<input type="range" max="200" min="0.001" step="0.001">
|
||||
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0.001" max="200" step="0.001">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 5;">
|
||||
<span class="label">文字内容</span>
|
||||
<input class="input" type="text" @model="textValue" maxlength="30">
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="btn" @click="textPosPick">设置位置</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">文字开关</span>
|
||||
<input class="btn-switch" type="checkbox" @model="textShow">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">字体颜色</span>
|
||||
<div class="textColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">字体大小</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="1" max="99" @model="textFontSize">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">视野缩放</span>
|
||||
<input class="btn-switch" type="checkbox" @model="textScaleByDistance">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最近距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="textNear">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最远距离</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" @model="textFar">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item attribute-info">
|
||||
<div class="row">
|
||||
${attributeElm(that)}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
792
src/Obj/Base/GroundSvg/index-2.js
Normal file
792
src/Obj/Base/GroundSvg/index-2.js
Normal file
@ -0,0 +1,792 @@
|
||||
import Base from "../index";
|
||||
import * as THREE from '../../../../static/3rdparty/three/three.module.min.js';
|
||||
import { SVGLoader } from '../../../../static/3rdparty/three/jsm/loaders/SVGLoader.js';
|
||||
|
||||
// 合并图形,统一颜色
|
||||
class GroundSvg extends Base {
|
||||
#loadEvent=void 0
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options);
|
||||
this.options.angle = this.options.angle || 0
|
||||
this.options.color = this.options.color || '#ff0000'
|
||||
|
||||
this.loaded = false;
|
||||
|
||||
if (this.options.position.lat > 83.5) {
|
||||
this.options.position.lat = 83.5
|
||||
}
|
||||
if (this.options.position.lat < -83.5) {
|
||||
this.options.position.lat = -83.5
|
||||
}
|
||||
|
||||
this.hierarchys = []
|
||||
|
||||
this.options.scale = options.scale || {}
|
||||
this.options.scale.x = (this.options.scale.x || this.options.scale.x === 0) ? this.options.scale.x : 1
|
||||
this.options.scale.y = (this.options.scale.y || this.options.scale.y === 0) ? this.options.scale.y : 1
|
||||
|
||||
this.init()
|
||||
}
|
||||
|
||||
get position() {
|
||||
return this.options.position
|
||||
}
|
||||
|
||||
set position(v) {
|
||||
this.options.position = v
|
||||
if (this.options.position.lat > 83.5) {
|
||||
this.options.position.lat = 83.5
|
||||
}
|
||||
if (this.options.position.lat < -83.5) {
|
||||
this.options.position.lat = -83.5
|
||||
}
|
||||
this.update()
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
for (let i = 0; i < this.entity.values.length; i++) {
|
||||
this.entity.values[i].polygon.material = Cesium.Color.fromCssColorString(this.options.color || '#ff0000')
|
||||
}
|
||||
}
|
||||
|
||||
get angle() {
|
||||
return this.options.angle
|
||||
}
|
||||
|
||||
set angle(v) {
|
||||
this.options.angle = v
|
||||
this.update()
|
||||
}
|
||||
|
||||
get scale() {
|
||||
return this.options.scale
|
||||
}
|
||||
|
||||
set scale(scale) {
|
||||
this.options.scale.x = scale.x
|
||||
this.options.scale.y = scale.y
|
||||
this.update()
|
||||
}
|
||||
|
||||
init() {
|
||||
this.hierarchys = []
|
||||
let geometryArray = []
|
||||
const loader = new SVGLoader();
|
||||
loader.load(this.options.url, (data) => {
|
||||
data.xml.style.width = '0'
|
||||
data.xml.style.height = '0'
|
||||
document.body.appendChild(data.xml)
|
||||
for (const path of data.paths) {
|
||||
const fillColor = path.userData.style.fill;
|
||||
let style = window.getComputedStyle(path.userData.node)
|
||||
if (style.strokeWidth) {
|
||||
path.userData.style.strokeWidth = Number(style.strokeWidth.replace(/[a-zA-Z]/g, ''))
|
||||
}
|
||||
if (fillColor !== undefined && fillColor !== 'none') {
|
||||
const shapes = SVGLoader.createShapes(path);
|
||||
for (const shape of shapes) {
|
||||
const geometry = new THREE.ShapeGeometry(shape);
|
||||
const mesh = new THREE.Mesh(geometry);
|
||||
geometryArray.push(mesh.geometry)
|
||||
}
|
||||
}
|
||||
const strokeColor = path.userData.style.stroke;
|
||||
if (strokeColor !== undefined && strokeColor !== 'none') {
|
||||
for (const subPath of path.subPaths) {
|
||||
const geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData.style);
|
||||
if (geometry) {
|
||||
const mesh = new THREE.Mesh(geometry);
|
||||
geometryArray.push(mesh.geometry)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
document.body.removeChild(data.xml)
|
||||
|
||||
let min = 0
|
||||
let max = 0
|
||||
let geojson
|
||||
for (let key = 0; key < geometryArray.length; key++) {
|
||||
let geometry = geometryArray[key];
|
||||
let array = geometry.attributes.position.array
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (min > array[i]) {
|
||||
min = array[i]
|
||||
}
|
||||
if (max < array[i]) {
|
||||
max = array[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
min = Math.abs(min)
|
||||
max = Math.abs(max)
|
||||
|
||||
if (min > max) {
|
||||
max = min
|
||||
}
|
||||
let max2 = max
|
||||
max = max * (10 / 3) * 100
|
||||
let scale = (4000 / max) / 5
|
||||
max2 = max2 * scale
|
||||
for (let key = 0; key < geometryArray.length; key++) {
|
||||
let positions = []
|
||||
let position = []
|
||||
geometryArray[key].scale(scale, scale, 1)
|
||||
|
||||
geometryArray[key].rotateX(THREE.MathUtils.degToRad(180))
|
||||
let geometry = geometryArray[key];
|
||||
let array = geometry.attributes.position.array
|
||||
|
||||
for (let i = 0; i < array.length; i += 3) {
|
||||
let x = array[i] - (max2 / 2)
|
||||
let y = array[i + 1] + (max2 / 2)
|
||||
position.push([x, y, array[i + 1]])
|
||||
}
|
||||
if (geometry.index && geometry.index.array) {
|
||||
let index = geometry.index.array
|
||||
for (let i = 0; i < index.length; i += 3) {
|
||||
positions.push([position[index[i]], position[index[i + 1]], position[index[i + 2]]])
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < position.length; i += 3) {
|
||||
positions.push([position[i], position[i + 1], position[i + 2]])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let polygons = []
|
||||
// 组合多边形
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let polygon = turf.polygon([[
|
||||
...positions[i],
|
||||
positions[i][0]
|
||||
]]);
|
||||
polygons.push(polygon)
|
||||
|
||||
if (geojson) {
|
||||
geojson = turf.union(geojson, polygon);
|
||||
}
|
||||
else {
|
||||
geojson = polygon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.geojson = JSON.parse(JSON.stringify(geojson))
|
||||
|
||||
// 计算边界框
|
||||
let bbox = turf.bbox(geojson);
|
||||
let width = Math.abs(bbox[2] - bbox[0])
|
||||
let height = Math.abs(bbox[3] - bbox[1])
|
||||
|
||||
// 获取最小正方形
|
||||
let square = turf.square(bbox);
|
||||
// 控制点界限
|
||||
square[0] = square[0] + this.options.position.lng - (width / 5)
|
||||
square[1] = square[1] + this.options.position.lat - (height / 5)
|
||||
square[2] = square[2] + this.options.position.lng + (width / 5)
|
||||
square[3] = square[3] + this.options.position.lat + (height / 5)
|
||||
|
||||
this.bbox = square
|
||||
|
||||
|
||||
|
||||
geojson = JSON.parse(JSON.stringify(this.geojson))
|
||||
|
||||
geojson.properties.directionDistance = []
|
||||
|
||||
|
||||
if (geojson.geometry.type === 'MultiPolygon') {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let array = []
|
||||
for (let m = 0; m < geojson.geometry.coordinates[i].length; m++) {
|
||||
let array2 = []
|
||||
for (let n = 0; n < geojson.geometry.coordinates[i][m].length; n++) {
|
||||
let point1 = turf.point([0, geojson.geometry.coordinates[i][m][n][1]])
|
||||
let point2 = turf.point([...geojson.geometry.coordinates[i][m][n]])
|
||||
let distance = turf.distance(point1, point2, { units: 'kilometers' });
|
||||
let angle = turf.rhumbBearing(point1, point2);
|
||||
array2.push(
|
||||
{
|
||||
origin: geojson.geometry.coordinates[i][m][n],
|
||||
distance: distance,
|
||||
angle: angle
|
||||
}
|
||||
)
|
||||
}
|
||||
array.push(array2)
|
||||
}
|
||||
geojson.properties.directionDistance.push(array)
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let array = []
|
||||
for (let m = 0; m < geojson.geometry.coordinates[i].length; m++) {
|
||||
let point1 = turf.point([0, geojson.geometry.coordinates[i][m][1]])
|
||||
let point2 = turf.point([...geojson.geometry.coordinates[i][m]])
|
||||
let distance = turf.distance(point1, point2, { units: 'kilometers' });
|
||||
let angle = turf.rhumbBearing(point1, point2);
|
||||
array.push(
|
||||
{
|
||||
origin: geojson.geometry.coordinates[i][m],
|
||||
distance: distance,
|
||||
angle: angle
|
||||
}
|
||||
)
|
||||
}
|
||||
geojson.properties.directionDistance.push(array)
|
||||
}
|
||||
}
|
||||
|
||||
if (geojson.geometry.type === 'MultiPolygon') {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let hierarchy = this.getHierarchyPolygon(geojson, i)
|
||||
this.hierarchys.push(hierarchy)
|
||||
}
|
||||
}
|
||||
else {
|
||||
let hierarchy = this.getHierarchyPolygon(geojson)
|
||||
this.hierarchys.push(hierarchy)
|
||||
}
|
||||
this.entity = new Cesium.EntityCollection()
|
||||
for (let i = 0; i < this.hierarchys.length; i++) {
|
||||
this.entity.add(this.sdk.viewer.entities.add({
|
||||
polygon: {
|
||||
hierarchy: new Cesium.CallbackProperty(() => {
|
||||
let hierarchy = this.hierarchys[i]
|
||||
let holes = []
|
||||
for (let m = 0; m < hierarchy.holes.length; m++) {
|
||||
holes.push({
|
||||
positions: hierarchy.holes[m]
|
||||
})
|
||||
}
|
||||
return {
|
||||
positions: hierarchy.positions,
|
||||
holes: holes
|
||||
}
|
||||
}, false),
|
||||
material: Cesium.Color.fromCssColorString(this.color),
|
||||
zIndex: 1
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
this.scale = this.scale
|
||||
|
||||
this.loaded = true
|
||||
if (this.#loadEvent) {
|
||||
this.#loadEvent()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
drag() {
|
||||
this.createControlPoints()
|
||||
this.update()
|
||||
}
|
||||
|
||||
getHierarchyPolygon(geojson, key) {
|
||||
let hierarchy = {}
|
||||
let holes = []
|
||||
let directionDistance = geojson.properties.directionDistance
|
||||
if (key !== undefined) {
|
||||
directionDistance = geojson.properties.directionDistance[key]
|
||||
}
|
||||
|
||||
for (let i = 0; i < directionDistance.length; i++) {
|
||||
let positions = []
|
||||
for (let m = 0; m < directionDistance[i].length; m++) {
|
||||
let lng = this.options.position.lng
|
||||
let lat = directionDistance[i][m].origin[1] + this.options.position.lat
|
||||
if (lat > 90) {
|
||||
lng += 180
|
||||
}
|
||||
let origin = [lng, lat]
|
||||
let pt = turf.point(origin);
|
||||
let destination = turf.rhumbDestination(pt, directionDistance[i][m].distance, directionDistance[i][m].angle, { units: 'kilometers' });
|
||||
positions.push(Cesium.Cartesian3.fromDegrees(...destination.geometry.coordinates))
|
||||
}
|
||||
if (i === 0) {
|
||||
|
||||
hierarchy.positions = positions
|
||||
}
|
||||
else {
|
||||
holes.push(positions)
|
||||
}
|
||||
}
|
||||
hierarchy.holes = holes
|
||||
return hierarchy
|
||||
}
|
||||
|
||||
createControlPoints() {
|
||||
if (this.ScreenSpaceEventHandler) {
|
||||
this.ScreenSpaceEventHandler.destroy()
|
||||
this.ScreenSpaceEventHandler = null
|
||||
}
|
||||
this.ScreenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(
|
||||
sdk.viewer.canvas
|
||||
)
|
||||
let width = Math.abs(this.bbox[0] - this.bbox[2])
|
||||
let height = Math.abs(this.bbox[1] - this.bbox[3])
|
||||
this.ScreenSpaceEventHandler.setInputAction(async (movement) => {
|
||||
if (this.pickPoint) {
|
||||
let sCartesian = this.pickPoint.position.getValue()
|
||||
let eCartesian = sdk.viewer.scene.pickPosition(movement.endPosition)
|
||||
if (!eCartesian) {
|
||||
const ray = sdk.viewer.camera.getPickRay(movement.endPosition);
|
||||
eCartesian = sdk.viewer.scene.globe.pick(ray, sdk.viewer.scene);
|
||||
}
|
||||
if (!sCartesian || !eCartesian) {
|
||||
return
|
||||
}
|
||||
let position1 = this.cartesian3Towgs84(sCartesian, sdk.viewer)
|
||||
let position2 = this.cartesian3Towgs84(eCartesian, sdk.viewer)
|
||||
let x = 0
|
||||
let y = 0
|
||||
|
||||
let radians, radiansW, radiansH
|
||||
|
||||
let w = 3.5 * this.scale.x
|
||||
let h = 3.5 * this.scale.y
|
||||
let wh = Math.sqrt(((w / 2) ** 2) + ((h / 2) ** 2))
|
||||
let angle = Math.atan((w / 2) / (h / 2)) * (180 / Math.PI)
|
||||
let angleW, angleH;
|
||||
|
||||
let point = turf.point([this.position.lng, this.position.lat]);
|
||||
let options = { units: 'kilometers' };
|
||||
let controlPoints = []
|
||||
controlPoints[0] = turf.destination(point, h / 2 * 1.5, 0 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[1] = turf.destination(point, wh, 180 + angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[2] = turf.destination(point, h / 2, 180 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[3] = turf.destination(point, wh, 180 - angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[4] = turf.destination(point, w / 2, 270 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[5] = [this.position.lng, this.position.lat]
|
||||
controlPoints[6] = turf.destination(point, w / 2, 90 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[7] = turf.destination(point, wh, 360 - angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[8] = turf.destination(point, h / 2, 0 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[9] = turf.destination(point, wh, 0 + angle + this.options.angle, options).geometry.coordinates
|
||||
|
||||
let point1 = turf.point([position1.lng, position1.lat]);
|
||||
let point2 = turf.point([position2.lng, position2.lat]);
|
||||
let pointC = turf.point([this.position.lng, this.position.lat]);
|
||||
let bearing1 = turf.rhumbBearing(pointC, point1);
|
||||
let bearing2_0 = turf.rhumbBearing(pointC, point2);
|
||||
let bearing2 = (((bearing2_0 + 360) - this.angle) % 360)
|
||||
let bearingH
|
||||
let bearingW
|
||||
// 中心点到鼠标的距离
|
||||
let distance = turf.rhumbDistance(pointC, point2, options);
|
||||
|
||||
switch (this.pickPoint.id) {
|
||||
case 'svg-control-points_0':
|
||||
angle = bearing2_0 - bearing1
|
||||
this.angle += angle
|
||||
break
|
||||
case 'svg-control-points_1':
|
||||
case 'svg-control-points_7':
|
||||
bearingW = (((turf.rhumbBearing(pointC, turf.point(controlPoints[4])) + 360) - this.angle) % 360)
|
||||
bearingH = (((turf.rhumbBearing(pointC, turf.point(controlPoints[2])) + 360) - this.angle) % 360)
|
||||
angleW = bearing2 - bearingW
|
||||
angleH = bearing2 - bearingH
|
||||
|
||||
if ((angleW > -360 && angleW < -90) || (angleW < 360 && angleW > 90)) {
|
||||
angleW = angleW + 180
|
||||
}
|
||||
if ((angleH > -360 && angleH < -90) || (angleH < 360 && angleH > 90)) {
|
||||
angleH = angleH + 180
|
||||
}
|
||||
|
||||
radiansW = (Math.PI / 180) * angleW
|
||||
radiansH = (Math.PI / 180) * angleH
|
||||
// 矩形高度
|
||||
w = (Math.cos(radiansW) * distance) * 2
|
||||
h = (Math.cos(radiansH) * distance) * 2
|
||||
// scaleY值
|
||||
this.scale.x = w / 3.5
|
||||
this.scale.y = h / 3.5
|
||||
break
|
||||
case 'svg-control-points_2':
|
||||
case 'svg-control-points_8':
|
||||
bearingH = (((turf.rhumbBearing(pointC, turf.point(controlPoints[2])) + 360) - this.angle) % 360)
|
||||
angleH = bearing2 - bearingH
|
||||
|
||||
if ((angleH > -360 && angleH < -90) || (angleH < 360 && angleH > 90)) {
|
||||
angleH = angleH + 180
|
||||
}
|
||||
|
||||
radiansH = (Math.PI / 180) * angleH
|
||||
// 矩形高度
|
||||
h = (Math.cos(radiansH) * distance) * 2
|
||||
// scaleY值
|
||||
this.scale.y = h / 3.5
|
||||
break
|
||||
case 'svg-control-points_3':
|
||||
case 'svg-control-points_9':
|
||||
bearingW = (((turf.rhumbBearing(pointC, turf.point(controlPoints[6])) + 360) - this.angle) % 360)
|
||||
bearingH = (((turf.rhumbBearing(pointC, turf.point(controlPoints[2])) + 360) - this.angle) % 360)
|
||||
angleW = bearing2 - bearingW
|
||||
angleH = bearing2 - bearingH
|
||||
|
||||
if ((angleW > -360 && angleW < -90) || (angleW < 360 && angleW > 90)) {
|
||||
angleW = angleW + 180
|
||||
}
|
||||
if ((angleH > -360 && angleH < -90) || (angleH < 360 && angleH > 90)) {
|
||||
angleH = angleH + 180
|
||||
}
|
||||
|
||||
radiansW = (Math.PI / 180) * angleW
|
||||
radiansH = (Math.PI / 180) * angleH
|
||||
// 矩形高度
|
||||
w = (Math.cos(radiansW) * distance) * 2
|
||||
h = (Math.cos(radiansH) * distance) * 2
|
||||
// scaleY值
|
||||
this.scale.x = w / 3.5
|
||||
this.scale.y = h / 3.5
|
||||
break
|
||||
case 'svg-control-points_4':
|
||||
bearingW = (((turf.rhumbBearing(pointC, turf.point(controlPoints[4])) + 360) - this.angle) % 360)
|
||||
angleW = bearing2 - bearingW
|
||||
|
||||
if ((angleW > -360 && angleW < -90) || (angleW < 360 && angleW > 90)) {
|
||||
angleW = angleW + 180
|
||||
}
|
||||
|
||||
radiansW = (Math.PI / 180) * angleW
|
||||
// 矩形宽度
|
||||
w = (Math.cos(radiansW) * distance) * 2
|
||||
// scaleY值
|
||||
this.scale.x = w / 3.5
|
||||
|
||||
break
|
||||
case 'svg-control-points_5':
|
||||
if (position2.lat > 83.5) {
|
||||
position2.lat = 83.5
|
||||
}
|
||||
if (position2.lat < -83.5) {
|
||||
position2.lat = -83.5
|
||||
}
|
||||
this.position = {lng: position2.lng, lat: position2.lat}
|
||||
let cx = position2.lng - position1.lng
|
||||
let cy = position2.lat - position1.lat
|
||||
this.bbox[0] = this.bbox[0] + cx
|
||||
this.bbox[1] = this.bbox[1] + cy
|
||||
this.bbox[2] = this.bbox[2] + cx
|
||||
this.bbox[3] = this.bbox[3] + cy
|
||||
break
|
||||
case 'svg-control-points_6':
|
||||
bearingW = (((turf.rhumbBearing(pointC, turf.point(controlPoints[6])) + 360) - this.angle) % 360)
|
||||
angleW = bearing2 - bearingW
|
||||
|
||||
if ((angleW > -360 && angleW < -90) || (angleW < 360 && angleW > 90)) {
|
||||
angleW = angleW + 180
|
||||
}
|
||||
|
||||
radiansW = (Math.PI / 180) * angleW
|
||||
// 矩形高度
|
||||
w = (Math.cos(radiansW) * distance) * 2
|
||||
this.scale.x = w / 3.5
|
||||
|
||||
break
|
||||
default:
|
||||
}
|
||||
|
||||
// let radians = (Math.PI / 180) * this.options.angle
|
||||
// x = x*Math.cos(radians)
|
||||
// y = y*Math.cos(radians)
|
||||
|
||||
|
||||
// let bbox = turf.bbox(geojson);
|
||||
// let square = turf.square(bbox);
|
||||
|
||||
x = x / (width / 2) * 100
|
||||
y = y / (height / 2) * 100
|
||||
|
||||
let scale = { ...this.scale }
|
||||
scale.x = scale.x + x
|
||||
scale.y = scale.y - y
|
||||
|
||||
// let pt = turf.point(this.center);
|
||||
// let destination1 = turf.rhumbDestination(pt, 220, 45, { units: 'kilometers' });
|
||||
// let destination2 = turf.rhumbDestination(pt, 220, 225, { units: 'kilometers' });
|
||||
|
||||
// width = Math.abs(destination2.geometry.coordinates[0] - destination1.geometry.coordinates[0])
|
||||
// height = Math.abs(destination2.geometry.coordinates[1] - destination1.geometry.coordinates[1])
|
||||
|
||||
if (scale.y > 200) {
|
||||
scale.y = 200
|
||||
}
|
||||
if (scale.y < 0) {
|
||||
scale.y = 0
|
||||
}
|
||||
|
||||
if (scale.x > 200) {
|
||||
scale.x = 200
|
||||
}
|
||||
if (scale.x < 0) {
|
||||
scale.x = 0
|
||||
}
|
||||
|
||||
this.scale = { ...scale }
|
||||
|
||||
}
|
||||
else {
|
||||
let pickedObjectArray = sdk.viewer.scene.drillPick(movement.endPosition);
|
||||
let pickPoint
|
||||
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||
let pickedObject = pickedObjectArray[i]
|
||||
if (pickedObject && pickedObject.primitive && pickedObject.primitive._id &&
|
||||
(pickedObject.primitive._id.id && pickedObject.primitive._id.id.indexOf('svg-control-points_') !== -1)
|
||||
) {
|
||||
pickPoint = pickedObject.primitive._id
|
||||
break
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < this.pointEntityCollection.values.length; i++) {
|
||||
if (pickPoint && this.pointEntityCollection.values[i].id === pickPoint.id) {
|
||||
pickPoint.point.color = Cesium.Color.fromCssColorString('#ffff00')
|
||||
}
|
||||
else {
|
||||
switch (this.pointEntityCollection.values[i].id) {
|
||||
case 'svg-control-points_5':
|
||||
this.pointEntityCollection.values[i].point.color = Cesium.Color.fromCssColorString('#ffff00')
|
||||
break
|
||||
case 'svg-control-points_0':
|
||||
this.pointEntityCollection.values[i].point.color = Cesium.Color.fromCssColorString('#ff0000')
|
||||
break
|
||||
default:
|
||||
this.pointEntityCollection.values[i].point.color = Cesium.Color.fromCssColorString('#00ff0a')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||||
this.ScreenSpaceEventHandler.setInputAction((movement) => {
|
||||
let pickedObjectArray = sdk.viewer.scene.drillPick(movement.position);
|
||||
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||
let pickedObject = pickedObjectArray[i]
|
||||
if (pickedObject && pickedObject.primitive && pickedObject.primitive._id && pickedObject.primitive._id.objectId === this.options.id &&
|
||||
(pickedObject.primitive._id.id && pickedObject.primitive._id.id.indexOf('svg-control-points_') !== -1)
|
||||
) {
|
||||
YJ.Global.CameraController(sdk, false)
|
||||
this.pickPoint = pickedObject.primitive._id
|
||||
this.pickPoint.point.color = Cesium.Color.fromCssColorString('#ff0000')
|
||||
break
|
||||
}
|
||||
}
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
||||
this.ScreenSpaceEventHandler.setInputAction((movement) => {
|
||||
if (this.pickPoint) {
|
||||
YJ.Global.CameraController(sdk, true)
|
||||
switch (this.pickPoint.id) {
|
||||
case 'svg-control-points_4':
|
||||
this.pickPoint.point.color = Cesium.Color.fromCssColorString('#ffff00')
|
||||
break
|
||||
case 'svg-control-points_9':
|
||||
this.pickPoint.point.color = Cesium.Color.fromCssColorString('#ff0000')
|
||||
break
|
||||
default:
|
||||
this.pickPoint.point.color = Cesium.Color.fromCssColorString('#00ff0a')
|
||||
}
|
||||
this.pickPoint = null
|
||||
}
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_UP)
|
||||
|
||||
|
||||
|
||||
|
||||
this.pointEntityCollection = new Cesium.EntityCollection()
|
||||
let w = 3.5 * this.scale.x
|
||||
let h = 3.5 * this.scale.y
|
||||
let wh = Math.sqrt(((w / 2) ** 2) + ((h / 2) ** 2))
|
||||
let angle = Math.atan((w / 2) / (h / 2)) * (180 / Math.PI)
|
||||
|
||||
let point = turf.point([this.position.lng, this.position.lat]);
|
||||
let options = { units: 'kilometers' };
|
||||
let controlPoints = []
|
||||
controlPoints[0] = turf.destination(point, h / 2 * 1.5, 0, options).geometry.coordinates
|
||||
controlPoints[1] = turf.destination(point, wh, 180 + angle, options).geometry.coordinates
|
||||
controlPoints[2] = turf.destination(point, h / 2, 180, options).geometry.coordinates
|
||||
controlPoints[3] = turf.destination(point, wh, 180 - angle, options).geometry.coordinates
|
||||
controlPoints[4] = turf.destination(point, w / 2, 270, options).geometry.coordinates
|
||||
controlPoints[5] = [this.position.lng, this.position.lat]
|
||||
controlPoints[6] = turf.destination(point, w / 2, 90, options).geometry.coordinates
|
||||
controlPoints[7] = turf.destination(point, wh, 360 - angle, options).geometry.coordinates
|
||||
controlPoints[8] = turf.destination(point, h / 2, 0, options).geometry.coordinates
|
||||
controlPoints[9] = turf.destination(point, wh, 0 + angle, options).geometry.coordinates
|
||||
|
||||
this.controlPoints = controlPoints
|
||||
for (let i = 0; i < this.controlPoints.length; i++) {
|
||||
let color = '#00ff0a'
|
||||
if (i === 5) {
|
||||
color = '#ffff00'
|
||||
}
|
||||
if (i === 0) {
|
||||
color = '#ff0000'
|
||||
}
|
||||
let entity = sdk.viewer.entities.getOrCreateEntity('svg-control-points_' + i)
|
||||
entity.objectId = this.options.id
|
||||
entity.position = new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Cartesian3.fromDegrees(...this.controlPoints[i])
|
||||
})
|
||||
entity.point = new Cesium.PointGraphics({
|
||||
color: Cesium.Color.fromCssColorString(color), // 点的颜色
|
||||
pixelSize: 10, // 点的大小
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY // 不应用深度测试
|
||||
})
|
||||
this.pointEntityCollection.add(entity)
|
||||
}
|
||||
}
|
||||
|
||||
_updateGeojson(data, x, y) {
|
||||
let width = Math.abs(this.bbox[0] - this.bbox[2])
|
||||
let height = Math.abs(this.bbox[1] - this.bbox[3])
|
||||
if (typeof data[0] === 'object') {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
this._updateGeojson(data[i], x, y)
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < data.length; i += 2) {
|
||||
data[i] = data[i] + ((data[i] / (width / 2)) * x)
|
||||
}
|
||||
for (let i = 1; i < data.length; i += 2) {
|
||||
data[i] = data[i] - ((data[i] / (height / 2)) * y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
let point = turf.point([this.position.lng, this.position.lat]);
|
||||
let options = { units: 'kilometers' };
|
||||
|
||||
let hierarchys = []
|
||||
let interimBbox = [...this.bbox]
|
||||
let width = Math.abs(interimBbox[2] - interimBbox[0])
|
||||
let height = Math.abs(interimBbox[3] - interimBbox[1])
|
||||
let x = ((width / 2) * this.options.scale.x) / 100 - (width / 2)
|
||||
let y = (height / 2) * (-(this.options.scale.y)) / 100 + (height / 2)
|
||||
|
||||
interimBbox[0] = interimBbox[0] - x
|
||||
interimBbox[1] = interimBbox[1] + y
|
||||
interimBbox[2] = interimBbox[2] + x
|
||||
interimBbox[3] = interimBbox[3] - y
|
||||
|
||||
let interim
|
||||
|
||||
if (interimBbox[0] > interimBbox[2]) {
|
||||
interim = interimBbox[0]
|
||||
interimBbox[0] = interimBbox[2]
|
||||
interimBbox[2] = interim
|
||||
}
|
||||
if (interimBbox[1] > interimBbox[3]) {
|
||||
interim = interimBbox[1]
|
||||
interimBbox[1] = interimBbox[3]
|
||||
interimBbox[3] = interim
|
||||
}
|
||||
|
||||
let geojson = JSON.parse(JSON.stringify(this.geojson))
|
||||
this._updateGeojson(geojson.geometry.coordinates, x, y)
|
||||
geojson = turf.transformRotate(geojson, this.angle, { pivot: [0, 0] });
|
||||
let directionDistance = []
|
||||
if (geojson.geometry.type === 'MultiPolygon') {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let array = []
|
||||
for (let m = 0; m < geojson.geometry.coordinates[i].length; m++) {
|
||||
let array2 = []
|
||||
for (let n = 0; n < geojson.geometry.coordinates[i][m].length; n++) {
|
||||
let point1 = turf.point([0, geojson.geometry.coordinates[i][m][n][1]])
|
||||
let point2 = turf.point([...geojson.geometry.coordinates[i][m][n]])
|
||||
let distance = turf.distance(point1, point2, { units: 'kilometers' });
|
||||
let angle2 = turf.rhumbBearing(point1, point2);
|
||||
array2.push(
|
||||
{
|
||||
origin: geojson.geometry.coordinates[i][m][n],
|
||||
distance: distance,
|
||||
angle: angle2
|
||||
}
|
||||
)
|
||||
}
|
||||
array.push(array2)
|
||||
}
|
||||
directionDistance.push(array)
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let array = []
|
||||
for (let m = 0; m < geojson.geometry.coordinates[i].length; m++) {
|
||||
let array2 = []
|
||||
let point1 = turf.point([0, geojson.geometry.coordinates[i][m][1]])
|
||||
let point2 = turf.point([...geojson.geometry.coordinates[i][m]])
|
||||
let distance = turf.distance(point1, point2, { units: 'kilometers' });
|
||||
let angle2 = turf.rhumbBearing(point1, point2);
|
||||
array.push({
|
||||
origin: geojson.geometry.coordinates[i][m],
|
||||
distance: distance,
|
||||
angle: angle2
|
||||
})
|
||||
}
|
||||
directionDistance.push(array)
|
||||
}
|
||||
}
|
||||
|
||||
geojson.properties.directionDistance = directionDistance
|
||||
|
||||
// this.bbox = [...interimBbox]
|
||||
|
||||
|
||||
let w = 3.5 * this.scale.x
|
||||
let h = 3.5 * this.scale.y
|
||||
let wh = Math.sqrt(((w / 2) ** 2) + ((h / 2) ** 2))
|
||||
let angle = Math.atan((w / 2) / (h / 2)) * (180 / Math.PI)
|
||||
let controlPoints = []
|
||||
controlPoints[0] = turf.destination(point, h / 2 * 1.5, 0 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[1] = turf.destination(point, wh, 180 + angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[2] = turf.destination(point, h / 2, 180 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[3] = turf.destination(point, wh, 180 - angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[4] = turf.destination(point, w / 2, 270 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[5] = [this.position.lng, this.position.lat]
|
||||
controlPoints[6] = turf.destination(point, w / 2, 90 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[7] = turf.destination(point, wh, 360 - angle + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[8] = turf.destination(point, h / 2, 0 + this.options.angle, options).geometry.coordinates
|
||||
controlPoints[9] = turf.destination(point, wh, 0 + angle + this.options.angle, options).geometry.coordinates
|
||||
|
||||
let points = turf.points(controlPoints);
|
||||
controlPoints = []
|
||||
for (let i = 0; i < points.features.length; i++) {
|
||||
controlPoints.push(points.features[i].geometry.coordinates)
|
||||
}
|
||||
this.controlPoints = controlPoints
|
||||
|
||||
if (geojson.geometry.type === 'MultiPolygon') {
|
||||
for (let i = 0; i < geojson.geometry.coordinates.length; i++) {
|
||||
let hierarchy = this.getHierarchyPolygon(geojson, i)
|
||||
hierarchys.push(hierarchy)
|
||||
}
|
||||
}
|
||||
else {
|
||||
let hierarchy = this.getHierarchyPolygon(geojson)
|
||||
hierarchys.push(hierarchy)
|
||||
}
|
||||
this.hierarchys = hierarchys
|
||||
}
|
||||
|
||||
load(callback) {
|
||||
if(this.loaded) {
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
this.#loadEvent = callback
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GroundSvg
|
||||
1723
src/Obj/Base/GroundSvg/index-3.js
Normal file
1723
src/Obj/Base/GroundSvg/index-3.js
Normal file
File diff suppressed because it is too large
Load Diff
2255
src/Obj/Base/GroundSvg/index.js
Normal file
2255
src/Obj/Base/GroundSvg/index.js
Normal file
File diff suppressed because it is too large
Load Diff
131
src/Obj/Base/Heatmap/index.js
Normal file
131
src/Obj/Base/Heatmap/index.js
Normal file
@ -0,0 +1,131 @@
|
||||
// import Tools from '../../Tools'
|
||||
import Base from "../index";
|
||||
|
||||
export default class HeatMap extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 热力图
|
||||
* @param options {object} 属性
|
||||
* @param options.id {string} 唯一标识
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.gradient {object} 渐变色
|
||||
* @param {Array.<object>} options.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
|
||||
* @param {Array.<object>} options.data 热力图数据 [{lon,lat,value},...]
|
||||
* */
|
||||
constructor(sdk, options) {
|
||||
super(sdk, options)
|
||||
this.viewer = sdk.viewer
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.options.positions = this.options.positions || []
|
||||
this.options.data = this.options.data
|
||||
this.options.gradient = options.gradient || {
|
||||
'0.9': 'red',
|
||||
'0.8': 'orange',
|
||||
'0.7': 'yellow',
|
||||
'0.5': 'blue',
|
||||
'0.3': 'green'
|
||||
}
|
||||
this.entity = {
|
||||
id: this.options.id
|
||||
}
|
||||
if (!this.options.positions || this.options.positions.length < 3) {
|
||||
this._error = '最少需要三个坐标!'
|
||||
console.warn(this._error)
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: this._error,
|
||||
type: 'warning',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
else {
|
||||
let array = []
|
||||
for (let i = 0; i < this.options.positions.length; i++) {
|
||||
array.push([this.options.positions[i].lng, this.options.positions[i].lat])
|
||||
}
|
||||
let line = turf.lineString(array);
|
||||
let bbox = turf.bbox(line);
|
||||
this.bounds = {
|
||||
west: bbox[0], south: bbox[1], east: bbox[2], north: bbox[3]
|
||||
}
|
||||
HeatMap.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
static add(that) {
|
||||
let arr = []
|
||||
that.options.positions.forEach(item => {
|
||||
arr.push(item.lng, item.lat)
|
||||
})
|
||||
let data = HeatMap.getData(that)
|
||||
let heatMap = that.createHeatMap(data.max, data.data)
|
||||
that.entity = new Cesium.Entity({
|
||||
id: that.options.id,
|
||||
show: that.options.show,
|
||||
polygon: {
|
||||
hierarchy: new Cesium.PolygonHierarchy(
|
||||
Cesium.Cartesian3.fromDegreesArray(arr)
|
||||
),
|
||||
material: heatMap._heatmap._renderer.canvas,
|
||||
zIndex: that.sdk._entityZIndex
|
||||
}
|
||||
})
|
||||
that.sdk._entityZIndex ++
|
||||
that.viewer.entities.add(that.entity)
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
}
|
||||
|
||||
static getData(that) {
|
||||
let len = 1000
|
||||
let data = []
|
||||
if (that.options.data && Array.isArray(that.options.data)) {
|
||||
let max = that.options.data[0].value
|
||||
for (let i = 0; i < that.options.data.length; i++) {
|
||||
let val = that.options.data[i].value
|
||||
max = Math.max(max, val)
|
||||
data.push({
|
||||
x: that.options.data[i].lng,
|
||||
y: that.options.data[i].lat,
|
||||
value: val
|
||||
})
|
||||
}
|
||||
return { max: max, data: data }
|
||||
}
|
||||
else {
|
||||
//构建一些随机数据点
|
||||
let max = 0
|
||||
while (len--) {
|
||||
let val = Math.floor(Math.random() * 1000)
|
||||
max = Math.max(max, val)
|
||||
let point = {
|
||||
x: Math.random() * (that.bounds.east - that.bounds.west) + that.bounds.west,
|
||||
y: Math.random() * (that.bounds.north - that.bounds.south) + that.bounds.south,
|
||||
value: val
|
||||
}
|
||||
data.push(point)
|
||||
}
|
||||
return { max: max, data: data }
|
||||
}
|
||||
}
|
||||
|
||||
createHeatMap(max, data) {
|
||||
let heatMap = CesiumHeatmap.create(
|
||||
this.bounds, // 矩形坐标
|
||||
{ // heatmap相应参数
|
||||
backgroundColor: "rgba(0,0,0,0)",
|
||||
radius: 20,
|
||||
maxOpacity: .5,
|
||||
minOpacity: 0,
|
||||
blur: .75,
|
||||
gradient: this.options.gradient
|
||||
}
|
||||
)
|
||||
heatMap.setWGS84Data(0, max, data);
|
||||
return heatMap
|
||||
}
|
||||
}
|
||||
247
src/Obj/Base/ItineraryMove/index.js
Normal file
247
src/Obj/Base/ItineraryMove/index.js
Normal file
@ -0,0 +1,247 @@
|
||||
// /**
|
||||
// * @description 动态线
|
||||
// */
|
||||
// import FlowPictureMaterialProperty from '../../Materail/FlowPictureMaterialProperty'
|
||||
// import Dialog from '../../Element/Dialog';
|
||||
// import cy_slider from "../../Element/cy_html_slider";
|
||||
// import Base from "../index";
|
||||
|
||||
// class ItineraryMove extends Base {
|
||||
// /**
|
||||
// * @constructor
|
||||
// * @param sdk
|
||||
// * @param options {object} 线属性
|
||||
// * @param options.name{string} 名称
|
||||
// * @param options.image{string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL、Canvas 或 Video 的属性
|
||||
// * @param options.width=10{number} 线宽
|
||||
// * @param options.duration=500{number} 移动速度
|
||||
// * @param {Array.<number>} options.positions 经度、纬度和高度的列表[{经度,纬度,高度},{经度,纬度,高度}...]
|
||||
// * */
|
||||
// constructor(sdk, options = {}) {
|
||||
// super(sdk, options);
|
||||
// this.options.name = options.name || ''
|
||||
// this.options.image = options.image || this.getSourceRootPath() + '/img/arrowRoad.jpg'
|
||||
// this.options.width = (options.width || options.width === 0) ? options.width : 10
|
||||
// this.options.space = (options.space || options.space === 0) ? options.space : 1
|
||||
// this.options.backgroundColor = options.backgroundColor || "#ff000000"
|
||||
// this.options.duration = options.duration || options.duration === 0 || 500
|
||||
// ItineraryMove.create(this)
|
||||
// }
|
||||
|
||||
// static create(that) {
|
||||
// let positions = that.options.positions
|
||||
// let fromDegreesArray = []
|
||||
// for (let i = 0; i < positions.length; i++) {
|
||||
// fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
// }
|
||||
// const canvasEle = document.createElement('canvas');
|
||||
// const ctx = canvasEle.getContext('2d')
|
||||
// const myImg = new Image()
|
||||
// myImg.src = that.options.image
|
||||
// myImg.onload = function () {
|
||||
// canvasEle.width = myImg.width * (that.options.space + 1)
|
||||
// canvasEle.height = myImg.height
|
||||
// ctx.drawImage(myImg, myImg.width * (that.options.space / 2), 0)
|
||||
// that.entity = new Cesium.EntityCollection();
|
||||
// let imgEntity = that.sdk.viewer.entities.add({
|
||||
// name: 'imgEntity',
|
||||
// polyline: {
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// // height: 1,
|
||||
// width: that.options.width,
|
||||
// clampToGround: true,
|
||||
// material: new FlowPictureMaterialProperty({
|
||||
// image: canvasEle,
|
||||
// repeat: new Cesium.CallbackProperty(function () {
|
||||
// var positionProperty = imgEntity.polyline.positions;
|
||||
// var positions = positionProperty.getValue(that.sdk.viewer.clock.currentTime);
|
||||
|
||||
// if (!Cesium.defined(positions)) {
|
||||
// return new Cesium.Cartesian2(1.0, 1.0);
|
||||
// }
|
||||
|
||||
// var distance = 0;
|
||||
// for (var i = 0; i < positions.length - 1; ++i) {
|
||||
// distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
|
||||
// }
|
||||
|
||||
// var repeatX = distance / imgEntity.polyline.width.getValue();
|
||||
// // 根据地图缩放程度调整repeatX
|
||||
// var cameraHeight = that.sdk.viewer.camera.positionCartographic.height;
|
||||
// var boundingSphere = new Cesium.BoundingSphere(
|
||||
// new Cesium.Cartesian3(-1000000, 0, 0), // 中心点坐标
|
||||
// 500000 // 半径(距离)
|
||||
// );
|
||||
|
||||
// // 获取绘图缓冲区的宽度和高度(通常是屏幕的分辨率)
|
||||
// var drawingBufferWidth = that.sdk.viewer.canvas.clientWidth;
|
||||
// var drawingBufferHeight = that.sdk.viewer.canvas.clientHeight;
|
||||
|
||||
// // 使用 getPixelSize 方法获取包围球在屏幕上的像素大小
|
||||
// var groundResolution = that.sdk.viewer.scene.camera.getPixelSize(boundingSphere, drawingBufferWidth, drawingBufferHeight)
|
||||
// repeatX *= groundResolution / cameraHeight / (that.options.space * (canvasEle.width / canvasEle.height * 5) + 1);
|
||||
// // if (repeatX < 3) {
|
||||
// // repeatX = 3
|
||||
// // }
|
||||
// return new Cesium.Cartesian2(repeatX, 1.0);
|
||||
// }, false),
|
||||
// duration: that.options.duration,
|
||||
// zIndex: that.sdk._entityZIndex,
|
||||
// })
|
||||
// // material: new Cesium.ImageMaterialProperty(
|
||||
// // {
|
||||
// // image: this.options.image,
|
||||
// // repeat: new Cesium.CallbackProperty(function () {
|
||||
// // var positionProperty = _this.entity.polyline.positions;
|
||||
// // var positions = positionProperty.getValue(_this.sdk.viewer.clock.currentTime);
|
||||
|
||||
// // if (!Cesium.defined(positions)) {
|
||||
// // return new Cesium.Cartesian2(1.0, 1.0);
|
||||
// // }
|
||||
|
||||
// // var distance = 0;
|
||||
// // for (var i = 0; i < positions.length - 1; ++i) {
|
||||
// // distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
|
||||
// // }
|
||||
|
||||
// // var repeatX = distance / _this.entity.polyline.width.getValue();
|
||||
// // // 根据地图缩放程度调整repeatX
|
||||
// // var cameraHeight = _this.sdk.viewer.camera.positionCartographic.height;
|
||||
// // var boundingSphere = new Cesium.BoundingSphere(
|
||||
// // new Cesium.Cartesian3(-1000000, 0, 0), // 中心点坐标
|
||||
// // 500000 // 半径(距离)
|
||||
// // );
|
||||
|
||||
// // // 获取绘图缓冲区的宽度和高度(通常是屏幕的分辨率)
|
||||
// // var drawingBufferWidth = _this.sdk.viewer.canvas.clientWidth;
|
||||
// // var drawingBufferHeight = _this.sdk.viewer.canvas.clientHeight;
|
||||
|
||||
// // // 使用 getPixelSize 方法获取包围球在屏幕上的像素大小
|
||||
// // var groundResolution = _this.sdk.viewer.scene.camera.getPixelSize(boundingSphere, drawingBufferWidth, drawingBufferHeight);
|
||||
// // repeatX *= groundResolution / cameraHeight / (Math.abs(_this.sdk.viewer.camera.pitch) + 1);
|
||||
// // if (repeatX < 3) {
|
||||
// // repeatX = 3
|
||||
// // }
|
||||
// // return new Cesium.Cartesian2(repeatX, 1.0);
|
||||
// // }, false),
|
||||
// // }
|
||||
// // )
|
||||
// },
|
||||
// })
|
||||
// that.sdk._entityZIndex ++
|
||||
// let lineEntity = that.sdk.viewer.entities.add({
|
||||
// name: 'lineEntity',
|
||||
// polyline: {
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// width: that.options.width,
|
||||
// clampToGround: true,
|
||||
// material: Cesium.Color.fromCssColorString(that.options.backgroundColor),
|
||||
// zIndex: that.sdk._entityZIndex,
|
||||
// },
|
||||
// })
|
||||
// that.sdk._entityZIndex ++
|
||||
|
||||
// // let geojson = {
|
||||
// // type: "FeatureCollection",
|
||||
// // features: [
|
||||
// // {
|
||||
// // type: "Feature",
|
||||
// // geometry: {
|
||||
// // type: "LineString",
|
||||
// // coordinates: [
|
||||
// // [100.0, 40],
|
||||
// // [110.0, 40],
|
||||
// // [120.0, 40],
|
||||
// // ],
|
||||
// // },
|
||||
// // properties: { color: '#00c311' }
|
||||
// // },
|
||||
// // {
|
||||
// // type: "Feature",
|
||||
// // geometry: {
|
||||
// // type: "LineString",
|
||||
// // coordinates: [
|
||||
// // [120.0, 70],
|
||||
// // [130.0, 70],
|
||||
// // [140.0, 40],
|
||||
// // ],
|
||||
// // },
|
||||
// // properties: { color: '#ff0000' }
|
||||
// // }
|
||||
// // ]
|
||||
// // }
|
||||
// // var positions = [];
|
||||
// // var colors = [];
|
||||
// // for (var i = 0; i < geojson.features.length; i++) {
|
||||
// // for(let m = 0; m<geojson.features[i].geometry.coordinates.length;m++) {
|
||||
// // positions.push(Cesium.Cartesian3.fromDegrees(...geojson.features[i].geometry.coordinates[m]));
|
||||
// // colors.push(Cesium.Color.fromCssColorString(geojson.features[i].properties.color));
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
// // this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({//GroundPrimitive贴地
|
||||
// // geometryInstances: new Cesium.GeometryInstance({
|
||||
// // geometry: new Cesium.CorridorGeometry({
|
||||
// // positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// // width: this.options.width,
|
||||
// // height: this.options.height,
|
||||
// // cornerType: Cesium.CornerType.MITERED,
|
||||
// // vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
|
||||
// // }),
|
||||
// // attributes: {
|
||||
// // color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 0.5))
|
||||
// // }
|
||||
// // }),
|
||||
// // appearance: new Cesium.MaterialAppearance({
|
||||
// // material: Cesium.Material.fromType('Image', {
|
||||
// // image: this.options.image,
|
||||
// // repeat: new Cesium.Cartesian2(100, 1.0)
|
||||
// // }),
|
||||
// // faceForward: true,
|
||||
// // renderState: {
|
||||
// // blending: Cesium.BlendingState.ALPHA_BLEND
|
||||
// // }
|
||||
// // })
|
||||
// // }));
|
||||
// // const instance = new Cesium.GeometryInstance({
|
||||
// // geometry : new Cesium.GroundPolylineGeometry({
|
||||
// // positions : Cesium.Cartesian3.fromDegreesArray([
|
||||
// // -112.1340164450331, 36.05494287836128,
|
||||
// // -112.08821010582645, 36.097804071380715
|
||||
// // ]),
|
||||
// // width : 4.0
|
||||
// // }),
|
||||
// // id : 'object returned when this instance is picked and to get/set per-instance attributes'
|
||||
// // });
|
||||
|
||||
// // _this.sdk.viewer.scene.groundPrimitives.add(new Cesium.GroundPolylinePrimitive({
|
||||
// // geometryInstances: new Cesium.GeometryInstance({
|
||||
// // geometry: new Cesium.GroundPolylineGeometry({
|
||||
// // positions: positions,
|
||||
// // width: 40.0,
|
||||
// // colors : colors
|
||||
// // })
|
||||
// // }),
|
||||
// // appearance: new Cesium.PolylineMaterialAppearance()
|
||||
// // }));
|
||||
// // console.log('entity', _this.entity)
|
||||
// that.entity.add(imgEntity)
|
||||
// that.entity.add(lineEntity)
|
||||
// that.sdk.viewer.entities.add(that.entity)
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 删除
|
||||
// */
|
||||
// remove() {
|
||||
// for (let i = 0; i < this.entity.values.length; i++) {
|
||||
// this.sdk.viewer.entities.remove(this.entity.values[i])
|
||||
// }
|
||||
// this.entity.removeAll()
|
||||
// this.entity = null
|
||||
// }
|
||||
// }
|
||||
|
||||
// export default ItineraryMove
|
||||
136
src/Obj/Base/KML/index.js
Normal file
136
src/Obj/Base/KML/index.js
Normal file
@ -0,0 +1,136 @@
|
||||
/**
|
||||
* @name: kml
|
||||
* @author: Administrator
|
||||
* @date: 2023-07-19 09:25
|
||||
* @description:kml
|
||||
* @update: 2023-07-19 09:25
|
||||
*/
|
||||
import Base from '../index'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
class KML extends Base {
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options)
|
||||
this.source = new Cesium.CustomDataSource(this.options.id)
|
||||
// this.source = new Cesium.CompositeEntityCollection([])
|
||||
this.detail = []
|
||||
// this.load()
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(val) {
|
||||
if (this.source) {
|
||||
this.source.show = val
|
||||
this.options.show = val
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultValue() {
|
||||
this.options.id = this.options.id || Cesium.createGuid()
|
||||
this.options.url = this.options.url || ''
|
||||
this.options.show = this.options.show ?? true
|
||||
}
|
||||
|
||||
async flyTo(duration = 3) {
|
||||
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)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation,
|
||||
duration
|
||||
})
|
||||
}
|
||||
else {
|
||||
if (this.source) this.viewer.flyTo(this.source, { duration })
|
||||
}
|
||||
}
|
||||
|
||||
remove() {
|
||||
super.remove()
|
||||
this.viewer.dataSources.remove(this.source)
|
||||
this.source = null
|
||||
}
|
||||
|
||||
async on() {
|
||||
this.show = this.options.show
|
||||
let source = await Cesium.KmlDataSource.load(this.options.url, {
|
||||
camera: this.viewer.scene.camera,
|
||||
canvas: this.viewer.scene.canvas
|
||||
// clampToGround: true
|
||||
})
|
||||
source.entities.values.forEach((entity, index) => {
|
||||
this.detail.push({ name: entity.name, id: entity.id })
|
||||
if (entity.label) {
|
||||
let scale = 1
|
||||
if (entity.billboard) {
|
||||
scale = entity.billboard.scale._value
|
||||
}
|
||||
entity.label.pixelOffset = new Cesium.Cartesian2(0, -32 * scale - 15)
|
||||
entity.label.horizontalOrigin = Cesium.HorizontalOrigin.CENTER
|
||||
entity.label.disableDepthTestDistance = Number.POSITIVE_INFINITY
|
||||
}
|
||||
if (entity.polygon) {
|
||||
//polygon需要重写,不然无法贴地
|
||||
let polygon = {
|
||||
hierarchy: entity.polygon.hierarchy.getValue().positions,
|
||||
material: entity.polygon.material,
|
||||
classificationType: Cesium.ClassificationType.BOTH
|
||||
}
|
||||
//拆分边线,因为边线不能贴地,需要改为polyline,但是有可能存在entity本身就有polyline,所以需要单独创建一个entity,
|
||||
if (entity.polygon.outline.getValue()) {
|
||||
let positions = entity.polygon.hierarchy.getValue().positions
|
||||
let entity2 = new Cesium.Entity({
|
||||
id: this.getOutlineId(entity.id),
|
||||
polyline: {
|
||||
positions,
|
||||
width: entity.polygon.outlineWidth.getValue(),
|
||||
material: entity.polygon.outlineColor.getValue(),
|
||||
clampToGround: true,
|
||||
zIndex: this.sdk._entityZIndex
|
||||
}
|
||||
})
|
||||
this.source.entities.add(entity2)
|
||||
}
|
||||
entity.polygon = polygon
|
||||
}
|
||||
if (entity.billboard) {
|
||||
entity.billboard.heightReference =
|
||||
Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
if (entity.polyline) {
|
||||
entity.polyline = {
|
||||
positions: entity.polyline.positions.getValue(),
|
||||
material: entity.polyline.material,
|
||||
clampToGround: true,
|
||||
width: entity.polyline.width ? entity.polyline.width.getValue() : 1
|
||||
}
|
||||
//这里在设置贴地的时候,需要单独创建polyline,部分kml的polyline设置贴地,会导致引擎崩溃,原因暂未查询到
|
||||
}
|
||||
entity.show = true
|
||||
this.source.entities.add(entity)
|
||||
})
|
||||
await this.viewer.dataSources.add(this.source)
|
||||
}
|
||||
|
||||
getOutlineId(id) {
|
||||
return [id, 'outline'].join('_')
|
||||
}
|
||||
}
|
||||
|
||||
export default KML
|
||||
98
src/Obj/Base/KML/index2.js
Normal file
98
src/Obj/Base/KML/index2.js
Normal file
@ -0,0 +1,98 @@
|
||||
// /**
|
||||
// * @name: kml
|
||||
// * @author: Administrator
|
||||
// * @date: 2023-07-19 09:25
|
||||
// * @description:kml
|
||||
// * @update: 2023-07-19 09:25
|
||||
// */
|
||||
// class KML2 {
|
||||
// constructor(options = {}) {
|
||||
// this.options = {...options}
|
||||
// this.viewer = YJ.getEarth().czm.viewer
|
||||
// this.setDefaultValue()
|
||||
// this.source = new Cesium.CustomDataSource(this.options.id)
|
||||
// this.billboardsCollection = this.viewer.scene.primitives.add(new Cesium.BillboardCollection());
|
||||
// this.labelCollection = this.viewer.scene.primitives.add(new Cesium.LabelCollection());
|
||||
|
||||
// // this.source = new Cesium.CompositeEntityCollection([])
|
||||
// this.detail = []
|
||||
// this.labelAttrs = ["show", "position", "text", "font", "fillColor"]
|
||||
// this.load()
|
||||
// }
|
||||
|
||||
// get show() {
|
||||
// return this.options.show
|
||||
// }
|
||||
|
||||
// set show(val) {
|
||||
// if (this.source) {
|
||||
// this.source.show = val
|
||||
// this.options.show = val
|
||||
// }
|
||||
// }
|
||||
|
||||
// setDefaultValue() {
|
||||
// this.options.id = this.options.id || Cesium.createGuid()
|
||||
// this.options.url = this.options.url || ""
|
||||
// this.options.show = this.options.show ?? true
|
||||
// }
|
||||
|
||||
// flyTo(duration = 3) {
|
||||
// if (this.source)
|
||||
// this.viewer.flyTo(this.source, {duration})
|
||||
// }
|
||||
|
||||
// remove() {
|
||||
// this.viewer.dataSources.remove(this.source);
|
||||
// this.source = null
|
||||
// }
|
||||
|
||||
// async load() {
|
||||
// this.show = this.options.show
|
||||
// let source = await Cesium.KmlDataSource.load(this.options.url,
|
||||
// {
|
||||
// camera: this.viewer.scene.camera,
|
||||
// canvas: this.viewer.scene.canvas,
|
||||
// // clampToGround: true
|
||||
// })
|
||||
// let types = ["label", "billboard", "polyline", "polygon"]//kml暂时只考虑这几种
|
||||
|
||||
// source.entities.values.forEach((entity, index) => {
|
||||
// if (entity.label) {
|
||||
// this.dealLabel(entity)
|
||||
// }
|
||||
// if (entity.billboard) {
|
||||
// this.addBillboard(entity)
|
||||
// }
|
||||
// })
|
||||
|
||||
// // await this.viewer.dataSources.add(this.source);
|
||||
// }
|
||||
|
||||
// getOutlineId(id) {
|
||||
// return [id, "outline"].join("_")
|
||||
// }
|
||||
|
||||
// addBillboard(entity) {
|
||||
// this.billboardsCollection.add({
|
||||
// position: entity.position.getValue(),
|
||||
// image: entity.billboard.image.getValue() //图片存储路径
|
||||
// });
|
||||
// }
|
||||
|
||||
// dealLabel(entity) {
|
||||
// let config = {
|
||||
// pixelOffset: new Cesium.Cartesian2(0, -32),
|
||||
// position: entity.position.getValue(),
|
||||
// }
|
||||
// this.labelAttrs.forEach(key => {
|
||||
// if (entity.label[key]) {
|
||||
// config[key] = entity.label[key].getValue()
|
||||
// }
|
||||
// })
|
||||
// this.labelCollection.add(config);
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// export default KML2
|
||||
594
src/Obj/Base/LabelObject/index.js
Normal file
594
src/Obj/Base/LabelObject/index.js
Normal file
@ -0,0 +1,594 @@
|
||||
/**
|
||||
* 标注
|
||||
*/
|
||||
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 {
|
||||
#updateBillboardImageTimeout
|
||||
#canvas = document.createElement('canvas')
|
||||
#canvas2 = document.createElement('canvas')
|
||||
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.lineWidth = options.lineWidth || 4
|
||||
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: {
|
||||
// show: this.options.show,
|
||||
// text: new Cesium.CallbackProperty(function () {
|
||||
// return _this.options.text
|
||||
// }, false),
|
||||
// font: this.options.fontSize + "px Helvetica",
|
||||
// fillColor: Cesium.Color.fromCssColorString(this.options.color),
|
||||
// pixelOffset: new Cesium.Cartesian2(0, -this.options.pixelOffset),
|
||||
// outlineColor: Cesium.Color.BLACK,
|
||||
// backgroundColor: Cesium.Color.fromCssColorString('#42c6ef'),
|
||||
// backgroundPadding: new Cesium.Cartesian2(12, 12),
|
||||
// showBackground: true,
|
||||
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
// outlineWidth: 1,
|
||||
// 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')
|
||||
this.entity && (this.updateBillboardImage())
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
this.entity && (this.entity.billboard.image = this.getcanvas())
|
||||
}
|
||||
|
||||
get scaleByDistance() {
|
||||
return this.options.scaleByDistance
|
||||
}
|
||||
set scaleByDistance(v) {
|
||||
this.options.scaleByDistance = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
if (this.options.scaleByDistance) {
|
||||
this.entity.billboard.scaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
this.entity.billboard.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
this.entity.billboard.scaleByDistance = undefined
|
||||
this.entity.billboard.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.billboard.scaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
this.entity.billboard.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
this.entity.billboard.scaleByDistance = undefined
|
||||
this.entity.billboard.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.billboard.scaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
this.entity.billboard.pixelOffsetScaleByDistance = new Cesium.NearFarScalar(
|
||||
this.options.near,
|
||||
1,
|
||||
this.options.far,
|
||||
0
|
||||
)
|
||||
} else {
|
||||
this.entity.billboard.scaleByDistance = undefined
|
||||
this.entity.billboard.pixelOffsetScaleByDistance = undefined
|
||||
}
|
||||
}
|
||||
|
||||
get fontSize() {
|
||||
return this.options.fontSize
|
||||
}
|
||||
set fontSize(v) {
|
||||
this.options.fontSize = Number(v)
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.updateBillboardImage()
|
||||
}
|
||||
|
||||
get fontFamily() {
|
||||
return this.options.fontFamily
|
||||
}
|
||||
|
||||
set fontFamily(v) {
|
||||
this.options.fontFamily = v || 0
|
||||
this.font = getFontFamily(this.options.fontFamily) || 'SimHei'
|
||||
this.updateBillboardImage()
|
||||
}
|
||||
|
||||
get lineWidth() {
|
||||
return this.options.lineWidth
|
||||
}
|
||||
set lineWidth(v) {
|
||||
this.options.lineWidth = ((Number(v) || Number(v) === 0) ? Number(v) : 4)
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.updateBillboardImage()
|
||||
}
|
||||
|
||||
get pixelOffset() {
|
||||
return this.options.pixelOffset
|
||||
}
|
||||
set pixelOffset(v) {
|
||||
this.options.pixelOffset = Number(v)
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
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)
|
||||
}
|
||||
get lineColor() {
|
||||
return this.options.pixelOffset
|
||||
}
|
||||
set lineColor(v) {
|
||||
this.options.lineColor = v || '#00ffff80'
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.entity.billboard.image = this.getcanvas()
|
||||
}
|
||||
|
||||
get backgroundColor() {
|
||||
return this.options.backgroundColor
|
||||
}
|
||||
set backgroundColor(v) {
|
||||
this.options.backgroundColor = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.entity.billboard.image = this.getcanvas()
|
||||
}
|
||||
|
||||
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()
|
||||
// }
|
||||
|
||||
getcanvas() {
|
||||
const ctx = this.#canvas.getContext('2d')
|
||||
ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);
|
||||
ctx.font = this.options.fontSize + 'px ' + this.font
|
||||
let texts = this.options.text.split('\n')
|
||||
let canvasWidth = 0
|
||||
let canvasHeight = 0
|
||||
for (let i = 0; i < texts.length; i++) {
|
||||
const text = texts[i]
|
||||
const width = ctx.measureText(text).width
|
||||
if (width > canvasWidth) {
|
||||
canvasWidth = width
|
||||
}
|
||||
canvasHeight += this.options.fontSize
|
||||
}
|
||||
canvasHeight = canvasHeight + 20 + (texts.length - 1) * 5
|
||||
canvasWidth = canvasWidth + 30
|
||||
if (canvasWidth < this.options.lineWidth) {
|
||||
canvasWidth = this.options.lineWidth
|
||||
}
|
||||
this.#canvas.width = canvasWidth
|
||||
this.#canvas.height = this.options.pixelOffset + canvasHeight
|
||||
const linearGradient = ctx.createLinearGradient(
|
||||
0,
|
||||
0,
|
||||
canvasWidth,
|
||||
canvasHeight + 20
|
||||
)
|
||||
linearGradient.addColorStop(0, this.options.backgroundColor[0])
|
||||
linearGradient.addColorStop(1, this.options.backgroundColor[1])
|
||||
ctx.fillStyle = linearGradient
|
||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight)
|
||||
ctx.fillStyle = this.options.color
|
||||
ctx.font = this.options.fontSize + 'px ' + this.font
|
||||
let maxWidth = 0
|
||||
for (let i = 0; i < texts.length; i++) {
|
||||
let width = ctx.measureText(texts[i]).width
|
||||
if (maxWidth < width) {
|
||||
maxWidth = width
|
||||
}
|
||||
}
|
||||
maxWidth = maxWidth + 30
|
||||
let centerDistance = (canvasWidth - maxWidth) / 2
|
||||
for (let i = 0; i < texts.length; i++) {
|
||||
const text = texts[i]
|
||||
if (this.options.fontSize < 10) {
|
||||
ctx.fillText(text, 15 + centerDistance, this.options.fontSize * (i + 1) + 10 + i * 5)
|
||||
} else {
|
||||
ctx.fillText(
|
||||
text,
|
||||
15 + centerDistance,
|
||||
this.options.fontSize * (i + 1) +
|
||||
(10 * 10) / this.options.fontSize +
|
||||
i * 5
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 虚线
|
||||
ctx.strokeStyle = this.options.lineColor
|
||||
ctx.setLineDash([4, 4]) //设置虚线长度4,间隔为4
|
||||
ctx.lineWidth = this.options.lineWidth
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(canvasWidth / 2, canvasHeight)
|
||||
ctx.lineTo(canvasWidth / 2, canvasHeight + this.options.pixelOffset)
|
||||
ctx.stroke()
|
||||
ctx.closePath()
|
||||
|
||||
const ctx2 = this.#canvas2.getContext('2d')
|
||||
this.#canvas2.width = this.#canvas.width + 10
|
||||
this.#canvas2.height = this.#canvas.height + 10
|
||||
ctx2.drawImage(this.#canvas, 5, 5);
|
||||
|
||||
// const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
// ctx.putImageData(imageData, 40, 40);
|
||||
return this.#canvas2.toDataURL("image/png")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
1360
src/Obj/Base/LoadObjModel/AModelLoader.js
Normal file
1360
src/Obj/Base/LoadObjModel/AModelLoader.js
Normal file
File diff suppressed because it is too large
Load Diff
105
src/Obj/Base/LoadObjModel/_element.js
Normal file
105
src/Obj/Base/LoadObjModel/_element.js
Normal file
@ -0,0 +1,105 @@
|
||||
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input name" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">海拔高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" step="0.01" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="lable-left-line">
|
||||
<span>缩放</span>
|
||||
<div class="checkbox-box" style="display: flex;align-items: center;margin-left: 20px;">
|
||||
<input type="checkbox" style="width: 14px;height: 14px;margin-top: 2px;margin-right: 5px;cursor: pointer;">
|
||||
<span>是否等比例缩放</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-equal" style="display: none;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">x 轴</span>
|
||||
<input class="scale-x" style="flex: 1;margin-right: 15px;" type="range" max="99" min="0.0001" step="0.01" @model="scaleX">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input class="scale-x" style="width: 100px;" type="number" title="" min="0" max="99" step="0.01" @model="scaleX">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">y 轴</span>
|
||||
<input class="scale-y" style="flex: 1;margin-right: 15px;" type="range" max="99" min="0.0001" step="0.01" @model="scaleY">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input class="scale-y" style="width: 100px;" type="number" title="" min="0" max="99" step="0.01" @model="scaleY">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">z 轴</span>
|
||||
<input class="scale-z" style="flex: 1;margin-right: 15px;" type="range" max="99" min="0.0001" step="0.01" @model="scaleZ">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input class="scale-z" style="width: 100px;" type="number" title="" min="0" max="99" step="0.01" @model="scaleZ">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row equal" style="display: none;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">等比例缩放</span>
|
||||
<input class="scale-all" style="flex: 1;margin-right: 15px;" type="range" max="99" min="0.0001" step="0.01">
|
||||
<div class="input-number input-number-unit-1" style="width: auto;">
|
||||
<input class="scale-all" style="width: 100px;" type="number" title="" min="0" max="99" step="0.01">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
35
src/Obj/Base/LoadObjModel/flvplayer.js
Normal file
35
src/Obj/Base/LoadObjModel/flvplayer.js
Normal file
@ -0,0 +1,35 @@
|
||||
class flvplayer {
|
||||
constructor(dom, options) {
|
||||
this.dom = dom
|
||||
this.playerUrl = options.url
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
this.flvPlayer = flvjs.createPlayer({
|
||||
type: 'flv',
|
||||
url: this.playerUrl,
|
||||
isLive: true,
|
||||
hasAudio: false,
|
||||
hasVideo: true
|
||||
},{
|
||||
enableWorker: true,
|
||||
enableStashBuffer: false,
|
||||
stashInitialSize: 128
|
||||
});
|
||||
this.flvPlayer.attachMediaElement(this.dom);
|
||||
this.flvPlayer.load();
|
||||
// this.flvPlayer.play();
|
||||
}
|
||||
|
||||
on(type, Events, cd) {
|
||||
this.flvPlayer.on(flvjs[type][Events], cd)
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.flvPlayer.destroy()
|
||||
this.flvPlayer = null
|
||||
}
|
||||
}
|
||||
|
||||
export default flvplayer
|
||||
700
src/Obj/Base/LoadObjModel/index.js
Normal file
700
src/Obj/Base/LoadObjModel/index.js
Normal file
@ -0,0 +1,700 @@
|
||||
import { getHost, getToken } from "../../../on";
|
||||
import tools from '../../../Tools'
|
||||
import { html } from "./_element";
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import ControllerObject from '../../../Controller'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
export default class LoadObjModel extends tools {
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super()
|
||||
// eslint-disable-next-line no-undef
|
||||
this.sdk = sdk
|
||||
this.viwer = sdk.viewer
|
||||
this.options = { ...options }
|
||||
this.options.host = options.host || getHost()
|
||||
this.options.name = options.name || '未命名对象'
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
if (typeof options.scale === 'number') {
|
||||
this.options.scale = {}
|
||||
this.options.scale.x = options.scale
|
||||
this.options.scale.y = options.scale
|
||||
this.options.scale.z = options.scale
|
||||
}
|
||||
else {
|
||||
this.options.scale = options.scale || {}
|
||||
this.options.scale.x = (this.options.scale.x || this.options.scale.x === 0) ? this.options.scale.x : 1
|
||||
this.options.scale.y = (this.options.scale.y || this.options.scale.y === 0) ? this.options.scale.y : 1
|
||||
this.options.scale.z = (this.options.scale.z || this.options.scale.z === 0) ? this.options.scale.z : 1
|
||||
}
|
||||
this.primitive = null
|
||||
this._loadEvent = void 0
|
||||
this._loaded = false
|
||||
this._elms = {};
|
||||
this.Dialog = _Dialog
|
||||
this._EventBinding = new EventBinding()
|
||||
LoadObjModel.setDefaultValue(this)
|
||||
this.requestResource()
|
||||
this.ControllerObject = new ControllerObject(this.sdk, {
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
})
|
||||
this.ControllerObject.controllerCallBack = this.controllerCallBack
|
||||
this.HeadingPitchRollCallBack = this.Dialog.HeadingPitchRollCallBack
|
||||
|
||||
// this.viwer.camera.moveEnd.addEventListener(() => {
|
||||
// if (this.options.show && this.primitive && this.primitive.video && this.primitive.video.player && this.options.position) {
|
||||
// const position1 = Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt);
|
||||
// const position2 = this.viwer.camera.position
|
||||
// const distance = Cesium.Cartesian3.distance(position1, position2);
|
||||
// if (this.options.playDistance && distance > this.options.playDistance) {
|
||||
// this.primitive.video.player.getVueInstance().pause()
|
||||
// }
|
||||
// else {
|
||||
// this.primitive.video.player.getVueInstance().play()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
requestResource() {
|
||||
this.addResource().then(r => { })
|
||||
}
|
||||
|
||||
static setDefaultValue(that) {
|
||||
that.options.id = that.options.id || that.randomString()
|
||||
that.options.position = that.options.position
|
||||
that.options.objUrl = that.options.objUrl || ''
|
||||
that.options.videoUrl = that.options.videoUrl || ''
|
||||
that.options.xmlURL = that.options.xmlURL || ''
|
||||
that.options.heading = that.options.heading || 0
|
||||
that.options.pitch = that.options.pitch || 0
|
||||
that.options.roll = that.options.roll || 0
|
||||
}
|
||||
async addResource() {
|
||||
let that = this
|
||||
that.options.xmlURL = that.options.objUrl.replace('.obj', '.xml')
|
||||
if (that.options.xmlURL !== '') {
|
||||
const xml = await fetch(that.options.xmlURL)
|
||||
if (xml.ok) {
|
||||
const xmlString = await xml.text()
|
||||
const parser = new DOMParser()
|
||||
const xmlDoc = parser.parseFromString(xmlString, 'text/xml')
|
||||
// console.log('xmlDocxmlDocxmlDoc', xmlDoc)
|
||||
const position = xmlDoc
|
||||
.getElementsByTagName('Position')[0]
|
||||
.textContent.split(',')
|
||||
// const bbox = xmlDoc.getElementsByTagName('bbox')[0]
|
||||
const crs = xmlDoc.getElementsByTagName('Crs')[0].textContent
|
||||
const result = that.convert(
|
||||
[{ x: position[0], y: position[1], z: position[2] }],
|
||||
crs,
|
||||
'EPSG:4326'
|
||||
)
|
||||
|
||||
that.options.position = that.options.position || { lng: result.points[0].x, lat: result.points[0].y, alt: result.points[0].z }
|
||||
that.ControllerObject.position = that.options.position
|
||||
const scene = that.viwer.scene
|
||||
const origin = Cesium.Cartesian3.fromDegrees(
|
||||
that.options.position.lng,
|
||||
that.options.position.lat,
|
||||
that.options.position.alt
|
||||
)
|
||||
const obj_modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||
origin,
|
||||
new Cesium.HeadingPitchRoll(
|
||||
Cesium.Math.toRadians(0.85),
|
||||
Cesium.Math.toRadians(0),
|
||||
Cesium.Math.toRadians(0)
|
||||
)
|
||||
)
|
||||
let obj = await window.objLoader.Load(that.options.objUrl)
|
||||
obj.show = that.options.show
|
||||
obj.modelMatrix = obj_modelMatrix
|
||||
obj.setFlvVideo(that.options.videoUrl)
|
||||
scene.primitives.add(obj)
|
||||
that.primitive = obj
|
||||
that.controllerCallBack({
|
||||
rotate: { x: that.options.roll, y: -that.options.pitch, z: -that.options.heading },
|
||||
position: { ...that.options.position }
|
||||
})
|
||||
this.loaded = true
|
||||
this._loaded = true
|
||||
if (this._loadEvent) {
|
||||
this._loadEvent()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('请填写xml路径')
|
||||
return
|
||||
}
|
||||
if (that.options.objUrl === '') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('请填写obj模型路径')
|
||||
return
|
||||
}
|
||||
}
|
||||
async flyTo(options = {}) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else if (this.options.start) {
|
||||
position = { ...this.options.start }
|
||||
}
|
||||
else {
|
||||
if (this.options.hasOwnProperty('lng')) {
|
||||
position.lng = this.options.lng
|
||||
}
|
||||
if (this.options.hasOwnProperty('lat')) {
|
||||
position.lat = this.options.lat
|
||||
}
|
||||
if (this.options.hasOwnProperty('alt')) {
|
||||
position.alt = this.options.alt
|
||||
}
|
||||
}
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
if (!position.hasOwnProperty('alt')) {
|
||||
position.alt = await this.getClampToHeight(position)
|
||||
}
|
||||
lng = this.options.customView.relativePosition.lng + position.lng
|
||||
lat = this.options.customView.relativePosition.lat + position.lat
|
||||
alt = this.options.customView.relativePosition.alt + position.alt
|
||||
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation
|
||||
})
|
||||
}
|
||||
else {
|
||||
let a = 100 * Math.tan(60)
|
||||
let latitude = a / 111319.55
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: new Cesium.Cartesian3.fromDegrees(
|
||||
this.options.position.lng,
|
||||
this.options.position.lat - latitude,
|
||||
this.options.position.alt + 100
|
||||
),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-60.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async edit(state = false) {
|
||||
let equal = false
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '编辑属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
|
||||
},
|
||||
// resetCallBack: () => {
|
||||
// this.name = this.originalOptions.name
|
||||
// this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
// },
|
||||
resetCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
},
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
this.positionEditing = false
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
rotateCallBack: () => {
|
||||
if (this.rotationEditing) {
|
||||
this.rotationEditing = false
|
||||
}
|
||||
else {
|
||||
this.rotationEditing = true
|
||||
}
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
if (this.positionEditing) {
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
this.positionEditing = true
|
||||
}
|
||||
}
|
||||
}, true)
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.style.width = '448px'
|
||||
contentElm.innerHTML = html()
|
||||
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
let equalSwitchElm = this._DialogObject._element.content.getElementsByClassName('checkbox-box')[0].querySelector('input')
|
||||
let equalBoxElm = this._DialogObject._element.content.getElementsByClassName('equal')[0]
|
||||
let noEqualBoxElm = this._DialogObject._element.content.getElementsByClassName('no-equal')[0]
|
||||
equalSwitchElm.checked = equal
|
||||
equalSwitchElm.addEventListener('change', (e) => {
|
||||
equal = e.target.checked
|
||||
if (equal) {
|
||||
equalBoxElm.style.display = 'flex'
|
||||
noEqualBoxElm.style.display = 'none'
|
||||
}
|
||||
else {
|
||||
equalBoxElm.style.display = 'none'
|
||||
noEqualBoxElm.style.display = 'flex'
|
||||
}
|
||||
})
|
||||
|
||||
let equalElms = equalBoxElm.getElementsByTagName('input')
|
||||
equalElms[0].value = this.scaleX
|
||||
equalElms[1].value = this.scaleX
|
||||
|
||||
equalElms[0].addEventListener('input', (e) => {
|
||||
this.scaleX = e.target.value
|
||||
this.scaleY = e.target.value
|
||||
this.scaleZ = e.target.value
|
||||
})
|
||||
equalElms[1].addEventListener('input', (e) => {
|
||||
this.scaleX = e.target.value
|
||||
this.scaleY = e.target.value
|
||||
this.scaleZ = e.target.value
|
||||
})
|
||||
|
||||
if (equal) {
|
||||
equalBoxElm.style.display = 'flex'
|
||||
noEqualBoxElm.style.display = 'none'
|
||||
}
|
||||
else {
|
||||
equalBoxElm.style.display = 'none'
|
||||
noEqualBoxElm.style.display = 'flex'
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (this._DialogObject._element.foot) {
|
||||
let translationalElm = this._DialogObject._element.foot.getElementsByClassName('rotate')[0]
|
||||
if (translationalElm) {
|
||||
translationalElm.style.position = 'absolute'
|
||||
translationalElm.style.left = '100px'
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
|
||||
for (let i = 0; i < all_elm.length; i++) {
|
||||
all_elm[i].addEventListener('input', (e) => {
|
||||
if (e.target.value === '0' && e.target.min === '0') {
|
||||
switch (e.target.className) {
|
||||
case 'scale-x':
|
||||
this.scaleX = 0.0001
|
||||
break;
|
||||
case 'scale-y':
|
||||
this.scaleY = 0.0001
|
||||
break;
|
||||
case 'scale-z':
|
||||
this.scaleZ = 0.0001
|
||||
case 'scale-all':
|
||||
this.scaleX = 0.0001
|
||||
this.scaleY = 0.0001
|
||||
this.scaleZ = 0.0001
|
||||
break;
|
||||
case 3:
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
this._elms.scaleX.push(equalElms[0], equalElms[1])
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.ControllerObject.destroy()
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.name = this.options.name
|
||||
if (!this.primitive) {
|
||||
return
|
||||
}
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||
new Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt)
|
||||
)
|
||||
this.primitive.modelMatrix = m
|
||||
// 旋转
|
||||
this.primitive.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(
|
||||
this.primitive.modelMatrix,
|
||||
Cesium.Matrix3.fromHeadingPitchRoll(
|
||||
Cesium.HeadingPitchRoll.fromDegrees(this.options.heading, this.options.pitch, this.options.roll)
|
||||
),
|
||||
this.primitive.modelMatrix
|
||||
)
|
||||
|
||||
// 缩放
|
||||
let scaleX = this.options.scale.x
|
||||
let scaleY = this.options.scale.y
|
||||
let scaleZ = this.options.scale.z
|
||||
if (scaleX === 0) {
|
||||
scaleX = 0.00001
|
||||
}
|
||||
if (scaleY === 0) {
|
||||
scaleY = 0.00001
|
||||
}
|
||||
if (scaleZ === 0) {
|
||||
scaleZ = 0.00001
|
||||
}
|
||||
Cesium.Matrix4.multiplyByScale(this.primitive.modelMatrix, new Cesium.Cartesian3(scaleX, scaleY, scaleZ), this.primitive.modelMatrix)
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.sdk.viewer.scene.primitives.remove(this.primitive)
|
||||
this.primitive = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
|
||||
set controllerCallBack(callback) {
|
||||
this._controllerCallBack = callback
|
||||
}
|
||||
get controllerCallBack() {
|
||||
return params => {
|
||||
this.options.heading = -params.rotate.z
|
||||
this.options.pitch = -params.rotate.y
|
||||
this.options.roll = params.rotate.x
|
||||
this.HeadingPitchRollCallBack && this.HeadingPitchRollCallBack(params)
|
||||
let lng = Number(Number(params.position.lng).toFixed(8))
|
||||
let lat = Number(Number(params.position.lat).toFixed(8))
|
||||
let alt = Number(Number(params.position.alt).toFixed(2))
|
||||
this.options.position = { lng, lat, alt }
|
||||
// 平移
|
||||
let m = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||
new Cesium.Cartesian3.fromDegrees(params.position.lng, params.position.lat, params.position.alt)
|
||||
)
|
||||
this.primitive.modelMatrix = m
|
||||
// 旋转
|
||||
Cesium.Matrix4.multiplyByMatrix3(
|
||||
this.primitive.modelMatrix,
|
||||
Cesium.Matrix3.fromHeadingPitchRoll(
|
||||
Cesium.HeadingPitchRoll.fromDegrees(-params.rotate.z, -params.rotate.y, params.rotate.x)
|
||||
),
|
||||
this.primitive.modelMatrix
|
||||
)
|
||||
|
||||
// 缩放
|
||||
let scaleX = this.options.scale.x
|
||||
let scaleY = this.options.scale.y
|
||||
let scaleZ = this.options.scale.z
|
||||
if (scaleX === 0) {
|
||||
scaleX = 0.00001
|
||||
}
|
||||
if (scaleY === 0) {
|
||||
scaleY = 0.00001
|
||||
}
|
||||
if (scaleZ === 0) {
|
||||
scaleZ = 0.00001
|
||||
}
|
||||
Cesium.Matrix4.multiplyByScale(this.primitive.modelMatrix, new Cesium.Cartesian3(scaleX, scaleY, scaleZ), this.primitive.modelMatrix)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.position.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.position.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.position.alt
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get name() {
|
||||
return this.options.name
|
||||
}
|
||||
set name(v) {
|
||||
this.options.name = v
|
||||
this._elms.name && this._elms.name.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 打开模型旋转功能
|
||||
* @param status {boolean}
|
||||
* @methodOf Source
|
||||
* */
|
||||
set rotationEditing(status) {
|
||||
if (status) {
|
||||
this.ControllerObject.editRtation()
|
||||
} else {
|
||||
this.ControllerObject.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get scaleX() {
|
||||
return this.options.scale.x
|
||||
}
|
||||
|
||||
set scaleX(v) {
|
||||
this.options.scale.x = Number(Number(v).toFixed(4))
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
this._elms.scaleX && this._elms.scaleX.forEach((item) => {
|
||||
item.value = this.options.scale.x
|
||||
})
|
||||
}
|
||||
|
||||
get scaleY() {
|
||||
return this.options.scale.y
|
||||
}
|
||||
|
||||
set scaleY(v) {
|
||||
this.options.scale.y = Number(Number(v).toFixed(4))
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
this._elms.scaleY && this._elms.scaleY.forEach((item) => {
|
||||
item.value = this.options.scale.y
|
||||
})
|
||||
}
|
||||
|
||||
get scaleZ() {
|
||||
return this.options.scale.z
|
||||
}
|
||||
|
||||
set scaleZ(v) {
|
||||
this.options.scale.z = Number(Number(v).toFixed(4))
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
this._elms.scaleZ && this._elms.scaleZ.forEach((item) => {
|
||||
item.value = this.options.scale.z
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 获取模型旋转状态
|
||||
* @method rotationEditing
|
||||
* @return boolean
|
||||
* @methodOf Source
|
||||
|
||||
* */
|
||||
get rotationEditing() {
|
||||
if (this.ControllerObject.getActiveState() === 'rtation') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**@desc 打开平移模型功能
|
||||
*
|
||||
* @memberOf Source
|
||||
*@param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.ControllerObject) {
|
||||
return
|
||||
}
|
||||
if (status) {
|
||||
this.ControllerObject.editTranslational()
|
||||
} else {
|
||||
this.ControllerObject.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
if (this.ControllerObject.getActiveState() === 'translational') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.position.lng
|
||||
}
|
||||
set lng(v) {
|
||||
this.options.position.lng = v
|
||||
this.ControllerObject.position = {lng: this.options.position.lng, lat: this.options.position.lat, alt: this.options.position.alt}
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.position.lat
|
||||
}
|
||||
set lat(v) {
|
||||
this.options.position.lat = v
|
||||
this.ControllerObject.position = {lng: this.options.position.lng, lat: this.options.position.lat, alt: this.options.position.alt}
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.position.alt
|
||||
}
|
||||
set alt(v) {
|
||||
this.options.position.alt = v
|
||||
this.ControllerObject.position = {lng: this.options.position.lng, lat: this.options.position.lat, alt: this.options.position.alt}
|
||||
this.controllerCallBack(
|
||||
{
|
||||
position: { ...this.options.position },
|
||||
rotate: {
|
||||
x: (360 + (this.options.roll % 360)) % 360,
|
||||
y: (360 + (-this.options.pitch % 360)) % 360,
|
||||
z: (360 + (-this.options.heading % 360)) % 360
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.show = v
|
||||
this.primitive.show = v
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
get playDistance() {
|
||||
return this.options.playDistance
|
||||
}
|
||||
|
||||
set playDistance(v) {
|
||||
this.options.playDistance = v
|
||||
// this._elms.playDistance && this._elms.playDistance.forEach((item) => {
|
||||
// item.value = this.options.playDistance
|
||||
// })
|
||||
// if (this.options.show && this.primitive && this.primitive.video && this.primitive.video.player && this.options.position) {
|
||||
// const position1 = Cesium.Cartesian3.fromDegrees(this.options.position.lng, this.options.position.lat, this.options.position.alt);
|
||||
// const position2 = this.viwer.camera.position
|
||||
// const distance = Cesium.Cartesian3.distance(position1, position2);
|
||||
// if (this.options.playDistance && distance > this.options.playDistance) {
|
||||
// this.primitive.video.player.getVueInstance().pause()
|
||||
// }
|
||||
// else {
|
||||
// this.primitive.video.player.getVueInstance().play()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
|
||||
load(callback) {
|
||||
if (this._loaded) {
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
this._loadEvent = callback
|
||||
}
|
||||
}
|
||||
|
||||
get customView() {
|
||||
this.options.customView
|
||||
}
|
||||
|
||||
// 设置视角
|
||||
setCustomView(val) {
|
||||
if (val) {
|
||||
this.options.customView = val
|
||||
}
|
||||
else {
|
||||
let camera = this.sdk.viewer.camera
|
||||
this.options.customView = {
|
||||
orientation: { heading: camera.heading, pitch: camera.pitch, roll: camera.roll },
|
||||
position: { x: camera.position.x, y: camera.position.y, z: camera.position.z }
|
||||
}
|
||||
this.originalOptions && (this.originalOptions.customView = this.options.customView)
|
||||
}
|
||||
}
|
||||
// 重置视角
|
||||
resetCustomView() {
|
||||
this.options.customView = undefined
|
||||
}
|
||||
}
|
||||
63
src/Obj/Base/LoadObjModel/jessibucaPlayer.js
Normal file
63
src/Obj/Base/LoadObjModel/jessibucaPlayer.js
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
class jessibucaPlayer {
|
||||
constructor(dom, options) {
|
||||
this.dom = dom
|
||||
this.url = options.url
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
this.player = new Jessibuca({
|
||||
container: this.dom,
|
||||
decoder:this.getSourceRootPath() + '/3rdparty/jessibuca/decoder.js',
|
||||
timeout: 30,
|
||||
heartTimeout: 30,
|
||||
heartTimeoutReplay: false,
|
||||
loadingTimeout: 30,
|
||||
loadingTimeoutReplay: false,
|
||||
wasmDecodeErrorReplay: false,
|
||||
videoBuffer: 0.2, // 缓存时长
|
||||
isResize: false,
|
||||
text: "",
|
||||
loadingText: "",
|
||||
useMSE: false,
|
||||
debug: true,
|
||||
showBandwidth: false, // 显示网速
|
||||
operateBtns: {
|
||||
fullscreen: false,
|
||||
screenshot: false,
|
||||
play: false,
|
||||
audio: false,
|
||||
recorder: false
|
||||
},
|
||||
forceNoOffscreen: false,
|
||||
isNotMute: false,
|
||||
},);
|
||||
this.player.play(this.url);
|
||||
}
|
||||
|
||||
on(Events, cd) {
|
||||
this.player.on(Events, cd)
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.player.destroy()
|
||||
this.player = null
|
||||
}
|
||||
|
||||
getSourceRootPath() {
|
||||
let sdkName = 'YJEarth.min.js'
|
||||
let scripts = document.querySelectorAll('script')
|
||||
let prefix = ''
|
||||
scripts.forEach((item) => {
|
||||
if (item.src && item.src.indexOf(sdkName) > -1) {
|
||||
let arr = item.src.split('/')
|
||||
arr.pop()
|
||||
prefix = arr.join('/')
|
||||
}
|
||||
})
|
||||
return prefix
|
||||
}
|
||||
}
|
||||
|
||||
export default jessibucaPlayer
|
||||
50
src/Obj/Base/LocateCurrent/_element.js
Normal file
50
src/Obj/Base/LocateCurrent/_element.js
Normal file
@ -0,0 +1,50 @@
|
||||
import Tools from "../../../Tools";
|
||||
function _element() {
|
||||
let tools = new Tools()
|
||||
let elm = document.createElement('div');
|
||||
elm.className = 'locate-current-bubble-box'
|
||||
elm.innerHTML = `
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="lng" style="display: flex;align-items: center;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/lng.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">经度:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="lat" style="display: flex;align-items: center;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/lat.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">纬度:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="height" style="display: flex;align-items: center;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/h.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">海拔:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="satellite" style="display: flex;align-items: center;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/satellite.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">卫星:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
elm.style.position = 'absolute'
|
||||
elm.style.background = `url(${tools.getSourceRootPath() + '/img/bubble/bubble.png'}) no-repeat 100% 100%`;
|
||||
elm.style.backgroundSize = '100% 100%'
|
||||
elm.style.width = '220px'
|
||||
elm.style.height = '140px'
|
||||
elm.style.color = '#ffffff'
|
||||
elm.style.padding = '10px'
|
||||
elm.style.boxSizing = 'border-box'
|
||||
elm.style.fontSize = '14px'
|
||||
elm.style.pointerEvents = 'none'
|
||||
document.body.appendChild(elm)
|
||||
return elm
|
||||
}
|
||||
|
||||
export { _element }
|
||||
58
src/Obj/Base/LocateCurrent/_element2.js
Normal file
58
src/Obj/Base/LocateCurrent/_element2.js
Normal file
@ -0,0 +1,58 @@
|
||||
import Tools from "../../../Tools";
|
||||
function _element() {
|
||||
let tools = new Tools()
|
||||
let elm = document.createElement('div');
|
||||
elm.className = 'locate-current-bubble-box'
|
||||
elm.innerHTML = `
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="lng" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/lng.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">经度:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="ew" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/e.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">东经:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="lat" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/lat.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">纬度:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="sn" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/s.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">南纬:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content: space-between;margin: 6px;margin-top: 0;">
|
||||
<div class="height" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/h.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">高程:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="satellite" style="display: flex;align-items: center;width: 48%;">
|
||||
<i style="display: inline-block;width: 20px;height: 20px;flex: 0 0 20px;margin-right: 10px;background: url(${tools.getSourceRootPath() + '/img/bubble/satellite.png'}) no-repeat 100% 100%;"></i>
|
||||
<span style="white-space: nowrap;">卫星:</span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
elm.style.position = 'absolute'
|
||||
elm.style.background = `url(${tools.getSourceRootPath() + '/img/bubble/bubble.png'}) no-repeat 100% 100%`;
|
||||
elm.style.backgroundSize = '100% 100%'
|
||||
elm.style.width = '400px'
|
||||
elm.style.height = '115px'
|
||||
elm.style.color = '#ffffff'
|
||||
elm.style.padding = '10px'
|
||||
elm.style.boxSizing = 'border-box'
|
||||
elm.style.fontSize = '14px'
|
||||
elm.style.pointerEvents = 'none'
|
||||
document.body.appendChild(elm)
|
||||
return elm
|
||||
}
|
||||
|
||||
export { _element }
|
||||
210
src/Obj/Base/LocateCurrent/index.js
Normal file
210
src/Obj/Base/LocateCurrent/index.js
Normal file
@ -0,0 +1,210 @@
|
||||
import { getHost } from "../../../on";
|
||||
import Tools from "../../../Tools";
|
||||
import { getGroundCover } from '../../../Global/global'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
class LocateCurrent {
|
||||
#canvas = null
|
||||
#img = {
|
||||
bgimg: null,
|
||||
img1: null,
|
||||
img2: null,
|
||||
img3: null,
|
||||
img4: null,
|
||||
}
|
||||
constructor(sdk, options = {}, callback) {
|
||||
this.sdk = sdk
|
||||
this.options = options
|
||||
this.data = {}
|
||||
this._webSocketCallback = callback
|
||||
this._tools = new Tools(this.sdk)
|
||||
this.requestResource()
|
||||
}
|
||||
|
||||
requestResource() {
|
||||
this.options.host = this.options.host || getHost()
|
||||
let url = ""
|
||||
url = this.options.host + '/yjearth4.0/api/v1/gps/state'
|
||||
this.reconnecting = new ReconnectingWebSocket('ws://' + url, [], { maxReconnectAttempts: 8 })
|
||||
this.reconnecting.onopen = (event) => {
|
||||
this.reconnecting.onmessage = async (event) => {
|
||||
this.data = JSON.parse(event.data)
|
||||
if (this.data && this.data.rmc) {
|
||||
let height = await this._tools.getClampToHeight(this.data.rmc)
|
||||
this.position = new Cesium.Cartesian3.fromDegrees(this.data.rmc.lng, this.data.rmc.lat, height);
|
||||
this.create()
|
||||
}
|
||||
this._webSocketCallback && this._webSocketCallback(this.data)
|
||||
}
|
||||
}
|
||||
|
||||
// let _this = this
|
||||
// this.data = {
|
||||
// rmc: {
|
||||
// lng: 116.397428,
|
||||
// lat: 39.90923,
|
||||
// alt: 100
|
||||
// }
|
||||
// }
|
||||
// this.position = new Cesium.Cartesian3.fromDegrees(this.data.rmc.lng, this.data.rmc.lat, 0);
|
||||
// setInterval(() => {
|
||||
// _this.create()
|
||||
// console.log(1111)
|
||||
// }, 50);
|
||||
}
|
||||
|
||||
create() {
|
||||
this.getcanvas()
|
||||
if (this.data && this.data.rmc && !this.entity) {
|
||||
this.entity = new Cesium.CustomDataSource();
|
||||
this.sdk.viewer.dataSources.add(this.entity);
|
||||
let point = new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let c3 = this.position
|
||||
return c3
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this._tools.getSourceRootPath() + '/img/locate2.png',
|
||||
scale: 1,
|
||||
disableDepthTestDistance: new Cesium.CallbackProperty(function () {
|
||||
return getGroundCover() ? undefined : 100000000
|
||||
}, false),
|
||||
width: 31,
|
||||
height: 36,
|
||||
pixelOffset: new Cesium.Cartesian2(0, -15),
|
||||
},
|
||||
})
|
||||
let lable = new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let c3 = this.position
|
||||
return c3
|
||||
}, false),
|
||||
billboard: {
|
||||
image: new Cesium.CallbackProperty(() => {
|
||||
return this.lableCanvas
|
||||
}),
|
||||
scale: 1,
|
||||
disableDepthTestDistance: new Cesium.CallbackProperty(function () {
|
||||
return getGroundCover() ? undefined : 100000000
|
||||
}, false),
|
||||
width: 220,
|
||||
height: 140,
|
||||
pixelOffset: new Cesium.Cartesian2(0, -110),
|
||||
},
|
||||
})
|
||||
this.entity.entities.add(point)
|
||||
this.entity.entities.add(lable)
|
||||
}
|
||||
}
|
||||
|
||||
loaded(cd) {
|
||||
let data
|
||||
Object.defineProperty(this, 'data', {
|
||||
get() {
|
||||
return data
|
||||
},
|
||||
set(value) {
|
||||
data = value
|
||||
if (cd) {
|
||||
cd()
|
||||
cd = undefined
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getcanvas() {
|
||||
const data = [
|
||||
{
|
||||
images: this._tools.getSourceRootPath() + '/img/bubble/lng.png',
|
||||
text: '经度:' + parseFloat(this.data.rmc.lng.toFixed(10))
|
||||
},
|
||||
{
|
||||
images: this._tools.getSourceRootPath() + '/img/bubble/lat.png',
|
||||
text: '纬度:' + parseFloat(this.data.rmc.lat.toFixed(10))
|
||||
},
|
||||
{
|
||||
images: this._tools.getSourceRootPath() + '/img/bubble/h.png',
|
||||
text: '海拔:' + parseFloat(this.data.rmc.alt.toFixed(10))
|
||||
},
|
||||
{
|
||||
images: this._tools.getSourceRootPath() + '/img/bubble/satellite.png',
|
||||
text: '卫星:' + this.data.satellites || 0
|
||||
}
|
||||
]
|
||||
if (this.#canvas) {
|
||||
const ctx = this.#canvas.getContext('2d')
|
||||
ctx.clearRect(0, 0, this.#canvas.width, this.#canvas.height);
|
||||
ctx.drawImage(this.#img.bgimg, 0, 0, this.#canvas.width, this.#canvas.height);
|
||||
let imagesLoaded = 0
|
||||
data.forEach((item, index) => {
|
||||
ctx.drawImage(this.#img['img' + (index + 1)], 12, 12 + (index * 26));
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.font = "16px Arial";
|
||||
ctx.fillText(item.text, 44, 28 + (index * 26));
|
||||
imagesLoaded++;
|
||||
if (imagesLoaded === data.length) {
|
||||
this.lableCanvas = this.#canvas.toDataURL()
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
this.#canvas = document.createElement('canvas');
|
||||
const ctx = this.#canvas.getContext('2d')
|
||||
this.#canvas.width = 220
|
||||
this.#canvas.height = 140
|
||||
let img = new Image();
|
||||
this.#img.bgimg = img
|
||||
img.src = this._tools.getSourceRootPath() + '/img/bubble/bubble.png';
|
||||
let imagesLoaded = 0
|
||||
img.onload = () => {
|
||||
ctx.drawImage(img, 0, 0, this.#canvas.width, this.#canvas.height);
|
||||
data.forEach((item, index) => {
|
||||
const img = new Image();
|
||||
this.#img['img' + (index + 1)] = img
|
||||
img.src = item.images;
|
||||
img.onload = () => {
|
||||
ctx.drawImage(img, 12, 12 + (index * 26));
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.font = "16px Arial";
|
||||
ctx.fillText(item.text, 44, 28 + (index * 26));
|
||||
imagesLoaded++;
|
||||
if (imagesLoaded === data.length) {
|
||||
this.lableCanvas = this.#canvas.toDataURL()
|
||||
}
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async flyTo(options = {}) {
|
||||
if (this.data && this.data.rmc) {
|
||||
let height = await this._tools.getClampToHeight(this.data.rmc)
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
},
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.data.rmc.lng, this.data.rmc.lat, height + (options.height || 500)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.#canvas = null
|
||||
this.#img = {}
|
||||
this.reconnecting && this.reconnecting.close()
|
||||
this.sdk.viewer.dataSources.remove(this.entity)
|
||||
this.entity = null
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default LocateCurrent
|
||||
111
src/Obj/Base/ParticleEffects/Flame/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Flame/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
||||
92
src/Obj/Base/ParticleEffects/Flame/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Flame/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] ||!elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
743
src/Obj/Base/ParticleEffects/Flame/index.js
Normal file
743
src/Obj/Base/ParticleEffects/Flame/index.js
Normal file
@ -0,0 +1,743 @@
|
||||
/**
|
||||
* 火焰特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncPrimitives } from '../../../../Global/MultiViewportMode'
|
||||
import { syncData, getSdk as get2DSdk } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Flame extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 火焰特效
|
||||
* @param sdk
|
||||
* @param options {object} 粒子属性
|
||||
* @param options.id {string} 标注id
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 贴图地址
|
||||
* @param options.startColor="#ff0000" {string} 起始颜色
|
||||
* @param options.endColor="#fff000" {string} 结束颜色
|
||||
* @param options.startScale=0.5 {number} 初始比例
|
||||
* @param options.endScale=2 {number} 结束比例
|
||||
* @param options.minimumSpeed=1 {number} 最小初速度
|
||||
* @param options.maximumSpeed=30 {number} 最大初速度
|
||||
* @param options.minimumParticleLife=1 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=2 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=60 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=10 {number} 粒子尺大小
|
||||
* @param options.lng 经度
|
||||
* @param options.lat 纬度
|
||||
* @param options.alt 高度
|
||||
* @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} 高度
|
||||
* */
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.url = options.url
|
||||
this.options.startColor = options.startColor || "#ff0000"
|
||||
this.options.endColor = options.endColor || "#fff000"
|
||||
this.options.startScale = options.startScale || 0.5
|
||||
this.options.endScale = options.endScale || 2
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 1
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 2
|
||||
this.options.minimumSpeed = options.minimumSpeed || 1
|
||||
this.options.maximumSpeed = options.maximumSpeed || 30
|
||||
this.options.emissionRate = options.emissionRate || 60
|
||||
this.options.particleSize = options.particleSize || 10
|
||||
this.options.show = options.show === false ? false : true
|
||||
this.positionCallBack = null
|
||||
this.rotationCallback = null
|
||||
this.onClickCallback = null
|
||||
this._DialogObject = null
|
||||
this._element = null
|
||||
this.particleSystem
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.add()
|
||||
this.operate = {}
|
||||
this._elms = {};
|
||||
this.previous = {
|
||||
positions: {
|
||||
lng: this.options.lng,
|
||||
lat: this.options.lat,
|
||||
alt: this.options.alt,
|
||||
}
|
||||
}
|
||||
this.Dialog = _Dialog
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "ParticleEffects"
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
let sdkD = get2DSdk().sdkD
|
||||
if (!this.isShowView || !sdkD) {
|
||||
this.options.show = v
|
||||
}
|
||||
if (!this.showView || this.showView == 3 || !sdkD) {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = this.options.show
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = this.options.show
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = false
|
||||
}
|
||||
}
|
||||
|
||||
if (this._DialogObject && this._DialogObject.showBtn) {
|
||||
this._DialogObject.showBtn.checked = v
|
||||
}
|
||||
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
this.isShowView = false
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async add() {
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
const scene = this.sdk.viewer.scene;
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(1, 1, 1), matrix)
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height
|
||||
this.particleSystem = scene.primitives.add(
|
||||
new Cesium.ParticleSystem({
|
||||
show: (cameraHeight >= 10000000) ? false : this.options.show,
|
||||
image: this.options.url || (this.getSourceRootPath() + '/img/particlesystem/smoke.png'),
|
||||
startColor: Cesium.Color.fromCssColorString(this.options.startColor), //粒子出生时的颜色
|
||||
endColor: Cesium.Color.fromCssColorString(this.options.endColor), //当粒子死亡时的颜色
|
||||
startScale: this.options.startScale, //粒子出生时的比例
|
||||
endScale: this.options.endScale, //粒子在死亡时的比例
|
||||
minimumParticleLife: this.options.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位)
|
||||
maximumParticleLife: this.options.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位)
|
||||
minimumSpeed: this.options.minimumSpeed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
|
||||
maximumSpeed: this.options.maximumSpeed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
|
||||
// imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小
|
||||
// this.options.imageSize || 10,
|
||||
// this.options.imageSize || 10
|
||||
// ),
|
||||
minimumImageSize: new Cesium.Cartesian2(
|
||||
this.options.particleSize,
|
||||
this.options.particleSize
|
||||
),
|
||||
maximumImageSize: new Cesium.Cartesian2(
|
||||
this.options.particleSize,
|
||||
this.options.particleSize
|
||||
),
|
||||
sizeInMeters: true,
|
||||
emissionRate: this.options.emissionRate, //每秒发射的粒子数。
|
||||
lifetime: 0.5,
|
||||
loop: true,
|
||||
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(30.0)),
|
||||
modelMatrix: matrix,
|
||||
updateCallback: (r) => {
|
||||
r._billboard.id = this.options.id
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// this.entity.modelMatrix
|
||||
this.particleSystem.id = this.options.id
|
||||
this.entity = this.particleSystem
|
||||
// this.entity.modelMatrix = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(100.0, 20.0)), new Cesium.Cartesian3(0.0, 0.0, 10000.0), new Cesium.Matrix4())
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
// this.editObj = new EditParticle(this.sdk, this.entity)
|
||||
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
|
||||
// 监听相机高度
|
||||
this.sdk.viewer.camera.changed.addEventListener(() => {
|
||||
if (this.entity && this.show) {
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
if (cameraHeight >= 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
else {
|
||||
this.entity.show = true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async flyTo(options = {}) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else {
|
||||
if (this.options.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 {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.lng, this.options.lat, this.options.alt + 500),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get startColor() {
|
||||
return this.options.startColor
|
||||
}
|
||||
|
||||
set startColor(v) {
|
||||
this.options.startColor = v
|
||||
this.particleSystem.startColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.startColor) {
|
||||
this._elms.startColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.startColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.startColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get endColor() {
|
||||
return this.options.endColor
|
||||
}
|
||||
|
||||
set endColor(v) {
|
||||
this.options.endColor = v
|
||||
this.particleSystem.endColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.endColor) {
|
||||
this._elms.endColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.endColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.endColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get minimumSpeed() {
|
||||
return this.options.minimumSpeed
|
||||
}
|
||||
|
||||
set minimumSpeed(v) {
|
||||
this.options.minimumSpeed = v
|
||||
this.particleSystem.minimumSpeed = v
|
||||
this._elms.minimumSpeed && this._elms.minimumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get maximumSpeed() {
|
||||
return this.options.maximumSpeed
|
||||
}
|
||||
|
||||
set maximumSpeed(v) {
|
||||
this.options.maximumSpeed = v
|
||||
this.particleSystem.maximumSpeed = v
|
||||
this._elms.maximumSpeed && this._elms.maximumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get minimumParticleLife() {
|
||||
return this.options.minimumParticleLife
|
||||
}
|
||||
|
||||
set minimumParticleLife(v) {
|
||||
this.options.minimumParticleLife = v
|
||||
this.particleSystem.minimumParticleLife = v
|
||||
this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get maximumParticleLife() {
|
||||
return this.options.maximumParticleLife
|
||||
}
|
||||
|
||||
set maximumParticleLife(v) {
|
||||
this.options.maximumParticleLife = v
|
||||
this.particleSystem.maximumParticleLife = v
|
||||
this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get startScale() {
|
||||
return this.options.startScale
|
||||
}
|
||||
|
||||
set startScale(v) {
|
||||
this.options.startScale = v
|
||||
this.particleSystem.startScale = v
|
||||
this._elms.startScale && this._elms.startScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get endScale() {
|
||||
return this.options.endScale
|
||||
}
|
||||
|
||||
set endScale(v) {
|
||||
this.options.endScale = v
|
||||
this.particleSystem.endScale = v
|
||||
this._elms.endScale && this._elms.endScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get emissionRate() {
|
||||
return this.options.emissionRate
|
||||
}
|
||||
|
||||
set emissionRate(v) {
|
||||
this.options.emissionRate = v
|
||||
this.particleSystem.emissionRate = v
|
||||
this._elms.emissionRate && this._elms.emissionRate.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get particleSize() {
|
||||
return this.options.particleSize
|
||||
}
|
||||
|
||||
set particleSize(v) {
|
||||
this.options.particleSize = v
|
||||
this.particleSystem.minimumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this.particleSystem.maximumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this._elms.particleSize && this._elms.particleSize.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.lng = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.lat = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.alt
|
||||
}
|
||||
|
||||
set alt(v) {
|
||||
this.options.alt = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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
|
||||
}
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' particle-effects'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let startColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("start_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.startColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.startColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let endColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("end_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.endColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.endColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
EventBinding.on(this, all_elm)
|
||||
this._elms = EventBinding.element
|
||||
this._elms.startColor = [startColorPicker]
|
||||
this._elms.endColor = [endColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.startColor = this.originalOptions.startColor
|
||||
this.endColor = this.originalOptions.endColor
|
||||
this.minimumSpeed = this.originalOptions.minimumSpeed
|
||||
this.maximumSpeed = this.originalOptions.maximumSpeed
|
||||
this.minimumParticleLife = this.originalOptions.minimumParticleLife
|
||||
this.maximumParticleLife = this.originalOptions.maximumParticleLife
|
||||
this.startScale = this.originalOptions.startScale
|
||||
this.endScale = this.originalOptions.endScale
|
||||
this.emissionRate = this.originalOptions.emissionRate
|
||||
this.particleSize = this.originalOptions.particleSize
|
||||
this.lng = this.originalOptions.lng
|
||||
this.lat = this.originalOptions.lat
|
||||
this.alt = this.originalOptions.alt
|
||||
syncPrimitives(this.entity)
|
||||
}
|
||||
|
||||
async remove() {
|
||||
super.remove()
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity);
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.operate.positionEditing = status
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.picking = false
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
let movPos
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
movPos = movement.endPosition
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
if (!movPos || movPos.x !== movement.position.x || movPos.y !== movement.position.y-2) {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
}
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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 {
|
||||
this.picking = true
|
||||
if (this.event) {
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
if(!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.options.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default Flame
|
||||
111
src/Obj/Base/ParticleEffects/Fountain/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Fountain/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
||||
92
src/Obj/Base/ParticleEffects/Fountain/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Fountain/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] ||!elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
765
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
765
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
@ -0,0 +1,765 @@
|
||||
/**
|
||||
* 喷泉特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData, getSdk as get2DSdk } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Fountain extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 喷泉特效
|
||||
* @param sdk
|
||||
* @param options {object} 粒子属性
|
||||
* @param options.id {string} 标注id
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 贴图地址
|
||||
* @param options.startColor="#c1f7f24d" {string} 起始颜色
|
||||
* @param options.endColor="#ffffff00" {string} 结束颜色
|
||||
* @param options.startScale=1 {number} 初始比例
|
||||
* @param options.endScale=20 {number} 结束比例
|
||||
* @param options.minimumSpeed=9 {number} 最小初速度
|
||||
* @param options.maximumSpeed=9.5 {number} 最大初速度
|
||||
* @param options.minimumParticleLife=6 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=7 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=20 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=0.5{number} 粒子尺大小
|
||||
* @param options.lng 经度
|
||||
* @param options.lat 纬度
|
||||
* @param options.alt 高度
|
||||
* @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} 高度
|
||||
* */
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.url = options.url
|
||||
this.options.startColor = options.startColor || "#c1f7f24d"
|
||||
this.options.endColor = options.endColor || "#ffffff00"
|
||||
this.options.startScale = options.startScale || 1
|
||||
this.options.endScale = options.endScale || 20
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 6
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 7
|
||||
this.options.minimumSpeed = options.minimumSpeed || 9
|
||||
this.options.maximumSpeed = options.maximumSpeed || 9.5
|
||||
this.options.emissionRate = options.emissionRate || 20
|
||||
this.options.particleSize = options.particleSize || 0.5
|
||||
// this.options.gravity = (options.gravity || options.gravity === 0) ? options.gravity : -3.5
|
||||
this.options.show = options.show === false ? false : true
|
||||
this._elms = {};
|
||||
this.positionCallBack = null
|
||||
this.rotationCallback = null
|
||||
this.onClickCallback = null
|
||||
this._DialogObject = null
|
||||
this._element = null
|
||||
this.particleSystem
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.add()
|
||||
this.operate = {}
|
||||
this.previous = {
|
||||
positions: {
|
||||
lng: this.options.lng,
|
||||
lat: this.options.lat,
|
||||
alt: this.options.alt,
|
||||
}
|
||||
}
|
||||
this.Dialog = _Dialog
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "ParticleEffects"
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
let sdkD = get2DSdk().sdkD
|
||||
if (!this.isShowView || !sdkD) {
|
||||
this.options.show = v
|
||||
}
|
||||
if (!this.showView || this.showView == 3 || !sdkD) {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = this.options.show
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = this.options.show
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = false
|
||||
}
|
||||
}
|
||||
if(this._DialogObject && this._DialogObject.showBtn) {
|
||||
this._DialogObject.showBtn.checked = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
this.isShowView = false
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async add() {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
const scene = this.sdk.viewer.scene;
|
||||
let gravityScratch = new Cesium.Cartesian3();
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(1, 1, 1), matrix)
|
||||
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height
|
||||
this.particleSystem = scene.primitives.add(
|
||||
new Cesium.ParticleSystem({
|
||||
show: (cameraHeight >= 10000000) ? false : this.options.show,
|
||||
image: this.options.url || (this.getSourceRootPath() + '/img/particlesystem/fountain.png'),
|
||||
// 从绿色到白色淡出
|
||||
startColor: Cesium.Color.fromCssColorString(this.options.startColor), //粒子出生时的颜色
|
||||
endColor: Cesium.Color.fromCssColorString(this.options.endColor), //当粒子死亡时的颜色
|
||||
startScale: this.options.startScale, //粒子出生时的比例
|
||||
endScale: this.options.endScale, //粒子在死亡时的比例
|
||||
minimumParticleLife: this.options.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位)
|
||||
maximumParticleLife: this.options.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位)
|
||||
minimumSpeed: this.options.minimumSpeed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
|
||||
maximumSpeed: this.options.maximumSpeed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
|
||||
// imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小
|
||||
// this.options.imageSize || 10,
|
||||
// this.options.imageSize || 10
|
||||
// ),
|
||||
lifetime: 0.5,
|
||||
imageSize: new Cesium.Cartesian2(this.options.particleSize, this.options.particleSize * 2),
|
||||
sizeInMeters: true,
|
||||
emissionRate: this.options.emissionRate, //每秒发射的粒子数。
|
||||
loop: true,
|
||||
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(0.2)),
|
||||
modelMatrix: matrix,
|
||||
emitterModelMatrix: computeEmitterodelMatrix(),// 发射器转换为世界坐标
|
||||
|
||||
// 增加重力场影像,
|
||||
updateCallback: applyGravity,
|
||||
})
|
||||
);
|
||||
let gravityVector = new Cesium.Cartesian3();
|
||||
let gravity = -3.5;// !!!重力方向向上向下 -(9.8*9.8)
|
||||
function applyGravity(p, dt) {
|
||||
p._billboard.id = _this.options.id
|
||||
let position = p.position;
|
||||
Cesium.Cartesian3.normalize(position, gravityVector);
|
||||
Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector);
|
||||
p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
|
||||
}
|
||||
|
||||
|
||||
// 计算粒子发射器的位置姿态
|
||||
function computeEmitterodelMatrix() {
|
||||
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);//!!!发射粒子的方向
|
||||
let trs = new Cesium.TranslationRotationScale();
|
||||
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0);
|
||||
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
|
||||
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
|
||||
return Matrix4
|
||||
}
|
||||
|
||||
|
||||
function computeModelMatrix(position) {
|
||||
let center = Cesium.Cartesian3.fromDegrees(120.40100613624982, 36.09030781, -5)
|
||||
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
|
||||
return modelMatrix;
|
||||
}
|
||||
|
||||
// this.entity.modelMatrix
|
||||
this.particleSystem.id = this.options.id
|
||||
this.entity = this.particleSystem
|
||||
// this.entity.modelMatrix = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(100.0, 20.0)), new Cesium.Cartesian3(0.0, 0.0, 10000.0), new Cesium.Matrix4())
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
// this.editObj = new EditParticle(this.sdk, this.entity)
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
|
||||
// 监听相机高度
|
||||
this.sdk.viewer.camera.changed.addEventListener(() => {
|
||||
if (this.entity && this.show) {
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
if (cameraHeight >= 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
else {
|
||||
this.entity.show = true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async flyTo(options = {}) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else {
|
||||
if (this.options.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 {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.lng, this.options.lat, this.options.alt + 500),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get startColor() {
|
||||
return this.options.startColor
|
||||
}
|
||||
|
||||
set startColor(v) {
|
||||
this.options.startColor = v
|
||||
this.particleSystem.startColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.startColor) {
|
||||
this._elms.startColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.startColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.startColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get endColor() {
|
||||
return this.options.endColor
|
||||
}
|
||||
|
||||
set endColor(v) {
|
||||
this.options.endColor = v
|
||||
this.particleSystem.endColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.endColor) {
|
||||
this._elms.endColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.endColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.endColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get minimumSpeed() {
|
||||
return this.options.minimumSpeed
|
||||
}
|
||||
|
||||
set minimumSpeed(v) {
|
||||
this.options.minimumSpeed = v
|
||||
this.particleSystem.minimumSpeed = v
|
||||
this._elms.minimumSpeed && this._elms.minimumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get maximumSpeed() {
|
||||
return this.options.maximumSpeed
|
||||
}
|
||||
|
||||
set maximumSpeed(v) {
|
||||
this.options.maximumSpeed = v
|
||||
this.particleSystem.maximumSpeed = v
|
||||
this._elms.maximumSpeed && this._elms.maximumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get minimumParticleLife() {
|
||||
return this.options.minimumParticleLife
|
||||
}
|
||||
|
||||
set minimumParticleLife(v) {
|
||||
this.options.minimumParticleLife = Number(v)
|
||||
this.particleSystem.minimumParticleLife = Number(v)
|
||||
this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get maximumParticleLife() {
|
||||
return this.options.maximumParticleLife
|
||||
}
|
||||
|
||||
set maximumParticleLife(v) {
|
||||
this.options.maximumParticleLife = Number(v)
|
||||
this.particleSystem.maximumParticleLife = Number(v)
|
||||
this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get startScale() {
|
||||
return this.options.startScale
|
||||
}
|
||||
|
||||
set startScale(v) {
|
||||
this.options.startScale = v
|
||||
this.particleSystem.startScale = v
|
||||
this._elms.startScale && this._elms.startScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get endScale() {
|
||||
return this.options.endScale
|
||||
}
|
||||
|
||||
set endScale(v) {
|
||||
this.options.endScale = v
|
||||
this.particleSystem.endScale = v
|
||||
this._elms.endScale && this._elms.endScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get emissionRate() {
|
||||
return this.options.emissionRate
|
||||
}
|
||||
|
||||
set emissionRate(v) {
|
||||
this.options.emissionRate = v
|
||||
this.particleSystem.emissionRate = v
|
||||
this._elms.emissionRate && this._elms.emissionRate.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get particleSize() {
|
||||
return this.options.particleSize
|
||||
}
|
||||
|
||||
set particleSize(v) {
|
||||
this.options.particleSize = v
|
||||
this.particleSystem.minimumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this.particleSystem.maximumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this._elms.particleSize && this._elms.particleSize.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.lng = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.lat = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.alt
|
||||
}
|
||||
|
||||
set alt(v) {
|
||||
this.options.alt = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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
|
||||
}
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' particle-effects'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let startColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("start_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.startColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.startColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let endColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("end_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.endColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.endColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
EventBinding.on(this, all_elm)
|
||||
this._elms = EventBinding.element
|
||||
this._elms.startColor = [startColorPicker]
|
||||
this._elms.endColor = [endColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.startColor = this.originalOptions.startColor
|
||||
this.endColor = this.originalOptions.endColor
|
||||
this.minimumSpeed = this.originalOptions.minimumSpeed
|
||||
this.maximumSpeed = this.originalOptions.maximumSpeed
|
||||
this.minimumParticleLife = this.originalOptions.minimumParticleLife
|
||||
this.maximumParticleLife = this.originalOptions.maximumParticleLife
|
||||
this.startScale = this.originalOptions.startScale
|
||||
this.endScale = this.originalOptions.endScale
|
||||
this.emissionRate = this.originalOptions.emissionRate
|
||||
this.particleSize = this.originalOptions.particleSize
|
||||
this.lng = this.originalOptions.lng
|
||||
this.lat = this.originalOptions.lat
|
||||
this.alt = this.originalOptions.alt
|
||||
}
|
||||
|
||||
async remove() {
|
||||
super.remove()
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity);
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.operate.positionEditing = status
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.picking = false
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
let movPos
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
movPos = movement.endPosition
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
if(!movPos || movPos.x !== movement.position.x || movPos.y !== movement.position.y-2) {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
}
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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 {
|
||||
this.picking = true
|
||||
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()
|
||||
if(!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.options.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default Fountain
|
||||
111
src/Obj/Base/ParticleEffects/Smoke/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Smoke/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
||||
92
src/Obj/Base/ParticleEffects/Smoke/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Smoke/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] ||!elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
739
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
739
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
@ -0,0 +1,739 @@
|
||||
/**
|
||||
* 烟雾特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData, getSdk as get2DSdk } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Smoke extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 烟雾特效
|
||||
* @param sdk
|
||||
* @param options {object} 粒子属性
|
||||
* @param options.id {string} 标注id
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 贴图地址
|
||||
* @param options.startColor="#00000000" {string} 起始颜色
|
||||
* @param options.endColor="#0000001a" {string} 结束颜色
|
||||
* @param options.startScale=0.1 {number} 初始比例
|
||||
* @param options.endScale=10 {number} 结束比例
|
||||
* @param options.minimumSpeed=10 {number} 最小初速度
|
||||
* @param options.maximumSpeed=15 {number} 最大初速度
|
||||
* @param options.minimumParticleLife=6 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=7 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=28 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=2{number} 粒子尺大小
|
||||
* @param options.lng 经度
|
||||
* @param options.lat 纬度
|
||||
* @param options.alt 高度
|
||||
* @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} 高度
|
||||
* */
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.url = options.url
|
||||
this.options.startColor = options.startColor || "#00000000"
|
||||
this.options.endColor = options.endColor || "#0000001a"
|
||||
this.options.startScale = options.startScale || 0.1
|
||||
this.options.endScale = options.endScale || 10
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 6
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 7
|
||||
this.options.minimumSpeed = options.minimumSpeed || 10
|
||||
this.options.maximumSpeed = options.maximumSpeed || 15
|
||||
this.options.emissionRate = options.emissionRate || 28
|
||||
this.options.particleSize = options.particleSize || 2
|
||||
this.options.show = options.show === false ? false : true
|
||||
this._elms = {};
|
||||
this.positionCallBack = null
|
||||
this.rotationCallback = null
|
||||
this.onClickCallback = null
|
||||
this._DialogObject = null
|
||||
this._element = null
|
||||
this.particleSystem
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.add()
|
||||
this.operate = {}
|
||||
this.previous = {
|
||||
positions: {
|
||||
lng: this.options.lng,
|
||||
lat: this.options.lat,
|
||||
alt: this.options.alt,
|
||||
}
|
||||
}
|
||||
this.Dialog = _Dialog
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "ParticleEffects"
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
let sdkD = get2DSdk().sdkD
|
||||
if (!this.isShowView || !sdkD) {
|
||||
this.options.show = v
|
||||
}
|
||||
if (!this.showView || this.showView == 3 || !sdkD) {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = this.options.show
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = this.options.show
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = false
|
||||
}
|
||||
}
|
||||
if(this._DialogObject && this._DialogObject.showBtn) {
|
||||
this._DialogObject.showBtn.checked = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
this.isShowView = false
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async add() {
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
const scene = this.sdk.viewer.scene;
|
||||
var cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
var position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(1, 1, 1), matrix)
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
this.particleSystem = scene.primitives.add(
|
||||
new Cesium.ParticleSystem({
|
||||
show: (cameraHeight >= 10000000) ? false : this.options.show,
|
||||
image: this.options.url || (this.getSourceRootPath() + '/img/particlesystem/smoke.png'),
|
||||
startColor: Cesium.Color.fromCssColorString(this.options.startColor), //粒子出生时的颜色
|
||||
endColor: Cesium.Color.fromCssColorString(this.options.endColor), //当粒子死亡时的颜色
|
||||
startScale: this.options.startScale, //粒子出生时的比例
|
||||
endScale: this.options.endScale, //粒子在死亡时的比例
|
||||
minimumParticleLife: this.options.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位)
|
||||
maximumParticleLife: this.options.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位)
|
||||
minimumSpeed: this.options.minimumSpeed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
|
||||
maximumSpeed: this.options.maximumSpeed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
|
||||
// imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小
|
||||
// this.options.imageSize || 10,
|
||||
// this.options.imageSize || 10
|
||||
// ),
|
||||
minimumImageSize: new Cesium.Cartesian2(
|
||||
this.options.particleSize,
|
||||
this.options.particleSize
|
||||
),
|
||||
maximumImageSize: new Cesium.Cartesian2(
|
||||
this.options.particleSize,
|
||||
this.options.particleSize
|
||||
),
|
||||
sizeInMeters: true,
|
||||
emissionRate: this.options.emissionRate, //每秒发射的粒子数。
|
||||
lifetime: 0.5, //多长时间的粒子系统将以秒为单位发射粒子
|
||||
loop: true,
|
||||
emitter: new Cesium.CircleEmitter(0.2),
|
||||
performance: false,
|
||||
modelMatrix: matrix,
|
||||
updateCallback: (r)=>{
|
||||
r._billboard.id = this.options.id
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.particleSystem.id = this.options.id
|
||||
this.entity = this.particleSystem
|
||||
// this.entity.modelMatrix = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(100.0, 20.0)), new Cesium.Cartesian3(0.0, 0.0, 10000.0), new Cesium.Matrix4())
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
// this.editObj = new EditParticle(this.sdk, this.entity)
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
|
||||
// 监听相机高度
|
||||
this.sdk.viewer.camera.changed.addEventListener(() => {
|
||||
if (this.entity && this.show) {
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
if (cameraHeight >= 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
else {
|
||||
this.entity.show = true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async flyTo(options = {}) {
|
||||
if (this._error) {
|
||||
return
|
||||
}
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else {
|
||||
if (this.options.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 {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.lng, this.options.lat, this.options.alt + 500),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get startColor() {
|
||||
return this.options.startColor
|
||||
}
|
||||
|
||||
set startColor(v) {
|
||||
this.options.startColor = v
|
||||
this.particleSystem.startColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.startColor) {
|
||||
this._elms.startColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.startColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.startColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get endColor() {
|
||||
return this.options.endColor
|
||||
}
|
||||
|
||||
set endColor(v) {
|
||||
this.options.endColor = v
|
||||
this.particleSystem.endColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.endColor) {
|
||||
this._elms.endColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.endColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.endColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get minimumSpeed() {
|
||||
return this.options.minimumSpeed
|
||||
}
|
||||
|
||||
set minimumSpeed(v) {
|
||||
this.options.minimumSpeed = v
|
||||
this.particleSystem.minimumSpeed = v
|
||||
this._elms.minimumSpeed && this._elms.minimumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get maximumSpeed() {
|
||||
return this.options.maximumSpeed
|
||||
}
|
||||
|
||||
set maximumSpeed(v) {
|
||||
this.options.maximumSpeed = v
|
||||
this.particleSystem.maximumSpeed = v
|
||||
this._elms.maximumSpeed && this._elms.maximumSpeed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get minimumParticleLife() {
|
||||
return this.options.minimumParticleLife
|
||||
}
|
||||
|
||||
set minimumParticleLife(v) {
|
||||
this.options.minimumParticleLife = v
|
||||
this.particleSystem.minimumParticleLife = v
|
||||
this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get maximumParticleLife() {
|
||||
return this.options.maximumParticleLife
|
||||
}
|
||||
|
||||
set maximumParticleLife(v) {
|
||||
this.options.maximumParticleLife = v
|
||||
this.particleSystem.maximumParticleLife = v
|
||||
this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get startScale() {
|
||||
return this.options.startScale
|
||||
}
|
||||
|
||||
set startScale(v) {
|
||||
this.options.startScale = v
|
||||
this.particleSystem.startScale = v
|
||||
this._elms.startScale && this._elms.startScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get endScale() {
|
||||
return this.options.endScale
|
||||
}
|
||||
|
||||
set endScale(v) {
|
||||
this.options.endScale = v
|
||||
this.particleSystem.endScale = v
|
||||
this._elms.endScale && this._elms.endScale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get emissionRate() {
|
||||
return this.options.emissionRate
|
||||
}
|
||||
|
||||
set emissionRate(v) {
|
||||
this.options.emissionRate = v
|
||||
this.particleSystem.emissionRate = v
|
||||
this._elms.emissionRate && this._elms.emissionRate.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get particleSize() {
|
||||
return this.options.particleSize
|
||||
}
|
||||
|
||||
set particleSize(v) {
|
||||
this.options.particleSize = v
|
||||
this.particleSystem.minimumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this.particleSystem.maximumImageSize = new Cesium.Cartesian2(v, v)
|
||||
this._elms.particleSize && this._elms.particleSize.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.lng = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.lat = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.alt
|
||||
}
|
||||
|
||||
set alt(v) {
|
||||
this.options.alt = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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
|
||||
}
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' particle-effects'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let startColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("start_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.startColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.startColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let endColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("end_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.endColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.endColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
EventBinding.on(this, all_elm)
|
||||
this._elms = EventBinding.element
|
||||
this._elms.startColor = [startColorPicker]
|
||||
this._elms.endColor = [endColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.startColor = this.originalOptions.startColor
|
||||
this.endColor = this.originalOptions.endColor
|
||||
this.minimumSpeed = this.originalOptions.minimumSpeed
|
||||
this.maximumSpeed = this.originalOptions.maximumSpeed
|
||||
this.minimumParticleLife = this.originalOptions.minimumParticleLife
|
||||
this.maximumParticleLife = this.originalOptions.maximumParticleLife
|
||||
this.startScale = this.originalOptions.startScale
|
||||
this.endScale = this.originalOptions.endScale
|
||||
this.emissionRate = this.originalOptions.emissionRate
|
||||
this.particleSize = this.originalOptions.particleSize
|
||||
this.lng = this.originalOptions.lng
|
||||
this.lat = this.originalOptions.lat
|
||||
this.alt = this.originalOptions.alt
|
||||
}
|
||||
|
||||
async remove() {
|
||||
super.remove()
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity);
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.operate.positionEditing = status
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.picking = false
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
let movPos
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
movPos = movement.endPosition
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
if(!movPos || movPos.x !== movement.position.x || movPos.y !== movement.position.y-2) {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
}
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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 {
|
||||
this.picking = true
|
||||
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()
|
||||
if(!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.options.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.alt
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
flicker() {}
|
||||
}
|
||||
|
||||
export default Smoke
|
||||
122
src/Obj/Base/ParticleEffects/Spout/_element.js
Normal file
122
src/Obj/Base/ParticleEffects/Spout/_element.js
Normal file
@ -0,0 +1,122 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input style="width: 175px;" class="input" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>速度</span>
|
||||
<input type="range" max="30" min="0" step="0.1" @model="speed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>朝向</span>
|
||||
<input type="range" max="360" min="0.1" step="0.1" @model="heading">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>俯仰角度</span>
|
||||
<input type="range" max="360" min="0.1" step="0.1" @model="pitch">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
974
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
974
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
@ -0,0 +1,974 @@
|
||||
/**
|
||||
* 水柱特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData, getSdk as get2DSdk } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global'
|
||||
|
||||
class Spout extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 水柱
|
||||
* @param sdk
|
||||
* @param options {object} 粒子属性
|
||||
* @param options.id {string} 标注id
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string} 贴图地址
|
||||
* @param options.startColor="#c1f7f2" {string} 起始颜色
|
||||
* @param options.endColor="#ffffff00" {string} 结束颜色
|
||||
* @param options.startScale=0.2 {number} 初始比例
|
||||
* @param options.endScale=2 {number} 结束比例
|
||||
* @param options.speed {number} 速度
|
||||
* @param options.minimumParticleLife=12 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=12 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=100 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=1 {number} 粒子尺大小
|
||||
* @param options.heading 航向角
|
||||
* @param options.pitch 俯仰角
|
||||
* @param options.start {object} 开始位置
|
||||
* @param options.start.lng 经度
|
||||
* @param options.start.lat 纬度
|
||||
* @param options.start.alt 高度
|
||||
* @param options.end {object} 结束位置
|
||||
* @param options.end.lng 经度
|
||||
* @param options.end.lat 纬度
|
||||
* @param options.end.alt 高度
|
||||
* @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} 高度
|
||||
* */
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.url = options.url
|
||||
this.options.startColor = options.startColor || "#c1f7f2"
|
||||
this.options.endColor = options.endColor || "#ffffff00"
|
||||
this.options.startScale = options.startScale || 0.2
|
||||
this.options.endScale = options.endScale || 2
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 12
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 12
|
||||
this.options.emissionRate = options.emissionRate || 100
|
||||
this.options.particleSize = options.particleSize || 1
|
||||
this.options.show = options.show === false ? false : true
|
||||
this._elms = {};
|
||||
this.positionCallBack = null
|
||||
this.rotationCallback = null
|
||||
this.onClickCallback = null
|
||||
this._DialogObject = null
|
||||
this._element = null
|
||||
this.particleSystem
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.add()
|
||||
this.operate = {}
|
||||
this.previous = {
|
||||
positions: {
|
||||
lng: this.options.start.lng,
|
||||
lat: this.options.start.lat,
|
||||
alt: this.options.start.alt,
|
||||
}
|
||||
}
|
||||
this.Dialog = _Dialog
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "ParticleEffects"
|
||||
}
|
||||
|
||||
get show() {
|
||||
return this.options.show
|
||||
}
|
||||
|
||||
set show(v) {
|
||||
if (typeof v === "boolean") {
|
||||
let sdkD = get2DSdk().sdkD
|
||||
if (!this.isShowView || !sdkD) {
|
||||
this.options.show = v
|
||||
}
|
||||
if (!this.showView || this.showView == 3 || !sdkD) {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = this.options.show
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = this.options.show
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
if (this.options.label && this.options.label.show) {
|
||||
this.label.show = false
|
||||
}
|
||||
}
|
||||
if(this._DialogObject && this._DialogObject.showBtn) {
|
||||
this._DialogObject.showBtn.checked = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
this.isShowView = false
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async add() {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
const scene = this.sdk.viewer.scene;
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(1, 1, 1), matrix)
|
||||
|
||||
let gravityVector = new Cesium.Cartesian3();
|
||||
let gravity = -3.8;// 重力方向
|
||||
|
||||
let start = Cesium.Cartesian3.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt)
|
||||
let end = Cesium.Cartesian3.fromDegrees(this.options.end.lng, this.options.end.lat, this.options.end.alt)
|
||||
if (!this.options.heading && this.options.heading !== 0) {
|
||||
this.options.heading = getHeading(start, end)
|
||||
}
|
||||
|
||||
let y0 = this.options.end.alt - this.options.start.alt
|
||||
let x0 = Cesium.Cartesian3.distance(start, Cesium.Cartesian3.fromDegrees(this.options.end.lng, this.options.end.lat, this.options.start.alt))
|
||||
let tanA
|
||||
if (!y0) {
|
||||
tanA = 0
|
||||
}
|
||||
else {
|
||||
tanA = 2 * y0 / x0
|
||||
}
|
||||
|
||||
let a = Math.atan(tanA) * (180 / Math.PI);
|
||||
|
||||
let t = Math.sqrt((Math.abs(tanA) * x0) / -gravity)
|
||||
let speed = -gravity * t / Math.abs(Math.cos(a))
|
||||
if (!this.options.pitch && this.options.pitch !== 0) {
|
||||
this.options.pitch = 90 - a
|
||||
}
|
||||
if (!this.options.speed && this.options.speed !== 0) {
|
||||
this.options.speed = speed
|
||||
}
|
||||
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
|
||||
|
||||
|
||||
// // 计算发射参数
|
||||
// function calculateLaunchParameters(height, distance, gravity) {
|
||||
// // 解决斜抛运动问题:y = h + x·tan(θ) - (g·x²)/(2·v₀²·cos²(θ))
|
||||
// // 当 y = 0, x = distance 时,求解 v₀ 和 θ
|
||||
|
||||
// // 简化计算,使用最优角度 θ = 45°
|
||||
// const angle = Cesium.Math.toRadians(45);
|
||||
|
||||
// // 计算初始速度
|
||||
// const velocity = Math.sqrt((gravity * distance * distance) /
|
||||
// (2 * (height + distance * Math.tan(angle)) * Math.pow(Math.cos(angle), 2)));
|
||||
|
||||
// // 计算飞行时间
|
||||
// const vy0 = velocity * Math.sin(angle);
|
||||
// const flightTime = (vy0 + Math.sqrt(vy0 * vy0 + 2 * gravity * height)) / gravity;
|
||||
|
||||
// // 计算最大高度
|
||||
// const maxHeight = height + (vy0 * vy0) / (2 * gravity);
|
||||
|
||||
// return { velocity, angle, flightTime, maxHeight };
|
||||
// }
|
||||
// let params = {
|
||||
// launchHeight: this.options.start.alt, // 发射高度
|
||||
// targetDistance: Cesium.Cartesian3.distance(start, end), // 目标距离
|
||||
// gravity: 9.8, // 重力
|
||||
// }
|
||||
// // 计算初始速度和发射角度
|
||||
// const { velocity, angle, flightTime, maxHeight } = calculateLaunchParameters(
|
||||
// params.launchHeight,
|
||||
// params.targetDistance,
|
||||
// params.gravity
|
||||
// );
|
||||
|
||||
// if (!this.options.speed && this.options.speed !== 0) {
|
||||
// this.options.speed = velocity*10
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
this.particleSystem = scene.primitives.add(
|
||||
new Cesium.ParticleSystem({
|
||||
show: (cameraHeight >= 10000000) ? false : this.options.show,
|
||||
image: this.options.url || (this.getSourceRootPath() + '/img/particlesystem/smoke.png'),
|
||||
// 从绿色到白色淡出
|
||||
startColor: Cesium.Color.fromCssColorString(this.options.startColor), //粒子出生时的颜色
|
||||
endColor: Cesium.Color.fromCssColorString(this.options.endColor), //当粒子死亡时的颜色
|
||||
startScale: this.options.startScale, //粒子出生时的比例
|
||||
endScale: this.options.endScale, //粒子在死亡时的比例
|
||||
minimumParticleLife: this.options.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位)
|
||||
maximumParticleLife: this.options.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位)
|
||||
minimumSpeed: this.options.speed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
|
||||
maximumSpeed: this.options.speed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
|
||||
// imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小
|
||||
// this.options.imageSize || 10,
|
||||
// this.options.imageSize || 10
|
||||
// ),
|
||||
lifetime: 0.5,
|
||||
imageSize: new Cesium.Cartesian2(this.options.particleSize, this.options.particleSize * 2),
|
||||
sizeInMeters: true,
|
||||
emissionRate: this.options.emissionRate, //每秒发射的粒子数。
|
||||
loop: true,
|
||||
emitter: new Cesium.CircleEmitter(0.2),
|
||||
modelMatrix: matrix,
|
||||
emitterModelMatrix: computeEmitterModelMatrix(),// 发射器转换为世界坐标
|
||||
|
||||
// 增加重力场影像,
|
||||
updateCallback: applyGravity,
|
||||
})
|
||||
);
|
||||
|
||||
function applyGravity(p, dt) {
|
||||
p._billboard.id = _this.options.id
|
||||
let position = p.position;
|
||||
Cesium.Cartesian3.normalize(position, gravityVector);
|
||||
// Cesium.Cartesian3.multiplyByScalar(gravityVector, -4.8 * dt, gravityVector);
|
||||
Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector);
|
||||
p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
|
||||
}
|
||||
|
||||
|
||||
// 计算粒子发射器的位置姿态
|
||||
function computeEmitterModelMatrix() {
|
||||
let hpr = Cesium.HeadingPitchRoll.fromDegrees(_this.options.heading + 90, _this.options.pitch, 0);//!!!发射粒子的方向
|
||||
let trs = new Cesium.TranslationRotationScale();
|
||||
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1);
|
||||
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
|
||||
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
|
||||
return Matrix4
|
||||
}
|
||||
|
||||
// 根据两个坐标点,获取Heading(朝向)
|
||||
function getHeading(fromPosition, toPosition) {
|
||||
let finalPosition = new Cesium.Cartesian3();
|
||||
let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(fromPosition);
|
||||
Cesium.Matrix4.inverse(matrix4, matrix4);
|
||||
Cesium.Matrix4.multiplyByPoint(matrix4, toPosition, finalPosition);
|
||||
Cesium.Cartesian3.normalize(finalPosition, finalPosition);
|
||||
return Cesium.Math.toDegrees(Math.atan2(finalPosition.x, finalPosition.y));
|
||||
}
|
||||
|
||||
|
||||
// this.entity.modelMatrix
|
||||
this.particleSystem.id = this.options.id
|
||||
this.entity = this.particleSystem
|
||||
// this.entity.modelMatrix = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(100.0, 20.0)), new Cesium.Cartesian3(0.0, 0.0, 10000.0), new Cesium.Matrix4())
|
||||
this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt }
|
||||
// this.editObj = new EditParticle(this.sdk, this.entity)
|
||||
syncData(this.sdk, this.options.id)
|
||||
if (this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
|
||||
// 监听相机高度
|
||||
this.sdk.viewer.camera.changed.addEventListener(() => {
|
||||
if (this.entity && this.show) {
|
||||
let cameraHeight = this.sdk.viewer.camera.positionCartographic.height;
|
||||
if (cameraHeight >= 10000000) {
|
||||
this.entity.show = false
|
||||
}
|
||||
else {
|
||||
this.entity.show = true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// this.translation = new Cesium.Cartesian3();
|
||||
// this.rotation = new Cesium.Quaternion();
|
||||
// this.hpr = new Cesium.HeadingPitchRoll();
|
||||
// this.trs = new Cesium.TranslationRotationScale();
|
||||
// this.emitterModelMatrix = new Cesium.Matrix4();
|
||||
// this.hpr = Cesium.HeadingPitchRoll.fromDegrees(60, 0.0, 0.0, this.hpr);
|
||||
// this.trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0, this.translation);
|
||||
// this.trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(this.hpr, this.rotation);
|
||||
// this.particleSystem.emitterModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(this.trs, this.emitterModelMatrix);
|
||||
}
|
||||
|
||||
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.line && this.options.line.positions) {
|
||||
position = { ...this.options.line.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 {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt + 500),
|
||||
orientation: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get startColor() {
|
||||
return this.options.startColor
|
||||
}
|
||||
|
||||
set startColor(v) {
|
||||
this.options.startColor = v
|
||||
this.particleSystem.startColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.startColor) {
|
||||
this._elms.startColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.startColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.startColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get endColor() {
|
||||
return this.options.endColor
|
||||
}
|
||||
|
||||
set endColor(v) {
|
||||
this.options.endColor = v
|
||||
this.particleSystem.endColor = Cesium.Color.fromCssColorString(v)
|
||||
if (this._elms.endColor) {
|
||||
this._elms.endColor.forEach((item, i) => {
|
||||
let picker = new YJColorPicker({
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.endColor = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.endColor[i] = picker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get speed() {
|
||||
return this.options.speed
|
||||
}
|
||||
|
||||
set speed(v) {
|
||||
this.options.speed = Number(v)
|
||||
this.particleSystem.minimumSpeed = Number(v)
|
||||
this.particleSystem.maximumSpeed = Number(v)
|
||||
this._elms.speed && this._elms.speed.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get minimumParticleLife() {
|
||||
return this.options.minimumParticleLife
|
||||
}
|
||||
|
||||
set minimumParticleLife(v) {
|
||||
this.options.minimumParticleLife = Number(v)
|
||||
this.particleSystem.minimumParticleLife = Number(v)
|
||||
this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get maximumParticleLife() {
|
||||
return this.options.maximumParticleLife
|
||||
}
|
||||
|
||||
set maximumParticleLife(v) {
|
||||
this.options.maximumParticleLife = Number(v)
|
||||
this.particleSystem.maximumParticleLife = Number(v)
|
||||
this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get startScale() {
|
||||
return this.options.startScale
|
||||
}
|
||||
|
||||
set startScale(v) {
|
||||
this.options.startScale = Number(v)
|
||||
this.particleSystem.startScale = Number(v)
|
||||
this._elms.startScale && this._elms.startScale.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get endScale() {
|
||||
return this.options.endScale
|
||||
}
|
||||
|
||||
set endScale(v) {
|
||||
this.options.endScale = Number(v)
|
||||
this.particleSystem.endScale = Number(v)
|
||||
this._elms.endScale && this._elms.endScale.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get emissionRate() {
|
||||
return this.options.emissionRate
|
||||
}
|
||||
|
||||
set emissionRate(v) {
|
||||
this.options.emissionRate = Number(v)
|
||||
this.particleSystem.emissionRate = Number(v)
|
||||
this._elms.emissionRate && this._elms.emissionRate.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get particleSize() {
|
||||
return this.options.particleSize
|
||||
}
|
||||
|
||||
set particleSize(v) {
|
||||
this.options.particleSize = Number(v)
|
||||
this.particleSystem.minimumImageSize = new Cesium.Cartesian2(Number(v), Number(v) * 2)
|
||||
this.particleSystem.maximumImageSize = new Cesium.Cartesian2(Number(v), Number(v) * 2)
|
||||
this._elms.particleSize && this._elms.particleSize.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.start.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.start.lng = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt }
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.start.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.start.lat = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt }
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.start.alt
|
||||
}
|
||||
|
||||
set alt(v) {
|
||||
this.options.start.alt = v
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt }
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get heading() {
|
||||
return this.options.heading
|
||||
}
|
||||
|
||||
set heading(v) {
|
||||
this.options.heading = Number(v)
|
||||
let hpr = Cesium.HeadingPitchRoll.fromDegrees(this.options.heading + 90, this.options.pitch, 0);//!!!发射粒子的方向
|
||||
let trs = new Cesium.TranslationRotationScale();
|
||||
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1);
|
||||
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
|
||||
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
|
||||
this.particleSystem.emitterModelMatrix = Matrix4
|
||||
this._elms.heading && this._elms.heading.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
get pitch() {
|
||||
return this.options.pitch
|
||||
}
|
||||
|
||||
set pitch(v) {
|
||||
this.options.pitch = Number(v)
|
||||
let hpr = Cesium.HeadingPitchRoll.fromDegrees(this.options.heading + 90, this.options.pitch, 0);//!!!发射粒子的方向
|
||||
let trs = new Cesium.TranslationRotationScale();
|
||||
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1);
|
||||
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
|
||||
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
|
||||
this.particleSystem.emitterModelMatrix = Matrix4
|
||||
this._elms.pitch && this._elms.pitch.forEach((item) => {
|
||||
item.value = Number(v)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 编辑框
|
||||
* @param state=false {boolean} 状态: true打开, false关闭
|
||||
*/
|
||||
async edit(state = false) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
// let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog')
|
||||
// for (let i = elms.length - 1; i >= 0; i--) {
|
||||
// this.sdk.viewer._container.removeChild(elms[i])
|
||||
// }
|
||||
|
||||
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
|
||||
}
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' particle-effects'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// 颜色组件
|
||||
let startColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("start_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.startColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.startColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.startColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let endColorPicker = new YJColorPicker({
|
||||
el: contentElm.getElementsByClassName("end_color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.endColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.endColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.endColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
Spout.EventBinding(this, all_elm)
|
||||
this._elms.startColor = [startColorPicker]
|
||||
this._elms.endColor = [endColorPicker]
|
||||
} else {
|
||||
// if (this._element_style) {
|
||||
// document.getElementsByTagName('head')[0].removeChild(this._element_style)
|
||||
// this._element_style = null
|
||||
// }
|
||||
// if (this._DialogObject && this._DialogObject.remove) {
|
||||
// this._DialogObject.remove()
|
||||
// this._DialogObject = null
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.startColor = this.originalOptions.startColor
|
||||
this.endColor = this.originalOptions.endColor
|
||||
this.speed = this.originalOptions.speed
|
||||
this.minimumParticleLife = this.originalOptions.minimumParticleLife
|
||||
this.maximumParticleLife = this.originalOptions.maximumParticleLife
|
||||
this.startScale = this.originalOptions.startScale
|
||||
this.endScale = this.originalOptions.endScale
|
||||
this.emissionRate = this.originalOptions.emissionRate
|
||||
this.particleSize = this.originalOptions.particleSize
|
||||
this.lng = this.originalOptions.start.lng
|
||||
this.lat = this.originalOptions.start.lat
|
||||
this.alt = this.originalOptions.start.alt
|
||||
}
|
||||
|
||||
async remove() {
|
||||
super.remove()
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity);
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.operate.positionEditing = status
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.picking = false
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
let movPos
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
movPos = movement.endPosition
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.start.lng = positions.lng
|
||||
this.options.start.lat = positions.lat
|
||||
this.options.start.alt = positions.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.start.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.start.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.start.alt
|
||||
})
|
||||
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
if (!movPos || movPos.x !== movement.position.x || movPos.y !== movement.position.y - 2) {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.start.lng = positions.lng
|
||||
this.options.start.lat = positions.lat
|
||||
this.options.start.alt = positions.alt
|
||||
}
|
||||
|
||||
this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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.start.lng = this.entity.position.lng
|
||||
this.options.start.lat = this.entity.position.lat
|
||||
this.options.start.alt = this.entity.position.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.lng = this.entity.position.lng
|
||||
this.options.lat = this.entity.position.lat
|
||||
this.options.alt = this.entity.position.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.lng = positions.lng
|
||||
this.options.lat = positions.lat
|
||||
this.options.alt = positions.alt
|
||||
|
||||
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
|
||||
this.previous = {
|
||||
positions: { ...this.entity.position }
|
||||
}
|
||||
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 {
|
||||
this.picking = true
|
||||
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()
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this.options.start.lng = this.entity.position.lng
|
||||
this.options.start.lat = this.entity.position.lat
|
||||
this.options.start.alt = this.entity.position.alt
|
||||
let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt);
|
||||
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
|
||||
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
|
||||
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = this.options.start.lng
|
||||
})
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = this.options.start.lat
|
||||
})
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = this.options.start.alt
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
static EventBinding(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
if (e.data != '.' && (e.data != '-' || e.target.value)) {
|
||||
value = Number(value)
|
||||
if ((e.target.max) && value > Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
}
|
||||
if ((e.target.min) && value < Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
}
|
||||
else {
|
||||
that[m.value] = value
|
||||
}
|
||||
})
|
||||
if (elements[i].nodeName == 'IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if (that._elms[m.value]) {
|
||||
that._elms[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
that._elms[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
case '@change': {
|
||||
isEvent = true
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number' && value != '') {
|
||||
value = Number(value)
|
||||
e.target.value = value
|
||||
}
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e, value)
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for (let n = 0; n < removeName.length; n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flicker() { }
|
||||
}
|
||||
|
||||
export default Spout
|
||||
115
src/Obj/Base/PincerArrowObject/_element.js
Normal file
115
src/Obj/Base/PincerArrowObject/_element.js
Normal file
@ -0,0 +1,115 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 56px;">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">动画时长</span>
|
||||
<div class="input-number input-number-unit-3">
|
||||
<input class="input blur" type="number" title="" min="500" max="9999999" @model="spreadTime">
|
||||
<span class="unit">ms</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">动画</span>
|
||||
<input class="btn-switch" type="checkbox" @model="spreadState">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">动画重复</span>
|
||||
<input class="btn-switch" type="checkbox" @model="loop">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="pincer-arrow-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">边线宽度</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2683
src/Obj/Base/PincerArrowObject/index.js
Normal file
2683
src/Obj/Base/PincerArrowObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
93
src/Obj/Base/PolygonObject/_element.js
Normal file
93
src/Obj/Base/PolygonObject/_element.js
Normal file
@ -0,0 +1,93 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="polygon-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="面风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">面颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">描边颜色</span>
|
||||
<div class="lineColor"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">描边宽度</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="0" max="99" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
2866
src/Obj/Base/PolygonObject/index.js
Normal file
2866
src/Obj/Base/PolygonObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
60
src/Obj/Base/PolyhedronObject/_element.js
Normal file
60
src/Obj/Base/PolyhedronObject/_element.js
Normal file
@ -0,0 +1,60 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">多面体颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 60%;">
|
||||
<span class="label">多面体高度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="9999999" data-null data-min="0.01" @model="height">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col">
|
||||
<span class="label">拉伸高度</span>
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="extrudedHeight">
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="polygon-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
142
src/Obj/Base/PolyhedronObject/eventBinding.js
Normal file
142
src/Obj/Base/PolyhedronObject/eventBinding.js
Normal file
@ -0,0 +1,142 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
let blurEvent = () => { }
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
let str = e.target.value + ''
|
||||
if (e.data != '.' && (e.data != '-' || e.target.value) && !(str.charAt(str.length - 1) == '0' && e.target.value.toString().includes('.')) && e.target.value != '0') {
|
||||
value = Number(value)
|
||||
if((e.target.max) && value>Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
}
|
||||
if((e.target.min) && value<Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
}
|
||||
if (e.target.dataset.min !== 'undefined' && e.target.dataset.min !== '') {
|
||||
let min = Number(e.target.dataset.min)
|
||||
if(value<min) {
|
||||
value = min
|
||||
}
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
}
|
||||
else {
|
||||
that[m.value] = value
|
||||
}
|
||||
})
|
||||
blurEvent = (e) => {
|
||||
let value = e.target.value
|
||||
if ((e.target.type == 'number') && (e.target.value || (e.target.dataset.null !== 'undefined' && e.target.dataset.null !== '' && !Boolean(e.target.dataset.null)))) {
|
||||
value = Number(value)
|
||||
if ((e.target.max) && value > Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
}
|
||||
if ((e.target.min) && value < Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
}
|
||||
if ((e.target.dataset.min) && value < Number(e.target.dataset.min)) {
|
||||
value = Number(e.target.dataset.min)
|
||||
}
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
case '@change': {
|
||||
isEvent = true
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' && value!='') {
|
||||
value = Number(value)
|
||||
e.target.value = value
|
||||
}
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e, value)
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
elements[i].addEventListener('blur', blurEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
1691
src/Obj/Base/PolyhedronObject/index.js
Normal file
1691
src/Obj/Base/PolyhedronObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
62
src/Obj/Base/PolyhedronObject2/_element.js
Normal file
62
src/Obj/Base/PolyhedronObject2/_element.js
Normal file
@ -0,0 +1,62 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="margin-right: 0px;">投影面积:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" @model="area">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="polygon-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="多面体风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">多面体颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">多面体高度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="height">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<!-- <span class="label">拉伸高度</span>
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="extrudedHeight"> -->
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
114
src/Obj/Base/PolyhedronObject2/eventBinding.js
Normal file
114
src/Obj/Base/PolyhedronObject2/eventBinding.js
Normal file
@ -0,0 +1,114 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
if (e.data != '.' && (e.data != '-' || e.target.value)) {
|
||||
value = Number(value)
|
||||
if((e.target.max) && value>Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
}
|
||||
if((e.target.min) && value<Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
}
|
||||
else {
|
||||
that[m.value] = value
|
||||
}
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
case '@change': {
|
||||
isEvent = true
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if(e.target.type == 'number' && value!='') {
|
||||
value = Number(value)
|
||||
e.target.value = value
|
||||
}
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e, value)
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for(let n=0;n<removeName.length;n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
1332
src/Obj/Base/PolyhedronObject2/index.js
Normal file
1332
src/Obj/Base/PolyhedronObject2/index.js
Normal file
File diff suppressed because it is too large
Load Diff
168
src/Obj/Base/PolylineObject/_element.js
Normal file
168
src/Obj/Base/PolylineObject/_element.js
Normal file
@ -0,0 +1,168 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 56%;">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<div class="input-select-unit"></div>
|
||||
<input class="input input-text" readonly="readonly" type="text" style="flex: 0 0 130px;" @model="length">
|
||||
<div class="input-select-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="polyline-object-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="空间信息">
|
||||
<div class="row">
|
||||
<div class="col height-mode-box">
|
||||
<span class="label" style="flex: 0 0 56px;">高度模式</span>
|
||||
<div class="height-mode"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">Z值统一增加</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input height" type="number" title="" min="-9999999" max="999999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<button class="confirm height-confirm" style="margin-left: 5px;">应用</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="table spatial-info-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th"></div>
|
||||
<div class="th">经度(X)</div>
|
||||
<div class="th">纬度(Y)</div>
|
||||
<div class="th">高度(Z)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="线条风格">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">线条颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">线条宽度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="1" max="999" @model="lineWidth">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col input-select-line-type-box" style="flex: 0 0 37%;">
|
||||
<span class="label">线条形式</span>
|
||||
<div class="input-select-line-type"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">首尾相连</span>
|
||||
<input class="btn-switch" type="checkbox" @model="noseToTail">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">线段圆滑</span>
|
||||
<input class="btn-switch" type="checkbox" @model="smooth">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">线段缓冲</span>
|
||||
<input class="btn-switch" type="checkbox" @model="extend">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">缓冲宽度</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" data-min="0.01" max="999999" @model="extendWidth">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
<span class="label">缓冲颜色</span>
|
||||
<div class="extendColor"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="dashTextureDom">
|
||||
<div class="col">
|
||||
<span class="label">首尾反向</span>
|
||||
<input class="btn-switch" type="checkbox" @model="rotate">
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 33%;">
|
||||
<span class="label">流动速率</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="999999" step="1" @model="speed">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="flex: 0 0 37%;">
|
||||
<span class="label lineSpace">线条间距</span>
|
||||
<div class="input-number input-number-unit-1 lineSpace" style="width: 80px;">
|
||||
<input class="input" type="number" title="" min="0" max="4.5" step="0.1" @model="space">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</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">设置操作点</span>-->
|
||||
<!-- <input class="input" type="text" @model="operatingPoint">-->
|
||||
<!-- <button class="primary" @click="operatingPointSubmit">提交</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </DIV-cy-tab-pane>-->
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
122
src/Obj/Base/PolylineObject/eventBinding.js
Normal file
122
src/Obj/Base/PolylineObject/eventBinding.js
Normal file
@ -0,0 +1,122 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(that, elements) {
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let Event = []
|
||||
let isEvent = false
|
||||
let removeName = []
|
||||
if (!elements[i] || !elements[i].attributes) {
|
||||
continue
|
||||
}
|
||||
for (let m of elements[i].attributes) {
|
||||
switch (m.name) {
|
||||
case '@model': {
|
||||
isEvent = true
|
||||
if (elements[i].type == 'checkbox') {
|
||||
Event.push((e) => { that[m.value] = e.target.checked })
|
||||
elements[i].checked = that[m.value]
|
||||
}
|
||||
else {
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number') {
|
||||
if (e.data != '.' && (e.data != '-' || e.target.value)) {
|
||||
value = Number(value)
|
||||
if ((e.target.max) && value > Number(e.target.max)) {
|
||||
value = Number(e.target.max)
|
||||
e.target.value = value
|
||||
}
|
||||
if ((e.target.min) && value < Number(e.target.min)) {
|
||||
value = Number(e.target.min)
|
||||
e.target.value = value
|
||||
}
|
||||
if ((e.target.dataset.min) && value < Number(e.target.dataset.min)) {
|
||||
value = Number(e.target.dataset.min)
|
||||
}
|
||||
that[m.value] = value
|
||||
}
|
||||
}
|
||||
else {
|
||||
that[m.value] = value
|
||||
}
|
||||
})
|
||||
if (elements[i].nodeName == 'IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if (this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
break;
|
||||
}
|
||||
case '@change': {
|
||||
isEvent = true
|
||||
Event.push((e) => {
|
||||
let value = e.target.value
|
||||
if (e.target.type == 'number' && value != '') {
|
||||
value = Number(value)
|
||||
e.target.value = value
|
||||
}
|
||||
if (typeof (that[m.value]) === 'function') {
|
||||
that[m.value](e, value)
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
// elements[i].attributes[m] = undefined
|
||||
}
|
||||
for (let n = 0; n < removeName.length; n++) {
|
||||
elements[i].attributes.removeNamedItem(removeName[n])
|
||||
}
|
||||
|
||||
if (isEvent) {
|
||||
let ventType = 'input'
|
||||
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||
ventType = 'change'
|
||||
}
|
||||
elements[i].addEventListener(ventType, (e) => {
|
||||
for (let t = 0; t < Event.length; t++) {
|
||||
Event[t](e)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
||||
3339
src/Obj/Base/PolylineObject/index.js
Normal file
3339
src/Obj/Base/PolylineObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
67
src/Obj/Base/RadarScan/_element.js
Normal file
67
src/Obj/Base/RadarScan/_element.js
Normal file
@ -0,0 +1,67 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描半径</span>
|
||||
<div class="input-number input-number-unit-2 input-radius">
|
||||
<input class="input" type="number" title="" data-min="0.1" max="999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<div class="input-radius-unit-box" style="flex: 0 0 60px;">
|
||||
<div class="input-radius-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描速度</span>
|
||||
<input class="input" type="number" title="" min="0" max="100" @model="speed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="radar-scan-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
1552
src/Obj/Base/RadarScan/index.js
Normal file
1552
src/Obj/Base/RadarScan/index.js
Normal file
File diff suppressed because it is too large
Load Diff
91
src/Obj/Base/RadarScanStereoscopic/_element.js
Normal file
91
src/Obj/Base/RadarScanStereoscopic/_element.js
Normal file
@ -0,0 +1,91 @@
|
||||
import { attributeElm, labelStyleElm1, labelStyleElm2 } from '../../Element/elm_html'
|
||||
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扩散半径</span>
|
||||
<div class="input-number input-number-unit-2 input-radius">
|
||||
<input class="input" type="number" title="" data-min="0.1" max="999999">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<div class="input-radius-unit-box" style="flex: 0 0 60px;">
|
||||
<div class="input-radius-unit"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">持续时间</span>
|
||||
<div class="input-number input-number-unit-2">
|
||||
<input class="input" type="number" title="" min="100" max="99999" @model="duration">
|
||||
<span class="unit">ms</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">范围颜色</span>
|
||||
<div class="colorOut"></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描颜色</span>
|
||||
<div class="colorIn"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<DIV-cy-tabs id="radar-scan-edit-tabs">
|
||||
<DIV-cy-tab-pane label="属性信息">
|
||||
${attributeElm(that)}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标注风格">
|
||||
${labelStyleElm1()}
|
||||
</DIV-cy-tab-pane>
|
||||
<DIV-cy-tab-pane label="标签风格">
|
||||
${labelStyleElm2()}
|
||||
</DIV-cy-tab-pane>
|
||||
</DIV-cy-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
1496
src/Obj/Base/RadarScanStereoscopic/index.js
Normal file
1496
src/Obj/Base/RadarScanStereoscopic/index.js
Normal file
File diff suppressed because it is too large
Load Diff
124
src/Obj/Base/Road/RoadMaterialProperty.js
Normal file
124
src/Obj/Base/Road/RoadMaterialProperty.js
Normal file
@ -0,0 +1,124 @@
|
||||
import Tools from "../../../Tools";
|
||||
|
||||
function init_material() {
|
||||
let _that = this
|
||||
let tools = new Tools()
|
||||
if (typeof Cesium !== 'undefined') (function (Cesium) {
|
||||
/**
|
||||
* 自定义材质线Property 适用于entity和primitive材质
|
||||
* @param {object} options
|
||||
* @param source {string} glsl的shader代码
|
||||
* @param options.image {string} 图片地址
|
||||
*/
|
||||
function RoadMaterialProperty(options = {}, source) {
|
||||
|
||||
var Color = Cesium.Color,
|
||||
defaultValue = Cesium.defaultValue,
|
||||
defineProperties = Object.defineProperties,
|
||||
Event = Cesium.Event,
|
||||
createPropertyDescriptor = Cesium.createPropertyDescriptor,
|
||||
Property = Cesium.Property,
|
||||
Material = Cesium.Material,
|
||||
MaterialType = options.MaterialType || 'wallType' + parseInt(Math.random() * 1000);
|
||||
|
||||
// 创建自定义动态材质对象
|
||||
function PolylineCustomMaterialProperty(options = {}) {
|
||||
|
||||
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
|
||||
// 定义内置属性
|
||||
this._definitionChanged = new Event();
|
||||
this._color = undefined;
|
||||
this._colorSubscription = undefined;
|
||||
this._repeat = undefined;
|
||||
this._repeatSubscription = undefined;
|
||||
this._rotate = undefined;
|
||||
this._rotateSubscription = undefined;
|
||||
this.image = options.image;
|
||||
this.color = new Cesium.Color.fromCssColorString(options.color || "rgba(4,253,231,0.87)");
|
||||
this.repeat = options.repeat;
|
||||
this.rotate = options.rotate;
|
||||
|
||||
this.duration = (options.duration || options.duration===0) ? options.duration : 1000
|
||||
this._time = new Date().getTime();
|
||||
}
|
||||
|
||||
// 定义材质对象默认属性
|
||||
defineProperties(PolylineCustomMaterialProperty.prototype, {
|
||||
isvarant: {
|
||||
get: function () {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
definitionChanged: {
|
||||
get: function () {
|
||||
return this._definitionChanged;
|
||||
}
|
||||
},
|
||||
repeat: Cesium.createPropertyDescriptor('repeat'),
|
||||
rotate: Cesium.createPropertyDescriptor('rotate'),
|
||||
color: createPropertyDescriptor('color')
|
||||
});
|
||||
// 材质对象需要有type函数 value函数 equals函数
|
||||
PolylineCustomMaterialProperty.prototype.getType = function (time) {
|
||||
return MaterialType;
|
||||
};
|
||||
PolylineCustomMaterialProperty.prototype.getValue = function (time, result) {
|
||||
if (!Cesium.defined(result)) {
|
||||
result = {};
|
||||
}
|
||||
result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
|
||||
result.time = this.duration ? ((new Date().getTime() - this._time) % this.duration) / this.duration : 0;
|
||||
result.image = this.image;
|
||||
result.repeat = Cesium.Property.getValueOrDefault(this.repeat);
|
||||
result.rotate = Cesium.Property.getValueOrDefault(this.rotate);
|
||||
return result;
|
||||
};
|
||||
PolylineCustomMaterialProperty.prototype.equals = function (other) {
|
||||
return this === other || //
|
||||
(other instanceof PolylineCustomMaterialProperty &&
|
||||
Property.equals(this._color, other._color)) &&
|
||||
Property.equals(this.repeat, other._repeat) &&
|
||||
Property.equals(this.rotate, other._rotate)
|
||||
};
|
||||
// 将定义的材质对象添加到cesium的材质队列中
|
||||
Material._materialCache.addMaterial(MaterialType, {
|
||||
fabric: {
|
||||
type: MaterialType,
|
||||
uniforms: {
|
||||
color: new Cesium.Color(1.0, 1.0, 1.0, 1),
|
||||
image: options.image || tools.getSourceRootPath() + "/img/material/arrow.png",
|
||||
time: options.time || 0,
|
||||
repeat: new Cesium.Cartesian2(100.0, 100.0),
|
||||
rotate: 0,
|
||||
},
|
||||
// 动态材质shader
|
||||
source: `
|
||||
czm_material czm_getMaterial(czm_materialInput materialInput)
|
||||
{
|
||||
czm_material material = czm_getDefaultMaterial(materialInput);
|
||||
mat2 rotationMatrix = mat2(cos(radians(rotate)), sin(radians(rotate)), -sin(radians(rotate)), cos(radians(rotate)));
|
||||
vec2 st = repeat * materialInput.st*rotationMatrix;
|
||||
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));
|
||||
material.alpha = colorImage.a;
|
||||
material.diffuse = colorImage.rgb*1.0;
|
||||
return material;
|
||||
}`,
|
||||
components: {
|
||||
specular: 10.0,
|
||||
diffuse: "vec3(0.5)"
|
||||
},
|
||||
},
|
||||
// 透明
|
||||
translucent: function (material) {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
return new PolylineCustomMaterialProperty(options);
|
||||
}
|
||||
|
||||
Cesium.RoadMaterialProperty = RoadMaterialProperty;
|
||||
})(Cesium);
|
||||
|
||||
}
|
||||
|
||||
export { init_material }
|
||||
386
src/Obj/Base/Road/index.js
Normal file
386
src/Obj/Base/Road/index.js
Normal file
@ -0,0 +1,386 @@
|
||||
import Base from "../index";
|
||||
import PolylineImageTrailMaterialProperty from "../../Materail/PolylineImageTrailMaterialProperty";
|
||||
|
||||
class Corridor extends Base {
|
||||
// /**
|
||||
// * @constructor
|
||||
// * @description 道路
|
||||
// * @param sdk
|
||||
// * @param options {object} 属性
|
||||
// * @param options.name{string} 名称
|
||||
// * @param options.image{string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL、Canvas 或 Video 的属性
|
||||
// * @param options.width=10{number} 宽度
|
||||
// * @param options.height=0{number} 高度
|
||||
// * */
|
||||
constructor(sdk, options = {}) {
|
||||
super(sdk, options);
|
||||
this.options.name = options.name || ''
|
||||
this.options.image = options.image
|
||||
this.options.width = options.width || 10
|
||||
this.options.height = options.height || 0
|
||||
}
|
||||
|
||||
create(positions) {
|
||||
this.computeRoad(positions)
|
||||
let fromDegreesArray = []
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
}
|
||||
|
||||
let length = this.computeDistance2(positions)
|
||||
|
||||
let geometry = new Cesium.CorridorGeometry({
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
width: this.options.width,
|
||||
height: this.options.height,
|
||||
cornerType: Cesium.CornerType.MITERED,
|
||||
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
|
||||
})
|
||||
// console.log(Cesium.CorridorGeometry.createGeometry(geometry))
|
||||
// this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({//GroundPrimitive贴地
|
||||
// geometryInstances: new Cesium.GeometryInstance({
|
||||
// geometry: geometry,
|
||||
// attributes: {
|
||||
// color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 0.5))
|
||||
// }
|
||||
// }),
|
||||
// appearance: new Cesium.MaterialAppearance({
|
||||
// material: Cesium.Material.fromType('Image', {
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(length / this.options.width * 2, 1.0)
|
||||
// }),
|
||||
// faceForward: true,
|
||||
// renderState: {
|
||||
// blending: Cesium.BlendingState.ALPHA_BLEND
|
||||
// }
|
||||
// })
|
||||
// }));
|
||||
// console.log(this.entity, Outlinegeometry)
|
||||
|
||||
// this.entity = this.sdk.viewer.entities.add({
|
||||
// name: "Red corridor on surface with rounded corners",
|
||||
// corridor: {
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// width: this.options.width,
|
||||
// height: 10,
|
||||
// cornerType: Cesium.CornerType.MITERED,
|
||||
// material: new Cesium.ImageMaterialProperty({
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(100, 1.0),
|
||||
// color: Cesium.Color.TOMATO
|
||||
// })
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) { }
|
||||
|
||||
remove() {
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity)
|
||||
this.entity = null
|
||||
}
|
||||
|
||||
computeRoad(positions) {
|
||||
let fromDegreesArray = []
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
}
|
||||
let Outlinegeometry = new Cesium.CorridorGeometry({
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
width: this.options.width,
|
||||
cornerType: Cesium.CornerType.MITERED,
|
||||
vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
|
||||
})
|
||||
let geometry = Cesium.CorridorGeometry.createGeometry(Outlinegeometry)
|
||||
console.log(geometry)
|
||||
let initposition = []
|
||||
for (let i = 0; i < geometry.attributes.position.values.length; i += 3) {
|
||||
console.log(geometry.attributes.position.values[i], geometry.attributes.position.values[i + 1], geometry.attributes.position.values[i + 2])
|
||||
initposition.push(new Cesium.Cartesian3(geometry.attributes.position.values[i], geometry.attributes.position.values[i + 1], geometry.attributes.position.values[i + 2]))
|
||||
}
|
||||
console.log(initposition, Cesium.Cartesian3.fromDegrees(91.08567036051947, 24.990201656481236))
|
||||
let flag = true
|
||||
let bearing
|
||||
this.entityArray = []
|
||||
// 创建一个矩形实体,顶点坐标为世界坐标
|
||||
const rectangle = this.sdk.viewer.entities.add({
|
||||
rectangle: {
|
||||
coordinates: Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
|
||||
material: new Cesium.ImageMaterialProperty({
|
||||
image: this.options.image,
|
||||
repeat: new Cesium.Cartesian2(10, 1.0),
|
||||
}),
|
||||
},
|
||||
});
|
||||
for (let i = 0; i < geometry.indices.length; i += 3) {
|
||||
// console.log(bearing)
|
||||
|
||||
let angleInDegrees
|
||||
let theta
|
||||
if (flag) {
|
||||
let a = this.cartesian3Towgs84(initposition[geometry.indices[i]], this.sdk.viewer)
|
||||
let b = this.cartesian3Towgs84(initposition[geometry.indices[i + 2]], this.sdk.viewer)
|
||||
let point1 = turf.point([a.lng, a.lat]);
|
||||
let point2 = turf.point([b.lng, b.lat]);
|
||||
bearing = turf.bearing(point1, point2);
|
||||
// 计算两点之间的角度
|
||||
let angle = Cesium.Cartesian3.angleBetween(initposition[geometry.indices[i]], initposition[geometry.indices[i + 2]]);
|
||||
// 转换角度为角度而不是弧度
|
||||
angleInDegrees = Cesium.Math.toDegrees(angle)
|
||||
|
||||
//以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
|
||||
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(initposition[geometry.indices[i]]);
|
||||
//求世界坐标到局部坐标的变换矩阵
|
||||
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
|
||||
//a点在局部坐标的位置,其实就是局部坐标原点
|
||||
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i]], new Cesium.Cartesian3());
|
||||
//B点在以A点为原点的局部的坐标位置
|
||||
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 2]], new Cesium.Cartesian3());
|
||||
//弧度
|
||||
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.y - localPosition_A.y), (localPosition_B.x - localPosition_A.x))
|
||||
//角度
|
||||
theta = angle2 * (180 / Cesium.Math.PI);
|
||||
}
|
||||
else {
|
||||
let a = this.cartesian3Towgs84(initposition[geometry.indices[i + 1]], this.sdk.viewer)
|
||||
let b = this.cartesian3Towgs84(initposition[geometry.indices[i + 2]], this.sdk.viewer)
|
||||
let point1 = turf.point([a.lng, a.lat]);
|
||||
let point2 = turf.point([b.lng, b.lat]);
|
||||
bearing = turf.bearing(point1, point2);
|
||||
// 计算两点之间的角度
|
||||
let angle = Cesium.Cartesian3.angleBetween(initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]);
|
||||
// 转换角度为角度而不是弧度
|
||||
angleInDegrees = Cesium.Math.toDegrees(angle)
|
||||
|
||||
//以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
|
||||
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(initposition[geometry.indices[i + 1]]);
|
||||
//求世界坐标到局部坐标的变换矩阵
|
||||
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
|
||||
//a点在局部坐标的位置,其实就是局部坐标原点
|
||||
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 1]], new Cesium.Cartesian3());
|
||||
//B点在以A点为原点的局部的坐标位置
|
||||
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, initposition[geometry.indices[i + 2]], new Cesium.Cartesian3());
|
||||
//弧度
|
||||
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.y - localPosition_A.y), (localPosition_B.x - localPosition_A.x))
|
||||
//角度
|
||||
theta = angle2 * (180 / Cesium.Math.PI);
|
||||
}
|
||||
|
||||
let point1 = Cesium.Cartesian3.fromDegrees(91, 24.990201656481236);
|
||||
let point2 = Cesium.Cartesian3.fromDegrees(91, 24.626517401118033);
|
||||
// 计算两点之间的角度
|
||||
let angle = Cesium.Cartesian3.angleBetween(point1, point2);
|
||||
// 转换角度为角度而不是弧度
|
||||
let xx = Cesium.Math.toDegrees(angle)
|
||||
|
||||
flag = !flag
|
||||
bearing = bearing - 90 + 0.145
|
||||
console.log(bearing, angleInDegrees, angle, xx, theta)
|
||||
|
||||
//以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
|
||||
let localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(point1);
|
||||
//求世界坐标到局部坐标的变换矩阵
|
||||
let worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4());
|
||||
//a点在局部坐标的位置,其实就是局部坐标原点
|
||||
let localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, point1, new Cesium.Cartesian3());
|
||||
//B点在以A点为原点的局部的坐标位置
|
||||
let localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, point2, new Cesium.Cartesian3());
|
||||
//弧度
|
||||
let angle2 = Cesium.Math.fastApproximateAtan2((localPosition_B.z - localPosition_A.z), (localPosition_B.x - localPosition_A.x))
|
||||
//角度
|
||||
let theta2 = angle2 * (180 / Cesium.Math.PI);
|
||||
// alert(theta2)
|
||||
|
||||
|
||||
// let entity = this.sdk.viewer.entities.add({
|
||||
// show: this.options.show,
|
||||
// polygon: {
|
||||
// hierarchy: new Cesium.PolygonHierarchy([initposition[geometry.indices[i]], initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]]),
|
||||
// perPositionHeight: false,
|
||||
// // material: new PolylineImageTrailMaterialProperty({
|
||||
// // image: this.options.image,
|
||||
// // repeat: new Cesium.Cartesian2(10, 1.0),
|
||||
// // color: Cesium.Color.TOMATO,
|
||||
// // rotate: 0
|
||||
// // }),
|
||||
// material: new Cesium.ImageMaterialProperty({
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(1000, 1.0),
|
||||
// }),
|
||||
// stRotation: Cesium.Math.toRadians(theta - 90 - 0.0128),
|
||||
// outline: true,
|
||||
// outlineColor: Cesium.Color.BLACK,
|
||||
// }
|
||||
// })
|
||||
|
||||
let aa = 0
|
||||
|
||||
const shader = `
|
||||
uniform sampler2D image;
|
||||
uniform vec4 color;
|
||||
uniform vec2 repeat;
|
||||
|
||||
czm_material czm_getMaterial(czm_materialInput materialInput){
|
||||
czm_material material=czm_getDefaultMaterial(materialInput);
|
||||
mat2 rotationMatrix = mat2(cos(radians(-rotate)), sin(radians(-rotate)), -sin(radians(-rotate)), cos(radians(-rotate)));
|
||||
vec2 st=repeat*materialInput.st*rotationMatrix;
|
||||
float time=fract(czm_frameNumber);
|
||||
vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t));
|
||||
material.alpha=colorImage.a;
|
||||
material.diffuse=colorImage.rgb;
|
||||
return material;
|
||||
}`
|
||||
console.log(Cesium.Math.toRadians(theta - 90))
|
||||
let entity = this.sdk.viewer.scene.primitives.add(new Cesium.GroundPrimitive({
|
||||
geometryInstances: new Cesium.GeometryInstance({
|
||||
geometry: new Cesium.PolygonGeometry({
|
||||
polygonHierarchy: new Cesium.PolygonHierarchy([initposition[geometry.indices[i]], initposition[geometry.indices[i + 1]], initposition[geometry.indices[i + 2]]]),
|
||||
}),
|
||||
}),
|
||||
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||
aboveGroud: true,
|
||||
material: new Cesium.Material({
|
||||
fabric: {
|
||||
uniforms: {
|
||||
color: new Cesium.Color(1.0, 0.0, 0.0, 0.1),
|
||||
image: this.options.image,
|
||||
repeat: new Cesium.Cartesian2(1000, 1.0),
|
||||
rotate: 0
|
||||
},
|
||||
source: shader
|
||||
},
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
// console.log(entity)
|
||||
// let geometryInstances2 = new Cesium.GeometryInstance({
|
||||
// geometry: new Cesium.PolygonGeometry({
|
||||
// polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([100, 1, 101, 1, 101, -1, 100, -1])),
|
||||
// }),
|
||||
// })
|
||||
// let entity2 = this.sdk.viewer.scene.primitives.add(new Cesium.GroundPrimitive({
|
||||
// geometryInstances: geometryInstances2,
|
||||
// appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||
// aboveGroud: true,
|
||||
// material: new Cesium.Material({
|
||||
// fabric: {
|
||||
// uniforms: {
|
||||
// color: new Cesium.Color(1.0, 0.0, 0.0, 0.1),
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(1000, 1.0),
|
||||
// rotate: 0
|
||||
// },
|
||||
// source: shader
|
||||
// },
|
||||
// }),
|
||||
// }),
|
||||
// }));
|
||||
// console.log(geometryInstances2)
|
||||
// // 获取多边形的边界矩形
|
||||
// let boundingSphere = geometryInstances2.geometry.boundingSphere;
|
||||
// // 创建一个矩阵,它表示多边形的本地坐标到世界坐标的转换
|
||||
// let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(boundingSphere.center);
|
||||
// console.log(entity2, matrix)
|
||||
// setInterval(() => {
|
||||
// }, 100);
|
||||
this.entityArray.push(entity)
|
||||
console.log(entity)
|
||||
}
|
||||
|
||||
|
||||
// let entity = this.sdk.viewer.entities.add({
|
||||
// show: this.options.show,
|
||||
// polygon: {
|
||||
// hierarchy: new Cesium.PolygonHierarchy([
|
||||
// new Cesium.Cartesian3(1201222.3498141132, 5794200.4246190665, 2372132.932514765),
|
||||
// new Cesium.Cartesian3(1200929.6921250424, 5794615.962987943, 2371271.7244476764),
|
||||
// new Cesium.Cartesian3(1199139.8791256004, 5794316.892300814, 2372896.7988495603)]),
|
||||
// perPositionHeight: true,
|
||||
// material: new PolylineImageTrailMaterialProperty({
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(10, 1.0),
|
||||
// color: Cesium.Color.TOMATO,
|
||||
// rotate: 0
|
||||
// }),
|
||||
// outline: true,
|
||||
// outlineColor: Cesium.Color.BLACK,
|
||||
// }
|
||||
// })
|
||||
// console.log(entity)
|
||||
|
||||
|
||||
// 创建新材质
|
||||
let newMaterial = new Cesium.Material({
|
||||
fabric: {
|
||||
type: 'Color',
|
||||
uniforms: {
|
||||
color: new Cesium.Color(1.0, 0.0, 0.0, 1.0) // 红色
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(newMaterial)
|
||||
// this.entity = this.sdk.viewer.entities.add({
|
||||
// show: this.options.show,
|
||||
// polygon: {
|
||||
// hierarchy: new Cesium.PolygonHierarchy(initposition),
|
||||
// perPositionHeight: false,
|
||||
// material: new Cesium.ImageMaterialProperty({
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(100, 1.0),
|
||||
// color: Cesium.Color.AQUA
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
|
||||
for (let i = 0; i < initposition.length; i++) {
|
||||
let entity = this.sdk.viewer.entities.add({
|
||||
name: 'node-secondary-edit-point',
|
||||
index: i,
|
||||
position: initposition[i],
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/point.png',
|
||||
width: 15,
|
||||
height: 15,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||
},
|
||||
label: {
|
||||
text: '' + i,
|
||||
pixelOffset: { x: 0, y: -20 },
|
||||
},
|
||||
})
|
||||
}
|
||||
this.sdk.viewer.entities.add({
|
||||
name: 'node-secondary-edit-point',
|
||||
position: Cesium.Cartesian3.fromDegrees(91.08567036051947, 24.990201656481236),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/point.png',
|
||||
width: 15,
|
||||
height: 15,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||
},
|
||||
})
|
||||
|
||||
this.sdk.viewer.entities.add({
|
||||
name: 'node-secondary-edit-point',
|
||||
position: Cesium.Cartesian3.fromDegrees(91.08588488854294, 24.626517401118033),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/point.png',
|
||||
width: 15,
|
||||
height: 15,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
test(v) {
|
||||
for (let i = 0; i < this.entityArray.length; i++) {
|
||||
this.entityArray[i].polygon.stRotation = Cesium.Math.toRadians(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Corridor
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user