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

vue2通过leaflet实现图片点位回显功能

需求:在图片上标点了,需要根据标记点在图片上进行回显功能,并且不会根据窗口大小导致标记点移位

1.效果

2.下载插件

用到的是leaflet插件:一个交互式地图 JavaScript 库,我下载是  "leaflet": "^1.9.4"

npm install leaflet

引入到项目

icon是自带的图标

import icon from 'leaflet/dist/images/marker-icon.png';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';

3.主要代码详解

图片加载后需要创建map对象,注意!!如果后端传的点数据是根据图片原有大小比如图片尺寸800*800,x:20,y:20,就是在800像素上的xy的值那么直接设置leftmap的unproject为图片本身的尺寸即可

​var south_west = that.leftMap.unproject([0, img_original_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width, 0], 1);​

如果图片原尺寸为800*800,后端传来尺寸为400*400,x:10,y:10,需要设置如下代码

      var style = window.getComputedStyle(document.getElementById("roc_map"));var map_height = parseFloat(style.height);     var south_west = that.leftMap.unproject([0, map_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width / this_ratio, 0],1);

创建点:draggable:是否拖拽L.marker上面的这些代码全部都是坐标转换的,就是为了应对原有尺寸和后端尺寸不对应的问题

        // 1. 获取旧图片尺寸(pointArr中保存的width/height)const oldWidth = obj_.width; // 例如 1036const oldHeight = obj_.height; // 例如 582// 3. 根据地理边界 this_bounds 计算实际的地理坐标const boundsWidth = this_bounds.getEast() - this_bounds.getWest();const boundsHeight = this_bounds.getNorth() - this_bounds.getSouth();const lng = this_bounds.getWest() + (boundsWidth / oldWidth) * obj_.x;const lat = this_bounds.getNorth() - (+boundsHeight / oldHeight) * obj_.y; // Y轴取反const DefaultIcon = L.icon({iconUrl: icon,iconAnchor: [10, 41]});// 4. 创建标记点(Leaflet的Y轴需要取反)const marker = L.marker([lat, lng], {draggable: false,title: obj_.name,icon: DefaultIcon}).addTo(that.leftMap);

创建点弹窗,弹窗样式自行设计

   const popup = L.popup().setContent('加载中...');marker.bindPopup(popup);

4.完整代码

