This commit is contained in:
zh
2025-12-23 17:33:29 +08:00
27 changed files with 576 additions and 3634 deletions

View File

@ -1,7 +1,7 @@
server:
host: 127.0.0.1
port: 8848
path: C:\Users\MSI\AppData\Roaming\dzsp_shijingjun_offline_Y_save
path: C:\Users\Administrator\AppData\Roaming\dzsp_shijingjun_offline_Y_save
poi:
global:
enabled: false

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -11,7 +11,7 @@
</div>
<div class="boxBody">
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px"
@keyup.enter.native="submitForm(ruleForm)" @submit.native.prevent>
@keyup.enter.native="submitForm(ruleForm)" @submit.native.prevent>
<el-form-item label="名称:" prop="sourceName">
<!-- @input="removeSpaces" -->
<el-input v-model.trim="form.sourceName" placeholder="节点名称"></el-input>
@ -29,12 +29,13 @@
</template>
<script lang="ts" setup>
import { $changeComponentPop } from '@/utils/communication'
import { throttle } from '@/utils/index'
import { ElMessage, FormInstance } from 'element-plus'
import { TreeApi } from '@/api/tree'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { getKeyOfSelectedNode, getSelectedNode, cusUpdateNode, getSameLevel, getSelectedNodes } = useTreeNode()
import {$changeComponentPop} from '@/utils/communication'
import {throttle} from '@/utils/index'
import {ElMessage, FormInstance} from 'element-plus'
import {TreeApi} from '@/api/tree'
import {useTreeNode} from '@/views/components/tree/hooks/treeNode'
const {getKeyOfSelectedNode, getSelectedNode, cusUpdateNode, getSameLevel, getSelectedNodes} = useTreeNode()
const title = ref('编辑节点')
const sourceId = ref('')
let form: any = reactive({
@ -42,7 +43,7 @@ let form: any = reactive({
})
const ruleForm = ref()
const rules = reactive({
sourceName: [{ required: true, message: '请输入名称', trigger: 'blur' }]
sourceName: [{required: true, message: '请输入名称', trigger: 'blur'}]
})
const removeSpaces = (value: string) => {
form.sourceName = value.replace(/\s/g, '')
@ -70,7 +71,7 @@ const add = throttle(async () => {
id: sourceId.value,
sourceName: form.sourceName
})
cusUpdateNode({ id: sourceId.value, sourceName: form.sourceName, params: undefined })
cusUpdateNode({id: sourceId.value, sourceName: form.sourceName, params: undefined})
close()
// console.log(res)
}, 3000)
@ -117,6 +118,7 @@ defineExpose({
<style lang="scss">
.editdirectoryBox {
user-select: none;
width: 100vw;
height: 100vh;

View File

@ -106,6 +106,18 @@ const initTreeCallBack = () => {
TsApi.queryTsSource(formData).then(async res => {
console.log('queryTsSource', res)
if (res.code == 200) {
res.data.sort((a: any, b: any) => {
if ((a.treeIndex || a.treeIndex == 0) && (b.treeIndex || b.treeIndex == 0)) {
return a.treeIndex - b.treeIndex
}
if (a.treeIndex) {
return -1;
}
if (b.treeIndex) {
return 1;
}
return 0;
});
for (let i = res.data.length - 1; i >= 0; i--) {
res.data[i].svg = await cusNodeIcon(res.data[i]);
@ -416,12 +428,12 @@ let rightClick = (event: MouseEvent, treeId: string, treeNode: any) => {
let menus = showRightMenuTs(event, treeObj.value, getSelectedNodes(treeObj.value), nodeType)
// console.log("menus", menus)
// canCheckType.includes(treeNode.sourceType) 包含的类型才有视角
if (treeNode && treeNode.sourceType != 'directory') {
if (treeNode && treeNode.sourceType != 'directory' && selectNodes.length == 1) {
let customView
let entity = window['_entityMap'].get(treeNode.id)
customView = Boolean(entity.customView && entity.customView.orientation)
menus = [...menus, customView ? 'resetView' : 'setView']
// customView ? 'resetView' : 'setView'
menus = [...menus, 'resetView', 'setView']
}
// console.log('menus', menus)
if (menus.length == 0) {

View File

@ -25,7 +25,11 @@ const eventBus: any = inject('bus')
const props = defineProps(['eventList', 'hr', 'originHrOffset', 'scrollLeft'])
let clickEventBar = (event) => {
console.log("点击事件块", selectedEventId.value, event)
let entity = window['_entityMap'].get(event.sourceId)
let key = event.sourceId
/* if (event.callback == 'move')
key = event.id + "move" + event.sourceId*/
// console.log(key)
let entity = window['_entityMap'].get(key)
entity && entity.flyTo()
selectedEventId.value = (selectedEventId.value == null || selectedEventId.value != event.id) ? event.id : null
eventBus.emit('click-event-show-plane', selectedEventId.value ? event : null)

View File

@ -110,13 +110,27 @@ const updateEvent = () => {
let durationS = eventObj.value.duration_time
// console.log("eventObj.value", eventObj.value)
// console.log("eventObj.value", durationS)
// 数据是否合法有效
let isRight = true
let errorFields:any = []//数据错误的字段
if (!durationS)
durationS = (eventObj.value.endTime - eventObj.value.startTime) / 1000
switch (eventObj.value.callback) {
case "flicker":
detail.value.times = Number((durationS / detail.value.numbers).toFixed(2))
if (Number(obj.numbers) == 0 || !Number(obj.numbers)) {
isRight = false
errorFields.push("闪烁次数")
}
if (isRight) {
detail.value.times = Number((durationS / detail.value.numbers).toFixed(2))
}
break
}
if (!isRight) {
let eventType = eventObj.value.name.split("-")[0] + "事件"
ElMessage({message: eventType + errorFields.join("、") + "数据不合法", type: "warning"})
return
}
obj.detail = JSON.stringify(detail.value)
console.log(obj)
delete obj.createdAt
@ -127,12 +141,13 @@ const updateEvent = () => {
if (res.code == 200) {
eventBus.emit('update-event', obj)
ElMessage({type: "success", message: "操作成功"})
cancel()
cancel(false)
}
})
}
const cancel = () => {
const cancel = (cancel = true) => {
if (cancel)
revert()
eventObj.value = null
detail.value = {}
eventBus.emit('click-cancel-hide-plane',)
@ -140,6 +155,13 @@ const cancel = () => {
eventBus.on('delete-event', () => {
cancel()
})
const revert = () => {
let entity = window['_entityMap'].get(eventObj.value.id + "move" + eventObj.value.sourceId)
console.log(eventObj.value)
let detail = JSON.parse(eventObj.value.detail)
entity.lineShow = detail.line.show
entity.smooth = detail.line.smooth
}
</script>
<style lang="scss" scoped>

View File

@ -32,7 +32,6 @@
import {$changeComponentPop} from '@/utils/communication'
import {throttle} from '@/utils/index'
import {ElMessage, FormInstance} from 'element-plus'
import {TreeApi} from '@/api/tree'
import {useTreeNode} from '@/views/components/tree/hooks/treeNode'
import {addMapSource} from "../entity";
import {useI18n} from 'vue-i18n'
@ -51,7 +50,7 @@ const removeSpaces = (value: string) => {
form.sourceName = value.replace(/\s/g, '')
}
const close = () => {
$changeComponentPop('.adddirectory', false)
$changeComponentPop('.tsdirectory', false)
}
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
@ -75,66 +74,8 @@ const add = throttle(async () => {
cancel()
}
})
/* const res: any = await TreeApi.addDirectory({
id: new YJ.Tools().randomString(),
sourceName: form.sourceName,
parentId: parentId || undefined
})
console.log(res)
if (res.code == 0 || res.code == 200) {
const node = {
...res.data
}
let addNode = await cusAddNodes(window.treeObj, getSelectedNode(window.treeObj), [node], true) //添加节点
//获取该节点下的同级节点
const someNode: any = getSameLevel(window.treeObj, addNode[0])
console.log('someNode', someNode)
const newNode = someNode.map((item: any) => {
let index = item.getIndex()
item.treeIndex = index + 1
return {
...item,
treeIndex: item.getIndex()
}
})
ElMessage({
message: '添加成功',
type: 'success'
})
cancel()
} else {
ElMessage({
message: '添加失败',
type: 'error'
})
}*/
// console.log(res)
}, 3000)
////上传或修改树的层级
// const updateTree = async (newNode: any) => {
// const list = newNode.map((item: any) => {
// return {
// id: item.id,
// treeIndex: item.treeIndex,
// parentId: item.parentId
// }
// })
// console.log(list)
// const res = await TreeApi.updateTree({ list })
// if (res.code == 0) {
// ElMessage({
// message: '添加成功',
// type: 'success'
// })
// cancel()
// } else {
// ElMessage({
// message: '添加失败',
// type: 'error'
// })
// }
// }
}, 3000)
const cancel = () => {
$changeComponentPop('.tsdirectory', false)

View File

@ -191,6 +191,11 @@ let formatTime = (timeStamp) => {
return props.TSOBJ.parseTime(timeStamp)
}
let play = () => {
if (props.TSOBJ._Store._currentTimestamp >= props.TSOBJ._Store.getTotalTime()) {
ElMessage.warning("到达推演终点")
return
}
props.TSOBJ._Clock._status = "play"
console.log(props.TSOBJ._Clock._status)
// return

View File

@ -171,6 +171,8 @@
<deduction :TSOBJ="tsOBJ"></deduction>
<newEvent></newEvent>
<addDirectory class="adddirectoryBox absolute zIndex999"></addDirectory>
<directoryTs ref="editDirectoryTsBox" class="editDirectoryTsBox absolute zIndex999"></directoryTs>
<mouseRight></mouseRight>
<component :is="currentComponent" ref="dynamicComponentRef"/>
<!-- 方案描述编辑框 -->
@ -319,11 +321,13 @@ import {ElMessage} from "element-plus";
import {addMapSource} from "../../common/addMapSource";
import {$changeComponentShow} from "../../utils/communication";
import {useI18n} from "vue-i18n";
import directoryTs from "./edit/directoryTs.vue";
import billboardObject from "./edit/billboardObjectTs.vue";
import polylineObject from "./edit/polylineObjectTs.vue";
import polygonObject from "./edit/polygonObjectTs.vue";
const {t} = useI18n()
let editDirectoryTsBox = ref()
const planInfo = ref({})
const isShowPup = ref(false)
const showStandText = ref(false)
@ -403,6 +407,10 @@ let submit = () => {
})
}
let submitStandText = (flag) => {
if (standText.value.trim() == '' && flag) {
ElMessage.warning("内容不能为空")
return
}
showStandText.value = false
/* let res = {
currentDrawItem: currentDrawItem.value,
@ -565,6 +573,10 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
dynamicComponentRef.value.close()
}
switch (sourceType) {
case 'directory':
console.log(editDirectoryTsBox.value)
editDirectoryTsBox.value.open()
break
case 'point':
currentComponent.value = billboardObject
await nextTick()
@ -744,7 +756,7 @@ eventBus.on('destroyComponent', (id) => {
cursor: pointer;
}
.adddirectoryBox {
.adddirectoryBox, .editDirectoryTsBox {
display: none;
}
}

View File

@ -0,0 +1,228 @@
<template>
<div class="directoryTs">
<div class="box">
<div class="boxHeader nav">
<!-- <span></span> -->
<span class="label">{{ title }}</span>
<div class="close-box" @click="close">
<span class="close"></span>
<i>x</i>
</div>
</div>
<div class="boxBody">
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px"
@keyup.enter.native="submitForm(ruleForm)" @submit.native.prevent>
<el-form-item label="名称:" prop="sourceName">
<!-- @input="removeSpaces" -->
<el-input v-model.trim="form.sourceName" placeholder="节点名称"></el-input>
</el-form-item>
<el-form-item>
<div class="btnOption">
<el-button type="primary" @click="submitForm(ruleForm)">确定</el-button>
<el-button @click="close">取消</el-button>
</div>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {inject, ref} from "vue";
import {$changeComponentPop} from "../../../utils/communication";
import {FormInstance} from "element-plus";
import {throttle} from '@/utils/index'
import {useTreeNode} from "../../components/tree/hooks/treeNode";
import {TsApi} from "../../../api/ts";
const {getSelectedNodes, cusSelectNode, getSameLevel, cusNodeIcon, nodeType, cusUpdateNode} = useTreeNode()
const title = ref('编辑节点')
const eventBus: any = inject('bus')
const baseDialog: any = ref(null)
const sourceId = ref('')
let form: any = reactive({
sourceName: ''
})
const ruleForm = ref()
const rules = reactive({
sourceName: [{required: true, message: '请输入名称', trigger: 'blur'}]
})
const close = () => {
$changeComponentPop('.editDirectoryTsBox', false)
setTimeout(() => {
sourceId.value = ''
form.sourceName = ''
ruleForm.value?.resetFields()
}, 200);
}
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
add()
} else {
console.log('error submit!', fields)
}
})
}
const add = throttle(async () => {
const res: any = await TsApi.updateTsSource({
id: sourceId.value,
sourceName: form.sourceName
})
cusUpdateNode({id: sourceId.value, sourceName: form.sourceName, params: undefined})
close()
console.log(res, form.sourceName)
}, 3000)
const open = () => {
console.log("文件夹编辑框")
let selectNodes = getSelectedNodes(window.treeObj);
if (selectNodes && selectNodes[selectNodes.length - 1]) {
sourceId.value = selectNodes[selectNodes.length - 1].id
form.sourceName = selectNodes[selectNodes.length - 1].sourceName
$changeComponentPop('.editDirectoryTsBox', true)
}
}
const closeCallback = () => {
/* entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
that.reset()*/
eventBus?.emit('destroyComponent')
}
defineExpose({
open,
})
</script>
<style lang="scss" scoped>
.directoryTs {
user-select: none;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
.box {
width: 20vw;
height: 10vw;
display: flex;
flex-direction: column;
position: absolute;
left: 50%;
top: 45%;
transform: translate(-50%, -50%);
color: var(--color-sdk-auxiliary-public);
font-size: 14px;
// z-index: 999999;
background: linear-gradient(0deg, var(--color-sdk-bg-gradual)), rgba(0, 0, 0, 0.6);
border: 1.5px solid;
backdrop-filter: blur(2px);
border-image: linear-gradient(to bottom, var(--color-sdk-gradual)) 1;
text-align: left;
font-family: 'sy-boldface';
.boxHeader {
display: flex;
justify-content: space-between;
font-size: 18px;
line-height: 46px;
padding: 5px 16px 5px 16px;
height: 46px;
.label {
font-family: 'Ali-mother-counts-bold';
font-size: 18px;
font-weight: 400;
color: rgba(255, 255, 255, 1);
text-align: left;
text-shadow: 0px 0px 9px rgb(20 118 255);
}
.close-box {
position: absolute;
top: -1px;
right: 0;
height: 30px;
cursor: pointer;
width: 30px;
border-radius: 0 0 0 90%;
overflow: hidden;
.close {
display: block;
width: 100%;
height: 100%;
background: rgba(var(--color-base1), 1);
opacity: 0.5;
}
i {
font-style: normal;
font-size: 18px;
font-weight: 900;
position: absolute;
top: -13px;
left: 11px;
}
}
}
.boxBody {
flex: auto;
flex-direction: column;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 20px;
.el-form--label-top .el-form-item__label {
padding: 0;
}
.el-form-item {
margin-bottom: 10px;
}
:deep(.el-form-item__label) {
color: #fff;
}
.el-input__wrapper {
background-color: rgba(0, 0, 0, 0.5);
border: 0.2px solid rgba(var(--color-base1), 0.5);
box-shadow: 0 0 0 0.2px rgba(var(--color-base1), 0.5) inset !important;
/* 新增此行 */
}
.el-input__inner {
background-color: transparent;
color: #fff;
// border-color: rgba(var(--color-base1), 0.5) !important;
}
.btnOption {
margin-top: 5px;
text-align: right;
}
.el-button {
background: rgba(var(--color-base1), 0.2);
border-color: rgba(var(--color-base1), 0.5) !important;
color: #ffffff;
padding: 8px 16px;
}
.el-button:hover {
border-color: rgba(var(--color-base1), 1) !important;
}
}
}
}
</style>

View File

@ -217,13 +217,23 @@ const lists = ref([])
const elementList = ref([])
let input2 = ref('')
watch(input2, (val) => {
console.log("activIndex", activIndex.value)
console.log("input2", val)
console.log("lists", lists)
console.log("lists", lists.value.filter(item => item.name.includes(val)))
if (val == '') {
handleTabClick(tabs[activIndex.value], activIndex.value)
if (dataType.value == 'tree') {
if (activIndex.value == 0) {
getModelTypeList(input2.value)
} else if (activIndex.value == 1) {
getGraphTypeList(input2.value)
}
} else {
lists.value = lists.value.filter(item => item.name.includes(val))
if (val == '') {
handleTabClick(tabs[activIndex.value], activIndex.value)
} else {
lists.value = lists.value.filter(item => item.name.includes(val))
}
}
treeRef.value && treeRef.value!.filter(val)
})
@ -240,6 +250,7 @@ const filterNode = (value: string, data: Tree) => {
const handleTabClick = (item, index) => {
activIndex.value = index
currentTypeId.value = ""
input2.value = ""
elementList.value = []
console.log(item)
@ -290,14 +301,21 @@ const getModelListByType = (id) => {
}
}
// 获取模型类型列表
let getModelTypeList = async () => {
let res = await ModelApi.modelTypeList()
let getModelTypeList = async (modelName = null) => {
let Obj = {modelName}
if (modelName == null)
delete Obj.modelName
let res = await ModelApi.modelTypeList(Obj)
if (res.code == 200) {
modelTypes.value = res.data
treeData.value = modelTypes.value
}
}
let getGraphTypeList = async () => {
let res = await GraphApi.modelTypeList()
let getGraphTypeList = async (militaryName = null) => {
let Obj = {militaryName}
if (militaryName == null)
delete Obj.militaryName
let res = await GraphApi.modelTypeList(Obj)
if (res.code == 200) {
graphTypes.value = res.data
}
@ -339,6 +357,13 @@ let addMarker = (item, needSendEvent = true) => {
window.draw.start((a, position) => {
console.log(position)
if (position != undefined) {
if (position.length == 0 && item.type == "standText") {
item.source_name = ""
return;
}
if (position.length < 2 && item.type == "waterL") {
return;
}
let obj = {id, name: item.source_name, position}
switch (item.type) {
case 'model':
@ -385,10 +410,8 @@ let addMarker = (item, needSendEvent = true) => {
if (item.type == "standText") {
item.source_name = ""
}
}
})
}

View File

@ -219,8 +219,12 @@ const handleNodeClick = (data: Tree, node, TreeNode, event) => {
form.name = data.name + '-' + zNode.value.sourceName
}
const drawLine = () => {
$(".newEvent")[0].style.display = "none"
let draw = new YJ.Draw.DrawPolyline(window['earth_ts'])
draw.start((error, p) => {
if (p != undefined) {
$(".newEvent")[0].style.display = "block"
}
positions.value = p
})
}
@ -344,6 +348,7 @@ const reset = (changeEventType = false) => {
numbers.value = 0
times.value = 1
form.name = '闪烁-'
positions.value = []
// datetime: '',
form['datetime'] = new Date(window['tsObj']._Store._currentTimestamp)

View File

@ -37,7 +37,8 @@ export class Clock {
nowTime = now
// 设置时间指示器位置
store.setCursorLeft(store._currentTimestamp)
if (store._currentTimestamp >= store.getTotalTime()) {
if (store._currentTimestamp > store.getTotalTime()) {
eventCallback()
this.stopAnimation()
this._status = "stop"
}

View File

@ -62,6 +62,7 @@ export class TS extends Tools {
const value = l.num
// 第几个大格,小标-=1
this.setWheel(value)
this._Store.setCursorLeft(this._Store._currentTimestamp)
break;
case "scroll-chart":
this._Store._scales.scrollTop = obj.top

View File

@ -502,6 +502,7 @@ const addModelDB = (path) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('导入成功')
modelList.value = []
currModelList.value = []
getModelList()
}
})
@ -668,7 +669,9 @@ const toggleExpand = (row: any) => {
// loadModelsByType(row.id)
contextMenu.visible && (contextMenu.visible = false)
}
let clickTypeId = null //存储点击数据,用来删除时更新右侧列表
const getModelListByType = (id) => {
clickTypeId = id
let formData = new FormData()
formData.append('militaryTypeId', id)
formData.append('name', photoName.value)
@ -835,6 +838,10 @@ const handleDeleteType = (row: TypeNode) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('删除成功')
getModelList()
if (row.id === clickTypeId) {
modelList.value = []
currModelList.value = []
}
}
})
})

View File

@ -183,6 +183,7 @@ import type { DragEvents } from 'element-plus/es/components/tree/src/model/useDr
import type { AllowDropType, NodeDropType, RenderContentContext } from 'element-plus'
import { ModelApi } from '@/api/model/index'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
$sendElectronChanel,
$recvElectronChanel,
@ -551,6 +552,7 @@ const addModelDB = (path) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('导入成功')
modelList.value = []
currModelList.value = []
getModelList()
}
})
@ -889,6 +891,7 @@ const handleDeleteType = (row: TypeNode) => {
//如果删除当前选中数据 清空右侧列表
if (row.id === clickTypeId) {
modelList.value = []
currModelList.value = []
}
}
})

View File

@ -592,6 +592,8 @@ const addModelDB = (path) => {
PhotoApi.importModelDB(formData).then((res) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('导入成功')
modelList.value = []
currModelList.value = []
getModelList()
}
})
@ -760,12 +762,14 @@ const toggleExpand = (row: any) => {
// loadModelsByType(row.id)
contextMenu.visible && (contextMenu.visible = false)
}
let clickTypeId = null //存储点击数据,用来删除时更新右侧列表
const getModelListByType = async (id) => {
if (activeIndex.value === 0) {
modelList.value = threePhoto
} else if (activeIndex.value === 1) {
modelList.value = ordinaryPhoto
} else {
clickTypeId = id
let formData = new FormData()
formData.append('iconTypeId', id)
formData.append('name', photoName.value)
@ -924,6 +928,10 @@ const handleDeleteType = (row: TypeNode) => {
PhotoApi.delModelType(formData).then((res) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('删除成功')
if (row.id === clickTypeId) {
currModelList.value = []
modelList.value = []
}
getModelList()
}
})

View File

@ -140,10 +140,10 @@
<script setup lang="ts">
//@ts-nocheck
import {ref, reactive, onBeforeUnmount} from 'vue'
import {inject} from 'vue'
import { ref, reactive, onBeforeUnmount } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import {RouteApi} from '@/api/route/index'
import { RouteApi } from '@/api/route/index'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
@ -223,7 +223,7 @@ const open = () => {
//加载路网数据
const addRoute = async (fileId) => {
let res = await RouteApi.loadRoute({fileId})
let res = await RouteApi.loadRoute({ fileId })
}
const getList = async () => {
let list = await RouteApi.getRouteList()
@ -238,6 +238,7 @@ const closeCallBack = (e) => {
startLat.value = null
endLng.value = null
endLat.value = null
routePlanning.destroyMouse()
}
onBeforeUnmount(() => {
closeCallBack('')
@ -251,8 +252,7 @@ const routeQuery = async (e) => {
waypoints: []
})
}
const clearRoute = (e) => {
}
const clearRoute = (e) => {}
const pickStartPos = () => {
routePlanning.pickStartPos((position) => {
startLng.value = position.lng

View File

@ -45,6 +45,7 @@
max="100"
min="0"
step="0.01"
disabled
v-model="progressVal"
/>
</div>
@ -101,6 +102,7 @@ const closeCallBack = (e) => {
progressVal.value = 0
scale.value = 1
modify.value = false
eventBus.emit('closeScreenShot', false)
}
onBeforeUnmount(() => {
closeCallBack('')
@ -124,8 +126,10 @@ const getResultData = (data) => {
// eventBus.emit('mapPrintDialog')
}
}
const name = 'ScreenShotHD'
defineExpose({
open
open,
name
})
</script>

View File

@ -63,9 +63,12 @@ let func = (data) => {
rowData.name = data.modelName
baseDialog.value?.open()
setTimeout(() => {
initThreeJS()
loadModel()
animate()
// initThreeJS()
// loadModel()
// animate()
(window as any).viewGlb = new viewGlbByEarth('threeCanvas');
console.log(service.value + rowData.modelDataUrl, 'cccccc');
(window as any).viewGlb.addGltf(service.value + rowData.modelDataUrl);
})
}
onMounted(() => {
@ -197,7 +200,7 @@ const viewPointHeightInput = () => {
}
}
const closeCallBack = (e) => {
renderer.domElement.remove() // 从DOM中移除渲染器。
renderer?.domElement.remove() // 从DOM中移除渲染器。
imageData.value = null
rowData = []
//打开系统设置弹框
@ -206,25 +209,19 @@ const closeCallBack = (e) => {
var posterLoading: any = ref(false)
const setImage = (e) => {
renderer.render(scene, camera) // 确保场景已渲染
const canvas = renderer.domElement
canvas.toBlob((blob) => {
const file = new File([blob], 'filename.png', { type: 'image/png' })
imageData.value = file
(window as any).viewGlb.canvasToBase((file) => {
console.log(file, 'file')
const formData = new FormData()
formData.append('modelId', rowData.id)
// rowData.name && formData.append('modelName', rowData.name)
imageData.value && formData.append('file', imageData.value)
file && formData.append('file', file)
ModelApi.updatePoster(formData).then((res) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('设置成功')
}
})
});
// ElMessage.warning('设置成功')
}, 'image/png')
// })
// const formData = new FormData()
// formData.append('modelId', rowData.id)

View File

@ -1,137 +1,132 @@
import * as THREE from "three";
import * as THREE from 'three'
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
//导入GLTF模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
class viewGlb {
constructor(selector) {
this.canvasWidth = 900;
this.canvasHeight = 650;
this.container = document.querySelector(selector); //获取容器
this.modelInfo = {};
this.scene = null;
this.camera = null;
this.renderer = null;
this.controls = null;
this.init(); //初始化
this.animate(); //循环函数
this.canvasWidth = 900
this.canvasHeight = 650
this.container = document.querySelector(selector) //获取容器
this.modelInfo = {}
this.scene = null
this.camera = null
this.renderer = null
this.controls = null
this.init() //初始化
this.animate() //循环函数
}
init() {
// 初始化场景
this.initScene();
this.initScene()
// 初始化辅助轴
this.initAxesHelper();
this.initAxesHelper()
// 初始化灯光
this.initLight();
this.initLight()
// 初始化相机
this.initCamera();
this.initCamera()
// 初始化渲染器
this.initRender();
this.initRender()
// 初始化轨道控制器
this.initControls();
this.initControls()
// 监听场景大小改变,重新渲染尺寸
window.addEventListener("resize", this.onWindowResize.bind(this));
window.addEventListener('resize', this.onWindowResize.bind(this))
// this.addGLTFModel()
}
initScene() {
this.scene = new THREE.Scene();
this.scene = new THREE.Scene()
// this.scene.background = new THREE.Color(0xffffff)
}
initAxesHelper() {
const axesHelper = new THREE.AxesHelper(5);
this.scene.add(axesHelper);
const axesHelper = new THREE.AxesHelper(5)
this.scene.add(axesHelper)
}
initLight() {
const hesLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hesLight.intensity = 0.6;
this.scene.add(hesLight);
const hesLight = new THREE.HemisphereLight(0xffffff, 0x444444)
hesLight.intensity = 0.6
this.scene.add(hesLight)
const dirLight = new THREE.DirectionalLight();
dirLight.position.set(5, 5, 5);
this.scene.add(dirLight);
const dirLight = new THREE.DirectionalLight()
dirLight.position.set(5, 5, 5)
this.scene.add(dirLight)
}
initCamera() {
this.camera = new THREE.PerspectiveCamera(
75,
this.canvasWidth / this.canvasHeight,
0.1,
100
);
this.camera = new THREE.PerspectiveCamera(75, this.canvasWidth / this.canvasHeight, 0.1, 100)
// this.camera.position.set(1.5, 1.5, 1.5)
this.camera.position.set(2, 2, 2);
this.camera.position.set(2, 2, 2)
}
initRender() {
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
alpha: true
// preserveDrawingBuffer: true
}); //设置抗锯齿
}) //设置抗锯齿
//设置屏幕像素比
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setPixelRatio(window.devicePixelRatio)
//渲染的尺寸大小
this.renderer.setSize(this.canvasWidth, this.canvasHeight);
this.renderer.setSize(this.canvasWidth, this.canvasHeight)
//gltf格式模型纹理贴图
this.renderer.outputEncoding = THREE.sRGBEncoding;
this.renderer.outputEncoding = THREE.sRGBEncoding
// 设置背景颜色
this.renderer.setClearColor(0x000000, 0);
this.renderer.setClearColor(0x000000, 0)
// 添加到容器
this.container.appendChild(this.renderer.domElement);
this.container.appendChild(this.renderer.domElement)
}
render() {
this.renderer.render(this.scene, this.camera);
this.renderer.render(this.scene, this.camera)
}
animate() {
this.renderer.setAnimationLoop(this.render.bind(this));
this.renderer.setAnimationLoop(this.render.bind(this))
}
initControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
}
onWindowResize() {
this.camera.aspect = this.canvasWidth / this.canvasHeight;
this.camera.updateProjectionMatrix(); //更新矩阵将3d内容投射到2d画面上转换
this.renderer.setSize(this.canvasWidth, this.canvasHeight);
this.camera.aspect = this.canvasWidth / this.canvasHeight
this.camera.updateProjectionMatrix() //更新矩阵将3d内容投射到2d画面上转换
this.renderer.setSize(this.canvasWidth, this.canvasHeight)
}
addGLTFModel(obj) {
this.modelInfo = obj;
this.modelInfo = obj
return new Promise((resolve, reject) => {
const loader = new GLTFLoader(); //.setPath('3dModels/')
const loader = new GLTFLoader() //.setPath('3dModels/')
loader.load(obj.model_url, (gltf) => {
console.log(gltf);
this.scene.add(gltf.scene);
resolve("模型添加成功");
});
});
console.log(gltf)
this.scene.add(gltf.scene)
resolve('模型添加成功')
})
})
}
canvasToBase(cb) {
this.renderer.render(this.scene, this.camera);
let imgData = this.renderer.domElement.toDataURL("image/png");
console.log(imgData);
let base64 = imgData.replace(/^data:image\/\w+;base64,/, "");
let dataBuffer = new Buffer(base64, "base64");
base64ToFile(base64, "image/png", "poster.png");
console.log(process.cwd());
$root_home_index.$sendElectronChanel("newDir", {
this.renderer.render(this.scene, this.camera)
let imgData = this.renderer.domElement.toDataURL('image/png')
console.log(imgData)
let base64 = imgData.replace(/^data:image\/\w+;base64,/, '')
let dataBuffer = new Buffer(base64, 'base64')
base64ToFile(base64, 'image/png', 'poster.png')
console.log(process.cwd())
$root_home_index.$sendElectronChanel('newDir', {
name: this.modelInfo.model_name,
paths: [process.cwd(), "model_thumb"],
buffer: dataBuffer,
});
$root_home_index.$recvElectronChanel("newDirRes", (e, res) => {
paths: [process.cwd(), 'model_thumb'],
buffer: dataBuffer
})
$root_home_index.$recvElectronChanel('newDirRes', (e, res) => {
// $root_home_index.$message.info(res)
cb(res);
});
cb(res)
})
/*;*/
}
@ -139,33 +134,33 @@ class viewGlb {
clearScene() {
this.scene.traverse((child) => {
if (child.material) {
child.material.dispose();
child.material.dispose()
}
if (child.geometry) {
child.geometry.dispose();
child.geometry.dispose()
}
child = null;
});
this.container.childNodes[1].remove();
this.renderer.forceContextLoss();
this.renderer.dispose();
this.scene.clear();
this.modelInfo = {};
this.scene = null;
this.camera = null;
this.controls = null;
this.renderer.domElement = null;
this.renderer = null;
this.container = null;
child = null
})
this.container.childNodes[1].remove()
this.renderer.forceContextLoss()
this.renderer.dispose()
this.scene.clear()
this.modelInfo = {}
this.scene = null
this.camera = null
this.controls = null
this.renderer.domElement = null
this.renderer = null
this.container = null
}
}
class viewGlbByEarth {
constructor(selector) {
this.viewer = null;
this.modelInfo = null;
this.selector = selector;
this.init(selector);
this.viewer = null
this.modelInfo = null
this.selector = selector
this.init(selector)
}
init(selector) {
@ -177,22 +172,24 @@ class viewGlbByEarth {
baseLayerPicker: false,
sceneModePicker: false,
animation: false,
});
const scene = this.viewer.scene;
fullscreenButton: false, // 禁用全屏按钮
geocoder: false
})
const scene = this.viewer.scene
/*this.viewer.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.PINCH,
Cesium.CameraEventType.RIGHT_DRAG,
]*/
scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
Cesium.CameraEventType.PINCH,
];
Cesium.CameraEventType.PINCH
]
scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.PINCH,
Cesium.CameraEventType.RIGHT_DRAG,
];
this.viewer._cesiumWidget._creditContainer.style.display = "none";
scene.globe.depthTestAgainstTerrain = true;
Cesium.CameraEventType.RIGHT_DRAG
]
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
scene.globe.depthTestAgainstTerrain = true
// scene.globe.show = false;
// scene.sun.show = false;
// scene.moon.show = false;
@ -201,46 +198,45 @@ class viewGlbByEarth {
}
addGltf(obj) {
this.modelInfo = obj;
this.modelInfo = obj
const czml = [
{
id: "aircraft model",
name: "Cesium Air",
id: 'aircraft model',
name: 'Cesium Air',
position: {
cartographicDegrees: [-77, 37, 10000],
cartographicDegrees: [-77, 37, 10000]
},
model: {
gltf: obj.model_url,
// gltf: obj.model_url,
gltf: obj,
scale: 2.0,
minimumPixelSize: 128,
},
},
];
minimumPixelSize: 128
}
}
]
let entity = this.viewer.entities.add({
position: Cesium.Cartesian3.fromRadians(
106.31593773128115,
29.625102082951624
),
position: Cesium.Cartesian3.fromRadians(106.31593773128115, 29.625102082951624),
model: {
uri: obj.model_url,
},
});
// uri: obj.model_url,
uri: obj
}
})
this.viewer.trackedEntity = entity;
this.viewer.trackedEntity = entity
}
canvasToBase(cb) {
// let imgData = $(`#${this.selector}`).find("canvas")[0].toDataURL("image/png");
// console.log(imgData)
this.viewer.render();
let imgData = this.viewer.scene.canvas.toDataURL("image/png");
let base64 = imgData.replace(/^data:image\/\w+;base64,/, "");
let dataBuffer = new Buffer(base64, "base64");
let file = this.base64ToFile(base64, "image/png", "poster.png");
this.viewer.render()
let imgData = this.viewer.scene.canvas.toDataURL('image/png')
let base64 = imgData.replace(/^data:image\/\w+;base64,/, '')
let dataBuffer = new Buffer(base64, 'base64')
let file = this.base64ToFile(base64, 'image/png', 'poster.png')
// console.log("ddddddddddddd", file);
cb(file);
cb(file)
// $root_home_index.$sendElectronChanel("newDir", {
// name: this.modelInfo.model_name, //+ "_" + new Date().getTime(),
// paths: [process.cwd(), "model_thumb"],
@ -255,25 +251,25 @@ class viewGlbByEarth {
}
base64ToFile(base64, mime, filename) {
// let arr = base64.split(",");
let type = mime || arr[0].match(/:(.*?);/)[1];
let type = mime || arr[0].match(/:(.*?);/)[1]
// let suffix = mine.split("/")[1];
// let fileName = filename || `未命名.${suffix}`;
let fileName = filename || `未命名.png`;
let bstr = atob(base64);
let n = bstr.length;
let u8arr = new Uint8Array(n);
let fileName = filename || `未命名.png`
let bstr = atob(base64)
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], fileName, { type });
return new File([u8arr], fileName, { type })
}
clearScene() {
this.viewer.destroy();
this.viewer = null;
this.modelInfo = null;
this.selector = "";
this.viewer.destroy()
this.viewer = null
this.modelInfo = null
this.selector = ''
}
}
export { viewGlb, viewGlbByEarth };
export { viewGlb, viewGlbByEarth }

