优秀的编程知识分享平台

网站首页 > 技术文章 正文

leaflet地图截图批量导出(leaflet地图旋转)

nanyue 2024-10-10 07:28:14 技术文章 5 ℃

前言

leaflet 入门开发系列环境知识点了解:

leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等leaflet 在线例子leaflet 插件,leaflet 的插件库,非常有用

内容概览

leaflet地图截图批量导出
源代码demo下载

效果图如下:

具体实现思路:
打开csv文件,读取点数据源经纬度,循环遍历数据源,以经纬度为中心,构造1000*1000屏幕像素值的正方形范围,批量截图,最后压缩导出。

  • 核心代码,完整源码见尾部下载
var map = null; //地图对象
var marker = null;
var packageName = '打包下载'; // 打包文件名称
var zip = new JSZip();
var baseList = []; // base64格式图片列表
var imgNameList = []; // 图片名称列表
var points = []; //经纬度点列表
var filePath = null;
var loading;
// [113.6250387, 22.6713741], [113.64075074, 22.68880195], [113.53854455, 22.78899001], [113.52453318, 22.79709604]]; // 经纬度点列表
var node = document.getElementById('map');
// 打开文件按钮点击事件
$("input[type='file']").change(function () {
var file = this.files[0];
if (window.FileReader) {
var reader = new FileReader();
reader.readAsDataURL(file);
//监听文件读取结束后事件
reader.onloadend = function (e) {
filePath = e.target.result;
console.log('文件路径:' + e.target.result);
// 读取文件数据处理中……
loading = Qmsg.loading("读取文件数据处理中……");
openFile();
};
}
});
// 导出图片按钮点击事件
$("#mapexport_btn").click(function () {
goScreenshotMap2Img();
});
// 地图初始化
initMap();

// 地图初始化加载
function initMap() {
map = L.map('map');
L.tileLayer('http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', { subdomains: ["1", "2", "3", "4"], crossOrigin: true }).addTo(map);
map.setView([22.83883628, 113.50329857], 16); //设置缩放级别及中心点
}
// 打开文件读取数据函数
function openFile() {
var result = [];
var xhr = new XMLHttpRequest();
xhr.open("GET", filePath, false);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
result = csvJSON(xhr.responseText);
console.log(result);
loadDataFromCSV(result);
} else {
console.error(xhr.statusText);
Qmsg.warning('<i style="color:red">读取CSV文件报错异常</i>', {
html: true
});
loading.close();
}
}
};
xhr.send(null);
}
// 数据预处理,批量转换坐标点
function loadDataFromCSV(dataList) {
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
var name = data['名称'];
if (name) {
imgNameList.push(name);
}
var lat = data['纬度'];
var lng = data['经度'];
if (lat && lng) {
lat = Number(data['纬度'].replace(/\s*/g, ""));
lng = Number(data['经度'].replace(/\s*/g, ""));
// 将WGS84坐标转换为GCJ02坐标
var gcj02 = gcoord.transform([lng, lat], gcoord.WGS84, gcoord.GCJ02);
points.push(gcj02);
}
}
// 处理完成
Qmsg.info('<i style="color:red">数据预处理完成</i>', { html: true });
loading.close();
}
// csv数据源转换json格式数据源
function csvJSON(csv) {
var lines = csv.split("\n");
var result = [];
// var headers = lines[0].split(",");
var headers = lines[0].split("\t");
for (var k = 0; k < headers.length; k++) {
headers[k] = headers[k].replace('\"', '').replace('\r', '').replace('\"', '')
}
for (var i = 1; i < lines.length; i++) {
var obj = {};
// var currentline = lines[i].split(",");
var currentline = lines[i].split("\t");
for (var n = 0; n < currentline.length; n++) {
currentline[n] = currentline[n].replace('\"', '').replace('\r', '').replace('\"', '')
}
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return result;
}
// 批量导出图片
async function goScreenshotMap2Img() {
if (points.length === 0) {
Qmsg.warning('<i style="color:red">获取不到CSV文件采集点经纬度数据源,导出图片异常</i>', {
html: true
});
return;
}
// 导出图片处理中
loading = Qmsg.loading("导出图片处理中……");
for (var i = 0; i < points.length; i++) {
var point = points[i];
var latlng = L.latLng(point[1], point[0]);
if (marker) {
marker.remove();
marker = null;
}
marker = L.marker(latlng).addTo(map);
map.setView(latlng, 16); //设置缩放级别及中心点
baseList.push(await screenshotMap2Img(latlng)); //await会阻塞当前异步函数的执行,等待promise返回处理结果
}
if (baseList.length === points.length && baseList.length > 0) {
for (let k = 0; k < baseList.length; k++) {
zip.file(imgNameList[k] + '.png', baseList[k], { base64: true })
}
zip.generateAsync({ type: 'blob' }).then(function (content) {
saveAs(content, packageName + '.zip');
loading.close();
// 导出完成
Qmsg.info('<i style="color:red">导出完成</i>', { html: true });
});
}
}
// 截屏图片函数
function screenshotMap2Img(latlng) {
return new Promise((resolve, reject) => {
//模仿ajax请求
setTimeout(() => {
// 坐标点转换屏幕坐标
const centerPoint = map.latLngToContainerPoint(latlng);
// 转换的屏幕坐标点为中心,构造一个1000*1000像素的正方形
// 求左下角屏幕坐标
const southWestPoint = L.point(Math.abs(centerPoint.x - 500), Math.abs(centerPoint.y - 500));
// 求右上角屏幕坐标
const northEastPoint = L.point(Math.abs(centerPoint.x + 500), Math.abs(centerPoint.y + 500));
// 计算框选矩形的宽度以及高度像素
const width = Math.abs(northEastPoint.x - southWestPoint.x);
const height = Math.abs(northEastPoint.y - southWestPoint.y);
// 计算框选矩形的左上角屏幕坐标
const minx =
northEastPoint.x <= southWestPoint.x
? northEastPoint.x
: southWestPoint.x;
const miny =
northEastPoint.y <= southWestPoint.y
? northEastPoint.y
: southWestPoint.y;
// 截图导出
domtoimage
.toPng(node)
.then(function (dataUrl) {
if (dataUrl.length <= 6) {
console.log("屏幕截图结果为空,建议放大地图,重新截图操作试试看");
return;
}
// 过渡img图片,为了截取img指定位置的截图需要
const img = new Image();
img.src = dataUrl;
img.onload = function () {
// 要先确保图片完整获取到,这是个异步事件
const canvas = document.createElement("canvas"); // 创建canvas元素
canvas.width = width;
canvas.height = height;
canvas
.getContext("2d")
.drawImage(img, minx, miny, width, height, 0, 0, width, height); // 将图片绘制到canvas中
dataUrl = canvas.toDataURL(); // 转换图片为dataURL
resolve(dataUrl.substring(22));
};
})
.catch(function (error) {
console.error("oops, something went wrong!", error);
});
}, 1000);
});
}

Tags:

最近发表
标签列表