1.添加森防绘制,添加修改图标的属性;2.修改图标默认是修改当前图标,但也可以选择作用于所有此类要素,此时已经绘制的要素图标都修改,并修改对应要素类型的配置;

This commit is contained in:
zhangquan 2025-07-29 11:59:03 +08:00
parent 2817417d19
commit 8e6f5b5695
7 changed files with 795 additions and 271 deletions

View File

@ -41,6 +41,7 @@
v-model="editingValue" v-model="editingValue"
placeholder="请选择" placeholder="请选择"
size="small" size="small"
style="width: 180px;"
@change="handleEditorChange(row, editingValue)" @change="handleEditorChange(row, editingValue)"
@blur="handleSave(row, editingValue)" @blur="handleSave(row, editingValue)"
ref="editorRef" ref="editorRef"
@ -81,6 +82,7 @@
type="date" type="date"
placeholder="选择日期" placeholder="选择日期"
size="small" size="small"
style="width: 180px;"
@change="handleEditorChange(row, editingValue)" @change="handleEditorChange(row, editingValue)"
@blur="handleSave(row, editingValue)" @blur="handleSave(row, editingValue)"
ref="editorRef" ref="editorRef"
@ -94,12 +96,14 @@
type="datetime" type="datetime"
placeholder="选择日期时间" placeholder="选择日期时间"
size="small" size="small"
style="width: 180px;"
@change="handleEditorChange(row, editingValue)" @change="handleEditorChange(row, editingValue)"
@blur="handleSave(row, editingValue)" @blur="handleSave(row, editingValue)"
ref="editorRef" ref="editorRef"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
/> />
</template> </template>
<!-- Icon 类型不在这里编辑通过弹窗编辑 -->
<template v-else> <template v-else>
<!-- 默认使用 el-input --> <!-- 默认使用 el-input -->
<el-input <el-input
@ -115,7 +119,19 @@
<!-- 显示模式 --> <!-- 显示模式 -->
<div v-else class="display-container"> <div v-else class="display-container">
<!-- Icon 类型显示图标 -->
<template v-if="row.type === 'icon'">
<el-image
v-if="row.value"
:src="row.value"
fit="contain"
style="width: 24px; height: 24px; vertical-align: middle;"
/>
<span v-else style="color: #909399;">未选择图标</span>
</template>
<template v-else>
{{ getDisplayValue(row) }} {{ getDisplayValue(row) }}
</template>
</div> </div>
</div> </div>
</template> </template>
@ -128,27 +144,21 @@
<el-button type="success" size="small" @click="handleSaveButtonClick"> </el-button> <el-button type="success" size="small" @click="handleSaveButtonClick"> </el-button>
</div> </div>
</div> </div>
<!-- 图片选择弹窗 -->
<icon-dialog
v-model="showIconDialog"
:current="currentIconProperty ? currentIconProperty.value : ''"
@update:current="handleIconSelected"
/>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, watch, nextTick, onMounted } from 'vue'; import { ref, watch, nextTick, onMounted } from 'vue';
import {
ElTable,
ElTableColumn,
ElInput,
ElInputNumber,
ElSelect,
ElOption,
ElColorPicker,
ElMessage,
ElIcon,
ElButton,
ElDatePicker,
} from 'element-plus';
import { Close } from '@element-plus/icons-vue'; import { Close } from '@element-plus/icons-vue';
import { useDraggable, useElementBounding, useWindowSize } from '@vueuse/core'; import { useDraggable, useElementBounding, useWindowSize } from '@vueuse/core';
import { parseTime } from '@/utils/ruoyi'; import { parseTime } from '@/utils/ruoyi';
import IconDialog from './iconDialog.vue';
const props = defineProps({ const props = defineProps({
/** /**
@ -158,7 +168,7 @@ const props = defineProps({
* key: string | number, // * key: string | number, //
* name: string, // * name: string, //
* value: any, // * value: any, //
* type: 'text' | 'number' | 'select' | 'color' | 'date' | 'datetime', // * type: 'text' | 'number' | 'select' | 'color' | 'date' | 'datetime' | 'icon', //
* options?: Array<{ label: string, value: any }>, // typeselect * options?: Array<{ label: string, value: any }>, // typeselect
* checkMethod?: (newValue: any, property: object) => boolean | Promise<boolean>, // * checkMethod?: (newValue: any, property: object) => boolean | Promise<boolean>, //
* disabled?: boolean, // false * disabled?: boolean, // false
@ -195,6 +205,10 @@ const editingValue = ref(null);
// focus // focus
const editorRef = ref(null); const editorRef = ref(null);
//
const showIconDialog = ref(false);
const currentIconProperty = ref(null);
// refs and state // refs and state
const targetRef = ref(null); // (.dialog-property-grid-container) const targetRef = ref(null); // (.dialog-property-grid-container)
const handleRef = ref(null); // (.property-header) const handleRef = ref(null); // (.property-header)
@ -275,6 +289,21 @@ const handleCellClick = (row, column, cell, event) => {
// //
if (column.className.includes('property-value-column')) { if (column.className.includes('property-value-column')) {
// icon
if (row.type === 'icon') {
// //
// if (editingKey.value !== null && editingKey.value !== row.key) {
// const previousRow = internalData.value.find(item => item.key === editingKey.value);
// if (previousRow && !previousRow.disabled) {
// handleSave(previousRow, editingValue.value);
// }
// }
//
currentIconProperty.value = row;
showIconDialog.value = true;
return;
}
// //
if (editingKey.value !== null && editingKey.value !== row.key) { if (editingKey.value !== null && editingKey.value !== row.key) {
const previousRow = internalData.value.find(item => item.key === editingKey.value); const previousRow = internalData.value.find(item => item.key === editingKey.value);
@ -306,6 +335,11 @@ const startEditing = (row) => {
return; return;
} }
// icon
if (row.type === 'icon') {
return;
}
// //
if (editingKey.value === row.key) { if (editingKey.value === row.key) {
return; return;
@ -446,10 +480,36 @@ const handleClose = () => {
editingKey.value = null; editingKey.value = null;
editingValue.value = null; editingValue.value = null;
} }
//
if (showIconDialog.value) {
showIconDialog.value = false;
currentIconProperty.value = null;
}
// close , // close ,
emit('close'); emit('close');
}; };
/**
* 处理 IconDialog 选择图标后的回调
* @param {string} newIconValue - 选择的新图标路径或dataURL
*/
const handleIconSelected = (newIconValue) => {
if (currentIconProperty.value) {
const property = internalData.value.find(item => item.key === currentIconProperty.value.key);
if (property) {
//
if (property.value !== newIconValue) {
property.value = newIconValue;
// Emit
emit('property-change', property.key, newIconValue, property);
}
}
}
// Reset icon dialog state
currentIconProperty.value = null;
showIconDialog.value = false;
};
/** /**
* 获取属性在显示模式下的展示值 * 获取属性在显示模式下的展示值
@ -481,6 +541,8 @@ const getDisplayValue = (row) => {
console.error("Error formatting datetime for display:", e); console.error("Error formatting datetime for display:", e);
} }
return row.value; // return row.value; //
} else if (row.type === 'icon') {
return ''; // icon
} }
// nullundefined // nullundefined
return row.value !== null && row.value !== undefined ? row.value : ''; return row.value !== null && row.value !== undefined ? row.value : '';
@ -641,4 +703,21 @@ defineExpose({
.property-table_wrapper .el-table th.el-table__cell.is-leaf { .property-table_wrapper .el-table th.el-table__cell.is-leaf {
background-color: transparent; background-color: transparent;
} }
/* icon 显示的样式 */
.property-value-cell {
display: flex;
align-items: center;
min-height: 32px; /* 确保图像有足够的高度 */
}
.property-value-cell .display-container {
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
.property-value-cell .display-container .el-image {
margin-right: 8px; /* 图标和潜在文本之间的空间 */
}
</style> </style>

View File

@ -0,0 +1,170 @@
<template>
<el-dialog v-model="show" title="选择图标" width="600px" append-to-body>
<!-- <el-button type="primary">上传本地图片</el-button> -->
<div v-loading="loading">
<el-upload action="#" :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
accept="image/*">
<el-button type="primary">上传本地图片</el-button>
</el-upload>
<div class="icon-container">
<div :class="{active: icon === selectedItem}" class="icon-item" v-for="(icon, index) in icons" :key="index" @click="selectIcon(icon)">
<el-image style="width: 48px; height: 48px" :src="icon" fit="contain" />
</div>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm" :disabled="!selectedItem">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import analysisAroundIcon from '@/assets/icons/example/analysis_around.png'
import analysisCoordinationLocationIcon from '@/assets/icons/example/analysis_coordination_location.png'
import analysisMapLocationIcon from '@/assets/icons/example/analysis_map_location.png'
import analysisSandboxIcon from '@/assets/icons/example/analysis_sandbox.png'
import analysisSpreadIcon from '@/assets/icons/example/analysis_spread.png'
import checkPointIcon from '@/assets/icons/example/check_point.png'
import sandboxExplosiveIcon from '@/assets/icons/example/sandbox_explosive.png'
import sandboxFireIcon from '@/assets/icons/example/sandbox_fire.png'
import sandboxFirefighterIcon from '@/assets/icons/example/sandbox_firefighter.png'
import sandboxFirepointIcon from '@/assets/icons/example/sandbox_firepoint.png'
import sandboxFlameIcon from '@/assets/icons/example/sandbox_flame.png'
import sandboxTrappedIcon from '@/assets/icons/example/sandbox_trapped.png'
import sandboxWaterIcon from '@/assets/icons/example/sandbox_water.png'
const show = defineModel()
const props = defineProps({
current: {
type: String,
default: ''
}
})
const emits = defineEmits(['update:current'])
// const icons = ref([
// { url: analysisAroundIcon },
// { url: analysisCoordinationLocationIcon },
// { url: analysisMapLocationIcon },
// { url: analysisSandboxIcon },
// { url: analysisSpreadIcon },
// { url: checkPointIcon },
// { url: sandboxExplosiveIcon },
// { url: sandboxFireIcon },
// { url: sandboxFirefighterIcon },
// { url: sandboxFirepointIcon },
// { url: sandboxFlameIcon },
// { url: sandboxTrappedIcon },
// { url: sandboxWaterIcon }
// ])
const icons = ref([
analysisAroundIcon,
analysisCoordinationLocationIcon,
analysisMapLocationIcon,
analysisSandboxIcon,
analysisSpreadIcon,
checkPointIcon,
sandboxExplosiveIcon,
sandboxFireIcon,
sandboxFirefighterIcon,
sandboxFirepointIcon,
sandboxFlameIcon,
sandboxTrappedIcon,
sandboxWaterIcon
])
const loading = ref(false)
const selectedItem = ref(props.current)
/* 上传图片 */
const handleFileChange = (uploadFile) => {
loading.value = true;
const file = uploadFile.raw;
if (!file) return;
//
if (!file.type.startsWith('image/')) {
ElMessage.error('只能上传图片文件!');
return;
}
// ()
// const isLt2M = file.size / 1024 / 1024 < 2;
// if (!isLt2M) {
// ElMessage.error(' 2MB!');
// return;
// }
const reader = new FileReader();
reader.onloadend = () => {
const base64String = reader.result;
if(icons.value.includes(base64String)) {
ElMessage.error('该图片已存在,请选择其他图片!');
loading.value = false;
return;
}
icons.value.push(base64String);
loading.value = false;
};
reader.onerror = () => {
ElMessage.error('读取图片时出错!');
loading.value = false;
};
reader.readAsDataURL(file);
}
/* 图片点击 */
const selectIcon = (icon) => {
selectedItem.value = icon
}
/* 确认 */
const handleConfirm = () => {
emits('update:current', selectedItem.value)
show.value = false
}
/* 取消 */
const handleCancel = () => {
selectedItem.value = props.current
show.value = false
}
</script>
<style lang="scss" scoped>
.icon-container {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
border-left: 1px solid var(--el-border-color);
.icon-item {
width: 60px;
height: 60px;
// background-color: #f0f0f0;
border-right: 1px solid var(--el-border-color);
border-bottom: 1px solid var(--el-border-color);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:nth-child(-n+10) {
border-top: 1px solid var(--el-border-color);
}
&:hover {
// background-color: #e0e0e0;
background-color: var(--el-border-color-extra-light);
color: var(--brand-color-light);
}
&.active {
background-color: var(--el-color-primary-light-6);
}
}
}
</style>

View File

@ -1,6 +1,9 @@
// src/utils/DialogPropertyGrid.js // src/utils/DialogPropertyGrid.js
import { createApp, h, ref, watch } from 'vue'; import { createApp, h, ref, watch } from 'vue';
import * as Cesium from 'cesium'; import * as Cesium from 'cesium';
import ElementPlus from 'element-plus'
import locale from 'element-plus/es/locale/lang/zh-cn'
import Cookies from 'js-cookie'
// 导入修改后的 PropertyGrid 组件 (现在作为 DialogPropertyGrid 的内容) // 导入修改后的 PropertyGrid 组件 (现在作为 DialogPropertyGrid 的内容)
import PropertyGridContent from './PropertyGrid.vue'; // 假设文件名为 PropertyGrid.vue import PropertyGridContent from './PropertyGrid.vue'; // 假设文件名为 PropertyGrid.vue
@ -117,6 +120,13 @@ const show = (entity = null, onSave = null) => {
// 4. 创建 Vue 应用实例并挂载 // 4. 创建 Vue 应用实例并挂载
currentApp = createApp(wrapperComponent); currentApp = createApp(wrapperComponent);
// 添加 ElementPlus 组件库
currentApp.use(ElementPlus, {
locale: locale,
// 支持 large、default、small
size: Cookies.get('size') || 'default'
})
// 5. 将应用挂载到临时容器 // 5. 将应用挂载到临时容器
// 挂载后,获取根组件实例,以便后续更新数据 // 挂载后,获取根组件实例,以便后续更新数据
currentWrapperInstance = currentApp.mount(currentContainer); currentWrapperInstance = currentApp.mount(currentContainer);

View File

@ -75,10 +75,28 @@ export const warning = [
{ {
key: "discoveryTime", key: "discoveryTime",
name: "发现时间", name: "发现时间",
type: "text", type: "datetime",
value: "", value: "",
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
]; ];
// 定义巡护路线的属性 // 定义巡护路线的属性
@ -143,6 +161,24 @@ export const ranger = [
value: "", value: "",
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
]; ];
// 定义云台的属性 // 定义云台的属性
@ -189,6 +225,24 @@ export const ptz = [
value: "", value: "",
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
] ]
// 定义卡口的属性 // 定义卡口的属性
@ -235,6 +289,24 @@ export const bayonet = [
value: "", value: "",
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
] ]
// 定义无人机机场的属性 // 定义无人机机场的属性
@ -281,6 +353,24 @@ export const airport = [
value: "", value: "",
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
] ]
// 定义热点的属性 // 定义热点的属性
@ -325,6 +415,24 @@ export const hot = [
], ],
disabled: false, disabled: false,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
] ]
// 定义水源地的属性 // 定义水源地的属性
@ -403,6 +511,24 @@ export const warehouse = [
value: "0", value: "0",
disabled: true, disabled: true,
}, },
{
key: "icon",
name: "图标",
type: "icon",
value: "",
disabled: false,
},
{
key: "changeAll",
name: "作用于该类型要素",
type: "select",
value: "false",
options: [
{ label: "是", value: "true" },
{ label: "否", value: "false" },
],
disabled: false,
},
]; ];
// 定义林区道路的属性 // 定义林区道路的属性
@ -552,6 +678,7 @@ export const setPropertyData = (data, entity) => {
return return
} }
const oldProperties = JSON.parse(JSON.stringify(entity.properties.getValue()))
const newProperties = entity.properties.getValue() const newProperties = entity.properties.getValue()
data.forEach(item => { data.forEach(item => {
if (item.key && item.value !== undefined) { if (item.key && item.value !== undefined) {
@ -561,8 +688,5 @@ export const setPropertyData = (data, entity) => {
// 替换 properties // 替换 properties
entity.properties = new Cesium.PropertyBag(newProperties) entity.properties = new Cesium.PropertyBag(newProperties)
// 这里默认name字段是标签显示的内容如果entity有label则更新name字段值 return [oldProperties, newProperties]
if(entity.label) {
entity.label.text = new Cesium.ConstantProperty(newProperties.name);
}
} }

View File

@ -45,7 +45,7 @@
import * as Cesium from 'cesium'; import * as Cesium from 'cesium';
import { useDrawTool } from '@/components/CesiumMap/mixins/useDrawTool'; import { useDrawTool } from '@/components/CesiumMap/mixins/useDrawTool';
import { useEventBus } from '@/components/CesiumMap/mixins/useEventBus'; import { useEventBus, ScreenMode } from '@/components/CesiumMap/mixins/useEventBus';
import { useMeasureTool } from '@/components/CesiumMap/mixins/useMeasureTool'; import { useMeasureTool } from '@/components/CesiumMap/mixins/useMeasureTool';
import { useWeatherParticle } from '@/components/CesiumMap/mixins/useWeatherParticle'; import { useWeatherParticle } from '@/components/CesiumMap/mixins/useWeatherParticle';
import { import {
@ -72,7 +72,12 @@ import {
drawWatersource, drawWatersource,
drawRoad, drawRoad,
drawKeyarea, drawKeyarea,
pickFeatureProperty,
} from './forestFireDraw' } from './forestFireDraw'
//
import DialogPropertyGrid from './../DialogPropertyGrid';
import { setPropertyData } from './../DialogPropertyGrid/property';
import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive';
// //
import baseDrawIcon from "@/assets/icons/toolbar_base_draw.png"; import baseDrawIcon from "@/assets/icons/toolbar_base_draw.png";
@ -413,6 +418,11 @@ watch(() => props.viewer, (v) => {
bus.on('toolbar_fog', () => weatherSwitchClick('fog')) bus.on('toolbar_fog', () => weatherSwitchClick('fog'))
// //
bus.on('toolbar_clear', toolbarClear); bus.on('toolbar_clear', toolbarClear);
// view
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, ({ position }) => {
pickFeatureProperty(position, params)
}, ScreenMode.VIEW)
} }
}, { immediate: true }); }, { immediate: true });

View File

@ -5,13 +5,130 @@ import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitiv
import { getDistance, getArea, getBoundingCenterCoordinate, getBoundingCenter } from '@/components/CesiumMap/mixins/useMeasureTool'; import { getDistance, getArea, getBoundingCenterCoordinate, getBoundingCenter } from '@/components/CesiumMap/mixins/useMeasureTool';
import { parseTime } from '@/utils/ruoyi'; import { parseTime } from '@/utils/ruoyi';
import fireWarningIcon from '@/assets/icons/fire_warning.png'; import fireWarningDefaultIcon from '@/assets/icons/fire_warning.png';
import fireRangerIcon from '@/assets/icons/fire_ranger.png'; import fireRangerDefaultIcon from '@/assets/icons/fire_ranger.png';
import firePtzIcon from '@/assets/icons/fire_ptz.png'; import firePtzDefaultIcon from '@/assets/icons/fire_ptz.png';
import fireBayonetIcon from '@/assets/icons/fire_bayonet.png'; import fireBayonetDefaultIcon from '@/assets/icons/fire_bayonet.png';
import fireAirportIcon from '@/assets/icons/fire_airport.png'; import fireAirportDefaultIcon from '@/assets/icons/fire_airport.png';
import fireHotIcon from '@/assets/icons/fire_hot.png'; import fireHotDefaultIcon from '@/assets/icons/fire_hot.png';
import fireWarehouseIcon from '@/assets/icons/fire_warehouse.png'; import fireWarehouseDefaultIcon from '@/assets/icons/fire_warehouse.png';
let fireWarningIcon = fireWarningDefaultIcon;
let fireRangerIcon = fireRangerDefaultIcon;
let firePtzIcon = firePtzDefaultIcon;
let fireBayonetIcon = fireBayonetDefaultIcon;
let fireAirportIcon = fireAirportDefaultIcon;
let fireHotIcon = fireHotDefaultIcon;
let fireWarehouseIcon = fireWarehouseDefaultIcon;
const getImage = async (url) => {
return new Promise((resolve, reject) => {
const image = new Image();
image.src = url;
image.onload = () => {
resolve(image);
};
image.onerror = (error) => {
reject(error);
};
});
}
const checkLabel = (entity, oldProperties, newProperties) => {
if(oldProperties.name !== newProperties.name) {
// 这里默认name字段是标签显示的内容如果entity有label则更新name字段值
if(entity.label) {
entity.label.text = new Cesium.ConstantProperty(newProperties.name);
}
}
}
const checkIcon = (entity, oldProperties, newProperties, layer) => {
if(oldProperties.icon !== newProperties.icon) {
// 默认icon字段是图标路径如果entity有billboard则更新图标
if(entity.billboard) {
// 重新计算图标大小
getImage(newProperties.icon).then(image => {
// 如果是同类型全局修改
if(newProperties.changeAll === 'true') {
// 修改全局要素图标
switch(newProperties.__type) {
case 'warning':
fireWarningIcon = newProperties.icon;
break;
case 'ranger':
fireRangerIcon = newProperties.icon;
break;
case 'ptz':
firePtzIcon = newProperties.icon;
break;
case 'bayonet':
fireBayonetIcon = newProperties.icon;
break;
case 'airport':
fireAirportIcon = newProperties.icon;
break;
case 'hot':
fireHotIcon = newProperties.icon;
break;
case 'warehouse':
fireWarehouseIcon = newProperties.icon;
}
// 修改已经生成的
if(layer) {
layer.entities.values.forEach(e => {
if(e.properties.getValue().__type === newProperties.__type) {
e.billboard.image = new Cesium.ConstantProperty(newProperties.icon);
if(e.label) {
e.label.pixelOffset = new Cesium.Cartesian2(0, - image.height - 6)
}
}
})
}
}
// 修改当前要素图标
entity.billboard.image = new Cesium.ConstantProperty(newProperties.icon);
if(entity.label) {
entity.label.pixelOffset = new Cesium.Cartesian2(0, - image.height - 6)
}
})
}
}
}
const pickFeatureProperty = (position, params) => {
// 如果点击的是实体,则获取该实体的属性数据
const pickedObjectList = params.viewer.scene.drillPick(position);
if (pickedObjectList.length > 0) {
// 遍历拾取实体,获取第一个非辅助实体
for (let index = 0; index < pickedObjectList.length; index++) {
const obj = pickedObjectList[index];
if (obj && obj.id && obj.id instanceof Cesium.Entity) {
// 辅助实体的name都以'__'开头,不识别
if(obj.id.name?.indexOf('__') === 0) {
continue
}
// getPropertyData(obj.id);
DialogPropertyGrid.show(obj.id, (data) => {
// 更新实体属性
const [oldProperties, newProperties] = setPropertyData(data, obj.id);
checkLabel(obj.id, oldProperties, newProperties);
if(['warning', 'ranger', 'ptz', 'bayonet', 'airport', 'hot', 'warehouse'].indexOf(newProperties.__type) !== -1) {
checkIcon(obj.id, oldProperties, newProperties, params.toolbarLayer);
}
// 调用接口
})
return
} else if(obj.primitive && obj.primitive instanceof FeatureGroundPrimitive) {
DialogPropertyGrid.show(obj.primitive, (data) => {
// 更新实体属性
setPropertyData(data, obj.primitive);
// 调用接口
})
}
}
}
}
// 绘制火情点 // 绘制火情点
const drawWarning = (options) => { const drawWarning = (options) => {
@ -29,17 +146,19 @@ const drawWarning = (options) => {
// 获取当前时间 // 获取当前时间
const time = new Date() const time = new Date()
// 获取icon的图片
getImage(fireWarningIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireWarningIcon, image: fireWarningIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -51,14 +170,19 @@ const drawWarning = (options) => {
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
discoveryTime: parseTime(time), discoveryTime: parseTime(time),
icon: fireWarningIcon,
changeAll: fireWarningIcon === fireWarningDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -103,7 +227,8 @@ const drawTrack = (options) => {
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties)
// 调用接口 // 调用接口
}); });
}); });
@ -122,18 +247,19 @@ const drawRanger = (options) => {
drawTool.drawPoint().then((position) => { drawTool.drawPoint().then((position) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(fireRangerIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireRangerIcon, image: fireRangerIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -144,14 +270,19 @@ const drawRanger = (options) => {
__type: 'ranger', __type: 'ranger',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: fireRangerIcon,
changeAll: fireRangerIcon === fireRangerDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -169,17 +300,19 @@ const drawPtz = (options) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(firePtzIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: firePtzIcon, image: firePtzIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -190,14 +323,19 @@ const drawPtz = (options) => {
__type: 'ptz', __type: 'ptz',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: firePtzIcon,
changeAll: firePtzIcon === firePtzDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -215,17 +353,19 @@ const drawBayonet = (options) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(fireBayonetIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireBayonetIcon, image: fireBayonetIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -236,14 +376,19 @@ const drawBayonet = (options) => {
__type: 'bayonet', __type: 'bayonet',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: fireBayonetIcon,
changeAll: fireBayonetIcon === fireBayonetDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -261,17 +406,19 @@ const drawHot = (options) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(fireHotIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireHotIcon, image: fireHotIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -282,14 +429,19 @@ const drawHot = (options) => {
__type: 'hot', __type: 'hot',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: fireHotIcon,
changeAll: fireHotIcon === fireHotDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -307,17 +459,19 @@ const drawAirport = (options) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(fireAirportIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireAirportIcon, image: fireAirportIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -328,14 +482,19 @@ const drawAirport = (options) => {
__type: 'airport', __type: 'airport',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: fireAirportIcon,
changeAll: fireAirportIcon === fireAirportDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -446,17 +605,19 @@ const drawWarehouse = (options) => {
// 计算中心点坐标 // 计算中心点坐标
const center = Cesium.Cartographic.fromCartesian(position); const center = Cesium.Cartographic.fromCartesian(position);
// 获取icon的图片
getImage(fireWarehouseIcon).then(image => {
const entity = toolbarLayer?.entities.add({ const entity = toolbarLayer?.entities.add({
position, position,
billboard: { billboard: {
image: fireWarehouseIcon, image: fireWarehouseIcon,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移 // pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
}, },
label: { label: {
text: '', text: '',
font: '14px sans-serif', font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6), pixelOffset: new Cesium.Cartesian2(0, - image.height - 6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
showBackground: true, showBackground: true,
@ -468,14 +629,19 @@ const drawWarehouse = (options) => {
name: '', name: '',
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6), longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6), latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
icon: fireWarehouseIcon,
changeAll: fireWarehouseIcon === fireWarehouseDefaultIcon ? 'true' : 'false',
} }
}); });
// 编辑属性 // 编辑属性
DialogPropertyGrid.show(entity, (data) => { DialogPropertyGrid.show(entity, (data) => {
// 更新实体属性 // 更新实体属性
setPropertyData(data, entity); const [oldProperties, newProperties] = setPropertyData(data, entity);
checkLabel(entity, oldProperties, newProperties);
checkIcon(entity, oldProperties, newProperties, toolbarLayer);
// 调用接口 // 调用接口
}); });
})
}); });
}; };
@ -598,4 +764,5 @@ export {
drawWatersource, drawWatersource,
drawRoad, drawRoad,
drawKeyarea, drawKeyarea,
pickFeatureProperty,
} }

View File

@ -10,11 +10,7 @@
import { shallowRef } from 'vue'; import { shallowRef } from 'vue';
import * as Cesium from 'cesium'; import * as Cesium from 'cesium';
import CesiumMap from '@/components/CesiumMap/index.vue'; import CesiumMap from '@/components/CesiumMap/index.vue';
import { useEventBus, ScreenMode } from '@/components/CesiumMap/mixins/useEventBus';
import Toolbar from './Toolbar'; import Toolbar from './Toolbar';
import DialogPropertyGrid from './DialogPropertyGrid';
import { setPropertyData } from './DialogPropertyGrid/property';
import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive';
const viewerRef = shallowRef(null) const viewerRef = shallowRef(null)
const options = ref({ const options = ref({
@ -36,38 +32,6 @@ const propertyData = ref([])
const initMap = (v) => { const initMap = (v) => {
viewerRef.value = v; viewerRef.value = v;
console.log('地图已初始化', v); console.log('地图已初始化', v);
const bus = useEventBus(viewerRef.value)
// view
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, ({ position }) => {
//
const pickedObjectList = viewerRef.value.scene.drillPick(position);
if (pickedObjectList.length > 0) {
//
for (let index = 0; index < pickedObjectList.length; index++) {
const obj = pickedObjectList[index];
if (obj && obj.id && obj.id instanceof Cesium.Entity) {
// name'__'
if(obj.id.name?.indexOf('__') === 0) {
continue
}
// getPropertyData(obj.id);
DialogPropertyGrid.show(obj.id, (data) => {
//
setPropertyData(data, obj.id);
//
})
return
} else if(obj.primitive && obj.primitive instanceof FeatureGroundPrimitive) {
DialogPropertyGrid.show(obj.primitive, (data) => {
//
setPropertyData(data, obj.primitive);
//
})
}
}
}
}, ScreenMode.VIEW)
}; };
</script> </script>