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

vue+leaflet笔记之地图量测

vue+leaflet笔记之地图量测

文章目录

  • vue+leaflet笔记之地图量测
    • 开发环境
    • 代码简介
      • 插件简介与安装
      • 使用简介
        • 图形量测
        • 动态量测
    • 详细源码(Vue3)

本文介绍了Web端使用Leaflet开发库进行距离量测的一种方法 (底图来源:天地图),结合leaflet-measure-path插件能够快速的实现地图量测功能。显示效果如下图所示。


开发环境

Vue开发库:3.2.37 & Leaflet开发库:1.9.3

Leaflet主要插件:leaflet-measure-path


代码简介

插件简介与安装

leaflet-measure-path是一个在路径的上显示测量结果的插件(目前支持线、面和圆圈),优点是简单易用,缺点是线要素的长度信息标注在最后一个点的位置觉得不太合理,测量精度的话勉强够用。

官方文档 https://github.com/ProminentEdge/leaflet-measure-path

# 插件安装
npm i leaflet-measure-path
# 插件安装(国内镜像,速度较快)
npm --registry https://registry.npm.taobao.org install leaflet-measure-path
# 引入地图量测插件 leaflet-measure-path
import 'leaflet-measure-path/leaflet-measure-path.css'
import 'leaflet-measure-path/leaflet-measure-path.js'

使用简介

图形量测

创建一些基础图形,然后利用leaflet-measure-path中的方法和属性,对图形进行量测,效果如下图所示 。