View File

@ -1,3 +1,4 @@
// @ts-nocheck
import {$changeComponentShow} from '@/utils/communication'
import {useTreeNode} from './treeNode'
import {TreeApi} from '@/api/tree'

View File

@ -137,6 +137,7 @@ import { getdefaultLabelStyle } from '../components/propertyBox/defaultLabelStyl
import { setEventBus } from './eventBus'
import router from '@renderer/router'
import { ElMessage, ElMessageBox } from 'element-plus'
const { rightMenus } = useRightOperate()
const firstMenuRef = ref(null)
@ -162,8 +163,27 @@ if (!localStorage.getItem('defaultLabelStyle')) {
}
//移除天气设置
localStorage.removeItem('weartherSetting')
eventBus.on('closeScreenShot', () => {
if (currentComponent.value?.__name == 'ScreenShot') {
currentComponent.value = undefined
}
})
eventBus.on('openDialog', async (sourceType: any, id: any) => {
if (dynamicComponentRef.value?.name == 'ScreenShotHD') {
ElMessageBox.confirm('此操作将会打开新弹窗关闭高清截图功能, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
openOtherDialog(sourceType, id)
})
.catch(() => {})
} else {
openOtherDialog(sourceType, id)
}
})
const openOtherDialog = async (sourceType: any, id: any) => {
if (dynamicComponentRef.value && dynamicComponentRef.value.close) {
dynamicComponentRef.value.close()
}
@ -445,7 +465,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
break
}
id && dynamicComponentRef.value && (dynamicComponentRef.value.id = id)
})
}
eventBus.on('openSelectImg', (selected, entity) => {
// $sendElectronChanel("requireGEMarkerName", {
// dirName: "GEMarker",