vue+leaflet示例:地图全图以及框选截图导出功能(附源码下载)

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,
    });
  });
  //绘制工具draw
  const 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>

下载源码:GIS之家的学习交流圈

posted @ 2025-03-25 20:43  GIS之家  阅读(28)  评论(0)    收藏  举报