openlayers实现点图查询我能想到的有两种方法:
一种是通过给map挂载点击事件,点击事件会传入事件对象e,利用map.getEventPixel(e.originalEvent)方法获取点击的像元pixel,然后通过map.forEachFeatureAtPixel(pixel,(feature)=>{return feature;})遍历map中的所有与pixel相交的feature,以此获得点击到的feature对象。
map.on("click", (e) => {
const pixel = map.getEventPixel(e.originalEvent);
const feature = map.forEachFeatureAtPixel(pixel, (feature, whereLayer) => {
// 第二个参数whereLayer代表feature所在图层
return feature;
})
this.feature = feature;
})
另一种是通过给map添加 选择交互## ol/interaction/Select 的方式获得点击到的feature
// 设置点击时被选中
const select = new Select({ condition: click });
select.on("select", (e) => {
const feature = e.target.getFeatures();
this.feature = feature.array_[0];
})
map.addInteraction(select);
最后通过设置Overlay的方式展示点击的feature的信息
下面是我在vue2项目中写的一个点图查询的组件(这也是上面的代码的出处)
<template>
<div id="map">
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
</div>
</template>
<script>
import VectorLayer from 'ol/layer/Vector';
import Map from "ol/Map"
import { Overlay, View } from 'ol';
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import * as olProj from "ol/proj";
import { Style, Fill } from 'ol/style';
import Select from 'ol/interaction/Select';
import { click } from 'ol/events/condition';
export default {
data() {
return {
openMap: null,
feature: null
}
},
mounted() {
this.initMap();
this.addClickEvt();
// 还有一种方法就是点图选择要素(这里不采用这种方式)
// this.addSelectInteraction();
this.addOverlay();
},
methods: {
initMap() {
this.openMap = new Map({
target: "map",
layers: [
new VectorLayer({
source: new VectorSource({
url: 'https://openlayers.org/data/vector/ecoregions.json',
format: new GeoJSON(),
}),
background: 'white',
style: function (feature) {
const style = new Style({
fill: new Fill({
color: '#eeeeee',
}),
});
const color = feature.get('COLOR') || '#eeeeee';
style.getFill().setColor(color);
return style;
},
})
],
view: new View({
center: olProj.fromLonLat([108.945951, 34.465262]),
zoom: 4
}),
controls: []
})
},
addClickEvt() {
this.openMap.on("click", (e) => {
const pixel = this.openMap.getEventPixel(e.originalEvent);
const feature = this.openMap.forEachFeatureAtPixel(pixel, (feature, whereLayer) => {
// 第二个参数whereLayer代表feature所在图层
return feature;
})
this.feature = feature;
})
},
addSelectInteraction() {
// 设置点击时被选中
const select = new Select({ condition: click });
select.on("select", (e) => {
const feature = e.target.getFeatures();
this.feature = feature.array_[0];
})
this.openMap.addInteraction(select);
},
addOverlay() {
const container = document.getElementById('popup');
const content = document.getElementById('popup-content');
const closer = document.getElementById('popup-closer');
const overlay = new Overlay({
element: container,
// autoPan属性用来保证view能够完全将弹出的弹窗展示出来
autoPan: {
animation: {
duration: 250,
},
},
});
closer.onclick = function () {
overlay.setPosition(undefined);
closer.blur();
return false;
};
// 这里用箭头函数,使得this指向当前的vue实例
this.openMap.on('singleclick', (evt) => {
const coordinate = evt.coordinate;
try {
content.innerHTML = `ECO_NAME: ${this.feature.values_.ECO_NAME}`;
overlay.setPosition(coordinate);
} catch (error) {
// 如果点击的pixel没有feature则将刚才的弹窗删去
overlay.setPosition(undefined);
}
});
this.openMap.addOverlay(overlay);
}
}
}
</script>
<style>
#map {
height: 100%;
width: 100%;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
line-height: 20px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>
最终的效果:
这是第一种方法的addClickEvt()
这是第二种方法的
addSelectInteraction()