|
|
@ -5,33 +5,21 @@ |
|
|
|
功能概述:引入vc-drawings地图绘制插件,实现区域绘制并编辑保存数据,注意数据格式!注意数据格式!注意数据格式! |
|
|
|
--> |
|
|
|
<template> |
|
|
|
<a-modal :visible="visible" :title="title" @ok="handleOk" @cancel="handleCancel" width="60vw" destroyOnClose wrapClassName="EarthMap"> |
|
|
|
<a-modal :visible="visible" :title="title" @ok="handleOk" @cancel="handleCancel" width="60vw" destroyOnClose |
|
|
|
wrapClassName="EarthMap"> |
|
|
|
<a-row ref="viewerContainer" class="demo-viewer"> |
|
|
|
<vc-viewer> |
|
|
|
<vc-viewer :showCredit="false"> |
|
|
|
<!-- 修改定位 和 位置偏移 --> |
|
|
|
<vc-drawings |
|
|
|
ref="drawingsRef" |
|
|
|
position="top-left" |
|
|
|
:main-fab-opts="mainFabOpts" |
|
|
|
:offset="[10, 50]" |
|
|
|
:editable="editable" |
|
|
|
:clamp-to-ground="clampToGround" |
|
|
|
@draw-evt="drawEvt" |
|
|
|
@active-evt="activeEvt" |
|
|
|
@editor-evt="editorEvt" |
|
|
|
@mouse-evt="mouseEvt" |
|
|
|
@clear-evt="clearEvt" |
|
|
|
@ready="drawingsReadyDefault" |
|
|
|
:pin-drawing-opts="pinDrawingOpts" |
|
|
|
:point-drawing-opts="pointDrawingOpts" |
|
|
|
:polygon-drawing-opts="polygonDrawingOpts" |
|
|
|
:polyline-drawing-opts="polylineDrawingOpts" |
|
|
|
:regular-drawing-opts="regularDrawingOpts" |
|
|
|
:circle-drawing-opts="circleDrawingOpts" |
|
|
|
:rectangle-drawing-opts="rectangleDrawingOpts" |
|
|
|
></vc-drawings> |
|
|
|
<vc-drawings ref="drawingsRef" position="top-left" :main-fab-opts="mainFabOpts" :offset="[10, 50]" |
|
|
|
:editable="editable" :clamp-to-ground="clampToGround" @draw-evt="drawEvt" @active-evt="activeEvt" |
|
|
|
@editor-evt="editorEvt" @mouse-evt="mouseEvt" @clear-evt="clearEvt" @ready="drawingsReadyDefault" |
|
|
|
:pin-drawing-opts="pinDrawingOpts" :point-drawing-opts="pointDrawingOpts" |
|
|
|
:polygon-drawing-opts="polygonDrawingOpts" :polyline-drawing-opts="polylineDrawingOpts" |
|
|
|
:regular-drawing-opts="regularDrawingOpts" :circle-drawing-opts="circleDrawingOpts" |
|
|
|
:rectangle-drawing-opts="rectangleDrawingOpts"></vc-drawings> |
|
|
|
<vc-layer-imagery> |
|
|
|
<vc-imagery-provider-tianditu map-style="img_c" :maximum-level="17" token="436ce7e50d27eede2f2929307e6b33c0"></vc-imagery-provider-tianditu> |
|
|
|
<!-- <vc-imagery-provider-tianditu map-style="img_c" :maximum-level="17" token="436ce7e50d27eede2f2929307e6b33c0"></vc-imagery-provider-tianditu> --> |
|
|
|
<vc-imagery-provider-tms :url="mapURL"></vc-imagery-provider-tms> |
|
|
|
</vc-layer-imagery> |
|
|
|
<vc-terrain-provider-cesium v-if="addTerrain"></vc-terrain-provider-cesium> |
|
|
|
</vc-viewer> |
|
|
@ -50,11 +38,15 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script lang="ts" setup> |
|
|
|
import { message } from 'ant-design-vue'; |
|
|
|
import { onMounted, watch } from 'vue'; |
|
|
|
import { ref, getCurrentInstance, nextTick } from 'vue'; |
|
|
|
const { proxy }: any = getCurrentInstance(); |
|
|
|
const props = defineProps({ |
|
|
|
import { message } from 'ant-design-vue'; |
|
|
|
import $mitt from '@/utils/earthMap/mitt'; |
|
|
|
import { onMounted, watch } from 'vue'; |
|
|
|
import { ref, getCurrentInstance, nextTick } from 'vue'; |
|
|
|
import { useUserStore } from '/@/store/modules/user'; |
|
|
|
import { defHttp } from '/@/utils/http/axios'; |
|
|
|
|
|
|
|
const { proxy }: any = getCurrentInstance(); |
|
|
|
const props = defineProps({ |
|
|
|
title: { |
|
|
|
type: String, |
|
|
|
default: '区域选取', |
|
|
@ -73,24 +65,31 @@ |
|
|
|
type: String, |
|
|
|
default: '', |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|
//地图提供 |
|
|
|
const mapURL = import.meta.env.VITE_GLOB_EARTHMAP_URL + import.meta.env.VITE_GLOB_SATELLITE_URL |
|
|
|
// const mapURL = "http://127.0.0.1:8088/dt/mapTile/satellite_zh/" |
|
|
|
// console.log("mapURL",mapURL); |
|
|
|
const userStore = useUserStore(); |
|
|
|
//部门信息 |
|
|
|
const sceneInfo: any = ref() |
|
|
|
|
|
|
|
let $viewer = ref(undefined); |
|
|
|
const drawingsRef = ref(); |
|
|
|
// 地形 |
|
|
|
const addTerrain: any = ref(false); |
|
|
|
// 可编辑 |
|
|
|
const editable: any = ref(false); |
|
|
|
// 贴地 |
|
|
|
const clampToGround: any = ref(false); |
|
|
|
// 浮动按钮样式 |
|
|
|
const mainFabOpts = ref<any>({ |
|
|
|
let $viewer: any = ref(undefined); |
|
|
|
const drawingsRef = ref(); |
|
|
|
// 地形 |
|
|
|
const addTerrain: any = ref(false); |
|
|
|
// 可编辑 |
|
|
|
const editable: any = ref(false); |
|
|
|
// 贴地 |
|
|
|
const clampToGround: any = ref(false); |
|
|
|
// 浮动按钮样式 |
|
|
|
const mainFabOpts = ref<any>({ |
|
|
|
direction: 'right', |
|
|
|
}); |
|
|
|
// 表单更新数据 |
|
|
|
const emit = defineEmits(['update:areaData', 'update:drawData']); |
|
|
|
// 绘图数据 |
|
|
|
const drawData = ref<any>({ |
|
|
|
}); |
|
|
|
// 表单更新数据 |
|
|
|
const emit = defineEmits(['update:areaData', 'update:drawData']); |
|
|
|
// 绘图数据 |
|
|
|
const drawData = ref<any>({ |
|
|
|
name: '绘图数据', |
|
|
|
drawList: [ |
|
|
|
{ |
|
|
@ -129,19 +128,19 @@ |
|
|
|
list: [], |
|
|
|
}, |
|
|
|
], |
|
|
|
}); |
|
|
|
const areaDataLits = ref<any>([]); |
|
|
|
// 线绘制参数 |
|
|
|
const polylineDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
const areaDataLits = ref<any>([]); |
|
|
|
// 线绘制参数 |
|
|
|
const polylineDrawingOpts = ref<any>({ |
|
|
|
// 预绘制数组 点、图标点:二维数组 线、面:三维数组 |
|
|
|
preRenderDatas: [], |
|
|
|
// loop: true, |
|
|
|
onClick(e: any) { |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 图标点绘制参数 |
|
|
|
const pinDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 图标点绘制参数 |
|
|
|
const pinDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
billboardOpts: { |
|
|
|
image: 'https://zouyaoji.top/vue-cesium/images/grepin.png', |
|
|
@ -156,9 +155,9 @@ |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 点绘制参数 |
|
|
|
const pointDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 点绘制参数 |
|
|
|
const pointDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
pointOpts: { |
|
|
|
color: 'red', |
|
|
@ -166,45 +165,45 @@ |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 面绘制参数 |
|
|
|
const polygonDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 面绘制参数 |
|
|
|
const polygonDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
onClick(e: any) { |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 正多边形绘制参数 |
|
|
|
const regularDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 正多边形绘制参数 |
|
|
|
const regularDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
onClick(e: any) { |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 圆绘制参数 |
|
|
|
const circleDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 圆绘制参数 |
|
|
|
const circleDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
onClick(e: any) { |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 矩形绘制参数 |
|
|
|
const rectangleDrawingOpts = ref<any>({ |
|
|
|
}); |
|
|
|
// 矩形绘制参数 |
|
|
|
const rectangleDrawingOpts = ref<any>({ |
|
|
|
preRenderDatas: [], |
|
|
|
onClick(e: any) { |
|
|
|
console.log(e); |
|
|
|
}, |
|
|
|
}); |
|
|
|
// 确定 |
|
|
|
async function handleOk(viewer) { |
|
|
|
}); |
|
|
|
// 确定 |
|
|
|
async function handleOk(viewer) { |
|
|
|
//上传 |
|
|
|
updateDraw(viewer); |
|
|
|
message.success('区域编辑成功,请保存上传!'); |
|
|
|
//退出 |
|
|
|
handleCancel(); |
|
|
|
} |
|
|
|
// 上传 |
|
|
|
function updateDraw(viewer: any) { |
|
|
|
} |
|
|
|
// 上传 |
|
|
|
function updateDraw(viewer: any) { |
|
|
|
// 整理数据 |
|
|
|
getDrawingActionInstances(viewer); |
|
|
|
// 格式转换 |
|
|
@ -213,9 +212,9 @@ |
|
|
|
//上传 |
|
|
|
emit('update:drawData', drawDataToString); |
|
|
|
emit('update:areaData', areaDataToString); |
|
|
|
} |
|
|
|
// 加载 |
|
|
|
function loadingData() { |
|
|
|
} |
|
|
|
// 加载 |
|
|
|
function loadingData() { |
|
|
|
if (props.areaData || props.drawData) { |
|
|
|
let loadingSource = JSON.parse(props.drawData); |
|
|
|
drawData.value.drawList = loadingSource; |
|
|
@ -255,9 +254,9 @@ |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
// 整理数据 |
|
|
|
function getDrawingActionInstances(viewer: any) { |
|
|
|
} |
|
|
|
// 整理数据 |
|
|
|
function getDrawingActionInstances(viewer: any) { |
|
|
|
// 监控区域数据 |
|
|
|
let areaData: any = []; |
|
|
|
let k = 0; |
|
|
@ -413,32 +412,158 @@ |
|
|
|
} |
|
|
|
}); |
|
|
|
areaDataLits.value = areaData; |
|
|
|
} |
|
|
|
//监听visible 的值 |
|
|
|
watch( |
|
|
|
} |
|
|
|
//监听visible 的值 |
|
|
|
watch( |
|
|
|
() => props.visible, |
|
|
|
(val) => { |
|
|
|
if (val) { |
|
|
|
loadingData(); |
|
|
|
} |
|
|
|
} |
|
|
|
); |
|
|
|
// 取消 |
|
|
|
function handleCancel() { |
|
|
|
); |
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
|
await loadingData(); |
|
|
|
}); |
|
|
|
|
|
|
|
// 取消 |
|
|
|
function handleCancel() { |
|
|
|
nextTick(() => { |
|
|
|
proxy.$parent.mapVisible = false; |
|
|
|
}); |
|
|
|
} |
|
|
|
async function drawingsReadyDefault({ viewer, cesiumObject }) { |
|
|
|
} |
|
|
|
async function drawingsReadyDefault(e) { |
|
|
|
let viewer = e.viewer |
|
|
|
console.log("viewer", viewer); |
|
|
|
console.log("e", e); |
|
|
|
$viewer.value = viewer; |
|
|
|
// 取消双击旋转事件 |
|
|
|
$viewer.value.cesiumWidget.screenSpaceEventHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); |
|
|
|
} |
|
|
|
onMounted(async () => { |
|
|
|
await loadingData(); |
|
|
|
|
|
|
|
// 获取部门信息 |
|
|
|
await getSceneInfo(); |
|
|
|
// 飞入事件 |
|
|
|
await fly(viewer); |
|
|
|
} |
|
|
|
|
|
|
|
// 获取部门信息 |
|
|
|
async function getSceneInfo() { |
|
|
|
// 登录人部门信息 |
|
|
|
const orgCode: any = userStore.userInfo?.orgCode; |
|
|
|
// this.orgCode = orgCode; |
|
|
|
// console.log("orgCode",orgCode); |
|
|
|
|
|
|
|
// 登录人部门信息长度为3则为总部,否则为岛屿 |
|
|
|
if (orgCode.length == 3) { |
|
|
|
// 总部 |
|
|
|
await defHttp.get({ |
|
|
|
url: '/military/msMapScene/list', |
|
|
|
params: { |
|
|
|
pageNo: 1, |
|
|
|
pageSize: 999, |
|
|
|
sceneCode: "00001-00001*", |
|
|
|
column: 'sysOrgCode', |
|
|
|
order: 'asc', |
|
|
|
} |
|
|
|
}, { isTransformResponse: false }).then((response) => { |
|
|
|
// console.log("response",response); |
|
|
|
const records = response.result.records |
|
|
|
// 设置岛屿信息为数组 |
|
|
|
sceneInfo.value = records; |
|
|
|
return records; |
|
|
|
}); |
|
|
|
} else { |
|
|
|
await defHttp.get({ |
|
|
|
url: '/military/msMapScene/queryByOrgCode', |
|
|
|
params: { orgCode: orgCode } |
|
|
|
}, { isTransformResponse: false }) |
|
|
|
.then((response) => { |
|
|
|
const data = response.result; |
|
|
|
// 设置岛屿信息为Object |
|
|
|
sceneInfo.value = data; |
|
|
|
return data; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function drawEvt(e, viewer) { |
|
|
|
//飞入 |
|
|
|
function fly(viewer: any = null) { |
|
|
|
let position, rotation, viewDistance, duration; |
|
|
|
|
|
|
|
// 获取当前坐标系标准 |
|
|
|
let ellipsoid = viewer.scene.globe.ellipsoid; |
|
|
|
|
|
|
|
// |
|
|
|
let parentData = |
|
|
|
sceneInfo.value instanceof Array |
|
|
|
? sceneInfo.value.filter((item, index) => { |
|
|
|
return item.sceneCode == "00001-00001"; |
|
|
|
}) |
|
|
|
: sceneInfo.value; |
|
|
|
//过滤掉总部层级的 |
|
|
|
let data = sceneInfo.value instanceof Array ? |
|
|
|
sceneInfo.value.filter((item, index) => { |
|
|
|
return item.sceneCode.length > 3; |
|
|
|
}) |
|
|
|
: sceneInfo.value; |
|
|
|
// console.log("data",data); |
|
|
|
// console.log("this.sceneInfo",this.sceneInfo); |
|
|
|
if (data) { |
|
|
|
if (!(data instanceof Array)) { |
|
|
|
// debugger; |
|
|
|
// 各岛礁 |
|
|
|
position = [data.lon, data.lat, data.altitude]; |
|
|
|
rotation = [data.rotationX, data.rotationY, data.rotationZ]; |
|
|
|
viewDistance = data.viewDistance; |
|
|
|
duration = data.duration ? data.duration : 0; |
|
|
|
// viewer.camera.flyTo(position, viewDistance, rotation, duration); |
|
|
|
console.log("data", position, viewDistance, rotation, duration); |
|
|
|
} else { |
|
|
|
// 总指挥中心 |
|
|
|
position = [parentData[0].lon, parentData[0].lat, parentData[0].altitude]; |
|
|
|
rotation = [parentData[0].rotationX, parentData[0].rotationY, parentData[0].rotationZ]; |
|
|
|
viewDistance = parentData[0].viewDistance; |
|
|
|
duration = parentData[0].duration; |
|
|
|
console.log("data2", position, viewDistance, rotation, duration); |
|
|
|
// 根据坐标系标准,将地理坐标转换为笛卡尔坐标 |
|
|
|
// let CartesianPosition = ellipsoid.cartographicToCartesian({ |
|
|
|
// x: position[0], y: position[1], z: position[2] |
|
|
|
// }); |
|
|
|
// let CartesianPosition = ellipsoid.cartographicToCartesian(position[0],position[1],position[2]); |
|
|
|
// console.log("CartesianPosition", CartesianPosition); |
|
|
|
|
|
|
|
// 先飞入到能看见红旗 |
|
|
|
// viewer.camera.flyTo(CartesianPosition, viewDistance, rotation, duration); |
|
|
|
|
|
|
|
// viewer.camera.flyTo({ |
|
|
|
// x: -990536.0465518984, |
|
|
|
// y: 5531995.514841362, |
|
|
|
// z: 3004737.189031571, |
|
|
|
// duration: 1.0, |
|
|
|
// }); |
|
|
|
// viewer.camera.position = { |
|
|
|
// x: -990536.0465518984, |
|
|
|
// y: 5531995.514841362, |
|
|
|
// z: 3004737.189031571, |
|
|
|
// } |
|
|
|
// viewer.camera.position = CartesianPosition |
|
|
|
|
|
|
|
|
|
|
|
// for (let record of data) { |
|
|
|
// if (record.sceneCode.length == 11) { |
|
|
|
// continue; |
|
|
|
// } |
|
|
|
// // 设置红旗 |
|
|
|
// this.setLoginPoint(record); |
|
|
|
// } |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 没权限人员控制 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function drawEvt(e, viewer) { |
|
|
|
const restoreCursor = getComputedStyle(viewer.canvas).cursor; |
|
|
|
if (e.finished) { |
|
|
|
if (e.type === 'move') { |
|
|
@ -454,25 +579,25 @@ |
|
|
|
viewer.canvas.setAttribute('style', 'cursor: crosshair'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
function activeEvt(e, viewer) { |
|
|
|
} |
|
|
|
function activeEvt(e, viewer) { |
|
|
|
// console.log(e) |
|
|
|
viewer.canvas.setAttribute('style', `cursor: ${e.isActive ? 'crosshair' : 'auto'}`); |
|
|
|
if (!e.isActive) { |
|
|
|
proxy.drawing = false; |
|
|
|
proxy.restoreCursorMove = 'auto'; |
|
|
|
} |
|
|
|
} |
|
|
|
function editorEvt(e, viewer) { |
|
|
|
} |
|
|
|
function editorEvt(e, viewer) { |
|
|
|
if (e.type === 'move') { |
|
|
|
viewer.canvas.setAttribute('style', 'cursor: move'); |
|
|
|
proxy.drawing = true; |
|
|
|
} else { |
|
|
|
viewer.canvas.setAttribute('style', 'cursor: auto'); |
|
|
|
} |
|
|
|
} |
|
|
|
// 绘制结束 |
|
|
|
function mouseEvt(e, viewer) { |
|
|
|
} |
|
|
|
// 绘制结束 |
|
|
|
function mouseEvt(e, viewer) { |
|
|
|
const restoreCursor = getComputedStyle(viewer.canvas).cursor; |
|
|
|
if (!proxy.drawing) { |
|
|
|
if (e.type === 'onmouseover') { |
|
|
@ -482,35 +607,37 @@ |
|
|
|
viewer.canvas.setAttribute('style', `cursor: ${proxy.restoreCursorMove || 'auto'}`); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
function clearEvt(e) { |
|
|
|
} |
|
|
|
function clearEvt(e) { |
|
|
|
console.log(e); |
|
|
|
} |
|
|
|
function unload() { |
|
|
|
} |
|
|
|
function unload() { |
|
|
|
proxy.$refs.drawingsRef.unload(); |
|
|
|
} |
|
|
|
function load() { |
|
|
|
} |
|
|
|
function load() { |
|
|
|
proxy.$refs.drawingsRef.load(); |
|
|
|
} |
|
|
|
function reload() { |
|
|
|
} |
|
|
|
function reload() { |
|
|
|
proxy.$refs.drawingsRef.reload(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function cartesian3ToCartographic(cartesian3: any, viewer: any) { |
|
|
|
console.log("cartesian3", cartesian3); |
|
|
|
|
|
|
|
function cartesian3ToCartographic(cartesian3: any, viewer: any) { |
|
|
|
let ellipsoid = viewer.scene.globe.ellipsoid; |
|
|
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian3); |
|
|
|
if (cartographic) { |
|
|
|
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), cartographic.height]; |
|
|
|
} |
|
|
|
} |
|
|
|
// function pickEvt(e) { |
|
|
|
// console.log(e) |
|
|
|
// } |
|
|
|
} |
|
|
|
// function pickEvt(e) { |
|
|
|
// console.log(e) |
|
|
|
// } |
|
|
|
</script> |
|
|
|
|
|
|
|
<style scoped> |
|
|
|
.demo-toolbar { |
|
|
|
.demo-toolbar { |
|
|
|
margin-left: 20px; |
|
|
|
font-size: 20px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|