// 创建一个矢量面,并显示多边形的测量值
let polygon = L.polygon([[57.69, 11.89], [57.697, 11.88], [57.71, 11.89], [57.71, 11.91], [57.69, 11.91]], { showMeasurements: true }).addTo(map);
// 创建一个矢量面,当光标悬停在多边形上时,显示测量值的多边形
let polygonWithHover = L.polygon([[57.668, 11.89], [57.675, 11.88], [57.688, 11.89], [57.688, 11.91], [57.668, 11.91]], { showMeasurements: true, measurementOptions: { showOnHover: true } }).addTo(map);
// 创建一条折线,并显示测量值(对测量值格式化) 
L.polyline([[57.67, 11.85], [57.677, 11.86], [57.68, 11.85], [57.69, 11.86],],{showMeasurements: true, color: 'green', measurementOptions: {showTotalDistance:false,formatDistance: function valFormat(val) {// 测量值保留一位小数return '测量值:' + val.toFixed(1)}}}).addTo(map);
// 创建一个圆,并显示测量值
let circle = L.circle([57.699, 11.86], {color: 'red',fillColor: '#f03',fillOpacity: 0.5,radius: 300,showMeasurements: true,
}).addTo(map);

此外,measurementOptions还提供了几个别的属性:

属性默认值说明备注
showOnHover: Booleanfalse为true时,当用户将光标悬停在图形上时,测量值才会显示
showTotalDistance: Booleantrue为false时,则不会显示多段线的总长度
minDistance: Number30线段测量时,要素中的线段必须具有的最小长度实测,不生效
formatDistance: Function/覆盖内置函数,该函数以米为单位格式化地图中显示的字符串的距离对显示测量值格式化
formatArea: Function/覆盖内置函数,该函数将面积(平方米)格式化为地图中显示的字符串对显示测量值格式化

动态量测

在地图上动态绘制线或面,进行长度或面积的量测。

详细源码(Vue3)

源代码下载地址 链接:https://pan.baidu.com/s/1axmOSj3cc8ve26_aODISeg?pwd=GIS6
提取码:GIS6

<template><div class="app-contain"><!-- leaflet 地图容器 --><div id="myMap"></div><div class="controls"><el-button color="#626aef" @click="handMeasureDistance()">距离量算</el-button><el-button color="#626aef" @click="handMeasureArea()">面积量算</el-button><el-button color="#626aef" @click="handMeasureClear()">清空</el-button></div></div>
</template><script setup>
// 引入本地标记图片
import deleteIconUrl from '/@/assets/images/deleteIcon.png'
// 引入样式
import L from 'leaflet';
import 'leaflet/dist/leaflet.css'// 鼠标提示控件
import './store/MouseTips'
import './store/MouseTips.css'
// 引入地图量测插件 leaflet-measure-path
import 'leaflet-measure-path/leaflet-measure-path.css'
import 'leaflet-measure-path/leaflet-measure-path.js'
// 标记点
let deleteIcon = L.icon({iconUrl: deleteIconUrl,iconSize: [14, 14], // 图标大小iconAnchor: [7, 7], // 图标偏移量,否则无法居住显示
});
import { onMounted } from 'vue'
// 天地图TK
let tdtKey = 'YOURS_TK'
// 地图
let map = null;
// 创建鼠标提示控件
let mouseTips = L.control.mouseTips({show: true,message: '鼠标单击左键加点,双击结束'
});
// 距离测量方法
let distanceMeasure = {points: [],color: "red",layers: L.layerGroup(),polyline: null,polylineGroup: [],marker: null,markerGroup: [],init: function () {distanceMeasure.points = [];distanceMeasure.polyline = null;distanceMeasure.marker = null;map.on('click', distanceMeasure.click).on('dblclick', distanceMeasure.dblclick);},click: function (e) {map.doubleClickZoom.disable();// 添加点信息distanceMeasure.points.push(e.latlng);// 添加线map.on('mousemove', distanceMeasure.mousemove);},mousemove: function (e) {distanceMeasure.points.push(e.latlng);if (distanceMeasure.polyline)map.removeLayer(distanceMeasure.polyline);distanceMeasure.polyline = L.polyline(distanceMeasure.points, { showMeasurements: true, color: distanceMeasure.color });distanceMeasure.polyline.addTo(distanceMeasure.layers);distanceMeasure.layers.addTo(map);distanceMeasure.points.pop();},dblclick: function (e) { // 双击结束// 移除鼠标绘制提示mouseTips.hide()distanceMeasure.polyline.addTo(distanceMeasure.layers);distanceMeasure.polylineGroup.push(distanceMeasure.polyline)map.off('click', distanceMeasure.click).off('mousemove', distanceMeasure.mousemove).off('dblclick', distanceMeasure.dblclick);},destory: function () {if (distanceMeasure.polyline) {// map.removeLayer(distanceMeasure.polyline);distanceMeasure.polylineGroup.forEach(element => {map.removeLayer(element);});}if (distanceMeasure.marker) {// distanceMeasure.marker.remove();distanceMeasure.markerGroup.forEach(element => {element.remove()})}}
}
// 面积测量方法
let areaMeasure = {points: [],color: "red",layers: L.layerGroup(),polygon: null,polygonGroup: [],marker: null,markerGroup: [],init: function () {areaMeasure.points = [];areaMeasure.polygon = null;areaMeasure.marker = null;map.on('click', areaMeasure.click).on('dblclick', areaMeasure.dblclick);},close: function (latlng) {areaMeasure.marker = L.marker(latlng, { icon: deleteIcon }).addTo(map).on("click", function (e) {if (areaMeasure.polygon)map.removeLayer(areaMeasure.polygon);if (areaMeasure.marker)areaMeasure.marker.remove();});areaMeasure.markerGroup.push(areaMeasure.marker);},click: function (e) {map.doubleClickZoom.disable();// 添加点信息areaMeasure.points.push(e.latlng);// 添加面map.on('mousemove', areaMeasure.mousemove);},mousemove: function (e) {areaMeasure.points.push(e.latlng);if (areaMeasure.polygon)map.removeLayer(areaMeasure.polygon);areaMeasure.polygon = L.polygon(areaMeasure.points, { showMeasurements: true, color: areaMeasure.color });areaMeasure.polygon.addTo(areaMeasure.layers);areaMeasure.layers.addTo(map);areaMeasure.points.pop();},dblclick: function (e) { // 双击结束// 移除鼠标绘制提示mouseTips.hide()areaMeasure.polygon.addTo(areaMeasure.layers);areaMeasure.polygonGroup.push(areaMeasure.polygon)areaMeasure.close(e.latlng);map.off('click', areaMeasure.click).off('mousemove', areaMeasure.mousemove).off('dblclick', areaMeasure.dblclick);},destory: function () {if (areaMeasure.polygon) {areaMeasure.polygonGroup.forEach(element => {map.removeLayer(element);});}if (areaMeasure.marker) {areaMeasure.markerGroup.forEach(element => {element.remove()})}}
}
// 地图初始化
const initMap = () => {//影像地图const sourceMap = L.tileLayer(`https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}`)// 注记const tiandituText = L.tileLayer(`http://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tdtKey}`)const layers = L.layerGroup([sourceMap, tiandituText])map = L.map('myMap', {  //需绑定地图容器div的idattributionControl: false,zoomControl: true, // 显示缩放控件// 最小显示等级minZoom: 1,// 最大显示等级maxZoom: 18,crs: L.CRS.EPSG3857,//设置坐标系类型  EPSG3857伪墨卡托投影scrollWheelZoom: true, //默认开启鼠标滚轮缩放// 限制显示地理范围maxBounds: L.latLngBounds(L.latLng(-90, -180), L.latLng(90, 180)),// 限制显示地理范围layers: [layers] // 图层}).setView([30, 120], 6)// 添加比例尺L.control.scale({ maxWidth: 240, metric: true, imperial: false, position: 'bottomleft' }).addTo(map);
}
// 距离量测
const handMeasureDistance = () => {// 鼠标绘制提示mouseTips.addTo(map).show();distanceMeasure.init()
}
// 面积量测
const handMeasureArea = () => {// 鼠标绘制提示mouseTips.addTo(map).show();areaMeasure.init()
}
// 清空量测内容
const handMeasureClear = () => {// 鼠标绘制提示mouseTips.addTo(map).hide();// 销毁测量组件distanceMeasure.destory()areaMeasure.destory()
}
onMounted(() => {initMap()
})
</script><style scoped>
#myMap {width: 94vw;height: 96vh;
}.controls {position: absolute;top: 0px;left: 200px;padding: 15px;z-index: 1000;
}
</style>

相关文章:

vue+leaflet笔记之地图量测

vueleaflet笔记之地图量测 文章目录 vueleaflet笔记之地图量测开发环境代码简介插件简介与安装使用简介图形量测动态量测 详细源码(Vue3) 本文介绍了Web端使用Leaflet开发库进行距离量测的一种方法 (底图来源:天地图)&#xff0c;结合leaflet-measure-path插件能够快速的实现地…...

“深入理解SpringBoot:从入门到精通的几个关键要点“

标题&#xff1a;深入理解Spring Boot&#xff1a;从入门到精通 摘要&#xff1a;本文将深入探讨Spring Boot的关键要点&#xff0c;帮助读者从入门到精通。我们将从Spring Boot的基本概念开始&#xff0c;介绍自动配置、起步依赖、注解驱动开发等特性&#xff0c;并通过示例代…...

数值线性代数: 共轭梯度法

本文总结线性方程组求解的相关算法&#xff0c;特别是共轭梯度法的原理及流程。 零、预修 0.1 LU分解 设&#xff0c;若对于&#xff0c;均有&#xff0c;则存在下三角矩阵和上三角矩阵&#xff0c;使得。 设&#xff0c;若对于&#xff0c;均有&#xff0c;则存在唯一的下三…...

【JVM】详解对象的创建过程

文章目录 1、创建对像的几种方式1、new关键字2、反射3、clone4、反序列化 2、创建过程步骤 1、检查类是否已经被加载步骤 2、 为对象分配内存空间1、指针碰撞针对指针碰撞线程不安全&#xff0c;有两种方案&#xff1a; 2、空闲列表选择哪种分配方式 步骤3、将内存空间初始化为…...

华纳云:ubuntu下如何搭建nfs服务

在Ubuntu下搭建NFS(Network File System)服务&#xff0c;可以实现网络文件共享。以下是在Ubuntu上搭建NFS服务的步骤&#xff1a; 安装NFS服务器和客户端软件&#xff1a; 打开终端&#xff0c;并使用以下命令安装NFS服务器和客户端软件&#xff1a; sudo apt-get update s…...

HCIA实验二

实验要求&#xff1a; 1.R2为ISP&#xff0c;只能配置IP 2.R1-R2之间为HDLC封装 3.R2-R3之间为PPP封装&#xff0c;pap认证&#xff0c;R2为主认证方 4.R2-R4之间为PPP封装&#xff0c;chap认证&#xff0c;R2为主认证方 5.R1、R2、R3构建MGRE&#xff0c;仅R1的IP地址固定…...

stm32 舵机 cubemx

文章目录 前言一、cubemx配置二、代码1.serve.c2.serve.h3.主函数 总结 前言 stm32对舵机进行控制&#xff0c;很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此&#…...

无涯教程-jQuery - Spinner组件函数

Widget Spinner 函数可与JqueryUI中的窗口小部件一起使用。Spinner提供了一种从一组中选择一个值的快速方法。 Spinner - 语法 $( "#menu" ).selectmenu(); Spinner - 示例 以下是显示Spinner用法的简单示例- <!doctype html> <html lang"en"…...

Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘

Python 有趣的模块之pynupt ——通过pynput控制鼠标和键盘 文章目录 Python 有趣的模块之pynupt ——通过pynput控制鼠标和键盘1️⃣简介2️⃣鼠标控制与移动3️⃣键盘控制与输入4️⃣结语&#x1f4e2; 1️⃣简介 &#x1f680;&#x1f680;&#x1f680;学会控制鼠标和键盘是…...

docker基于centos7镜像安装python3.7.9

下载centos7镜像 docker pull centos&#xff1a;centos7 启动容器centos-python-3.7 docker run -itd --name centos-python-3.7 -p 60021:22 --privileged centos:centos7 /usr/sbin/init 进入容器 docker exec -it centos-python-3.7 /bin/bash centos7环境下安装python3.7.…...

JavaScript中的switch语句

switch语句和if语句一样&#xff0c;同样是运用于条件循环中&#xff1b; 下面例子我们用switch实现 例如如果今天是周一就学习HTML&#xff0c;周二学习CSS和JavaScript&#xff0c;周三学习vue&#xff0c;周四&#xff0c;周五学习node.js&#xff0c;周六周日快乐玩耍&…...

Jquery笔记

DOM对象通过jquery获取 所有的代码都是基于引入jquery.js文件 var mydiv $(#div);//直接获取到DOM对象元素id var mydiv$(.div)&#xff1b;//通过class获取DOM对象&#xff0c;如果有同名class只会获取第一个 var mysapn$(span);//通过元素的标签名获取DOM对象 var divarr$(…...

【C++】优先级队列的基本概念以及其模拟实现

文章目录 补充知识&#xff1a;仿函数一、优先级队列&#xff1a;1.引入2.介绍 二、priority_queue的模拟实现1.大体框架2.私有成员函数&#xff1a;1.向下调整&#xff08;AdjustDown&#xff09;2.向上调整&#xff08;AdjustUp&#xff09; 3.公有成员函数1大小&#xff08;…...

TextClamp for Vue3.0(Vue3.0的文本展开收起组件)

呦&#xff01;大家好&#xff0c;好久没有更新博客了&#xff0c;最近实现了一个一直想自己完成的一个东西&#xff0c;就是文本的展开收起组件&#xff0c;以前项目需要用到&#xff0c;自己实现一个又太繁琐&#xff0c;所以那个时候都是用的别人的轮子&#xff0c;现在自己…...

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 目录 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 VAR(Vector Autoregression)模型是一种广泛应用于时…...

在 Windows 上搭建 NTP 服务器

文章目录 一、基础环境二、适用场景三、操作步骤四、常用的NTP服务器五、参考资料 版权声明&#xff1a;本文为博主原创文章&#xff0c;于2023年7月30日首发于CSDN&#xff0c;转载请附上原文出处链接和本声明。本文链接&#xff1a;https://blog.csdn.net/u011046671 一、基础…...

应急响应经典案例-FTP 暴力破解

应急响应经典案例-FTP 暴力破解 应急场景日志分析应急处理措施 应急场景 从昨天开始&#xff0c;网站响应速度变得缓慢&#xff0c;网站服务器登录上去非常卡&#xff0c;重启服务器就能保证一段时间的正常访问&#xff0c;网站响应状态时而飞快时而缓慢&#xff0c;多数时间是…...

41. linux通过yum安装postgresql

文章目录 1.下载安装包2.关闭内置PostgreSQL模块:3.安装postgresql服务:4.初始化postgresql数据库:5.设置开机自启动:6.启动postgresql数据库7.查看postgresql进程8.通过netstat命令或者lsof 监听默认端口54329.使用find命令查找了一下postgresql.conf的配置位置10.修改postgre…...

SpringBoot启动流程及自动配置

SpringBoot启动流程源码&#xff1a; 1、启动SpringBoot启动类SpringbootdemoApplication中的main方法。 SpringBootApplication public class SpringbootdemoApplication {public static void main(String[] args) {SpringApplication.run(SpringbootdemoApplication.class, …...

【Linux】进程轻松入门

目录 一&#xff0c; 冯* 诺依曼体系结构 1&#xff0c;存储结构 ​编辑 二&#xff0c; 操作系统 1&#xff0c;概念 2&#xff0c;设计OS的目的 3&#xff0c;定位 4&#xff0c;如何理解 "管理" 5&#xff0c; 总结 三&#xff0c;进程 1. 概念 那么…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...