demo源码运行环境以及配置
- 运行环境:依赖Node安装环境,demo本地Node版本:14.19.1。
- 运行工具:vscode或者其他工具。
- 配置方式:下载demo源码,vscode打开,然后顺序执行以下命令:
(1)下载demo环境依赖包命令:npm i
(2)启动demo命令:npm run dev
(3)打包demo命令: npm run build:release
示例效果
本篇实现的思路:主要参考截图插件domtoimage:https://github.com/tsayen/dom-to-image
地图全图导出直接用上面的domtoimage插件,然后矩形框选截图导出也是在domtoimage插件基础上自己计算矩形范围来实现的
- 核心源码
<template><div id="map" ref="mapDiv"></div><div class="titleContainer center"><span>vue+leaflet示例:地图全图以及框选截图导出功能</span></div><div style="position: absolute; top: 50px; left: 60px; z-index: 999"><button type="button" id="mapexport_btn">全图导出</button></div><div style="position: absolute; top: 50px; left: 160px; z-index: 999"><button type="button" id="rctanglexport_btn">框选导出</button></div>
</template><script setup>
import { onMounted, reactive, ref } from "vue";
import L from "leaflet";
import "@geoman-io/leaflet-geoman-free";
import "@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
import domtoimage from "dom-to-image";
// import config from "../config";
// import { useRouter } from "vue-router";
// const router = useRouter();
const mapDiv = ref(null);
let map = null;
let geojsonLayer = null;
onMounted(() => {initMap();
});
const initMap = () => {// 创建地图对象map = L.map("map", {attributionControl: false,}).setView(L.latLng(22.95186415, 113.90271877), 14);//创建底图切换数据源const baseLayer = L.tileLayer("http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",{ crossOrigin: true });map.addLayer(baseLayer); //地图默认加载的底图//参考截图插件:https://github.com/tsayen/dom-to-image// const node = document.getElementById('map');const node = mapDiv.value;// console.log('node:', node);$("#mapexport_btn").click(function () {domtoimage.toJpeg(node, { quality: 1.0 }).then(function (dataUrl) {const link = document.createElement("a");link.download = "全图导出.jpeg";link.href = dataUrl;link.click();});});$("#rctanglexport_btn").click(function () {//绘制矩形map.pm.enableDraw("Rectangle", {finishOn: "dblclick",allowSelfIntersection: false,tooltips: false,});});//绘制工具drawconst customTranslation = {tooltips: {finishLine: "单击任何存在的标记或者双击以完成",finishPoly: "单击第一个标记或者双击完成以完成",},};map.pm.setLang("customName", customTranslation, "zh");map.pm.addControls({position: "topleft",drawMarker: false,drawCircleMarker: false,drawCircle: false,drawPolyline: false,drawRectangle: false,drawPolygon: false,editMode: false,dragMode: false,removalMode: false,cutPolygon: false,drawText: false,rotateMode: false,});map.on("pm:create", (e) => {//console.log(e);geojsonLayer = e.layer;geojsonLayer.addTo(map);const northEast = e.layer.getBounds()._northEast;const southWest = e.layer.getBounds()._southWest;//框选矩形的中心点const centerPoint = L.latLng((northEast.lat + southWest.lat) / 2.0,(northEast.lng + southWest.lng) / 2.0);//地理坐标转换屏幕坐标const northEastPoint = map.latLngToContainerPoint(northEast);const southWestPoint = map.latLngToContainerPoint(southWest);//计算框选矩形的宽度以及高度像素const width = Math.abs(northEastPoint.x - southWestPoint.x);const height = Math.abs(northEastPoint.y - southWestPoint.y);………….catch(function (error) {console.error("oops, something went wrong!", error);});});
};
</script><style scoped>
#map {width: 100vw;height: 100vh;
}
.titleContainer {position: absolute;top: 0;background: rgba(0, 0, 0, 0.45);height: 50px;width: 100vw;z-index: 999;font-size: 14px;color: #fff;font-size: 28px;
}
.center {display: flex;flex-direction: column;align-items: center;justify-content: center;
}
</style>