DiKongGanZhiPingTai/src/views/demo/workmanagement/flightannotation/pathMap.vue

2537 lines
84 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>