Vue2+OpenLayers添加/删除点、点击事件功能实现(提供Gitee源码)

news2025/1/16 19:10:10

目录

一、案例截图

二、安装OpenLayers库

三、安装Element-UI

四、代码实现

4.1、添加一个点

4.2、删除所有点

4.3、根据经纬度删除点

4.4、给点添加点击事件

4.5、完整代码 

五、Gitee源码


一、案例截图

可以新增/删除标记点,点击标记点可以获取到当前标记点的经纬度信息(绑定了点击事件)。

二、安装OpenLayers库

npm install ol

三、安装Element-UI

没安装的看官方文档:Element - The world's most popular Vue UI framework

四、代码实现

在OpenLayers中,Feature(要素)是地图上表示一个空间实体的对象,它包含的类型有: Point(点) LineString(线段) Polygon(多边形)。

VectorLayer是一个用于在地图上渲染矢量数据的层,支持显示点、线和面等几何图形。

4.1、添加一个点

首先新增一个图层,我们所有的点信息都存放在这个图层上,你也可以添加一个点就新增一个图层,看各自需求,然后初始化经纬度变量。

data() {
  return {
    map:null,
    //所有点信息都放在这个图层
    pointLayer: new VectorLayer({
      source: new VectorSource(),
    }),
    form:{
      lon:'',
      lat:'',
    },
  }
},

在地图初始化以后要把这个图层添加到地图上:

//把图层添加到地图上
this.map.addLayer(this.pointLayer);

新增一个点JS关键代码:

/**
 * 根据经纬度坐标添加自定义图标 支持base64
 */
addPoints() {
  let coordinate = [this.form.lon,this.form.lat];
  // 创建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,
        }),
      }),
  );

  // 要素添加到地图图层上
  this.pointLayer.getSource().addFeature(feature);
  // 设置中心
  this.map.getView().setCenter(coordinate);
},

4.2、删除所有点

removeAllPoint(){
  // 从图层源中获取当前要素
  const features = this.pointLayer.getSource().getFeatures();
  // 遍历要素
  features.forEach(feature => {
    this.pointLayer.getSource().removeFeature(feature);
  });
}

4.3、根据经纬度删除点

删除一个点JS关键代码:

removePoint() {
  let coordinate = [this.form.lon,this.form.lat];
  // 从图层源中获取当前要素
  const features = this.pointLayer.getSource().getFeatures();
  let _that = this;
  // 遍历要素,查找匹配的坐标
  features.forEach(feature => {
    const geometry = feature.getGeometry();
    const featureCoordinates = geometry.getCoordinates();
    // 检查经纬度是否匹配
    if (featureCoordinates[0] == coordinate[0] && featureCoordinates[1] == coordinate[1]) {
      // 找到匹配的要素,移除它
      _that.pointLayer.getSource().removeFeature(feature);
    }
  });
},

4.4、给点添加点击事件

JS关键代码:

initPointEvent(){
  //给点初始化点击事件
  this.map.on("singleclick", (e) => {
    let pixel = this.map.getEventPixel(e.originalEvent);
    let feature = this.map.forEachFeatureAtPixel(pixel, function(feature) { return feature; });
    let coordinate = e.coordinate;
    if(feature){
      console.log("当前点击经纬度:"+coordinate);
    }
  });
}

4.5、完整代码 

<template>
  <div>
    <div style="margin-bottom: 10px">
      <el-button type="danger" @click="removeAllPoint">删除所有点标记</el-button>
      <el-input v-model="form.lon" placeholder="经度" style="margin-left: 10px;width: 200px"></el-input>
      <el-input v-model="form.lat" placeholder="纬度" style="margin-left: 10px;width: 200px"></el-input>
      <el-button type="success" @click="addPoints" style="margin-left: 10px">新增</el-button>
      <el-button type="warning" @click="removePoint" style="margin-left: 10px">删除</el-button>
    </div>
    <div id="map-container"></div>
  </div>

</template>
<script>
import { Map, View,Feature } 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 VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import {Point} from "ol/geom";
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,
      //所有点信息都放在这个图层
      pointLayer: new VectorLayer({
        source: new VectorSource(),
      }),
      form:{
        lon:'',
        lat:'',
      },
    }
  },
  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
        })
      })
      //把图层添加到地图上
      this.map.addLayer(this.pointLayer);
      //标记点初始化点击事件
      this.initPointEvent();
    },
    /**
     * 根据经纬度坐标添加自定义图标 支持base64
     */
    addPoints() {
      let coordinate = [this.form.lon,this.form.lat];
      // 创建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,
            }),
          }),
      );

      // 要素添加到地图图层上
      this.pointLayer.getSource().addFeature(feature);
      // 设置中心
      this.map.getView().setCenter(coordinate);
    },
    removePoint() {
      let coordinate = [this.form.lon,this.form.lat];
      // 从图层源中获取当前要素
      const features = this.pointLayer.getSource().getFeatures();
      let _that = this;
      // 遍历要素,查找匹配的坐标
      features.forEach(feature => {
        const geometry = feature.getGeometry();
        const featureCoordinates = geometry.getCoordinates();
        // 检查经纬度是否匹配
        if (featureCoordinates[0] == coordinate[0] && featureCoordinates[1] == coordinate[1]) {
          // 找到匹配的要素,移除它
          _that.pointLayer.getSource().removeFeature(feature);
        }
      });
    },
    removeAllPoint(){
      // 从图层源中获取当前要素
      const features = this.pointLayer.getSource().getFeatures();
      // 遍历要素
      features.forEach(feature => {
        this.pointLayer.getSource().removeFeature(feature);
      });
    },
    initPointEvent(){
      //给点初始化点击事件
      this.map.on("singleclick", (e) => {
        let pixel = this.map.getEventPixel(e.originalEvent);
        let feature = this.map.forEachFeatureAtPixel(pixel, function(feature) { return feature; });
        let coordinate = e.coordinate;
        if(feature){
          console.log("当前点击经纬度:"+coordinate);
        }
      });
    }
  }
}
</script>
<style scoped>
#map-container {
  width: 100%;
  height: 100vh;
}
</style>

五、Gitee源码

地址:Vue2+OpenLayers添加+删除点+点击事件功能实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML中如何保留字符串的空白符和换行符号的效果

有个字符串 储值门店{{thing3.DATA}}\n储值卡号{{character_string1.DATA}}\n储值金额{{amount4.DATA}}\n当前余额{{amount5.DATA}}\n储值时间{{time2.DATA}} &#xff0c; HTML中想要保留 \n的换行效果的有下面3种方法&#xff1a; 1、style 中 设置 white-space: pre-lin…

GB44495-2024 汽车整车信息安全技术要求 - V2X部分前置要求

背景 GB 44495-2024《汽车整车信息安全技术要求》中关于V2X&#xff08;车与外界通信&#xff09;的部分&#xff0c;主要关注于通信安全要求&#xff0c;旨在确保车辆在与外部设备进行数据交互时的信息安全。其测试大致可分为消息层&#xff08;数据无异常&#xff09;、应用…

[PAT 甲级] 1179 Chemical Equation (DFS)

​ 题目翻译&#xff08;GPT&#xff09;&#xff1a; 1179 化学方程式 化学方程式是一种用符号和公式表示化学反应的方法&#xff0c;其中反应物在方程式的左侧&#xff0c;生成物在右侧。例如&#xff1a; CH₄ 2O₂ -> CO₂ 2H₂O 表示反应物为甲烷和氧气&#xff…

android分区和root

线刷包内容&#xff1a; 线刷包是一个完整的android镜像&#xff0c;不但包括android、linux和用户数据&#xff0c;还包括recovery等。当然此图中没有recovery,但是我们可以自己刷入一个。 主要分区 system.img 系统分区&#xff0c;包括linux下主要的二进制程序。 boot.img…

每日一题(五):n个正整数排列,求组合后最大数

目录 一、题目 二、题目分析 &#xff08;一&#xff09;明确需求 背景知识&#xff1a;字符串的比较与连接 1.字符串的比较 2.字符串的连接 (二)分析思路 三、将思路转换为程序 四、总结 一、题目 给定n个正整数a1,a2,……,an对这n个数进行排列&#xff0c;求组合后可以得到…

【STM32-学习笔记-3-】TIM定时器

文章目录 TIM定时器Ⅰ、TIM定时器函数Ⅱ、TIM_TimeBaseInitTypeDef结构体参数①、TIM_ClockDivision②、TIM_CounterMode③、TIM_Period④、TIM_Prescaler⑤、TIM_RepetitionCounter Ⅱ、定时器配置Ⅲ、定时器外部中断NVIC配置 TIM定时器 Ⅰ、TIM定时器函数 // 将定时器寄存器…

【Rust自学】12.2. 读取文件

12.2.0. 写在正文之前 第12章要做一个实例的项目——一个命令行程序。这个程序是一个grep(Global Regular Expression Print)&#xff0c;是一个全局正则搜索和输出的工具。它的功能是在指定的文件中搜索出指定的文字。 这个项目分为这么几步&#xff1a; 接收命令行参数读…

新垂直电商的社交传播策略与AI智能名片2+1链动模式S2B2C商城小程序的应用探索

摘要&#xff1a;随着互联网技术的不断进步和电商行业的快速发展&#xff0c;传统电商模式已难以满足消费者日益增长的个性化和多元化需求。新垂直电商在此背景下应运而生&#xff0c;通过精准定位、用户细分以及深度社交传播策略&#xff0c;实现了用户群体的快速裂变与高效营…

