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         },

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM