将ArcGIS Pro 桌面打印制图功能搬到前端页面上 实现BS端打印制图功能
简介
将ArcGIS Pro 桌面打印制图功能搬到前端页面上 实现BS端打印制图功能
需要实现:
1、地图框可随意拖拽布局、控制大小
2、指北针可随意拖拽布局
3、比例尺按照地图放大缩小 自动更改 可随意拖拽布局
4、图例 根据地图加载的图层进行展示,可随意拖拽布局,控制大小
5、支持预览、下载
地图框
冲突
地图需要在地图框内进行移动缩放等操作,与地图框的鼠标事件冲突,固地图框样式 pointer-events设置成none 关闭鼠标事件
拖拽
添加拖拽功能 ,使用vue的自定义指令 directives 创建drag指令,将v-drag 添加到div中,完成拖拽功能
directives: {
drag: {
// 指令的定义
bind: function (el) {
let oDiv = el; // 获取当前元素
oDiv.onmousedown = (e) => {
// 算出鼠标相对元素的位置
let oDiv = document.getElementById("地图框div"); // 获取当前元素
let disX = e.clientX - oDiv.offsetLeft;
let disY = e.clientY - oDiv.offsetTop;
document.onmousemove = (e) => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
let top = e.clientY - disY;
oDiv.style.left = left + 'px';
oDiv.style.top = top + 'px';
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
},
}
放大缩小
添加放大缩小功能,使用vue的自定义指令 directives 创建scale指令,将v-scale 添加到div中,完成拖拽功能
directives: {
scale: {
// 指令的定义
bind: function (el) {
let oDiv = el; // 获取当前元素
oDiv.onmousedown = (e) => {
// 算出鼠标相对元素的位置
let oDivf = document.getElementById("地图框div"); // 获取当前元素
let disX = e.clientX - oDiv.offsetLeft;
let disY = e.clientY - oDiv.offsetTop;
document.onmousemove = (e) => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
let left = e.clientX - disX;
let top = e.clientY - disY;
oDivf.style.width = left + 'px';
oDivf.style.height = top + 'px';
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
}
}
标题
富文本编辑器使用的是wangEditor 5
拖拽功能同地图框
图例
图例储存
arcgis的服务 都是可以获取到图例的
图例获取
可以直接使用axios 获取图层信息
const getJsonByLegend= await axios({url: layer.url + '/legend?f=pjson',method: "get",})
返回结果如下
可以将imageData放到img标签进行展示,注意!imageData前面要添加’data:image/jpg;base64,'否则页面无法识别
<div class="imgCom" v-for="item,index in legendDatas" :key="index">
<div class="yizu">
<b>{{ item.layerName}}</b>
<table>
<tbody>
<tr valign="'middle'" v-for="i,k in item.legend" :key="k">
<td><img :src="'data:image/jpg;base64,'+i.imageData" alt=""></td>
<td>{{ i.label }}</td>
</tr>
</tbody>
</table>
</div>
</div>
图例摆放
想要改变图例摆放位置,只需要把给div 样式设置 float就可以通过拉伸边框进行排列。
拖拽功能同地图框
比例尺
scale属性
监听 视图的scale属性 就可以实时获取到当前比例尺的值
_self.view.watch("scale", (newValue) => {
_self.$store.state.vars.scaleNum = _self.ceilNum(parseInt(newValue)).toLocaleString()
});
格式化
比例尺一般是500 1000 20000 这种格式,获取到的值需要做一下格式化处理。
ceilNum(num) {
const bite = Math.pow(10, String(num).length - 1 || 1)
return Math.ceil(num / bite) * bite
},
拖拽功能同地图框
指北针
只需注意 指北针图片是svg格式,jpg或png打印预览会失真
拖拽功能同地图框
预览
确认区域
先用html2canvas将需要打印的区域整个转为一张截图
const dom = document.getElementById(id); //获取需要打印的区域
html2canvas(dom, {
backgroundColor: null,
scale: 2,
width: dom.offsetWidth,
height: dom.offsetHeight,
}).then((canvas) => {})
制作地图
再利用arcgis api中 view的takeScreenshot方法 将当前需要打印的地图转为图片
let options = {
width: dom.getBoundingClientRect().width,
height: dom.getBoundingClientRect().height,
area: {
x: dom.getBoundingClientRect().x,
y: dom.getBoundingClientRect().y - 80,
width: dom.getBoundingClientRect().width,
height: dom.getBoundingClientRect().height
}
};
_self.arcmap.view.takeScreenshot(options).then(function (screenshot) {
const src64 = canvas.toDataURL();
const imgWidth = dom.offsetWidth; // 根据纸张宽度设定
const imgHeight = dom.offsetHeight
var img = new Image();
img.src = screenshot.dataUrl;
var img1 = new Image();
img1.src = src64;
img.onload = function () {
// 将图片添加到canvas
ctx.drawImage(img, 0, 0, imgWidth, imgHeight)
img1.onload = function () {
// 将图片添加到canvas
ctx.drawImage(img1, 0, 0, imgWidth, imgHeight)
}
}
});
生成预览
最后利用canvas将图片整合 生成img标签 完成预览功能
// 导出为图片
let url = canvasC.toDataURL("image/png")
const div = document.createElement("div");
var img2 = new Image();
div.appendChild(img2);
img2.setAttribute("src", url);
img2.setAttribute("width", imgWidth.toString());
img2.setAttribute("height", imgHeight.toString());
img2.setAttribute("id", "imgs");
div.setAttribute("id", "printImg");
_self.$refs.preview.appendChild(div);
下载
原理同预览,唯一不同是下载不生成img标签生成a标签模拟click事件
//下载图片
downloadImage(url) {
// 如果是在网页中可以直接创建一个 a 标签直接下载
let a = document.createElement('a')
a.href = url
a.download = '地图打印'
a.click()
},
总结
功能完成,完结撒花!!!