【ORACLE战报】2025.1月OCP | MySQL考试

2025.1月【最新考试成绩出炉】 OCP战报 MySQL 战报 部分学员成绩及证书

九 RK3568 android11 MPU6500

一 MPU6500 内核驱动 1.1 查询设备连接地址 查看原理图, MPU6500 I2C 连接在 I2C4 上, 且中断没有使用 i2c 探测设备地址为 0x68 1.2 驱动源码 drivers/input/sensors/gyro/mpu6500_gyro.c drivers/input/sensors/accel/mpu6500_acc.c 默认 .config 配置编译了 mpu6550 …

Android JecPack组件之LifeCycles 使用详解

一、背景 LifeCycle 是一个可以感知宿主生命周期变化的组件。常见的宿主包括 Activity/Fragment、Service 和 Application。LifeCycle 会持有宿主的生命周期状态的信息&#xff0c;当宿主生命周期发生变化时&#xff0c;会通知监听宿主的观察者。 LifeCycle 的出现主要是为了…

机器学习(2):线性回归Python实现

1 概念回顾 1.1 模型假设 线性回归模型假设因变量y yy与自变量x xx之间的关系可以用以下线性方程表示&#xff1a; y β 0 β 1 ⋅ X 1 β 2 ⋅ X 2 … β n ⋅ X n ε y 是因变量 (待预测值)&#xff1b;X1, X2, ... Xn 是自变量&#xff08;特征&#xff09;β0, β1,…

2025.1.15——二、字符型注入

一、基本操作&#xff1a;整理已知信息&#xff0c;本题为字符型注入 二、解题步骤 step 1&#xff1a;确认为字符型注入 键入&#xff1a; 1 键入&#xff1a;1 and 12 # 发现报错 键入&#xff1a;1 and 11 # 未发现报错 所以确认为字符型注入 step 2&#xff1a;查询…

4、dockerfile实现lnmp和elk

dockerfile实现lnmp 使用dockerfile n&#xff1a;nginx&#xff0c;172.111.0.10 m&#xff1a;mysql&#xff0c;172.111.0.20 p&#xff1a;php&#xff0c;172.111.0.30 安装配置nginx 1、准备好nginx和wordpress安装包 2、配置dockerfile 3、配置nginx主配置文件ngin…

金融项目实战 05|Python实现接口自动化——登录接口

目录 一、代码实现自动化理论及流程 二、脚本实现的理论和准备工作 1、抽取功能转为自动化用例 2、搭建环境(测试工具) 3、搭建目录结构 三、登录接口脚本实现 1、代码编写 1️⃣api目录 2️⃣script目录 2、断言 3、参数化 1️⃣编写数据存储文件&#xff1a;jso…

Flink链接Kafka

一、基于 Flink 的 Kafka 消息生产者 Kafka 生产者的创建与配置&#xff1a; 代码通过 FlinkKafkaProducer 创建 Kafka 生产者&#xff0c;用于向 Kafka 主题发送消息。Flink 执行环境的配置&#xff1a; 配置了 Flink 的检查点机制&#xff0c;确保消息的可靠性&#xff0c;支…

基于国产麒麟操作系统,通过Kubeadm离线部署Kubernetes 1.28版本

文章目录 前言一、环境准备1.主机操作系统说明2.主机硬件配置3.ansible-playbook相关目录准备4.下载离线部署包4.1. 下载kubeclt、kubeam、kubelet RPM包4.2. 下载docker安装包4.3. 下载containerd安装包4.4. 镜像包下载 二、部署流程三、部署过程1.修改hosts文件2.部署单maste…

3、docker的数据卷和dockerfile

dockerfile--------------------自定义镜像 docker的数据卷&#xff1a; 容器与宿主机之间&#xff0c;或者容器和容器之间的数据共享&#xff08;目录&#xff09;。 创建容器的时间&#xff0c;通过指定目录&#xff0c;实现容器于宿主机之间&#xff0c;或者容器和容器之…

登上Nature!交叉注意力机制 发顶会流量密码!

在深度学习领域&#xff0c;交叉注意力融合技术正迅速崛起&#xff0c;并成为处理多模态数据的关键工具。这一技术通过有效地整合来自不同模态的信息&#xff0c;使得模型能够更好地理解和推理复杂的数据关系。 随着多模态数据的日益普及&#xff0c;如图像、文本和声音等&…

网安——CSS

一、CSS基础概念 CSS有两个重要的概念&#xff0c;分为样式和布局 CSS的样式分为两种&#xff0c;一种是文字的样式&#xff0c;一种是盒模型的样式 CSS的另一个重要的特质就是辅助页面布局&#xff0c;完成HTML不能完成的功能&#xff0c;比如并排显示或精确定位显示 从HT…