1.添加森防绘制,添加修改图标的属性;2.修改图标默认是修改当前图标,但也可以选择作用于所有此类要素,此时已经绘制的要素图标都修改,并修改对应要素类型的配置;
This commit is contained in:
parent
2817417d19
commit
8e6f5b5695
|
@ -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 }>, // type为select时需要
|
* options?: Array<{ label: string, value: any }>, // type为select时需要
|
||||||
* 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 类型返回空字符串,因为直接显示图像
|
||||||
}
|
}
|
||||||
// 对于其他类型,直接显示值,null或undefined显示空字符串
|
// 对于其他类型,直接显示值,null或undefined显示空字符串
|
||||||
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>
|
||||||
|
|
|
@ -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>
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 });
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue