openlayers 聚合图层点击事件--点击feature展示相关信息操作

聚合情况下,点击聚合要素,则显示聚合的设备信息;若只有一个要素,则显示设备信息;聚合情况下:点击设备信息,则继续弹出点击的这个设备详情

业务功能分析:

获取地图上的点击要素方法有2种途径,

1、interaction中select方法

2、map中forEachFeatureAtPixel方法

其中,当数据量多大的时候,是不建议采用第二种方法,因为forEachFeatureAtPixel的原理,是遍历操作,当数据量大的时候,页面容易卡顿;因此建议采用第一种方法;

在以下的地图初始化方法init中,

  this.clickMap(evt)方法,就是采用了第二种map中forEachFeatureAtPixel的做法,因此被注释;

  this.featureClick()方法,是后来后来优化的方法,采用第一种interaction中select方法 。

 仅截取部分核心代码,仅供借鉴

1、地图部分代码

其中

id="map"是地图渲染的部分
ref="overlayPopup"是设备信息弹窗
ref="deviceListPopup" 设备聚合列表弹窗
 1         <el-container style="position: relative;">
 2             <div id="map" class="map"></div>
 3             <!-- 自定义开发控件 -->
 4             <div class="tool-box" v-show="hasLoadMap">
 5                 <map-operation :map="map"></map-operation>
 6             </div>
 7             <!-- 设备信息弹窗 -->
 8             <div class="ol-popup" ref="overlayPopup">
 9                 <div class="close-icon" @click="closeVideoPopup">x</div>
10                 <div>
11                     <div class="vedio-selection" @click="showPlayBox(1)">监测</div>
12                     <div class="vedio-selection" @click="showPlayBox(2)">回放</div>
13                     <div class="vedio-selection" @click="showDeviceInfoBox" v-if="dockingOneForOne">设备信息</div>
14                 </div>
15                 <div class="eachItem">名称:{{popupDeviceInfo.dev_chann_name}}</div>
16                 <div class="eachItem">类型:{{popupDeviceInfo.channel_type}}</div>
17             </div> 
18             <!-- 设备聚合列表弹窗 -->
19             <div class="ol-popup-devicelist" ref="deviceListPopup">
20                 <div class="close-icon" @click="closeDevicePopup">x</div>
21                 <div class="popupTitle">设备信息
22                     <span class="popupsubTitle">(合计{{popupDeviceList.length}}个)</span>
23                 </div>
24                 <div class="popupDeviceOutter">
25                     <div v-for="(item,index) in popupDeviceList" :key="index" class="eachItem" :title="item.dev_chann_name" @click="showDeviceInfoFun(item)">
26                         <span class="indexCls">{{index+1}}、</span>
27                         <img :src="rspImg(item.facade, item.status)" class="popupImg">
28                         {{item.dev_chann_name}}
29                     </div>
30                 </div>
31             </div>
32         </el-container>

2、地图初始化代码

#method里面

 1     //初始化
 2         init() {
 3             let appCode = 'appCode';
 4             let layersUrl = sessionStorage.getItem('mapUrl');
 5             let viewCenter = JSON.parse(sessionStorage.getItem('viewCenter'));
 6             let mapLayer = initMapLayer(_data.mapType, layersUrl);
 7 
 8              ///鸟瞰图控件
 9             this.OverviewMapObj = new ol.control.OverviewMap({
10                 collapsed: false,
11                 view: new ol.View({
12                     center: viewCenter,
13                     maxZoom: 18,
14                     minZoom: 12,
15                     zoom: 13,
16                     projection: 'EPSG:4326', //需要跟map中的view一致
17                 }),
18             });
19             this.map = new ol.Map({
20                 layers: mapLayer,
21                 view: new ol.View({
22                     center: viewCenter,
23                     maxZoom: 18,
24                     minZoom: 8,
25                     zoom: 13,
26                     projection: 'EPSG:4326',
27                 }),
28                 controls: ol.control.defaults({
29                     zoomOptions: {
30                         zoomInTipLabel: '放大', //Default is Zoom in
31                         zoomOutTipLabel: '缩小', //Default is Zoom out
32                     },
33                     }).extend([
34                         new ol.control.MousePosition({
35                             coordinateFormat: ol.coordinate.createStringXY(5), //保留5位小数
36                         }),
37                         new ol.control.ScaleLine(),
38                         // new ol.control.ZoomSlider(),
39                         this.OverviewMapObj
40                     ]),
41                 interactions: ol.interaction.defaults({
42                     doubleClickZoom: false, // 取消双击放大功能交互
43                 }),
44                 target: 'map',
45             });
46 
47             //   双击事件
48             this.map.on('dblclick', evt => {
49                 this.dbclickMap(evt);
50             });
51             //   双击事件
52             // this.map.on('click', evt => {
53             //     this.clickMap(evt);
54             // });        
55             this.featureClick();    // 要素点击事件           
56             // this.addListener();
57         },

3、地图点击事件

对应init里面的click事件

 1         //点击事件
 2         clickMap(evt) {
 3             let featureMouseOver = this.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
 4                 return feature;
 5             });
 6             if (!featureMouseOver) return 
 7             let overFeature = featureMouseOver.getProperties().features
 8             if(!overFeature || overFeature.length == 0) return false
 9             if (overFeature.length === 1) {// 只有一个元素的情况下
10                 let feature = overFeature[0]; //获取该要素
11                 let featureData = feature.get('data') || {}
12                 this.showFeature(featureData, evt.coordinate) 
13             } else if(overFeature.length > 1){// 多个元素的情况下
14                 this.showFeatureList(overFeature, evt.coordinate)   // 展示设备列表
15             }
16         },

4、地图要素select事件

 1        // 给页面的要素添加点击事件
 2         featureClick(evt) {
 3             var selectSingleClick = new ol.interaction.Select({
 4                 style: new ol.style.Style({
 5                     image: new ol.style.Circle({
 6                         radius: 18,
 7                         fill: new ol.style.Fill({
 8                             color: 'rgba(70,220,198,0.5)'
 9                         })
10                     })
11                 })
12             });
13             this.map.addInteraction(selectSingleClick);
14             selectSingleClick.on('select', e =>{
15                 var featuresAry=e.target.getFeatures().getArray();
16                 if (featuresAry.length>0){
17                     let featureList=featuresAry[0];
18                     let coordinate = ol.extent.getCenter(featureList.getGeometry().getExtent());    // 点击的点经纬度
19                     // 至此得出聚合图层的要素列表
20                     let features=featureList.getProperties().features;   
21                     this.closeDevicePopup() // 关闭已打开的列表popup
22                     this.closeVideoPopup()  // 关闭已打开的详情popup
23                     if(features.length == 1 ) {
24                         let featureData = features[0].get('data') || {}
25                         this.showFeature(featureData, coordinate) 
26                     } else if(features.length > 1) {
27                         this.showFeatureList(features, coordinate)   // 展示设备列表
28                     }
29                 }
30             })
31         },

5、地图双击事件。

聚合点击时,和双击事件关系不大,此处仅为记录双击的事件而言

 1         //双击地图事件
 2         dbclickMap(evt) {
 3             let featureMouseOver = this.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
 4                 return feature;
 5             });
 6             if (featureMouseOver) {
 7                 let featureProperties = featureMouseOver.getProperties();
 8                 if (!featureProperties.features) return;
 9                 //聚合情况下
10                 if (featureProperties.features.length > 1) {
11                     //双击聚合图层放大
12                     let view = this.map.getView();
13                     view.setZoom(view.getZoom() + 2);
14                     view.setCenter(featureMouseOver.getGeometry().getCoordinates()); //设置地图显示中心
15                 }
16             }
17         },

6、查看详情和查看列表方法

附加代码: 

 1 // popup展示,聚合列表数据
 2         showFeatureList(overFeature, coordinate) {
 3             this.popupDeviceList = []
 4             overFeature.forEach(itemFeature =>{
 5                 const itemFeatureData = itemFeature.get('data') || {}
 6                 this.popupDeviceList.push(itemFeatureData)
 7             })
 8             let deviceListPopup = this.$refs.deviceListPopup;
 9             if (!_data.deviceListPopup) {
10                 _data.deviceListPopup = new ol.Overlay({
11                     element: deviceListPopup,
12                     offset: [10, 0],
13                 });
14                 deviceListPopup.style.display = 'block';
15                 this.map.addOverlay(_data.deviceListPopup);
16             } else {
17                 deviceListPopup.style.display = 'block';
18                 _data.deviceListPopup.setOffset([10, 0]); // 设置偏移量
19                 _data.deviceListPopup.setElement(deviceListPopup);
20             }
21             _data.deviceListPopup.setPosition(coordinate);
22         },
23         //popup展示设备的具体信息
24         showFeature(featureData, coordinate) {
25             let overlayPopup = this.$refs.overlayPopup;
26             this.popupDeviceInfo = featureData
27             if (!_data.overlayPopup) {
28                 _data.overlayPopup = new ol.Overlay({
29                     element: overlayPopup,
30                     offset: [10, 0],
31                 });
32                 overlayPopup.style.display = 'block';
33                 this.map.addOverlay(_data.overlayPopup);
34             } else {
35                 overlayPopup.style.display = 'block';
36                 _data.overlayPopup.setOffset([10, 0]); // 设置偏移量
37                 _data.overlayPopup.setElement(overlayPopup);
38             }
39             _data.overlayPopup.setPosition(coordinate);
40             this.setCurrentDevice(featureData)
41         },
42         //关闭overlayPopup
43         closeVideoPopup() {
44             let overlayPopup = this.$refs.overlayPopup;
45             overlayPopup.style.display = 'none';
46         },
47          //关闭overlayPopup
48         closeDevicePopup() {
49             let deviceListPopup = this.$refs.deviceListPopup;
50             deviceListPopup.style.display = 'none';
51         },
原文地址:https://www.cnblogs.com/luoxuemei/p/13963526.html