当前位置: 首页 > news >正文

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位

 效果:点击表格可实现选中地图点位,删除按钮点击可删除对应点位并且重新绘制线段,点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 

 

 完整的组件代码如下  文件名称为:

leafletMakePointYt
<!--* @Description: leaflet 地图选择点位 实现画线 页面* @Author: mhf* @Date: 2023-05-30 18:23:37
-->
<template><el-dialogwidth="1300px"append-to-bodyv-dialog-outv-if="dialogVisible":title="title":visible.sync="dialogVisible":close-on-click-modal="false":before-close="hideDialog"><div><!-- 地图盒子 --><div id="map"></div><!-- 左侧坐标展示框 --><div class="points-box"><!-- 顶部标题 --><div class="points-box-title"><span> 线路坐标 </span></div><!-- 坐标展示表 --><div class="points-box-table"><el-tablehighlight-current-row@current-change="handleCurrentChange":data="pointsArr"style="width: 100%":height="tableHeight"><el-table-column label="#" type="index" /><el-table-column prop="lat" label="经度" width="158" /><el-table-column prop="lng" label="纬度" width="158" /><el-table-columnlabel="操作"width="60"fixed="right"v-if="showBtn"><template slot-scope="scope"><el-button type="text" size="small" @click="delRow(scope)">删除</el-button></template></el-table-column></el-table></div><!-- 坐标盒子 底部按钮组 --><div v-if="showBtn" class="points-box-btn"><el-button type="" size="" @click="clearMapLine"> 清除</el-button><el-button type="primary" size="" @click="makeMapLine">开始</el-button><el-button type="primary" size="" @click="endMakeLine">结束</el-button></div></div></div><!-- 弹窗底部按钮组 --><div v-if="showBtn" slot="footer" class="dialog-footer"><el-button @click="hideDialog">取 消</el-button><el-button type="primary" @click="submitPoints()">确 定</el-button></div></el-dialog>
</template><script>
import L from "leaflet";
import "leaflet/dist/leaflet.css";
//  引入互联网地图插件
require("@/utils/leftletMap/leaflet.ChineseTmsProviders.js");
require("@/utils/leftletMap/tileLayer.baidu.js");
// 引入互联网地图纠偏插件
require("@/utils/leftletMap/leaflet.mapCorrection.min.js");export default {name: "leafletMakePointYt",components: {},props: {showBtn: {type: Boolean,default: true,},},data() {return {dialogVisible: false,title: "",map: null,iconStyle: {icon: L.icon({iconUrl: require("/public/img/mapIcon/point.png"),iconSize: [12, 12],// iconAnchor: [19, 19],// popupAnchor: [0, -10]}),}, // 点位图标样式chooseIconStyle: {icon: L.icon({iconUrl: require("/public/img/mapIcon/marker.png"),iconSize: [30, 30],iconAnchor: [18, 22],}),}, // 表格中选中的点位图标样式startIconStyle: {icon: L.icon({iconUrl: require("/public/img/mapIcon/startPoint.png"),iconSize: [30, 30],iconAnchor: [18, 22],}),}, // 起点点位图标样式endIconStyle: {icon: L.icon({iconUrl: require("/public/img/mapIcon/endPoint.png"),iconSize: [30, 30],iconAnchor: [18, 22],}),}, // 终点点位图标样式polylineStyle: {color: "#FF6B00",weight: 4,}, // 线条样式pointsArr: [], // 标记点位列表 [{lat: 30, lng: 120}, {lat: 31, lng: 121}]pointsArrMarker: [], // 已经绘制的点位polylineArr: [], // 已经绘制多条线段chooseMarker: undefined, // 当前选中的点位tableHeight: 440,loading: false, // loading 动画loadingInstance: null,};},methods: {hideDialog() {this.dialogVisible = false;this.map.remove();this.map = null;},submitPoints() {if (this.pointsArr.length < 2) {this.$message.warning("请先绘制线路");} else {this.$emit("on-response", this.pointsArr); // 将绘制好的坐标传递给父组件this.hideDialog();}},showDialog(data) {this.dialogVisible = true;this.title = data.title;this.$nextTick(() => {/* 避免重复渲染 */if (!this.map) this.initMap();this.handleResize();if (data.data) {this.pointsArr = JSON.parse(data.data);/* 线段回显 */var polyline = L.polyline(this.pointsArr, this.polylineStyle).addTo(this.map);this.polylineArr.push(polyline);/* 点位回显 */this.pointsArr.forEach((item, index) => {var marker = L.marker([item.lat, item.lng], this.iconStyle).addTo(this.map); // 添加标记点this.pointsArrMarker.push(marker);});}});},/*** @Event 方法* @description: 初始化 leaflet 地图* */initMap() {this.map = L.map("map", {center: [30.194637, 120.122247],zoom: 13,attributionControl: false, // 隐藏logozoomControl: false, // 默认缩放控件(仅当创建地图时该 zoomControl 选项是 true)。crs: L.CRS.Baidu, // 用于 WMS 请求的坐标参考系统,默认为映射 CRS。 如果您不确定它的含义,请不要更改它。});L.control.zoom({position: "bottomright",}).addTo(this.map);L.tileLayer.baidu({ layer: "vec" }).addTo(this.map); // 添加底图},/*** @Event 方法* @description: 开始画线* */makeMapLine() {this.map.getContainer().style.cursor = "crosshair"; // 更改鼠标样式// let index = -1var marker, polyline;this.map.on("click", (e) => {// index++// if (index === 0) {/* 设置起点 */// L.marker([e.latlng.lat, e.latlng.lng], this.startIconStyle).addTo(this.map);/* 设置起点 */// } else {marker = L.marker([e.latlng.lat, e.latlng.lng], this.iconStyle).addTo(this.map); // 添加标记点// }this.pointsArrMarker.push(marker);this.pointsArr.push(e.latlng); // 添加点位坐标至点位数组polyline = L.polyline(this.pointsArr, this.polylineStyle).addTo(this.map); // 创建单条线段this.polylineArr.push(polyline);});},/*** @Event 方法* @description: 结束画线* */endMakeLine() {if (this.pointsArr === [] || this.pointsArr.length === 0) {this.$message.warning("请先绘制线路");} else {this.map.getContainer().style.cursor = "grab"; // 更改鼠标样式this.map.fitBounds(this.polylineArr[this.polylineArr.length - 1].getBounds()); // 缩放地图以适应标记和线条this.map.on("mousedown", (e) => {this.map.getContainer().style.cursor = "grabbing"; // 更改鼠标样式});this.map.on("mouseup", (e) => {this.map.getContainer().style.cursor = "grab"; // 更改鼠标样式});this.map.off("click"); // 关闭点击事件}},/*** @Event 方法* @description: 移除线段和点位* */clearMapLine() {if (this.pointsArr === [] || this.pointsArr.length === 0) {} else {/* 移除点位 */this.pointsArrMarker.forEach((marker) => {this.map.removeLayer(marker);});/* 移除线段 */this.polylineArr.forEach((polyline) => {polyline.remove();});this.endMakeLine(); // 结束画线this.polylineArr = [];this.pointsArr = [];}},/*** @Event 方法* @description: 动态改变表格的高度* */handleResize() {const height = document.querySelector(".points-box-table").offsetHeight;this.tableHeight = height - 10;},/*** @Event 方法* @description: 表格单行选中事件,实现每次点击时都能删除上一次点击的图标* */handleCurrentChange(row) {if (this.chooseMarker) {this.map.removeLayer(this.chooseMarker);}this.chooseMarker = L.marker([row.lat, row.lng],this.chooseIconStyle).addTo(this.map); // 添加标记点},/*** @Event 方法* @description: 删除表格单行数据并且移除该点位* */delRow(row) {this.loading = true;this.$nextTick(() => {const target = document.querySelector(".el-dialog__body");let options = {lock: true,text: "重新绘制中...",spinner: "el-icon-loading",background: "rgba(0, 0, 0, 0.7)",};this.loadingInstance = this.$loading(options, target);});setTimeout(() => {this.loading = false;this.loadingInstance.close();/* 删除点位 */this.map.removeLayer(this.pointsArrMarker[row.$index]);this.pointsArrMarker.splice(row.$index, 1); // 已经绘制的点位this.pointsArr.splice(row.$index, 1); // 标记点位列表/* 删除点位 *//* 删除线段 */this.polylineArr.forEach((polyline) => {polyline.remove();});var polyline = L.polyline(this.pointsArr, this.polylineStyle).addTo(this.map);this.polylineArr.push(polyline);/* 删除线段 */}, 500);},},created() {},mounted() {window.addEventListener("resize", this.handleResize);},destroyed() {window.removeEventListener("resize", this.handleResize);},
};
</script><style lang="scss" scoped>
.dialog-footer {text-align: center;
}#map {height: 68vh;
}.points-box {width: 426px;height: 570px;position: absolute;top: 100px;z-index: 99999 !important;background-color: #fff;left: 40px;&-title {height: 40px;background-color: #1492ff;font-size: 18px;color: #ffffff;line-height: 40px;padding: 0 20px;}&-table {height: 490px;}&-btn {height: 50px;position: absolute;padding-bottom: 18px;bottom: 0;left: 0;right: 0;margin: auto;width: 80%;display: flex;justify-content: space-around;align-items: center;}
}
</style>
<el-form-item label="线路轨迹 : " prop="assetSection.point"><el-inputv-model="formData.assetSection.point"disabledplaceholder=""><template slot="append"><div class="choose-class" @click="showLeafletMap"><i class="iconfont if-ditudingwei" /> <span>选择</span></div></template></el-input></el-form-item><leafletMakePointYt ref="leafletMakePointYt" @on-response="getPoints" />// 打开弹窗 showLeafletMap() {let passData = {title: "选择线路轨迹",data: this.formData.assetSection.point,};this.$refs.leafletMakePointYt.showDialog(passData);},// passData: {
title: "选择线路轨迹",
data: "[{"lat":30.19398904706604,"lng":120.1454230189172},{"lat":30.204226626758985,"lng":120.19285355280543},{"lat":30.22270148713875,"lng":120.13162504542244},{"lat":30.189494160206575,"lng":120.15490912569484}]"
}// 接收弹窗的点位数据getPoints(data) {this.$set(this.formData.assetSection, "point", JSON.stringify(data));this.$set(this.formData.assetSection, "startLongitude", data[0].lng);this.$set(this.formData.assetSection, "startLatitude", data[0].lat);this.$set(this.formData.assetSection,"endLongitude",data[data.length - 1].lng);this.$set(this.formData.assetSection,"endLatitude",data[data.length - 1].lat);},

相关文章:

Vue实现leafletMap自定义绘制线段 并且删除指定的已绘制的点位

效果&#xff1a;点击表格可实现选中地图点位&#xff0c;删除按钮点击可删除对应点位并且重新绘制线段&#xff0c;点击确定按钮 保存已经绘制的点位信息传给父组件 并且该组件已实现回显 完整的组件代码如下 文件名称为&#xff1a; leafletMakePointYt <!--* Descripti…...

ChatGPT辅助写论文:提升效率与创造力的利器

写作是人类最重要的交流方式之一&#xff0c;也是学术研究中不可或缺的环节。然而&#xff0c;写作并不是一件容易的事情&#xff0c;尤其是对于科研人员来说&#xff0c;他们需要花费大量的时间和精力来撰写高质量的论文&#xff0c;并且面临着各种各样的挑战&#xff0c;如语…...

面试攻略,Java 基础面试 100 问(六)

JAVA 泛型 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许程序员在编译时检测到非法的类型。泛型的本 质是参数化类型&#xff0c;也就是说所操作的数据类型被指定为一个参数。比如我们要写一个排序方法&#xff0c; 能够对整型数组、字符串数组甚至其他任何类型的…...

图解系列 DNS查找过程和DNS缓存

DNS 充当地址簿。它将人类可读的域名 (google.com) 转换为机器可读的 IP 地址 (142.251.46.238)。 开局一张图 来自&#xff1a;https://xiaolishen.medium.com/the-dns-lookup-journey-240e9a5d345c 寻址流程 查询浏览器缓存&#xff1a;当你输入一个域名后&#xff0c;浏览…...

《吐血整理》高级系列教程-吃透Fiddler抓包教程(21)-如何使用Fiddler生成Jmeter脚本-上篇

1.简介 我们知道Jmeter本身可以录制脚本&#xff0c;也可以通过BadBoy&#xff0c;BlazeMeter等工具进行录制&#xff0c;其实Fiddler也可以录制Jmter脚本&#xff08;而且有些页面&#xff0c;由于安全设置等原因&#xff0c;使用Jmeter直接无法打开录制时&#xff0c;这时就…...

vim中出现复制不对齐-乱码问题

不对齐解决&#xff1a; 使用纯文本模式粘贴&#xff1a;在进入 Vim 编辑器后&#xff0c;先按下 :set paste 进入插入模式&#xff0c;然后再进行粘贴操作。这样可以确保粘贴的文本以纯文本格式插入&#xff0c;而不会触发自动缩进或其他格式化操作 中文乱码问题&#xff1a;…...

华为OD机考真题--单词接龙--带答案

2023华为OD统一考试&#xff08;AB卷&#xff09;题库清单-带答案&#xff08;持续更新&#xff09;or2023年华为OD真题机考题库大全-带答案&#xff08;持续更新&#xff09; 题目描述&#xff1a; 单词接龙的规则是&#xff1a; 用于接龙的单词首字母必须要前一个单词的尾字母…...

排序进行曲-v3.0

文章目录 小程一言归并排序步骤举例总结时间复杂度分析&#xff1a;空间复杂度分析&#xff1a;注意 应用场景总结 实际举例Other 代码实现结果解释 小程一言 这篇文章是在排序进行曲2.0之后的续讲&#xff0c; 这篇文章主要是对归并排序进行细致分析&#xff0c;以及操作。 希…...

编辑列表操作时的一些思考,关于全量和增量操作

假设我有一个这样的页面&#xff0c;需要对用户的信息做编辑操作 角色下面有一些菜单项&#xff0c;通过一张角色-菜单关系表来维护&#xff0c;那么我要在编辑用户后也要对用户角色关系表做修改&#xff0c;是经过两次比较分别计算出需要增加或者删除的角色用户关系&#xff0…...

【python】Python tkinter库实现重量单位转换器的GUI程序

文章目录 前言学到什么?导入模块和库创建一个GUI窗口定义函数 from_kg()创建标签、输入框、文本框和按钮设置组件的布局运行窗口循环完整代码运行效果结束语 前言 这段代码是一个简单的重量单位转换器的 GUI 程序&#xff0c;使用了 Python 的 tkinter 库来创建图形界面。该程…...

CVPR2023新作:源数据集对迁移学习性能的影响以及相应的解决方案

Title: A Data-Based Perspective on Transfer Learning (迁移学习的基于数据的观点) Affiliation: MIT (麻省理工学院) Authors: Saachi Jain, Hadi Salman, Alaa Khaddaj, Eric Wong, Sung Min Park, Aleksander Mądry Keywords: transfer learning, source dataset, dow…...

《TCP IP 网络编程》第十五章

第 15 章 套接字和标准I/O 15.1 标准 I/O 的优点 标准 I/O 函数的两个优点&#xff1a; 除了使用 read 和 write 函数收发数据外&#xff0c;还能使用标准 I/O 函数收发数据。下面是标准 I/O 函数的两个优点&#xff1a; 标准 I/O 函数具有良好的移植性标准 I/O 函数可以利用…...

新特性解读 | MySQL 8.0 字段信息统计机制

作者通过一个案例详细说明了 MySQL 8.0 字段信息统计机制的相关参数和使用方式。 作者&#xff1a;杨奇龙 网名“北在南方”&#xff0c;资深 DBA&#xff0c;主要负责数据库架构设计和运维平台开发工作&#xff0c;擅长数据库性能调优、故障诊断。 本文来源&#xff1a;原创投…...

基于Java+Swing实现超级玛丽游戏

基于JavaSwing实现超级玛丽游戏 一、系统介绍二、功能展示三、其他系统 一、系统介绍 超级玛丽小游戏的JAVA程序&#xff0c;进入游戏后首先按空格键开始&#xff0c;利用方向键来控制的马里奥的移动&#xff0c;同时检测马里奥与场景中的障碍物和敌人的碰撞&#xff0c;并判断…...

Day12-1-Webpack前端工程化开发

Webpack前端工程化 1 案例-webpack打包js文件 1 在index.html中编写代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><me…...

JUnit教程_编程入门自学教程_菜鸟教程-免费教程分享

教程简介 JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立&#xff0c;逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。JUnit是由 Erich Gamma 和…...

Hive 安装介绍

介绍 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能。 其本质是将SQL转换为MapReduce的任务进行运算&#xff0c;底层由HDFS来提供数据的存储&#xff0c;说白了hive可以理解为一个将SQL转换为Ma…...

npm ERR! code EPERM npm ERR! syscall unlink npm ERR!错误解决方法

npm ERR! code EPERM npm ERR! syscall unlink npm ERR!错误解决方法 1、问题描述2、解决方法 1、问题描述 由于之前电脑系统的原因&#xff0c;电脑重置了一下&#xff0c;之前安装的环境都没了&#xff0c;然后在重新安装node.js后在使用npm安装时总是报如下错误&#xff1a…...

redis 高级篇4 分布式锁

一 redis架构图 1.1 redis的架构图 1.2 分布式锁满足条件 1.独占性&#xff1b;2.高可用&#xff1b;3.防死锁&#xff1b;4.不乱抢&#xff1b;5.重入性 二 分布式锁的案例情况 2.1 分布式锁1:单机分布式部署 描述&#xff1a; 使用lock锁和synchronized&#xff0c;单机…...

TPU-NNTC 编译部署LPRNet 车牌识别算法

TPU-NNTC 编译部署LPRNet 车牌识别算法 注意&#xff1a; 由于SOPHGO SE5微服务器的CPU是基于ARM架构&#xff0c;以下步骤将在基于x86架构CPU的开发环境中完成 初始化开发环境(基于x86架构CPU的开发环境中完成)模型转换 (基于x86架构CPU的开发环境中完成) 处理后的LPRNet 项…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...