数字孪生Web 后台dt( digital twin)2.0版本 统一命名格式
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1034 lines
33 KiB

<template>
<a-modal :title="title" :visible="visible" @ok="handleOk" @cancel="handleCancel" width="60vw" :destroyOnClose="true"
wrapClassName="EarthMap">
<a-row>
<a-col :span="24">
<div id="earthContainer" :style="{ cursor: cursorCss }"></div>
<!-- <span class="mapManage" @click="() => { mapManageShow = !mapManageShow }">
<a-icon type="setting" theme="filled" />
</span> -->
<span :class="['scaleWin', 'iconSpan', scaleWin.status ? 'colorBlue' : '']" title="放大或缩小" @click="scaleWinFunc">
<ExpandOutlined v-if="!scaleWin.status" />
<CompressOutlined v-else />
</span>
<span :class="['mapModel', 'iconSpan']" @click="modelChange" title="地图维度切换">
{{ modelText == "2D" ? "3D" : "2D" }}
</span>
<span :class="['selectIcon', 'iconSpan']" title="选取区域" @click="SelectArea">
<GatewayOutlined />
</span>
<!-- <span :class="['testIcon', 'iconSpan']" title="测试" @click="test">
<GatewayOutlined />
</span> -->
<a-popconfirm title="确认重置区域?" placement="right" ok-text="确认" cancel-text="取消" @confirm="clearArea">
<span :class="['clearIcon', 'iconSpan']" title="重置区域">
<FormatPainterOutlined />
</span>
</a-popconfirm>
<template v-if="editTileModel != undefined && modelText == '3D'">
<span class="buildManage iconSpan" @click="enableTileChange" title="建筑加载">
<img src="../../../../../../../assets/images/build_close.png" class="iconSize" v-show="!enableTile" />
<img src="../../../../../../../assets/images/build_able.png" class="iconSize" v-show="enableTile" />
</span>
<span class="modelDw iconSpan" @click="modelDwFunc" title="模型跟随鼠标">
<img src="../../../../../../../assets/images/dw_close.png" class="iconSize" v-show="!modelDw" />
<img src="../../../../../../../assets/images/dw_able.png" class="iconSize" v-show="modelDw" />
</span>
<span class="modelMove iconSpan" @click="modelMoveFunc" title="模型移动">
<img src="../../../../../../../assets/images/move_close.png" class="iconSize" v-show="!modelMove" />
<img src="../../../../../../../assets/images/move_able.png" class="iconSize" v-show="modelMove" />
</span>
<span class="modelRotation iconSpan" @click="modelRotationFunc" title="模型旋转">
<img src="../../../../../../../assets/images/rotation_close.png" class="iconSize" v-show="!modelRotation" />
<img src="../../../../../../../assets/images/rotation_able.png" class="iconSize" v-show="modelRotation" />
</span>
<span class="modelScale iconSpan" title="缩放">
<a-tooltip placement="left" trigger="click"
:getPopupContainer="(triggerNode) => { return triggerNode.parentElement }">
<img src="../../../../../../../assets/images/scale_close.png" class="iconSize" v-show="!modelScaleStatus"
@click="modelScaleStatusChange" />
<img src="../../../../../../../assets/images/scale_able.png" class="iconSize" v-show="modelScaleStatus"
@click="modelScaleStatusChange" />
<template #title>
<div class="sliderContainer">
<a-row class="sliderRow">
<a-col :span="4">
X轴:
</a-col>
<a-col :span="11">
<a-slider v-model:value="scaleValues[0]" :min="scaleConfig.X.min" :max="scaleConfig.X.max"
:step="scaleConfig.X.step" />
</a-col>
<a-col :span="6">
<a-input-number v-model:value="scaleValues[0]" :min="scaleConfig.X.min" :max="scaleConfig.X.max"
:step="scaleConfig.X.step" style="width:100%"></a-input-number>
</a-col>
<a-col :span="2" :offset="1" @click="() => { scaleConfig.X.show = !scaleConfig.X.show }">
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" />
</a-col>
</a-row>
<a-row v-show="scaleConfig.X.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]">
<a-col :span="8">
最小值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.X.min" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
最大值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.X.max" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
步长:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.X.step" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="24" class="sliderRow">
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('X') }">应用全部</a-button>
</a-col>
</a-row>
<a-row class="sliderRow">
<a-col :span="4">
Y轴:
</a-col>
<a-col :span="11">
<a-slider v-model:value="scaleValues[1]" :min="scaleConfig.Y.min" :max="scaleConfig.Y.max"
:step="scaleConfig.Y.step" />
</a-col>
<a-col :span="6">
<a-input-number v-model:value="scaleValues[1]" :min="scaleConfig.Y.min" :max="scaleConfig.Y.max"
:step="scaleConfig.Y.step" style="width:100%"></a-input-number>
</a-col>
<a-col :span="2" :offset="1" @click="() => { scaleConfig.Y.show = !scaleConfig.Y.show }">
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" />
</a-col>
</a-row>
<a-row v-show="scaleConfig.Y.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]">
<a-col :span="8">
最小值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Y.min" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
最大值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Y.max" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
步长:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Y.step" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="24" class="sliderRow">
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('Y') }">应用全部</a-button>
</a-col>
</a-row>
<a-row class="sliderRow">
<a-col :span="4">
Z轴:
</a-col>
<a-col :span="11">
<a-slider v-model:value="scaleValues[2]" :min="scaleConfig.Z.min" :max="scaleConfig.Z.max"
:step="scaleConfig.Z.step" />
</a-col>
<a-col :span="6">
<a-input-number v-model:value="scaleValues[2]" :min="scaleConfig.Z.min" :max="scaleConfig.Z.max"
:step="scaleConfig.Z.step" style="width:100%"></a-input-number>
</a-col>
<a-col :span="2" :offset="1" @click="() => { scaleConfig.Z.show = !scaleConfig.Z.show }">
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" />
</a-col>
</a-row>
<a-row v-show="scaleConfig.Z.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]">
<a-col :span="8">
最小值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Z.min" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
最大值:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Z.max" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="8">
步长:
</a-col>
<a-col :span="16">
<a-input-number v-model:value="scaleConfig.Z.step" class="fill-9-row"></a-input-number>
</a-col>
<a-col :span="24" class="sliderRow">
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('Z') }">应用全部</a-button>
</a-col>
</a-row>
</div>
</template>
</a-tooltip>
</span>
</template>
</a-col>
</a-row>
<!-- <EarthMapManage :show="mapManageShow"></EarthMapManage> -->
</a-modal>
</template>
<script setup>
import { toRefs, watch, nextTick, ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { message } from 'ant-design-vue';
import { useEarthMapStore } from '/@/store/modules/earthMap';
import rotationXYZ from '@/assets/images/rotationXYZ.png';
import { defHttp } from '@/utils/http/axios';
import { FormatPainterOutlined, SettingOutlined, ExpandOutlined, GatewayOutlined, ZoomInOutlined, ZoomOutOutlined, CompressOutlined } from '@ant-design/icons-vue';
// import dwPng from '/@/assets/images/dwPng.png';
import dwPng from '@/assets/images/rotationXYZ.png';
import { drawPolygonSave, drawGeoSmoothPolygon } from "@/utils/earthMap/earthDraw";
const store = useEarthMapStore();
const { proxy } = getCurrentInstance();
// 获取地图
const getMapPage = (params) => defHttp.get({ url: "/military/msMapManage/list/page", params: params }, { isTransformResponse: false });
// 鼠标样式
const cursorCss = ref("grab");
const props = defineProps(['areaData', 'drawData', 'title', 'visible', 'hasMoveMethod', 'initModeType', 'editTileModel', 'enableTile', 'enablePointer']);
const { title, visible, hasMoveMethod, initModeType, editTileModel, enablePointer } = toRefs(props);
// 禁用切片
const enableTile = ref(props.enableTile);
const pointerXyz = ref([]);
const defaultPinUrl = "../";
const emit = defineEmits(["closeWin", "checkPosition", "moveChinaPosition", 'update:areaData', 'update:drawData'])
// 确认事件
const handleOk = function () {
let position = null;
let rotation = null;
let fov = null;
if (CModel.value) {
position = [...CModel.value.czmObject.xbsjPosition];
rotation = [...CModel.value.czmObject.xbsjRotation];
emit("checkPosition", position, rotation, [...scaleValues.value]);
} else {
let cposition = [window.earth.camera.position[0], window.earth.camera.position[1], window.earth.camera.position[2]];
if (pin) {
position = [pin.position[0], pin.position[1], pin.position[2]];
}
rotation = [window.earth.camera.rotation[0], window.earth.camera.rotation[1], window.earth.camera.rotation[2]];
fov = window.earth.camera.fov;
emit("checkPosition", position, cposition, rotation, fov);
}
handleCancel();
//整理数据
sceneTreeToAreaObjList()
//上传-画图数据
updateDraw()
//上传-监控范围数据
updateArea()
//退出
handleCancel()
}
const handleCancel = function () {
emit("closeWin");
}
// 地球对象
let earth = undefined;
let _viewer = undefined;
watch(
visible, async (value, oldValue) => {
// 初始化地球和其他
if (value) {
await nextTick()
// 地图初始化
window.XE.ready().then(() => {
// 加载标绘插件
return window.XE.HTML.loadJS('/earthsdk/XbsjEarth-Plugins/plottingSymbol/plottingSymbol.js');
}).then(async () => {
earth = new window.XE.Earth('earthContainer');
window.earth = window.$earth = earth
window.$viewer = _viewer = window.earth.czm.viewer;
initMode();
listenMouseHandler();
listenMouseHandlerSelect();
addContainerClickListen();
await getDataSource();
moveChinaPosition();
await getDrawArea()
});
} else {
// 销毁缓存
destroyCache();
}
}
)
// ---------- 监控区域选择部分 ----------
//重置范围
const clearArea = function () {
if (window.earth.sceneTree.root.children.length > 1) {
window.earth.sceneTree.root.children.pop();
emit('clearAreaData')
// message.success('重置成功,请保存设置');
}
}
// 区域模型数组
let areaObjList = ref([])
// 加载区域选择-多边形
const getDrawArea = function () {
if (props.areaData || props.drawData) {
areaObjList.value = JSON.parse(props.drawData)
// console.log("aa",areaObjList.value);
areaObjList.value.forEach((e) => {
//绘画
let t = drawPolygonSave(e, 1)
t.name = '区域选取'
//存入store
store.shapeShowList.push(t.xbsjGuid)
//创建叶子节点
let leaf = new window.XE.SceneTree.Leaf(t)
//添加叶子节点属性
leaf.ref = t.guid
leaf.guid = t.guid;
//push 场景树
window.earth.sceneTree.root.children.push(leaf);
})
}
}
// 加载区域选择-平滑多边形、圆弧
// const getDrawAreaSmooth = function () {
// if (props.areaData || props.drawData) {
// areaObjList.value = JSON.parse(props.drawData)
// // console.log("aa",areaObjList.value);
// areaObjList.value.forEach((e) => {
// //绘画
// let t = drawGeoSmoothPolygon(e, 1)
// t.name = '区域选取'
// //存入store
// store.shapeShowList.push(t.xbsjGuid)
// //创建叶子节点
// let leaf = new window.XE.SceneTree.Leaf(t)
// //添加叶子节点属性
// leaf.ref = t.guid
// leaf.guid = t.guid;
// //push 场景树
// window.earth.sceneTree.root.children.push(leaf);
// })
// }
// }
// 创建区域选择-多边形
const SelectArea = function () {
console.log(window.earth.sceneTree.root.children);
// 如果场景树中存在区域数据,则清除
if (window.earth.sceneTree.root.children.length > 1) {
window.earth.sceneTree.root.children.pop();
}
// 使用绘制方法
let t = drawPolygonSave(null, 1)
t.creating = true
t.creatingWithoutHeight = true
t.ground = true
t.name = '区域选取'
//创建叶子节点
let leaf = new window.XE.SceneTree.Leaf(t)
//添加叶子节点属性
leaf.ref = t.guid
leaf.guid = t.guid;
//push 场景树
window.earth.sceneTree.root.children.push(leaf);
// areaObjList.value.push(t)
// return t
}
// 创建区域选择-平滑多边形
// const SelectAreaSmooth = function () {
// if (window.earth.sceneTree.root.children.length > 1) {
// window.earth.sceneTree.root.children.pop();
// }
// let t2 = drawGeoSmoothPolygon(null, 1);
// console.log('t2', t2);
// t2.creating = true
// t2.creatingWithoutHeight = true
// t2.ground = true
// t2.name = '区域选取'
// let leaf = new window.XE.SceneTree.Leaf(t2)
// leaf.ref = t2.guid
// leaf.guid = t2.guid
// window.earth.sceneTree.root.children.push(leaf)
// }
//整理数据
// 将场景树中的模型数据转换到区域模型数组中
const sceneTreeToAreaObjList = function () {
areaObjList.value = []
let sceneTree = window.earth.sceneTree.$refs
for (let element in sceneTree) {
if (sceneTree[element].title == "区域选取") {
areaObjList.value.push(sceneTree[element].czmObject)
}
}
}
//上传-画图数据
const updateDraw = function () {
let drawDataToString = JSON.stringify(areaObjList.value)
//上传-画图数据
if (drawDataToString == '[]') {
emit('update:drawData', '');
} else {
emit('update:drawData', drawDataToString);
}
}
// 上传-监控范围数据(多边形)
function updateArea() {
//上传监控范围数据
let areaData = []
let k = 1; //序号
areaObjList.value.forEach((e) => {
//全部弧度转角度
let positionToDegrees = []
e.positions.forEach((p) => {
positionToDegrees.push(window.Cesium.Math.toDegrees(p))
})
//经纬度,两两切分
let result = []
for (let i = 0; i < positionToDegrees.length; i += 2) {
result.push({
lon: positionToDegrees[i], //经度
lat: positionToDegrees[i + 1], //纬度
key: k //序号
});
k++;
}
areaData.push(result)
})
// console.log("areaData", areaData);
if (areaData.length == 0) {
emit('update:areaData', '');
} else {
emit('update:areaData', JSON.stringify(areaData));
}
}
// 上传-监控范围数据(平滑多边形、圆弧)
// function updateAreaSmooth() {
// //上传监控范围数据
// let areaData = []
// let k = 1
// areaObjList.value.forEach((e) => {
// //弧度转角度
// let positionToDegrees = []
// e.positions.forEach((i) => {
// let positionItem = []
// i.forEach(p => {
// positionItem.push(window.Cesium.Math.toDegrees(p))
// })
// positionToDegrees.push(positionItem)
// })
// //经纬度,两两切分
// let result = []
// for (let i = 0; i < positionToDegrees.length; i++) {
// result.push({
// lon: positionToDegrees[i][0], //经度
// lat: positionToDegrees[i][1], //纬度
// key: k //序号
// });
// k++;
// }
// areaData.push(result)
// console.log(result);
// })
// // emit('update:areaData', JSON.stringify(areaData));
// if (areaData.length == 0) {
// emit('update:areaData', '');
// } else {
// emit('update:areaData', JSON.stringify(areaData));
// }
// }
// const test = function () {
// _viewer.camera.moveLeft(100000)
// }
const mapManageShow = ref(false);
const modelText = ref('2D');
const modelChange = function () {
const viewer = window.earth.czm.viewer;
if (modelText.value == '3D') {
// 禁用切片,后切换为2D
// const loyauts = window.earth.sceneTree.$refs["loyauts"].children;
// loyauts.forEach(loyaut => {
// loyaut.enabled = false;
// });
modelText.value = "2D";
enableTile.value = false;
if (CModel.value) {
// CModel.value.show = false;
if (modelDw.value) {
modelDwFunc();
}
if (modelMove.value) {
modelMoveFunc();
}
if (modelRotation.value) {
modelRotationFunc();
}
}
viewer.scene.morphTo2D(0)
} else {
viewer.scene.morphTo3D(0)
modelText.value = "3D";
}
}
const enableTileChange = function () {
if (modelText.value != "3D") {
message.info("2D切片。若要加载切片,请切换至3D模式!")
return;
}
enableTile.value = !enableTile.value;
}
const initMode = function () {
const viewer = window.earth.czm.viewer;
// 当没有initModeType属性时,默认2D模式展示
if (!initModeType.value) {
modelText.value = "3D"
viewer.scene.morphTo3D(0)
return;
}
// 2D模式
if (initModeType.value == "2D") {
modelText.value = "3D"
viewer.scene.morphTo2D(0)
} else if (initModeType.value == "3D") {
// 3D模式
modelText.value = "3D"
viewer.scene.morphTo3D(0)
}
}
const CModel = ref(null);
// 编辑切片模型
const editTileModelFunc = function (root) {
// 空值判断
if (!editTileModel || !editTileModel.value) {
return;
}
// 模型对象
const modelObj = {
ref: editTileModel.value.custom.id,
czmObject: editTileModel.value.czmObject,
enabled: true,
}
// 创建模型
root.push(modelObj);
// 拿取创建的模型
CModel.value = window.earth.sceneTree.$refs[editTileModel.value.custom.id];
// 启用
CModel.value.enabled = true;
CModel.value.czmObject.enabled = true;
// 初始大小
scaleValues.value = [...CModel.value.czmObject.xbsjScale];
}
const moveChinaPosition = function () {
// 如果外部传入了moveChinaPosition方法则调用外部的
if (hasMoveMethod.value) {
emit('moveChinaPosition');
} else {
// 否则则给一个默认位置
window.earth.camera.fov = 1.0471975511965976;
window.earth.camera.position = [1.8833961240252113, 0.6131398723508994, 8921610.846366767];
window.earth.camera.rotation = [6.283185307179586, -1.5704896980852325, 0]
}
}
let viewer = undefined;
// 鼠标样式
const cssGrab = function (e) {
const buttonNum = e.button;
if (buttonNum == 0) {
cursorCss.value = `grabbing`;
} else if (buttonNum == 1) {
cursorCss.value = `${rotationXYZ}`;
}
}
// 添加事件监听
const addContainerClickListen = function () {
const dom = document.getElementById("earthContainer");
dom.addEventListener("mousedown", cssGrab, true)
// dom.addEventListener("mouseup", cssGrab)
}
// 模型跟随鼠标
const modelFollowMouse = (event) => {
if (CModel.value && modelText.value == "3D") {
if (CModel.value.enabled == false) {
CModel.value.enabled = true;
}
//地图左键触发 右侧菜单隐藏
// 屏幕坐标转为世界坐标
let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.endPosition), viewer.scene);
if (!cartesian) {
return;
}
// 世界坐标转换为弧度
let ellipsoid = viewer.scene.globe.ellipsoid;
let cartographic = ellipsoid.cartesianToCartographic(cartesian);
let lon = cartographic.longitude; // 经度
let lat = cartographic.latitude; // 纬度
// let alt = cartographic.height; // 高度
let alt = 0; // 高度
CModel.value.czmObject.xbsjPosition = [lon, lat, alt];
}
}
let pin = undefined;
// 添加地图上的鼠标监听事件
const listenMouseHandler = function () {
viewer = window.earth.czm.viewer;
window.viewer = viewer;
window.earth.interaction.picking.enabled = true;
window.earth.interaction.picking.clickedColor = [1, 0, 0, 1];
const handler = new window.Cesium.ScreenSpaceEventHandler(
viewer.scene.canvas
);
window.CesiumGlobalHandler = handler;
// 取消双击旋转事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
// handler.setInputAction(modelFollowMouse, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
if (enablePointer.value) {
viewer.cesiumWidget.screenSpaceEventHandler.setInputAction((event) => {
let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.position), viewer.scene);
if (!cartesian) {
return;
}
// 世界坐标转换为弧度
let ellipsoid = viewer.scene.globe.ellipsoid;
let cartographic = ellipsoid.cartesianToCartographic(cartesian);
// 弧度转换为经纬度
let pointLon = Cesium.Math.toDegrees(cartographic.longitude); // 经度
let pointLat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
let pointAlt = cartographic.height; // 高度
console.log("点击的的经纬度坐标是:", {
"经度:": pointLon,
"纬度:": pointLat
});
pin && pin.destroy();
pin = new window.XE.Obj.Pin(window.earth);
pin.position = [cartographic.longitude, cartographic.latitude, pointAlt];
pin.imageUrl = dwPng;
},
window.Cesium.ScreenSpaceEventType.LEFT_CLICK
);
}
// /* 左键事件 */
handler.setInputAction((event) => {
handler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
modelDw.value = false;
if (clearId != null) {
clearTimeout(clearId);
clearId = null;
}
cursorCss.value = `grabbing`;
}, window.Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction((event) => {
if (clearId != null) {
clearTimeout(clearId);
clearId = null;
}
cursorCss.value = `grab`;
}, window.Cesium.ScreenSpaceEventType.LEFT_UP);
handler.setInputAction((event) => {
if (clearId != null) {
clearTimeout(clearId);
clearId = null;
}
cursorCss.value = `url(${rotationXYZ}),grab`;
}, window.Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
handler.setInputAction((event) => {
if (clearId != null) {
clearTimeout(clearId);
clearId = null;
}
cursorCss.value = `grab`;
}, window.Cesium.ScreenSpaceEventType.MIDDLE_UP);
let clearId = null;
handler.setInputAction((event) => {
if (event > 0) {
cursorCss.value = `zoom-in`;
} else {
cursorCss.value = `zoom-out`;
}
clearId = setTimeout(() => {
clearTimeout(clearId);
cursorCss.value = `grab`
}, 2000);
}, window.Cesium.ScreenSpaceEventType.WHEEL);
// window.earth.onclick = function () {
// console.log(1);
// }
}
//添加地图上的监听事件-选取区域
const listenMouseHandlerSelect = function () {
// window.$earth.interaction.picking.enabled = true;
// window.$earth.interaction.picking.clickedColor = [1, 0, 0, 1];
const _handler = new window.Cesium.ScreenSpaceEventHandler(
_viewer.scene.canvas
);
// window.CesiumGlobalHandler = handler;
// 取消双击旋转事件
_viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
_handler.setInputAction((click) => {
// 判断点击位置是否有实体
//返回具有 `primitive` 属性的对象,该属性包含场景中特定窗口坐标处的第一个(顶部)图元,如果该位置没有任何内容,则返回未定义的对象。其他属性可能会根据基元的类型进行设置,并可用于进一步识别拾取的对象。
let pickedFeature = _viewer.scene.pick(click.position);
// console.log("pick", pickedFeature);
let entity = pickedFeature && pickedFeature.id;
if (entity == undefined) { return; }
//区域选取
else if (typeof pickedFeature !== 'undefined' && entity.name == '区域选取') {
console.log("entity", entity);
//右键菜单
entity.showProperty()
}
}, window.Cesium.ScreenSpaceEventType.RIGHT_CLICK); //右键事件
}
// 获取其他切片
const getDataSource = async function () {
const params = {
pageNo: 1,
pageSize: 9999,
status: 1,
}
return getMapPage(params).then(
(res) => {
if (res.code == 200) {
const loyaut = {
ref: "loyauts",
expand: false,
title: "地图图层",
children: []
}
const records = res.result.records;
records.forEach(item => {
const czmObject = JSON.parse(item.czmObject);
const child = {
ref: item.id,
czmObject: czmObject,
enabled: true,
}
loyaut.children.push(child);
});
window.earth.sceneTree.root.children.push(loyaut);
const loyauts = window.earth.sceneTree.$refs["loyauts"].children;
editTileModelFunc(loyauts);
// 添加监听
watch([modelText, enableTile], ([newVal, newVal1], [oldValue, oldValue1]) => {
// 在模式为3D,并且启用切片的时候,将其他的切片展示出来
if (newVal == "3D" && newVal1) {
loyauts.forEach(loyaut => {
if (loyaut.czmObject.xbsjType == "Tileset") {
loyaut.enabled = true;
}
if (CModel.value) {
CModel.value.enabled = true;
}
});
} else if (newVal == "2D" || !newVal1) {
// 禁用3D切片
loyauts.forEach(loyaut => {
if (loyaut.czmObject.xbsjType == "Tileset") {
loyaut.enabled = false;
}
if (CModel.value) {
CModel.value.enabled = false;
}
});
}
})
} else {
message.error("无法显示数据!");
}
}
).catch(
(e) => {
message.error("无法显示数据!");
}
)
}
// 放大缩小弹窗
const scaleWin = reactive({
status: false
})
const scaleWinFunc = function () {
const el = document.getElementsByClassName("EarthMap")[0].querySelector(".ant-modal-content");
if (!scaleWin.status) {
const width = window.innerWidth;
el.setAttribute("style", `width:${width}px;position:fixed;left:0;top:0;`);
scaleWin.status = true;
} else {
el.removeAttribute("style");
scaleWin.status = false;
}
}
// 模型定位
const modelDw = ref(false);
const modelDwFunc = function (e) {
modelScaleStatus.value = false;
if (!modelDw.value) {
window.CesiumGlobalHandler.setInputAction(
modelFollowMouse, window.Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
modelDw.value = true;
} else {
window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
modelDw.value = false
}
}
// 模型平移
const modelMove = ref(false);
const modelMoveFunc = function (e) {
if (!CModel.value) {
return;
}
if (!modelMove.value) {
if (CModel.value.enabled == false) {
CModel.value.enabled = true;
}
CModel.value.czmObject.positionEditing = true;
modelRotation.value = false;
modelMove.value = true;
} else {
CModel.value.czmObject.positionEditing = false;
modelMove.value = false
}
}
// 模型旋转
const modelRotation = ref(false);
const modelRotationFunc = function (e) {
if (!CModel.value) {
return;
}
if (!modelRotation.value) {
if (CModel.value.enabled == false) {
CModel.value.enabled = true;
}
CModel.value.czmObject.rotationEditing = true;
modelMove.value = false;
modelRotation.value = true;
} else {
CModel.value.czmObject.rotationEditing = false;
modelRotation.value = false
}
}
// 模型大小比例
const scaleValues = ref([1, 1, 1]);
const modelScaleStatus = ref(false);
// 模型放大缩小状态的切换
const modelScaleStatusChange = function () {
modelScaleStatus.value = !modelScaleStatus.value;
}
// 放大缩小值的配置
const scaleConfigObj = {
X: {
min: -10,
max: 10,
step: 1,
show: false,
},
Y: {
min: -10,
max: 10,
step: 1,
show: false,
},
Z: {
min: -10,
max: 10,
step: 1,
show: false,
},
};
const scaleConfig = ref(
{
...scaleConfigObj
}
)
// xyz所有轴都应用同一设置
const allSetting = function (propName) {
const keys = Object.keys(scaleConfig.value);
const beCopyObj = scaleConfig.value[propName];
keys.forEach(key => {
scaleConfig.value[key] = { ...beCopyObj, show: scaleConfig.value[key].show }
});
}
// 监听放大缩小值的变化
watch(scaleValues, (new_scale, scale) => {
if (!CModel.value || !CModel.value.czmObject) {
return;
}
CModel.value.czmObject.xbsjScale = new_scale;
}, {
deep: true
})
// 销毁缓存
const destroyCache = function () {
scaleConfig.value = { ...scaleConfigObj };
scaleValues.value = [1, 1, 1];
modelRotation.value = false;
modelMove.value = false;
scaleWin.value = false;
modelScaleStatus.value = false;
modelDw.value = false;
enableTile.value = false;
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE)
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOWN)
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_UP)
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MIDDLE_DOWN)
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MIDDLE_UP)
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.WHEEL)
CModel.value && CModel.value.destroy();
earth && earth.destroy();
modelText.value = "2D";
scaleWin.status = false;
}
defineExpose(
{
CModel
}
);
</script>
<style scoped>
.container {}
.fill-9-row {
width: 90%;
}
.sliderRow {
display: flex;
justify-content: center;
align-items: center;
min-height: 50px;
}
.sliderContainer {
width: 200px;
}
.iconSize {
width: 16px;
height: 16px;
}
.colorBlue {
color: #1296db !important;
}
.iconSpan {
color: #fff;
display: block;
width: 36px;
height: 36px;
font-size: 16px;
font-style: normal;
line-height: 36px;
text-align: center;
text-transform: none;
text-rendering: auto;
background-color: rgba(0, 0, 0, 0.4);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.selectIcon {
position: absolute;
top: 108px;
left: 0;
}
.testIcon {
position: absolute;
top: 188px;
left: 0;
}
.clearIcon {
position: absolute;
top: 144px;
left: 0;
}
.modelScale {
position: absolute;
top: 252px;
left: 0;
}
.modelRotation {
position: absolute;
top: 216px;
left: 0;
}
.modelMove {
position: absolute;
top: 180px;
left: 0;
}
.modelDw {
position: absolute;
top: 144px;
left: 0;
}
.scaleWin {
position: absolute;
top: 36px;
left: 0;
}
.mapModel {
position: absolute;
top: 72px;
left: 0;
}
.buildManage {
position: absolute;
top: 108px;
left: 0;
}
:deep(.ant-modal-body) {
padding: 0px !important;
}
:deep(.ant-modal-close-x) {
color: #fff;
background-color: rgba(0, 0, 0, 0.4);
width: 36px;
height: 36px;
line-height: 36px;
}
</style>