<!--* @Description:* @Author: 请叫我欧皇!* @Date: 2025-04-28 14:58:23* @FilePath: \vue-secondMenu-test-master\src\page\test4\zongti\02.leftjs.vue
-->
<template><div class="leaflet-box"><div id="roc_map" class="map"></div></div>
</template><script>
import icon from 'leaflet/dist/images/marker-icon.png';
import * as L from 'leaflet';
import 'leaflet/dist/leaflet.css';
export default {data() {return {pointArr: [{x: 80,y: 50,name: '测试111',group: ['测试111'],point_id: 1,sn: '123456789',width: 800,height: 572},{x: 200,y: 0,name: '测试222',group: ['测试222'],point_id: 2,sn: '123456789',width: 800,height: 572},{x: 200,y: 200,name: '测试333',group: ['测试222'],point_id: 3,sn: '123456789',width: 800,height: 572}],leftMap: null};},mounted() {this.initLeaflet();},methods: {initLeaflet() {let that = this;let pointArr = this.pointArr;var mark_map = {};var this_img = new Image();let imgs = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg';// this_img.src = "../images/01.jpg";this_img.src = imgs;this_img.onload = function () {var img_original_width = this_img.width,img_original_height = this_img.height;// 在初始化地图前检查是否已存在地图实例if (that.leftMap) {that.leftMap.remove(); // 移除旧地图that.leftMap = null;}that.leftMap = new L.Map('roc_map', {minZoom: 1,maxZoom: 4,center: [0, 0],zoom: 1,crs: L.CRS.Simple,zoomControl: false,attributionControl: false// zoomControl: false, // 禁用默认的缩放控件});var south_west = that.leftMap.unproject([0, img_original_height], 1); //西南var north_east = that.leftMap.unproject([img_original_width, 0], 1);var this_bounds = new L.LatLngBounds(south_west, north_east);L.imageOverlay(imgs, this_bounds).addTo(that.leftMap);that.leftMap.fitBounds(this_bounds);init_p();//   init_grid_2();function init_p() {for (var i = 0; i < pointArr.length; i++) {let obj_ = pointArr[i];// 1. 获取旧图片尺寸(pointArr中保存的width/height)const oldWidth = obj_.width; // 例如 1036const oldHeight = obj_.height; // 例如 582// 3. 根据地理边界 this_bounds 计算实际的地理坐标const boundsWidth = this_bounds.getEast() - this_bounds.getWest();const boundsHeight = this_bounds.getNorth() - this_bounds.getSouth();const lng = this_bounds.getWest() + (boundsWidth / oldWidth) * obj_.x;const lat = this_bounds.getNorth() - (+boundsHeight / oldHeight) * obj_.y; // Y轴取反const DefaultIcon = L.icon({iconUrl: icon,iconAnchor: [10, 41]});// 4. 创建标记点(Leaflet的Y轴需要取反)const marker = L.marker([lat, lng], {draggable: false,title: obj_.name,icon: DefaultIcon}).addTo(that.leftMap);const popup = L.popup().setContent('加载中...');marker.bindPopup(popup);// 最新监测时间:2025-12-23 00:00:00 累计变化量X:1234.45mm 累计变化量Y:12345.567mm// .bindPopup(that.getBindPopup(obj_))marker.on('click', async function (e) {that.sendPointInfo = { ...obj_ };// Show loading messagemarker.bindPopup("<div style='width:260px;height:150px;font-size:12px' class='popup'>加载中...</div>").openPopup();try {const popupContent = `<div style='width:260px;height:150px;font-size:13px' class='popup'><div class="title">点编号:${obj_.name}</div><ul><li>sn:${obj_.sn}</li></ul></div>`;popup.setContent(popupContent);//                             }} catch (error) {popup.setContent('请求数据时出错');}});mark_map[obj_.point_id] = marker;}}};}}
};
</script><style lang="scss" scoped>
.leaflet-box {width: 100%;height: 800px;.map {width: 50%;height: 70%;margin: 40px;}
}
</style>

文章到此结束,希望对你有所帮助~

http://www.lryc.cn/news/572697.html

相关文章:

  • Fiddler抓包工具使用技巧:如何结合Charles和Wireshark提升开发调试效率
  • OpenCV C++ 边缘检测与图像分割
  • NY339NY341美光固态闪存NW841NW843
  • 【VUE】某时间某空间占用情况效果展示,vue2+element ui实现。场景:会议室占用、教室占用等。
  • PVE使用ubuntu-cloud-24.img创建虚拟机并制作模板
  • NVIDIA开源Fast-dLLM!解析分块KV缓存与置信度感知并行解码技术
  • 旋转图像C++
  • json.Unmarshal精度丢失问题分析
  • vue3组件式开发示例
  • 大模型与搜索引擎的技术博弈及未来智能范式演进
  • MySQL查询语句的通配符*
  • 组态王工程运行时间显示
  • 【案例拆解】米客方德 SD NAND 在车联网中(有方模块)的应用:破解传统 TF 卡振动脱落与寿命短板
  • 在VTK中捕捉体绘制图像进阶(同步操作)
  • 零基础入门PCB设计 一实践项目篇 第三章(STM32开发板原理图设计)
  • 云计算处理器选哪款?性能与能效的平衡艺术
  • 【网络安全】文件上传型XSS攻击解析
  • 特征金字塔在Vision Transformer中的创新应用:原理、优势与实现分析
  • AS32系列MCU芯片I2C模块性能解析与调试
  • 408第二季 - 组成原理 - 流水线
  • Linux之线程同步与互斥
  • Rust 学习笔记:Unsafe Rust
  • 使用 .NET Core 8.0 和 SignalR 构建实时聊天服务
  • OPENPPP2 VMUX 技术探秘(高级指南)
  • 北京京东,看看难度
  • 解锁决策树:数据挖掘的智慧引擎
  • ffmpeg 给视频画圆圈
  • Electron (02)集成 SpringBoot:服务与桌面程序协同启动方案
  • 大白话说目标检测中的IOU(Intersection over Union)
  • Maven并行构建