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.
466 lines
12 KiB
466 lines
12 KiB
<template>
|
|
<div class="safe-operation">
|
|
<div id="reservoir-map-container"></div>
|
|
|
|
<!-- 按钮,浮窗 -->
|
|
<!-- <el-input
|
|
class="search-input"
|
|
placeholder="请输入内容"
|
|
style="width: 240px"
|
|
size="small"
|
|
>
|
|
<el-button
|
|
type="default"
|
|
slot="append"
|
|
icon="el-icon-search"
|
|
size="small"
|
|
></el-button>
|
|
</el-input> -->
|
|
<div class="tool-btn">
|
|
<div class="btn cursor-pointer" @click="handleChangeTreeShow">
|
|
<img class="icon" src="../../../assets/icons/layer.png" alt="" />
|
|
图层管理
|
|
</div>
|
|
<div class="line"></div>
|
|
<div class="btn cursor-pointer" @click="handleChangeMode">
|
|
<img class="icon" src="../../../assets/icons/change23D.png" alt="" />
|
|
{{ mapSceneType === 3 ? "三" : "二" }}维地图
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 树结构浮窗 -->
|
|
<Transition name="fade">
|
|
<div class="tree-box" v-if="showTreeBox">
|
|
<el-tree
|
|
@check-change="handleCheckTree"
|
|
:data="treeData"
|
|
default-expand-all
|
|
node-key="id"
|
|
ref="treeRef"
|
|
show-checkbox
|
|
highlight-current
|
|
:props="defaultProps"
|
|
>
|
|
<template #default="{ node, data }">
|
|
<div class="flex items-center">
|
|
<img
|
|
v-if="node.level > 1"
|
|
src="../../../assets/common/icon-layer.png"
|
|
alt=""
|
|
/>
|
|
<img v-else src="../../../assets/common/icon-folder.png" alt="" />
|
|
<span style="margin-left: 4px">{{
|
|
data.nameCn || data.text
|
|
}}</span>
|
|
</div>
|
|
</template>
|
|
</el-tree>
|
|
</div>
|
|
</Transition>
|
|
|
|
<div class="legend-icon">
|
|
<Legend></Legend>
|
|
</div>
|
|
|
|
<!-- 弹窗 -->
|
|
<el-dialog
|
|
:title="`${(resInfoData && resInfoData.dikeName) || commonName || '??'}(${
|
|
(resInfoData && resInfoData.dikeCode) || commonCode || '??'
|
|
})`"
|
|
:visible.sync="showDialog"
|
|
:destroy-on-close="true"
|
|
width="1200px"
|
|
>
|
|
<ProjectDetail
|
|
ref="detailRef"
|
|
:resCode="commonCode"
|
|
@getResInfo="handleGetResInfo"
|
|
></ProjectDetail>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import mitt from "mitt";
|
|
|
|
import ProjectDetail from "./components/ProjectDetail.vue";
|
|
|
|
import { getSceneListData, getLayerData } from "@/api/mapCommon";
|
|
import { getSceneConfig } from "@/api/aiSupervision/layerConfigApi";
|
|
|
|
import {
|
|
addLayer,
|
|
removeLayer,
|
|
zoomToLayer,
|
|
} from "@/views/aiSupervision/waterSetting/runScene/layerTree/index";
|
|
|
|
import { queryLayersByPos, getSelectedLayersLegend } from "@/utils/mapUtils";
|
|
import Legend from "./components/Legend.vue";
|
|
|
|
import { throttle } from "lodash-es";
|
|
import { devRun } from "@/utils";
|
|
|
|
const emitter = mitt();
|
|
|
|
let viewer, htmlLayer;
|
|
// let graphicsList = [];
|
|
|
|
window.panelClickFunc = function (code, name) {
|
|
console.log("panelClickFunc >>>>> ", code, name);
|
|
emitter.emit("openDialog", {
|
|
code,
|
|
name,
|
|
});
|
|
};
|
|
export default {
|
|
components: { ProjectDetail, Legend },
|
|
data() {
|
|
return {
|
|
showDialog: false,
|
|
// 水库信息
|
|
resInfoData: null,
|
|
// 当前水库code
|
|
commonCode: null,
|
|
commonName: null,
|
|
mapSceneType: 2, // 2: 2D, 3: 3D
|
|
showTreeBox: false,
|
|
defaultProps: {
|
|
children: "layers",
|
|
label: "nameCn",
|
|
},
|
|
configData: null,
|
|
layerList: [],
|
|
checkList: [],
|
|
treeData: [],
|
|
};
|
|
},
|
|
methods: {
|
|
async initData() {
|
|
let res1 = await getSceneListData({
|
|
name: "堤防安全运行",
|
|
});
|
|
let id = res1.records?.[0]?.id;
|
|
let res2 = await getLayerData(id);
|
|
this.treeData = res2.data?.children || [];
|
|
let res3 = await getSceneConfig(id);
|
|
this.configData = res3.data || null;
|
|
if (res3.data?.layerId && typeof res3.data.layerId === "string") {
|
|
this.checkList = JSON.parse(res3.data?.layerId);
|
|
this.treeData.forEach((item) => {
|
|
if (item.layers) {
|
|
let arr = item.layers?.filter((item) =>
|
|
this.checkList.includes(item.id)
|
|
);
|
|
this.layerList.push(...arr);
|
|
}
|
|
});
|
|
}
|
|
this.initMap();
|
|
},
|
|
handleChangeMode() {
|
|
this.mapSceneType = this.mapSceneType === 3 ? 2 : 3;
|
|
viewer?.changeSceneMode(this.mapSceneType);
|
|
let position = new sycim.Position(113.27, 23.13, 600000, 0, -90, 0);
|
|
viewer?.flyToPosition(
|
|
position,
|
|
() => {
|
|
console.log("移动结束 >>>>> ");
|
|
},
|
|
1
|
|
);
|
|
},
|
|
handleGetResInfo(data) {
|
|
console.log("handleGetResInfo >>>>> ", data);
|
|
this.resInfoData = data;
|
|
},
|
|
initMap() {
|
|
if (!sycim) {
|
|
setTimeout(() => {
|
|
this.initMap();
|
|
}, 1000);
|
|
return;
|
|
}
|
|
viewer = new sycim.Viewer("reservoir-map-container");
|
|
window.viewer = viewer;
|
|
let baseLayer = sycim.ImageryLayerFactory.createImageryLayer(
|
|
sycim.ImageryType.ARCGIS,
|
|
{
|
|
url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
|
|
}
|
|
);
|
|
viewer.addBaseLayer(baseLayer);
|
|
let layer = new sycim.EntityLayer("layer");
|
|
viewer.addLayer(layer);
|
|
// plot = new sycim.Plot(viewer);
|
|
|
|
htmlLayer = new sycim.HtmlLayer("layer");
|
|
viewer.addLayer(htmlLayer);
|
|
|
|
viewer.setOptions({
|
|
globe: {
|
|
depthTestAgainstTerrain: true,
|
|
},
|
|
});
|
|
|
|
setTimeout(() => {
|
|
if (this.layerList.length) {
|
|
this.layerList.forEach((item) => {
|
|
addLayer(item);
|
|
});
|
|
}
|
|
if (this.configData) {
|
|
let pos = JSON.parse(this.configData.cameraPosture);
|
|
viewer.scene.camera.setView({
|
|
destination: new Cesium.Cartesian3.fromDegrees(
|
|
pos.lng,
|
|
pos.lat,
|
|
pos.alt
|
|
),
|
|
|
|
duration: 2,
|
|
});
|
|
} else {
|
|
viewer.scene.camera.setView({
|
|
destination: new Cesium.Cartesian3.fromDegrees(
|
|
113.27,
|
|
23.13,
|
|
600000
|
|
),
|
|
// orientation: {
|
|
// heading: 0,
|
|
// pitch: -90,
|
|
// roll: 0,
|
|
// },
|
|
duration: 2,
|
|
});
|
|
}
|
|
this.viewerAddEventListener();
|
|
}, 300);
|
|
},
|
|
handleChangeTreeShow() {
|
|
this.showTreeBox = !this.showTreeBox;
|
|
if (this.showTreeBox) {
|
|
this.$nextTick(() => {
|
|
this.$refs.treeRef?.setCheckedKeys(this.checkList);
|
|
});
|
|
}
|
|
},
|
|
handleAddHtmlLayer(position, data) {
|
|
console.log("添加DivIcon >>>>> ", position, data);
|
|
htmlLayer?.clear();
|
|
let divIcon = new sycim.DivIcon(
|
|
`${position.lng}, ${position.lat}`,
|
|
`
|
|
<div class="sycim-panel" onclick="panelClickFunc('${
|
|
data.attributes?.showCode
|
|
}','${data.attributes?.showName}')">
|
|
<div class="panel-text">${data.attributes?.showName || "未知"}
|
|
</div>
|
|
</div>
|
|
`
|
|
);
|
|
divIcon.setStyle({
|
|
// 设置可视距离
|
|
distanceDisplayCondition: {
|
|
near: 0, //最近距离
|
|
far: 8000000, //最远距离
|
|
},
|
|
//设置视距缩放
|
|
scaleByDistance: {
|
|
near: 0, //最近距离
|
|
nearValue: 1.5, //最近距离值
|
|
far: 50000, //最远距离值
|
|
farValue: 1, //最远距离值
|
|
},
|
|
horizontalOrigin: sycim.Cesium.HorizontalOrigin.CENTER,
|
|
verticalOrigin: sycim.Cesium.VerticalOrigin.BOTTOM,
|
|
});
|
|
htmlLayer.addGraphic(divIcon);
|
|
},
|
|
|
|
// 监听鼠标移动事件
|
|
viewerAddEventListener() {
|
|
window.viewer.on(
|
|
sycim.MouseEventType.MOUSE_MOVE,
|
|
throttle((e) => {
|
|
if (!e.wgs84SurfacePosition) {
|
|
return;
|
|
}
|
|
queryLayersByPos(e.wgs84SurfacePosition, this.layerList, (res) => {
|
|
console.log("res >>>>> ", res);
|
|
if (res) {
|
|
this.handleAddHtmlLayer(e.wgs84SurfacePosition, res);
|
|
} else {
|
|
htmlLayer?.clear();
|
|
}
|
|
});
|
|
}, 100),
|
|
window.viewer
|
|
);
|
|
},
|
|
|
|
openDialog({ code, name }) {
|
|
console.log("打开弹窗获取resCode >>>>> ", code, name);
|
|
let tempCode = code;
|
|
let tempName = name;
|
|
// devRun(() => {
|
|
// // tempCode = "440111000008";
|
|
// tempCode = "HP0174419000000566";
|
|
// tempName = "开发写死的名字";
|
|
// });
|
|
this.commonCode = tempCode;
|
|
this.commonName = tempName;
|
|
this.showDialog = true;
|
|
},
|
|
// 点击
|
|
handleClickTree(data, node) {
|
|
if (node.isLeaf && !data.children) {
|
|
let resId = this.checkList.find((v) => v === data.id);
|
|
if (resId) {
|
|
this.checkList = this.checkList.filter((v) => v != resId);
|
|
this.layerList = this.layerList.filter((v) => v.id != resId);
|
|
removeLayer(data);
|
|
} else {
|
|
this.checkList = [...this.checkList, data.id];
|
|
addLayer(data);
|
|
this.layerList.push(data);
|
|
}
|
|
}
|
|
},
|
|
handleCheckTree(data, checked) {
|
|
if (data.pid === "root" || data.layers) return;
|
|
if (checked) {
|
|
this.checkList = [...this.checkList, data.id];
|
|
addLayer(data);
|
|
this.layerList.push(data);
|
|
} else {
|
|
this.checkList = this.checkList.filter((v) => v != data.id);
|
|
this.layerList = this.layerList.filter((v) => v.id != data.id);
|
|
removeLayer(data);
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
emitter.on("openDialog", this.openDialog);
|
|
// devRun(() => {
|
|
// setTimeout(() => {
|
|
// this.openDialog({
|
|
// code: "",
|
|
// name: "",
|
|
// });
|
|
// }, 1000);
|
|
// });
|
|
},
|
|
mounted() {
|
|
this.initData();
|
|
},
|
|
beforeDestroy() {
|
|
window.viewer = null;
|
|
htmlLayer = null;
|
|
},
|
|
};
|
|
</script>
|
|
<style scoped lang="scss">
|
|
.safe-operation {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
#reservoir-map-container {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.search-input {
|
|
position: absolute;
|
|
font-size: 14px;
|
|
z-index: 9;
|
|
right: 148px;
|
|
top: 20px;
|
|
}
|
|
|
|
.tool-btn {
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
padding: 12px;
|
|
background: #fff;
|
|
position: absolute;
|
|
z-index: 9;
|
|
right: 12px;
|
|
top: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
.btn {
|
|
user-select: none;
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 14px;
|
|
.icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
}
|
|
.line {
|
|
width: 2px;
|
|
background: #e7e7e7;
|
|
height: 12px;
|
|
margin: 0 8px;
|
|
}
|
|
}
|
|
|
|
.tree-box {
|
|
position: absolute;
|
|
z-index: 9;
|
|
right: 12px;
|
|
top: 66px;
|
|
border-radius: 4px;
|
|
padding: 2px;
|
|
background: #fff;
|
|
width: 280px;
|
|
min-height: 300px;
|
|
max-height: 600px;
|
|
padding: 12px 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
.legend-icon {
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
background: #fff;
|
|
width: 140px;
|
|
position: absolute;
|
|
z-index: 9;
|
|
right: 12px;
|
|
bottom: 12px;
|
|
max-height: 168px;
|
|
overflow: auto;
|
|
.row {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 14px;
|
|
margin-bottom: 4px;
|
|
.icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
<style lang="scss">
|
|
.sycim-panel {
|
|
padding: 12px;
|
|
background: rgba(0, 0, 0, 0.6);
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
.panel-text {
|
|
color: #fff;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
</style>
|
|
|