ArcGIS API+Canvas +Vue框架 制作前端地图打印功能

简介

将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()
        },

请添加图片描述

总结

功能完成,完结撒花!!!

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值