2537 lines
84 KiB
Vue
2537 lines
84 KiB
Vue
<template>
|
||
<div ref="vChartRef" id="mars3d-container" class="mars3d-container">
|
||
<div class="annotationButtons">
|
||
<div
|
||
:class="mapDrawType == 'drawPoint' ? 'button_choose' : 'button_nochoose'"
|
||
@click="drawPoint"
|
||
>
|
||
<a-popover placement="left">
|
||
<template #content>
|
||
<div style="display: flex; gap: 5px">
|
||
<div
|
||
class="popoverAnnotation"
|
||
v-for="color in ['#2D8CF0', '#19BE6B', '#FFBB00', '#E23C39', '#B620E0']"
|
||
:key="color"
|
||
:style="{ background: color }"
|
||
@click="drawColorPoint = color"
|
||
>
|
||
<CheckOutlined v-if="drawColorPoint == color" style="color: white" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<AntDesignOutlined
|
||
:style="{
|
||
color: drawColorPoint,
|
||
fontSize: '20px',
|
||
}"
|
||
/>
|
||
</a-popover>
|
||
</div>
|
||
<div
|
||
:class="mapDrawType == 'drawPolyline' ? 'button_choose' : 'button_nochoose'"
|
||
@click="drawPolyline"
|
||
>
|
||
<a-popover placement="left">
|
||
<template #content>
|
||
<div style="display: flex; gap: 5px">
|
||
<div
|
||
class="popoverAnnotation"
|
||
v-for="color in ['#2D8CF0', '#19BE6B', '#FFBB00', '#E23C39', '#B620E0']"
|
||
:key="color"
|
||
:style="{ background: color }"
|
||
@click="drawColorPolyline = color"
|
||
>
|
||
<CheckOutlined v-if="drawColorPolyline == color" style="color: white" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<ExpandAltOutlined
|
||
:style="{
|
||
color: drawColorPolyline,
|
||
fontSize: '20px',
|
||
}"
|
||
/>
|
||
</a-popover>
|
||
</div>
|
||
<div
|
||
:class="mapDrawType == 'drawPolygon' ? 'button_choose' : 'button_nochoose'"
|
||
@click="drawPolygon"
|
||
>
|
||
<a-popover placement="left">
|
||
<template #content>
|
||
<div style="display: flex; gap: 5px">
|
||
<div
|
||
class="popoverAnnotation"
|
||
v-for="color in ['#2D8CF0', '#19BE6B', '#FFBB00', '#E23C39', '#B620E0']"
|
||
:key="color"
|
||
:style="{ background: color }"
|
||
@click="drawColorPolygon = color"
|
||
>
|
||
<CheckOutlined v-if="drawColorPolygon == color" style="color: white" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<BorderOutlined
|
||
:style="{
|
||
color: drawColorPolygon,
|
||
fontSize: '20px',
|
||
}"
|
||
/>
|
||
</a-popover>
|
||
</div>
|
||
<div
|
||
:class="mapDrawType == 'drawCricle' ? 'button_choose' : 'button_nochoose'"
|
||
@click="drawCricle"
|
||
>
|
||
<a-popover placement="left">
|
||
<template #content>
|
||
<div style="display: flex; gap: 5px">
|
||
<div
|
||
class="popoverAnnotation"
|
||
v-for="color in ['#2D8CF0', '#19BE6B', '#FFBB00', '#E23C39', '#B620E0']"
|
||
:key="color"
|
||
:style="{ background: color }"
|
||
@click="drawColorCricle = color"
|
||
>
|
||
<CheckOutlined v-if="drawColorCricle == color" style="color: white" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<LogoutOutlined
|
||
:style="{
|
||
color: drawColorCricle,
|
||
fontSize: '20px',
|
||
}"
|
||
/>
|
||
</a-popover>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="areaButtons">
|
||
<div
|
||
:class="mapAreaDrawFlag ? 'button_choose' : 'button_nochoose'"
|
||
style="border-radius: 3px"
|
||
@click="drawArea"
|
||
>
|
||
<a-popover placement="leftTop">
|
||
<template #content>
|
||
<div style="display: block; gap: 5px; width: 170px">
|
||
<div
|
||
class="popoverArea"
|
||
v-for="type in [
|
||
'nfz_Polygon',
|
||
'nfz_Circle',
|
||
'dfence_Polygon',
|
||
'dfence_Circle',
|
||
'noland_Polygon',
|
||
]"
|
||
:key="type"
|
||
:style="{ background: '#ffffff' }"
|
||
@click="areaDrawType = type"
|
||
>
|
||
<div
|
||
v-if="type.indexOf('noland') > -1"
|
||
:style="{
|
||
width: '15px',
|
||
height: '15px',
|
||
outline: `2px solid #FF9900`,
|
||
'margin-right': '6px',
|
||
}"
|
||
/>
|
||
<div
|
||
v-if="type.indexOf('dfence') > -1"
|
||
:style="{
|
||
width: '13px',
|
||
height: '13px',
|
||
outline: `2px solid #00FF00`,
|
||
'margin-right': '6px',
|
||
'border-radius': type == 'dfence_Circle' ? '6.5px' : '0px',
|
||
}"
|
||
/>
|
||
<div
|
||
v-if="type.indexOf('nfz') > -1"
|
||
:style="{
|
||
width: '13px',
|
||
height: '13px',
|
||
outline: `2px solid #FF0000`,
|
||
background: `#FF000055`,
|
||
'margin-right': '6px',
|
||
'border-radius': type == 'nfz_Circle' ? '6.5px' : '0px',
|
||
}"
|
||
/>
|
||
<div style="width: 130px" v-if="type == 'nfz_Polygon'">自定义多边形限飞区</div>
|
||
<div style="width: 130px" v-if="type == 'nfz_Circle'">自定义圆形限飞区</div>
|
||
<div style="width: 130px" v-if="type == 'dfence_Polygon'">自定义多边形作业区</div>
|
||
<div style="width: 130px" v-if="type == 'dfence_Circle'">自定义圆形作业区</div>
|
||
<div style="width: 130px" v-if="type == 'noland_Polygon'">自定义禁降区</div>
|
||
<CheckOutlined v-if="areaDrawType == type" style="color: blue; margin-left: 10px" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<div
|
||
v-if="areaDrawType.indexOf('noland') > -1"
|
||
:style="{
|
||
width: '16px',
|
||
height: '16px',
|
||
outline: `2px solid #FF9900`,
|
||
}"
|
||
/>
|
||
<div
|
||
v-if="areaDrawType.indexOf('dfence') > -1"
|
||
:style="{
|
||
width: '16px',
|
||
height: '16px',
|
||
outline: `2px solid #00FF00`,
|
||
|
||
'border-radius': areaDrawType == 'dfence_Circle' ? '6.5px' : '0px',
|
||
}"
|
||
/>
|
||
<div
|
||
v-if="areaDrawType.indexOf('nfz') > -1"
|
||
:style="{
|
||
width: '16px',
|
||
height: '16px',
|
||
outline: `2px solid #FF0000`,
|
||
background: `#FF000055`,
|
||
'border-radius': areaDrawType == 'nfz_Circle' ? '6.5px' : '0px',
|
||
}"
|
||
/>
|
||
</a-popover>
|
||
</div>
|
||
</div> -->
|
||
</div>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import { ref, watch, onMounted, defineEmits } from 'vue';
|
||
import * as mars3d from 'mars3d';
|
||
import * as Cesium from 'mars3d-cesium';
|
||
import { circle, rect, triangle } from './svg';
|
||
import {
|
||
CheckOutlined,
|
||
AntDesignOutlined,
|
||
ExpandAltOutlined,
|
||
BorderOutlined,
|
||
LogoutOutlined,
|
||
} from '@ant-design/icons-vue';
|
||
import {
|
||
AddAnnotation,
|
||
UpdateAnnotation,
|
||
AddWorkArea,
|
||
UpdateWorkArea,
|
||
} from '@/api/demo/mediaLibrary';
|
||
import {
|
||
locateBack,
|
||
defaultIcon,
|
||
fireIcon,
|
||
peopleIcon,
|
||
warnIcon,
|
||
carIcon,
|
||
checkIcon,
|
||
closeIcon,
|
||
} from './svg';
|
||
import * as turf from '@turf/turf';
|
||
import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform';
|
||
import dayjs from 'dayjs';
|
||
|
||
const props = defineProps([
|
||
'allAnnotationDataList',
|
||
'nowShowAnnotationData',
|
||
'allImageDataList',
|
||
'nowShowImageData',
|
||
'allAreaDataList',
|
||
'nowShowAreaData',
|
||
]);
|
||
const emits = defineEmits([
|
||
'setNowShowAnnotationData',
|
||
'setNowShowImageData',
|
||
'setNowShowAreaData',
|
||
'closePathImageInfo',
|
||
'setAllAnnotationData',
|
||
'setAllImageData',
|
||
'setAllAreaData',
|
||
]);
|
||
|
||
const vChartRef: any = ref<HTMLElement>();
|
||
let map: mars3d.Map; // 地图对象
|
||
let graphicLayers = new mars3d.layer.GraphicLayer({
|
||
isAutoEditing: true,
|
||
});
|
||
// 地图标注
|
||
// 地图标注-点
|
||
let annotation_PointGraphicData: any = [];
|
||
// 地图标注-线
|
||
let annotation_LineStringGraphicData: any = [];
|
||
// 地图标注-多边形
|
||
let annotation_PolygonGraphicData: any = [];
|
||
// 地图标注-圈
|
||
let annotation_CircleGraphicData: any = [];
|
||
|
||
// 地图照片
|
||
// 地图照片-地面点
|
||
let image_bottomPointGraphicData: any = [];
|
||
// 地图照片-飞行点
|
||
let image_flightointGraphicData: any = [];
|
||
// 地图照片-地面点到展示图片的线
|
||
let image_bottomImagePolylineGraphicData: any = [];
|
||
// 地图照片-展示图片
|
||
let image_imageGraphicData: any = [];
|
||
|
||
// 地图作业区域
|
||
// 地图作业区域-禁降区-多边形
|
||
let area_noland_PolygonGraphicData: any = [];
|
||
// 地图作业区域-作业区-多边形
|
||
let area_dfence_PolygonGraphicData: any = [];
|
||
// 地图作业区域-作业区-圈
|
||
let area_dfence_CircleGraphicData: any = [];
|
||
// 地图作业区域-限飞区-多边形
|
||
let area_nfz_PolygonGraphicData: any = [];
|
||
// 地图作业区域-限飞区-圈
|
||
let area_nfz_CircleGraphicData: any = [];
|
||
|
||
onMounted(() => {
|
||
initMap();
|
||
});
|
||
|
||
const initMap = () => {
|
||
map = new mars3d.Map(vChartRef.value, {
|
||
scene: {
|
||
center: {
|
||
lat: 35.134608,
|
||
lng: 118.29853,
|
||
alt: 8306.3,
|
||
heading: 360,
|
||
pitch: -45,
|
||
},
|
||
scene3DOnly: false,
|
||
shadows: false,
|
||
removeDblClick: true,
|
||
sceneMode: 3,
|
||
showSun: true,
|
||
showMoon: true,
|
||
showSkyBox: true,
|
||
showSkyAtmosphere: true,
|
||
fog: true,
|
||
fxaa: true,
|
||
requestRenderMode: true,
|
||
contextOptions: {
|
||
requestWebgl1: false,
|
||
webgl: {
|
||
preserveDrawingBuffer: true,
|
||
alpha: false,
|
||
stencil: true,
|
||
powerPreference: 'high-performance',
|
||
},
|
||
},
|
||
globe: {
|
||
depthTestAgainstTerrain: false,
|
||
baseColor: '#546a53',
|
||
showGroundAtmosphere: true,
|
||
enableLighting: false,
|
||
},
|
||
cameraController: {
|
||
zoomFactor: 3,
|
||
minimumZoomDistance: 1,
|
||
maximumZoomDistance: 50000000,
|
||
enableRotate: true,
|
||
enableTranslate: true,
|
||
enableTilt: true,
|
||
enableZoom: true,
|
||
enableCollisionDetection: true,
|
||
minimumCollisionTerrainHeight: 15000,
|
||
},
|
||
},
|
||
control: {
|
||
homeButton: true,
|
||
baseLayerPicker: false,
|
||
sceneModePicker: true,
|
||
vrButton: false,
|
||
fullscreenButton: true,
|
||
navigationHelpButton: true,
|
||
animation: false,
|
||
timeline: false,
|
||
infoBox: false,
|
||
geocoder: false,
|
||
selectionIndicator: false,
|
||
showRenderLoopErrors: true,
|
||
contextmenu: {
|
||
hasDefault: true,
|
||
},
|
||
mouseDownView: true,
|
||
zoom: {
|
||
insertIndex: 1,
|
||
},
|
||
compass: {
|
||
bottom: 'toolbar',
|
||
left: '5px',
|
||
rotation: true,
|
||
},
|
||
distanceLegend: {
|
||
left: '10px',
|
||
bottom: '2px',
|
||
},
|
||
locationBar: {
|
||
crs: 'CGCS2000_GK_Zone_3',
|
||
crsDecimal: 0,
|
||
template:
|
||
"<div>经度:{lng}</div> <div>纬度:{lat}</div> <div class='hide1000'>横{crsx} 纵{crsy}</div> <div>海拔:{alt}米</div> <div class='hide700'>层级:{level}</div><div>方向:{heading}°</div> <div>俯仰角:{pitch}°</div><div class='hide700'>视高:{cameraHeight}米</div>",
|
||
cacheTime: 50,
|
||
},
|
||
},
|
||
method: {
|
||
templateValues: {
|
||
dataServer: '//data.mars3d.cn',
|
||
gltfServerUrl: '//data.mars3d.cn/gltf',
|
||
},
|
||
},
|
||
terrain: {
|
||
url: '//data.mars3d.cn/terrain',
|
||
show: true,
|
||
clip: true,
|
||
},
|
||
basemaps: [
|
||
{
|
||
id: 10,
|
||
name: '地图底图',
|
||
type: 'group',
|
||
opacity: 1,
|
||
},
|
||
{
|
||
id: 2021,
|
||
pid: 10,
|
||
name: '天地图影像',
|
||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||
type: 'group',
|
||
layers: [
|
||
{
|
||
name: '底图',
|
||
type: 'tdt',
|
||
layer: 'img_d',
|
||
eventParent: {
|
||
id: 2021,
|
||
pid: 10,
|
||
name: '天地图影像',
|
||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||
type: 'group',
|
||
layers: [
|
||
{
|
||
name: '底图',
|
||
type: 'tdt',
|
||
layer: 'img_d',
|
||
show: true,
|
||
},
|
||
{
|
||
name: '注记',
|
||
type: 'tdt',
|
||
layer: 'img_z',
|
||
show: true,
|
||
},
|
||
],
|
||
show: true,
|
||
},
|
||
private: false,
|
||
id: 'm-770c35e7-9054-4259-b5ee-c15f108becd0',
|
||
opacity: 1,
|
||
pid: 2021,
|
||
parent: {
|
||
id: 2021,
|
||
pid: 10,
|
||
name: '天地图影像',
|
||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||
type: 'group',
|
||
layers: [
|
||
{
|
||
name: '底图',
|
||
type: 'tdt',
|
||
layer: 'img_d',
|
||
show: true,
|
||
},
|
||
{
|
||
name: '注记',
|
||
type: 'tdt',
|
||
layer: 'img_z',
|
||
show: true,
|
||
},
|
||
],
|
||
show: true,
|
||
},
|
||
zIndex: 1,
|
||
},
|
||
{
|
||
name: '注记',
|
||
type: 'tdt',
|
||
layer: 'img_z',
|
||
eventParent: {
|
||
id: 2021,
|
||
pid: 10,
|
||
name: '天地图影像',
|
||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||
type: 'group',
|
||
layers: [
|
||
{
|
||
name: '底图',
|
||
type: 'tdt',
|
||
layer: 'img_d',
|
||
show: true,
|
||
},
|
||
{
|
||
name: '注记',
|
||
type: 'tdt',
|
||
layer: 'img_z',
|
||
show: true,
|
||
},
|
||
],
|
||
show: true,
|
||
},
|
||
private: false,
|
||
id: 'm-3b881368-574b-48a5-88b2-8b3c2c48fd62',
|
||
opacity: 1,
|
||
pid: 2021,
|
||
parent: {
|
||
id: 2021,
|
||
pid: 10,
|
||
name: '天地图影像',
|
||
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
|
||
type: 'group',
|
||
layers: [
|
||
{
|
||
name: '底图',
|
||
type: 'tdt',
|
||
layer: 'img_d',
|
||
show: true,
|
||
},
|
||
{
|
||
name: '注记',
|
||
type: 'tdt',
|
||
layer: 'img_z',
|
||
show: true,
|
||
},
|
||
],
|
||
show: true,
|
||
},
|
||
zIndex: 2,
|
||
},
|
||
],
|
||
show: true,
|
||
opacity: 1,
|
||
},
|
||
],
|
||
layers: [],
|
||
});
|
||
if (map) {
|
||
map.addLayer(graphicLayers);
|
||
// 图层
|
||
showAllAnnotationDataList();
|
||
// showAllImageDataList();
|
||
// showAllAreaDataList();
|
||
handlerLocation([118.2958779, 35.1342553]);
|
||
// 监听地图点击事件
|
||
map.on(mars3d.EventType.click, function (event) {
|
||
if (!event.czmObject) {
|
||
// 地图标注 - 恢复默认
|
||
// if (props.nowShowAnnotationData && props.nowShowAnnotationData.id) {
|
||
// annotationRestoreDefault();
|
||
// emits('setNowShowAnnotationData', {});
|
||
// }
|
||
// // 地图作业区域-恢复默认
|
||
// if (props.nowShowAreaData.id) {
|
||
// areaRestoreDefault();
|
||
// emits('setNowShowAreaData', {});
|
||
// }
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
// 地图标注--------------------------------------------------------------------
|
||
watch(
|
||
() => props.allAnnotationDataList,
|
||
() => {
|
||
showAllAnnotationDataList();
|
||
},
|
||
);
|
||
watch(
|
||
() => props.nowShowAnnotationData,
|
||
(newVal, oldVal) => {
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
if (newVal) {
|
||
// 点
|
||
annotation_PointGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAnnotationData.id) {
|
||
const image1 = new Image();
|
||
image1.crossOrigin = 'Anonymous';
|
||
image1.src = svgToDataURL(
|
||
locateBack.replaceAll('currentColor', props.nowShowAnnotationData.properties.color),
|
||
);
|
||
image1.onload = () => {
|
||
const image2 = new Image();
|
||
image2.crossOrigin = 'Anonymous';
|
||
let svgString = '';
|
||
switch (props.nowShowAnnotationData.properties.iconname) {
|
||
case 'defaultIcon':
|
||
svgString = defaultIcon;
|
||
break;
|
||
case 'fireIcon':
|
||
svgString = fireIcon;
|
||
break;
|
||
case 'peopleIcon':
|
||
svgString = peopleIcon;
|
||
break;
|
||
case 'warnIcon':
|
||
svgString = warnIcon;
|
||
break;
|
||
case 'carIcon':
|
||
svgString = carIcon;
|
||
break;
|
||
case 'checkIcon':
|
||
svgString = checkIcon;
|
||
break;
|
||
case 'closeIcon':
|
||
svgString = closeIcon;
|
||
break;
|
||
}
|
||
image2.src = svgToDataURL(
|
||
svgString.replaceAll('currentColor', props.nowShowAnnotationData.properties.color),
|
||
);
|
||
image2.onload = () => {
|
||
// 创建Canvas元素
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = 30;
|
||
canvas.height = 40;
|
||
// 获取Canvas绘图上下文
|
||
const ctx = canvas.getContext('2d');
|
||
ctx.fillStyle = '#00000000';
|
||
ctx?.fillRect(0, 0, canvas.width, canvas.height);
|
||
// 在Canvas上绘制图片
|
||
if (props.nowShowAnnotationData.properties.iconname == 'defaultIcon') {
|
||
ctx.drawImage(image2, 0, 0, canvas.width, canvas.height);
|
||
} else {
|
||
ctx.drawImage(image1, 0, 0, canvas.width, canvas.height);
|
||
ctx.drawImage(image2, 8, 3, 14, 28);
|
||
}
|
||
// 将Canvas内容转换为图片的数据URL
|
||
const dataURL2 = canvas.toDataURL('image/png');
|
||
|
||
graphicLayer.position = [
|
||
parseFloat(props.nowShowAnnotationData.coordinates[0]),
|
||
parseFloat(props.nowShowAnnotationData.coordinates[1]),
|
||
parseFloat(props.nowShowAnnotationData.coordinates[2]),
|
||
];
|
||
graphicLayer.setStyle({
|
||
// 图标(待修改)
|
||
image: dataURL2,
|
||
iconname: props.nowShowAnnotationData.properties.iconname,
|
||
label: {
|
||
text: props.nowShowAnnotationData.name,
|
||
color: props.nowShowAnnotationData.properties.color,
|
||
font_size: props.nowShowAnnotationData.properties.font_size,
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkAnnotation(graphicLayer, 'point', time, 'update');
|
||
}
|
||
};
|
||
};
|
||
}
|
||
});
|
||
// 线
|
||
annotation_LineStringGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAnnotationData.id) {
|
||
graphicLayer.setStyle({
|
||
// 线头部样式/线尾部样式(待修改)
|
||
width: props.nowShowAnnotationData.properties.line_width,
|
||
color: props.nowShowAnnotationData.properties.color,
|
||
label: {
|
||
text: props.nowShowAnnotationData.name,
|
||
color: props.nowShowAnnotationData.properties.color,
|
||
font_size: props.nowShowAnnotationData.properties.font_size,
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkAnnotation(graphicLayer, 'polyline', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
// 多边形
|
||
annotation_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAnnotationData.id) {
|
||
graphicLayer.setStyle({
|
||
outlineColor: props.nowShowAnnotationData.properties.color,
|
||
label: {
|
||
text: props.nowShowAnnotationData.name,
|
||
color: props.nowShowAnnotationData.properties.color,
|
||
font_size: props.nowShowAnnotationData.properties.font_size,
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkAnnotation(graphicLayer, 'polygon', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
// 圆
|
||
annotation_CircleGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAnnotationData.id) {
|
||
graphicLayer.position = [
|
||
parseFloat(props.nowShowAnnotationData.properties.centerPoint[0]),
|
||
parseFloat(props.nowShowAnnotationData.properties.centerPoint[1]),
|
||
parseFloat(props.nowShowAnnotationData.properties.centerPoint[2]),
|
||
];
|
||
graphicLayer.setStyle({
|
||
radius: props.nowShowAnnotationData.properties.radius,
|
||
outlineColor: props.nowShowAnnotationData.properties.color,
|
||
label: {
|
||
text: props.nowShowAnnotationData.name,
|
||
color: props.nowShowAnnotationData.properties.color,
|
||
font_size: props.nowShowAnnotationData.properties.font_size,
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkAnnotation(graphicLayer, 'circle', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
}
|
||
},
|
||
{
|
||
deep: true,
|
||
},
|
||
);
|
||
// 地图标注-初始化-遍历展示
|
||
const showAllAnnotationDataList = async () => {
|
||
// 删除旧数据
|
||
annotation_PointGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
annotation_LineStringGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
annotation_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
annotation_CircleGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
// 图层数据
|
||
annotation_PointGraphicData = [];
|
||
annotation_LineStringGraphicData = [];
|
||
annotation_PolygonGraphicData = [];
|
||
annotation_CircleGraphicData = [];
|
||
if (!props.allAnnotationDataList || props.allAnnotationDataList.length == 0) {
|
||
return;
|
||
}
|
||
// 地图标注-遍历
|
||
props.allAnnotationDataList.forEach((item, index) => {
|
||
// console.log(item);
|
||
// 地图标注-点
|
||
if (item.type == 0) {
|
||
const image1 = new Image();
|
||
image1.crossOrigin = 'Anonymous';
|
||
image1.src = svgToDataURL(locateBack.replaceAll('currentColor', item.properties.color));
|
||
image1.onload = () => {
|
||
const image2 = new Image();
|
||
image2.crossOrigin = 'Anonymous';
|
||
let svgString = '';
|
||
switch (item.properties.iconname) {
|
||
case 'defaultIcon':
|
||
svgString = defaultIcon;
|
||
break;
|
||
case 'fireIcon':
|
||
svgString = fireIcon;
|
||
break;
|
||
case 'warnIcon':
|
||
svgString = warnIcon;
|
||
break;
|
||
case 'peopleIcon':
|
||
svgString = peopleIcon;
|
||
break;
|
||
case 'carIcon':
|
||
svgString = carIcon;
|
||
break;
|
||
case 'checkIcon':
|
||
svgString = checkIcon;
|
||
break;
|
||
case 'closeIcon':
|
||
svgString = closeIcon;
|
||
break;
|
||
}
|
||
image2.src = svgToDataURL(svgString.replaceAll('currentColor', item.properties.color));
|
||
image2.onload = () => {
|
||
// 创建Canvas元素
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = 30;
|
||
canvas.height = 40;
|
||
// 获取Canvas绘图上下文
|
||
const ctx = canvas.getContext('2d');
|
||
ctx.fillStyle = '#00000000';
|
||
ctx?.fillRect(0, 0, canvas.width, canvas.height);
|
||
// 在Canvas上绘制图片
|
||
if (item.properties.iconname == 'defaultIcon') {
|
||
ctx.drawImage(image2, 0, 0, canvas.width, canvas.height);
|
||
} else {
|
||
ctx.drawImage(image1, 0, 0, canvas.width, canvas.height);
|
||
ctx.drawImage(image2, 8, 3, 14, 28);
|
||
}
|
||
// 将Canvas内容转换为图片的数据URL
|
||
const dataURL = canvas.toDataURL('image/png');
|
||
|
||
let pointGraphic = new mars3d.graphic.BillboardEntity({
|
||
id: item.id,
|
||
position: item.coordinates,
|
||
style: {
|
||
image: dataURL,
|
||
iconname: item.properties.iconname,
|
||
clampToGround: item.properties.clampToGround,
|
||
scale: 1,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: item.properties.font_size,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, 0],
|
||
},
|
||
},
|
||
show: item.state == 0 ? true : false,
|
||
hasEdit: true,
|
||
});
|
||
// 监听mouseover事件
|
||
pointGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
pointGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
pointGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
pointGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
pointGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
annotationRestoreDefault();
|
||
pointGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
emits('setNowShowAnnotationData', item);
|
||
});
|
||
// 将点对象 添加到图层中
|
||
graphicLayers.addGraphic(pointGraphic);
|
||
// 数据
|
||
annotation_PointGraphicData.push(pointGraphic);
|
||
};
|
||
};
|
||
}
|
||
// 地图标注-线
|
||
if (item.type == 1) {
|
||
let lineGraphic = new mars3d.graphic.PolylineEntity({
|
||
id: item.id,
|
||
positions: item.coordinates,
|
||
style: {
|
||
color: item.properties.color,
|
||
width: item.properties.line_width,
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: item.properties.font_size,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, -5],
|
||
},
|
||
},
|
||
show: item.state == 0 ? true : false,
|
||
hasEdit: true,
|
||
drawShowMeasure: true,
|
||
});
|
||
// 监听mouseover事件
|
||
lineGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
lineGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
lineGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
lineGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
lineGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
annotationRestoreDefault();
|
||
lineGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
emits('setNowShowAnnotationData', item);
|
||
});
|
||
// 将线对象 添加到图层中
|
||
graphicLayers.addGraphic(lineGraphic);
|
||
// 数据
|
||
annotation_LineStringGraphicData.push(lineGraphic);
|
||
}
|
||
// 地图标注-多边形
|
||
if (item.type == 2) {
|
||
let polygonGraphic = new mars3d.graphic.PolygonEntity({
|
||
id: item.id,
|
||
positions: item.coordinates,
|
||
style: {
|
||
color: item.properties.color,
|
||
fill: false,
|
||
width: item.properties.line_width,
|
||
outlineColor: item.properties.color,
|
||
outlineWidth: 2,
|
||
outline: true,
|
||
clampToGround: item.properties.clampToGround,
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: item.properties.font_size,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
show: item.state == 0 ? true : false,
|
||
hasEdit: true,
|
||
drawShowMeasure: true,
|
||
});
|
||
// 监听mouseover事件
|
||
polygonGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
polygonGraphic.setStyle({
|
||
// color: '#ffffff00',
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
polygonGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
polygonGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
polygonGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
annotationRestoreDefault();
|
||
polygonGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
emits('setNowShowAnnotationData', item);
|
||
});
|
||
// 将形状对象 添加到图层中
|
||
graphicLayers.addGraphic(polygonGraphic);
|
||
// 数据
|
||
annotation_PolygonGraphicData.push(polygonGraphic);
|
||
}
|
||
// 地图标注-圆
|
||
if (item.type == 3) {
|
||
let circleGraphic = new mars3d.graphic.CircleEntity({
|
||
id: item.id,
|
||
position: item.properties.centerPoint,
|
||
style: {
|
||
radius: item.properties.radius,
|
||
fill: false,
|
||
outlineColor: item.properties.color,
|
||
outlineWidth: 4,
|
||
outline: true,
|
||
clampToGround: item.properties.clampToGround,
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: item.properties.font_size,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
show: item.state == 0 ? true : false,
|
||
hasEdit: true,
|
||
drawShowMeasure: true,
|
||
});
|
||
// 监听mouseover事件
|
||
circleGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
circleGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
circleGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAnnotationData || props.nowShowAnnotationData.id !== item.id) {
|
||
circleGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
circleGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
annotationRestoreDefault();
|
||
circleGraphic.setStyle({
|
||
label: {
|
||
color: item.properties.color,
|
||
},
|
||
});
|
||
emits('setNowShowAnnotationData', item);
|
||
});
|
||
// 将圆对象 添加到图层中
|
||
graphicLayers.addGraphic(circleGraphic);
|
||
// 数据
|
||
annotation_CircleGraphicData.push(circleGraphic);
|
||
}
|
||
});
|
||
};
|
||
// 地图标注-恢复默认
|
||
function annotationRestoreDefault() {
|
||
// 点-恢复默认
|
||
for (let i = 0; i < annotation_PointGraphicData.length; i++) {
|
||
let pointGraphic = annotation_PointGraphicData[i];
|
||
pointGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 线-恢复默认
|
||
for (let i = 0; i < annotation_LineStringGraphicData.length; i++) {
|
||
let lineGraphic = annotation_LineStringGraphicData[i];
|
||
lineGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 矩形-恢复默认
|
||
for (let i = 0; i < annotation_PolygonGraphicData.length; i++) {
|
||
let polygonGraphic = annotation_PolygonGraphicData[i];
|
||
polygonGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 圆形-恢复默认
|
||
for (let i = 0; i < annotation_CircleGraphicData.length; i++) {
|
||
let circleGraphic = annotation_CircleGraphicData[i];
|
||
circleGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
}
|
||
// 地图标注-SVG内容生成图片链接
|
||
function svgToDataURL(svgString: any) {
|
||
return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString)));
|
||
}
|
||
|
||
// 地图标注-绘制--------------------------------------------------------------------
|
||
const mapDrawType: any = ref('');
|
||
const drawColorPoint = ref('#2D8CF0');
|
||
const drawColorPolyline = ref('#2D8CF0');
|
||
const drawColorPolygon = ref('#2D8CF0');
|
||
const drawColorCricle = ref('#2D8CF0');
|
||
|
||
// 地图标注-绘制-点
|
||
async function drawPoint() {
|
||
if (mapDrawType.value == 'drawPoint') {
|
||
mapDrawType.value = '';
|
||
return;
|
||
}
|
||
mapDrawType.value = 'drawPoint';
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
const image = new Image();
|
||
image.crossOrigin = 'Anonymous';
|
||
image.src = svgToDataURL(defaultIcon.replaceAll('currentColor', drawColorPoint.value));
|
||
image.onload = () => {
|
||
// 创建Canvas元素
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = 30;
|
||
canvas.height = 40;
|
||
// 获取Canvas绘图上下文
|
||
const ctx = canvas.getContext('2d');
|
||
ctx.fillStyle = '#00000000';
|
||
ctx?.fillRect(0, 0, canvas.width, canvas.height);
|
||
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||
const dataURL = canvas.toDataURL('image/png');
|
||
graphicLayers
|
||
.startDraw({
|
||
type: 'billboard',
|
||
style: {
|
||
image: dataURL,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
iconname: 'defaultIcon',
|
||
label: {
|
||
text: '点 ' + time,
|
||
font_size: 18,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineWidth: 6,
|
||
outlineColor: '#ffffff',
|
||
pixelOffsetY: -60,
|
||
},
|
||
},
|
||
})
|
||
.then((graphic) => {
|
||
annotation_PointGraphicData.push(graphic);
|
||
addAndUpdateWorkAnnotation(graphic, 'point', time);
|
||
});
|
||
};
|
||
}
|
||
// 地图标注-绘制-线
|
||
async function drawPolyline() {
|
||
if (mapDrawType.value == 'drawPolyline') {
|
||
mapDrawType.value = '';
|
||
return;
|
||
}
|
||
mapDrawType.value = 'drawPolyline';
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'polyline',
|
||
style: {
|
||
width: 5,
|
||
line_start_cap: 0,
|
||
line_end_cap: 0,
|
||
color: drawColorPolyline.value,
|
||
label: {
|
||
text: '线 ' + time,
|
||
font_size: 18,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineWidth: 6,
|
||
outlineColor: '#ffffff',
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, -5],
|
||
},
|
||
},
|
||
});
|
||
annotation_LineStringGraphicData.push(graphic);
|
||
addAndUpdateWorkAnnotation(graphic, 'polyline', time);
|
||
}
|
||
// 地图标注-绘制-形状
|
||
async function drawPolygon() {
|
||
if (mapDrawType.value == 'drawPolygon') {
|
||
mapDrawType.value = '';
|
||
return;
|
||
}
|
||
mapDrawType.value = 'drawPolygon';
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'polygon',
|
||
style: {
|
||
color: drawColorPolygon.value,
|
||
fill: false,
|
||
outline: true,
|
||
outlineColor: drawColorPolygon.value,
|
||
outlineWidth: 3,
|
||
label: {
|
||
text: '多边形 ' + time,
|
||
font_size: 18,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineWidth: 6,
|
||
outlineColor: '#ffffff',
|
||
},
|
||
},
|
||
});
|
||
annotation_PolygonGraphicData.push(graphic);
|
||
addAndUpdateWorkAnnotation(graphic, 'polygon', time);
|
||
}
|
||
// 地图标注-绘制-圆
|
||
async function drawCricle() {
|
||
if (mapDrawType.value == 'drawCricle') {
|
||
mapDrawType.value = '';
|
||
return;
|
||
}
|
||
mapDrawType.value = 'drawCricle';
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'circle',
|
||
style: {
|
||
color: drawColorCricle.value,
|
||
fill: false,
|
||
outline: true,
|
||
outlineColor: drawColorCricle.value,
|
||
outlineWidth: 3,
|
||
label: {
|
||
text: '圆 ' + time,
|
||
font_size: 18,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineWidth: 6,
|
||
outlineColor: '#ffffff',
|
||
},
|
||
},
|
||
});
|
||
annotation_CircleGraphicData.push(graphic);
|
||
addAndUpdateWorkAnnotation(graphic, 'circle', time);
|
||
}
|
||
|
||
// 新增到数据库并刷新列表
|
||
async function addAndUpdateWorkAnnotation(graphic, annotationtype, time, addOrUpdate = 'add') {
|
||
let graphicJson = graphic.toJSON();
|
||
let params: any = {};
|
||
let coordinates = graphicJson.position || graphicJson.positions;
|
||
let properties = {};
|
||
let polygonData: any = [];
|
||
let type = 0;
|
||
let geom = '';
|
||
|
||
switch (annotationtype) {
|
||
case 'point':
|
||
type = 0;
|
||
geom = GeojsonToWkt(turf.point(coordinates).geometry);
|
||
properties = {
|
||
iconname: addOrUpdate == 'add' ? 'defaultIcon' : graphicJson.style.iconname,
|
||
font_size: 16,
|
||
iconnum: 0,
|
||
clampToGround: false,
|
||
color: drawColorPoint.value,
|
||
centerPoint: coordinates,
|
||
};
|
||
break;
|
||
case 'polyline':
|
||
type = 1;
|
||
geom = GeojsonToWkt(turf.lineString(coordinates).geometry);
|
||
properties = {
|
||
font_size: 16,
|
||
line_width: 5,
|
||
clampToGround: false,
|
||
color: drawColorPolyline.value,
|
||
centerPoint: coordinates[0],
|
||
line_start_cap: 0,
|
||
line_end_cap: 0,
|
||
};
|
||
break;
|
||
case 'polygon':
|
||
type = 2;
|
||
coordinates.push(coordinates[0]);
|
||
if (addOrUpdate == 'add') {
|
||
polygonData.push(coordinates);
|
||
} else {
|
||
polygonData = coordinates;
|
||
}
|
||
geom = GeojsonToWkt(turf.polygon(polygonData).geometry);
|
||
properties = {
|
||
font_size: 16,
|
||
clampToGround: false,
|
||
color: drawColorPolygon.value,
|
||
centerPoint: coordinates[0],
|
||
};
|
||
break;
|
||
case 'circle':
|
||
type = 3;
|
||
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
|
||
properties = {
|
||
font_size: 16,
|
||
clampToGround: true,
|
||
color: drawColorCricle.value,
|
||
radius: graphicJson.style.radius,
|
||
centerPoint: coordinates,
|
||
};
|
||
break;
|
||
}
|
||
if (addOrUpdate == 'add') {
|
||
params = {
|
||
name: graphicJson.style.label.text,
|
||
type: type,
|
||
properties: JSON.stringify(properties),
|
||
createTime: time,
|
||
createUser: '',
|
||
geom: geom,
|
||
workSpaceId: '1',
|
||
state: 0,
|
||
createUserName: '',
|
||
};
|
||
AddAnnotation(params).then((result) => {
|
||
// 刷新区域信息
|
||
emits('setAllAnnotationData');
|
||
mapDrawType.value = '';
|
||
});
|
||
} else {
|
||
params = {
|
||
id: graphicJson.id,
|
||
name: graphicJson.style.label.text,
|
||
type: type,
|
||
properties: JSON.stringify(properties),
|
||
geom: geom,
|
||
workSpaceId: '1',
|
||
state: props.nowShowAnnotationData.state,
|
||
};
|
||
UpdateAnnotation(params).then((result) => {
|
||
// 刷新区域信息
|
||
// emits('setAllAreaData');
|
||
// mapAreaDrawFlag.value = false;
|
||
});
|
||
}
|
||
}
|
||
|
||
// 地图照片--------------------------------------------------------------------
|
||
// 地图照片-初始化-遍历展示
|
||
const showAllImageDataList = async () => {
|
||
// 删除旧数据
|
||
image_bottomPointGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
image_flightointGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
image_bottomImagePolylineGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
image_imageGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
// 图层数据
|
||
image_bottomPointGraphicData = [];
|
||
image_flightointGraphicData = [];
|
||
image_bottomImagePolylineGraphicData = [];
|
||
image_imageGraphicData = [];
|
||
|
||
// 地图照片-遍历
|
||
let rotation = 0;
|
||
props.allImageDataList.forEach((item, index) => {
|
||
if (
|
||
item.photo_position &&
|
||
item.photo_position.lng &&
|
||
item.photo_position.lat &&
|
||
item.photo_position.abs_alt
|
||
) {
|
||
const image = new Image();
|
||
image.crossOrigin = 'Anonymous';
|
||
// image.src = item.preview_url;
|
||
image.src =
|
||
'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871';
|
||
image.onload = () => {
|
||
// 创建Canvas元素
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = 34;
|
||
canvas.height = 29;
|
||
// 获取Canvas绘图上下文
|
||
const ctx = canvas.getContext('2d');
|
||
ctx.fillStyle = 'white';
|
||
ctx?.fillRect(0, 0, canvas.width, canvas.height);
|
||
// 在Canvas上绘制图片
|
||
ctx.drawImage(image, 2, 2, 30, 25);
|
||
// 将Canvas内容转换为图片的数据URL
|
||
const dataURL1 = canvas.toDataURL('image/png');
|
||
|
||
// 在Canvas上绘制图片(假设image变量已经定义并且是一个有效的Image对象)
|
||
ctx.drawImage(image, 2, 2, 30, 25);
|
||
// 设置边框颜色和宽度
|
||
ctx.strokeStyle = '#2d8cef'; // 蓝色边框
|
||
ctx.lineWidth = 1; // 边框宽度
|
||
// 绘制边框
|
||
ctx.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1); // 调整坐标和尺寸以适应边框宽度
|
||
// 将Canvas内容转换为图片的数据URL
|
||
const dataURL2 = canvas.toDataURL('image/png');
|
||
|
||
// 位置
|
||
let position = [
|
||
parseFloat(item?.photo_position?.lng),
|
||
parseFloat(item.photo_position.lat),
|
||
parseFloat(item.photo_position.abs_alt),
|
||
];
|
||
// 地形高度
|
||
mars3d.PointUtil.getSurfaceHeight(
|
||
map.scene,
|
||
Cesium.Cartesian3.fromDegrees(position[0], position[1]),
|
||
).then((point) => {
|
||
// 地面点
|
||
let bottomPointGraphic = new mars3d.graphic.BillboardEntity({
|
||
id: item.id + '_bottom',
|
||
position: [position[0], position[1], point.height],
|
||
style: {
|
||
image: '/src/assets/images/flightoperation/mediaLibraryPoint.png',
|
||
clampToGround: true,
|
||
scale: 1,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
},
|
||
hasEdit: false,
|
||
});
|
||
if (index + 1 < props.allImageDataList.length) {
|
||
const afterItem = props.allImageDataList[index + 1];
|
||
let lng = afterItem.photo_position.lng - item.photo_position.lng;
|
||
let lat = afterItem.photo_position.lat - item.photo_position.lat;
|
||
let angleARad = Math.atan(lng / lat);
|
||
let angleA = (angleARad * 180) / Math.PI;
|
||
rotation = angleA;
|
||
}
|
||
// 飞行点
|
||
let flightointGraphic = new mars3d.graphic.BillboardEntity({
|
||
id: item.id + '_flight',
|
||
position: [position[0], position[1], position[2] * 2],
|
||
style: {
|
||
image: '/src/assets/images/flightoperation/mediaLibraryFlight.png',
|
||
clampToGround: false,
|
||
scale: 1,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
rotation: rotation,
|
||
},
|
||
hasEdit: false,
|
||
show: false,
|
||
});
|
||
// 地面点到展示图片的线
|
||
let bottomImagePolylineGraphic = new mars3d.graphic.PolylineEntity({
|
||
id: item.id + '_polyline',
|
||
positions: [
|
||
Cesium.Cartesian3.fromDegrees(position[0], position[1], point.height),
|
||
Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]),
|
||
],
|
||
style: {
|
||
color: '#ffffff',
|
||
width: 1, // 线宽
|
||
clampToGround: false,
|
||
},
|
||
hasEdit: false,
|
||
// 用于恢复默认
|
||
defaultPosition: position,
|
||
// 地形高度
|
||
surfaceHeight: point.height,
|
||
});
|
||
// 展示图片
|
||
let imageGraphic = new mars3d.graphic.BillboardEntity({
|
||
id: item.id + '_image',
|
||
position: [position[0], position[1], position[2]],
|
||
style: {
|
||
image: dataURL1,
|
||
clampToGround: false,
|
||
scale: 1,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 14,
|
||
color: '#2d8cf0',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, -5],
|
||
show: false,
|
||
},
|
||
},
|
||
hasEdit: false,
|
||
// 用于恢复默认
|
||
defaultImage: dataURL1,
|
||
// 用于外侧修改图片
|
||
chooseImage: dataURL2,
|
||
});
|
||
// 监听mouseover事件
|
||
imageGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
|
||
// 鼠标悬停时更改图片、图片变大
|
||
imageGraphic.setStyle({
|
||
image: dataURL2,
|
||
scale: 1.1,
|
||
label: {
|
||
show: true,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
imageGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
|
||
// 鼠标移出时恢复默认图片、图片恢复大小
|
||
imageGraphic.setStyle({
|
||
image: dataURL1,
|
||
scale: 1,
|
||
label: {
|
||
show: false,
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
imageGraphic.on(mars3d.EventType.click, function () {
|
||
// 点击当前展示的图片
|
||
if (props.nowShowImageData && props.nowShowImageData.id == item.id) {
|
||
// 全部恢复默认
|
||
imageRestoreDefault();
|
||
emits('setNowShowImageData', {});
|
||
emits('closePathImageInfo');
|
||
} else if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
|
||
// 当前展示图片为空 或者 点击与当前展示不同
|
||
// 全部恢复默认
|
||
imageRestoreDefault();
|
||
// 鼠标点击
|
||
// 更新 PolylineEntity 的位置
|
||
bottomImagePolylineGraphic.positions = [
|
||
Cesium.Cartesian3.fromDegrees(position[0], position[1], point.height),
|
||
Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2] * 2),
|
||
];
|
||
// 更新 PolylineEntity 的颜色
|
||
bottomImagePolylineGraphic.setStyle({
|
||
color: '#2d8cf0',
|
||
});
|
||
// 飞行点显示
|
||
flightointGraphic.show = true;
|
||
// 鼠标更改图片
|
||
imageGraphic.setStyle({
|
||
image: dataURL2,
|
||
label: {
|
||
show: true,
|
||
},
|
||
});
|
||
emits('setNowShowImageData', item);
|
||
}
|
||
});
|
||
// 将地面点 添加到图层中
|
||
graphicLayers.addGraphic(bottomPointGraphic);
|
||
// 将飞行点 添加到图层中
|
||
graphicLayers.addGraphic(flightointGraphic);
|
||
// 地面点到展示图片的线 添加到图层中
|
||
graphicLayers.addGraphic(bottomImagePolylineGraphic);
|
||
// 展示图片 添加到图层中
|
||
graphicLayers.addGraphic(imageGraphic);
|
||
// 数据
|
||
image_bottomPointGraphicData.push(bottomPointGraphic);
|
||
image_flightointGraphicData.push(flightointGraphic);
|
||
image_bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic);
|
||
image_imageGraphicData.push(imageGraphic);
|
||
});
|
||
};
|
||
}
|
||
});
|
||
};
|
||
// 地图照片-恢复默认
|
||
function imageRestoreDefault() {
|
||
// 飞行点
|
||
for (let i = 0; i < image_flightointGraphicData.length; i++) {
|
||
let flightointGraphic = image_flightointGraphicData[i];
|
||
flightointGraphic.show = false;
|
||
}
|
||
// 地面点到展示图片的线
|
||
for (let i = 0; i < image_bottomImagePolylineGraphicData.length; i++) {
|
||
let bottomImagePolylineGraphic = image_bottomImagePolylineGraphicData[i];
|
||
let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition;
|
||
let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight;
|
||
bottomImagePolylineGraphic.setStyle({
|
||
color: '#ffffff',
|
||
});
|
||
bottomImagePolylineGraphic.positions = [
|
||
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], surfaceHeight),
|
||
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], defaultPosition[2]),
|
||
];
|
||
}
|
||
// 展示图片
|
||
for (let i = 0; i < image_imageGraphicData.length; i++) {
|
||
let imageGraphic = image_imageGraphicData[i];
|
||
let defaultImage = imageGraphic.options.defaultImage;
|
||
imageGraphic.setStyle({
|
||
image: defaultImage,
|
||
scale: 1,
|
||
label: {
|
||
show: false,
|
||
},
|
||
});
|
||
}
|
||
}
|
||
// 地图照片-右侧图片模块修改当前显示图片
|
||
function setNowShowImageByRight() {
|
||
setTimeout(() => {
|
||
// 全部恢复默认
|
||
imageRestoreDefault();
|
||
// 飞行点
|
||
for (let i = 0; i < image_flightointGraphicData.length; i++) {
|
||
if (image_flightointGraphicData[i].options.id.includes(props.nowShowImageData.id)) {
|
||
let flightointGraphic = image_flightointGraphicData[i];
|
||
flightointGraphic.show = true;
|
||
}
|
||
}
|
||
// 地面点到展示图片的线
|
||
for (let i = 0; i < image_bottomImagePolylineGraphicData.length; i++) {
|
||
if (
|
||
image_bottomImagePolylineGraphicData[i].options.id.includes(props.nowShowImageData.id)
|
||
) {
|
||
let bottomImagePolylineGraphic = image_bottomImagePolylineGraphicData[i];
|
||
let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition;
|
||
let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight;
|
||
bottomImagePolylineGraphic.setStyle({
|
||
color: '#2d8cf0',
|
||
});
|
||
bottomImagePolylineGraphic.positions = [
|
||
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], surfaceHeight),
|
||
Cesium.Cartesian3.fromDegrees(
|
||
defaultPosition[0],
|
||
defaultPosition[1],
|
||
defaultPosition[2] * 2,
|
||
),
|
||
];
|
||
}
|
||
}
|
||
// 展示图片
|
||
for (let i = 0; i < image_imageGraphicData.length; i++) {
|
||
if (image_imageGraphicData[i].options.id.includes(props.nowShowImageData.id)) {
|
||
let imageGraphic = image_imageGraphicData[i];
|
||
let chooseImage = imageGraphic.options.chooseImage;
|
||
imageGraphic.setStyle({
|
||
image: chooseImage,
|
||
label: {
|
||
show: true,
|
||
},
|
||
});
|
||
}
|
||
}
|
||
}, 500);
|
||
}
|
||
|
||
// 地图作业区域--------------------------------------------------------------------
|
||
watch(
|
||
() => props.allAreaDataList,
|
||
() => {
|
||
showAllAreaDataList();
|
||
},
|
||
);
|
||
watch(
|
||
() => props.nowShowAreaData,
|
||
(newVal, oldVal) => {
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
if (newVal) {
|
||
// 样式
|
||
area_noland_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAreaData.id) {
|
||
graphicLayer.setStyle({
|
||
label: {
|
||
text: props.nowShowAreaData.name,
|
||
color: graphicLayer.options.style.color,
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkArea(graphicLayer, 'noland_Polygon', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
area_dfence_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAreaData.id) {
|
||
graphicLayer.setStyle({
|
||
label: {
|
||
text: props.nowShowAreaData.name,
|
||
color: graphicLayer.options.style.color.substring(0, 7),
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkArea(graphicLayer, 'dfence_Polygon', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
area_nfz_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAreaData.id) {
|
||
graphicLayer.setStyle({
|
||
label: {
|
||
text: props.nowShowAreaData.name,
|
||
color: graphicLayer.options.style.color.substring(0, 7),
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkArea(graphicLayer, 'nfz_Polygon', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
area_dfence_CircleGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAreaData.id) {
|
||
graphicLayer.setStyle({
|
||
radius: props.nowShowAreaData.properties.radius,
|
||
label: {
|
||
text: props.nowShowAreaData.name,
|
||
color: graphicLayer.options.style.color.substring(0, 7),
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkArea(graphicLayer, 'dfence_Circle', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
area_nfz_CircleGraphicData?.forEach((graphicLayer) => {
|
||
if (graphicLayer.options.id == props.nowShowAreaData.id) {
|
||
graphicLayer.setStyle({
|
||
radius: props.nowShowAreaData.properties.radius,
|
||
label: {
|
||
text: props.nowShowAreaData.name,
|
||
color: graphicLayer.options.style.color.substring(0, 7),
|
||
},
|
||
});
|
||
if (oldVal && newVal.id == oldVal.id) {
|
||
addAndUpdateWorkArea(graphicLayer, 'nfz_Circle', time, 'update');
|
||
}
|
||
}
|
||
});
|
||
}
|
||
},
|
||
{
|
||
deep: true,
|
||
},
|
||
);
|
||
|
||
// 地图作业区域-初始化-遍历展示
|
||
function showAllAreaDataList() {
|
||
// 删除旧数据
|
||
area_noland_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
area_dfence_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
area_dfence_CircleGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
area_nfz_PolygonGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
area_nfz_CircleGraphicData?.forEach((graphicLayer) => {
|
||
graphicLayers.removeGraphic(graphicLayer);
|
||
});
|
||
// 图层数据
|
||
area_noland_PolygonGraphicData = [];
|
||
// 地图作业区域-作业区-多边形
|
||
area_dfence_PolygonGraphicData = [];
|
||
// 地图作业区域-作业区-圈
|
||
area_dfence_CircleGraphicData = [];
|
||
// 地图作业区域-限飞区-多边形
|
||
area_nfz_PolygonGraphicData = [];
|
||
// 地图作业区域-限飞区-圈
|
||
area_nfz_CircleGraphicData = [];
|
||
if (!props.allAreaDataList || props.allAreaDataList.length == 0) {
|
||
return;
|
||
}
|
||
props.allAreaDataList.forEach((item, index) => {
|
||
// console.log(item);
|
||
// 地图作业区域-禁降区-线
|
||
if (item.type == 'noland' && item.geomtype == 'Polygon') {
|
||
let nolandPolygonGraphic = new mars3d.graphic.PolygonEntity({
|
||
id: item.id,
|
||
positions: item.coordinates,
|
||
style: {
|
||
clampToGround: item.properties.clampToGround,
|
||
fill: false,
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d', // 中心线颜色
|
||
dashLength: 36, // 十字长度
|
||
maskLength: 10, // 空隙间隔长度
|
||
centerPower: 0.1, // 中心宽百分比
|
||
dashPower: 0.2, // 虚线百分比
|
||
},
|
||
},
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, -5],
|
||
},
|
||
},
|
||
});
|
||
// 监听mouseover事件
|
||
nolandPolygonGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nolandPolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
nolandPolygonGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nolandPolygonGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
nolandPolygonGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
areaRestoreDefault();
|
||
nolandPolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
emits('setNowShowAreaData', item);
|
||
});
|
||
// 将 禁降区-线 添加到图层中
|
||
graphicLayers.addGraphic(nolandPolygonGraphic);
|
||
// 数据
|
||
area_noland_PolygonGraphicData.push(nolandPolygonGraphic);
|
||
}
|
||
// 地图作业区域-作业区-多边形
|
||
if (item.type == 'dfence' && item.geomtype == 'Polygon') {
|
||
let dfence_PolygonGraphic = new mars3d.graphic.PolygonEntity({
|
||
id: item.id,
|
||
positions: item.coordinates,
|
||
style: {
|
||
clampToGround: item.properties.clampToGround,
|
||
fill: false,
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
background: true,
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
// 监听mouseover事件
|
||
dfence_PolygonGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
dfence_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
dfence_PolygonGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
dfence_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
dfence_PolygonGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
areaRestoreDefault();
|
||
dfence_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
emits('setNowShowAreaData', item);
|
||
});
|
||
// 将 作业区-圈 添加到图层中
|
||
graphicLayers.addGraphic(dfence_PolygonGraphic);
|
||
// 数据
|
||
area_dfence_PolygonGraphicData.push(dfence_PolygonGraphic);
|
||
}
|
||
// 地图作业区域-限飞区-多边形
|
||
if (item.type == 'nfz' && item.geomtype == 'Polygon') {
|
||
let nfz_PolygonGraphic = new mars3d.graphic.PolygonEntity({
|
||
id: item.id,
|
||
positions: item.coordinates,
|
||
style: {
|
||
clampToGround: item.properties.clampToGround,
|
||
color: item.state == 0 ? item.properties.color + '33' : '#6d6d6d' + '33',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
// 监听mouseover事件
|
||
nfz_PolygonGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nfz_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
nfz_PolygonGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nfz_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
nfz_PolygonGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
areaRestoreDefault();
|
||
nfz_PolygonGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
emits('setNowShowAreaData', item);
|
||
});
|
||
// 将 作业区-圈 添加到图层中
|
||
graphicLayers.addGraphic(nfz_PolygonGraphic);
|
||
// 数据
|
||
area_nfz_PolygonGraphicData.push(nfz_PolygonGraphic);
|
||
}
|
||
// 地图作业区域-作业区-圈
|
||
if (item.type == 'dfence' && item.geomtype == 'Circle') {
|
||
let dfence_CircleGraphic = new mars3d.graphic.CircleEntity({
|
||
id: item.id,
|
||
position: item.properties.centerPoint,
|
||
style: {
|
||
clampToGround: item.properties.clampToGround,
|
||
radius: item.properties.radius,
|
||
fill: false,
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
background: true,
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
// 监听mouseover事件
|
||
dfence_CircleGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
dfence_CircleGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
dfence_CircleGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
dfence_CircleGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
dfence_CircleGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
areaRestoreDefault();
|
||
dfence_CircleGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
emits('setNowShowAreaData', item);
|
||
});
|
||
// 将 作业区-圈 添加到图层中
|
||
graphicLayers.addGraphic(dfence_CircleGraphic);
|
||
// 数据
|
||
area_dfence_CircleGraphicData.push(dfence_CircleGraphic);
|
||
}
|
||
// 地图作业区域-限飞区-圈
|
||
if (item.type == 'nfz' && item.geomtype == 'Circle') {
|
||
let nfz_CircleGraphic = new mars3d.graphic.CircleEntity({
|
||
id: item.id,
|
||
position: item.properties.centerPoint,
|
||
style: {
|
||
clampToGround: item.properties.clampToGround,
|
||
radius: item.properties.radius,
|
||
color: item.state == 0 ? item.properties.color + '33' : '#6d6d6d' + '33',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `${item.name}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
// 监听mouseover事件
|
||
nfz_CircleGraphic.on(mars3d.EventType.mouseOver, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nfz_CircleGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听mouseout事件
|
||
nfz_CircleGraphic.on(mars3d.EventType.mouseOut, function () {
|
||
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
|
||
nfz_CircleGraphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
});
|
||
// 监听点击事件
|
||
nfz_CircleGraphic.on(mars3d.EventType.click, function () {
|
||
// 全部恢复默认
|
||
areaRestoreDefault();
|
||
nfz_CircleGraphic.setStyle({
|
||
label: {
|
||
color: item.state == 0 ? item.properties.color : '#6d6d6d',
|
||
},
|
||
});
|
||
emits('setNowShowAreaData', item);
|
||
});
|
||
// 将 限飞区-圈 添加到图层中
|
||
graphicLayers.addGraphic(nfz_CircleGraphic);
|
||
// 数据
|
||
area_nfz_CircleGraphicData.push(nfz_CircleGraphic);
|
||
}
|
||
});
|
||
}
|
||
// 地图作业区域-恢复默认
|
||
function areaRestoreDefault() {
|
||
// 作业区-多边形-恢复默认
|
||
for (let i = 0; i < area_noland_PolygonGraphicData.length; i++) {
|
||
let graphic = area_noland_PolygonGraphicData[i];
|
||
graphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 作业区-多边形-恢复默认
|
||
for (let i = 0; i < area_dfence_PolygonGraphicData.length; i++) {
|
||
let graphic = area_dfence_PolygonGraphicData[i];
|
||
graphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 限飞区-多边形-恢复默认
|
||
for (let i = 0; i < area_nfz_PolygonGraphicData.length; i++) {
|
||
let graphic = area_nfz_PolygonGraphicData[i];
|
||
graphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 作业区-圈-恢复默认
|
||
for (let i = 0; i < area_dfence_CircleGraphicData.length; i++) {
|
||
let graphic = area_dfence_CircleGraphicData[i];
|
||
graphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
// 限飞区-圈-恢复默认
|
||
for (let i = 0; i < area_nfz_CircleGraphicData.length; i++) {
|
||
let graphic = area_nfz_CircleGraphicData[i];
|
||
graphic.setStyle({
|
||
label: {
|
||
color: '#000000',
|
||
},
|
||
});
|
||
}
|
||
}
|
||
|
||
// 地图区域-绘制
|
||
const mapAreaDrawFlag = ref(false);
|
||
const areaDrawType = ref('dfence_Polygon');
|
||
async function drawArea() {
|
||
if (mapAreaDrawFlag.value) {
|
||
mapAreaDrawFlag.value = false;
|
||
return;
|
||
}
|
||
mapAreaDrawFlag.value = true;
|
||
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||
// 自定义禁降区
|
||
if (areaDrawType.value == 'noland_Polygon') {
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'polygon',
|
||
style: {
|
||
clampToGround: true,
|
||
color: '#FF9900',
|
||
fill: false,
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: '#FF9900',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `自定义禁降区${time}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
pixelOffset: [25, -5],
|
||
},
|
||
},
|
||
});
|
||
area_dfence_PolygonGraphicData.push(graphic);
|
||
addAndUpdateWorkArea(graphic, 'noland_Polygon', time);
|
||
}
|
||
// 自定义多边形限飞区
|
||
if (areaDrawType.value == 'nfz_Polygon') {
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'polygon',
|
||
style: {
|
||
clampToGround: true,
|
||
color: '#FF0000' + '33',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: '#FF0000',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `自定义多边形限飞区${time}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
area_nfz_PolygonGraphicData.push(graphic);
|
||
addAndUpdateWorkArea(graphic, 'nfz_Polygon', time);
|
||
}
|
||
// 自定义圆形限飞区
|
||
if (areaDrawType.value == 'nfz_Circle') {
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'circle',
|
||
style: {
|
||
clampToGround: true,
|
||
color: '#FF0000' + '33',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
background: true,
|
||
color: '#FF0000',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `自定义圆形限飞区${time}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
area_nfz_CircleGraphicData.push(graphic);
|
||
addAndUpdateWorkArea(graphic, 'nfz_Circle', time);
|
||
}
|
||
// 自定义多边形作业区
|
||
if (areaDrawType.value == 'dfence_Polygon') {
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'polygon',
|
||
style: {
|
||
clampToGround: true,
|
||
color: '#00FF00',
|
||
fill: false,
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
color: '#00FF00',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `自定义多边形作业区${time}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
area_dfence_PolygonGraphicData.push(graphic);
|
||
addAndUpdateWorkArea(graphic, 'dfence_Polygon', time);
|
||
}
|
||
// 自定义圆形作业区
|
||
if (areaDrawType.value == 'dfence_Circle') {
|
||
const graphic = await graphicLayers.startDraw({
|
||
type: 'circle',
|
||
style: {
|
||
clampToGround: true,
|
||
fill: false,
|
||
color: '#00FF00',
|
||
outline: true,
|
||
outlineStyle: {
|
||
width: 12,
|
||
materialType: mars3d.MaterialType.LineCross,
|
||
materialOptions: {
|
||
background: true,
|
||
color: '#00FF00',
|
||
dashLength: 36,
|
||
maskLength: 10,
|
||
centerPower: 0.1,
|
||
dashPower: 0.2,
|
||
},
|
||
},
|
||
label: {
|
||
text: `自定义圆形作业区${time}`,
|
||
font_size: 16,
|
||
color: '#000000',
|
||
outline: true,
|
||
outlineColor: '#ffffff',
|
||
outlineWidth: 6,
|
||
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
},
|
||
},
|
||
});
|
||
area_dfence_CircleGraphicData.push(graphic);
|
||
addAndUpdateWorkArea(graphic, 'dfence_Circle', time);
|
||
}
|
||
}
|
||
|
||
// 新增到数据库并刷新列表
|
||
async function addAndUpdateWorkArea(graphic, areatype, time, addOrUpdate = 'add') {
|
||
let graphicJson = graphic.toJSON();
|
||
let params: any = {};
|
||
let coordinates = graphicJson.position || graphicJson.positions;
|
||
let properties = {};
|
||
let polygonData: any = [];
|
||
let type = '';
|
||
let geom = '';
|
||
switch (areatype) {
|
||
// 自定义禁降区
|
||
case 'noland_Polygon':
|
||
type = 'noland';
|
||
coordinates.push(coordinates[0]);
|
||
if (addOrUpdate == 'add') {
|
||
polygonData.push(coordinates);
|
||
} else {
|
||
polygonData = coordinates;
|
||
}
|
||
geom = GeojsonToWkt(turf.polygon(polygonData).geometry);
|
||
properties = {
|
||
clampToGround: true,
|
||
color: '#FF9900',
|
||
centerPoint: coordinates[0],
|
||
};
|
||
break;
|
||
// 自定义多边形作业区
|
||
case 'dfence_Polygon':
|
||
type = 'dfence';
|
||
coordinates.push(coordinates[0]);
|
||
if (addOrUpdate == 'add') {
|
||
polygonData.push(coordinates);
|
||
} else {
|
||
polygonData = coordinates;
|
||
}
|
||
geom = GeojsonToWkt(turf.polygon(polygonData).geometry);
|
||
properties = {
|
||
clampToGround: true,
|
||
color: '#00FF00',
|
||
centerPoint: coordinates[0],
|
||
};
|
||
break;
|
||
// 自定义多边形限飞区
|
||
case 'nfz_Polygon':
|
||
type = 'nfz';
|
||
coordinates.push(coordinates[0]);
|
||
if (addOrUpdate == 'add') {
|
||
polygonData.push(coordinates);
|
||
} else {
|
||
polygonData = coordinates;
|
||
}
|
||
geom = GeojsonToWkt(turf.polygon(polygonData).geometry);
|
||
properties = {
|
||
clampToGround: true,
|
||
color: '#FF0000',
|
||
centerPoint: coordinates[0],
|
||
};
|
||
break;
|
||
// 自定义圆形作业区
|
||
case 'dfence_Circle':
|
||
type = 'dfence';
|
||
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
|
||
properties = {
|
||
clampToGround: true,
|
||
color: '#00FF00',
|
||
radius: graphicJson.style.radius,
|
||
centerPoint: coordinates,
|
||
};
|
||
break;
|
||
// 自定义圆形限飞区
|
||
case 'nfz_Circle':
|
||
type = 'nfz';
|
||
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
|
||
properties = {
|
||
clampToGround: true,
|
||
color: '#FF0000',
|
||
radius: graphicJson.style.radius,
|
||
centerPoint: coordinates,
|
||
};
|
||
break;
|
||
}
|
||
if (addOrUpdate == 'add') {
|
||
params = {
|
||
name: graphicJson.style.label.text,
|
||
type: type,
|
||
properties: JSON.stringify(properties),
|
||
createTime: time,
|
||
createUser: '',
|
||
geom: geom,
|
||
workSpaceId: '1',
|
||
state: 0,
|
||
createUserName: '',
|
||
};
|
||
AddWorkArea(params).then((result) => {
|
||
// 刷新区域信息
|
||
emits('setAllAreaData');
|
||
mapAreaDrawFlag.value = false;
|
||
});
|
||
} else {
|
||
params = {
|
||
id: graphicJson.id,
|
||
name: graphicJson.style.label.text,
|
||
type: type,
|
||
properties: JSON.stringify(properties),
|
||
geom: geom,
|
||
workSpaceId: '1',
|
||
state: props.nowShowAreaData.state,
|
||
};
|
||
UpdateWorkArea(params).then((result) => {
|
||
// 刷新区域信息
|
||
// emits('setAllAreaData');
|
||
// mapAreaDrawFlag.value = false;
|
||
});
|
||
}
|
||
}
|
||
|
||
// 图斑定位
|
||
const handlerLocation = (lngLat) => {
|
||
const position = Cesium.Cartesian3.fromDegrees(lngLat[0], lngLat[1]);
|
||
map.flyToPoint(position);
|
||
};
|
||
|
||
defineExpose({
|
||
setNowShowImageByRight,
|
||
handlerLocation,
|
||
annotationRestoreDefault,
|
||
areaRestoreDefault,
|
||
});
|
||
</script>
|
||
<style lang="less" scoped>
|
||
.mars3d-container {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.annotationButtons {
|
||
position: absolute;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
top: 10%;
|
||
right: 1%;
|
||
width: 30px;
|
||
height: 123px;
|
||
gap: 1px;
|
||
}
|
||
|
||
.button_nochoose {
|
||
background: #ffffff;
|
||
z-index: 200;
|
||
width: 30px;
|
||
height: 30px;
|
||
// border-radius: 3px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
&:hover {
|
||
border: 2px solid #2b85e4;
|
||
outline: 1px solid #2b85e4;
|
||
}
|
||
}
|
||
.button_choose {
|
||
background: linear-gradient(to bottom left, #2b85e4 10px, transparent 1px), #ffffff;
|
||
background-size:
|
||
100% 100%,
|
||
auto;
|
||
z-index: 200;
|
||
width: 30px;
|
||
height: 30px;
|
||
// border-radius: 3px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
outline: 2px solid #2b85e4;
|
||
}
|
||
|
||
.popoverAnnotation {
|
||
width: 18px;
|
||
height: 18px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
.areaButtons {
|
||
position: absolute;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
top: 30%;
|
||
right: 1%;
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.popoverArea {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
width: 170px;
|
||
height: 35px;
|
||
}
|
||
</style>
|