模型压平

This commit is contained in:
2025-09-11 18:06:03 +08:00
parent 0e8793f01d
commit 485c6067c8
41 changed files with 571 additions and 74 deletions

BIN
ffplay/81.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
ffplay/avcodec-60.dll Normal file

Binary file not shown.

BIN
ffplay/avdevice-60.dll Normal file

Binary file not shown.

BIN
ffplay/avfilter-9.dll Normal file

Binary file not shown.

BIN
ffplay/avformat-60.dll Normal file

Binary file not shown.

BIN
ffplay/avutil-58.dll Normal file

Binary file not shown.

BIN
ffplay/earth.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

BIN
ffplay/ffmpeg.exe Normal file

Binary file not shown.

BIN
ffplay/ffmpeg_arm Normal file

Binary file not shown.

BIN
ffplay/ffmpeg_x86 Normal file

Binary file not shown.

BIN
ffplay/ffplay Normal file

Binary file not shown.

BIN
ffplay/ffplay.exe Normal file

Binary file not shown.

BIN
ffplay/ffprobe.exe Normal file

Binary file not shown.

BIN
ffplay/jingwu.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
ffplay/postproc-57.dll Normal file

Binary file not shown.

BIN
ffplay/rcedit-x86.exe Normal file

Binary file not shown.

1
ffplay/rcedit-x86.txt Normal file
View File

@ -0,0 +1 @@
$ rcedit "path-to-exe-or-dll" --set-icon "path-to-ico"

BIN
ffplay/swresample-4.dll Normal file

Binary file not shown.

BIN
ffplay/swscale-7.dll Normal file

Binary file not shown.

10
package-lock.json generated
View File

@ -19,6 +19,7 @@
"electron-updater": "^6.3.9",
"element-plus": "^2.10.4",
"mitt": "^3.0.1",
"moment": "^2.30.1",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"scss": "^0.2.4",
@ -9301,6 +9302,15 @@
"pathe": "^2.0.1"
}
},
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",

View File

@ -31,6 +31,7 @@
"electron-updater": "^6.3.9",
"element-plus": "^2.10.4",
"mitt": "^3.0.1",
"moment": "^2.30.1",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"scss": "^0.2.4",

View File

@ -1,8 +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 { Recorder } from "../preload/recorder";
import fs from 'fs'
import dayjs from 'dayjs'
const { exec } = require('child_process');
@ -126,6 +128,50 @@ function createWindow(): void {
}, 200)
})
})
ipcMain.on("saveFile", (event, { title, filename, filters }) => {
dialog
.showSaveDialog({
title,
defaultPath: filename,
filters,
})
.then((files) => {
let path = "";
if (!files.canceled) {
path = files.filePath.replace(/\\/g, "/");
}
event.sender.send("selectedFileItem", path);
});
});
let recorder;
ipcMain.on("startRecoder", (event) => {
console.log("开始录制");
recorder = new Recorder();
recorder.start();
});
ipcMain.on("endRecoder", (event) => {
console.log("结束录制");
// 判断是否存在recorder是否有recorder.end方法
if (!recorder) {
console.log("recorder不存在");
return;
}
recorder.end(() => {
let path = dialog.showSaveDialogSync({
title: "保存视频文件",
defaultPath: dayjs().format("YYYYMMDDHHmmss") + "视频录制.mp4",
filters: [{ name: "文件类型", extensions: ["mp4"] }],
});
if (path != undefined) {
recorder.move(path, () => {
recorder = null;
});
} else {
recorder = null;
}
});
});
// 设置窗口标题和图标
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)

22
src/preload/config.ts Normal file
View File

@ -0,0 +1,22 @@
//获取项目根目录
function GetHomeDir() {
let HOME_DIR = process.cwd();
console.log("process.env.NODE_ENV", process.env.NODE_ENV);
if (process.env.NODE_ENV === "production") {
let arr = process.execPath.replaceAll("\\", "/").split("/");
arr.pop();
HOME_DIR = arr.join("/");
}
return HOME_DIR;
}
//获取项目根目录
function GetAsar() {
let HOME_DIR = process.cwd();
if (process.env.NODE_ENV === "production") {
let arr = process.execPath.replaceAll("\\", "/").split("/");
arr.pop();
HOME_DIR = arr.join("/");
}
return HOME_DIR;
}
export { GetHomeDir, GetAsar };

