225 lines
5.8 KiB
Vue
Raw Normal View History

<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2025-01-02 11:56:20
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2025-01-02 15:54:11
* @FilePath: \znxjxt-ui\src\views\xj\inspection\task-management\components\task-map.vue
* @Description: 巡检任务-地图弹窗
-->
<template>
<div class="content">
<!-- 多选框切换坐标类型 -->
<div class="check-box">
<el-cascader
ref="screenCascader"
v-model="mapCareSelect"
placeholder="病害类型筛选"
:options="defectCascaderList"
collapse-tags
:props="{
multiple: true,
emitPath: false,
children: 'subTypes',
}"
@change="changeMapCareSelect"
clearable
></el-cascader>
</div>
<fssm-map ref="taskMap"></fssm-map>
</div>
</template>
<script>
// 接口
import { getDefectPoint } from "@/api/xj/task";
import FssmMap from "@/components/map/fssm-map.vue";
import { Feature } from "ol";
import { Point } from "ol/geom";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import { Style, Icon } from "ol/style";
export default {
name: "TaskMap",
components: {
FssmMap,
},
props: {
// 弹窗传的数据
dialogItem: {
type: Object,
default: () => {},
},
// 病害类型筛选下拉数据
defectCascaderList: {
type: Array,
default: () => [],
},
},
data() {
return {
// 病害类型筛选绑定
mapCareSelect: [],
// 地图打点图层
markLayerPoints: null,
// 中心点集合(过滤后得点位)
centerPiont: [],
// 中心点集合(所有点位)
drawPointList: [],
};
},
mounted() {
this.getMapPoint();
},
methods: {
/**
* @description: 病害类型筛选改变事件
* @return {void}
*/
changeMapCareSelect(value) {
if (value.length > 0) {
this.centerPiont = this.drawPointList.filter((item) => {
return value.includes(item.iconType);
});
} else {
this.centerPiont = this.drawPointList;
}
this.drawPoint();
},
/**
* @description: 获取地图点位的方法
* @return {void}
*/
getMapPoint() {
getDefectPoint({ id: this.dialogItem.extId }).then(({ code, data }) => {
if (code === 200) {
this.drawPointList = data.map((item) => {
if (item.geometry) {
return {
...item,
geometry: [item.geometry[0], item.geometry[1]],
};
}
return [];
});
this.centerPiont = data.map((item) => {
if (item.geometry) {
return {
...item,
geometry: [item.geometry[0], item.geometry[1]],
};
}
return [];
});
// 如果不是病害巡检,则绘制点位
// 如果图片弹窗打开,则绘制点位
// if (!this.shouldLoadClusters) {
// 修改地图中心点位
const pointArray = data.map((item) => {
if (item.geometry) {
return [item.geometry[0], item.geometry[1]];
}
return [];
});
this.fitMapToPoints(pointArray);
this.drawPoint();
// }
}
});
},
/**
* @description: 根据点位计算地图中心点
* @return {void}
*/
fitMapToPoints(points) {
if (points.length > 0) {
// 创建一个空的 extent
let extent = [Infinity, Infinity, -Infinity, -Infinity];
// 计算所有点的边界框extent
points.forEach((point) => {
extent = [
Math.min(extent[0], point[0]),
Math.min(extent[1], point[1]),
Math.max(extent[2], point[0]),
Math.max(extent[3], point[1]),
];
});
this.$nextTick(() => {
// 获取地图实例
const map = this.$refs.taskMap.instance.get("map");
// 使用 fit 方法根据边界框计算最佳缩放级别
map.getView().fit(extent, {
duration: 500, // 动画持续时间
padding: [10, 10, 10, 10], // 边缘填充
});
});
}
},
/**
* @description: 绘制地图点位
* @return {void}
*/
drawPoint() {
const features = [];
this.centerPiont.forEach((element) => {
// 修改坐标样式
const point = new Point(element.geometry);
const feature = new Feature({
geometry: point,
data: element,
// 自己设置一个标识
type: "icon",
});
// 设置点位样式
feature.setStyle([
new Style({
image: new Icon({
crossOrigin: "anonymous",
src: require(`@/assets/screen/index/${element.iconTypeName}.png`),
// size: [40, 40],
scale: 0.5, // 图标缩放比例
displacement: [0, 30],
}),
}),
]);
features.push(feature);
});
//设置地图的数据源
const pointSource = new VectorSource({
features,
});
if (!this.markLayerPoints) {
this.markLayerPoints = new VectorLayer({
source: pointSource,
properties: {
type: "point",
},
});
this.$nextTick(() => {
const map = this.$refs.taskMap.instance.get("map");
map.addLayer(this.markLayerPoints);
});
} else {
this.markLayerPoints.setSource(pointSource);
}
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 45rem;
position: relative;
.check-box {
position: absolute;
z-index: 1;
}
}
</style>