| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- import * as KMap from "@/utils/ol-map/KMap";
- import { Circle, Fill, Stroke, Style, Text, Icon } from "ol/style.js";
- import LineString from "ol/geom/LineString";
- import { newPoint } from "@/utils/map.js";
- import Point from "ol/geom/Point";
- import { Feature } from "ol";
- import { Select } from 'ol/interaction';
- import { platformModifierKeyOnly } from 'ol/events/condition';
- /**
- * @description 地图层对象
- */
- class airLineStringLayer {
- constructor(map) {
- let that = this;
- this.vectorStyle = new KMap.VectorStyle();
- this.lineStringLayer = new KMap.VectorLayer("lineStringLayer", 9999, {
- style: this.styleFunction,
- });
- map.addLayer(this.lineStringLayer.layer);
- this.kmap = map;
- this.selectedFeatures = []; // 存储选中的要素
- this.editMode = false; // 编辑模式标志
- // 位置图标
- this.pointLayer = new KMap.VectorLayer("pointLayer", 9999, {
- style: () => {
- return new Style({
- image: new Icon({
- src: require(`@/assets/images/map/drone-icon.png`),
- scale: 0.38,
- }),
- });
- },
- });
- map.addLayer(this.pointLayer.layer);
- // 位置图标
- this.pointOfflineLayer = new KMap.VectorLayer("pointOfflineLayer", 9999, {
- style: () => {
- return new Style({
- image: new Icon({
- src: require(`@/assets/images/map/drone-offline-icon.png`),
- scale: 0.38,
- }),
- });
- },
- });
- map.addLayer(this.pointOfflineLayer.layer);
- // 添加选择交互
- this.selectInteraction = new Select({
- layers: [this.lineStringLayer.layer],
- style: this.getSelectStyle(), // 选中样式
- toggleCondition: platformModifierKeyOnly, // 按住Ctrl键多选
- multi: true // 允许多选
- });
- map.map.addInteraction(this.selectInteraction);
-
- // 监听选择变化
- this.selectInteraction.on('select', (event) => {
- this.selectedFeatures = event.selected;
- });
- }
- // 获取选中要素的样式
- getSelectStyle() {
- return new Style({
- image: new Circle({
- radius: 16,
- stroke: new Stroke({
- color: 'rgba(255, 0, 0, 0.7)',
- width: 3
- }),
- fill: new Fill({
- color: 'rgba(255, 0, 0, 0.3)'
- })
- }),
- stroke: new Stroke({
- color: 'rgba(255, 0, 0, 0.7)',
- width: 3
- })
- });
- }
- // 进入编辑模式
- enterEditMode() {
- this.editMode = true;
- this.selectInteraction.setActive(true);
- }
- // 退出编辑模式
- exitEditMode() {
- this.editMode = false;
- this.selectInteraction.setActive(false);
- this.selectInteraction.getFeatures().clear();
- this.selectedFeatures = [];
- }
- // 删除选中的点位
- deleteSelectedPoints() {
- if (!this.editMode || this.selectedFeatures.length === 0) return;
- console.log('this.selectedFeatures', this.selectedFeatures);
- const source = this.lineStringLayer.layer.getSource();
-
- // 删除选中的要素
- this.selectedFeatures.forEach(feature => {
- source.removeFeature(feature);
- });
-
- // 重新生成连线
- this.regenerateLineString();
-
- // 清空选择
- this.selectedFeatures = [];
- this.selectInteraction.getFeatures().clear();
- }
- // 重新生成连线
- regenerateLineString() {
- const source = this.lineStringLayer.layer.getSource();
- const features = source.getFeatures();
-
- // 获取所有点要素并按pointIndex排序
- const pointFeatures = features.filter(f => f.getGeometry().getType() === 'Point');
- pointFeatures.sort((a, b) => {
- return parseInt(a.get('pointIndex')) - parseInt(b.get('pointIndex'));
- });
-
- // 提取坐标数组
- const coordinates = pointFeatures.map(feature => {
- const geom = feature.getGeometry();
- return geom.getCoordinates();
- });
-
- // 删除旧的线要素
- const lineFeatures = features.filter(f => f.getGeometry().getType() === 'LineString');
- lineFeatures.forEach(f => source.removeFeature(f));
-
- // 创建新的线要素
- if (coordinates.length > 1) {
- const lineGeometry = new LineString(coordinates);
- const lineFeature = new Feature({
- geometry: lineGeometry
- });
- lineFeature.set("type", 'Online');
- source.addFeature(lineFeature);
- }
- }
- styleFunction(feature) {
- const type = feature.get('type');
- const geometry = feature.getGeometry();
- const styles = [];
- // 处理线段的样式
- if (geometry.getType() === 'LineString') {
- styles.push(
- new Style({
- stroke: new Stroke({
- color: type === 'Online' ? '#FFD689' : '#FFFFFF',
- width: 3,
- }),
- })
- );
- geometry.forEachSegment(function (start, end) {
- // 计算中间点坐标
- const midX = (start[0] + end[0]) / 2;
- const midY = (start[1] + end[1]) / 2;
- const midPoint = [midX, midY];
- // 计算线段方向角(弧度)
- const dx = end[0] - start[0];
- const dy = end[1] - start[1];
- const rotation = Math.atan2(dy, dx);
- // 添加箭头样式
- styles.push(
- new Style({
- geometry: new Point(midPoint),
- image: new Icon({
- src: require(`@/assets/images/map/${type === 'Online' ? 'arrow' : 'arrow-offline'}-icon.png`),
- anchor: [0.5, 0.5],
- scale: 0.8,
- zIndex: 2,
- rotateWithView: true,
- rotation: -rotation,
- }),
- })
- );
- });
- }
- // 处理点位的样式
- if (geometry.getType() === 'Point') {
- styles.push(
- new Style({
- image: new Icon({
- src: require(`@/assets/images/map/${type === 'Online' ? 'air' : 'air-offline'}-icon.png`),
- scale: 1,
- displacement: [0, 20],
- }),
- }),
- new Style({
- image: new Icon({
- src: require(`@/assets/images/map/${type === 'Online' ? 'text' : 'text-offline'}-bj.png`),
- scale: 0.42,
- displacement: [5, 110],
- zIndex: 2,
- }),
- }),
- new Style({
- text: new Text({
- font: "18px PangMenZhengDao",
- text: feature.get('pointIndex') || '', // 显示顺序编号
- offsetY: -47,
- fill: new Fill({ color: "#fff" }),
- }),
- })
- );
- }
- return styles;
- }
- initData(droneArr, dronePoint, name) {
- this.clearLayer();
- //在线数据
- const lineCoordinates = {
- type: 'Online',
- arr: droneArr
- };
- // 创建线特征
- let lineGeometry = new LineString(lineCoordinates.arr);
- let lineFeature = new Feature({
- geometry: lineGeometry,
- });
- lineFeature.set("type", lineCoordinates.type);
- this.lineStringLayer.addFeature(lineFeature);
- // 为每个点位创建单独的特征并设置顺序编号
- lineCoordinates.arr.forEach((coord, index) => {
- let pointFeature = new Feature({
- geometry: new Point(coord),
- });
- pointFeature.set("type", lineCoordinates.type);
- pointFeature.set("pointIndex", (index + 1).toString()); // 设置从1开始的顺序编号
- this.lineStringLayer.addFeature(pointFeature);
- });
- // 添加无人机位置点
- const pointVal = { id: 1, wkt: dronePoint, type: 'Online' };
- let point = newPoint(pointVal, 'wkt');
- this.pointLayer.addFeature(point);
- this.kmap.fit(this.lineStringLayer.source.getExtent(), { padding: [230, 230, 230, 230] });
- }
- clearLayer() {
- this.lineStringLayer && this.lineStringLayer.layer.getSource().clear();
- this.pointLayer && this.pointLayer.layer.getSource().clear();
- this.pointOfflineLayer && this.pointOfflineLayer.layer.getSource().clear();
- }
- }
- export default airLineStringLayer;
|