main
徐景良 2025-07-18 08:43:07 +08:00
commit 752c869865
17 changed files with 5299 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

View File

@ -0,0 +1,322 @@
<template>
<div class="pathModal">
<!-- 左侧目录 -->
<div
class="leftMenuDiv"
:style="{
width: leftMenuShow ? '340px' : '64px',
}"
>
<PathLeftMenu
ref="pathLeftMenuRef"
:leftMenuShow="leftMenuShow"
:allAreaDataList="allAreaDataList"
:nowShowAreaData="nowShowAreaData"
@changeLeftMenuShow="changeLeftMenuShow"
@handlerLocation="handlerLocation"
@changeAnnotationInfoShow="changeAnnotationInfoShow"
@setNowShowAnnotationData="setNowShowAnnotationData"
@setNowShowImageData="setNowShowImageData"
@setNowShowAreaData="setNowShowAreaData"
@setAllAnnotationData="setAllAnnotationData"
@setAllAreaData="setAllAreaData"
@deleteAnnotation="deleteAnnotation"
@deleteArea="deleteArea"
/>
</div>
<!-- 地图 -->
<div class="mapDiv" :style="{ width: dynamicWidth }">
<PathMap
ref="pathMapRef"
:allAnnotationDataList="allAnnotationDataList"
:nowShowAnnotationData="nowShowAnnotationData"
:allAreaDataList="allAreaDataList"
:nowShowAreaData="nowShowAreaData"
:allImageDataList="allImageDataList"
:nowShowImageData="nowShowImageData"
@setNowShowAnnotationData="setNowShowAnnotationData"
@setNowShowImageData="setNowShowImageData"
@setNowShowAreaData="setNowShowAreaData"
@setAllAnnotationData="setAllAnnotationData"
@setAllAreaData="setAllAreaData"
@closePathImageInfo="closePathImageInfo"
/>
</div>
<!-- 地图作业区域 -->
<div class="areaInfoDiv" v-if="areaInfoShow">
<PathAreaInfo
:allAreaDataList="allAreaDataList"
:nowShowAreaData="nowShowAreaData"
@setNowShowAreaData="setNowShowAreaData"
@closePathAreaInfo="closePathAreaInfo"
@handlerLocation="handlerLocation"
@deleteArea="deleteArea"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue';
import { PathLeftMenu, PathMap, PathAreaInfo } from './path';
import { cloneDeep } from 'lodash-es';
import imageJson from './json/image.json';
import {
GetAnnotationList,
DeleteAnnotation,
GetWorkAreaList,
DeleteWorkArea,
} from '@/api/demo/mediaLibrary';
import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['pathRecord']);
//
const dynamicWidth = computed(() => {
let width = 0;
//
if (leftMenuShow.value) {
width += 340;
} else {
width += 64;
}
//
if (areaInfoShow.value) {
width += 320;
}
return 'calc(100% - ' + width + 'px)';
});
// ref
const pathMapRef = ref();
// ----------------------------------------------------
const pathLeftMenuRef = ref();
const leftMenuShow = ref(true);
function changeLeftMenuShow() {
leftMenuShow.value = !leftMenuShow.value;
}
function changeAnnotationInfoShow() {
}
//
function closePathAnnotationInfo() {
nowShowAnnotationData.value = {};
pathMapRef.value.annotationRestoreDefault();
}
//
const nowShowAnnotationData = ref();
const allAnnotationDataList: any = ref([]);
//
function setNowShowAnnotationData(value, restore = true) {
if (restore) {
pathMapRef.value.annotationRestoreDefault();
}
nowShowAnnotationData.value = value;
}
//
function setAllAnnotationData() {
//
getAnnotationList();
}
//
async function getAnnotationList(showThis = true) {
allAnnotationDataList.value = await GetAnnotationList({ workspaceid: 1 });
if (allAnnotationDataList.value.length > 0) {
allAnnotationDataList.value.forEach((annotation, index) => {
let geomjson = WktToGeojson(annotation.geom);
annotation = {
...annotation,
properties: JSON.parse(annotation.properties),
geomtype: getGeomType(annotation),
coordinates: geomjson.coordinates,
};
allAnnotationDataList.value[index] = annotation;
});
}
if (showThis) {
setTimeout(() => {
pathLeftMenuRef.value.updateShowMenuInfoList('地图标注');
}, 50);
}
}
//
function deleteAnnotation(value) {
if (nowShowAnnotationData.value && nowShowAnnotationData.value.id == value.id) {
nowShowAnnotationData.value = {};
}
DeleteAnnotation({
id: value.id,
}).then((result) => {
if (result) {
//
getAnnotationList();
createMessage.success('删除成功');
}
});
}
// ----------------------------------------------------
const areaInfoShow = ref(false);
function changeAreaInfoShow() {
areaInfoShow.value = !areaInfoShow.value;
}
//
function closePathAreaInfo() {
areaInfoShow.value = false;
nowShowAreaData.value = {};
pathMapRef.value.areaRestoreDefault();
}
//
const nowShowAreaData = ref();
const allAreaDataList: any = ref([]);
//
function setNowShowAreaData(value, restore = true) {
if (value.id) {
areaInfoShow.value = true;
} else {
areaInfoShow.value = false;
}
if (restore) {
pathMapRef.value.areaRestoreDefault();
}
nowShowAreaData.value = value;
}
//
function setAllAreaData() {
//
getWorkAreaList();
}
//
async function getWorkAreaList(showThis = true) {
allAreaDataList.value = await GetWorkAreaList({ workspaceid: 1 });
if (allAreaDataList.value.length > 0) {
allAreaDataList.value.forEach((area, index) => {
let geomjson = WktToGeojson(area.geom);
area = {
...area,
properties: JSON.parse(area.properties),
geomtype: getGeomType(area),
coordinates: geomjson.coordinates,
};
allAreaDataList.value[index] = area;
});
}
if (showThis) {
setTimeout(() => {
pathLeftMenuRef.value.updateShowMenuInfoList('地图作业区域');
}, 50);
}
}
//
async function deleteArea(value) {
if (nowShowAreaData.value && nowShowAreaData.value.id == value.id) {
areaInfoShow.value = false;
nowShowAreaData.value = {};
}
DeleteWorkArea({
id: value.id,
}).then((result) => {
if (result) {
//
getWorkAreaList();
createMessage.success('删除成功');
}
});
}
//
function closePathImageInfo() {
}
//
const nowShowImageData = ref();
const allImageDataList = ref(imageJson);
//
function setNowShowImageData(value) {
nowShowImageData.value = value;
pathMapRef.value.setNowShowImageByRight();
}
// -----------------------------------------------------------------
//
function handlerLocation(position) {
pathMapRef.value.handlerLocation([position.lng, position.lat]);
}
// WKT
function getGeomType(area) {
let geom = area.geom;
let radiusFlag = area.properties.indexOf('radius') > -1 ? true : false;
//
if (geom.indexOf('POINT') > -1 && !radiusFlag) {
return 'Point';
}
// 线
if (geom.indexOf('LINESTRING') > -1 && !radiusFlag) {
return 'Polyline';
}
//
if (geom.indexOf('POLYGON') > -1 && !radiusFlag) {
return 'Polygon';
}
//
if (geom.indexOf('POLYGON') > -1 && radiusFlag) {
return 'Circle';
}
}
onMounted(() => {
//
getWorkAreaList(false);
getAnnotationList();
});
</script>
<style lang="less" scoped>
.pathModal {
position: relative;
display: flex;
width: 100%;
height: 100vh;
.leftMenuDiv {
position: relative;
height: 100%;
}
.mapDiv {
position: relative;
height: 100%;
// width: auto;
}
.annotationInfoDiv {
position: relative;
height: 100%;
width: 320px;
}
.areaInfoDiv {
position: relative;
height: 100%;
width: 320px;
}
.imageInfoDiv {
position: relative;
height: 100%;
// width: 37%;
width: 720px;
// min-width: 720px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
export { default as PathLeftMenu } from './pathLeftMenu.vue';
export { default as PathMap } from './pathMap.vue';
export { default as PathAreaInfo } from './pathAreaInfo.vue';

View File

@ -0,0 +1,374 @@
<template>
<div class="areaInfo">
<a-row>
<a-col :span="24">
<div class="annotationTitle"> 自定义飞行区 </div>
</a-col>
<a-col :span="24">
<div class="annotationTitle">
<!-- 自定义禁降区 -->
<div
v-if="props.nowShowAreaData.type == 'noland'"
:style="{
width: '15px',
height: '15px',
outline: `2px solid #FF9900`,
'margin-left': '2px',
'margin-right': '12px',
}"
/>
<!-- 自定义作业区 -->
<div
v-if="props.nowShowAreaData.type == 'dfence'"
:style="{
width: '13px',
height: '13px',
outline: `2px solid #00FF00`,
'margin-left': '2px',
'margin-right': '12px',
'border-radius': props.nowShowAreaData.geomtype == 'Circle' ? '6.5px' : '0px',
}"
/>
<!-- 自定义限飞区 -->
<div
v-if="props.nowShowAreaData.type == 'nfz'"
:style="{
width: '13px',
height: '13px',
outline: `2px solid #FF0000`,
background: `#FF000055`,
'margin-left': '2px',
'margin-right': '12px',
'border-radius': props.nowShowAreaData.geomtype == 'Circle' ? '6.5px' : '0px',
}"
/>
<a-input v-model:value="nowAreaData.name" style="width: 65%" size="small"></a-input>
<div class="annotationTitleButton" @click="handlerLocation">
<AimOutlined />
</div>
<div class="annotationTitleButton" @click="deleteArea">
<DeleteOutlined />
</div>
</div>
</a-col>
<a-col :span="24">
<div class="annotationPrompt" v-if="props.nowShowAreaData.type == 'noland'">
自定义作业区绘制后飞行器只能在该区域内飞行
</div>
<div class="annotationPrompt" v-if="props.nowShowAreaData.type == 'dfence'">
自定义禁降区绘制后飞行器不能在绘制区域内自动降落
</div>
<div class="annotationPrompt" v-if="props.nowShowAreaData.type == 'nfz'">
自定义作业区绘制后飞行器只能在该区域内飞行
</div>
</a-col>
<a-col :span="24">
<div class="annotationTitle"> 更多信息 </div>
</a-col>
<!-- 启用状态 -->
<a-col :span="6">
<div class="annotationTitle">启用状态</div>
</a-col>
<a-col :span="18">
<div class="annotationContent">
{{ props.nowShowAreaData.state == 0 ? '已启用' : '已禁用' }}
</div>
</a-col>
<!-- 水平周长 -->
<a-col :span="6">
<div class="annotationTitle">水平周长</div>
</a-col>
<a-col :span="18">
<div class="annotationContent"> {{ length.toFixed(2) }}m</div>
</a-col>
<!-- 水平面积 -->
<a-col :span="6">
<div class="annotationTitle">水平面积</div>
</a-col>
<a-col :span="18">
<div class="annotationContent"> {{ area.toFixed(2) }}</div>
</a-col>
<!-- 半径 -->
<a-col :span="6" v-if="props.nowShowAreaData.geomtype == 'Circle'">
<div class="annotationTitle">半径</div>
</a-col>
<a-col :span="18" v-if="props.nowShowAreaData.geomtype == 'Circle'">
<div class="annotationContent">
<a-input v-model:value="nowAreaData.properties.radius" style="width: 100%" size="small">
<template #addonAfter> <span style="color: white">m</span> </template>
</a-input>
</div>
</a-col>
<!-- 绘制者 -->
<a-col :span="6">
<div class="annotationTitle">绘制者</div>
</a-col>
<a-col :span="18">
<div class="annotationContent"> {{ props.nowShowAreaData.createdUser }}</div>
</a-col>
<a-col :span="24">
<div class="area_buttons">
<div class="cancelDiv" @click="closePathAreaInfo"></div>
<div class="startDiv" :class="{ disabled: props.nowShowAreaData }">确认</div>
</div>
</a-col>
</a-row>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, nextTick } from 'vue';
import * as mars3d from 'mars3d';
import * as Cesium from 'mars3d-cesium';
import {
CloseOutlined,
DeleteOutlined,
CheckOutlined,
AimOutlined,
AlignLeftOutlined,
InfoCircleOutlined,
AntDesignOutlined,
ExpandAltOutlined,
BorderOutlined,
LogoutOutlined,
MinusOutlined,
PlusOutlined,
} from '@ant-design/icons-vue';
import {
GetWorkAreaList,
AddWorkArea,
UpdateWorkArea,
DeleteWorkArea,
} from '@/api/demo/mediaLibrary';
import { cloneDeep } from 'lodash-es';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['allAreaDataList', 'nowShowAreaData']);
console.log('nowShowAreaData',props.nowShowAreaData)
const emits = defineEmits([
'setNowShowAreaData',
'closePathAreaInfo',
'handlerLocation',
'deleteArea',
]);
const nowAreaData: any = ref(props.nowShowAreaData);
//
function closePathAreaInfo() {
emits('closePathAreaInfo');
}
//
function handlerLocation() {
emits('handlerLocation', {
lng: props.nowShowAreaData.properties.centerPoint[0],
lat: props.nowShowAreaData.properties.centerPoint[1],
});
}
//
function deleteArea() {
createConfirm({
iconType: 'info',
title: '提示',
content: '将会影响到项目内设备的作业范围,是否删除该区域?',
onOk: async () => {
emits('deleteArea', props.nowShowAreaData);
},
});
}
//
const length: any = ref();
const area: any = ref();
watch(
() => nowAreaData.value,
() => {
emits('setNowShowAreaData', nowAreaData.value, false);
},
{
deep: true,
},
);
watch(
() => props.nowShowAreaData,
() => {
nowAreaData.value = props.nowShowAreaData;
if (props.nowShowAreaData.geomtype == 'Polygon') {
//
length.value = mars3d.MeasureUtil.getDistance(nowAreaData.value.coordinates[0]);
//
area.value = mars3d.MeasureUtil.getArea(nowAreaData.value.coordinates[0]);
}
if (props.nowShowAreaData.geomtype == 'Circle') {
//
length.value = 2 * Math.PI * parseFloat(nowAreaData.value.properties.radius);
//
area.value =
Math.PI *
parseFloat(nowAreaData.value.properties.radius) *
parseFloat(nowAreaData.value.properties.radius);
}
},
{
deep: true,
immediate: true,
},
);
</script>
<style lang="less" scoped>
.areaInfo {
//
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none;
position: relative;
width: 100%;
height: 100%;
background: #232323;
padding: 15px;
}
.annotationTitle {
display: flex;
align-items: center;
justify-content: flex-start;
color: #ffffff;
font-size: 14px;
min-height: 45px;
height: auto;
width: 100%;
flex-wrap: wrap;
.annotationTitleButton_right {
height: 20px;
width: 20px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
font-size: 18px;
}
.annotationTitleButton {
height: 20px;
width: 20px;
display: flex;
align-items: center;
justify-content: center;
margin-left: 12px;
font-size: 18px;
}
}
.annotationContent {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 45px;
height: auto;
width: 100%;
flex-wrap: wrap;
color: #ffffff;
}
.annotationButton {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 45px;
height: auto;
width: 100%;
flex-wrap: wrap;
}
.annotationPrompt {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 45px;
height: auto;
width: 100%;
flex-wrap: wrap;
color: #ffffff55;
}
.button {
display: flex;
align-items: center;
justify-content: center;
width: 35px;
height: 35px;
background: #3c3c3c;
border-radius: 2px;
&:hover {
background: #5d5f61;
}
}
.button.disabled {
cursor: not-allowed;
opacity: 0.5;
background-color: #ccc;
}
.numDiv {
width: calc(80% - 70px);
display: flex;
align-items: center;
justify-content: center;
.numSpan {
color: #2d8cf0;
font-size: 26px;
font-weight: bold;
&:hover {
text-decoration: underline;
text-decoration-color: #2d8cf0;
}
}
}
//
.area_buttons {
display: flex;
align-items: center;
justify-content: center;
border-top: 1px solid #ffffff55;
width: 100%;
height: 68px;
gap: 20px;
.cancelDiv {
display: flex;
align-items: center;
justify-content: center;
background: #3c3c3c;
color: #ffffff;
width: 40%;
height: 32px;
border-radius: 5px;
&:hover {
background: #5d5f61;
}
}
.startDiv {
display: flex;
align-items: center;
justify-content: center;
background: #0960bd;
color: #ffffff;
width: 40%;
height: 32px;
border-radius: 5px;
&:hover {
background: #2a7dc9;
}
}
}
</style>

View File

@ -0,0 +1,592 @@
<template>
<div class="leftMenu">
<div class="leftMenuContent">
<div class="leftMenuContent_2" v-if="leftMenuShow">
<div class="leftMenuContent_title">
{{ showMenuInfoName }}
</div>
<div class="leftMenuContent_list">
<!-- 地图作业区域 -->
<div v-if="showMenuInfoName == '地图作业区域'" style="margin: 10px">
<a-select
v-model:value="areatype"
style="width: 120px; margin-right: 15px"
@change="handleChangeAreaSelect"
>
<a-select-option value="all">全部类型</a-select-option>
<a-select-option value="dfence">全部作业区</a-select-option>
<a-select-option value="nfz">全部限飞区</a-select-option>
<a-select-option value="noland">全部禁降区</a-select-option>
</a-select>
<a-select
v-model:value="areastate"
style="width: 120px"
@change="handleChangeAreaSelect"
>
<a-select-option value="all">全部状态</a-select-option>
<a-select-option value="0">已启用</a-select-option>
<a-select-option value="1">已禁用</a-select-option>
</a-select>
</div>
<!-- 列表 -->
<div v-for="show in showMenuInfoList" :key="show.id">
<!-- 地图作业区域 -->
<div
class="showMenuInfo_area"
:style="{
outline:
props.nowShowAreaData && props.nowShowAreaData.id == show.id
? '2px solid #2D8CF0'
: '',
background: props.nowShowAreaData && show.state == 0 ? '#3c3c3c' : '#3c3c3c55',
}"
>
<a-tooltip placement="right">
<template #title> {{ show.name }} </template>
<div
class="name"
@click="setNowShowAreaData(show)"
:style="{
color: show.state == 0 ? '#ffffff' : '#ffffff55',
}"
>
{{ show.name }}
</div>
</a-tooltip>
<div
class="type"
@click="setNowShowAreaData(show)"
:style="{
color: show.state == 0 ? '#ffffff' : '#ffffff55',
}"
>
<!-- 自定义禁降区 -->
<div
v-if="show.type == 'noland'"
:style="{
width: '13px',
height: '13px',
outline: `2px solid #FF9900`,
'margin-right': '6px',
}"
/>
<!-- 自定义作业区 -->
<div
v-if="show.type == 'dfence'"
:style="{
width: '13px',
height: '13px',
outline: `2px solid #00FF00`,
'margin-right': '6px',
'border-radius': show.geomtype == 'Circle' ? '6.5px' : '0px',
}"
/>
<!-- 自定义限飞区 -->
<div
v-if="show.type == 'nfz'"
:style="{
width: '13px',
height: '13px',
outline: `2px solid #FF0000`,
background: `#FF000055`,
'margin-right': '6px',
'border-radius': show.geomtype == 'Circle' ? '6.5px' : '0px',
}"
/>
<span>{{ getType(show.type) }}</span>
</div>
<div class="buttonlist">
<div class="button" v-if="show.state == 1">
<a-popconfirm
title="将会影响到项目内设备的作业范围,是否启用该区域?"
ok-text="启用"
cancel-text="取消"
placement="right"
@confirm="enableThisArea(show)"
>
<a-tooltip placement="top">
<template #title>
<span>可点击启用该区域</span>
</template>
<CheckCircleOutlined />
</a-tooltip>
</a-popconfirm>
</div>
<div class="button" v-if="show.state == 0">
<a-popconfirm
title="将会影响到项目内设备的作业范围,是否禁用该区域?"
ok-text="禁用"
cancel-text="取消"
placement="right"
@confirm="disableThisArea(show)"
>
<a-tooltip placement="top">
<template #title>
<span>可点击禁用该区域</span>
</template>
<StopOutlined />
</a-tooltip>
</a-popconfirm>
</div>
<div class="button">
<a-tooltip placement="top">
<template #title>
<span>回中</span>
</template>
<AimOutlined @click="handlerLocation(show)" />
</a-tooltip>
</div>
<div class="button">
<a-popconfirm
title="将会影响到项目内设备的作业范围,是否删除该区域?"
ok-text="删除"
cancel-text="取消"
placement="right"
@confirm="deleteArea(show)"
>
<a-tooltip placement="top">
<template #title>
<span>删除</span>
</template>
<DeleteOutlined />
</a-tooltip>
</a-popconfirm>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="suojinButton" @click="changeLeftMenuShow">
<DoubleLeftOutlined v-if="leftMenuShow" style="font-size: 16px" />
<DoubleRightOutlined v-if="!leftMenuShow" style="font-size: 16px" />
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import {
CloseOutlined,
AntDesignOutlined,
DoubleLeftOutlined,
DoubleRightOutlined,
EnvironmentOutlined,
CodeSandboxOutlined,
ExpandAltOutlined,
BorderOutlined,
LogoutOutlined,
EyeOutlined,
EyeInvisibleOutlined,
AimOutlined,
DeleteOutlined,
FileImageOutlined,
CheckCircleOutlined,
StopOutlined,
} from '@ant-design/icons-vue';
import { UpdateWorkArea, UpdateAnnotation } from '@/api/demo/mediaLibrary';
import { cloneDeep } from 'lodash-es';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps([
'leftMenuShow',
'allAreaDataList',
'nowShowAreaData',
]);
const emits = defineEmits([
'changeLeftMenuShow',
'handlerLocation',
'setNowShowAreaData',
'setAllAreaData',
'deleteArea',
]);
const showMenuInfoList = ref(props.allAreaDataList);
const showMenuInfoName = ref('地图作业区域');
function updateShowMenuInfoList(type) {
handleChangeAreaSelect();
}
// -
function changeLeftMenuShow() {
emits('changeLeftMenuShow');
}
// -------------------------------------------------
// -
const areatype = ref('all');
const areastate = ref('all');
// -
function getType(type) {
let name = '';
switch (type) {
case 'nfz':
name = '自定义限飞区';
break;
case 'dfence':
name = '自定义作业区';
break;
case 'noland':
name = '自定义禁降区';
break;
}
return name;
}
// -
const filterAfterAreaDataList = ref(props.allAreaDataList);
function handleChangeAreaSelect() {
let filterAreaData = props.allAreaDataList;
if (areatype.value !== 'all') {
filterAreaData = filterAreaData.filter((item) => item.type == areatype.value);
}
if (areastate.value !== 'all') {
filterAreaData = filterAreaData.filter((item) => item.state == areastate.value);
}
filterAfterAreaDataList.value = filterAreaData;
showMenuInfoList.value = filterAfterAreaDataList.value;
}
// -
function enableThisArea(value) {
setNowShowAreaData({
...value,
state: 0,
});
UpdateWorkArea({
...value,
properties: JSON.stringify(value.properties),
state: 0,
}).then((res) => {
emits('setAllAreaData');
});
}
// -
function disableThisArea(value) {
setNowShowAreaData({
...value,
state: 1,
});
UpdateWorkArea({
...value,
properties: JSON.stringify(value.properties),
state: 1,
}).then((res) => {
emits('setAllAreaData');
});
}
// -
function deleteArea(show) {
emits('deleteArea', show);
}
//
function setNowShowAreaData(value) {
emits('setNowShowAreaData', value);
}
// ------------------------------------------------------------------
//
function handlerLocation(position) {
// if (showMenuInfoName.value == '') {
// let coordinates = position.coordinates;
// switch (position.type) {
// case 0:
// emits('handlerLocation', {
// lng: coordinates[0],
// lat: coordinates[1],
// });
// break;
// case 1:
// emits('handlerLocation', {
// lng: coordinates[0][0],
// lat: coordinates[0][1],
// });
// break;
// case 2:
// emits('handlerLocation', {
// lng: coordinates[0][0][0],
// lat: coordinates[0][0][1],
// });
// break;
// case 3:
// emits('handlerLocation', {
// lng: coordinates[0],
// lat: coordinates[1],
// });
// break;
// }
// }
// if (showMenuInfoName.value == '') {
// emits('handlerLocation', {
// lng: position.photo_position.lng,
// lat: position.photo_position.lat,
// });
// }
if (showMenuInfoName.value == '地图作业区域') {
if (position.geomtype == 'Circle') {
emits('handlerLocation', {
lng: position.properties.centerPoint[0],
lat: position.properties.centerPoint[1],
});
} else {
emits('handlerLocation', {
lng: position.properties.centerPoint[0],
lat: position.properties.centerPoint[1],
});
}
}
}
defineExpose({
updateShowMenuInfoList,
});
</script>
<style lang="less" scoped>
.leftMenu {
position: relative;
width: 100%;
height: 100%;
background: #232323;
.leftMenuTitle {
position: relative;
width: 100%;
height: 50px;
padding: 10px;
border-bottom: 1px solid #ffffff55;
.title {
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 20px;
color: #ffffff;
width: 100%;
/* 关键属性 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.leftMenuContent {
position: relative;
display: flex;
width: 100%;
height: calc(100%-50px);
// height: 800px;
.leftMenuContent_1 {
position: relative;
width: 64px;
height: 100%;
border-right: 1px solid #ffffff55;
// padding-top: 10px;
// padding-bottom: 10px;
.leftMenu_closeButton {
position: relative;
padding-top: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
.leftMenu_buttonList {
position: relative;
width: 50px;
height: 100%;
border-radius: 10px;
background: #1a375a;
margin-top: 15px;
margin-left: 7px;
margin-right: 7px;
padding-top: 5px;
padding-bottom: 5px;
gap: 10px;
.leftMenu_buttonList_annotation {
position: relative;
border-radius: 5px;
height: 40px;
width: 40px;
margin: 5px;
display: flex;
align-items: center;
justify-content: center;
}
.leftMenu_buttonList_image {
position: relative;
border-radius: 5px;
height: 40px;
width: 40px;
margin: 5px;
display: flex;
align-items: center;
justify-content: center;
}
.leftMenu_buttonList_area {
position: relative;
border-radius: 5px;
height: 40px;
width: 40px;
margin: 5px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.leftMenuContent_2 {
position: relative;
width: 275px;
height: 100%;
.leftMenuContent_title {
margin-top: 10px;
margin-left: 10px;
color: #ffffff;
font-size: 16px;
}
.leftMenuContent_list {
overflow-y: auto;
max-height: 800px;
//
.showMenuInfo_annotation {
position: relative;
display: flex;
align-items: center;
justify-content: flex-start;
color: #ffffff;
height: 30px;
padding-left: 15px;
gap: 10px;
.eye {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
.buttonRight2 {
position: absolute;
right: 30px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.buttonRight1 {
position: absolute;
right: 5px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
}
//
.showMenuInfo_image {
display: flex;
align-items: center;
justify-content: flex-start;
color: #ffffff;
height: 30px;
padding-left: 15px;
gap: 10px;
.eye {
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
.buttonRight2 {
position: absolute;
right: 35px;
}
.buttonRight1 {
position: absolute;
right: 10px;
}
}
//
.showMenuInfo_area {
position: relative;
display: flex;
align-items: center;
justify-content: flex-start;
height: 70px;
margin: 10px 15px;
.name {
position: absolute;
top: 6px;
left: 6px;
color: #ffffff;
font-size: 15px;
width: 90%;
height: 30px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.type {
position: absolute;
display: inline-flex;
align-items: center;
justify-content: flex-start;
bottom: 6px;
left: 8px;
color: #ffffff;
font-size: 15px;
width: 165px;
}
.buttonlist {
position: absolute;
bottom: 6px;
right: 6px;
width: 75px;
height: 25px;
display: flex;
gap: 1px;
.button {
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 16px;
width: 25px;
height: 25px;
}
}
}
}
}
}
}
.suojinButton {
position: absolute;
top: 45%;
right: -18px;
height: 90px;
width: 18px;
background: #ffffff;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -814,6 +814,7 @@
//
const pathRecord = ref({});
function openPathModal(record) {
console.log('pathRecord',record)
pathRecord.value = record;
pathOpen.value = true;
}

View File

@ -144,6 +144,7 @@
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['allAreaDataList', 'nowShowAreaData']);
console.log('nowShowAreaData',props.nowShowAreaData)
const emits = defineEmits([
'setNowShowAreaData',
'closePathAreaInfo',

View File

@ -406,23 +406,15 @@ const getLocationCenter = () => {
const position = { lng: lon, lat }
project.value.centerLng = lon
project.value.centerLat = lat
const pointGraphic = new mars3d.graphic.PointEntity({
const pointGraphic = new mars3d.graphic.BillboardEntity({
position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
style: {
color: '#ff0000',
pixelSize: 10,
outlineColor: '#ffffff',
outlineWidth: 2,
label: {
text: `经度: ${lon.toFixed(6)}\n纬度: ${lat.toFixed(6)}`,
font_size: 16,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffsetY: -20
}
image: '/projecthome/project_location.png',
width: 53,
height: 97,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
}
})
props.graphicLayer.clear()

View File

@ -85,6 +85,7 @@ const selectProject = (item) => {
if(props.activeProject != item.Id){
props.airPort.latitude = null
props.airPort.longitude = null
props.airPort.mode_code = null
getClient().unsubscribe(lastSubscriptUrl.value,(error, res) => {})
}
emits('update:activeProject',item.Id)
@ -99,24 +100,16 @@ const selectProject = (item) => {
})
let { centerLat:lat, centerLng: lon } = res.workspace
const position:any = [lon, lat]
const pointGraphic = new mars3d.graphic.PointEntity({
const pointGraphic = new mars3d.graphic.BillboardEntity({
position: position,
style: {
color: '#ff0000',
pixelSize: 10,
outlineColor: '#ffffff',
outlineWidth: 2,
image: '/projecthome/project_location.png',
width: 53,
height: 97,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
clampToGround: true,
label: {
text: `${res.workspace.workspaceName}`,
font_size: 16,
color: '#000000',
outline: true,
outlineColor: '#ffffff',
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffsetY: -20
}
}
})
graphicLayer.value.clear()

View File

@ -39,6 +39,7 @@ const airRoute = ref({
const airPort = ref({
latitude: null,
longitude: null,
mode_code: null,
});
const activeProject = ref('')
const DESIGN_WIDTH = 1912
@ -76,6 +77,7 @@ const connectionCallback = () => {
if (rs.data.latitude && rs.data.longitude) {
airPort.value.latitude = rs.data.latitude;
airPort.value.longitude = rs.data.longitude;
airPort.value.mode_code = rs.data.mode_code;
}
}
});

View File

@ -209,6 +209,7 @@ const generatePreviewPoint = (placemark)=>{
//
let homeStartGraphic;
let homeStartGraphicLive;
let graphic = null;
@ -1812,7 +1813,7 @@ const clearAllLayer = () => {
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
const setAirportPosition = async () => {
@ -1876,21 +1877,26 @@ const setAirportPosition = async () => {
//
const homeSetAirportPosition = () => {
if(!graphicLayer){
return
}
// //
let position = [props.homeAirport.longitude, props.homeAirport.latitude, 70];
//
if (homeStartGraphic) {
homeStartGraphic.position = position
} else {
homeStartGraphic = new mars3d.graphic.BillboardEntity({
id: 'set-home-airport',
position: position,
style: {
image: '/projecthome/airport.png',
width: 35,
height: 59,
return
}
// //
let position = [props.homeAirport.longitude, props.homeAirport.latitude, 70];
let airportImg = props.homeAirport.mode_code == 4? '/projecthome/work_airport.png': '/projecthome/standby_airport.png'
let airportLiveImg = props.homeAirport.mode_code == 4? '/projecthome/work_airport_live.png': '/projecthome/standby_airport_live.png'
//
if (homeStartGraphic && homeStartGraphicLive) {
homeStartGraphic.position = position
homeStartGraphic.image = airportImg
homeStartGraphicLive.position = position
homeStartGraphicLive.image = airportLiveImg
} else {
homeStartGraphic = new mars3d.graphic.BillboardEntity({
id: 'set-home-airport',
position: position,
style: {
image: airportImg,
width: 118,
height: 133,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
@ -1902,15 +1908,36 @@ const homeSetAirportPosition = () => {
outlineColor: '#000000',
pixelOffsetY: -70,
},
},
});
homeStartGraphicLive = new mars3d.graphic.BillboardEntity({
id: 'set-home-airport-live',
position: position,
style: {
image: airportLiveImg,
width: 21,
height: 21,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(45, -107),
label: {
text: '机场',
font_size: 14,
color: '#ffffff',
outline: true,
outlineColor: '#000000',
pixelOffsetY: -70,
},
},
});
homeStartGraphic.on(mars3d.EventType.click, function (event) {
emits('clickAirPort')
});
graphicLayer.addGraphic(homeStartGraphic);
graphicLayer.addGraphic(homeStartGraphicLive);
}
}
//
const setUAVPosition = () => {
let point = graphicLayer.getGraphicById('set-uav');