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)
相关推荐
asdfg12589636 分钟前
JS中的闭包应用
开发语言·前端·javascript
kirk_wang8 分钟前
Flutter 导航锁踩坑实录:从断言失败到类型转换异常
前端·javascript·flutter
静小谢1 小时前
前后台一起部署,vite配置笔记base\build
前端·javascript·笔记
用户47949283569151 小时前
改了CSS刷新没反应-你可能不懂HTTP缓存
前端·javascript·面试
还好还好不是吗2 小时前
老项目改造 vue-cli 2.6 升级 rsbuild 提升开发效率300% upupup!!!
前端·性能优化
sumAll2 小时前
别再手动对齐矩形了!这个开源神器让 AI 帮你画架构图 (Next-AI-Draw-IO 体验)
前端·人工智能·next.js
OpenTiny社区2 小时前
2025OpenTiny星光ShowTime!年度贡献者征集启动!
前端·vue.js·低代码
wangan0942 小时前
不带圆圈的二叉树
java·前端·javascript
狗哥哥2 小时前
从零到一:打造企业级 Vue 3 高性能表格组件的设计哲学与实践
前端·vue.js·架构
疯狂平头哥2 小时前
微信小程序真机预览-数字不等宽如何解决
前端