View File

@ -23,3 +23,4 @@ if (process.contextIsolated) {
// @ts-ignore (define in dts)
window.YJColorPicker = YJColorPicker
}

113
src/preload/recorder.ts Normal file
View File

@ -0,0 +1,113 @@
import path from "path";
import { GetHomeDir } from "./config";
const os = require("os");
const fs = require("fs");
let platform = os.platform();
const arch = os.arch();
const moment = require("moment");
const { spawn } = require("child_process");
const EventEmitter = require("events");
let ffmpegExePath = path.join(GetHomeDir(), "ffplay");
class MyEmitter extends EventEmitter { }
const myEmitter = new MyEmitter();
class Recorder {
constructor(option = {}) {
this.shell = undefined;
this.filename =
moment(parseInt(new Date().getTime())).format("YYYYMMDDHHmmss") + ".mp4";
this.exe = "ffmpeg.exe";
if (platform === "win32") {
this.exe = "ffmpeg.exe";
this.params = "-f gdigrab -r 30 -y -i desktop -pix_fmt yuv420p";
}
if (platform === "linux") {
switch (arch) {
case "x64":
this.exe = "ffmpeg_x86";
break;
case "arm":
this.exe = "ffmpeg_arm";
break;
}
this.params =
"-v verbose -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0 -c:v libx264 -preset ultrafast -crf 18";
//-s 1920x1080
// ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0 -c:v libx264 -preset ultrafast -crf 18 output.mp4
}
this.commands = path.join(GetHomeDir(), "/ffplay/" + this.exe);
}
get_path() {
return path.join(ffmpegExePath, this.filename);
}
start() {
this.exec(this.commands, this.params);
}
exec(commands, param) {
let arr = param.split(" ");
arr.push(this.get_path());
console.log("commands, arr", commands, arr);
this.shell = spawn(commands, arr, {
ffmpegExePath,
// stdio: "ignore",
// shell: true
})
.on("exit", (err) => {
console.log("exit", err);
myEmitter.emit("process-exit");
})
.on("data", function (data) {
// console.log(typeof data);
})
.on("data", function (data) { });
this.shell.unref();
}
end(cb) {
if (!this.shell.killed) {
console.log(this.shell);
this.shell.stdin.write("q");
myEmitter.once("process-exit", () => {
cb();
});
} else {
cb();
}
}
move(dst, cb) {
let readStream = fs.createReadStream(this.get_path());
let writeStream = fs.createWriteStream(dst);
readStream.pipe(writeStream);
readStream.on("end", () => {
fs.unlinkSync(this.get_path());
cb();
});
}
}
/*function start() {
config.recorder = new Recorder()
config.recorder.start()
}
function end(cb) {
config.recorder.end(() => {
cb()
})
}
function getRecorder() {
return config.recorder
}
function resetRecorder() {
config.recorder = null
}
exports.Recorder = {
start,
end,
getRecorder,
resetRecorder,
}*/
export { Recorder };

View File

@ -0,0 +1,16 @@
//授权
import request from '@/axios/request'
export const AuthApi = {
// 查看授权信息
showAuth: async () => {
return await request.get({
url: `/auth/show`
})
},
//获取系统授权码
authInfo: async () => {
return await request.get({
url: `/auth/info`
})
},
}

View File

