Vue2+OpenLayers给2个标点Feature分别添加独立的点击事件(提供Gitee源码)
前言:之前开发都是将所有的点位存放在一个图层上面,并统一赋予它们相同的点击事件,如果其中某些点的点击事件不一样呢,这种问题如何解决呢,本篇博客就是解决这个通点。
目录
一、案例截图
二、安装OpenLayers库
三、代码实现
3.1、实现思路
3.2、添加两个点
3.3、初始化点击事件
3.4、完整代码
四、Gitee源码
一、案例截图
点击2个点,可以看到控制台,它们点击事件打印出来的信息是不一样的,这就是我们需要实现的效果。
二、安装OpenLayers库
npm install ol
三、代码实现
3.1、实现思路
其实就是为这两个点分别新建两个图层,先初始化变量。
关键代码:
data() {
return {
map:null,
overLay:null,
//图层1
firstLayer: new VectorLayer({
source: new VectorSource(),
}),
//图层2
secLayer: new VectorLayer({
source: new VectorSource(),
}),
}
},
3.2、添加两个点
先封装好生成点位的方法,传入经纬度信息就可以生成点位了,传入的格式例如[116.222222,38.222222]。
关键代码:
/**
* 根据经纬度坐标添加自定义图标 支持base64
*/
addPoints(coordinate) {
// 创建feature要素,一个feature就是一个点坐标信息
let feature = new Feature({
geometry: new Point(coordinate),
});
// 设置要素的图标
feature.setStyle(
new Style({
// 设置图片效果
image: new Icon({
src: 'http://api.tianditu.gov.cn/img/map/markerA.png',
// anchor: [0.5, 0.5],
scale: 1,
}),
}),
);
return feature;
},
在地图初始化以后,调用上面封装好的方法新增两个点,并分别添加到之前创建好的两个图层上。
关键代码:
//分别添加2个图层
this.map.addLayer(this.firstLayer);
this.map.addLayer(this.secLayer);
//添加第一个点
let firstFeature = this.addPoints([118.958412, 32.119130]);
this.firstLayer.getSource().addFeature(firstFeature);
//添加第二个点
let secFeature = this.addPoints([118.948627, 32.120428]);
this.secLayer.getSource().addFeature(secFeature);
3.3、初始化点击事件
实现思路:在地图上监听用户的单击事件,获取用户点击的坐标后,检查这一区域是否存在于第一个或第二个图层(VectorLayer)的特征(Feature)中。如果找到特征,则输出其几何体的坐标;如果没有找到特征,则输出提示信息,表明用户点击了地图的空白处。
关键代码:
initPointEvent(){
let _that = this;
// 添加点击事件
this.map.on('singleclick', (event) => {
// 获取点击的坐标
const pixel = this.map.getEventPixel(event.originalEvent);
const firstFeature = this.map.forEachFeatureAtPixel(pixel, (o) => {
let features = _that.firstLayer.getSource().getFeatures();
let find;
features.forEach(feature => {
if(feature === o){
find = feature;
}
});
return find;
});
const secFeature = this.map.forEachFeatureAtPixel(pixel, (o) => {
let features = _that.secLayer.getSource().getFeatures();
let find;
features.forEach(feature => {
if(feature === o){
find = feature;
}
});
return find;
});
if (firstFeature) {
// 获取 Feature 的几何体
const geometry = firstFeature.getGeometry();
// 获取坐标
const coordinates = geometry.getCoordinates();
console.log("第一个图层中点位的点击事件被触发了,当前经纬度:"+coordinates)
}else if(secFeature){
// 获取 Feature 的几何体
const geometry = secFeature.getGeometry();
// 获取坐标
const coordinates = geometry.getCoordinates();
console.log("第二个图层中点位的点击事件被触发了,当前经纬度:"+coordinates)
}else {
console.log("地图的空白处被点击了")
}
});
3.4、完整代码
<template>
<div>
<div id="map-container"></div>
</div>
</template>
<script>
import {Feature, Map, View} from 'ol'
import { Tile as TileLayer } from 'ol/layer'
import { get } from 'ol/proj';
import { getWidth, getTopLeft } from 'ol/extent'
import { WMTS } from 'ol/source'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import { defaults as defaultControls} from 'ol/control';
import {Point} from "ol/geom";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import {Icon, Style} from "ol/style";
export const projection = get("EPSG:4326");
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = [];
for (let z = 0; z < 19; ++z) {
resolutions[z] = size / Math.pow(2, z);
}
export default {
data() {
return {
map:null,
overLay:null,
//图层1
firstLayer: new VectorLayer({
source: new VectorSource(),
}),
//图层2
secLayer: new VectorLayer({
source: new VectorSource(),
}),
}
},
mounted(){
this.initMap() // 加载矢量底图
},
methods:{
initMap() {
const KEY = '你申请的KEY'
this.map = new Map({
target: 'map-container',
layers: [
// 底图
new TileLayer({
source: new WMTS({
url: `http://t{0-6}.tianditu.com/vec_c/wmts?tk=${KEY}`,
layer: 'vec', // 矢量底图
matrixSet: 'c', // c: 经纬度投影 w: 球面墨卡托投影
style: "default",
crossOrigin: 'anonymous', // 解决跨域问题 如无该需求可不添加
format: "tiles", //请求的图层格式,这里指定为瓦片格式
wrapX: true, // 允许地图在 X 方向重复(环绕)
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
})
})
}),
// 标注
new TileLayer({
source: new WMTS({
url: `http://t{0-6}.tianditu.com/cva_c/wmts?tk=${KEY}`,
layer: 'cva', //矢量注记
matrixSet: 'c',
style: "default",
crossOrigin: 'anonymous',
format: "tiles",
wrapX: true,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
})
})
})
],
view: new View({
center: [118.958366,32.119577],
projection: projection,
zoom: 12,
maxZoom: 17,
minZoom: 1
}),
//加载控件到地图容器中
controls: defaultControls({
zoom: false,
rotate: false,
attribution: false
})
});
//分别添加2个图层
this.map.addLayer(this.firstLayer);
this.map.addLayer(this.secLayer);
//添加第一个点
let firstFeature = this.addPoints([118.958412, 32.119130]);
this.firstLayer.getSource().addFeature(firstFeature);
//添加第二个点
let secFeature = this.addPoints([118.948627, 32.120428]);
this.secLayer.getSource().addFeature(secFeature);
this.initPointEvent();
},
/**
* 根据经纬度坐标添加自定义图标 支持base64
*/
addPoints(coordinate) {
// 创建feature要素,一个feature就是一个点坐标信息
let feature = new Feature({
geometry: new Point(coordinate),
});
// 设置要素的图标
feature.setStyle(
new Style({
// 设置图片效果
image: new Icon({
src: 'http://api.tianditu.gov.cn/img/map/markerA.png',
// anchor: [0.5, 0.5],
scale: 1,
}),
}),
);
return feature;
},
initPointEvent(){
let _that = this;
// 添加点击事件
this.map.on('singleclick', (event) => {
// 获取点击的坐标
const pixel = this.map.getEventPixel(event.originalEvent);
const firstFeature = this.map.forEachFeatureAtPixel(pixel, (o) => {
let features = _that.firstLayer.getSource().getFeatures();
let find;
features.forEach(feature => {
if(feature === o){
find = feature;
}
});
return find;
});
const secFeature = this.map.forEachFeatureAtPixel(pixel, (o) => {
let features = _that.secLayer.getSource().getFeatures();
let find;
features.forEach(feature => {
if(feature === o){
find = feature;
}
});
return find;
});
if (firstFeature) {
// 获取 Feature 的几何体
const geometry = firstFeature.getGeometry();
// 获取坐标
const coordinates = geometry.getCoordinates();
console.log("第一个图层中点位的点击事件被触发了,当前经纬度:"+coordinates)
}else if(secFeature){
// 获取 Feature 的几何体
const geometry = secFeature.getGeometry();
// 获取坐标
const coordinates = geometry.getCoordinates();
console.log("第二个图层中点位的点击事件被触发了,当前经纬度:"+coordinates)
}else {
console.log("地图的空白处被点击了")
}
});
}
}
}
</script>
<style scoped>
#map-container {
width: 100%;
height: 100vh;
}
</style>
四、Gitee源码
地址:Vue2+OpenLayers给2个标点Feature分别添加独立的点击事件