地图打印
TIP
点击按钮打印地图。
代码如下:
点我查看代码
vue
<template>
<div id="menu">
<el-button type="primary" @click="handleExport">导出地图</el-button>
</div>
<div id="map"></div>
</template>
<script lang="ts" setup>
import { onMounted, onBeforeUnmount } from "vue";
import { Map, View } from "ol";
import { Tile as TileLayer } from "ol/layer";
import { XYZ } from "ol/source";
import { MAPURL, ATTRIBUTIONS } from "../../../constants";
import { exportMap } from "../../../lib";
let map: Map | null = null;
const raster = new TileLayer({
source: new XYZ({
attributions: ATTRIBUTIONS,
url: MAPURL,
maxZoom: 20,
crossOrigin: "anonymous",
}),
});
const initMap = () => {
map = new Map({
//初始化map
target: "map",
//地图容器中加载的图层
layers: [
//加载瓦片图层数据
raster,
],
view: new View({
projection: "EPSG:4326", // 坐标系,有EPSG:4326和EPSG:3 857
center: [0, 0], // 深圳坐标
//地图初始显示级别
zoom: 5,
}),
});
};
const handleExport = () => {
exportMap(map, "地图打印");
};
onMounted(() => {
initMap();
});
onBeforeUnmount(() => {
if (map) {
map.dispose();
map = null;
}
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#map {
height: 650px;
}
#menu {
display: flex;
justify-content: space-around;
align-items: center;
height: 50px;
}
</style>
exportMap 代码如下:
点我查看代码
ts
import type { Map as olMapType } from "ol";
export const exportMap = (map: olMapType | null, filename = "map.png") => {
if (map === null) return
map.once("rendercomplete", function () {
const mapCanvas = document.createElement("canvas");
const size = map.getSize() || [];
mapCanvas.width = size[0];
mapCanvas.height = size[1];
const mapContext = mapCanvas.getContext("2d");
if (mapContext === null) return
Array.prototype.forEach.call(
map.getViewport().querySelectorAll(".ol-layer canvas, canvas.ol-layer"),
(canvas: HTMLCanvasElement) => {
if (canvas.width > 0 && canvas.parentElement !== null) {
const opacity =
canvas.parentElement.style.opacity || canvas.style.opacity;
mapContext.globalAlpha = opacity === "" ? 1 : Number(opacity);
const backgroundColor = canvas.parentElement.style.backgroundColor;
if (backgroundColor) {
mapContext.fillStyle = backgroundColor;
mapContext.fillRect(0, 0, canvas.width, canvas.height);
}
let matrix: number[];
const transform = canvas.style.transform;
if (transform) {
// Get the transform parameters from the style's transform matrix
matrix = transform.match(/^matrix\(([^(]*)\)$/)![1]
.split(",")
.map(Number);
} else {
matrix = [
parseFloat(canvas.style.width) / canvas.width,
0,
0,
parseFloat(canvas.style.height) / canvas.height,
0,
0,
];
}
// Apply the transform to the export map context
CanvasRenderingContext2D.prototype.setTransform.apply(
mapContext,
matrix
);
mapContext.drawImage(canvas, 0, 0);
}
}
);
mapContext.globalAlpha = 1;
if ((navigator as any).msSaveBlob) {
// 链接下载属性不能在MS浏览器上工作
(navigator as any).msSaveBlob((mapCanvas as any).msToBlob(), filename);
} else {
const downloadElement = document.createElement("a");
downloadElement.href = mapCanvas.toDataURL();
downloadElement.download = filename;
document.body.appendChild(downloadElement);
downloadElement.click();
// 移除a标签;
document.body.removeChild(downloadElement);
}
});
map.renderSync();
};