You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2099 lines
68 KiB
Vue

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="markButtons">
<div
:class="mapDrawType == 'drawPoint' ? 'button_choose' : 'button_nochoose'"
@click="drawPoint"
>
<a-popover placement="left">
<template #content>
<div style="display: flex; gap: 5px">
<div
class="popoverMark"
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="popoverMark"
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="popoverMark"
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="popoverMark"
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_Polyline',
]"
:key="type"
:style="{ background: '#ffffff' }"
@click="areaDrawType = type"
>
<!-- 自定义禁降区 -->
<div
v-if="type.indexOf('noland') > -1"
:style="{
width: '15px',
height: '15px',
background: `linear-gradient(to bottom right, transparent 45%, #FF9900 45%, #FF9900 60%, transparent 60%), #ffffff00`,
'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_Polyline'"></div>
<CheckOutlined v-if="areaDrawType == type" style="color: blue; margin-left: 10px" />
</div>
</div>
</template>
<!-- 自定义禁降区 -->
<div
v-if="areaDrawType.indexOf('noland') > -1"
:style="{
width: '18px',
height: '18px',
background: `linear-gradient(to bottom right, transparent 45%, #FF9900 45%, #FF9900 60%, transparent 60%), #ffffff00`,
}"
/>
<!-- 自定义作业区 -->
<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 {
GetWorkAreaList,
AddWorkArea,
UpdateWorkArea,
DeleteWorkArea,
} from '@/api/demo/mediaLibrary';
import * as turf from '@turf/turf';
import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import dayjs from 'dayjs';
const props = defineProps([
'allMarkDataList',
'nowShowMarkData',
'allImageDataList',
'nowShowImageData',
'allAreaDataList',
'nowShowAreaData',
]);
const emits = defineEmits([
'setNowShowMarkData',
'setNowShowImageData',
'setNowShowAreaData',
'closePathImageInfo',
'setAllMarkData',
'setAllImageData',
'setAllAreaData',
]);
const vChartRef: any = ref<HTMLElement>();
let map: mars3d.Map; // 地图对象
let graphicLayers = new mars3d.layer.GraphicLayer({
isAutoEditing: true,
});
// 地图标注
// 地图标注-点
let mark_PointGraphicData: any = [];
// 地图标注-线
let mark_LineStringGraphicData: any = [];
// 地图标注-多边形
let mark_PolygonGraphicData: any = [];
// 地图标注-圈
let mark_CircleGraphicData: any = [];
// 地图照片
// 地图照片-地面点
let image_bottomPointGraphicData: any = [];
// 地图照片-飞行点
let image_flightointGraphicData: any = [];
// 地图照片-地面点到展示图片的线
let image_bottomImagePolylineGraphicData: any = [];
// 地图照片-展示图片
let image_imageGraphicData: any = [];
// 地图作业区域
// 地图作业区域-禁降区-线
let area_noland_LineStringGraphicData: 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);
showAllMarkDataList();
showAllImageDataList();
showAllAreaDataList();
handlerLocation([118.2958779, 35.1342553]);
// 监听地图点击事件
map.on(mars3d.EventType.click, function (event) {
if (!event.czmObject) {
// 地图标注-恢复默认
if (props.nowShowMarkData.id) {
markRestoreDefault();
emits('setNowShowMarkData', {});
}
// // 地图作业区域-恢复默认
// if (props.nowShowAreaData.id) {
// areaRestoreDefault();
// emits('setNowShowAreaData', {});
// }
}
});
}
};
// 地图标注--------------------------------------------------------------------
// 地图标注-初始化-遍历展示
const showAllMarkDataList = async () => {
// 删除旧数据
mark_PointGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
mark_LineStringGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
mark_PolygonGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
mark_CircleGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
// 图层数据
mark_PointGraphicData = [];
mark_LineStringGraphicData = [];
mark_PolygonGraphicData = [];
mark_CircleGraphicData = [];
// 地图标注-遍历
props.allMarkDataList.forEach((item, index) => {
let content = item.resource.content;
// 地图标注-点
if (content.geometry.type == 'Point') {
let pointGraphic = new mars3d.graphic.BillboardEntity({
id: item.id,
position: content.geometry.coordinates,
style: {
image: 'https://data.mars3d.cn/img/marker/mark-red.png',
clampToGround: false,
scale: 1,
label: {
text: `${item.name}`,
font_size: content.properties.font_size,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
outlineWidth: 6,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
pixelOffset: [25, 0],
},
},
});
// 监听mouseover事件
pointGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
pointGraphic.setStyle({
label: {
color: content.properties.color,
},
});
}
});
// 监听mouseout事件
pointGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
pointGraphic.setStyle({
label: {
color: '#000000',
},
});
}
});
// 监听点击事件
pointGraphic.on(mars3d.EventType.click, function () {
// 全部恢复默认
markRestoreDefault();
pointGraphic.setStyle({
label: {
color: content.properties.color,
},
});
emits('setNowShowMarkData', item);
});
// 将点对象 添加到图层中
graphicLayers.addGraphic(pointGraphic);
// 数据
mark_PointGraphicData.push(pointGraphic);
}
// 地图标注-线
if (content.geometry.type == 'LineString') {
let lineGraphic = new mars3d.graphic.PolylineEntity({
id: item.id,
positions: content.geometry.coordinates,
style: {
color: content.properties.color,
width: content.properties.line_width,
label: {
text: `${item.name}`,
font_size: content.properties.font_size,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
outlineWidth: 6,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
pixelOffset: [25, -5],
},
},
hasEdit: true,
drawShowMeasure: true,
});
// 监听mouseover事件
lineGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
lineGraphic.setStyle({
label: {
color: content.properties.color,
},
});
}
});
// 监听mouseout事件
lineGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
lineGraphic.setStyle({
label: {
color: '#000000',
},
});
}
});
// 监听点击事件
lineGraphic.on(mars3d.EventType.click, function () {
// 全部恢复默认
markRestoreDefault();
lineGraphic.setStyle({
label: {
color: content.properties.color,
},
});
emits('setNowShowMarkData', item);
});
// 将线对象 添加到图层中
graphicLayers.addGraphic(lineGraphic);
// 数据
mark_LineStringGraphicData.push(lineGraphic);
}
// 地图标注-多边形
if (content.geometry.type == 'Polygon') {
let polygonGraphic = new mars3d.graphic.PolygonEntity({
id: item.id,
positions: content.geometry.coordinates,
style: {
color: content.properties.color,
fill: false,
width: content.properties.line_width,
outlineColor: content.properties.color,
outlineWidth: 2,
outline: true,
clampToGround: content.properties.clampToGround,
label: {
text: `${item.name}`,
font_size: content.properties.font_size,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
outlineWidth: 6,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
},
},
});
// 监听mouseover事件
polygonGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
polygonGraphic.setStyle({
// color: '#ffffff00',
label: {
color: content.properties.color,
},
});
}
});
// 监听mouseout事件
polygonGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
polygonGraphic.setStyle({
label: {
color: '#000000',
},
});
}
});
// 监听点击事件
polygonGraphic.on(mars3d.EventType.click, function () {
// 全部恢复默认
markRestoreDefault();
polygonGraphic.setStyle({
label: {
color: content.properties.color,
},
});
emits('setNowShowMarkData', item);
});
// 将形状对象 添加到图层中
graphicLayers.addGraphic(polygonGraphic);
// 数据
mark_PolygonGraphicData.push(polygonGraphic);
}
// 地图标注-圆
if (content.geometry.type == 'Circle') {
let circleGraphic = new mars3d.graphic.CircleEntity({
id: item.id,
position: content.geometry.coordinates,
style: {
radius: content.geometry.radius,
fill: false,
outlineColor: content.properties.color,
outlineWidth: 4,
outline: true,
clampToGround: content.properties.clampToGround,
label: {
text: `${item.name}`,
font_size: content.properties.font_size,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
outlineWidth: 6,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
},
},
});
// 监听mouseover事件
circleGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
circleGraphic.setStyle({
label: {
color: content.properties.color,
},
});
}
});
// 监听mouseout事件
circleGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowMarkData || props.nowShowMarkData.id !== item.id) {
circleGraphic.setStyle({
label: {
color: '#000000',
},
});
}
});
// 监听点击事件
circleGraphic.on(mars3d.EventType.click, function () {
// 全部恢复默认
markRestoreDefault();
circleGraphic.setStyle({
label: {
color: content.properties.color,
},
});
emits('setNowShowMarkData', item);
});
// 将圆对象 添加到图层中
graphicLayers.addGraphic(circleGraphic);
// 数据
mark_CircleGraphicData.push(circleGraphic);
}
});
};
// 地图标注-恢复默认
function markRestoreDefault() {
// 点-恢复默认
for (let i = 0; i < mark_PointGraphicData.length; i++) {
let pointGraphic = mark_PointGraphicData[i];
pointGraphic.setStyle({
label: {
color: '#000000',
},
});
}
// 线-恢复默认
for (let i = 0; i < mark_LineStringGraphicData.length; i++) {
let lineGraphic = mark_LineStringGraphicData[i];
lineGraphic.setStyle({
label: {
color: '#000000',
},
});
}
// 矩形-恢复默认
for (let i = 0; i < mark_PolygonGraphicData.length; i++) {
let polygonGraphic = mark_PolygonGraphicData[i];
polygonGraphic.setStyle({
label: {
color: '#000000',
},
});
}
// 圆形-恢复默认
for (let i = 0; i < mark_CircleGraphicData.length; i++) {
let circleGraphic = mark_CircleGraphicData[i];
circleGraphic.setStyle({
label: {
color: '#000000',
},
});
}
}
// 地图标注-SVG内容生成图片链接
function svgToDataURL(svgString) {
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';
const graphic = await graphicLayers.startDraw({
type: 'billboard',
style: {
image: 'https://data.mars3d.cn/img/marker/mark-red.png',
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
label: {
text: '可以同时支持文字',
font_size: 26,
color: drawColorPoint.value,
outline: true,
outlineColor: '#000000',
pixelOffsetY: -60,
},
},
});
}
// 地图标注-绘制-线
async function drawPolyline() {
if (mapDrawType.value == 'drawPolyline') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawPolyline';
const graphic = await graphicLayers.startDraw({
type: 'polyline',
style: {
pixelSize: 12,
color: '#3388ff',
label: {
text: '可以同时支持文字',
font_size: 20,
color: '#ffffff',
outline: true,
outlineColor: '#000000',
pixelOffsetY: -20,
},
},
});
console.log('标绘完成', graphic.toJSON());
}
// 地图标注-绘制-形状
async function drawPolygon() {
if (mapDrawType.value == 'drawPolygon') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawPolygon';
const graphic = await graphicLayers.startDraw({
type: 'polygon',
style: {
color: '#ffff00',
opacity: 0.5,
outline: true,
outlineColor: '#ffffff',
outlineWidth: 2.0,
},
});
console.log('标绘完成', graphic.toJSON());
}
// 地图标注-绘制-形状
async function drawCricle() {
if (mapDrawType.value == 'drawCricle') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawCricle';
const graphic = await graphicLayers.startDraw({
type: 'circle',
style: {
color: '#ffff00',
opacity: 0.6,
outline: true,
outlineColor: '#ffffff',
outlineWidth: 2.0,
},
});
console.log('标绘完成', graphic.toJSON());
}
// 地图照片--------------------------------------------------------------------
// 地图照片-初始化-遍历展示
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_LineStringGraphicData?.forEach((graphicLayer) => {
if (graphicLayer.options.id == props.nowShowAreaData.id) {
graphicLayer.setStyle({
label: {
color: graphicLayer.options.style.color,
},
});
if (oldVal && newVal.id == oldVal.id) {
addAndUpdateWorkArea(graphicLayer, 'noland_Polyline', 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_LineStringGraphicData?.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_LineStringGraphicData = [];
// 地图作业区域-作业区-多边形
area_dfence_PolygonGraphicData = [];
// 地图作业区域-作业区-圈
area_dfence_CircleGraphicData = [];
// 地图作业区域-限飞区-多边形
area_nfz_PolygonGraphicData = [];
// 地图作业区域-限飞区-圈
area_nfz_CircleGraphicData = [];
props.allAreaDataList.forEach((item, index) => {
// console.log(item);
// 地图作业区域-禁降区-线
if (item.type == 'noland' && item.geomtype == 'Polyline') {
let nolandLineGraphic = new mars3d.graphic.PolylineEntity({
positions: item.coordinates[0][0],
style: {
clampToGround: item.properties.clampToGround,
width: 10,
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事件
nolandLineGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
nolandLineGraphic.setStyle({
label: {
color: item.state == 0 ? item.properties.color : '#6d6d6d',
},
});
}
});
// 监听mouseout事件
nolandLineGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowAreaData || props.nowShowAreaData.id !== item.id) {
nolandLineGraphic.setStyle({
label: {
color: '#000000',
},
});
}
});
// 监听点击事件
nolandLineGraphic.on(mars3d.EventType.click, function () {
// 全部恢复默认
areaRestoreDefault();
nolandLineGraphic.setStyle({
label: {
color: item.state == 0 ? item.properties.color : '#6d6d6d',
},
});
emits('setNowShowAreaData', item);
});
// 将 禁降区-线 添加到图层中
graphicLayers.addGraphic(nolandLineGraphic);
// 数据
area_noland_LineStringGraphicData.push(nolandLineGraphic);
}
// 地图作业区域-作业区-多边形
if (item.type == 'dfence' && item.geomtype == 'Polygon') {
let dfence_PolygonGraphic = new mars3d.graphic.PolygonEntity({
id: item.id,
positions: item.coordinates[0][0],
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[0][0],
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_LineStringGraphicData.length; i++) {
let graphic = area_noland_LineStringGraphicData[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_Polyline') {
}
// 自定义多边形限飞区
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 '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;
// 自定义多边形作业区
case 'nfz_Polygon':
type = 'nfz';
coordinates.push(coordinates[0]);
polygonData.push(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 'dfence_Polygon':
type = 'dfence';
coordinates.push(coordinates[0]);
polygonData.push(coordinates);
geom = GeojsonToWkt(turf.polygon(polygonData).geometry);
properties = {
clampToGround: true,
color: '#00FF00',
centerPoint: coordinates[0],
};
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,
markRestoreDefault,
areaRestoreDefault,
});
</script>
<style lang="less" scoped>
.mars3d-container {
position: relative;
width: 100%;
height: 100%;
}
.markButtons {
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;
}
.popoverMark {
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>