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

目录

一、案例截图

二、安装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添加+删除点+点击事件功能实现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows 10 ARM工控主板连接I2S音频芯片

在Windows工控主板应用中&#xff0c;音频功能是一项基本的需求&#xff0c;USB声卡在x86/x64 Windows系统上就可直接免驱使用&#xff0c;但这些USB声卡通常不提供ARM上的Windows系统驱动。本文将介绍如何利用安装在ARM上的Windows工控主板——ESM8400的I2S接口、连接WM8960音…

【Rust】错误处理机制

目录 思维导图 引言 一、错误处理的重要性 1.1 软件中的错误普遍存在 1.2 编译时错误处理要求 二、错误的分类 2.1 可恢复错误&#xff08;Recoverable Errors&#xff09; 2.2 不可恢复错误&#xff08;Unrecoverable Errors&#xff09; 三、Rust 的错误处理机制 3…

提升租赁效率的租赁小程序全解析

内容概要 在如今快节奏的生活中&#xff0c;租赁小程序俨然成为了提升租赁效率的一把利器。无论是个人还是企业&#xff0c;都会因其便捷的功能而受益。简单来说&#xff0c;租赁小程序能让繁琐的租赁流程变得轻松、高效。在这里&#xff0c;我们将带您畅游租赁小程序的海洋&a…

SSM商城设计与实现

摘 要 本文的主要工作是对基于B/S模式及JSP技术的基于智能推荐的b2c销售网站进行了研究与设计。本文首先介绍了基于智能推荐的b2c销售网站的背景&#xff0c;分析比较了国内外相关基于智能推荐的b2c销售网站的运行模式、系统特点与开发技术。然后分析了目前热点的各种Web应用开…

drawDB docker部属

docker pull xinsodev/drawdb docker run --name some-drawdb -p 3000:80 -d xinsodev/drawdb浏览器访问&#xff1a;http://192.168.31.135:3000/

CentOS7下Hadoop集群分布式安装详细图文教程

1、集群规划 主机 角色 DSS20 NameNode DataNode ResourceManager NodeManager DSS21 SecondaryNameNode NameNode NodeManager DSS22 DataNode NodeManager 1.1、环境准备 1.1.1 关闭防火墙 #查看防火墙状态 firewall-cmd --state #停止…

计算机网络——网络层-IPV4相关技术

一、网络地址转换NAT • 网络地址转换 NAT 方法于1994年提出。 • 需要在专用网连接到因特网的路由器上安装 NAT 软件。装有 NAT 软件的路由器叫做 NAT路由器&#xff0c;它至少有一个有效的外部全球地址 IPG。 • 所有使用本地地址的主机在和外界通信时都要在 NAT 路由器上将…

postgresql|数据库|利用sqlparse和psycopg2库批量按顺序执行SQL语句(psyconpg2新优化版本)

一、 旧版批量执行SQL脚本的python文件缺点&#xff0c;优点&#xff0c;以及更新内容 书接上回&#xff0c;postgresql|数据库开发|python的psycopg2库按指定顺序批量执行SQL文件(可离线化部署)_python sql psycopg2-CSDN博客 这个python脚本写了很久了&#xff0c;最近开始…

Node.js——http 模块(二)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

基于element UI el-dropdown打造表格操作列的“更多⌵”上下文关联菜单

<template><div :class"$options.name"><el-table :data"tableData"><el-table-column type"index" label"序号" width"60" /><!-- 主要列 BEGIN---------------------------------------- --&g…

javascrip基础语法

为什么学习 JavaScript? JavaScript 是 web 开发人员必须学习的 3 门语言中的一门&#xff1a; HTML 定义了网页的内容CSS 描述了网页的布局JavaScript 控制了网页的行为 1. JavaScript 输出 1.1 console.log()&#xff1a;用于将信息输出到浏览器控制台&#xff0c;例如con…

大语言模型预训练、微调、RLHF

转发&#xff0c;如有侵权&#xff0c;请联系删除&#xff1a; 1.【LLM】3&#xff1a;从零开始训练大语言模型&#xff08;预训练、微调、RLHF&#xff09; 2.老婆饼里没有老婆&#xff0c;RLHF里也没有真正的RL 3.【大模型微调】一文掌握7种大模型微调的方法 4.基于 Qwen2.…

django基于Python的校园个人闲置物品换购平台

Django 基于 Python 的校园个人闲置物品换购平台 一、平台概述 Django 基于 Python 的校园个人闲置物品换购平台是专为校园师生打造的一个便捷、环保且充满活力的线上交易场所。它借助 Django 这一强大的 Python Web 开发框架&#xff0c;整合了校园内丰富的闲置物品资源&…

abap安装cl_json类

文章来自 SAP根据源码导入/ui2/cl_json类 - pikeduo - 博客园 新建一个se38程序&#xff0c;把源码放到里&#xff0c;源码如下 *----------------------------------------------------------------------* * CLASS zcl_json DEFINITION *----------------------------…

[OPEN SQL] ORDER BY排序数据

本次操作使用的数据库表为SFLIGHT&#xff0c;其字段内容如下所示 航班(SFLIGHT) 该数据库表中的部分值如下所示 OPEN SQL中的ORDER BY语句用于对数据库表中的数据进行排序 在查询数据的时候使用ORDER BY语句&#xff0c;则查询出来的结果会按照ORDER BY指定的字段进行排序 排序…

STM32F103ZET6战舰版单片机开发板PCB文件 电路原理图

资料下载地址&#xff1a;STM32战舰版单片机开发板PCB文件 电路原理图 1、原理图 2、PCB 3、板子介绍 一、核心芯片与性能 核心芯片&#xff1a;STM32F103ZET6&#xff0c;这是一款基于ARM Cortex-M3内核的高性能单片机。处理器频率&#xff1a;高达72MHz&#xff0c;确保了…

An FPGA-based SoC System——RISC-V On PYNQ项目复现

本文参考&#xff1a; &#x1f449; 1️⃣ 原始工程 &#x1f449; 2️⃣ 原始工程复现教程 &#x1f449; 3️⃣ RISCV工具链安装教程 1.准备工作 &#x1f447;下面以LOCATION代表本地源存储库的安装目录&#xff0c;以home/xilinx代表在PYNQ-Z2开发板上的目录 ❗ 下载Vivad…

GAN的应用

5、GAN的应用 ​ GANs是一个强大的生成模型&#xff0c;它可以使用随机向量生成逼真的样本。我们既不需要知道明确的真实数据分布&#xff0c;也不需要任何数学假设。这些优点使得GANs被广泛应用于图像处理、计算机视觉、序列数据等领域。上图是基于GANs的实际应用场景对不同G…

centos9设置静态ip

CentOS 9 默认使用 NetworkManager 管理网络&#xff0c;而nmcli是 NetworkManager 命令行接口的缩写&#xff0c;是一个用来进行网络配置、管理网络连接的命令工具&#xff0c;可以简化网络设置&#xff0c;尤其是在无头&#xff08;没有图形界面&#xff09;环境下。 1、 cd…

Idea日志乱码

问题描述 前提&#xff1a;本人使用windows Idea运行sh文件&#xff0c;指定了utf-8编码&#xff0c;但是运行过程中还是存在中文乱码 Idea的相关配置都已经调整 字体调整为雅黑 文件编码均调整为UTF-8 调整Idea配置文件 但是还是存在乱码&#xff0c;既然Idea相关配置已经…