态势模块添加gis模型,事件列表获取
This commit is contained in:
Binary file not shown.
@ -26,10 +26,24 @@ export const TsApi = {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
///tsSource/addModelSource
|
||||||
|
addTsModelSource: async (data: any) => {
|
||||||
|
return await request.post({
|
||||||
|
url: '/tsSource/addTsModelSource',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
},
|
||||||
queryTsSource: async (data: any) => {
|
queryTsSource: async (data: any) => {
|
||||||
return await request.post({
|
return await request.post({
|
||||||
url: '/tsSource/query',
|
url: '/tsSource/query',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// /tsEvent/query
|
||||||
|
queryTsEvent: async (data: any) => {
|
||||||
|
return await request.get({
|
||||||
|
url: "/tsEvent/query",
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,12 +20,14 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {computed, onMounted, ref} from "vue"
|
import {computed, onMounted, ref} from "vue"
|
||||||
|
|
||||||
|
const props = defineProps(['eventList',])
|
||||||
|
|
||||||
let columns = ref([{name: '事件名称', key: "name", style: "flex:auto"},
|
let columns = ref([{name: '事件名称', key: "name", style: "flex:auto"},
|
||||||
{name: '开始时间', key: "start_time", style: "width:120px"},
|
{name: '开始时间', key: "start_time", style: "width:120px"},
|
||||||
{name: '持续时间', key: "duration_time", style: "width:70px"}])
|
{name: '持续时间', key: "duration_time", style: "width:70px"}])
|
||||||
let eventList = ref([])
|
// let eventList = ref([])
|
||||||
let style = ref({})
|
let style = ref({})
|
||||||
eventList.value = window['tsObj']._Store._tasks
|
// eventList.value = window['tsObj']._Store._tasks
|
||||||
// 格式化时间
|
// 格式化时间
|
||||||
let format = (key, val) => {
|
let format = (key, val) => {
|
||||||
if ('start_time' == key) {
|
if ('start_time' == key) {
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import {useI18n} from 'vue-i18n'
|
|||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import {useRightOperate} from "./rightOperate";
|
import {useRightOperate} from "./rightOperate";
|
||||||
import {useRightMenu} from "../../components/tree/components/hooks/rightMenu";
|
import {useRightMenu} from "../../components/tree/components/hooks/rightMenu";
|
||||||
|
import {$changeComponentShow} from "../../../utils/communication";
|
||||||
|
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
const {rightMenus} = useRightOperate()
|
const {rightMenus} = useRightOperate()
|
||||||
@ -40,6 +41,8 @@ const {itemClick} = useRightMenu()
|
|||||||
const eventBus: any = inject('bus')
|
const eventBus: any = inject('bus')
|
||||||
const itemClicks = (item) => {
|
const itemClicks = (item) => {
|
||||||
itemClick(item, eventBus)
|
itemClick(item, eventBus)
|
||||||
|
$changeComponentShow('.rightMenuTs', false)
|
||||||
|
|
||||||
}
|
}
|
||||||
const initMenus = (arr: any, treeNode: any) => {
|
const initMenus = (arr: any, treeNode: any) => {
|
||||||
let rightMenu: any = []
|
let rightMenu: any = []
|
||||||
@ -70,8 +73,11 @@ defineExpose({
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
width: 8.5vw;
|
width: 8.5vw;
|
||||||
height: 23vh;
|
height: 23vh;
|
||||||
border: 1px solid red;
|
//border: 1px solid red;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
border: 1.5px solid;
|
||||||
|
border-image: linear-gradient(137.95deg, rgba(var(--color-base1), 1) 6.25%, var(--color-border1) 100%) 1.5;
|
||||||
|
|
||||||
.menuItem {
|
.menuItem {
|
||||||
//padding: 1vh .5vw;
|
//padding: 1vh .5vw;
|
||||||
|
|||||||
@ -1,5 +1,31 @@
|
|||||||
import {$changeComponentPop} from "../../../utils/communication";
|
import {$changeComponentPop} from "../../../utils/communication";
|
||||||
|
import {ipcRenderer} from "electron";
|
||||||
|
import {addMapSource, initMapData} from "../entity";
|
||||||
|
import {TsApi} from "../../../api/ts";
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
import {useTreeNode} from "../../components/tree/hooks/treeNode";
|
||||||
|
|
||||||
|
const {cusAddNodes} = useTreeNode()
|
||||||
|
|
||||||
|
function getLastPathComponent(path, extensionsToRemove = []) {
|
||||||
|
// 处理路径分隔符
|
||||||
|
const normalizedPath = path.replace(/\\/g, '/');
|
||||||
|
const lastComponent = normalizedPath.split('/').pop();
|
||||||
|
|
||||||
|
// 如果没有提供需要移除的后缀列表,直接返回原始名称
|
||||||
|
if (extensionsToRemove.length === 0) return lastComponent;
|
||||||
|
|
||||||
|
// 检查是否匹配任何需要移除的后缀
|
||||||
|
for (const ext of extensionsToRemove) {
|
||||||
|
//@ts-ignore
|
||||||
|
const extWithDot = ext.startsWith('.') ? ext : `.${ext}`;
|
||||||
|
if (lastComponent.endsWith(extWithDot)) {
|
||||||
|
return lastComponent.slice(0, -extWithDot.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastComponent;
|
||||||
|
}
|
||||||
|
|
||||||
export const useRightOperate = () => {
|
export const useRightOperate = () => {
|
||||||
const addDirectory = () => {
|
const addDirectory = () => {
|
||||||
@ -8,6 +34,110 @@ export const useRightOperate = () => {
|
|||||||
}
|
}
|
||||||
const addResource = () => {
|
const addResource = () => {
|
||||||
console.log("addResource")
|
console.log("addResource")
|
||||||
|
const {ipcRenderer} = require('electron')
|
||||||
|
const options = {
|
||||||
|
properties: ['openFile'], // 允许选择多个文件
|
||||||
|
filters: [
|
||||||
|
{name: '模型、影像、地形', extensions: ['clt', 'mbtiles', 'pak', /*'json', 'jct'*/]},
|
||||||
|
// {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);
|
||||||
|
// @ts-ignore
|
||||||
|
ipcRenderer.once('selectedItem', async (event, filePaths) => {
|
||||||
|
console.log(filePaths)
|
||||||
|
if (filePaths.length) {
|
||||||
|
let id = new YJ.Tools().randomString()
|
||||||
|
// 检查文件名是否有效
|
||||||
|
if (typeof filePaths[0] !== 'string' || filePaths[0].trim() === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let item = filePaths[0]
|
||||||
|
// @ts-ignore
|
||||||
|
let name = getLastPathComponent(item, ['clt', 'json', 'pak', 'kml', 'kmz', 'shp', 'geojson', 'geoJson', 'czml', 'jct', 'mif', 'tab', 'csv']);
|
||||||
|
let sourceType = "layer";
|
||||||
|
if (item.endsWith(".clt") || item.endsWith(".json")) {
|
||||||
|
sourceType = "tileset";
|
||||||
|
} else if (item.endsWith(".pak")) {
|
||||||
|
sourceType = "Terrain";
|
||||||
|
} else if (item.endsWith(".kml") || item.endsWith(".kmz")) {
|
||||||
|
sourceType = "kml";
|
||||||
|
} else if (item.endsWith(".shp")) {
|
||||||
|
sourceType = "shp";
|
||||||
|
} else if (item.endsWith(".geojson") || item.endsWith(".geoJson")) {
|
||||||
|
sourceType = "geojson";
|
||||||
|
} else if (item.endsWith(".czml")) {
|
||||||
|
sourceType = "czml";
|
||||||
|
} else if (item.endsWith(".jct")) {
|
||||||
|
sourceType = "bim";
|
||||||
|
} else if (item.endsWith(".mif")) {
|
||||||
|
sourceType = "shp";
|
||||||
|
} else if (item.endsWith(".tab")) {
|
||||||
|
sourceType = "shp";
|
||||||
|
} else if (item.endsWith(".csv")) {
|
||||||
|
sourceType = "csv";
|
||||||
|
}
|
||||||
|
// 获取最后一个点的位置
|
||||||
|
const lastDotIndex = filePaths[0].lastIndexOf('.');
|
||||||
|
|
||||||
|
// 如果没有点或者点是最后一个字符,则不是有效的文件后缀
|
||||||
|
if (lastDotIndex === -1 || lastDotIndex === filePaths[0].length - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let params2: any = {
|
||||||
|
id: id,
|
||||||
|
show: true,
|
||||||
|
}
|
||||||
|
if (item.endsWith(".mbtiles")) {
|
||||||
|
params2.alpha = 1
|
||||||
|
params2.brightness = 1
|
||||||
|
params2.layerIndex = 99999
|
||||||
|
}
|
||||||
|
let params: any = {
|
||||||
|
id: id,
|
||||||
|
sourcePath: filePaths[0],
|
||||||
|
parentId: parentId,
|
||||||
|
params: params2,
|
||||||
|
planId: window['planId']
|
||||||
|
}
|
||||||
|
// addMapSource(sourceType, parentId, params)
|
||||||
|
// 先调接口再渲染并上树
|
||||||
|
let res = await TsApi.addTsModelSource(params)
|
||||||
|
console.log('res', res)
|
||||||
|
if (res.code === 0 || res.code === 200) {
|
||||||
|
ElMessage({
|
||||||
|
message: '添加成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
res.data.params = JSON.parse(res.data.params)
|
||||||
|
if (!res.data.params.name) {
|
||||||
|
res.data.params.name = res.data.sourceName
|
||||||
|
}
|
||||||
|
if (!res.data.params.id) {
|
||||||
|
res.data.params.id = res.data.id
|
||||||
|
}
|
||||||
|
let detail = JSON.parse(res.data.detail)
|
||||||
|
let mapParams = {...detail, ...res.data.params}
|
||||||
|
initMapData(sourceType, mapParams, entity => {
|
||||||
|
entity.flyTo()
|
||||||
|
|
||||||
|
let selectedNode = window.treeObj.getNodeByParam('id', parentId)
|
||||||
|
//
|
||||||
|
cusAddNodes(window.treeObj, selectedNode, [res.data], true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const addEvent = (eventBus) => {
|
const addEvent = (eventBus) => {
|
||||||
eventBus.emit('openAddEvent', true)
|
eventBus.emit('openAddEvent', true)
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
<div class="layoutBoxs">
|
<div class="layoutBoxs">
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<!-- 左侧事件列表 -->
|
<!-- 左侧事件列表 -->
|
||||||
<grid></grid>
|
<grid :eventList="TSOBJ._Store._tasks"></grid>
|
||||||
<!--右侧时间轴容器-->
|
<!--右侧时间轴容器-->
|
||||||
<div class="TLContainer">
|
<div class="TLContainer">
|
||||||
<div class="timelineCursorBox" :style="{ left: `${cursorLeft || 0}px` }">
|
<div class="timelineCursorBox" :style="{ left: `${cursorLeft || 0}px` }">
|
||||||
|
|||||||
@ -22,9 +22,10 @@ import Deduction from "./deduction.vue";
|
|||||||
import AddDirectory from './components/tsdirectory.vue'
|
import AddDirectory from './components/tsdirectory.vue'
|
||||||
import {TS} from "./sdk";
|
import {TS} from "./sdk";
|
||||||
import * as domain from "domain";
|
import * as domain from "domain";
|
||||||
|
import {TsApi} from "../../api/ts";
|
||||||
|
|
||||||
let cabin = ref()
|
let cabin = ref()
|
||||||
let tsOBJ = reactive({})
|
let tsOBJ = ref({})
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
let params = {}
|
let params = {}
|
||||||
@ -52,13 +53,19 @@ let getEventList = () => {
|
|||||||
duration_time: (i * 5 + 10)
|
duration_time: (i * 5 + 10)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
let formData = {planId: window['planId']}
|
||||||
|
TsApi.queryTsEvent(formData).then(res => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
tsOBJ.value._Store._tasks = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
newTS(params, events)
|
newTS(params, events)
|
||||||
}
|
}
|
||||||
// 新建态势推演对象
|
// 新建态势推演对象
|
||||||
let newTS = (params, events) => {
|
let newTS = (params, events) => {
|
||||||
|
|
||||||
window['tsObj'] = new TS({name: params.name, tasks: events, startTimestamp: params.start_time})
|
window['tsObj'] = new TS({name: params.name, tasks: events, startTimestamp: params.start_time})
|
||||||
tsOBJ = window['tsObj']
|
tsOBJ.value = window['tsObj']
|
||||||
window['tsAction'] = window['tsObj'].initAction()
|
window['tsAction'] = window['tsObj'].initAction()
|
||||||
|
|
||||||
console.log("window['tsObj']", window['tsObj'])
|
console.log("window['tsObj']", window['tsObj'])
|
||||||
|
|||||||
@ -3,7 +3,9 @@ import {useTreeNode} from '@/views/components/tree/hooks/treeNode'
|
|||||||
|
|
||||||
const {cusAddNodes, getSelectedNode} = useTreeNode()
|
const {cusAddNodes, getSelectedNode} = useTreeNode()
|
||||||
|
|
||||||
export function initMapData(type, data) {
|
export function initMapData(type, data, cb: any = null) {
|
||||||
|
console.log("initMapData", type, data)
|
||||||
|
let baseURL = localStorage.getItem('ip')
|
||||||
let options
|
let options
|
||||||
let entityObject
|
let entityObject
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -27,6 +29,14 @@ export function initMapData(type, data) {
|
|||||||
break
|
break
|
||||||
case 'pincerArrow':
|
case 'pincerArrow':
|
||||||
entityObject = new YJ.Obj.PincerArrowObject(window['earth_ts'], data)
|
entityObject = new YJ.Obj.PincerArrowObject(window['earth_ts'], data)
|
||||||
|
break
|
||||||
|
case 'tileset':
|
||||||
|
data.host = baseURL
|
||||||
|
entityObject = new YJ.Obj.Tileset(window['earth_ts'], data)
|
||||||
|
entityObject.load((res) => {
|
||||||
|
cb && cb(entityObject)
|
||||||
|
})
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (entityObject) {
|
if (entityObject) {
|
||||||
@ -48,7 +58,7 @@ export function initMapData(type, data) {
|
|||||||
export function addMapSource(type, pId, option, cb: any = null) {
|
export function addMapSource(type, pId, option, cb: any = null) {
|
||||||
console.log("添加到地球上", option)
|
console.log("添加到地球上", option)
|
||||||
let options
|
let options
|
||||||
let baseURL = localStorage.getItem('ip')
|
|
||||||
/*switch (type) {
|
/*switch (type) {
|
||||||
case 'point':
|
case 'point':
|
||||||
data = {id, name, position: option.position}
|
data = {id, name, position: option.position}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.datetime"
|
v-model="form.datetime"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="Select date and time"
|
placeholder="选择触发时间"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="持续时间">
|
<el-form-item label="持续时间">
|
||||||
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<div class="optionbtn">
|
<div class="optionbtn">
|
||||||
<el-button>确定</el-button>
|
<el-button @click="addEvent">确定</el-button>
|
||||||
<el-button>取消</el-button>
|
<el-button>取消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -98,7 +98,7 @@ import type {RenderContentContext, TreeInstance} from 'element-plus'
|
|||||||
|
|
||||||
const treeRef = ref<TreeInstance>()
|
const treeRef = ref<TreeInstance>()
|
||||||
// 存储当前需要高亮的节点 key(初始为空)
|
// 存储当前需要高亮的节点 key(初始为空)
|
||||||
const currentKey = ref<number | null>(1);
|
const currentKey = ref<number | string | null>("flicker");
|
||||||
|
|
||||||
interface Tree {
|
interface Tree {
|
||||||
label: string
|
label: string
|
||||||
@ -107,6 +107,7 @@ interface Tree {
|
|||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
|
datetime: '',
|
||||||
})
|
})
|
||||||
const hour = ref(0)
|
const hour = ref(0)
|
||||||
const minute = ref(0)
|
const minute = ref(0)
|
||||||
@ -116,7 +117,7 @@ const numbers = ref(0)//闪烁次数
|
|||||||
const isContainModelPosition = ref(true)
|
const isContainModelPosition = ref(true)
|
||||||
const eventBus: any = inject('bus')
|
const eventBus: any = inject('bus')
|
||||||
|
|
||||||
form['datetime'] = new Date(2000, 1, 1, 12, 0, 0)
|
// form['datetime'] = new Date(2000, 1, 1, 12, 0, 0)
|
||||||
const isShowPup = ref(false)
|
const isShowPup = ref(false)
|
||||||
const eventTree: { children: ({ label: string } | { label: string })[]; id: string; label: string }[] = [
|
const eventTree: { children: ({ label: string } | { label: string })[]; id: string; label: string }[] = [
|
||||||
{
|
{
|
||||||
@ -143,6 +144,9 @@ const handleNodeClick = (data: Tree, node, TreeNode, event) => {
|
|||||||
currentKey.value = data.id; // data.id 为节点的唯一 key(需与 tree 的 node-key 对应)
|
currentKey.value = data.id; // data.id 为节点的唯一 key(需与 tree 的 node-key 对应)
|
||||||
form.name = data.label
|
form.name = data.label
|
||||||
}
|
}
|
||||||
|
const addEvent = () => {
|
||||||
|
console.log(form)
|
||||||
|
}
|
||||||
eventBus.on('openAddEvent', (data, cb, type) => {
|
eventBus.on('openAddEvent', (data, cb, type) => {
|
||||||
// selectCallback = cb
|
// selectCallback = cb
|
||||||
// addType.value = type
|
// addType.value = type
|
||||||
@ -155,6 +159,10 @@ eventBus.on('openAddEvent', (data, cb, type) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
:deep(.newEvent>div) {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
.newEvent {
|
.newEvent {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
@ -234,13 +242,18 @@ eventBus.on('openAddEvent', (data, cb, type) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.el-overlay-dialog) {
|
||||||
|
/*position: absolute;
|
||||||
|
bottom: auto;
|
||||||
|
right: auto;*/
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-dialog) {
|
:deep(.el-dialog) {
|
||||||
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
|
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
|
||||||
rgba(0, 0, 0, 0.6);
|
rgba(0, 0, 0, 0.6);
|
||||||
border: 1px solid #00c9ff;
|
border: 1px solid #00c9ff;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
width: 30vw;
|
//position: absolute;
|
||||||
height: 30vh;
|
|
||||||
|
|
||||||
width: 570px;
|
width: 570px;
|
||||||
height: 323px;
|
height: 323px;
|
||||||
|
|||||||
Reference in New Issue
Block a user