openlayer点击切换图标

一、项目介绍

在OpenLayers中,我们可以通过点击地图上的要素(Feature)来切换其图标。它的原理就是改变要素的样式(Style)就可以实现切换图标的效果。以下是实现的思路:

  1. 创建一个地图,并添加一个矢量图层(VectorLayer)来显示要素。
  2. 创建两个样式:一个用于默认图标,另一个用于点击后的图标。
  3. 为矢量图层添加点击事件,当点击要素时,检查该要素当前的样式,然后切换到另一个样式。

二、创建图标

js 复制代码
//矢量图层
this.source = new VectorSource({ wrapX: false });
this.vector = new VectorLayer({
    source: this.source,
    zIndex: 100,
    // declutter: true  // 避免图标重叠
});
//地图图层
this.raster = new TileLayer({
     source: new XYZ({
        url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=6",
      }),
 });
 
//创建地图
 this.map = new Map({
  layers: [this.raster, this.vector],
  target: id,
  view: new View({
    center: fromLonLat(this.center),
    zoom: 13,
    maxZoom: 22
  }),
  controls: [], // 不添加任何默认控件
});

//创建要素  
const iconFeature = new Feature({
  geometry: new Point(fromLonLat(item.lonlat)),
  name: item?.name,
  id: item?.id ,
  type: "icon",
  description:item.description,
});
//要素的字体样式
const textStyle = new Style({
  text: new Text({
    text: iconFeature.get("name"),
    textAlign: "center",
    textBaseline: "middle",
    offsetY: 45, // 文字向下偏移
    font: "bold 14px Calibri,sans-serif",
    fill: new Fill({
      color: "#333",
    }),
    stroke: new Stroke({
      color: "#fff",
      width: 1,
    }),
  }),
});

//要素的图标样式
const iconStyle = new Style({
  image: new Icon({
    anchor: [0.5, 0.5],
    scale: 0.8,
    src: url,
  }),
});

//添加样式
iconFeature.setStyle([iconStyle, textStyle]);

// 保存原始样式用于选择功能
iconFeature.set('originalStyle', [iconStyle, textStyle]);
iconFeature.set('textStyle', textStyle);

//添加到矢量图层
this.source.addFeature(iconFeature);

三、点击切换图标

我们使用OpenLayers的Select交互来选择地图上的要素。Select交互允许用户通过点击或悬停来选择矢量要素。我们可以通过配置选项来设置选择的方式(例如单击、悬停等),并且可以设置样式来高亮显示选中的要素。

Select的配置参数如下:

  1. condition : 定义触发选择的条件,默认为 ol/events/condition/singleClick。可以替换为其他条件,如 pointerMove 或自定义函数。
  2. style: 用于设置选中要素的样式。可以是一个样式对象、样式数组或一个返回样式的函数。
  3. layers: 指定在哪些图层上进行选择。可以是一个图层数组或一个过滤函数。
  4. filter : 一个过滤函数,用于确定哪些要素可以被选择。返回 true 表示要素可选择。
  5. features: 一个要素集合,用于管理选中的要素。如果不指定,交互会创建一个新的集合。
  6. hitTolerance: 选择要素时鼠标点击的容差范围,单位为像素。默认为0。
  7. multi : 是否允许多选。默认为 false。如果为 true,则可以通过按住某个键(如 shift)进行多选。
  8. toggleCondition : 定义在多选模式下切换要素选择状态的条件。默认为 ol/events/condition/shiftKeyOnly
  9. addCondition : 定义向当前选择中添加要素的条件。默认为 ol/events/condition/never,因为通常使用 toggleCondition
  10. removeCondition : 定义从当前选择中移除要素的条件。默认为 ol/events/condition/never
  11. wrapX : 是否在选择时考虑地图的重复(例如,在世界地图水平重复时)。默认为 true
js 复制代码
import Select from 'ol/interaction/Select'
//创建一个选择交互
 const select = new Select({
  layers: [this.vector,this.raster],
  multi: false 
})

//监听选择变化
select.on('select', (e)=>{
  console.log('select',e)
  //没有选中
  e.deselected.forEach(function(feature) {
    if(feature.values_?.type!=='icon'){
      return
    }
    const originalStyle = feature.get('originalStyle')
    feature.setStyle(originalStyle);
  });
  
  //选中
  e.selected.forEach(function(feature) {
    if(feature.values_?.type!=='icon'){
      return
    }
    const activeStyle = new Style({
      image: new Icon({
        anchor: [0.5, 0.5],
        scale: 0.8,
        src: `/images/index/active.png`,
      }),
    });
    const textStyle = feature.get('textStyle')
    feature.setStyle([activeStyle,textStyle]);
  });
})
//添加到地图
this.map.addInteraction(select)
相关推荐
GISer_Jing13 小时前
WebGL跨端兼容实战:移动端适配全攻略
前端·aigc·webgl
迦南giser13 小时前
前端性能——传输优化
前端
小白_ysf13 小时前
Vue 中常见的加密方法(对称、非对称、杂凑算法)
前端·vue.js·算法
人工智能训练20 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪20 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
pas1361 天前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠1 天前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
珑墨1 天前
【Turbo】使用介绍
前端
军军君011 天前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
打小就很皮...1 天前
Tesseract.js OCR 中文识别
前端·react.js·ocr