代码迁移
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 }
|
||||
2380
src/Obj/Base/AssembleObject/index.js
Normal file
2380
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 }
|
||||
2647
src/Obj/Base/AttackArrowObject/index.js
Normal file
2647
src/Obj/Base/AttackArrowObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
73
src/Obj/Base/BaseSource/BaseLayer/ArcgisImagery/index.js
Normal file
73
src/Obj/Base/BaseSource/BaseLayer/ArcgisImagery/index.js
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @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,)
|
||||
}
|
||||
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}
|
||||
71
src/Obj/Base/BaseSource/BaseLayer/GdImagery/index.js
Normal file
71
src/Obj/Base/BaseSource/BaseLayer/GdImagery/index.js
Normal file
@ -0,0 +1,71 @@
|
||||
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,)
|
||||
}
|
||||
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}
|
||||
146
src/Obj/Base/BaseSource/BaseLayer/Layer/index.js
Normal file
146
src/Obj/Base/BaseSource/BaseLayer/Layer/index.js
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @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,)
|
||||
}
|
||||
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
|
||||
57
src/Obj/Base/BaseSource/BaseLayer/Layer3rdparty/index.js
vendored
Normal file
57
src/Obj/Base/BaseSource/BaseLayer/Layer3rdparty/index.js
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @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,)
|
||||
}
|
||||
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
|
||||
311
src/Obj/Base/BaseSource/BaseLayer/index.js
Normal file
311
src/Obj/Base/BaseSource/BaseLayer/index.js
Normal file
@ -0,0 +1,311 @@
|
||||
/**
|
||||
* @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 } 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._layerIndex
|
||||
}
|
||||
|
||||
get layer_index() {
|
||||
return this.entity._layerIndex
|
||||
}
|
||||
|
||||
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)
|
||||
},
|
||||
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">视野缩放</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 }
|
||||
1689
src/Obj/Base/BaseSource/BaseModel/Model/index.js
Normal file
1689
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: this.getDateTimeString(),
|
||||
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: this.getDateTimeString(),
|
||||
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: '全景图' + (this.options.attribute.vr.content.length + 1),
|
||||
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: '全景图' + (this.options.attribute.vr.content.length + 1),
|
||||
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
|
||||
|
||||
286
src/Obj/Base/BaseSource/BaseTerrain/index.js
Normal file
286
src/Obj/Base/BaseSource/BaseTerrain/index.js
Normal file
@ -0,0 +1,286 @@
|
||||
/**
|
||||
* @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({})
|
||||
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()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
|
||||
},
|
||||
// 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
|
||||
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 }
|
||||
2619
src/Obj/Base/BillboardObject/index.js
Normal file
2619
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 }
|
||||
1576
src/Obj/Base/CircleDiffuse/index.js
Normal file
1576
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 }
|
||||
2173
src/Obj/Base/CircleObject/index.js
Normal file
2173
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
|
||||
152
src/Obj/Base/CurvelineObject/_element.js
Normal file
152
src/Obj/Base/CurvelineObject/_element.js
Normal file
@ -0,0 +1,152 @@
|
||||
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 54%;">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label">原始长度:</span>
|
||||
<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 class="row">
|
||||
<div class="col input-select-fit-unit-box">
|
||||
<span class="label">拟合长度:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" style="flex: 0 0 130px;" @model="fitLength">
|
||||
<div class="input-select-fit-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">
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<span class="label">缓冲颜色</span>
|
||||
<div class="extendColor"></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">
|
||||
</div>
|
||||
<div class="col">
|
||||
</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;
|
||||
2753
src/Obj/Base/CurvelineObject/index.js
Normal file
2753
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 }
|
||||
2171
src/Obj/Base/EllipseObject/index.js
Normal file
2171
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 }
|
||||
382
src/Obj/Base/Explosion/index.js
Normal file
382
src/Obj/Base/Explosion/index.js
Normal file
@ -0,0 +1,382 @@
|
||||
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} 爆炸属性
|
||||
* */
|
||||
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
|
||||
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 }
|
||||
418
src/Obj/Base/FlyRoam/index.js
Normal file
418
src/Obj/Base/FlyRoam/index.js
Normal file
@ -0,0 +1,418 @@
|
||||
|
||||
/**
|
||||
* @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(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
|
||||
}
|
||||
})
|
||||
|
||||
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
|
||||
191
src/Obj/Base/GeoJson/index.js
Normal file
191
src/Obj/Base/GeoJson/index.js
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @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 { 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) {
|
||||
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
|
||||
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 ewPlugins('colorpicker', {
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.color = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get 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 ewPlugins('colorpicker', {
|
||||
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
|
||||
42
src/Obj/Base/GroundImage/_element.js
Normal file
42
src/Obj/Base/GroundImage/_element.js
Normal file
@ -0,0 +1,42 @@
|
||||
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 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">
|
||||
<span class="label">调整大小</span>
|
||||
<input type="range" max="99999" 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="99999" step="0.1" @model="scale">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
||||
558
src/Obj/Base/GroundImage/index.js
Normal file
558
src/Obj/Base/GroundImage/index.js
Normal file
@ -0,0 +1,558 @@
|
||||
import Dialog from '../../Element/Dialog';
|
||||
import cy_slider from "../../Element/cy_html_slider";
|
||||
import { html } from "./_element";
|
||||
import EventBinding from '../../Element/Dialog/eventBinding';
|
||||
import Base from "../index";
|
||||
import MouseEvent from '../../../Event/index'
|
||||
import { syncData } from '../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||
|
||||
class GroundImage extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 贴地图片
|
||||
* @param options {object} 属性
|
||||
* @param options.id {string} 唯一标识
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.angle=0 {number} 旋转角度
|
||||
* @param options.scale=1 {number} 比例
|
||||
* @param options.flipe {object} 翻转
|
||||
* @param options.flipe.x=false {boolean} 绕X轴翻转
|
||||
* @param options.flipe.y=false {boolean} 绕Y轴翻转
|
||||
* @param options.url {string} 图片地址
|
||||
* @param {Array.<object>} options.positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.name = options.name || '未命名对象'
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.options.url = options.url
|
||||
this.options.angle = options.angle || 0
|
||||
this.options.scale = (options.scale || options.scale === 0) ? options.scale : 1
|
||||
this.options.positions = options.positions
|
||||
|
||||
this.options.flipe = options.flipe || {}
|
||||
this.options.flipe.x = this.options.flipe.x || false
|
||||
this.options.flipe.y = this.options.flipe.y || false
|
||||
|
||||
this.entity = {
|
||||
id: this.options.id
|
||||
}
|
||||
this._positionEditing = false
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this.previous = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
this._EventBinding = new EventBinding()
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.create()
|
||||
}
|
||||
|
||||
get angle() {
|
||||
return this.options.angle
|
||||
}
|
||||
|
||||
set angle(v) {
|
||||
this.options.angle = v
|
||||
this._elms.angle && this._elms.angle.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get scale() {
|
||||
return this.options.scale
|
||||
}
|
||||
|
||||
set scale(v) {
|
||||
this.options.scale = v
|
||||
this._elms.scale && this._elms.scale.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get flipeY() {
|
||||
return this.options.flipe.y
|
||||
}
|
||||
set flipeY(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.flipe.y = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
this.entity && (this.entity.rectangle.material = new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
get flipeX() {
|
||||
return this.options.flipe.x
|
||||
}
|
||||
set flipeX(v) {
|
||||
if (typeof v === "boolean") {
|
||||
this.options.flipe.x = v
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
this.entity.rectangle.material = new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.error("参数必须为boolean")
|
||||
}
|
||||
}
|
||||
|
||||
async create() {
|
||||
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.positions.lat)) * (0.0001*this.options.scale)
|
||||
// let fromDegreesArray = [
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat - 0.05,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat - 0.05,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat + 0.05,
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat + 0.05,
|
||||
// ]
|
||||
let response = await fetch(this.options.url, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
if (response.ok) {
|
||||
// let data = await response.blob()
|
||||
// let arrayBuffer = await data.arrayBuffer()
|
||||
// const str = String.fromCharCode(...new Uint8Array(arrayBuffer));
|
||||
const img = new Image();
|
||||
img.src = this.options.url;
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置画布大小
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
// 绘制图像
|
||||
if (this.flipeX) {
|
||||
ctx.scale(1, -1);
|
||||
ctx.translate(0, -canvas.height)
|
||||
}
|
||||
if (this.flipeY) {
|
||||
ctx.scale(-1, 1);
|
||||
ctx.translate(-canvas.width, 0);
|
||||
}
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
this.entity = this.sdk.viewer.entities.add({
|
||||
id: this.options.id,
|
||||
show: this.options.show,
|
||||
rectangle: {
|
||||
coordinates: new Cesium.CallbackProperty(() => {
|
||||
let gap = Math.abs(Math.cos(Math.PI / 180 * this.options.positions.lat)) * (0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.positions.lng - (0.0001 * this.options.scale), this.options.positions.lat - gap,
|
||||
// this.options.positions.lng + 0.05, this.options.positions.lat - 0.05,
|
||||
this.options.positions.lng + (0.0001 * this.options.scale), this.options.positions.lat + gap,
|
||||
// this.options.positions.lng - 0.05, this.options.positions.lat + 0.05,
|
||||
]
|
||||
|
||||
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
|
||||
}, false),
|
||||
material: new Cesium.ImageMaterialProperty({
|
||||
image: canvas,
|
||||
transparent: true
|
||||
}),
|
||||
rotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false),
|
||||
stRotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false)
|
||||
},
|
||||
})
|
||||
if (this.sdk.viewer._element.className === 'cesium-viewer 2d') {
|
||||
this.entity.rectangle.height = 0
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// if (data.code === 200 || data.code === 0) {
|
||||
// this.$message({
|
||||
// message: '添加成功!',
|
||||
// type: 'success',
|
||||
// duration: 1500
|
||||
// });
|
||||
// this.close()
|
||||
// // this.$emit('getBuildingList')
|
||||
// // this.$emit('onSubmitCallBack')
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = { ...this.options }
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._DialogObject = await new Dialog(this.sdk, this.originalOptions, {
|
||||
title: '军标属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.name = this.name.trim()
|
||||
if (!this.name) {
|
||||
this.name = '未命名对象'
|
||||
}
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions)
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
},
|
||||
resetCallBack: () => {
|
||||
this.reset()
|
||||
this.Dialog.resetCallBack && this.Dialog.resetCallBack()
|
||||
},
|
||||
removeCallBack: () => {
|
||||
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||
},
|
||||
closeCallBack: () => {
|
||||
this.reset()
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
this.positionEditing = false
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
this.positionEditing = !this.positionEditing
|
||||
},
|
||||
addFootElm: [
|
||||
{
|
||||
tagName: 'button',
|
||||
className: 'flipe-over-y',
|
||||
innerHTML: 'Y轴翻转',
|
||||
event: [
|
||||
'click',
|
||||
() => {
|
||||
this.flipeY = !this.flipeY
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
tagName: 'button',
|
||||
className: 'flipe-over-x',
|
||||
innerHTML: 'X轴翻转',
|
||||
event: [
|
||||
'click',
|
||||
() => {
|
||||
this.flipeX = !this.flipeX
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, true)
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' ground-image'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
|
||||
} else {
|
||||
if (this._DialogObject && this._DialogObject.remove) {
|
||||
this._DialogObject.remove()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this._positionEditing = status
|
||||
this.previous = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.positions.lng = positions.lng
|
||||
this.options.positions.lat = positions.lat
|
||||
this.options.positions.alt = positions.alt
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.positions.lng = positions.lng
|
||||
this.options.positions.lat = positions.lat
|
||||
this.options.positions.alt = positions.alt
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
this.event.gesture_pinck_start(() => { })
|
||||
this.event.gesture_pinck_end(() => { })
|
||||
this.positionEditing = false
|
||||
})
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
this.positionEditing = false
|
||||
})
|
||||
|
||||
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||
let startTime = new Date()
|
||||
this.event.gesture_pinck_end(() => {
|
||||
let endTime = new Date()
|
||||
if (endTime - startTime >= 500) {
|
||||
// 长按取消
|
||||
this.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.positions.lng = positions.lng
|
||||
this.options.positions.lat = positions.lat
|
||||
this.options.positions.alt = positions.alt
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
this.event.gesture_pinck_start(() => { })
|
||||
this.event.gesture_pinck_end(() => { })
|
||||
this.positionEditing = false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
else {
|
||||
if (this.event) {
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
this.event.gesture_pinck_start(() => { })
|
||||
this.event.gesture_pinck_end(() => { })
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
this.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this._positionEditing
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到
|
||||
*/
|
||||
async flyTo(options = {}) {
|
||||
setActiveViewer(0)
|
||||
closeRotateAround(this.sdk)
|
||||
closeViewFollow(this.sdk)
|
||||
|
||||
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||
let orientation = {
|
||||
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||
}
|
||||
|
||||
let lng = this.options.customView.relativePosition.lng
|
||||
let lat = this.options.customView.relativePosition.lat
|
||||
let alt = this.options.customView.relativePosition.alt
|
||||
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
|
||||
let position = { lng: 0, lat: 0 }
|
||||
if (this.options.position) {
|
||||
position = { ...this.options.position }
|
||||
}
|
||||
else if (this.options.positions) {
|
||||
position = { ...this.options.positions[0] }
|
||||
}
|
||||
else if (this.options.center) {
|
||||
position = { ...this.options.center }
|
||||
}
|
||||
else if (this.options.start) {
|
||||
position = { ...this.options.start }
|
||||
}
|
||||
else {
|
||||
if (this.options.hasOwnProperty('lng')) {
|
||||
position.lng = this.options.lng
|
||||
}
|
||||
if (this.options.hasOwnProperty('lat')) {
|
||||
position.lat = this.options.lat
|
||||
}
|
||||
if (this.options.hasOwnProperty('alt')) {
|
||||
position.alt = this.options.alt
|
||||
}
|
||||
}
|
||||
// 如果没有高度值,则获取紧贴高度计算
|
||||
if (!position.hasOwnProperty('alt')) {
|
||||
position.alt = await this.getClampToHeight(position)
|
||||
}
|
||||
lng = this.options.customView.relativePosition.lng + position.lng
|
||||
lat = this.options.customView.relativePosition.lat + position.lat
|
||||
alt = this.options.customView.relativePosition.alt + position.alt
|
||||
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: destination,
|
||||
orientation: orientation
|
||||
})
|
||||
}
|
||||
else {
|
||||
let gap = Math.abs(Math.cos(Math.PI / 180 * this.options.positions.lat)) * (0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
[this.options.positions.lng - (0.0001 * this.options.scale), this.options.positions.lat - gap],
|
||||
[this.options.positions.lng + (0.0001 * this.options.scale), this.options.positions.lat + gap],
|
||||
]
|
||||
let positionArray = []
|
||||
let height = 0
|
||||
let position = this.options.positions
|
||||
let point1 = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 0);
|
||||
let point2 = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 10000000);
|
||||
let direction = Cesium.Cartesian3.subtract(point2, point1, new Cesium.Cartesian3());
|
||||
let c = Cesium.Cartesian3.normalize(direction, direction);
|
||||
let ray = new Cesium.Ray(point1, c);
|
||||
let r = {}
|
||||
let pickedObjects = this.sdk.viewer.scene.drillPickFromRay(ray);
|
||||
for (let i = 0; i < pickedObjects.length; i++) {
|
||||
if (pickedObjects[i].position) {
|
||||
r = pickedObjects[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (r && r.position) {
|
||||
height = this.cartesian3Towgs84(r.position, this.sdk.viewer).alt
|
||||
}
|
||||
else {
|
||||
try {
|
||||
var promise = await Cesium.sampleTerrainMostDetailed(this.sdk.viewer.terrainProvider, [Cesium.Cartographic.fromDegrees(position.lng, position.lat)]);
|
||||
height = promise[0].height
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < fromDegreesArray.length; i++) {
|
||||
let a = Cesium.Cartesian3.fromDegrees(...fromDegreesArray[i], height)
|
||||
positionArray.push(a.x, a.y, a.z)
|
||||
}
|
||||
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||
offset: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.name = this.originalOptions.name
|
||||
this.angle = this.originalOptions.angle
|
||||
this.scale = this.originalOptions.scale
|
||||
}
|
||||
|
||||
async remove() {
|
||||
this.event && this.event.destroy()
|
||||
this.tip && this.tip.destroy()
|
||||
this.sdk.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
setPosition(v) {
|
||||
this.options.positions.lng = v.position.lng
|
||||
this.options.positions.lat = v.position.lat
|
||||
this.options.positions.alt = v.position.alt
|
||||
}
|
||||
}
|
||||
|
||||
export default GroundImage
|
||||
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">
|
||||
</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
2067
src/Obj/Base/GroundSvg/index.js
Normal file
2067
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
|
||||
589
src/Obj/Base/LabelObject/index.js
Normal file
589
src/Obj/Base/LabelObject/index.js
Normal file
@ -0,0 +1,589 @@
|
||||
/**
|
||||
* 标注
|
||||
*/
|
||||
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
|
||||
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) || 'Helvetica'
|
||||
this.options.fontSize = options.fontSize || 20
|
||||
this.options.lineWidth = options.lineWidth || 4
|
||||
this.options.lineColor = options.lineColor || '#fff000'
|
||||
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 || [
|
||||
'#42c6ef',
|
||||
'#42c6ef'
|
||||
]
|
||||
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)
|
||||
|
||||
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) || 'Helvetica'
|
||||
this.updateBillboardImage()
|
||||
}
|
||||
|
||||
get lineWidth() {
|
||||
return this.options.lineWidth
|
||||
}
|
||||
set lineWidth(v) {
|
||||
this.options.lineWidth = Number(v)
|
||||
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() {
|
||||
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
|
||||
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 canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
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
|
||||
}
|
||||
canvas.width = canvasWidth
|
||||
|
||||
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 canvas2 = document.createElement('canvas')
|
||||
const ctx2 = canvas2.getContext('2d')
|
||||
canvas2.width = canvas.width + 10
|
||||
canvas2.height = canvas.height + 10
|
||||
ctx2.drawImage(canvas, 5, 5);
|
||||
|
||||
// const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
// ctx.putImageData(imageData, 40, 40);
|
||||
return canvas2
|
||||
}
|
||||
|
||||
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;
|
||||
719
src/Obj/Base/ParticleEffects/Flame/index.js
Normal file
719
src/Obj/Base/ParticleEffects/Flame/index.js
Normal file
@ -0,0 +1,719 @@
|
||||
/**
|
||||
* 火焰特效
|
||||
*/
|
||||
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 } 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.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL或Canvas 的属性
|
||||
* @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 _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
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") {
|
||||
this.options.show = v
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
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.show = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
} 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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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;
|
||||
744
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
744
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
@ -0,0 +1,744 @@
|
||||
/**
|
||||
* 喷泉特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Fountain extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @description 喷泉特效
|
||||
* @param sdk
|
||||
* @param options {object} 粒子属性
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL或Canvas 的属性
|
||||
* @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.gravity=-3.5{number} 重力值
|
||||
* @param options.lng 经度
|
||||
* @param options.lat 纬度
|
||||
* @param options.alt 高度
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
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") {
|
||||
this.options.show = v
|
||||
if(this.entity && this.sdk.viewer.camera.positionCartographic.height <10000000) {
|
||||
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.show = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
} 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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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;
|
||||
717
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
717
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
@ -0,0 +1,717 @@
|
||||
/**
|
||||
* 烟雾特效
|
||||
*/
|
||||
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 } 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.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL或Canvas 的属性
|
||||
* @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 _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
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") {
|
||||
this.options.show = v
|
||||
if(this.entity && this.sdk.viewer.camera.positionCartographic.height <10000000) {
|
||||
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.show = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
} 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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 }
|
||||
952
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
952
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
@ -0,0 +1,952 @@
|
||||
/**
|
||||
* 水柱特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, 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.show=true {boolean} 显示/隐藏
|
||||
* @param options.name {string} 名称
|
||||
* @param options.url {string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL或Canvas 的属性
|
||||
* @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 _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
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") {
|
||||
this.options.show = v
|
||||
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
|
||||
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.show = v
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
syncSplitData(this.sdk, this.options.id)
|
||||
} 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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 ewPlugins('colorpicker', {
|
||||
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 }
|
||||
2641
src/Obj/Base/PincerArrowObject/index.js
Normal file
2641
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 }
|
||||
2827
src/Obj/Base/PolygonObject/index.js
Normal file
2827
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 }
|
||||
123
src/Obj/Base/PolyhedronObject/eventBinding.js
Normal file
123
src/Obj/Base/PolyhedronObject/eventBinding.js
Normal file
@ -0,0 +1,123 @@
|
||||
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 !== '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
|
||||
}
|
||||
})
|
||||
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;
|
||||
1656
src/Obj/Base/PolyhedronObject/index.js
Normal file
1656
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
154
src/Obj/Base/PolylineObject/_element.js
Normal file
154
src/Obj/Base/PolylineObject/_element.js
Normal file
@ -0,0 +1,154 @@
|
||||
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 54%;">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col input-select-unit-box">
|
||||
<span class="label">原始长度:</span>
|
||||
<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 class="row">
|
||||
<div class="col input-select-fit-unit-box">
|
||||
<span class="label">拟合长度:</span>
|
||||
<input class="input input-text" readonly="readonly" type="text" style="flex: 0 0 130px;" @model="fitLength">
|
||||
<div class="input-select-fit-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">
|
||||
<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">
|
||||
<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">
|
||||
<span class="label">线段圆滑</span>
|
||||
<input class="btn-switch" type="checkbox" @model="smooth">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">线段缓冲</span>
|
||||
<input class="btn-switch" type="checkbox" @model="extend">
|
||||
</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" data-min="0.01" max="999999" @model="extendWidth">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">缓冲颜色</span>
|
||||
<div class="extendColor"></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 }
|
||||
120
src/Obj/Base/PolylineObject/eventBinding.js
Normal file
120
src/Obj/Base/PolylineObject/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;
|
||||
2793
src/Obj/Base/PolylineObject/index.js
Normal file
2793
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 }
|
||||
1508
src/Obj/Base/RadarScan/index.js
Normal file
1508
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 }
|
||||
1462
src/Obj/Base/RadarScanStereoscopic/index.js
Normal file
1462
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.computeDistance(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
|
||||
787
src/Obj/Base/Road/index3.js
Normal file
787
src/Obj/Base/Road/index3.js
Normal file
@ -0,0 +1,787 @@
|
||||
/**
|
||||
* 道路
|
||||
*/
|
||||
import Base from "../index";
|
||||
import PolylineImageTrailMaterialProperty from "../../Materail/PolylineImageTrailMaterialProperty";
|
||||
import { init_material } from "./RoadMaterialProperty";
|
||||
|
||||
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
|
||||
init_material()
|
||||
}
|
||||
|
||||
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.computeDistance(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 t = 0
|
||||
setInterval(() => {
|
||||
t++
|
||||
}, 100);
|
||||
// let entity = this.sdk.viewer.scene.primitives.add(new Cesium.GroundPolylinePrimitive({
|
||||
// geometryInstances : new Cesium.GeometryInstance({
|
||||
// geometry : new Cesium.GroundPolylineGeometry({
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// width: this.options.width,
|
||||
// cornerType: Cesium.CornerType.MITERED,
|
||||
// vertexFormat: Cesium.MaterialAppearance.MaterialSupport.ALL.vertexFormat
|
||||
// })
|
||||
// }),
|
||||
// appearance: new Cesium.PolylineMaterialAppearance({
|
||||
// aboveGroud: true,
|
||||
// material: new Cesium.Material({
|
||||
// fabric: {
|
||||
// uniforms: {
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(1000, 1.0),
|
||||
// color: new Cesium.Color(1.0, 0.0, 0.0, 0.1)
|
||||
// },
|
||||
// source: `
|
||||
// uniform sampler2D image;
|
||||
// uniform vec4 color;
|
||||
// uniform vec2 repeat;
|
||||
|
||||
// czm_material czm_getMaterial(czm_materialInput materialInput){
|
||||
// czm_material material=czm_getDefaultMaterial(materialInput);
|
||||
// vec2 st=repeat*materialInput.st;
|
||||
// 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;
|
||||
// }`,
|
||||
// },
|
||||
// }),
|
||||
// vertexShaderSource: `#define CLIP_POLYLINE
|
||||
// void clipLineSegmentToNearPlane(
|
||||
// vec3 p0,
|
||||
// vec3 p1,
|
||||
// out vec4 positionWC,
|
||||
// out bool clipped,
|
||||
// out bool culledByNearPlane,
|
||||
// out vec4 clippedPositionEC)
|
||||
// {
|
||||
// culledByNearPlane = false;
|
||||
// clipped = false;
|
||||
// vec3 p0ToP1 = p1 - p0;
|
||||
// float magnitude = length(p0ToP1);
|
||||
// vec3 direction = normalize(p0ToP1);
|
||||
// float endPoint0Distance = czm_currentFrustum.x + p0.z;
|
||||
// float denominator = -direction.z;
|
||||
// if (endPoint0Distance > 0.0 && abs(denominator) < czm_epsilon7)
|
||||
// {
|
||||
// culledByNearPlane = true;
|
||||
// }
|
||||
// else if (endPoint0Distance > 0.0)
|
||||
// {
|
||||
// float t = endPoint0Distance / denominator;
|
||||
// if (t < 0.0 || t > magnitude)
|
||||
// {
|
||||
// culledByNearPlane = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// p0 = p0 + t * direction;
|
||||
// p0.z = min(p0.z, -czm_currentFrustum.x);
|
||||
// clipped = true;
|
||||
// }
|
||||
// }
|
||||
// clippedPositionEC = vec4(p0, 1.0);
|
||||
// positionWC = czm_eyeToWindowCoordinates(clippedPositionEC);
|
||||
// }
|
||||
// vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
|
||||
// {
|
||||
// #ifdef POLYLINE_DASH
|
||||
// vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);
|
||||
// vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);
|
||||
// vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);
|
||||
// vec2 lineDir;
|
||||
// if (usePrevious) {
|
||||
// lineDir = normalize(positionWindow.xy - previousWindow.xy);
|
||||
// }
|
||||
// else {
|
||||
// lineDir = normalize(nextWindow.xy - positionWindow.xy);
|
||||
// }
|
||||
// angle = atan(lineDir.x, lineDir.y) - 1.570796327;
|
||||
// angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
|
||||
// #endif
|
||||
// vec4 clippedPrevWC, clippedPrevEC;
|
||||
// bool prevSegmentClipped, prevSegmentCulled;
|
||||
// clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, clippedPrevWC, prevSegmentClipped, prevSegmentCulled, clippedPrevEC);
|
||||
// vec4 clippedNextWC, clippedNextEC;
|
||||
// bool nextSegmentClipped, nextSegmentCulled;
|
||||
// clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, clippedNextWC, nextSegmentClipped, nextSegmentCulled, clippedNextEC);
|
||||
// bool segmentClipped, segmentCulled;
|
||||
// vec4 clippedPositionWC, clippedPositionEC;
|
||||
// clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);
|
||||
// if (segmentCulled)
|
||||
// {
|
||||
// return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
// }
|
||||
// vec2 directionToPrevWC = normalize(clippedPrevWC.xy - clippedPositionWC.xy);
|
||||
// vec2 directionToNextWC = normalize(clippedNextWC.xy - clippedPositionWC.xy);
|
||||
// if (prevSegmentCulled)
|
||||
// {
|
||||
// directionToPrevWC = -directionToNextWC;
|
||||
// }
|
||||
// else if (nextSegmentCulled)
|
||||
// {
|
||||
// directionToNextWC = -directionToPrevWC;
|
||||
// }
|
||||
// vec2 thisSegmentForwardWC, otherSegmentForwardWC;
|
||||
// if (usePrevious)
|
||||
// {
|
||||
// thisSegmentForwardWC = -directionToPrevWC;
|
||||
// otherSegmentForwardWC = directionToNextWC;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// thisSegmentForwardWC = directionToNextWC;
|
||||
// otherSegmentForwardWC = -directionToPrevWC;
|
||||
// }
|
||||
// vec2 thisSegmentLeftWC = vec2(-thisSegmentForwardWC.y, thisSegmentForwardWC.x);
|
||||
// vec2 leftWC = thisSegmentLeftWC;
|
||||
// float expandWidth = width * 0.5;
|
||||
// if (!czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) && !czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
|
||||
// {
|
||||
// vec2 otherSegmentLeftWC = vec2(-otherSegmentForwardWC.y, otherSegmentForwardWC.x);
|
||||
// vec2 leftSumWC = thisSegmentLeftWC + otherSegmentLeftWC;
|
||||
// float leftSumLength = length(leftSumWC);
|
||||
// leftWC = leftSumLength < czm_epsilon6 ? thisSegmentLeftWC : (leftSumWC / leftSumLength);
|
||||
// vec2 u = -thisSegmentForwardWC;
|
||||
// vec2 v = leftWC;
|
||||
// float sinAngle = abs(u.x * v.y - u.y * v.x);
|
||||
// expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
|
||||
// }
|
||||
// vec2 offset = leftWC * expandDirection * expandWidth * czm_pixelRatio;
|
||||
// return vec4(clippedPositionWC.xy + offset, -clippedPositionWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
|
||||
// }
|
||||
// vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)
|
||||
// {
|
||||
// vec4 positionEC = czm_modelViewRelativeToEye * position;
|
||||
// vec4 prevEC = czm_modelViewRelativeToEye * previous;
|
||||
// vec4 nextEC = czm_modelViewRelativeToEye * next;
|
||||
// return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);
|
||||
// }
|
||||
|
||||
// attribute vec3 position3DHigh;
|
||||
// attribute vec3 position3DLow;
|
||||
// attribute vec3 prevPosition3DHigh;
|
||||
// attribute vec3 prevPosition3DLow;
|
||||
// attribute vec3 nextPosition3DHigh;
|
||||
// attribute vec3 nextPosition3DLow;
|
||||
// attribute vec2 expandAndWidth;
|
||||
// attribute vec2 st;
|
||||
// attribute float batchId;
|
||||
// varying float v_width;
|
||||
// varying vec2 v_st;
|
||||
// varying float v_polylineAngle;
|
||||
// void main()
|
||||
// {
|
||||
// float expandDir = expandAndWidth.x;
|
||||
// float width = abs(expandAndWidth.y) + 0.5;
|
||||
// bool usePrev = expandAndWidth.y < 0.0;
|
||||
// vec4 p = czm_computePosition();
|
||||
// vec4 prev = czm_computePrevPosition();
|
||||
// vec4 next = czm_computeNextPosition();
|
||||
// float angle;
|
||||
// vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);
|
||||
// gl_Position = czm_viewportOrthographic * positionWC;
|
||||
// v_width = width;
|
||||
// v_st.s = st.s;
|
||||
// v_st.t = czm_writeNonPerspective(st.t, gl_Position.w);
|
||||
// v_polylineAngle = angle;
|
||||
// }`,
|
||||
// fragmentShaderSource: `#ifdef VECTOR_TILE
|
||||
// uniform vec4 u_highlightColor;
|
||||
// #endif
|
||||
// varying vec2 v_st;
|
||||
// void main()
|
||||
// {
|
||||
// czm_materialInput materialInput;
|
||||
// vec2 st = v_st;
|
||||
// st.t = czm_readNonPerspective(st.t, gl_FragCoord.w);
|
||||
// materialInput.s = st.s;
|
||||
// materialInput.st = st;
|
||||
// materialInput.str = vec3(st, 0.0);
|
||||
// czm_material material = czm_getMaterial(materialInput);
|
||||
// gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
|
||||
// #ifdef VECTOR_TILE
|
||||
// gl_FragColor *= u_highlightColor;
|
||||
// #endif
|
||||
// czm_writeLogDepth();
|
||||
// }`
|
||||
// }),
|
||||
// }));
|
||||
console.log(entity)
|
||||
// let entity = this.sdk.viewer.entities.add({
|
||||
// corridor: {
|
||||
// positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
// width: 20000.0,
|
||||
// cornerType: Cesium.CornerType.MITERED,
|
||||
// material: new Cesium.RoadMaterialProperty({
|
||||
// image: this.getSourceRootPath() + '/img/asphaltRoad.jpg',
|
||||
// color: this.options.color,
|
||||
// repeat: new Cesium.CallbackProperty(() => {
|
||||
// let positionProperty = entity.corridor.positions;
|
||||
// let positions = positionProperty.getValue(this.sdk.viewer.clock.currentTime);
|
||||
|
||||
// if (!Cesium.defined(positions)) {
|
||||
// return new Cesium.Cartesian2(1.0, 1.0);
|
||||
// }
|
||||
|
||||
// let distance = 0;
|
||||
// for (let i = 0; i < positions.length - 1; ++i) {
|
||||
// distance += Cesium.Cartesian3.distance(positions[i], positions[i + 1]);
|
||||
// }
|
||||
|
||||
// let imgProportion = 945 / 411 // 图片长宽比例
|
||||
// let repeatX = distance / 20000;
|
||||
// repeatX = repeatX / imgProportion
|
||||
|
||||
// return new Cesium.Cartesian2(repeatX, 1.0);
|
||||
// }, false),
|
||||
// duration: 0,
|
||||
// rotate: new Cesium.CallbackProperty(() => {
|
||||
// return t
|
||||
// }),
|
||||
// })
|
||||
// },
|
||||
// });
|
||||
// console.log(entity)
|
||||
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);
|
||||
vec2 st=repeat*materialInput.st;
|
||||
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.Primitive({
|
||||
// geometryInstances : new Cesium.GeometryInstance({
|
||||
// geometry : new Cesium.PolylineGeometry({
|
||||
// positions : Cesium.Cartesian3.fromDegreesArray([
|
||||
// 0.0, 0.0,
|
||||
// 5.0, 0.0
|
||||
// ]),
|
||||
// width : 10.0,
|
||||
// vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT
|
||||
// })
|
||||
// }),
|
||||
// appearance: new Cesium.PolylineMaterialAppearance({
|
||||
// aboveGroud: true,
|
||||
// material: new Cesium.Material({
|
||||
// fabric: {
|
||||
// uniforms: {
|
||||
// image: this.options.image,
|
||||
// repeat: new Cesium.Cartesian2(1000, 1.0),
|
||||
// color: new Cesium.Color(1.0, 0.0, 0.0, 0.1)
|
||||
// },
|
||||
// source: shader,
|
||||
// },
|
||||
// }),
|
||||
// vertexShaderSource: `#define CLIP_POLYLINE
|
||||
// void clipLineSegmentToNearPlane(
|
||||
// vec3 p0,
|
||||
// vec3 p1,
|
||||
// out vec4 positionWC,
|
||||
// out bool clipped,
|
||||
// out bool culledByNearPlane,
|
||||
// out vec4 clippedPositionEC)
|
||||
// {
|
||||
// culledByNearPlane = false;
|
||||
// clipped = false;
|
||||
// vec3 p0ToP1 = p1 - p0;
|
||||
// float magnitude = length(p0ToP1);
|
||||
// vec3 direction = normalize(p0ToP1);
|
||||
// float endPoint0Distance = czm_currentFrustum.x + p0.z;
|
||||
// float denominator = -direction.z;
|
||||
// if (endPoint0Distance > 0.0 && abs(denominator) < czm_epsilon7)
|
||||
// {
|
||||
// culledByNearPlane = true;
|
||||
// }
|
||||
// else if (endPoint0Distance > 0.0)
|
||||
// {
|
||||
// float t = endPoint0Distance / denominator;
|
||||
// if (t < 0.0 || t > magnitude)
|
||||
// {
|
||||
// culledByNearPlane = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// p0 = p0 + t * direction;
|
||||
// p0.z = min(p0.z, -czm_currentFrustum.x);
|
||||
// clipped = true;
|
||||
// }
|
||||
// }
|
||||
// clippedPositionEC = vec4(p0, 1.0);
|
||||
// positionWC = czm_eyeToWindowCoordinates(clippedPositionEC);
|
||||
// }
|
||||
// vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
|
||||
// {
|
||||
// #ifdef POLYLINE_DASH
|
||||
// vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);
|
||||
// vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);
|
||||
// vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);
|
||||
// vec2 lineDir;
|
||||
// if (usePrevious) {
|
||||
// lineDir = normalize(positionWindow.xy - previousWindow.xy);
|
||||
// }
|
||||
// else {
|
||||
// lineDir = normalize(nextWindow.xy - positionWindow.xy);
|
||||
// }
|
||||
// angle = atan(lineDir.x, lineDir.y) - 1.570796327;
|
||||
// angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
|
||||
// #endif
|
||||
// vec4 clippedPrevWC, clippedPrevEC;
|
||||
// bool prevSegmentClipped, prevSegmentCulled;
|
||||
// clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, clippedPrevWC, prevSegmentClipped, prevSegmentCulled, clippedPrevEC);
|
||||
// vec4 clippedNextWC, clippedNextEC;
|
||||
// bool nextSegmentClipped, nextSegmentCulled;
|
||||
// clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, clippedNextWC, nextSegmentClipped, nextSegmentCulled, clippedNextEC);
|
||||
// bool segmentClipped, segmentCulled;
|
||||
// vec4 clippedPositionWC, clippedPositionEC;
|
||||
// clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);
|
||||
// if (segmentCulled)
|
||||
// {
|
||||
// return vec4(0.0, 0.0, 0.0, 1.0);
|
||||
// }
|
||||
// vec2 directionToPrevWC = normalize(clippedPrevWC.xy - clippedPositionWC.xy);
|
||||
// vec2 directionToNextWC = normalize(clippedNextWC.xy - clippedPositionWC.xy);
|
||||
// if (prevSegmentCulled)
|
||||
// {
|
||||
// directionToPrevWC = -directionToNextWC;
|
||||
// }
|
||||
// else if (nextSegmentCulled)
|
||||
// {
|
||||
// directionToNextWC = -directionToPrevWC;
|
||||
// }
|
||||
// vec2 thisSegmentForwardWC, otherSegmentForwardWC;
|
||||
// if (usePrevious)
|
||||
// {
|
||||
// thisSegmentForwardWC = -directionToPrevWC;
|
||||
// otherSegmentForwardWC = directionToNextWC;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// thisSegmentForwardWC = directionToNextWC;
|
||||
// otherSegmentForwardWC = -directionToPrevWC;
|
||||
// }
|
||||
// vec2 thisSegmentLeftWC = vec2(-thisSegmentForwardWC.y, thisSegmentForwardWC.x);
|
||||
// vec2 leftWC = thisSegmentLeftWC;
|
||||
// float expandWidth = width * 0.5;
|
||||
// if (!czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) && !czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
|
||||
// {
|
||||
// vec2 otherSegmentLeftWC = vec2(-otherSegmentForwardWC.y, otherSegmentForwardWC.x);
|
||||
// vec2 leftSumWC = thisSegmentLeftWC + otherSegmentLeftWC;
|
||||
// float leftSumLength = length(leftSumWC);
|
||||
// leftWC = leftSumLength < czm_epsilon6 ? thisSegmentLeftWC : (leftSumWC / leftSumLength);
|
||||
// vec2 u = -thisSegmentForwardWC;
|
||||
// vec2 v = leftWC;
|
||||
// float sinAngle = abs(u.x * v.y - u.y * v.x);
|
||||
// expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
|
||||
// }
|
||||
// vec2 offset = leftWC * expandDirection * expandWidth * czm_pixelRatio;
|
||||
// return vec4(clippedPositionWC.xy + offset, -clippedPositionWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
|
||||
// }
|
||||
// vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)
|
||||
// {
|
||||
// vec4 positionEC = czm_modelViewRelativeToEye * position;
|
||||
// vec4 prevEC = czm_modelViewRelativeToEye * previous;
|
||||
// vec4 nextEC = czm_modelViewRelativeToEye * next;
|
||||
// return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);
|
||||
// }
|
||||
|
||||
// attribute vec3 position3DHigh;
|
||||
// attribute vec3 position3DLow;
|
||||
// attribute vec3 prevPosition3DHigh;
|
||||
// attribute vec3 prevPosition3DLow;
|
||||
// attribute vec3 nextPosition3DHigh;
|
||||
// attribute vec3 nextPosition3DLow;
|
||||
// attribute vec2 expandAndWidth;
|
||||
// attribute vec2 st;
|
||||
// attribute float batchId;
|
||||
// varying float v_width;
|
||||
// varying vec2 v_st;
|
||||
// varying float v_polylineAngle;
|
||||
// void main()
|
||||
// {
|
||||
// float expandDir = expandAndWidth.x;
|
||||
// float width = abs(expandAndWidth.y) + 0.5;
|
||||
// bool usePrev = expandAndWidth.y < 0.0;
|
||||
// vec4 p = czm_computePosition();
|
||||
// vec4 prev = czm_computePrevPosition();
|
||||
// vec4 next = czm_computeNextPosition();
|
||||
// float angle;
|
||||
// vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);
|
||||
// gl_Position = czm_viewportOrthographic * positionWC;
|
||||
// v_width = width;
|
||||
// v_st.s = st.s;
|
||||
// v_st.t = czm_writeNonPerspective(st.t, gl_Position.w);
|
||||
// v_polylineAngle = angle;
|
||||
// }`,
|
||||
// fragmentShaderSource: `#ifdef VECTOR_TILE
|
||||
// uniform vec4 u_highlightColor;
|
||||
// #endif
|
||||
// varying vec2 v_st;
|
||||
// void main()
|
||||
// {
|
||||
// czm_materialInput materialInput;
|
||||
// vec2 st = v_st;
|
||||
// st.t = czm_readNonPerspective(st.t, gl_FragCoord.w);
|
||||
// materialInput.s = st.s;
|
||||
// materialInput.st = st;
|
||||
// materialInput.str = vec3(st, 0.0);
|
||||
// czm_material material = czm_getMaterial(materialInput);
|
||||
// gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
|
||||
// #ifdef VECTOR_TILE
|
||||
// gl_FragColor *= u_highlightColor;
|
||||
// #endif
|
||||
// czm_writeLogDepth();
|
||||
// }`
|
||||
// }),
|
||||
// }));
|
||||
// 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
|
||||
34
src/Obj/Base/RoutePlanning/_element.js
Normal file
34
src/Obj/Base/RoutePlanning/_element.js
Normal file
@ -0,0 +1,34 @@
|
||||
function html() {
|
||||
return `
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col start-col">
|
||||
<span class="label">起点</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="startLng">
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="startLat">
|
||||
<button @click="pickStartPos" style="margin-left: 10px;">拾取</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="align-items: flex-start;">
|
||||
<div class="col">
|
||||
<span class="label">终点</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="endLng">
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="endLat">
|
||||
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px;">拾取</button>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
function css() {
|
||||
return `
|
||||
.YJ-custom-base-dialog>.content {
|
||||
width: 460px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .row .label {
|
||||
flex: auto;
|
||||
}
|
||||
`
|
||||
}
|
||||
export { html, css }
|
||||
8
src/Obj/Base/RoutePlanning/clear.js
Normal file
8
src/Obj/Base/RoutePlanning/clear.js
Normal file
@ -0,0 +1,8 @@
|
||||
function Clear() {
|
||||
YJ.RoutePlanningArrays.forEach(m => {
|
||||
m.destroy()
|
||||
})
|
||||
YJ.RoutePlanningArrays = []
|
||||
}
|
||||
|
||||
export {Clear}
|
||||
701
src/Obj/Base/RoutePlanning/index.js
Normal file
701
src/Obj/Base/RoutePlanning/index.js
Normal file
@ -0,0 +1,701 @@
|
||||
import { getHost } from '../../../on'
|
||||
import Base from '../index'
|
||||
import Dialog from '../../../BaseDialog'
|
||||
import MouseEvent from '../../../Event/index'
|
||||
import MouseTip from '../../../MouseTip'
|
||||
import { html, css } from './_element'
|
||||
|
||||
class RoutePlanning extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 路径规划
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options)
|
||||
YJ.RoutePlanningArrays.push(this)
|
||||
this.options.width = options.width || 4
|
||||
this.options.color = options.color || '#ff0000'
|
||||
this.options.gps = options.gps || false
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {}
|
||||
this.start = {
|
||||
lng: null,
|
||||
lat: null
|
||||
}
|
||||
this.end = {
|
||||
lng: null,
|
||||
lat: null
|
||||
}
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
this.startEntity = this.sdk.viewer.entities.getOrCreateEntity(
|
||||
'YJ-route-planning-start'
|
||||
)
|
||||
if (
|
||||
this.start &&
|
||||
(this.start.lng || this.start.lng === 0) &&
|
||||
(this.start.lat || this.start.lat === 0)
|
||||
) {
|
||||
this.startEntity.show = true
|
||||
} else {
|
||||
this.startEntity.show = false
|
||||
}
|
||||
|
||||
this.startEntity.position = new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
|
||||
)
|
||||
return pos
|
||||
}, false)
|
||||
this.startEntity.billboard = {
|
||||
image: this.getSourceRootPath() + '/img/start.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
this.endEntity = this.sdk.viewer.entities.getOrCreateEntity(
|
||||
'YJ-route-planning-end'
|
||||
)
|
||||
if (
|
||||
this.end &&
|
||||
(this.end.lng || this.end.lng === 0) &&
|
||||
(this.end.lat || this.end.lat === 0)
|
||||
) {
|
||||
this.endEntity.show = true
|
||||
} else {
|
||||
this.endEntity.show = false
|
||||
}
|
||||
this.endEntity.position = new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
|
||||
)
|
||||
return pos
|
||||
}, false)
|
||||
this.endEntity.billboard = {
|
||||
image: this.getSourceRootPath() + '/img/end.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
this.edit(true)
|
||||
this.clear()
|
||||
}
|
||||
|
||||
get startLng() {
|
||||
return this.start.lng
|
||||
}
|
||||
set startLng(v) {
|
||||
this.start.lng = v
|
||||
if (
|
||||
this.start &&
|
||||
(this.start.lng || this.start.lng === 0) &&
|
||||
(this.start.lat || this.start.lat === 0)
|
||||
) {
|
||||
this.startEntity && (this.startEntity.show = true)
|
||||
} else {
|
||||
this.startEntity && (this.startEntity.show = false)
|
||||
}
|
||||
this._elms.startLng &&
|
||||
this._elms.startLng.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get startLat() {
|
||||
return this.start.lat
|
||||
}
|
||||
set startLat(v) {
|
||||
this.start.lat = v
|
||||
if (
|
||||
this.start &&
|
||||
(this.start.lng || this.start.lng === 0) &&
|
||||
(this.start.lat || this.start.lat === 0)
|
||||
) {
|
||||
this.startEntity && (this.startEntity.show = true)
|
||||
} else {
|
||||
this.startEntity && (this.startEntity.show = false)
|
||||
}
|
||||
this._elms.startLat &&
|
||||
this._elms.startLat.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get endLng() {
|
||||
return this.end.lng
|
||||
}
|
||||
set endLng(v) {
|
||||
this.end.lng = v
|
||||
if (
|
||||
this.end &&
|
||||
(this.end.lng || this.end.lng === 0) &&
|
||||
(this.end.lat || this.end.lat === 0)
|
||||
) {
|
||||
this.endEntity && (this.endEntity.show = true)
|
||||
} else {
|
||||
this.endEntity && (this.endEntity.show = false)
|
||||
}
|
||||
this._elms.endLng &&
|
||||
this._elms.endLng.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get endLat() {
|
||||
return this.end.lat
|
||||
}
|
||||
set endLat(v) {
|
||||
this.end.lat = v
|
||||
if (
|
||||
this.end &&
|
||||
(this.end.lng || this.end.lng === 0) &&
|
||||
(this.end.lat || this.end.lat === 0)
|
||||
) {
|
||||
this.endEntity && (this.endEntity.show = true)
|
||||
} else {
|
||||
this.endEntity && (this.endEntity.show = false)
|
||||
}
|
||||
this._elms.endLat &&
|
||||
this._elms.endLat.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._element_style = null
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._element_style = document.createElement('style')
|
||||
this._element_style.type = 'text/css'
|
||||
this._element_style.setAttribute('data-name', 'YJ_style_dialog')
|
||||
this._element_style.innerHTML = css()
|
||||
this._DialogObject = await new Dialog(this.sdk.viewer._container, {
|
||||
title: '路径规划',
|
||||
closeCallBack: () => {
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
}
|
||||
})
|
||||
await this._DialogObject.init()
|
||||
|
||||
let div = document.createElement('div')
|
||||
div.style.position = 'absolute'
|
||||
div.style.left = '24px'
|
||||
div.style.flet = '0'
|
||||
div.style.display = 'flex'
|
||||
this._DialogObject.footAppChild(div)
|
||||
|
||||
let queryBtn = document.createElement('button')
|
||||
queryBtn.className = 'default'
|
||||
queryBtn.innerHTML =
|
||||
'<svg class="icon-query"><use xlink:href="#yj-icon-query"></use></svg>查询'
|
||||
queryBtn.style.width = 'auto'
|
||||
queryBtn.addEventListener('click', () => {
|
||||
if (
|
||||
(this.startLng || this.startLng === 0) &&
|
||||
(this.startLat || this.startLat === 0) &&
|
||||
(this.endLng || this.endLng === 0) &&
|
||||
(this.endLat || this.endLat === 0)
|
||||
) {
|
||||
!this.startEntity &&
|
||||
(this.startEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/start.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.startEntity.show = true
|
||||
!this.endEntity &&
|
||||
(this.endEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/end.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.endEntity.show = true
|
||||
this.Dialog.queryCallBack &&
|
||||
this.Dialog.queryCallBack({
|
||||
start: [this.startLng, this.startLat],
|
||||
end: [this.endLng, this.endLat]
|
||||
})
|
||||
} else {
|
||||
console.error('请先设置起点和终点坐标!')
|
||||
}
|
||||
})
|
||||
div.appendChild(queryBtn)
|
||||
|
||||
let cleanBtn = document.createElement('button')
|
||||
cleanBtn.className = 'default'
|
||||
cleanBtn.innerHTML =
|
||||
'<svg class="icon-route"><use xlink:href="#yj-icon-route"></use></svg>清除路线'
|
||||
cleanBtn.style.width = 'auto'
|
||||
cleanBtn.style.marginLeft = '10px'
|
||||
cleanBtn.addEventListener('click', () => {
|
||||
this.clear()
|
||||
})
|
||||
div.appendChild(cleanBtn)
|
||||
|
||||
document.getElementsByTagName('head')[0].appendChild(this._element_style)
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
|
||||
if (this.options.gps) {
|
||||
let locateCurrentBtn = document.createElement('button')
|
||||
locateCurrentBtn.innerHTML = '当前位置'
|
||||
locateCurrentBtn.style.marginLeft = '10px'
|
||||
locateCurrentBtn.setAttribute('data-is', 'start')
|
||||
locateCurrentBtn.addEventListener('click', e => {
|
||||
this.getLocateCurrent(e)
|
||||
})
|
||||
let startColElm = contentElm.getElementsByClassName('start-col')[0]
|
||||
startColElm.appendChild(locateCurrentBtn)
|
||||
|
||||
let endPickBtnElm = this._DialogObject._element.body.getElementsByClassName(
|
||||
'end-pick-btn'
|
||||
)[0]
|
||||
endPickBtnElm.style.marginRight = '91px'
|
||||
}
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName('*')
|
||||
RoutePlanning.EventBinding(this, all_elm)
|
||||
} 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (this.startEntity) {
|
||||
this.sdk.viewer.entities.remove(this.startEntity)
|
||||
this.startEntity = null
|
||||
}
|
||||
if (this.endEntity) {
|
||||
this.sdk.viewer.entities.remove(this.endEntity)
|
||||
this.endEntity = null
|
||||
}
|
||||
if (this.entity) {
|
||||
this.sdk.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
}
|
||||
if (this.startExtensionEntity) {
|
||||
this.sdk.viewer.entities.remove(this.startExtensionEntity)
|
||||
this.startExtensionEntity = null
|
||||
}
|
||||
if (this.endExtensionEntity) {
|
||||
this.sdk.viewer.entities.remove(this.endExtensionEntity)
|
||||
this.endExtensionEntity = null
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.clear()
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
|
||||
getLocateCurrent(e) {
|
||||
this.reconnecting && this.reconnecting.close()
|
||||
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)
|
||||
this.reconnecting.onopen = event => {
|
||||
this.reconnecting.onmessage = event => {
|
||||
this.data = JSON.parse(event.data)
|
||||
if (this.data && this.data.rmc) {
|
||||
this.reconnecting.close()
|
||||
if (e.srcElement.getAttribute('data-is') === 'start') {
|
||||
this.startLng = this.data.rmc.lng
|
||||
this.startLat = this.data.rmc.lat
|
||||
!this.startEntity &&
|
||||
(this.startEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(
|
||||
this.startLng,
|
||||
this.startLat
|
||||
)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/start.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.startEntity.show = true
|
||||
} else {
|
||||
this.endLng = this.data.rmc.lng
|
||||
this.endLat = this.data.rmc.lat
|
||||
!this.endEntity &&
|
||||
(this.endEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(
|
||||
this.endLng,
|
||||
this.endLat
|
||||
)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/end.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.endEntity.show = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制路径
|
||||
*/
|
||||
createRoute(positions) {
|
||||
let fromDegreesArray = []
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
}
|
||||
if (
|
||||
(this.startLng || this.startLng === 0) &&
|
||||
(this.startLat || this.startLat === 0) &&
|
||||
(this.startLng !== positions[0].lng || this.startLat !== positions[0].lat)
|
||||
) {
|
||||
this.startExtension = [
|
||||
this.startLng,
|
||||
this.startLat,
|
||||
positions[0].lng,
|
||||
positions[0].lat
|
||||
]
|
||||
if (this.startExtensionEntity) {
|
||||
this.startExtensionEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
|
||||
this.startExtension
|
||||
)
|
||||
} else {
|
||||
this.startExtensionEntity = this.sdk.viewer.entities.add({
|
||||
show: this.options.show,
|
||||
polyline: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(this.startExtension),
|
||||
width: this.options.width,
|
||||
clampToGround: true,
|
||||
material: this.getMaterial(this.options.color, 2),
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (
|
||||
(this.endLng || this.endLng === 0) &&
|
||||
(this.endLat || this.endLat === 0) &&
|
||||
(this.endLng !== positions[positions.length - 1].lng ||
|
||||
this.endLat !== positions[positions.length - 1].lat)
|
||||
) {
|
||||
this.endExtension = [
|
||||
this.endLng,
|
||||
this.endLat,
|
||||
positions[positions.length - 1].lng,
|
||||
positions[positions.length - 1].lat
|
||||
]
|
||||
if (this.endExtensionEntity) {
|
||||
this.endExtensionEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
|
||||
this.endExtension
|
||||
)
|
||||
} else {
|
||||
this.endExtensionEntity = this.sdk.viewer.entities.add({
|
||||
show: this.options.show,
|
||||
polyline: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(this.endExtension),
|
||||
width: this.options.width,
|
||||
clampToGround: true,
|
||||
material: this.getMaterial(this.options.color, 2),
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (this.entity) {
|
||||
this.entity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
|
||||
fromDegreesArray
|
||||
)
|
||||
} else {
|
||||
this.entity = this.sdk.viewer.entities.add({
|
||||
show: this.options.show,
|
||||
polyline: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
width: this.options.width,
|
||||
clampToGround: true,
|
||||
material: this.getMaterial(this.options.color, 0),
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拾取起点
|
||||
*/
|
||||
pickStartPos(e) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
this.tip = new MouseTip('左键选择起点坐标,右键取消', this.sdk)
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
let leftEvent = (movement, cartesian) => {
|
||||
let pos84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.startLng = pos84.lng
|
||||
this.startLat = pos84.lat
|
||||
!this.startEntity &&
|
||||
(this.startEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/start.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.startEntity.show = true
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
}
|
||||
this.event.mouse_left(leftEvent)
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
})
|
||||
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||
let startTime = new Date()
|
||||
let pos = {
|
||||
position: {
|
||||
x: (movement.position1.x + movement.position2.x) / 2,
|
||||
y: (movement.position1.y + movement.position2.y) / 2
|
||||
}
|
||||
}
|
||||
this.event.gesture_pinck_end(() => {
|
||||
let endTime = new Date()
|
||||
if (endTime - startTime >= 500) {
|
||||
// 长按取消
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
} else {
|
||||
leftEvent(pos, cartesian)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拾取终点
|
||||
*/
|
||||
pickEndPos(e) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
this.tip = new MouseTip('左键选择终点坐标,右键取消', this.sdk)
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
let pos84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.endLng = pos84.lng
|
||||
this.endLat = pos84.lat
|
||||
!this.endEntity &&
|
||||
(this.endEntity = this.viewer.entities.add(
|
||||
new Cesium.Entity({
|
||||
position: new Cesium.CallbackProperty(() => {
|
||||
let pos = this.sdk.viewer.scene.clampToHeight(
|
||||
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
|
||||
)
|
||||
return pos
|
||||
}, false),
|
||||
billboard: {
|
||||
image: this.getSourceRootPath() + '/img/end.png',
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
width: 32,
|
||||
height: 32
|
||||
}
|
||||
})
|
||||
))
|
||||
this.endEntity.show = true
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
})
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.tip && this.tip.destroy()
|
||||
this.event && this.event.destroy()
|
||||
})
|
||||
}
|
||||
|
||||
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 RoutePlanning
|
||||
87
src/Obj/Base/SectorObject/_element.js
Normal file
87
src/Obj/Base/SectorObject/_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 }
|
||||
2219
src/Obj/Base/SectorObject/index.js
Normal file
2219
src/Obj/Base/SectorObject/index.js
Normal file
File diff suppressed because it is too large
Load Diff
1280
src/Obj/Base/Shp/index.js
Normal file
1280
src/Obj/Base/Shp/index.js
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user