提交
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import { app, shell, BrowserWindow, ipcMain, globalShortcut } from 'electron'
|
||||
import { app, shell, BrowserWindow, ipcMain, globalShortcut, dialog } from 'electron'
|
||||
import path, { join } from 'path'
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||
import icon from '../../resources/earth.png?asset'
|
||||
import fs from 'fs'
|
||||
import { exec } from 'child_process'
|
||||
|
||||
const { exec } = require('child_process');
|
||||
|
||||
// 开发环境路径处理 - 确保添加正确的file协议
|
||||
const devSplashPath = path.resolve(
|
||||
@ -53,6 +53,11 @@ if (prodSplashPath) {
|
||||
|
||||
// 最终的启动页URL
|
||||
const splashURL = process.env.NODE_ENV === 'development' ? devSplashURL : prodSplashURL
|
||||
let startBatPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'start.bat')
|
||||
startBatPath = process.platform === 'win32' ? startBatPath.replace(/^(\w:)/, '/$1') : startBatPath
|
||||
let stopBatPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'stop.bat')
|
||||
stopBatPath = process.platform === 'win32' ? stopBatPath.replace(/^(\w:)/, '/$1') : stopBatPath
|
||||
|
||||
// const splashURL =
|
||||
// process.env.NODE_ENV === 'development'
|
||||
// ? `${join(app.getAppPath(), 'src/renderer/public/startUp/startUp.html')}`
|
||||
@ -126,6 +131,23 @@ function createWindow(): void {
|
||||
}, 200)
|
||||
})
|
||||
})
|
||||
ipcMain.on("open-directory-dialog", (event, option) => {
|
||||
// @ts-ignore
|
||||
dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
||||
properties: option.properties,
|
||||
filters: option.filters,
|
||||
})
|
||||
.then((files) => {
|
||||
let arr = [];
|
||||
if (!files.canceled) {
|
||||
files.filePaths.forEach((url) => {
|
||||
// @ts-ignore
|
||||
arr.push(url.replace(/\\/g, "/"));
|
||||
});
|
||||
}
|
||||
event.sender.send("selectedItem", arr);
|
||||
});
|
||||
});
|
||||
// 设置窗口标题和图标
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url)
|
||||
@ -156,6 +178,26 @@ function createWindow(): void {
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
// alert(devSplashURL)
|
||||
// alert(prodSplashURL)
|
||||
// dialog.showMessageBox({
|
||||
// type: 'info',
|
||||
// title: '信息1',
|
||||
// message: devSplashURL,
|
||||
// buttons: ['确定']
|
||||
// })
|
||||
// 执行批处理文件
|
||||
exec(startBatPath.substring(1, 200), (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`执行错误: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
console.error(`错误输出: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
console.log(`批处理输出: ${stdout}`);
|
||||
});
|
||||
// Set app user model id for windows
|
||||
electronApp.setAppUserModelId('com.electron')
|
||||
|
||||
@ -189,6 +231,18 @@ app.on('window-all-closed', () => {
|
||||
// 退出时注销所有快捷键
|
||||
app.on('will-quit', () => {
|
||||
globalShortcut.unregisterAll()
|
||||
// 关闭后台服务
|
||||
exec(stopBatPath.substring(1, 200), (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`执行错误: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
console.error(`错误输出: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
console.log(`批处理输出: ${stdout}`);
|
||||
});
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="/tree/jquery-1.4.4.min.js"></script>
|
||||
<script src="/exif/exif.min.js"></script>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<script src="/sdk/YJEarth.min.js"></script>
|
||||
</body>
|
||||
|
||||
8
src/renderer/public/exif/exif.min.js
vendored
Normal file
8
src/renderer/public/exif/exif.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
src/renderer/public/tank.glb
Normal file
BIN
src/renderer/public/tank.glb
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
import request from '@/axios/request'
|
||||
|
||||
export const GisApi = {
|
||||
// 查询活动分页
|
||||
//文件上传
|
||||
linkFile: async (data: any) => {
|
||||
return await request.post({
|
||||
url: `/fileInfo/upload`,
|
||||
|
||||
@ -7,6 +7,13 @@ export const TreeApi = {
|
||||
url: `/source/list`
|
||||
})
|
||||
},
|
||||
// 新增资源 /source/addModelSource
|
||||
addModelSource: async (data: any) => {
|
||||
return await request.post({
|
||||
url: `/source/addModelSource`,
|
||||
data
|
||||
})
|
||||
},
|
||||
// 新增其他资源 /source/addOtherSource
|
||||
addOtherSource: async (data: any) => {
|
||||
return await request.post({
|
||||
@ -25,11 +32,6 @@ export const TreeApi = {
|
||||
return await request.post({
|
||||
url: `/source/addDirectory`,
|
||||
data
|
||||
}).then((res) => {
|
||||
ElMessage({
|
||||
message: '添加成功',
|
||||
type: 'success'
|
||||
})
|
||||
});
|
||||
},
|
||||
// 更新节点信息
|
||||
@ -47,7 +49,7 @@ export const TreeApi = {
|
||||
//删除节点
|
||||
removeDirectory: async (data: any) => {
|
||||
return await request.post({
|
||||
url: `/yjearth4/api/v1/source/del`,
|
||||
url: `/source/delete`,
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
@ -10,14 +10,15 @@ import type {
|
||||
const pendingRequests = new Map<string, AbortController>()
|
||||
let baseURL: any
|
||||
if (window && window.process && window.process.type === 'renderer') {
|
||||
baseURL = localStorage.getItem('ip') ||'http://192.168.110.25:8848'|| 'http://127.0.0.1:8808'
|
||||
// baseURL = localStorage.getItem('ip') ||'http://192.168.110.25:8848'|| 'http://127.0.0.1:8808'
|
||||
baseURL = 'http://127.0.0.1:8848'
|
||||
} else {
|
||||
baseURL = ''
|
||||
baseURL = 'http://192.168.110.25:8848'
|
||||
}
|
||||
|
||||
// 创建自定义配置的axios实例
|
||||
const service: AxiosInstance = axios.create({
|
||||
baseURL:'http://192.168.110.25:8848',
|
||||
baseURL:baseURL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
47
src/renderer/src/common/addMapSource.ts
Normal file
47
src/renderer/src/common/addMapSource.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import { useTreeNode } from '../views/components/tree/hooks/treeNode'
|
||||
import { initMapData } from './initMapData'
|
||||
export const addMapSource = async ({ type, id, sourceName = '未命名对象', opt = {} }) => {
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
if (!id) {
|
||||
id = new YJ.Tools().randomString()
|
||||
}
|
||||
let options: any = await initMapData(type, opt)
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
delete options.host
|
||||
switch (type) {
|
||||
case 'rendezvous':
|
||||
case 'attackArrow':
|
||||
case 'pincerArrow':
|
||||
delete options.label.ground
|
||||
delete options.label.position
|
||||
break;
|
||||
case 'path':
|
||||
delete options.label.text
|
||||
break;
|
||||
}
|
||||
console.log('options', options)
|
||||
let params: any = {
|
||||
id: id,
|
||||
sourceName: sourceName,
|
||||
sourceType: type,
|
||||
// isShow: 1,
|
||||
parentId: parentId,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
export const initMapData = async (type, data) => {
|
||||
let entityObject
|
||||
let options
|
||||
console.log('data', type, data)
|
||||
switch (type) {
|
||||
case 'groundText':
|
||||
entityObject = new YJ.Obj.GroundText(window.earth, data)
|
||||
@ -52,6 +51,18 @@ export const initMapData = async (type, data) => {
|
||||
data.host = 'http://192.168.110.25:8848'
|
||||
entityObject = new YJ.Obj.Tileset(window.earth, data)
|
||||
break
|
||||
case 'path':
|
||||
entityObject = new YJ.Obj.TrajectoryMotion(window.earth, data)
|
||||
break
|
||||
case 'wallStereoscopic':
|
||||
entityObject = new YJ.Obj.WallStereoscopic(window.earth, data)
|
||||
break
|
||||
case 'diffuseScan':
|
||||
entityObject = new YJ.Obj.CircleDiffuse(window.earth, data)
|
||||
break
|
||||
case 'radarScan':
|
||||
entityObject = new YJ.Obj.RadarScan(window.earth, data)
|
||||
break
|
||||
default:
|
||||
return
|
||||
break
|
||||
@ -10,13 +10,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="boxBody">
|
||||
<el-form
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
ref="ruleForm"
|
||||
label-width="80px"
|
||||
@keyup.enter.native="submitForm(ruleForm)"
|
||||
>
|
||||
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px"
|
||||
@keyup.enter.native="submitForm(ruleForm)">
|
||||
<el-form-item label="名称:" prop="sourceName">
|
||||
<!-- @input="removeSpaces" -->
|
||||
<el-input v-model.trim="form.sourceName" placeholder="图层文件夹"></el-input>
|
||||
@ -70,9 +65,10 @@ const add = throttle(async () => {
|
||||
const res: any = await TreeApi.addDirectory({
|
||||
id: new YJ.Tools().randomString(),
|
||||
sourceName: form.sourceName,
|
||||
parentId
|
||||
parentId: parentId || undefined
|
||||
})
|
||||
if (res.code == 0) {
|
||||
console.log(res)
|
||||
if (res.code == 0 || res.code == 200) {
|
||||
const node = {
|
||||
...res.data
|
||||
}
|
||||
@ -87,7 +83,11 @@ const add = throttle(async () => {
|
||||
tree_index: item.getIndex()
|
||||
}
|
||||
})
|
||||
await updateTree(newNode)
|
||||
ElMessage({
|
||||
message: '添加成功',
|
||||
type: 'success'
|
||||
})
|
||||
cancel()
|
||||
} else {
|
||||
ElMessage({
|
||||
message: '添加失败',
|
||||
@ -227,11 +227,14 @@ const cancel = () => {
|
||||
.el-form-item__label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border: 0.2px solid rgba(0, 255, 255, 0.5);
|
||||
box-shadow: 0 0 0 0.2px rgba(0, 255, 255, 0.5) inset !important; /* 新增此行 */
|
||||
box-shadow: 0 0 0 0.2px rgba(0, 255, 255, 0.5) inset !important;
|
||||
/* 新增此行 */
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
|
||||
@ -16,10 +16,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import { initMapData } from '../tree/initMapData'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
import { addMapSource } from '../../../common/addMapSource'
|
||||
const { t } = useI18n()
|
||||
const eventBus: any = inject('bus')
|
||||
|
||||
@ -70,27 +67,16 @@ const bottomMenuList = ref([
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '点标注'
|
||||
let options: any = await initMapData('point', {
|
||||
id: id,
|
||||
name: name,
|
||||
position: position
|
||||
})
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
delete options.host
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'point',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'point',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
position: position
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -109,26 +95,16 @@ const bottomMenuList = ref([
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '线标注'
|
||||
let options: any = await initMapData('line', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'line',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'line',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -145,26 +121,16 @@ const bottomMenuList = ref([
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '曲线标注'
|
||||
let options: any = await initMapData('curve', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'curve',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'curve',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -186,28 +152,16 @@ const bottomMenuList = ref([
|
||||
let id = new YJ.Tools().randomString()
|
||||
// let id = 'aaa'
|
||||
let name = '面标注'
|
||||
let options: any = await initMapData('panel', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'panel',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'panel',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
console.log(params)
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -221,30 +175,16 @@ const bottomMenuList = ref([
|
||||
Draw.start(async (a, opt) => {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '圆'
|
||||
let options: any = await initMapData('circle', {
|
||||
id: id,
|
||||
name: name,
|
||||
center: opt.center, radius: opt.radius
|
||||
})
|
||||
|
||||
delete options.host
|
||||
|
||||
console.log('options', options)
|
||||
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'circle',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: "circle",
|
||||
// isShow: 1,
|
||||
parentId: (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
|
||||
// eventBus.emit("openDialog", 'circle');
|
||||
// TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
center: opt.center, radius: opt.radius
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -264,31 +204,17 @@ const bottomMenuList = ref([
|
||||
return
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
// let id = 'aaa'
|
||||
let name = '矩形'
|
||||
let options: any = await initMapData('panel', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'rectangle',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'rectangle',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
console.log(params)
|
||||
// eventBus.emit("openDialog", 'panel');
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -308,33 +234,17 @@ const bottomMenuList = ref([
|
||||
return
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
// let id = 'aaa'
|
||||
let name = '集结地'
|
||||
let options: any = await initMapData('rendezvous', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
|
||||
delete options.label.ground
|
||||
delete options.label.position
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'rendezvous',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'rendezvous',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
console.log(params)
|
||||
// eventBus.emit("openDialog", 'panel');
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -354,33 +264,17 @@ const bottomMenuList = ref([
|
||||
return
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
// let id = 'aaa'
|
||||
let name = '箭头'
|
||||
let options: any = await initMapData('attackArrow', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
|
||||
delete options.label.ground
|
||||
delete options.label.position
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'attackArrow',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'attackArrow',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
console.log(params)
|
||||
// eventBus.emit("openDialog", 'panel');
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -401,32 +295,17 @@ const bottomMenuList = ref([
|
||||
return
|
||||
}
|
||||
let id = new YJ.Tools().randomString()
|
||||
// let id = 'aaa'
|
||||
let name = '双箭头'
|
||||
let options: any = await initMapData('pincerArrow', {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
})
|
||||
|
||||
delete options.label.ground
|
||||
delete options.label.position
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
await addMapSource({
|
||||
type: 'pincerArrow',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'pincerArrow',
|
||||
// isShow: 1,
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
// eventBus.emit("openDialog", 'panel');
|
||||
TreeApi.addOtherSource(params)
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -584,4 +463,4 @@ const addMarker = (item: any) => {
|
||||
transform: rotate(270deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@ -3,31 +3,29 @@
|
||||
<div class="leftSideSecondBox">
|
||||
<template v-if="obj">
|
||||
<div class="menuItem" v-for="value in obj.children" @click="handleClick(value)">
|
||||
<img
|
||||
:src="'src/assets/images/second/' + `${value}` + '.png'"
|
||||
style="color: rgb(255, 0, 0)"
|
||||
alt=""
|
||||
/>
|
||||
<img :src="'src/assets/images/second/' + `${value}` + '.png'" style="color: rgb(255, 0, 0)" alt="" />
|
||||
<span :style="{ color: !clickChange[value] ? 'var(--color-text)' : 'rgb(255,0,0)' }">{{
|
||||
t(`${obj.key}.${value}`)
|
||||
}}</span>
|
||||
t(`${obj.key}.${value}`)
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import { initMapData } from '../../../common/initMapData'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import { renderMethods } from '../tree/hooks/renderTreeNode'
|
||||
import { addMapSource } from '../../../common/addMapSource'
|
||||
const { proxy } = getCurrentInstance()
|
||||
const { t } = useI18n()
|
||||
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
|
||||
const obj = ref(null)
|
||||
const obj: any = ref(null)
|
||||
const isclick = ref(false)
|
||||
const eventBus = inject('bus')
|
||||
const eventBus: any = inject('bus')
|
||||
const initList = (value) => {
|
||||
obj.value = value
|
||||
}
|
||||
@ -38,61 +36,104 @@ var clickChange = reactive({
|
||||
videoRecord: false
|
||||
})
|
||||
var graffitiObjArr = reactive([])
|
||||
eventBus.on('graffitiObj', (data) => {
|
||||
eventBus.on('graffitiObj', (data: never) => {
|
||||
graffitiObjArr.push(data)
|
||||
})
|
||||
const methodMap = {
|
||||
// 轨迹运动
|
||||
trajectoryMotion: ()=>{
|
||||
// let draw = new YJ.Draw.DrawPolyline(window.earth)
|
||||
// draw.start((err, positions) => {
|
||||
// if (positions.length > 1) {}
|
||||
// })
|
||||
trajectoryMotion: () => {
|
||||
let draw = new YJ.Draw.DrawPolyline(window.earth)
|
||||
draw.start(async (err, positions) => {
|
||||
if (positions && positions.length > 1) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '轨迹运动'
|
||||
await addMapSource({
|
||||
type: 'path',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
model: {
|
||||
show: true,
|
||||
url: "http://localhost:5173/tank.glb",
|
||||
},
|
||||
line: {
|
||||
show: true,
|
||||
positions: positions,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 电子围墙
|
||||
electronicFence: () => {
|
||||
let draw = new YJ.Draw.DrawPolyline(window.earth)
|
||||
draw.start((err, positions) => {
|
||||
if (positions.length > 1) {
|
||||
let alt = positions[0].alt
|
||||
positions.forEach((item) => {
|
||||
if (item.alt < alt) alt = item.alt
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '电子围墙'
|
||||
addMapSource({
|
||||
type: 'wallStereoscopic',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
positions: positions,
|
||||
}
|
||||
})
|
||||
// let id = new YJ.Tools().randomString()
|
||||
let id = 'aaa'
|
||||
let params = {
|
||||
sourceName: '电子围墙',
|
||||
id,
|
||||
sourceType: 'wallStereoscopic',
|
||||
parentId: findParentId(window.treeObj),
|
||||
params: {
|
||||
id,
|
||||
positions,
|
||||
color: '#fff',
|
||||
cornerType: undefined,
|
||||
extrudedHeight: 2.4,
|
||||
width: 0.24
|
||||
},
|
||||
treeIndex: findTreeIndex(window.treeObj)
|
||||
}
|
||||
// console.log(params);
|
||||
// 渲染电子围墙
|
||||
renderMethods.renderWallStereoscopic(params)
|
||||
// 存入数据库
|
||||
// let res = TreeApi.addOtherSource(params)
|
||||
// console.log('addOtherSource', res)
|
||||
// 上树
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
eventBus.emit("openDialog", 'wallStereoscopic');
|
||||
}
|
||||
})
|
||||
},
|
||||
// 扩散光波
|
||||
radarLightWave: () => {
|
||||
let draw = new YJ.Draw.DrawCircle(window.earth)
|
||||
draw.start((err, params) => {
|
||||
console.log(params)
|
||||
if (params) {
|
||||
draw.start((err, options) => {
|
||||
console.log('options', options)
|
||||
if (options) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '扩散光波'
|
||||
addMapSource({
|
||||
type: 'diffuseScan',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
lng: options.center.lng,
|
||||
lat: options.center.lat,
|
||||
circle: [
|
||||
{
|
||||
radius: options.radius,
|
||||
color: '#ff0000',
|
||||
}
|
||||
],
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
diffusedLightWave: () => {
|
||||
let draw = new YJ.Draw.DrawCircle(window.earth)
|
||||
draw.start((err, options) => {
|
||||
console.log('options', options)
|
||||
if (options) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = '雷达光波'
|
||||
addMapSource({
|
||||
type: 'radarScan',
|
||||
id: id,
|
||||
sourceName: name,
|
||||
opt: {
|
||||
id: id,
|
||||
name: name,
|
||||
lng: options.center.lng,
|
||||
lat: options.center.lat,
|
||||
radius: options.radius
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -190,14 +231,14 @@ const methodMap = {
|
||||
eventBus.emit('routePlanningDialog')
|
||||
},
|
||||
//路径清除
|
||||
clearRoute() {},
|
||||
clearRoute() { },
|
||||
//涂鸦
|
||||
graffiti() {
|
||||
eventBus.emit('graffitiDialog')
|
||||
},
|
||||
//涂鸦清除
|
||||
clearGraffiti() {
|
||||
graffitiObjArr.forEach((item) => {
|
||||
graffitiObjArr.forEach((item: any) => {
|
||||
item.remove()
|
||||
})
|
||||
},
|
||||
@ -230,7 +271,7 @@ const methodMap = {
|
||||
// }
|
||||
},
|
||||
//屏幕截图
|
||||
screenShot() {},
|
||||
screenShot() { },
|
||||
//高清出图
|
||||
highQuality() {
|
||||
// eventBus.emit('screenShotDialog')
|
||||
@ -241,25 +282,25 @@ const methodMap = {
|
||||
clickChange.videoRecord = !clickChange.videoRecord
|
||||
},
|
||||
//压模
|
||||
pressModel() {},
|
||||
pressModel() { },
|
||||
//地形开挖
|
||||
terrainDig() {
|
||||
eventBus.emit('terrainExcavationDialog')
|
||||
},
|
||||
//剖切
|
||||
tilesetClipping() {},
|
||||
tilesetClipping() { },
|
||||
//删除剖切
|
||||
clearTilesetClipping() {},
|
||||
clearTilesetClipping() { },
|
||||
//度分秒
|
||||
projConvert() {},
|
||||
projConvert() { },
|
||||
//投影转换
|
||||
projectionConvert() {},
|
||||
projectionConvert() { },
|
||||
//GDB导入
|
||||
gdbImport() {},
|
||||
gdbImport() { },
|
||||
//圆形统计
|
||||
circleStatistics() {},
|
||||
circleStatistics() { },
|
||||
//多边形统计
|
||||
polygonStatistics() {}
|
||||
polygonStatistics() { }
|
||||
}
|
||||
|
||||
const handleClick = (value = 'projectionDistanceMeasure') => {
|
||||
|
||||
@ -122,6 +122,7 @@
|
||||
<use xlink:href="#yj-icon-py"></use>
|
||||
</svg>平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -318,6 +319,11 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => areaUnit.value,
|
||||
(val) => {
|
||||
@ -329,7 +335,8 @@ watch(
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { initMapData } from '../tree/initMapData'
|
||||
import { initMapData } from '../../../common/initMapData'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
@ -45,20 +45,28 @@ const confirm = () => {
|
||||
})
|
||||
delete options.host
|
||||
delete options.positions
|
||||
console.log('options', options)
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let params = {
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
let params: any = {
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'groundText',
|
||||
parentId:
|
||||
selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
? selectedNodes[selectedNodes.length - 1].id
|
||||
: undefined,
|
||||
parentId: parentId,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
})
|
||||
}
|
||||
|
||||
@ -14,7 +14,10 @@ import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { initMapData } from '../tree/initMapData'
|
||||
import { initMapData } from '../../../common/initMapData'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -42,19 +45,30 @@ const confirm = () => {
|
||||
})
|
||||
delete options.host
|
||||
console.log('options', options)
|
||||
// let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
// let params = {
|
||||
// id: id,
|
||||
// sourceName: name,
|
||||
// sourceType: 'standText',
|
||||
// parentId:
|
||||
// selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
// ? selectedNodes[selectedNodes.length - 1].id
|
||||
// : undefined,
|
||||
// // "treeIndex": 0,
|
||||
// params: options
|
||||
// }
|
||||
// TreeApi.addOtherSource(params)
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
|
||||
let params:any = {
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'standText',
|
||||
parentId: parentId,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
@ -62,4 +76,4 @@ defineExpose({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss"></style>
|
||||
@ -145,6 +145,7 @@
|
||||
<use xlink:href="#yj-icon-py"></use>
|
||||
</svg>平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -360,8 +361,14 @@ watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@ -3,18 +3,8 @@
|
||||
<div class="row">
|
||||
<div class="col attribute-select-box">
|
||||
<span class="label" style="line-height: 32px">内容类型</span>
|
||||
<el-select
|
||||
style="width: 175px"
|
||||
v-model="attributeType"
|
||||
@change="attributeChange"
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in attributeSelect"
|
||||
:key="item.key"
|
||||
:label="item.name"
|
||||
:value="item.key"
|
||||
>
|
||||
<el-select style="width: 175px" v-model="attributeType" @change="attributeChange" placeholder="请选择">
|
||||
<el-option v-for="item in attributeSelect" :key="item.key" :label="item.name" :value="item.key">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
@ -45,7 +35,7 @@
|
||||
<div class="th">操作</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0">
|
||||
<div class="table-body" v-if="attribute.link && attribute.link.content && attribute.link.content.length > 0">
|
||||
<div class="tr" v-for="(item, index) in attribute.link.content">
|
||||
<div class="td" v-if="linkEditActive.index === index">
|
||||
<input class="input" type="text" v-model="linkEditActive.name" />
|
||||
@ -75,7 +65,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">编辑内容</span>
|
||||
<input class="input" type="text" @model="cameraName" style="width: 100px" />
|
||||
<input class="input" type="text" v-model="cameraName" style="width: 100px" />
|
||||
<button class="select btn" @click="cameraSelect">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -157,7 +147,7 @@
|
||||
<div class="col">
|
||||
<span class="label">添加链接</span>
|
||||
<div style="flex: 1; position: relative">
|
||||
<input class="input vr_add" type="text" />
|
||||
<input class="input vr_add" type="text" v-model="addvrInput" />
|
||||
<i class="vr_add_btn" @click="_addRr"></i>
|
||||
</div>
|
||||
</div>
|
||||
@ -171,48 +161,32 @@
|
||||
<div class="th">操作</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body"></div>
|
||||
<div class="table-empty">
|
||||
<div class="table-body" v-if="attribute.vr && attribute.vr.content && attribute.vr.content.length > 0">
|
||||
<div class="tr" v-for="(item, index) in attribute.vr.content">
|
||||
<div class="td" v-if="vrEditActive.index === index">
|
||||
<input class="input" type="text" v-model="vrEditActive.name" />
|
||||
</div>
|
||||
<div class="td" v-else>{{ item.name }}</div>
|
||||
<div class="td" v-if="vrEditActive.index === index">
|
||||
<textarea class="input link-edit" type="text" v-model="vrEditActive.url"></textarea>
|
||||
</div>
|
||||
<div class="td" v-else>{{ item.url }}</div>
|
||||
<div class="td" v-if="vrEditActive.index === index">
|
||||
<button @click="vrConfirmEdit(index)">确认</button>
|
||||
<button @click="vrCancelEdit">取消</button>
|
||||
</div>
|
||||
<div class="td" v-else>
|
||||
<button @click="vrEdit(index, item)">编辑</button>
|
||||
<button @click="vrDelete(index)">删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-empty" v-else>
|
||||
<div class="empty-img"></div>
|
||||
<p>暂无数据</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="attribute-content attribute-content-goods" v-show="attributeType === 'goods'">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">编辑内容</span>
|
||||
<input
|
||||
class="input goods-select-input"
|
||||
type="text"
|
||||
style="width: 180px; margin-right: 10px"
|
||||
/>
|
||||
<button class="select btn" @click="goodsFilter">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table goods-table">
|
||||
<div class="table-head">
|
||||
<div class="tr">
|
||||
<div class="th" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
|
||||
<div class="th" style="flex: 0 0 280px">名称</div>
|
||||
<div class="th">数量</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-body" style="display: none">
|
||||
<div class="tr">
|
||||
<div class="td" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
|
||||
<div class="td" style="flex: 0 0 280px">名称</div>
|
||||
<div class="td">数量</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-empty">
|
||||
<div class="empty-img"></div>
|
||||
<p>暂无数据</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -220,6 +194,11 @@
|
||||
import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
|
||||
let ipcRenderer;
|
||||
if (window && window.process && window.process.type === 'renderer') {
|
||||
ipcRenderer = require('electron').ipcRenderer
|
||||
}
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const attributeType = ref('richText')
|
||||
@ -232,9 +211,10 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const attribute = ref(props.entityOptions.options.attribute)
|
||||
props.entityOptions.options.richTextContent = ''
|
||||
const richTextContent = ref(props.entityOptions.options.richTextContent)
|
||||
|
||||
const attributeSelect = ref([
|
||||
let attributeSelect = ref([
|
||||
{
|
||||
name: '富文本',
|
||||
value: '富文本',
|
||||
@ -245,43 +225,53 @@ const attributeSelect = ref([
|
||||
value: '链接',
|
||||
key: 'link'
|
||||
}
|
||||
// {
|
||||
// name: 'IP摄像头',
|
||||
// value: 'IP摄像头',
|
||||
// key: 'camera'
|
||||
// },
|
||||
// {
|
||||
// name: 'ISC摄像头',
|
||||
// value: 'ISC摄像头',
|
||||
// key: 'isc'
|
||||
// },
|
||||
// {
|
||||
// name: '传感器',
|
||||
// value: '传感器',
|
||||
// key: 'sensor'
|
||||
// },
|
||||
// {
|
||||
// name: '全景图',
|
||||
// value: '全景图',
|
||||
// key: 'vr'
|
||||
// },
|
||||
// {
|
||||
// name: '物资',
|
||||
// value: '物资',
|
||||
// key: 'goods'
|
||||
// },
|
||||
])
|
||||
|
||||
if (props.entityOptions.type === 'BillboardObject') {
|
||||
attributeSelect.value.push(
|
||||
// {
|
||||
// name: 'IP摄像头',
|
||||
// value: 'IP摄像头',
|
||||
// key: 'camera'
|
||||
// },
|
||||
// {
|
||||
// name: 'ISC摄像头',
|
||||
// value: 'ISC摄像头',
|
||||
// key: 'isc'
|
||||
// },
|
||||
// {
|
||||
// name: '传感器',
|
||||
// value: '传感器',
|
||||
// key: 'sensor'
|
||||
// },
|
||||
{
|
||||
name: '全景图',
|
||||
value: '全景图',
|
||||
key: 'vr'
|
||||
},
|
||||
// {
|
||||
// name: '物资',
|
||||
// value: '物资',
|
||||
// key: 'goods'
|
||||
// },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const cameraName = ref('')
|
||||
const addlinkInput = ref('')
|
||||
const addvrInput = ref('')
|
||||
const linkEditActive: any = ref({})
|
||||
const vrEditActive: any = ref({})
|
||||
|
||||
const openRichTextEditor = () => {
|
||||
eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => {
|
||||
eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val: any) => {
|
||||
richTextContent.value = val
|
||||
props.entityOptions.options.richTextContent = richTextContent.value
|
||||
})
|
||||
}
|
||||
const _addLink = () => {
|
||||
const _addLink = async () => {
|
||||
if (addlinkInput.value) {
|
||||
let link = {
|
||||
name: '链接',
|
||||
@ -290,18 +280,77 @@ const _addLink = () => {
|
||||
attribute.value.link.content.push(link)
|
||||
addlinkInput.value = ''
|
||||
} else {
|
||||
document.getElementById('fileInputlink')?.click()
|
||||
eventBus.emit('defineClickAddLinkCb', (list) => {
|
||||
list.forEach((item) => {
|
||||
attribute.value.link.content.push({
|
||||
name: '链接',
|
||||
url: item.previewUrl
|
||||
})
|
||||
})
|
||||
})
|
||||
const options = {
|
||||
properties: ['openFile', 'multiSelections'], // 允许选择多个文件
|
||||
filters: [
|
||||
{ name: '图片', extensions: ['jpg', 'jpeg', 'png', 'webp', 'svg', 'bmp'] },
|
||||
{ name: '音视频', extensions: ['mp4', 'mp3'] },
|
||||
{ name: 'pdf', extensions: ['pdf'] },
|
||||
]
|
||||
};
|
||||
if (ipcRenderer) {
|
||||
ipcRenderer.send('open-directory-dialog', options);
|
||||
// 监听主进程返回的结果
|
||||
ipcRenderer.once('selectedItem', (event, filePaths) => {
|
||||
if (filePaths.length > 0) {
|
||||
filePaths.forEach((item) => {
|
||||
attribute.value.link.content.push({
|
||||
name: '链接',
|
||||
url: item
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// const pickerOpts = {
|
||||
// types: [
|
||||
// {
|
||||
// description: '图片',
|
||||
// accept:
|
||||
// {
|
||||
// 'image/jpg': ['.jpg', '.jpeg'],
|
||||
// 'image/gif': ['.gif'],
|
||||
// 'image/webp': ['.webp'],
|
||||
// 'image/png': ['.png'],
|
||||
// 'image/svg+xml': ['.svg'],
|
||||
// 'image/x-ms-bmp': ['.bmp'],
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// description: '音视频',
|
||||
// accept:
|
||||
// {
|
||||
// 'video/mp4': ['.mp4'],
|
||||
// 'audio/mpeg': ['.mp3'],
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// description: 'pdf',
|
||||
// accept:
|
||||
// {
|
||||
// 'application/pdf': ['.pdf'],
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// excludeAcceptAllOption: true,
|
||||
// multiple: true
|
||||
// };
|
||||
// if ((window as any).showOpenFilePicker) {
|
||||
// const fileHandles = await (window as any).showOpenFilePicker(pickerOpts);
|
||||
// // const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
// // const dataTransfer = new DataTransfer();
|
||||
// // handleFileImgInput(files, parentId, 'vr')
|
||||
// }
|
||||
}
|
||||
|
||||
// $sendElectronChanel('open-directory-dialog', (a: any,b: any)=>{
|
||||
// console.log(a,b)
|
||||
// })
|
||||
|
||||
}
|
||||
}
|
||||
const linkEdit = (index, item) => {
|
||||
const linkEdit = (index: any, item: { name: any; url: any; }) => {
|
||||
let active = {
|
||||
index: index,
|
||||
name: item.name,
|
||||
@ -309,20 +358,76 @@ const linkEdit = (index, item) => {
|
||||
}
|
||||
linkEditActive.value = active
|
||||
}
|
||||
const linkDelete = (index) => {
|
||||
const linkDelete = (index: any) => {
|
||||
attribute.value.link.content.splice(index, 1)
|
||||
}
|
||||
const linkConfirmEdit = (index) => {
|
||||
const linkConfirmEdit = (index: string | number) => {
|
||||
attribute.value.link.content[index] = linkEditActive.value
|
||||
linkEditActive.value = {}
|
||||
}
|
||||
const linkCancelEdit = () => {
|
||||
linkEditActive.value = {}
|
||||
}
|
||||
const cameraSelect = () => {}
|
||||
const _addRr = () => {}
|
||||
const goodsFilter = () => {}
|
||||
const attributeChange = () => {}
|
||||
const cameraSelect = () => { }
|
||||
const _addRr = () => {
|
||||
if (addvrInput.value) {
|
||||
let link = {
|
||||
name: '全景图',
|
||||
url: addvrInput.value
|
||||
}
|
||||
attribute.value.vr.content.push(link)
|
||||
addvrInput.value = ''
|
||||
} else {
|
||||
const options = {
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: [
|
||||
{ name: '全景图', extensions: ['jpg'] },
|
||||
]
|
||||
};
|
||||
ipcRenderer.send('open-directory-dialog', options);
|
||||
// 监听主进程返回的结果
|
||||
ipcRenderer.once('selectedItem', (event, filePaths) => {
|
||||
if (filePaths.length > 0) {
|
||||
filePaths.forEach((item) => {
|
||||
attribute.value.link.content.push({
|
||||
name: '全景图',
|
||||
url: item
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
// document.getElementById('fileInputlink')?.click()
|
||||
// eventBus.emit('defineClickAddLinkCb', (list: any[]) => {
|
||||
// list.forEach((item: { previewUrl: any; }) => {
|
||||
// attribute.value.vr.content.push({
|
||||
// name: '全景图',
|
||||
// url: item.previewUrl
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
const vrEdit = (index: any, item: { name: any; url: any; }) => {
|
||||
let active = {
|
||||
index: index,
|
||||
name: item.name,
|
||||
url: item.url
|
||||
}
|
||||
vrEditActive.value = active
|
||||
}
|
||||
const vrDelete = (index: any) => {
|
||||
attribute.value.vr.content.splice(index, 1)
|
||||
}
|
||||
const vrConfirmEdit = (index: string | number) => {
|
||||
attribute.value.vr.content[index] = vrEditActive.value
|
||||
vrEditActive.value = {}
|
||||
}
|
||||
const vrCancelEdit = () => {
|
||||
vrEditActive.value = {}
|
||||
}
|
||||
const goodsFilter = () => { }
|
||||
const attributeChange = () => { }
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@ -445,11 +445,11 @@
|
||||
<div style="position: absolute; left: 24px; display: flex">
|
||||
<button @click="updateHeight">
|
||||
<svg class="icon-updateheigh">
|
||||
<use xlink:href="#yj-icon-updateheight"></use></svg
|
||||
>更新高程
|
||||
<use xlink:href="#yj-icon-updateheight"></use></svg>更新高程
|
||||
</button>
|
||||
<button style="margin-left: 10px" @click="translate">平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -770,8 +770,14 @@ const fontChange = (val) => {
|
||||
entityOptions.value.labelFontFamily = val
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
298
src/renderer/src/views/components/propertyBox/circleDiffuse.vue
Normal file
298
src/renderer/src/views/components/propertyBox/circleDiffuse.vue
Normal file
@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="扩散光波属性" left="180px" top="100px" className="circle-ciffuse"
|
||||
:closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<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" v-model="entityOptions.name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">透明度</span>
|
||||
<input type="range" min="0" max="1" step="0.01" v-model="entityOptions.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" v-model="entityOptions.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" v-model="entityOptions.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" v-model="entityOptions.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" v-model="entityOptions.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>
|
||||
<el-select v-model="radiusUnit" @change="changeRadiusUnit">
|
||||
<el-option label="米" value="m"></el-option>
|
||||
<el-option label="千米" value="km"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;">
|
||||
</div>
|
||||
<div class="col" style="margin: 0;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row circle-content-box">
|
||||
<div class="row" v-for="(item, index) in circle" :key="index">
|
||||
<div class="col">
|
||||
<span class="label">半径</span>
|
||||
<input class="input" type="number" title="" min="0" max="999999" v-model="item.radius"
|
||||
@input="changeRadius(index)">
|
||||
</div>
|
||||
<div class="col" style="flex-direction: row-reverse;">
|
||||
<div class="color" :ref="el => colorRefs[index] = el"></div>
|
||||
<span class="label">扩散颜色</span>
|
||||
</div>
|
||||
<div class="col" style="flex-direction: row-reverse;">
|
||||
<button class="circle-add" style="margin-left: 5px;" @click="addCircle"
|
||||
v-show="index == circle.length - 1"><svg class="icon-add2">
|
||||
<use xlink:href="#yj-icon-add2"></use>
|
||||
</svg></button>
|
||||
<button class="circle-minus" @click="minusCircle(index)" v-show="circle.length != 1">
|
||||
<svg class="icon-minus">
|
||||
<use xlink:href="#yj-icon-minus"></use>
|
||||
</svg></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="属性信息" name="1">
|
||||
<attribute :entityOptions="entityOptions"></attribute>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="标签风格" name="2">
|
||||
<labelStyle :entityOptions="entityOptions"></labelStyle>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="position: absolute; left: 24px; display: flex;">
|
||||
<button style="margin-left: 10px" @click="translate">平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { inject } from "vue";
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import attribute from './attribute.vue'
|
||||
import labelStyle from './labelStyle.vue'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
|
||||
eventBus.on("openStandTextAdd", () => {
|
||||
baseDialog.value?.open()
|
||||
});
|
||||
const radiusUnit = ref('m')
|
||||
const activeName = ref('1')
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const circle:any = ref([])
|
||||
const colorRefs = ref<(Element | ComponentPublicInstance | null)[]>([])
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
circle.value = structuredClone(that.options.circle)
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
for (let i = 0; i < colorRefs.value.length; i++) {
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRefs.value[i],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.options.circle[i].color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.options.circle[i].color = color
|
||||
circle.value[i].color = color
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.options.circle[i].color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const addCircle = async () => {
|
||||
circle.value.push({
|
||||
radius: 0,
|
||||
color: entityOptions.value.options.color
|
||||
})
|
||||
entityOptions.value.options.circle.push({
|
||||
radius: 0,
|
||||
color: entityOptions.value.options.color
|
||||
})
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
await nextTick()
|
||||
for (let i = 0; i < colorRefs.value.length; i++) {
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRefs.value[i],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.options.circle[i].color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.options.circle[i].color = color
|
||||
circle.value[i].color = color
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.options.circle[i].color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
}
|
||||
const minusCircle = async (index) => {
|
||||
circle.value.splice(index, 1)
|
||||
entityOptions.value.options.circle.splice(index, 1)
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
await nextTick()
|
||||
for (let i = 0; i < colorRefs.value.length; i++) {
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRefs.value[i],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.options.circle[i].color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.options.circle[i].color = color
|
||||
circle.value[i].color = color
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.options.circle[i].color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
}
|
||||
const changeRadius = async (index) => {
|
||||
let newCircle = JSON.parse(JSON.stringify(circle.value))
|
||||
if (radiusUnit.value == 'km') {
|
||||
for (let i = 0; i < newCircle.length; i++) {
|
||||
newCircle[i].radius = newCircle[i].radius * 1000
|
||||
}
|
||||
}
|
||||
entityOptions.value.circle = newCircle
|
||||
await nextTick()
|
||||
for (let i = 0; i < colorRefs.value.length; i++) {
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRefs.value[i],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.options.circle[i].color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.options.circle[i].color = color
|
||||
circle.value[i].color = color
|
||||
entityOptions.value.circle = entityOptions.value.options.circle
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.options.circle[i].color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
}
|
||||
const changeRadiusUnit = () => {
|
||||
if (radiusUnit.value == 'm') {
|
||||
for (let i = 0; i < circle.value.length; i++) {
|
||||
circle.value[i].radius = circle.value[i].radius * 1000
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < circle.value.length; i++) {
|
||||
circle.value[i].radius = circle.value[i].radius / 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
console.log('params', params)
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.remove()
|
||||
close()
|
||||
}
|
||||
const translate = () => {
|
||||
that.openPositionEditing(() => {
|
||||
entityOptions.value.lng = that.lng
|
||||
entityOptions.value.lat = that.lat
|
||||
})
|
||||
}
|
||||
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
that.reset()
|
||||
eventBus?.emit("destroyComponent")
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -272,11 +272,11 @@
|
||||
<div style="position: absolute; left: 24px; display: flex">
|
||||
<button @click="nodeEdit">
|
||||
<svg class="icon-edit">
|
||||
<use xlink:href="#yj-icon-edit"></use></svg
|
||||
>二次编辑
|
||||
<use xlink:href="#yj-icon-edit"></use></svg>二次编辑
|
||||
</button>
|
||||
<button style="margin-left: 10px" @click="translate">平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -288,7 +288,6 @@ import { ref, getCurrentInstance } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { initMapData } from '../tree/initMapData'
|
||||
import { getFontList } from './fontSelect'
|
||||
import attribute from './attribute.vue'
|
||||
import labelStyle from './labelStyle.vue'
|
||||
@ -546,6 +545,11 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => lengthUnit.value,
|
||||
(val) => {
|
||||
@ -560,7 +564,8 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -588,4 +593,4 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@ -87,7 +87,6 @@ import { ref } from 'vue';
|
||||
import { inject } from "vue";
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { initMapData } from '../tree/initMapData'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
@ -158,7 +157,8 @@ const closeCallback = () => {
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
96
src/renderer/src/views/components/propertyBox/layer.vue
Normal file
96
src/renderer/src/views/components/propertyBox/layer.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="底图属性" left="calc(50% - 160px)" top="calc(50% - 120px)" :closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" v-model="entityOptions.name">
|
||||
</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" min="0" max="1" step="0.01" v-model="entityOptions.alpha">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const text = ref('')
|
||||
eventBus.on('openStandTextAdd', () => {
|
||||
baseDialog.value?.open()
|
||||
})
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
entityOptions.value.reset()
|
||||
eventBus.emit("destroyComponent")
|
||||
}
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = {
|
||||
alpha: entityOptions.value.alpha,
|
||||
brightness: entityOptions.value.brightness,
|
||||
name: entityOptions.value.name,
|
||||
show: entityOptions.value.show,
|
||||
id: entityOptions.value.id,
|
||||
}
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -122,6 +122,7 @@
|
||||
<use xlink:href="#yj-icon-py"></use>
|
||||
</svg>平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -325,6 +326,11 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => areaUnit.value,
|
||||
(val) => {
|
||||
@ -336,7 +342,8 @@ watch(
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@ -277,15 +277,14 @@
|
||||
<div style="position: absolute; left: 24px; display: flex">
|
||||
<button @click="nodeEdit">
|
||||
<svg class="icon-edit">
|
||||
<use xlink:href="#yj-icon-edit"></use></svg
|
||||
>二次编辑
|
||||
<use xlink:href="#yj-icon-edit"></use></svg>二次编辑
|
||||
</button>
|
||||
<button style="margin-left: 10px" @click="translate">
|
||||
<svg class="icon-py">
|
||||
<use xlink:href="#yj-icon-py"></use></svg
|
||||
>平移
|
||||
<use xlink:href="#yj-icon-py"></use></svg>平移
|
||||
</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
@ -553,6 +552,11 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => lengthUnit.value,
|
||||
(val) => {
|
||||
@ -567,7 +571,8 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
179
src/renderer/src/views/components/propertyBox/radarScan.vue
Normal file
179
src/renderer/src/views/components/propertyBox/radarScan.vue
Normal file
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="雷达光波属性" left="180px" top="100px" className="circle-ciffuse"
|
||||
:closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<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" v-model="entityOptions.name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描颜色</span>
|
||||
<div class="color" ref="colorRef"></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" v-model="entityOptions.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" v-model="radius" @input="changeRadius">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
<el-select v-model="radiusUnit" @change="changeRadiusUnit">
|
||||
<el-option label="米" value="m"></el-option>
|
||||
<el-option label="千米" value="km"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">扫描速度</span>
|
||||
<input class="input" type="number" title="" min="0" max="100" v-model="entityOptions.speed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="属性信息" name="1">
|
||||
<attribute :entityOptions="entityOptions"></attribute>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="标签风格" name="2">
|
||||
<labelStyle :entityOptions="entityOptions"></labelStyle>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="position: absolute; left: 24px; display: flex;">
|
||||
<button style="margin-left: 10px" @click="translate">平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { inject } from "vue";
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import attribute from './attribute.vue'
|
||||
import labelStyle from './labelStyle.vue'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
|
||||
eventBus.on("openStandTextAdd", () => {
|
||||
baseDialog.value?.open()
|
||||
});
|
||||
const radiusUnit = ref('m')
|
||||
const activeName = ref('1')
|
||||
const radius = ref(0)
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const colorRef = ref(null)
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
radius.value = entityOptions.value.radius
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRef.value,
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.color = color
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
console.log('params', params)
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.remove()
|
||||
close()
|
||||
}
|
||||
const changeRadius = (val)=>{
|
||||
if (radiusUnit.value == 'km') {
|
||||
entityOptions.value.radius = radius.value * 1000
|
||||
}
|
||||
else {
|
||||
entityOptions.value.radius = radius.value
|
||||
}
|
||||
}
|
||||
const changeRadiusUnit = () => {
|
||||
if (radiusUnit.value == 'm') {
|
||||
radius.value = radius.value * 1000
|
||||
}
|
||||
else {
|
||||
radius.value = radius.value / 1000
|
||||
}
|
||||
}
|
||||
const translate = () => {
|
||||
that.openPositionEditing(() => {
|
||||
entityOptions.value.lng = that.lng
|
||||
entityOptions.value.lat = that.lat
|
||||
})
|
||||
}
|
||||
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
that.reset()
|
||||
eventBus?.emit("destroyComponent")
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="立体t文字属性" left="180px" top="100px" className="ground-text"
|
||||
<Dialog ref="baseDialog" title="立体文字属性" left="180px" top="100px" className="ground-text"
|
||||
:closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<span class="custom-divider"></span>
|
||||
@ -61,7 +61,6 @@ let originalOptions: any
|
||||
let that: any
|
||||
const colorRef = ref(null)
|
||||
const open = async (id: any) => {
|
||||
id = (window as any).standTextid
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
@ -91,12 +90,12 @@ const confirm = () => {
|
||||
delete params.name
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"sourceName": params.text,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.text, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
@ -117,7 +116,8 @@ const closeCallback = () => {
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
108
src/renderer/src/views/components/propertyBox/tileset.vue
Normal file
108
src/renderer/src/views/components/propertyBox/tileset.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="倾斜摄影属性" left="calc(50% - 160px)" top="calc(50% - 120px)" :closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" v-model="entityOptions.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="" v-model="entityOptions.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" v-model="entityOptions.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" v-model="entityOptions.transparency">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const text = ref('')
|
||||
eventBus.on('openStandTextAdd', () => {
|
||||
baseDialog.value?.open()
|
||||
})
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
entityOptions.value.reset()
|
||||
eventBus.emit("destroyComponent")
|
||||
}
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.text,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="轨迹运动属性" left="calc(50% - 160px)" top="calc(50% - 120px)" className="trajectory-motion"
|
||||
:closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 70px;">名称</span>
|
||||
<input class="input" maxlength="40" type="text" v-model="entityOptions.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" style="flex: 0 0 70px;">起始点高度</span>
|
||||
<div class="input-number input-number-unit-1 height-box">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" v-model="entityOptions.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-2">
|
||||
<input class="input" type="number" title="" min="0" max="99999" step="1" v-model="entityOptions.scale">
|
||||
<span class="unit">倍</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 70px;">运行速度</span>
|
||||
<div class="input-number input-number-unit-3">
|
||||
<input class="input" type="number" title="" min="0" max="99999999" step="1" v-model="entityOptions.speed">
|
||||
<span class="unit">m/s</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" max="9999999" v-model="entityOptions.delay">
|
||||
<span class="unit">ms</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 70px;">更换模型</span>
|
||||
<button class="btn" @click="clickChangeModel">选择</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">模型方向</span>
|
||||
<button class="btn model-rotate-btn" @click="modelRotate">开始调整</button>
|
||||
<svg class="icon-rubric" @mouseover="handleMouseOver" @mouseout="handleMouseOut">
|
||||
<use xlink:href="#yj-icon-rubric"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="btn-group">
|
||||
<button class="btn" :class="{ 'is-active': entityOptions.firstPersonView }"
|
||||
style="border-radius: 5px 0 0 5px;" name="firstPerson" data-state="true"
|
||||
@click="changeFirstPersonView(true)"><span>第一视角</span></button>
|
||||
<button class="btn" :class="{ 'is-active': !entityOptions.firstPersonView }"
|
||||
style="border-radius: 0 5px 5px 0;" name="firstPerson" data-state="false"
|
||||
@click="changeFirstPersonView(false)"><span>第三视角</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item div-item-switch">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">路径显隐</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.lineShow">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">模型显隐</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.modelShow">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">实时路径</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.realTimeRoute">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">编辑</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.lineEdit">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">路径圆滑</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.smooth">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">环线</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">轨迹贴地</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.ground">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">轨迹循环</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.loop">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">轨迹动画</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.state">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">路径方向</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.routeDirection">
|
||||
</div>
|
||||
<div class="col" style="margin-right: 33px;">
|
||||
<span class="label">视角跟随</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.viewFollow">
|
||||
</div>
|
||||
<div class="col" style="margin: 0px;">
|
||||
<span class="label">模型动画</span>
|
||||
<div class="input input-select model-animate-select"></div>
|
||||
<el-select class="model-animate-select" v-model="entityOptions.modelAnimate" v-if="entityOptions.model && entityOptions.model.loader && entityOptions.model.loader.components && entityOptions.model.loader.components.animations">
|
||||
<el-option label="无"></el-option>
|
||||
<el-option v-for="item in entityOptions.model.loader.components.animations" :label="item.name"
|
||||
:value="item.name"></el-option>
|
||||
</el-select>
|
||||
<el-select class="model-animate-select" v-model="entityOptions.modelAnimate" v-else>
|
||||
<el-option label="无"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">文字开关</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow">
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 0 0 120px;">
|
||||
<span class="label">字体颜色</span>
|
||||
<div class="labelColor" ref="labelColorRef"></div>
|
||||
</div>
|
||||
<div class="col font-select-box">
|
||||
<span class="label" style="flex: none;">字体选择</span>
|
||||
<el-select class="input input-select font-select" v-model="entityOptions.labelFontFamily">
|
||||
<el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">字体大小</span>
|
||||
<div class="input-number input-number-unit-2" style="width: 82px;">
|
||||
<input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize">
|
||||
<span class="unit">px</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 0 0 120px;">
|
||||
<span class="label">视野缩放</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">最近距离</span>
|
||||
<div class="input-number input-number-unit-1" style="width: 82px;">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelNear">
|
||||
<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" style="width: 82px;">
|
||||
<input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelFar">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="custom-rubric-box" v-show="tip"
|
||||
style="transform-origin: center bottom; position: absolute; top: 180px; right: 3px; padding: 5px 10px; background-color: rgb(62, 66, 73); border-radius: 5px; font-size: 12px; color: rgb(255, 87, 51);pointer-events: none;">
|
||||
场景正东方向为轨迹前进正方向<div x-arrow="" class="custom__popper__arrow" style="left: 59px;"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { inject } from 'vue'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
import { getFontList } from './fontSelect'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const text = ref('')
|
||||
const fontList = ref(getFontList())
|
||||
const labelColorRef = ref(null)
|
||||
const tip = ref(false)
|
||||
eventBus.on('openStandTextAdd', () => {
|
||||
baseDialog.value?.open()
|
||||
})
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
entityOptions.value.reset()
|
||||
eventBus.emit("destroyComponent")
|
||||
}
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
let labelColorPicker = new (window as any).YJColorPicker({
|
||||
el: labelColorRef.value,
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.labelColor,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
entityOptions.value.labelColor = color
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.labelColor = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
delete params.label.text
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0
|
||||
}
|
||||
console.log(params)
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
that.remove()
|
||||
close()
|
||||
}
|
||||
const clickChangeModel = () => { }
|
||||
const modelRotate = () => {
|
||||
that.modelRotate()
|
||||
}
|
||||
const changeFirstPersonView = (state) => {
|
||||
entityOptions.value.firstPersonView = state
|
||||
}
|
||||
const handleMouseOver = () => {
|
||||
tip.value = true
|
||||
}
|
||||
const handleMouseOut = () => {
|
||||
tip.value = false
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="电子围墙属性" left="180px" top="100px" className="wall-stereoscopic"
|
||||
:closeCallback="closeCallback">
|
||||
<template #content>
|
||||
<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" v-model="entityOptions.name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color" ref="colorRef"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">拉伸高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="0" max="999999999"
|
||||
v-model="entityOptions.extrudedHeight">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col material-box">
|
||||
<span class="label">材质样式</span>
|
||||
<el-select class="input input-select input-select-line-type" style="margin-left: 20px"
|
||||
v-model="entityOptions.material">
|
||||
<el-option v-for="item in material" :key="item.key" :label="item.name" :value="item.key">
|
||||
<i class="yj-custom-icon" :class="item.icon"></i>
|
||||
{{ item.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">墙体闭合</span>
|
||||
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="属性信息" name="1">
|
||||
<attribute :entityOptions="entityOptions"></attribute>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="标签风格" name="2">
|
||||
<labelStyle :entityOptions="entityOptions"></labelStyle>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="position: absolute; left: 24px; display: flex;">
|
||||
<button @click="nodeEdit">
|
||||
<svg class="icon-edit">
|
||||
<use xlink:href="#yj-icon-edit"></use>
|
||||
</svg>二次编辑
|
||||
</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { inject } from "vue";
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import attribute from './attribute.vue'
|
||||
import labelStyle from './labelStyle.vue'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
const material = ref([
|
||||
{
|
||||
name: '纯色墙',
|
||||
value: '纯色墙',
|
||||
key: 0,
|
||||
icon: 'icon-wall'
|
||||
},
|
||||
{
|
||||
name: '上升墙',
|
||||
value: '上升墙',
|
||||
key: 1,
|
||||
icon: 'icon-wall-gradient'
|
||||
},
|
||||
{
|
||||
name: '箭头墙',
|
||||
value: '箭头墙',
|
||||
key: 2,
|
||||
icon: 'icon-wall-arrow'
|
||||
},
|
||||
{
|
||||
name: '警戒墙',
|
||||
value: '警戒墙',
|
||||
key: 3,
|
||||
icon: 'icon-wall-warn'
|
||||
}
|
||||
])
|
||||
eventBus.on("openStandTextAdd", () => {
|
||||
baseDialog.value?.open()
|
||||
});
|
||||
const activeName = ref('1')
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const colorRef = ref(null)
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
originalOptions = structuredClone(that.options)
|
||||
entityOptions.value = that
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
let colorPicker = new window.YJColorPicker({
|
||||
el: colorRef.value,
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: entityOptions.value.color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
entityOptions.value.color = color
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
entityOptions.value.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
console.log('params', params)
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
|
||||
}
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.remove()
|
||||
close()
|
||||
}
|
||||
const nodeEdit = () => {
|
||||
that.nodeEdit()
|
||||
}
|
||||
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
that.positionEditing = false
|
||||
that.reset()
|
||||
eventBus?.emit("destroyComponent")
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -2,6 +2,9 @@ import { TreeApi } from '@/api/tree'
|
||||
import { $changeComponentPop } from '@/utils/communication'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
import { initMapData } from '../../../../../common/initMapData'
|
||||
import { GisApi } from '@/api/gisApi'
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
|
||||
export const useRightOperate = () => {
|
||||
const { getSelectedNodes, cusRemoveNode, cusUpdateNode } = useTreeNode()
|
||||
@ -11,11 +14,157 @@ export const useRightOperate = () => {
|
||||
$changeComponentPop('.adddirectoryBox', true)
|
||||
}
|
||||
//添加资源
|
||||
const addResource = () => { }
|
||||
const addResource = () => {
|
||||
const { ipcRenderer } = require('electron')
|
||||
const options = {
|
||||
properties: ['openFile'], // 允许选择多个文件
|
||||
filters: [
|
||||
{ name: '模型、影像、地形', extensions: ['clt', 'json', 'jct', 'mbtiles', 'pak'] },
|
||||
{ name: '矢量数据', extensions: ['kmz', 'kml', 'shp', 'tab', 'mif', 'geojson'] },
|
||||
]
|
||||
};
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
ipcRenderer.send('open-directory-dialog', options);
|
||||
// 监听主进程返回的结果
|
||||
ipcRenderer.once('selectedItem', async (event, filePaths) => {
|
||||
if (filePaths.length > 0) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let params: any = {
|
||||
id: id,
|
||||
sourcePath: filePaths[0],
|
||||
parentId: parentId,
|
||||
params: '',
|
||||
}
|
||||
// filePaths[0].split('\\').pop()
|
||||
let res = await TreeApi.addModelSource(params)
|
||||
console.log('res', res)
|
||||
if (res.code === 0 || res.code === 200) {
|
||||
ElMessage({
|
||||
message: '添加成功',
|
||||
type: 'success'
|
||||
})
|
||||
res.data.id = id
|
||||
if (res.data.params) {
|
||||
let params = JSON.parse(res.data.params)
|
||||
if (!params.id) {
|
||||
params.id = res.data.id
|
||||
}
|
||||
initMapData(res.data.sourceType, params)
|
||||
}
|
||||
else {
|
||||
//@ts-ignore
|
||||
if (res.data.detail) {
|
||||
//@ts-ignore
|
||||
let detail = JSON.parse(res.data.detail)
|
||||
if (!detail.id) {
|
||||
detail.id = res.data.id
|
||||
}
|
||||
initMapData(res.data.sourceType, detail)
|
||||
}
|
||||
}
|
||||
cusAddNodes(window.treeObj, params.parentId, [res.data])
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//导入全景
|
||||
const importPanorama = () => { }
|
||||
const importPanorama = async () => {
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
const pickerOpts = {
|
||||
types: [
|
||||
{
|
||||
description: '全景图',
|
||||
accept:
|
||||
{
|
||||
'image/jpg': ['.jpg']
|
||||
}
|
||||
}
|
||||
],
|
||||
excludeAcceptAllOption: true,
|
||||
multiple: true
|
||||
};
|
||||
if ((window as any).showOpenFilePicker) {
|
||||
const fileHandles = await (window as any).showOpenFilePicker(pickerOpts);
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'vr')
|
||||
}
|
||||
else {
|
||||
let input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '.jpg'
|
||||
input.multiple = true
|
||||
input.click()
|
||||
input.addEventListener('input', async (e: any) => {
|
||||
let files = e.target.files
|
||||
handleFileImgInput(files, parentId, 'vr')
|
||||
})
|
||||
}
|
||||
}
|
||||
//图片定位
|
||||
const pictureLocation = () => { }
|
||||
const pictureLocation = async () => {
|
||||
let selectedNodes = window.treeObj.getSelectedNodes()
|
||||
let node = selectedNodes && selectedNodes[selectedNodes.length - 1]
|
||||
let parentId
|
||||
if (node) {
|
||||
if (node.sourceType === 'directory') {
|
||||
parentId = node.id
|
||||
}
|
||||
else {
|
||||
parentId = node.parentId
|
||||
}
|
||||
}
|
||||
const pickerOpts = {
|
||||
types: [
|
||||
{
|
||||
description: '无人机航拍',
|
||||
accept:
|
||||
{
|
||||
'image/jpg': ['.jpg']
|
||||
}
|
||||
}
|
||||
],
|
||||
excludeAcceptAllOption: true,
|
||||
multiple: true
|
||||
};
|
||||
if ((window as any).showOpenFilePicker) {
|
||||
const fileHandles = await (window as any).showOpenFilePicker(pickerOpts);
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'link')
|
||||
}
|
||||
else {
|
||||
let input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '.jpg'
|
||||
input.multiple = true
|
||||
input.click()
|
||||
input.addEventListener('input', async (e: any) => {
|
||||
let files = e.target.files
|
||||
handleFileImgInput(files, parentId, 'link')
|
||||
})
|
||||
}
|
||||
}
|
||||
//属性
|
||||
const showAttr = () => { }
|
||||
//导入模型
|
||||
@ -28,9 +177,8 @@ export const useRightOperate = () => {
|
||||
const editNode = (eventBus) => {
|
||||
let selectNodes = getSelectedNodes(window.treeObj);
|
||||
if (selectNodes && selectNodes[selectNodes.length - 1]) {
|
||||
console.log('------------------',selectNodes[selectNodes.length - 1].params)
|
||||
let params = JSON.parse(selectNodes[selectNodes.length - 1].params)
|
||||
eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id);
|
||||
let node = selectNodes[selectNodes.length - 1]
|
||||
eventBus.emit("openDialog", node.sourceType, node.id);
|
||||
}
|
||||
}
|
||||
//删除
|
||||
@ -42,14 +190,17 @@ export const useRightOperate = () => {
|
||||
})
|
||||
.then(async () => {
|
||||
let selectNodes = getSelectedNodes(window.treeObj)
|
||||
const ids = selectNodes.map((item: any) => item.id)
|
||||
const res = await TreeApi.removeDirectory({ ids })
|
||||
if (res.code == 0) {
|
||||
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
|
||||
const res = await TreeApi.removeDirectory({ ids:source_ids })
|
||||
if (res.code == 0 || res.code == 200) {
|
||||
ElMessage({
|
||||
message: '删除成功',
|
||||
type: 'success'
|
||||
})
|
||||
cusRemoveNode(window.treeObj, selectNodes)
|
||||
source_ids.forEach(item => {
|
||||
let entity = window.earth.entityMap.get(item)
|
||||
entity?.remove?.();
|
||||
});
|
||||
} else {
|
||||
ElMessage({
|
||||
message: res.msg || '删除失败',
|
||||
@ -74,7 +225,7 @@ export const useRightOperate = () => {
|
||||
if (selectNodes && selectNodes[selectNodes.length - 1]) {
|
||||
let node = selectNodes[selectNodes.length - 1]
|
||||
let params = JSON.parse(node.params)
|
||||
if(!params) {
|
||||
if (!params) {
|
||||
params = {
|
||||
name: node.sourceName,
|
||||
show: node.isShow,
|
||||
@ -218,6 +369,75 @@ export const useRightOperate = () => {
|
||||
callback: resetPerspective
|
||||
}
|
||||
})
|
||||
|
||||
// 图片文件上传后续
|
||||
async function handleFileImgInput(files: any, parentId: string, type: string) {
|
||||
const formData = new FormData();
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const element = files[i]
|
||||
formData.append('files', element)
|
||||
}
|
||||
let res = await GisApi.linkFile(formData)
|
||||
if (res.code == 0 || res.code == 200) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i]
|
||||
// 检查文件类型
|
||||
if (!file.type.match('image*')) {
|
||||
continue;
|
||||
}
|
||||
(window as any).EXIF.getData(file, async function (e) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = file.name.split('.')[0]
|
||||
// 获取所有EXIF数据
|
||||
// @ts-ignore
|
||||
const allMetaData = (window as any).getAllTags(this);
|
||||
let lngDMS = allMetaData.GPSLongitude[0] + '°' + allMetaData.GPSLongitude[1] + "'" + allMetaData.GPSLongitude[2] + '"'
|
||||
let latDMS = allMetaData.GPSLatitude[0] + '°' + allMetaData.GPSLatitude[1] + "'" + allMetaData.GPSLatitude[2] + '"'
|
||||
let lngDecimal = window.earth.proj.dmsToDecimal(lngDMS)
|
||||
let latDecimal = window.earth.proj.dmsToDecimal(latDMS)
|
||||
if (allMetaData.GPSLongitudeRef === 'W') {
|
||||
lngDecimal = -(Math.abs(lngDecimal))
|
||||
}
|
||||
if (allMetaData.GPSLatitudeRef === 'S') {
|
||||
latDecimal = -(Math.abs(latDecimal))
|
||||
}
|
||||
let options: any = await initMapData('point', {
|
||||
id: id,
|
||||
name: name,
|
||||
position: {
|
||||
lng: lngDecimal,
|
||||
lat: latDecimal,
|
||||
alt: allMetaData.GPSAltitude.valueOf()
|
||||
},
|
||||
attribute: {
|
||||
[type]: {
|
||||
content: [
|
||||
{
|
||||
"name": "带定位照片",
|
||||
"url": res.data[i].previewUrl
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
delete options.host
|
||||
let params: any = {
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'point',
|
||||
// isShow: 1,
|
||||
parentId: parentId,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
rightMenus
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { $changeComponentShow } from '@/utils/communication'
|
||||
import { useTreeNode } from './treeNode'
|
||||
import { TreeApi } from '@/api/tree'
|
||||
import { initMapData } from '../initMapData'
|
||||
import { initMapData } from '../../../../common/initMapData'
|
||||
|
||||
export const useTree = () => {
|
||||
const rightMenuRef: any = ref() //右键菜单的实例
|
||||
@ -418,7 +418,8 @@ export const useTree = () => {
|
||||
})
|
||||
for (let i = res.data.length - 1; i >= 0; i--) {
|
||||
if (!res.data[i].id) {
|
||||
res.data.splice(i, 1);
|
||||
// res.data.splice(i, 1);
|
||||
res.data[i].id = generateRandomString(20, false)
|
||||
}
|
||||
}
|
||||
zNodes.value = res.data
|
||||
@ -430,6 +431,29 @@ export const useTree = () => {
|
||||
}
|
||||
}
|
||||
|
||||
function generateRandomString(length = 10, includeSpecial = true) {
|
||||
// 基础字符集:大小写字母和数字
|
||||
let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
// 如果需要包含特殊字符,则添加到字符集中
|
||||
if (includeSpecial) {
|
||||
chars += '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
||||
}
|
||||
|
||||
let result = '';
|
||||
const charsLength = chars.length;
|
||||
|
||||
// 循环生成指定长度的随机字符
|
||||
for (let i = 0; i < length; i++) {
|
||||
// 生成0到字符集长度之间的随机索引
|
||||
const randomIndex = Math.floor(Math.random() * charsLength);
|
||||
// 将对应索引的字符添加到结果中
|
||||
result += chars.charAt(randomIndex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const initTreeCallBack = () => {
|
||||
if (window.earth) {
|
||||
for (let i = 0; i < zNodes.value.length; i++) {
|
||||
|
||||
@ -10,14 +10,8 @@
|
||||
<firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
|
||||
<!--底部菜单-->
|
||||
<bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
|
||||
<input
|
||||
type="file"
|
||||
id="fileInputlink"
|
||||
style="display: none"
|
||||
multiple
|
||||
accept=".jpeg,.png,.jpg,.mp4,.pdf"
|
||||
@input="uploadFile"
|
||||
/>
|
||||
<input type="file" id="fileInputlink" style="display: none" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf"
|
||||
@input="uploadFile" />
|
||||
|
||||
<!-- 多点视线分析 -->
|
||||
<Visibility ref="visibility"></Visibility>
|
||||
@ -65,7 +59,13 @@ import Graffiti from '../components/propertyBox/Graffiti.vue'
|
||||
import FlyRoam from '../components/propertyBox/FlyRoam.vue'
|
||||
import CoorLocation from '../components/propertyBox/CoorLocation.vue'
|
||||
import ScreenShot from '../components/propertyBox/ScreenShot.vue'
|
||||
import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue'
|
||||
import terrainExcavation from '../components/propertyBox/terrainExcavation.vue'
|
||||
import tileset from '../components/propertyBox/tileset.vue'
|
||||
import layer from '../components/propertyBox/layer.vue'
|
||||
import trajectoryMotion from '../components/propertyBox/trajectoryMotion.vue'
|
||||
import wallStereoscopic from '../components/propertyBox/wallStereoscopic.vue'
|
||||
import circleDiffuse from '../components/propertyBox/circleDiffuse.vue'
|
||||
import radarScan from '../components/propertyBox/radarScan.vue'
|
||||
|
||||
import { GisApi } from '@/api/gisApi'
|
||||
|
||||
@ -77,6 +77,10 @@ let dynamicComponentRef = ref()
|
||||
let addStandTextRef = ref()
|
||||
let tree = ref()
|
||||
eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
console.log(sourceType, id)
|
||||
if(dynamicComponentRef.value && dynamicComponentRef.value.close) {
|
||||
dynamicComponentRef.value.close()
|
||||
}
|
||||
switch (sourceType) {
|
||||
case 'addGroundText':
|
||||
currentComponent.value = addGroundText
|
||||
@ -113,7 +117,6 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
break
|
||||
case 'panel':
|
||||
currentComponent.value = polygonObject
|
||||
await nextTick()
|
||||
@ -144,6 +147,36 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id, 'pincerArrow')
|
||||
break
|
||||
case 'tileset':
|
||||
currentComponent.value = tileset
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'layer':
|
||||
currentComponent.value = layer
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'path':
|
||||
currentComponent.value = trajectoryMotion
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'wallStereoscopic':
|
||||
currentComponent.value = wallStereoscopic
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'diffuseScan':
|
||||
currentComponent.value = circleDiffuse
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'radarScan':
|
||||
currentComponent.value = radarScan
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user