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

2.下载插件
用到的是leaflet插件:一个交互式地图 JavaScript 库,我下载是 "leaflet": "^1.9.4"
sql
npm install leaflet
引入到项目
icon是自带的图标
javascript
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为图片本身的尺寸即可
javascript
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,需要设置如下代码
javascript
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上面的这些代码全部都是坐标转换的,就是为了应对原有尺寸和后端尺寸不对应的问题
javascript
// 1. 获取旧图片尺寸(pointArr中保存的width/height)
const oldWidth = obj_.width; // 例如 1036
const 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);
创建点弹窗,弹窗样式自行设计
javascript
const popup = L.popup().setContent('加载中...');
marker.bindPopup(popup);
4.完整代码
javascript
<!--
* @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; // 例如 1036
const 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 message
marker
.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>
文章到此结束,希望对你有所帮助~