OpenLayers导出带比例尺PNG地图不显示及报错问题咨询
OpenLayers 导出带比例尺的PNG/PDF解决方案
问题原因
- 现有代码导出PNG无比例尺:绘制逻辑顺序错误,你先在导出画布上绘制了比例尺,之后才把地图图层的内容绘制到同一画布,图层内容直接覆盖了比例尺
Cannot read properties of undefined (reading 'beginPath')报错:你参考的旧版本示例依赖低版本OpenLayers的postcompose事件返回的上下文结构,你当前使用的OpenLayers版本接口变更,导致获取到的上下文为undefined
修复后的PNG导出代码
document.getElementById('export-png').addEventListener('click', function() { map.once('postcompose', function(event) { var canvas = document.createElement('canvas'); var size = map.getSize(); canvas.width = size[0]; canvas.height = size[1]; var mapContext = canvas.getContext('2d'); // 第一步:先绘制所有地图图层 Array.prototype.forEach.call( document.querySelectorAll('.ol-layer canvas'), function (layerCanvas) { if (layerCanvas.width > 0) { var opacity = layerCanvas.parentNode.style.opacity; mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity); var transform = layerCanvas.style.transform; // 解析变换矩阵 var matrix = transform .match(/^matrix\(([^\(]*)\)$/)[1] .split(',') .map(Number); CanvasRenderingContext2D.prototype.setTransform.apply( mapContext, matrix ); mapContext.drawImage(layerCanvas, 0, 0); } } ); // 第二步:图层绘制完成后再绘制比例尺,避免被覆盖 var resolution = map.getView().getResolution(); // 可根据需求调整比例尺长度,这里以200米为例 var scaleLength = 200 / resolution; var scaleY = size[1] - 20; // 调整y坐标避免文字被画布边缘截断 mapContext.setTransform(1, 0, 0, 1, 0, 0); // 重置变换矩阵,避免比例尺受图层变换影响 mapContext.strokeStyle = "#0000FF"; mapContext.lineWidth = 5; mapContext.beginPath(); mapContext.moveTo(10, scaleY); mapContext.lineTo(10 + scaleLength, scaleY); mapContext.stroke(); mapContext.font = "20px Arial"; mapContext.fillStyle = "#0000FF"; mapContext.fillText("200m", 10, scaleY - 5); // 下载逻辑保持不变 if (navigator.msSaveBlob) { var imgName = prompt("Please provide the name", "survey_map"); navigator.msSaveBlob(canvas.msToBlob(), imgName + '.png'); } else { var link = document.getElementById('image-download'); link.href = canvas.toDataURL(); link.download = 'survey_map.png'; link.click(); } }); map.renderSync(); });
如果需要和页面上显示的ScaleLine控件完全一致,不需要自己计算比例尺,可以引入html2canvas类库,将页面上的比例尺DOM元素转成图像后绘制到导出画布上,避免手动计算分辨率出现的误差。
PDF导出添加比例尺实现方式
导出PDF可借助jsPDF类库实现,逻辑如下:
- 按照上述修复后的逻辑生成带比例尺的PNG base64资源
- 初始化jsPDF实例,根据导出画布的尺寸设置PDF页面大小
- 调用
addImage方法将生成的PNG添加到PDF中,此时PNG已自带比例尺,无需额外绘制 - 调用
save方法导出PDF文件即可
内容的提问来源于stack exchange,提问作者Geographos
相关产品推荐
相关产品推荐

