1.扩展地图要素属性弹窗,添加日期类型编辑;2.集成火情点、巡护路线、护林员、云台、卡口、无人机机场、热点、林区道路、关键区域的绘制功能,添加相关属性配置;
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 782 B |
After Width: | Height: | Size: 840 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 707 B |
After Width: | Height: | Size: 735 B |
After Width: | Height: | Size: 981 B |
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 839 B After Width: | Height: | Size: 1.5 KiB |
|
@ -35,6 +35,7 @@
|
|||
<!-- 编辑模式 -->
|
||||
<div v-if="editingKey === row.key" class="editor-container">
|
||||
<!-- 根据属性类型渲染不同的编辑器 -->
|
||||
<!-- 选项类型编辑器 -->
|
||||
<template v-if="row.type === 'select'">
|
||||
<el-select
|
||||
v-model="editingValue"
|
||||
|
@ -52,7 +53,7 @@
|
|||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<!-- 颜色类型编辑器 -->
|
||||
<template v-else-if="row.type === 'color'">
|
||||
<el-color-picker
|
||||
v-model="editingValue"
|
||||
|
@ -62,7 +63,7 @@
|
|||
ref="editorRef"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 数值类型 -->
|
||||
<template v-else-if="row.type === 'number'">
|
||||
<el-input-number
|
||||
v-model="editingValue"
|
||||
|
@ -73,7 +74,32 @@
|
|||
ref="editorRef"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 日期类型编辑器 -->
|
||||
<template v-else-if="row.type === 'date'">
|
||||
<el-date-picker
|
||||
v-model="editingValue"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
size="small"
|
||||
@change="handleEditorChange(row, editingValue)"
|
||||
@blur="handleSave(row, editingValue)"
|
||||
ref="editorRef"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</template>
|
||||
<!-- 日期时间类型编辑器 -->
|
||||
<template v-else-if="row.type === 'datetime'">
|
||||
<el-date-picker
|
||||
v-model="editingValue"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
size="small"
|
||||
@change="handleEditorChange(row, editingValue)"
|
||||
@blur="handleSave(row, editingValue)"
|
||||
ref="editorRef"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- 默认使用 el-input -->
|
||||
<el-input
|
||||
|
@ -117,10 +143,12 @@ import {
|
|||
ElColorPicker,
|
||||
ElMessage,
|
||||
ElIcon,
|
||||
ElButton
|
||||
ElButton,
|
||||
ElDatePicker,
|
||||
} from 'element-plus';
|
||||
import { Close } from '@element-plus/icons-vue';
|
||||
import { useDraggable, useElementBounding, useWindowSize } from '@vueuse/core';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
|
@ -130,7 +158,7 @@ const props = defineProps({
|
|||
* key: string | number, // 唯一标识
|
||||
* name: string, // 属性名称
|
||||
* value: any, // 属性值
|
||||
* type: 'text' | 'number' | 'select' | 'color', // 编辑器类型
|
||||
* type: 'text' | 'number' | 'select' | 'color' | 'date' | 'datetime', // 编辑器类型
|
||||
* options?: Array<{ label: string, value: any }>, // type为select时需要
|
||||
* checkMethod?: (newValue: any, property: object) => boolean | Promise<boolean>, // 检查方法
|
||||
* disabled?: boolean, // 是否禁用该属性,禁用后不可编辑,默认为 false
|
||||
|
@ -138,8 +166,7 @@ const props = defineProps({
|
|||
*/
|
||||
data: {
|
||||
type: Array,
|
||||
// default: () => []
|
||||
default: () => [{a:1}] // 默认值为一个空数组
|
||||
default: () => []
|
||||
},
|
||||
/**
|
||||
* 保存按钮点击后的回调函数 (由外部 DialogPropertyGrid.js 传入)
|
||||
|
@ -314,7 +341,7 @@ const handleEditorChange = (row, newValue) => {
|
|||
}
|
||||
|
||||
// 对于select和color-picker,change事件通常意味着编辑完成,可以直接触发保存
|
||||
if (row.type === 'select' || row.type === 'color') {
|
||||
if (row.type === 'select' || row.type === 'color' || row.type === 'date' || row.type === 'datetime') {
|
||||
handleSave(row, newValue);
|
||||
} else {
|
||||
// 对于input和number,change/input更新editingValue,blur/enter触发保存
|
||||
|
@ -434,6 +461,26 @@ const getDisplayValue = (row) => {
|
|||
if (row.type === 'select' && row.options) {
|
||||
const option = row.options.find(opt => opt.value === row.value);
|
||||
return option ? option.label : row.value; // 如果找不到匹配的option,显示原始值
|
||||
} else if (row.type === 'date' && row.value) { // 日期类型显示逻辑
|
||||
try {
|
||||
const date = new Date(row.value);
|
||||
if (!isNaN(date.getTime())) { // 检查是否是有效日期
|
||||
return parseTime(date, '{y}-{m}-{d}'); // 使用 parseTime 格式化日期
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error formatting date for display:", e);
|
||||
}
|
||||
return row.value; // 格式化失败时返回原始值
|
||||
} else if (row.type === 'datetime' && row.value) { // 新增:日期时间类型显示逻辑
|
||||
try {
|
||||
const date = new Date(row.value);
|
||||
if (!isNaN(date.getTime())) { // 检查是否是有效日期时间
|
||||
return parseTime(date, '{y}-{m}-{d} {h}:{i}:{s}'); // 使用 parseTime 格式化日期时间
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error formatting datetime for display:", e);
|
||||
}
|
||||
return row.value; // 格式化失败时返回原始值
|
||||
}
|
||||
// 对于其他类型,直接显示值,null或undefined显示空字符串
|
||||
return row.value !== null && row.value !== undefined ? row.value : '';
|
||||
|
@ -549,6 +596,7 @@ defineExpose({
|
|||
.editor-container .el-input,
|
||||
.editor-container .el-input-number,
|
||||
.editor-container .el-select,
|
||||
.editor-container .el-color-picker,
|
||||
.editor-container .el-color-picker {
|
||||
width: 100%; /* 使编辑器宽度填充父容器 */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,332 @@
|
|||
import * as Cesium from 'cesium'
|
||||
|
||||
// 定义火情点的属性
|
||||
export const warning = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "火情点",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "点位名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "deviceModel",
|
||||
name: "设备型号",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "deviceType",
|
||||
name: "设备类型",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "amountOfDamage",
|
||||
name: "受损金额",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "fireArea",
|
||||
name: "火灾面积",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "fireLevel",
|
||||
name: "火情等级",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "causeOfFire",
|
||||
name: "起火原因",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "discoveryTime",
|
||||
name: "发现时间",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
// 定义巡护路线的属性
|
||||
export const track = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "巡护路线",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "length",
|
||||
name: "长度",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: true,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义护林员的属性
|
||||
export const ranger = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "护林员",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "人员名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "phone",
|
||||
name: "联系电话",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
// 定义云台的属性
|
||||
export const ptz = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "云台",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "云台名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "no",
|
||||
name: "云台编号",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "equipmentManufacturers",
|
||||
name: "设备厂商",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义卡口的属性
|
||||
export const bayonet = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "卡口",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "卡口名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "no",
|
||||
name: "卡口编号",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "equipmentManufacturers",
|
||||
name: "设备厂商",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义无人机机场的属性
|
||||
export const airport = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "无人机机场",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "机场名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "no",
|
||||
name: "机场编号",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "equipmentManufacturers",
|
||||
name: "设备厂商",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义热点的属性
|
||||
export const hot = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "热点",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "热点名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "fireLevel",
|
||||
name: "火情等级",
|
||||
type: "select",
|
||||
value: "",
|
||||
options: [
|
||||
{ label: "一级", value: "1" },
|
||||
{ label: "二级", value: "2" },
|
||||
{ label: "三级", value: "3" },
|
||||
],
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义水源地的属性
|
||||
export const watersource = [
|
||||
{
|
||||
|
@ -78,6 +405,119 @@ export const warehouse = [
|
|||
},
|
||||
];
|
||||
|
||||
// 定义林区道路的属性
|
||||
export const road = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "林区道路",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "道路名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "roadType",
|
||||
name: "道路类型",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "length",
|
||||
name: "道路长度",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "width",
|
||||
name: "道路宽度",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
|
||||
// 定义重点区域的属性
|
||||
export const keyarea = [
|
||||
{
|
||||
key: "type",
|
||||
name: "要素类型",
|
||||
type: "text",
|
||||
value: "重点区域",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
name: "名称",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "area",
|
||||
name: "占地面积",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "longitude",
|
||||
name: "经度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "latitude",
|
||||
name: "纬度",
|
||||
type: "text",
|
||||
value: "0",
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: "description",
|
||||
name: "区域说明",
|
||||
type: "text",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "startTime",
|
||||
name: "开始监管时间",
|
||||
type: "datetime",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "endTime",
|
||||
name: "结束监管时间",
|
||||
type: "datetime",
|
||||
value: "",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const config = {
|
||||
warning,
|
||||
track,
|
||||
ranger,
|
||||
ptz,
|
||||
bayonet,
|
||||
airport,
|
||||
hot,
|
||||
watersource,
|
||||
warehouse,
|
||||
road,
|
||||
keyarea,
|
||||
}
|
||||
|
||||
const getClone = (config) => {
|
||||
return config.map(item => ({ ...item }))
|
||||
}
|
||||
|
@ -89,11 +529,11 @@ export const getPropertyData = (entity) => {
|
|||
}
|
||||
|
||||
const properties = entity.properties.getValue()
|
||||
if (properties.__type === "watersource") {
|
||||
data = getClone(watersource)
|
||||
} else if (properties.__type === "warehouse") {
|
||||
data = getClone(warehouse)
|
||||
if (!properties.__type || !config[properties.__type]) {
|
||||
console.warn('__type属性无效,或__type属性的值不存在于配置对象中')
|
||||
return data
|
||||
}
|
||||
data = getClone(config[properties.__type])
|
||||
|
||||
// 遍历数据数组,将properties有的属性赋给对应的属性
|
||||
// 注意:地图要素属性主要参考这里的数据结构,就算properties没有值,也会显示出来
|
||||
|
@ -120,4 +560,9 @@ export const setPropertyData = (data, entity) => {
|
|||
})
|
||||
// 替换 properties
|
||||
entity.properties = new Cesium.PropertyBag(newProperties)
|
||||
|
||||
// 这里默认name字段是标签显示的内容,如果entity有label,则更新name字段值
|
||||
if(entity.label) {
|
||||
entity.label.text = new Cesium.ConstantProperty(newProperties.name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,11 +56,20 @@ import {
|
|||
drawAttackArrow,
|
||||
drawDoubleArrow,
|
||||
drawMeasureDistance,
|
||||
drawMeasureArea
|
||||
drawMeasureArea,
|
||||
} from './baseDraw'
|
||||
import {
|
||||
drawWarning,
|
||||
drawTrack,
|
||||
drawRanger,
|
||||
drawPtz,
|
||||
drawBayonet,
|
||||
drawAirport,
|
||||
drawHot,
|
||||
drawWarehouse,
|
||||
drawWatersource,
|
||||
drawWarehouse
|
||||
drawRoad,
|
||||
drawKeyarea,
|
||||
} from './forestFireDraw'
|
||||
|
||||
// 工具栏图标
|
||||
|
@ -80,8 +89,17 @@ import toolbarDoubleArrowIcon from '@/assets/icons/toolbar_double_arrow.png';
|
|||
import toolbarMeasureDistanceIcon from '@/assets/icons/toolbar_measure_distance.png';
|
||||
import toolbarMeasureAreaIcon from '@/assets/icons/toolbar_measure_area.png';
|
||||
// 森防绘制工具图标
|
||||
import toolbarWarningIcon from '@/assets/icons/toolbar_warning.png';
|
||||
import toolbarTrackIcon from '@/assets/icons/toolbar_track.png';
|
||||
import toolbarRangerIcon from '@/assets/icons/toolbar_ranger.png';
|
||||
import toolbarPtzIcon from '@/assets/icons/toolbar_ptz.png';
|
||||
import toolbarBayonetIcon from '@/assets/icons/toolbar_bayonet.png';
|
||||
import toolbarAirportIcon from '@/assets/icons/toolbar_airport.png';
|
||||
import toolbarHotIcon from '@/assets/icons/toolbar_hot.png';
|
||||
import toolbarWarehouseIcon from '@/assets/icons/toolbar_warehouse.png';
|
||||
import toolbarWatersourceIcon from '@/assets/icons/toolbar_watersource.png';
|
||||
import toolbarRoadIcon from '@/assets/icons/toolbar_road.png';
|
||||
import toolbarKeyareaIcon from '@/assets/icons/toolbar_keyarea.png';
|
||||
|
||||
const props = defineProps({
|
||||
viewer: {
|
||||
|
@ -163,14 +181,61 @@ const options = ref([
|
|||
label: '森防绘制',
|
||||
subtools: [
|
||||
{
|
||||
id: 21,
|
||||
name: 'warning',
|
||||
label: '火情点',
|
||||
icon: toolbarWarningIcon
|
||||
}, {
|
||||
id: 22,
|
||||
name: 'track',
|
||||
label: '巡护路线',
|
||||
icon: toolbarTrackIcon
|
||||
}, {
|
||||
id: 23,
|
||||
name: 'ranger',
|
||||
label: '护林员',
|
||||
icon: toolbarRangerIcon
|
||||
}, {
|
||||
id: 24,
|
||||
name: 'ptz',
|
||||
label: '云台',
|
||||
icon: toolbarPtzIcon
|
||||
}, {
|
||||
id: 25,
|
||||
name: 'bayonet',
|
||||
label: '卡口',
|
||||
icon: toolbarBayonetIcon
|
||||
}, {
|
||||
id: 26,
|
||||
name: 'airport',
|
||||
label: '无人机机场',
|
||||
icon: toolbarAirportIcon
|
||||
}, {
|
||||
id: 27,
|
||||
name: 'hot',
|
||||
label: '热点',
|
||||
icon: toolbarHotIcon
|
||||
}, {
|
||||
id: 28,
|
||||
name: 'warehouse',
|
||||
label: '仓库',
|
||||
icon: toolbarWarehouseIcon
|
||||
}, {
|
||||
id: 29,
|
||||
name: 'watersource',
|
||||
label: '水源',
|
||||
icon: toolbarWatersourceIcon
|
||||
}
|
||||
}, {
|
||||
id: 210,
|
||||
name: 'road',
|
||||
label: '林区道路',
|
||||
icon: toolbarRoadIcon
|
||||
}, {
|
||||
id: 211,
|
||||
name: 'keyarea',
|
||||
label: '重点区域',
|
||||
icon: toolbarKeyareaIcon
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -232,6 +297,7 @@ watch(() => props.viewer, (v) => {
|
|||
primitiveList,
|
||||
}
|
||||
bus = useEventBus(viewer);
|
||||
// 基础绘制部分
|
||||
bus.on('toolbar_location', drawLocation);
|
||||
bus.on('toolbar_polyline', drawPolyline);
|
||||
bus.on('toolbar_polygon', drawPolygon);
|
||||
|
@ -242,8 +308,19 @@ watch(() => props.viewer, (v) => {
|
|||
bus.on('toolbar_doubleArrow', drawDoubleArrow);
|
||||
bus.on('toolbar_measureDistance', drawMeasureDistance);
|
||||
bus.on('toolbar_measureArea', drawMeasureArea);
|
||||
// 森防绘制部分
|
||||
bus.on('toolbar_warning', drawWarning);
|
||||
bus.on('toolbar_track', drawTrack);
|
||||
bus.on('toolbar_ranger', drawRanger);
|
||||
bus.on('toolbar_ptz', drawPtz);
|
||||
bus.on('toolbar_bayonet', drawBayonet);
|
||||
bus.on('toolbar_airport', drawAirport);
|
||||
bus.on('toolbar_hot', drawHot);
|
||||
bus.on('toolbar_watersource', drawWatersource);
|
||||
bus.on('toolbar_warehouse', drawWarehouse);
|
||||
bus.on('toolbar_road', drawRoad);
|
||||
bus.on('toolbar_keyarea', drawKeyarea);
|
||||
// 清空
|
||||
bus.on('toolbar_clear', toolbarClear);
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
|
|
@ -2,10 +2,343 @@ import * as Cesium from 'cesium'
|
|||
import DialogPropertyGrid from '../DialogPropertyGrid';
|
||||
import { setPropertyData } from '../DialogPropertyGrid/property';
|
||||
import FeatureGroundPrimitive from '@/components/CesiumMap/FeatureGroundPrimitive';
|
||||
import { getArea, getBoundingCenterCoordinate } from '@/components/CesiumMap/mixins/useMeasureTool';
|
||||
import { getDistance, getArea, getBoundingCenterCoordinate, getBoundingCenter } from '@/components/CesiumMap/mixins/useMeasureTool';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
import fireWarningIcon from '@/assets/icons/fire_warning.png';
|
||||
import fireRangerIcon from '@/assets/icons/fire_ranger.png';
|
||||
import firePtzIcon from '@/assets/icons/fire_ptz.png';
|
||||
import fireBayonetIcon from '@/assets/icons/fire_bayonet.png';
|
||||
import fireAirportIcon from '@/assets/icons/fire_airport.png';
|
||||
import fireHotIcon from '@/assets/icons/fire_hot.png';
|
||||
import fireWarehouseIcon from '@/assets/icons/fire_warehouse.png';
|
||||
|
||||
// 绘制火情点
|
||||
const drawWarning = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
// 获取当前时间
|
||||
const time = new Date()
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: fireWarningIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(255, 0, 0).withAlpha(0.4),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'warning',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
discoveryTime: parseTime(time),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制巡护路线
|
||||
const drawTrack = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPolyline().then((positions) => {
|
||||
// 计算中心点坐标
|
||||
const position = getBoundingCenter(positions, 100);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
polyline: {
|
||||
positions,
|
||||
width: 8,
|
||||
material: Cesium.Color.fromCssColorString('#DCE057'),
|
||||
clampToGround: true,
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px Sans-Serif',
|
||||
fillColor: Cesium.Color.fromCssColorString('#DCE057'),
|
||||
outlineColor: Cesium.Color.fromCssColorString('#FFFFFF'),
|
||||
outlineWidth: 2,
|
||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||
pixelOffset: new Cesium.Cartesian2(0, -5),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
||||
},
|
||||
properties: {
|
||||
__type: 'track',
|
||||
length: getDistance(positions).toFixed(2),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制护林员(点)
|
||||
const drawRanger = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: fireRangerIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(155, 206, 255).withAlpha(0.15),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'ranger',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制云台(点)
|
||||
const drawPtz = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: firePtzIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(35, 206, 235).withAlpha(0.45),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'ptz',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制卡口(点)
|
||||
const drawBayonet = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: fireBayonetIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(233, 189, 128).withAlpha(0.45),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'bayonet',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制热点
|
||||
const drawHot = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: fireHotIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(255, 0, 0).withAlpha(0.4),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'hot',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制无人机机场(点)
|
||||
const drawAirport = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPoint().then((position) => {
|
||||
// 计算中心点坐标
|
||||
const center = Cesium.Cartographic.fromCartesian(position);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
billboard: {
|
||||
image: fireAirportIcon,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(164, 255, 147).withAlpha(0.4),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'airport',
|
||||
longitude: Cesium.Math.toDegrees(center.longitude).toFixed(6),
|
||||
latitude: Cesium.Math.toDegrees(center.latitude).toFixed(6),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制水源地(面)
|
||||
const drawWatersource = (options) => {
|
||||
const { drawTool, measureTool, viewer, primitiveList } = options;
|
||||
|
@ -120,6 +453,16 @@ const drawWarehouse = (options) => {
|
|||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18), // 可选偏移
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px sans-serif',
|
||||
pixelOffset: new Cesium.Cartesian2(0, 18 - 96 - 6),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
showBackground: true,
|
||||
backgroundColor : Cesium.Color.fromBytes(155, 206, 255).withAlpha(0.4),
|
||||
backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||
},
|
||||
properties: {
|
||||
__type: 'warehouse',
|
||||
name: '',
|
||||
|
@ -136,7 +479,123 @@ const drawWarehouse = (options) => {
|
|||
});
|
||||
};
|
||||
|
||||
export {
|
||||
drawWatersource,
|
||||
drawWarehouse
|
||||
// 绘制林区道路
|
||||
const drawRoad = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPolyline().then((positions) => {
|
||||
// 计算中心点坐标
|
||||
const position = getBoundingCenter(positions, 100);
|
||||
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position,
|
||||
polyline: {
|
||||
positions,
|
||||
width: 5,
|
||||
material: new Cesium.PolylineOutlineMaterialProperty({
|
||||
color: Cesium.Color.fromCssColorString('#fecd78'),
|
||||
outlineColor: Cesium.Color.fromCssColorString('#d29661'),
|
||||
outlineWidth: 2,
|
||||
}),
|
||||
clampToGround: true,
|
||||
},
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px Sans-Serif',
|
||||
fillColor: Cesium.Color.fromCssColorString('#fecd78'),
|
||||
outlineColor: Cesium.Color.fromCssColorString('#FFFFFF'),
|
||||
outlineWidth: 2,
|
||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||
pixelOffset: new Cesium.Cartesian2(0, -5),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
||||
},
|
||||
properties: {
|
||||
__type: 'road',
|
||||
length: getDistance(positions).toFixed(2),
|
||||
}
|
||||
});
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 绘制重点区域(面)
|
||||
const drawKeyarea = (options) => {
|
||||
const { drawTool, measureTool, toolbarLayer } = options;
|
||||
if(!drawTool) {
|
||||
console.error('绘制工具未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
drawTool.abort();
|
||||
measureTool.abort();
|
||||
drawTool.drawPolygon().then((positions) => {
|
||||
// 计算中心点坐标
|
||||
const center = getBoundingCenterCoordinate(positions);
|
||||
|
||||
// 添加实体
|
||||
const entity = toolbarLayer?.entities.add({
|
||||
position: Cesium.Cartesian3.fromDegrees(center[0], center[1], 100),
|
||||
label: {
|
||||
text: '',
|
||||
font: '14px Sans-Serif',
|
||||
fillColor: Cesium.Color.RED,
|
||||
outlineColor: Cesium.Color.fromCssColorString('#FFFFFF'),
|
||||
outlineWidth: 2,
|
||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||
pixelOffset: new Cesium.Cartesian2(0, -5),
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
||||
},
|
||||
polyline: {
|
||||
positions:[...positions, positions[0]], // 闭合多边形
|
||||
width: 2,
|
||||
material: Cesium.Color.RED,
|
||||
clampToGround: true,
|
||||
},
|
||||
polygon: {
|
||||
hierarchy: positions,
|
||||
material: Cesium.Color.RED.withAlpha(0.3),
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
},
|
||||
properties: {
|
||||
__type: 'keyarea',
|
||||
area: getArea(positions).toFixed(2), // 面积
|
||||
longitude: center[0].toFixed(6),
|
||||
latitude: center[1].toFixed(6),
|
||||
}
|
||||
});
|
||||
|
||||
// 编辑属性
|
||||
DialogPropertyGrid.show(entity, (data) => {
|
||||
// 更新实体属性
|
||||
setPropertyData(data, entity);
|
||||
// 调用接口
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export {
|
||||
drawWarning,
|
||||
drawTrack,
|
||||
drawRanger,
|
||||
drawPtz,
|
||||
drawBayonet,
|
||||
drawAirport,
|
||||
drawHot,
|
||||
drawWarehouse,
|
||||
drawWatersource,
|
||||
drawRoad,
|
||||
drawKeyarea,
|
||||
}
|
||||
|
|