@ -10,14 +10,14 @@ 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'
} else {
baseURL = ''
}
// 创建自定义配置的axios实例
const service: AxiosInstance = axios.create({
baseURL:'http://192.168.110.25:8848',
baseURL: 'http://192.168.110.25:8848',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
@ -49,10 +49,10 @@ service.interceptors.request.use(
// 在这里添加认证token
const token = localStorage.getItem('Authorization')
console.log("localStorage.getItem('Authorization')",token);
console.log("localStorage.getItem('Authorization')", token);
if (token && config.headers) {
// Bearer
// Bearer
config.headers.Authorization = `${token}`
}
return config
@ -67,18 +67,18 @@ service.interceptors.response.use(
(response: AxiosResponse) => {
const key = getRequestKey(response.config)
pendingRequests.delete(key)
console.log(response);
console.log(response);
// 统一处理HTTP状态码
if (response.status === 200) {
if ([0,200].includes(response.data.code)) {
if ([0, 200].includes(response.data.code)) {
return response
}
if (response.data.code==401) {
if (response.data.code == 401) {
router.push('/')
localStorage.removeItem('Authorization')
}
if (![0,200].includes(response.data.code)) {
if (![0, 200].includes(response.data.code)) {
ElMessage({
message: response.data.msg || response.data.message,
type: 'error'

View File

@ -1,6 +1,6 @@
<template>
<el-upload
:action="action"
:action="uploadUrl()"
:headers="headers"
:data="data"
:show-file-list="false"
@ -39,12 +39,19 @@ const props = defineProps({
}
})
const headers = ref({
Authorization: 'Bearer ' + localStorage.getItem('access_token')
// Authorization: 'Bearer ' + localStorage.getItem('access_token')
Authorization: localStorage.getItem('Authorization')
})
const action = ref('')
// const action = ref('')
// 上传状态
const isUploading = ref(false)
// 上传地址
const uploadUrl = () => {
//process.env.BASE_API +
console.log(process.env.BASE_API, 'yyyyy')
let url = 'http://192.168.110.25:8848' + '/yjearth4.0/api/v1/auth/import'
return url
}
// 上传前处理
const handleBeforeUpload = (file: File) => {
// 检查文件大小

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -28,3 +28,4 @@ export const $recvElectronChanel = (chanel: any, cb: any) => {
ipcRenderer.once(chanel, cb);
};

View File

@ -43,6 +43,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import uploadFiles from '@/components/upload/uploadFiles.vue'
import { AuthApi } from '@/api/setting/auth.ts'
const { t } = useI18n()
const authInfo = ref({
license_code: '',
@ -53,6 +54,18 @@ const authInfo = ref({
auth_type: '无', //授权时间
message: '' //
})
const getAuthInfo = async () => {
const res = await AuthApi.showAuth()
console.log(res, 'resres')
}
const getAuthCode = async () => {
const res = await AuthApi.authInfo()
authInfo.value.license_code = res.data
console.log(res, 'resres22')
}
getAuthInfo()
getAuthCode()
//复制
const copy = () => {
console.log(1111111)

View File

@ -23,13 +23,17 @@ import { useTreeNode } from '../tree/hooks/treeNode'
import { TreeApi } from '@/api/tree'
import { renderMethods } from '../tree/hooks/renderTreeNode'
import { processBase64Images, combineBase64Images } from '@/utils/HighDefinitionScreenshot'
import { $sendElectronChanel, $recvElectronChanel } from '@/utils/communication'
import { ElMessage } from 'element-plus'
import {
$sendElectronChanel,
$recvElectronChanel,
$changeComponentShow
} from '@/utils/communication'
import { ElMessage, ElLoading } from 'element-plus'
import dayjs from 'dayjs'
import fs from 'fs'
const { proxy } = getCurrentInstance()
const { t } = useI18n()
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
const fs = require('fs')
const obj = ref(null)
const isclick = ref(false)
const eventBus = inject('bus')
@ -46,6 +50,21 @@ var graffitiObjArr = reactive([])
eventBus.on('graffitiObj', (data) => {
graffitiObjArr.push(data)
})
function openLoading(
text = '拼命加载中...',
option = {
fullscreen: true,
background: 'rgba(0,0,0,0.63)',
lock: true
// spinner: 'el-icon-loading'
}
) {
option.text = text
let loadingInstance = ElLoading.service(option)
return loadingInstance
}
const methodMap = {
// 轨迹运动
trajectoryMotion: () => {
@ -238,7 +257,6 @@ const methodMap = {
async screenShot() {
function downloadScreen(res) {
let base64 = res.replace(/^data:image\/\w+;base64,/, '')
console.log('base64', base64)
let dataBuffer = new Buffer(base64, 'base64')
$sendElectronChanel('saveFile', {
title: '保存图片',
@ -246,10 +264,7 @@ const methodMap = {
filters: [{ name: '保存图片', extensions: ['jpg'] }]
})
$recvElectronChanel('selectedFileItem', (e, path) => {
console.log('path', fs.writeFile)
fs.writeFile(path, dataBuffer, (res) => {
console.log(res)
})
fs.writeFile(path, dataBuffer, (res) => {})
})
}
@ -302,18 +317,10 @@ const methodMap = {
clickChange.videoRecord = !clickChange.videoRecord
let time = 3
this.$changeComponentShow('#secondMenu', false)
// const onKeyDown = (e) => {
// if (e.keyCode === 27) {
// item.status = !item.status;
// $sendElectronChanel("endRecoder");
// document.removeEventListener("keydown", onKeyDown);
// }
// };
$changeComponentShow('#secondMenu', false)
if (clickChange.videoRecord) {
// document.addEventListener("keydown", onKeyDown);
let loading = $root_home.openLoading(time, {
let loading = openLoading(time, {
background: 'rgba(0,0,0,0)',
fullscreen: false,
customClass: 'timer'
@ -328,7 +335,6 @@ const methodMap = {
if (time == -1) {
clearInterval(timer)
loading.close()
console.log('开始了')
p.remove()
$sendElectronChanel('startRecoder')
}
@ -341,7 +347,76 @@ const methodMap = {
}
},
//压模
pressModel() {},
pressModel() {
// if (window.checkAuthIsValid) {
let selectedNode = window.treeObj.getSelectedNodes()[0]
if (selectedNode) {
let isTileset = ['bim', 'tileset'].includes(selectedNode.sourceType)
if (!isTileset) {
ElMessage({
message: '请在图层指挥舱选中对应模型进行操作',
type: 'warning'
})
return
}
// let source_id = this.$md5(new Date().getTime() + '压平面')
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, params) => {
if (params.length > 2) {
if (err) throw err
let alt = params[0].alt
params.forEach((item) => {
if (item.alt < alt) alt = item.alt
})
//获取节点树对象
let entity = window.earth.entityMap.get(selectedNode.id).entity
let flat = new YJ.Analysis.Flat(window.earth, entity, {
positions: params
})
let detailOption = {
// modleId: selectedNode.id,
modelId: selectedNode.id,
positions: params,
height: flat.height
}
let id = new YJ.Tools().randomString()
let paramsData = {
params: detailOption,
id,
sourceName: '压平面',
sourceType: 'pressModel',
// parentId:
// selectedNode.sourceType == 'directory' ? selectedNode.id : selectedNode.parentId
parentId: selectedNode.id
}
TreeApi.addOtherSource(paramsData)
paramsData.isShow = true
paramsData.params = JSON.stringify(paramsData.params)
pressModelMap.set(id + '_' + selectedNode.id, paramsData)
window.pressModelEntities.set(id, flat)
cusAddNodes(window.treeObj, paramsData.parentId, [paramsData])
// //鼠标右键点击事件
flat.onRightClick = () => {}
// _entityMap.set(node.source_id, flat)
} else {
// this.$message.warning('至少三个点')
}
})
} else {
// this.$message.warning('请在图层指挥舱选中对应模型进行操作!')
}
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//地形开挖
terrainDig() {
// if (window.checkAuthIsValid) {

View File

@ -16,14 +16,24 @@
<div class="row">
<div class="col" style="flex: 0 0 58%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
<input
class="input"
type="number"
placeholder="请输入坐标点经度数值"
v-model="longitude"
/>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 58%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
<input
class="input"
type="number"
placeholder="请输入坐标点纬度数值"
v-model="latitude"
/>
</div>
<div class="col"></div>
</div>
@ -42,9 +52,9 @@
<div class="row">
<div class="col" style="flex: 0 0 78%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
<input class="input" type="number" placeholder="请输入内容" v-model="longitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngMin" />
<input class="input" type="number" placeholder="请输入内容" v-model="lngMin" />
<span class="label2"></span>
</div>
<div class="col"></div>
@ -52,9 +62,9 @@
<div class="row">
<div class="col" style="flex: 0 0 78%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
<input class="input" type="number" placeholder="请输入内容" v-model="latitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="latMin" />
<input class="input" type="number" placeholder="请输入内容" v-model="latMin" />
<span class="label2"></span>
</div>
<div class="col"></div>
@ -74,11 +84,11 @@
<div class="row">
<div class="col" style="flex: 0 0 90%">
<span class="label">经度</span>
<input class="input" type="number" v-model="longitude" />
<input class="input" type="number" placeholder="请输入内容" v-model="longitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngMin" />
<input class="input" type="number" placeholder="请输入内容" v-model="lngMin" />
<span class="label2"></span>
<input class="input" type="number" v-model="lngSec" />
<input class="input" type="number" placeholder="请输入内容" v-model="lngSec" />
<span class="label2"></span>
</div>
<div class="col"></div>
@ -86,11 +96,11 @@
<div class="row">
<div class="col" style="flex: 0 0 90%">
<span class="label">纬度</span>
<input class="input" type="number" v-model="latitude" />
<input class="input" type="number" placeholder="请输入内容" v-model="latitude" />
<span class="label2"></span>
<input class="input" type="number" v-model="latMin" />
<input class="input" type="number" placeholder="请输入内容" v-model="latMin" />
<span class="label2"></span>
<input class="input" type="number" v-model="latSec" />
<input class="input" type="number" placeholder="请输入内容" v-model="latSec" />
<span class="label2"></span>
</div>
<div class="col"></div>
@ -107,8 +117,8 @@
</el-tabs>
</template>
<template #footer>
<button @click="draw">确定</button>
<button @click="close">取消</button>
<!-- <button @click="draw">确定</button> -->
<button @click="close">关闭</button>
</template>
</Dialog>
</template>

View File

@ -18,7 +18,7 @@
</div>
</div>
</div>
<div class="div-item item" data-type="0">
<div class="div-item item" data-type="0" v-show="isShowing">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px"></span>
@ -49,7 +49,7 @@
</div>
</div>
</div>
<div class="div-item item" data-type="1">
<div class="div-item item" data-type="1" v-show="isShowing">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分</span>
@ -124,7 +124,7 @@
</div>
</div>
</div>
<div class="div-item item" data-type="2">
<div class="div-item item" data-type="2" v-show="isShowing">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分秒</span>
@ -238,6 +238,7 @@ const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var status1: any = ref(false)
var isShowing: any = ref(false)
var tools: any = reactive([])
eventBus.on('projConvertDialog', () => {
baseDialog.value?.open()
@ -250,8 +251,9 @@ eventBus.on('projConvertDialog', () => {
tools = new YJ.Tools(window.earth)
tools.projConvert(status1.value, () => {
status1.value = false
isShowing.value = true
})
}, 100)
}, 10)
})
const closeCallBack = (e) => {

View File

@ -1,12 +1,21 @@
<template>
<Dialog ref="baseDialog" title="路径规划" left="180px" top="100px" :closeCallback="closeCallBack">
<Dialog
ref="baseDialog"
class="RoutePlanning"
title="路径规划"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<div class="row" style="align-items: flex-start">
<div class="col start-col">
<span class="label">起点</span>
<input class="input" type="number" title="" min="-180" max="180" @model="startLng" />
<input class="input" type="number" title="" min="-90" max="90" @model="startLat" />
<button @click="pickStartPos" style="margin-left: 10px">拾取</button>
<button class="crossPoint">
<svg-icon name="add" :size="16" color="rgba(255, 255, 255, 1)"></svg-icon> 途径点
</button>
<button style="margin-left: 10px">
<svg-icon name="add" :size="16" color="rgba(255, 255, 255, 1)"></svg-icon>避让点
</button>
</div>
</div>
<div class="row" style="align-items: flex-start">
@ -41,7 +50,6 @@ var endLat: any = ref(null)
var routePlanning: any = reactive([])
eventBus.on('routePlanningDialog', () => {
baseDialog.value?.open()
routePlanning = new YJ.Obj.RoutePlanning(window.earth, { gps: true })
})
const closeCallBack = (e) => {}
@ -52,13 +60,19 @@ const draw = (e) => {}
</script>
<style scoped lang="scss">
.YJ-custom-base-dialog > .content {
::v-deep .RoutePlanning > .content {
width: 460px;
}
.YJ-custom-base-dialog > .content > div > .row .col {
::v-deep .RoutePlanning > .content > div > .row .col {
margin: 0 10px;
}
.YJ-custom-base-dialog > .content .row .label {
::v-deep .RoutePlanning > .content .row .label {
flex: auto;
}
.crossPoint:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
}
.crossPoint:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<Dialog
ref="baseDialog"
title="压平面属性"
class="flatPlane"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label" style="width: 56px; flex: 0 0 56px">名称</span>
<input class="input input-name" />
</div>
</div>
<div class="row">
<div class="col">
<span class="label" style="width: 56px; flex: 0 0 56px">压平高度</span>
<div class="input-number input-number-unit-1">
<input
class="input flat-height"
type="number"
title=""
min="-9999999"
max="999999999"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
</template>
<template #footer>
<button @click="sure">确认</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import { TreeApi } from '@/api/tree'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var flat: any = reactive([])
var flatMsg: any = reactive([])
eventBus.on('flatDialog', (id) => {
baseDialog.value?.open()
})
const open = (data) => {
baseDialog.value?.open()
flat = window.pressModelEntities.get(data.id)
let params = JSON.parse(data.params)
flatMsg = pressModelMap.get(data.id + '_' + params.modelId)
setTimeout(() => {
flat.edit(true)
}, 100)
}
const closeCallBack = (e) => {}
const sure = (e) => {
let paramsData = JSON.parse(flatMsg.params)
paramsData.height = flat.height
let params = {
id: flatMsg.id,
sourceName: flat.name,
params: paramsData,
isShow: flatMsg.isShow ? 1 : 0
}
TreeApi.updateDirectoryInfo(params)
cusUpdateNode({
id: params.id,
sourceName: params.sourceName,
params: JSON.stringify(paramsData)
})
baseDialog.value?.close()
}
const close = (e) => {
flat.reset()
baseDialog.value?.close()
}
defineExpose({
open
})
</script>
<style scoped lang="scss"></style>

View File

@ -28,9 +28,13 @@ export const useRightOperate = () => {
const editNode = (eventBus) => {
let selectNodes = getSelectedNodes(window.treeObj);
if (selectNodes && selectNodes[selectNodes.length - 1]) {
console.log('------------------',selectNodes[selectNodes.length - 1].params)
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);
if (selectNodes[selectNodes.length - 1].sourceType == 'pressModel') {
eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, selectNodes[selectNodes.length - 1]);
} else {
eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id);
}
}
}
//删除
@ -74,7 +78,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,

View File

@ -69,7 +69,13 @@ export const useTree = () => {
* @param treeNode 鼠标右键点击时所在节点的 JSON 数据对象
*/
const onDblClick = (event: MouseEvent, treeId: string, treeNode: any) => {
let entityObject = window.earth.entityMap.get(treeNode.id)
let entityObject
if (treeNode.sourceType == 'pressModel') {
entityObject = window.pressModelEntities.get(treeNode.id)
} else {
entityObject = window.earth.entityMap.get(treeNode.id)
}
console.log('entityObject', entityObject)
entityObject.flyTo()
}
/**
@ -215,10 +221,31 @@ export const useTree = () => {
* @param treeNode
*/
const onCheck = async (event: any, treeId: any, treeNode: any) => {
console.log(treeNode, 'treeNode')
let params = JSON.parse(treeNode.params)
let entityObject = window.earth.entityMap.get(params.id)
entityObject.show = treeNode.isShow
params.show = treeNode.isShow
let entityObject
if (treeNode.sourceType == 'pressModel') {
let params = JSON.parse(treeNode.params)
let id = treeNode.id + '_' + params.modelId
let data = window.pressModelMap.get(id)
data.isShow = treeNode.isShow
entityObject = window.pressModelEntities.get(treeNode.id)
if (!entityObject && treeNode.isShow) {
const entity = window.earth.entityMap.get(params.modelId).entity
entityObject = new YJ.Analysis.Flat(window.earth, entity, {
positions: params.positions,
height: params.height,
name: treeNode.sourceName
})
window.pressModelEntities.set(treeNode.id, entityObject)
}
} else {
entityObject = window.earth.entityMap.get(params.id)
}
entityObject.show = treeNode.isShow;
(treeNode.sourceType != 'pressModel') && (params.show = treeNode.isShow)
let params2 = {
"id": treeNode.id,
"params": params,
@ -402,7 +429,6 @@ export const useTree = () => {
// 初始化树的方法
const initTree = async (selector: string = '#treeDemo') => {
let res = await TreeApi.getTreeList()
console.log('res', res)
if ([0, 200].includes(res.code)) {
res.data.sort((a: any, b: any) => {
if (a.treeIndex && b.treeIndex) {
@ -416,14 +442,20 @@ export const useTree = () => {
}
return 0;
})
//将模型压平
window.pressModelMap = new Map();
window.pressModelEntities = new Map();
for (let i = res.data.length - 1; i >= 0; i--) {
if (!res.data[i].id) {
res.data.splice(i, 1);
}
if (res.data[i].sourceType == "pressModel") {
const obj = JSON.parse(res.data[i].params);
pressModelMap.set(res.data[i].id + "_" + obj.modelId, res.data[i]);
}
}
zNodes.value = res.data
treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value)
console.log(res.data)
window.treeObj = treeObj.value
window.AllNodes = treeObj.value.getNodes()
initTreeCallBack()
@ -439,6 +471,7 @@ export const useTree = () => {
params.id = zNodes.value[i].id
}
initMapData(zNodes.value[i].sourceType, params)
}
else {
//@ts-ignore

View File

@ -510,7 +510,6 @@ export const useTreeNode = () => {
let showRightMenu = (event: any, treeObj: any) => {
// 获取选中的节点
let selectedNodes = getSelectedNodes(treeObj)
console.log('selectedNodes', selectedNodes)
let arr: any = []
let rightMenuHeight = window.getComputedStyle($('#rMenu')[0]).getPropertyValue('height')
let rightMenuWidth = window.getComputedStyle($('#rMenu')[0]).getPropertyValue('width')

View File

@ -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)
@ -44,19 +43,42 @@ export const initMapData = async (type, data) => {
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Terrain(window.earth, data)
break
case 'layer':
case 'layer':
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Layer(window.earth, data)
break
case 'tileset':
case 'tileset':
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Tileset(window.earth, data)
entityObject.load((res) => {
// 等模型加载完后再加载压平模型
Array.from(window.pressModelMap.keys()).forEach((key) => {
if (key.indexOf("_" + data.id) > -1) {
const nodes = window.pressModelMap.get(key);
if (nodes) {
if (nodes.isShow == 1) {
// nodeType[nodes.source_type].render(nodes);
const flatData = JSON.parse(nodes.params)
const entity = window.earth.entityMap.get(flatData.modelId).entity
let flat = new YJ.Analysis.Flat(window.earth, entity, {
positions: flatData.positions,
height: flatData.height,
name: nodes.sourceName
})
window.pressModelEntities.set(nodes.id, flat)
}
}
}
});
})
break
default:
return
break
}
options = structuredClone(entityObject.options)
delete options.host
// options = entityObject
return options
}

View File

@ -74,6 +74,7 @@ import ProjConvert from '../components/propertyBox/ProjConvert.vue'
import ProjectionConvert from '../components/propertyBox/ProjectionConvert.vue'
import GoodsSearchCircle from '../components/propertyBox/GoodsSearchCircle.vue'
import GoodsSearchPolgon from '../components/propertyBox/GoodsSearchPolgon.vue'
import flat from '../components/propertyBox/flat.vue'
import { GisApi } from '@/api/gisApi'
@ -152,6 +153,12 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
await nextTick()
dynamicComponentRef.value?.open(id, 'pincerArrow')
break
case 'pressModel':
currentComponent.value = flat
await nextTick()
console.log('cccc', id)
dynamicComponentRef.value?.open(id, 'pressModel')
break
default:
break
}