feature: 增加图层管理组件及相关逻辑(目前仅支持DataSource 和 ImageryLayer 的管理

devzpx
zhaipx 3 months ago
parent bb042154cd
commit 666dc130e2

@ -1,5 +0,0 @@
export default class Airline {
constructor(points) {
}
}

@ -1,7 +1,9 @@
import * as Cesium from 'cesium'
import {Cartesian3} from 'cesium'
import {useStaticStore} from "@/store/staticOptions.js";
import {useLayerStore} from "@/store/layerManagerStore.ts";
const store = useStaticStore()
let time = new Date()
export default class MeasureDistance {
constructor(viewer) {
this.viewer = viewer
@ -129,6 +131,7 @@ export default class MeasureDistance {
// console.log(dataSource);
this.viewer.dataSources.add(dataSource);
this.viewer.flyTo(dataSource);
useLayerStore().addLayer(kml_file.name,kmlDataPromise,undefined,true)
});
}
@ -148,6 +151,8 @@ export default class MeasureDistance {
dataGeo.then((dataSources) => {
console.log(dataSources);
viewer.dataSources.add(dataSources);
useLayerStore().addLayer(js_file.name,dataGeo,undefined,true)
// 获取datasources中的实体
let entities = dataSources.entities.values;
//获取每一个实体
@ -167,6 +172,34 @@ export default class MeasureDistance {
});
}
AddWMSLayer(url){
let wmsProvider = new Cesium.WebMapServiceImageryProvider({
url: url, //baseurl + workspace + '/wms',
enablePickFeatures: true,
defaultAlpha: 0,
parameters: {
service: 'WMS',
version: '1.1.1',
request: 'GetMap',
format: 'image/png8',
styles: '',
transparent: true
}
});
let imageLayer = new Cesium.ImageryLayer(wmsProvider,{
alpha: 0.6
});
this.viewer.imageryLayers.add(imageLayer);
useLayerStore().addLayer(url,undefined,imageLayer,true)
}
clearLayers(){
useLayerStore().Layers.forEach(layer=>{
this.viewer.imageryLayers.remove(layer?.imageLayer,true)
this.viewer.dataSources.remove(layer?.dataSource,true)
})
}
/**
* Cesium实体导出Geojson只导出实体中的 polyline polygon rectangle
* @param entity
@ -263,6 +296,7 @@ export default class MeasureDistance {
return geoJson
}
/**
* 显示飞行航线
* @param line Airline

@ -0,0 +1,96 @@
<script setup lang="ts">
import {Menu} from "@vicons/ionicons5";
import {useLayerStore} from "@/store/layerManagerStore.ts";
import {ref} from "vue";
let layerShow = ref(true)
let layer: {name:string,id:string} = {
name:'', id:''
}
let itemOptions = [
{label: "移除图层", key: 'remove'},
{label: "缩放至图层", key: 'lookAt'},
{label: "移至顶层", key: 'moveTop'},
{label: "移至底层", key: 'moveBottom'},
]
function handleLayerItem(key:any) {
useLayerStore().Layers.forEach((layer) => {
if (layer.lName == props.lname && layer.lId == props?.lid) {
switch (key) {
case 'remove': {
if(layer.dataSource){
layer.dataSource.then((ds)=>{
window.viewer.dataSources.remove(ds)
})
}
if(layer.imageLayer){
window.viewer.imageryLayers.remove(layer.imageLayer)
}
break
}
case 'lookAt': {
if(layer.dataSource) window.viewer.flyTo(layer.dataSource)
if(layer.imageLayer) window.viewer.flyTo(layer.imageLayer)
break
}
case 'moveTop': {
//TODO:
break
}
case 'moveBottom': {
// TODO:
break
}
}
}
})
}
const props = defineProps<{ lname: String, lid?: String }>()
function onCheck(checked: boolean) {
useLayerStore().Layers.forEach((layer) => {
if (layer.lName == props.lname && layer.lId == props?.lid) {
if(checked){
//
if(layer.dataSource) { // dataSourcePromise
layer.dataSource.then((ds)=>{
ds.show = true
})
}
if(layer.imageLayer) layer.imageLayer.show = true
window.viewer.flyTo(layer.dataSource);
}
else{ //
if(layer.dataSource) {
layer.dataSource.then((ds)=>{
ds.show = false
})
}
if(layer.imageLayer) layer.imageLayer.show = false
window.viewer.scene.requestRender()
layer.show = false
}
}
})
layerShow.value = !layerShow.value
}
</script>
<template>
<n-row justify-content="space-between" style="align-items: center; border-bottom: 1px solid #e7e6e6">
<n-checkbox size="medium" :label="props.lname" style="margin: 0 0 0 1rem;"
:checked="layerShow" @update:checked="onCheck"/>
<n-dropdown :options="itemOptions" @select="handleLayerItem">
<n-button tertiary type="success" size="medium">
<template #icon>
<n-icon><Menu/></n-icon>
</template>
</n-button>
</n-dropdown>
</n-row>
</template>
<style scoped>
</style>

@ -1,16 +1,118 @@
<!--
文件描述Cesium地图的图层管理器组件
创建时间2024/5/20 11:25
创建时间2025/3/4 11:25
创建人Zhaipeixiu
-->
<script setup lang="ts">
import {ArrowBackOutline} from "@vicons/ionicons5"
import LayerItem from "@/components/LayerItem.vue";
import { darkTheme } from 'naive-ui'
import {ref} from "vue";
import {useLayerStore} from "@/store/layerManagerStore.ts";
defineExpose({
open_closeSidebar: ()=>{
//
let sidebar = document.querySelector('.LayerManagerSidebar');
if(sidebar?.classList.contains('open')){ //
sidebar?.classList.remove('open');
}else { //
sidebar?.classList.add('open');
}
},
})
function closeBar() {
let sidebar = document.querySelector('.LayerManagerSidebar');
sidebar?.classList.remove('open');
}
let showWmsModal = ref(false);
let wmsConfig = {
url: ''
}
function addWMSLayer(){
window.measureViewer.AddWMSLayer(wmsConfig.url)
}
function clearLayers(){
window.measureViewer.clearLayers()
}
</script>
<template>
<div>
<n-config-provider :theme="darkTheme">
<n-layout class="LayerManagerSidebar">
<n-layout-header>
<n-row justify-content="space-between"
style="margin-bottom:.5rem; border-bottom:solid 1px #dcd9d8">
<h2 style="margin: .3rem 1rem" >图层管理</h2>
<n-button style=" margin: .6rem" @click="closeBar" size="tiny" type="error">
<template #icon>
<n-icon><ArrowBackOutline/></n-icon>
</template>
</n-button>
</n-row>
</n-layout-header>
<n-layout-content>
<n-empty size="large" description="暂未加载图层" v-show="useLayerStore().Layers.length==0"/>
<!-- 图层项目 layeritem 动态增减组件 -->
<layer-item v-for="layer in useLayerStore().Layers" :lid="layer.lId" :lname="layer.lName">
</layer-item>
</n-layout-content>
<n-layout-footer style="margin: .5rem">
<n-space justify="space-around">
<n-button size="small" type="info" @click="showWmsModal=true">
添加WMS图层
</n-button>
<n-button size="small" type="warning" @click="clearLayers">
清空图层
</n-button>
</n-space>
</n-layout-footer>
</n-layout>
</n-config-provider>
<n-modal v-model:show="showWmsModal"
style="width: 30%"
:mask-closable="false"
preset="dialog"
title="">
<template #header>
<div>WMS资源配置</div>
</template>
<div style="margin: 2rem 2rem .5rem 1rem">
<n-space>
<n-form ref="formRef" :model="wmsConfig"
label-placement="left"
label-width="auto"
require-mark-placement="right-hanging">
<n-form-item label="WMS URL">
<n-input v-model:value="wmsConfig.url" placeholder="127.0.0.1/wms"/>
</n-form-item>
</n-form>
</n-space>
<n-space justify="center">
<n-button @click="addWMSLayer" type="primary" size="small">确定</n-button>
<n-button @click="showWmsModal=false" type="warning" size="small">取消</n-button>
</n-space>
</div>
</n-modal>
</div>
</template>
<style scoped>
/* 侧边栏基础样式 */
.LayerManagerSidebar {
width: 15rem;
position: absolute;
top: 3rem;
left: -15rem; /* 默认隐藏 */
padding: 0;
border-radius: 7px;
transition: left 0.3s;
}
/* 侧边栏展开样式 */
.LayerManagerSidebar.open {
left: 0;
}
</style>

@ -14,6 +14,7 @@ import {useStaticStore} from "@/store/staticOptions.js";
import {login, requestAirline} from "@/assets/js/request.js";
import {dataProcess, getAirline} from "@/assets/js/websocketProtocol.ts";
import SpatialAnalysis from "@/components/SpatialAnalysis.vue";
import LayerManager from "@/components/map/LayerManager.vue";
const message = useMessage();
let SceneValue;
@ -22,6 +23,7 @@ let hasPlane = ref(false);
let store = useStaticStore();
const spatialAnalyse= ref(null)
const layerManager= ref(null)
SceneValue = ref('untrace');
function handleSceneSelect(key){
@ -193,18 +195,25 @@ function getUavAirline() {
}
}
function manageLayer(){
layerManager.value?.open_closeSidebar()
}
</script>
<template>
<n-flex id="panel">
<n-popselect v-model:value="layerValue" :options="store.menuOptions.layerOptions" size="medium">
<n-button tertiary circle type="warning">
<n-space id="panel">
<n-row justify-content="space-between">
<n-tooltip placement="bottom" trigger="hover" >
<template #trigger>
<n-button tertiary type="warning" @click="manageLayer">
<template #icon>
<n-icon><Layers/></n-icon>
</template>
</n-button>
</n-popselect>
</template>
<span> 图层管理 </span>
</n-tooltip>
<n-tooltip placement="bottom" trigger="hover">
<template #trigger>
<n-button tertiary circle type="warning" @click="handleFile">
@ -215,15 +224,13 @@ function getUavAirline() {
</template>
<span> 添加数据 </span>
</n-tooltip>
<n-dropdown :options="store.menuOptions.AnalyzeOptions" @select="handleAnalyseSelect">
<n-button tertiary circle type="warning">
<n-button tertiary type="warning">
<template #icon>
<n-icon><TerrainSharp/></n-icon>
</template>
</n-button>
</n-dropdown>
<n-dropdown :options="store.menuOptions.EditOptions" @select="handleEditSelect">
<n-button tertiary circle type="warning">
<template #icon>
@ -232,7 +239,7 @@ function getUavAirline() {
</n-button>
</n-dropdown>
<n-dropdown :options="store.menuOptions.MeasureOptions" @select="handleSelect">
<n-button tertiary circle type="warning">
<n-button tertiary type="warning">
<template #icon>
<n-icon><RulerAlt/></n-icon>
</template>
@ -247,7 +254,7 @@ function getUavAirline() {
</n-dropdown>
<n-tooltip placement="bottom" trigger="hover">
<template #trigger>
<n-button tertiary circle type="warning" @click="showModal = true">
<n-button tertiary type="warning" @click="showModal = true">
<template #icon>
<n-icon><Settings/></n-icon>
</template>
@ -271,10 +278,11 @@ function getUavAirline() {
<n-icon><ChevronBack/></n-icon>
</template>
</n-button>
</n-flex>
</n-row>
</n-space>
<n-modal v-model:show="showModal"
style="width: 40%"
style="width: 30%"
:mask-closable="false"
preset="dialog"
title="">
@ -304,6 +312,7 @@ function getUavAirline() {
</n-modal>
<SpatialAnalysis ref="spatialAnalyse"></SpatialAnalysis>
<LayerManager ref="layerManager"></LayerManager>
</template>
<style scoped>
@ -311,7 +320,7 @@ function getUavAirline() {
position: absolute;
top: 10px;
left: 2px;
background: rgba(21, 21, 21, 0.73);
border-radius: 7px;
background: rgba(21, 21, 21, 0.94);
}
</style>

@ -0,0 +1,30 @@
import {defineStore} from "pinia";
type layer = {
lName: string
lId: string
dataSource?: any
imageLayer?: any
show: boolean
}
export const useLayerStore = defineStore('LayerStore', {
state: ()=>{
return {
Layers: [] as layer[]
}
},
actions: {
addLayer(lName: string,dataSource?:any,imageLayer?: any,show=true) {
let time = new Date()
let layer: layer = {
dataSource: dataSource,
imageLayer: imageLayer,
lId: time.getTime().toString(),
lName: lName,
show: show
}
this.Layers.push(layer)
}
}
})

@ -1,10 +1,10 @@
import {defineStore} from "pinia";
import cesiumAirPlane from "@/assets/models/Cesium_Air.glb";
import {ref} from "vue";
export const useStaticStore = defineStore('staticOptions',{
state: ()=>{
return {
temp:{
temp: {
userName:"sysUser003",
password:"sysUser003",
token:"",

@ -15,7 +15,7 @@
"jsx": "preserve",
"allowJs": true,
/* Linting */
"strict": true,
"strict": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": false,

Loading…
Cancel
Save