本文包括地图导出核心代码、完整代码以及在线示例。
地图导出核心代码
这里放上 ES 封装的核心代码,创建多边形或者其他几何对象,直接使用材质即可:
/**
* todo 保存地图
* @param {string} format - 格式,目前只支持图片
*/
function saveMap(format) {
const thisObject = map;
thisObject.once('rendercomplete', function () {
const mapCanvas = document.createElement('canvas');
const size = thisObject.getSize();
mapCanvas.width = size[0];
mapCanvas.height = size[1];
const mapContext = mapCanvas.getContext('2d');
Array.prototype.forEach.call(
document.querySelectorAll('.ol-layers canvas'),
function (canvas) {
if (canvas.width > 0) {
const opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
const transform = canvas.style.transform;
// Get the transform parameters from the style's transform matrix
const transformTemp = transform
.match(/^matrix\(([^\\(]*)\)$/);
const matrix = transformTemp && transformTemp[1]
.split(',')
.map(Number);
// Apply the transform to the export map context
CanvasRenderingContext2D.prototype.setTransform.apply(
mapContext,
matrix
);
mapContext.drawImage(canvas, 0, 0);
}
}
);
if (navigator.msSaveBlob) {
// link download attribuute does not work on MS browsers
navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
} else {
mapCanvas.toBlob(function (blob) {
saveAs(blob, 'map.png');
});
}
});
map.renderSync();
}
完整代码:
<html lang="en">
<head>
<meta charSet="utf-8">
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
<style>
/* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
.map {
height: 400px;
width: 100%;
float: left;
}
</style>
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<script src="http://openlayers.vip/examples/resources/ol.js"></script>
<script src="https://openlayers.vip/examples/resources/FileSaver.js"></script>
<script src="./tiandituLayers.js"></script>
<title>OpenLayers example</title>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<h2>OpenLayers export</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<br/>
<br/>
<script type="text/javascript">
var map = new ol.Map({
// 地图容器
target: 'map',
// 地图图层,比如底图、矢量图等
layers: [
getIMG_CLayer(),
getIBO_CLayer(),
getCIA_CLayer(),
],
// 地图视野
view: new ol.View({
projection: "EPSG:4326",
// 定位
center: [115.67724700667199, 37.73879478106912],
// 缩放
zoom: 6,
maxZoom: 18,
minZoom: 1,
})
});
// 默认样式
var defaultStyle = new ol.style.Style({
//边框样式
stroke: new ol.style.Stroke({
color: 'red',
width: 2,
}),
//填充样式
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.3)',
}),
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: 'white',
})
})
})
// 初始化图层
var layer = initVectorLayer();
// 传递的方式开启悬浮的图形要素
let polygon1 = "POLYGON((112.80630306271966 46.27140545436643,116.23403743771966 44.33781170436643,117.81606868771966 40.29484295436643,117.90395931271966 38.36124920436643,117.81606868771966 35.02140545436643,116.14614681271966 32.38468670436643,113.50942806271966 33.26359295436643,111.75161556271966 34.58195232936643,110.60903743771966 35.46085857936643,113.28970150021968 36.03214764186642,111.35610775021968 36.33976482936642,110.91665462521968 36.91105389186642,111.22427181271968 37.52628826686642,112.10317806271968 37.30656170436642,112.41079525021968 37.78996014186642,112.32290462521968 38.36124920436642,111.44399837521968 38.66886639186642,110.52114681271968 39.10831951686642,110.38931087521968 39.81144451686642,111.09243587521968 40.07511639186642,112.19106868771968 40.38273357936642,112.49868587521968 41.04191326686642,111.88345150021968 41.21769451686642,111.26821712521968 40.86613201686642,110.43325618771968 40.91007732936642,110.65298275021968 41.39347576686642,110.47720150021968 42.66788982936642,111.79556087521968 42.75578045436642,110.38931087521968 43.19523357936642,110.56509212521968 44.24992107936642,111.44399837521968 43.76652264186642,111.79556087521968 44.16203045436642,111.09243587521968 44.60148357936642,111.22427181271968 45.30460857936642,112.10317806271968 44.95304607936642,112.67446712521968 45.26066326686642,111.75161556271968 45.78800701686642,111.88345150021968 46.40324139186642,112.14712337521968 47.94132732936642,112.45474056271968 47.15031170436642,113.99282650021968 47.28214764186642,113.28970150021968 46.79874920436642,114.95962337521968 46.71085857936642,112.80630306271966 46.27140545436643))";
// 移入和移出事件的图形要素
let polygon2 = "POLYGON((123.94676492355833 44.03121337817592,118.40965554855833 38.23043212817592,121.66160867355833 32.82515869067592,129.30809304855833 33.39644775317592,129.92332742355833 39.46090087817592,123.94676492355833 44.03121337817592))";
// 选中方式的悬浮的图形要素
let polygon3 = "POLYGON((107.96587424038064 27.434398296739595,125.98345236538064 30.554515484239595,126.68657736538064 24.446117046739595,110.16313986538064 17.942210796739595,107.96587424038064 27.434398296739595))";
// 添加点线面
function addFeatures() {
// 这里处理一下,可以自由传图形要素 start===================================================
layer.getSource().clear();
const feature1 = getFeatureByWKT(polygon1);
const feature2 = getFeatureByWKT(polygon2);
layer.getSource().addFeatures([feature1, feature2]);
map.getView().fit([93.64037006658276, 10.72265625,128.53294819158273, 51.181893294147805], {
duration: 1,//动画的持续时间,
callback: null,
});
}
addFeatures();
/**
* @todo 矢量图层
* @returns {VectorLayer}
* @constructor
*/
function initVectorLayer() {
//实例化一个矢量图层Vector作为绘制层
let source = new ol.source.Vector();
//创建一个图层
let customVectorLayer = new ol.layer.Vector({
source: source,
zIndex: 2,
//设置样式
style: defaultStyle,
});
//将绘制层添加到地图容器中
map.addLayer(customVectorLayer);
return customVectorLayer;
}
/**
* @todo wkt格式数据转化成图形对象
* @param {string} wkt "POINT(112.7197265625,39.18164062499999)" 格式数据
* @param {string|Projection} sourceCode 源投影坐标系
* @param {string|Projection} targetCode 目标投影坐标系
* @returns {Feature}
*/
function getFeatureByWKT(wkt, sourceCode, targetCode) {
try {
let view = map.getView();
if (!wkt) {
return null;
}
let format = new ol.format.WKT();
let feature;
feature = format.readFeature(wkt, {
featureProjection: targetCode || view.getProjection(),
dataProjection: sourceCode || view.getProjection(),
});
return feature;
} catch (e) {
console.log(e);
return null;
}
}
/**
* todo 保存地图
* @param {string} format - 格式,目前只支持图片
*/
function saveMap(format) {
const thisObject = map;
thisObject.once('rendercomplete', function () {
const mapCanvas = document.createElement('canvas');
const size = thisObject.getSize();
mapCanvas.width = size[0];
mapCanvas.height = size[1];
const mapContext = mapCanvas.getContext('2d');
Array.prototype.forEach.call(
document.querySelectorAll('.ol-layers canvas'),
function (canvas) {
if (canvas.width > 0) {
const opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
const transform = canvas.style.transform;
// Get the transform parameters from the style's transform matrix
const transformTemp = transform
.match(/^matrix\(([^\\(]*)\)$/);
const matrix = transformTemp && transformTemp[1]
.split(',')
.map(Number);
// Apply the transform to the export map context
CanvasRenderingContext2D.prototype.setTransform.apply(
mapContext,
matrix
);
mapContext.drawImage(canvas, 0, 0);
}
}
);
if (navigator.msSaveBlob) {
// link download attribuute does not work on MS browsers
navigator.msSaveBlob(mapCanvas.msToBlob(), 'map.png');
} else {
mapCanvas.toBlob(function (blob) {
saveAs(blob, 'map.png');
});
}
});
map.renderSync();
}
</script>
<button id="saveMap" onClick="saveMap()">打印地图</button>
</body>
</html>
在线示例
Openlayers 在线示例:地图以及图层数据导出