irpas技术客

arcgis for js4.xx 打印地图模仿GIS打印出图_ttbat

网络投稿 4744

原理:是使用地图的view.takeScreenshot方法返回地图的图像,再创建一个新的画布,然后把生成的地图图形putImageData到画布里。

效果图:(图上黑色是后来编辑添加上去的,怕涉密,哈哈!)

?

?

开始打印出图:

/** * 开始执行打印出图 * @param {*} priter_width 设置图片的宽度 * @param {*} priter_height 设置图片的高度 * @param {*} pixelRatio 分辨率 */ function startPrint(priter_width, priter_height, pixelRatio) { require(["esri/geometry/Point", "esri/geometry/support/webMercatorUtils", "utils/GisCommon"], function (Point, webMercatorUtils, GisCommon) { /* code goes here */ //把度格式分为度分秒的接口 var gisUnit = new GisCommon(); var c = document.createElement("CANVAS"); c.id = "printC"; //document.body.appendChild(c); if (true) { var options = { width: priter_width * pixelRatio, height: priter_height * pixelRatio }; //selectExtent 使用GIS的draw的Rect框选出的范围extent if (selectExtent) { //把点坐标转为平面坐标 var ltPoint = new Point({ x: selectExtent.xmin, y: selectExtent.ymax }); var _ltPoint = viewer.toScreen(ltPoint); //设置打印的平面范围xy与大小 options = {}; options.area = { x: _ltPoint.x, y: _ltPoint.y, width: priter_width * pixelRatio, height: priter_height * pixelRatio } } /* if(viewer.map.layers.length){ options.layers = viewer.map.layers; } */ viewer.takeScreenshot(options).then(function (screenshot) { var cWidth = screenshot.data.width; var cheight = screenshot.data.height; //第一个框的边距 var padding = (widgetConfig.mapborder && widgetConfig.mapborder.padding) ? widgetConfig.mapborder.padding : 10; //内外边框的间隔 var borderWidth = (widgetConfig.mapborder && widgetConfig.mapborder.borderWidth) ? widgetConfig.mapborder.borderWidth : 50; //标题高度 var titleHeight = (widgetConfig.mapborder && widgetConfig.mapborder.titleHeight) ? widgetConfig.mapborder.titleHeight : 25; cWidth = cWidth + borderWidth + padding cheight = cheight + borderWidth + padding + titleHeight; c.width = cWidth; c.height = cheight; c.style.backgroundColor = "#FFF"; var ctx = c.getContext("2d"); ctx.rect(0, 0, cWidth, cheight); ctx.fillStyle = "#FFF"; ctx.fill(); ctx.putImageData(screenshot.data, (padding + borderWidth) / 2, (padding + borderWidth) / 2 + titleHeight); drawCanvas(c, ctx, cWidth, cheight, padding, titleHeight, borderWidth, webMercatorUtils, gisUnit); }); } }); }

?制作图片的内容方法:

/** * 生成Canvas * @param {*} c 创建的Canvas * @param {*} ctx Canvas的2D内容 * @param {*} cWidth 图片宽度 * @param {*} cheight 图片高度 * @param {*} padding 边距 * @param {*} titleHeight 标题高度 * @param {*} borderWidth 内外边框的间隔 * @param {*} webMercatorUtils * @param {*} gisUnit */ function drawCanvas(c, ctx, cWidth, cheight, padding, titleHeight, borderWidth, webMercatorUtils, gisUnit) { var box = 2, box2 = 5; var sleep = 0; var nx = (padding / 2) + (borderWidth / 2), ny = (padding + borderWidth) / 2 + titleHeight; var nwidth = cWidth - padding - borderWidth, nheight = cheight - padding - titleHeight - borderWidth; ctx.strokeStyle = '#000'; //strokeStyle设置边框颜色 //绘制外边框 if (borderWidth > 0) { ctx.strokeRect((padding / 2), (padding / 2) + titleHeight, cWidth - padding, cheight - padding - titleHeight); } //绘制内边框 ctx.strokeRect(nx, ny, nwidth, nheight); ctx.fillStyle = "#000"; ctx.textBaseline = "alphabetic"; ctx.texAlign = "center"; ctx.font = "bold 20px SimSun"; ctx.fillText($('.priter-title').val(), (cWidth / 2), titleHeight); //显示内框四角坐标 if (true || widgetConfig.mapborder && widgetConfig.mapborder.bboxCoord) { var extent = selectExtent == null ? webMercatorUtils.webMercatorToGeographic(viewer.extent) : selectExtent; //左上角坐标 ctx.font = "14px SimSun"; ctx.fillText(gisUnit.formatDegree(extent.xmin, true), nx + box2, ny - box); ctx.save(); var lbl = gisUnit.formatDegree(extent.ymax, true); var strwidth = ctx.measureText(lbl).width; ctx.translate(nx - box2, ny + strwidth); f(-90, lbl); ctx.restore(); //右上角坐标 ctx.fillText(gisUnit.formatDegree(extent.xmax, true), nx + nwidth - strwidth - box2 * 2, ny - box); ctx.save(); ctx.translate(nx + nwidth + box2 * 2.5, ny + strwidth); f(-90, lbl); ctx.restore(); //左下角坐标 ctx.fillText(gisUnit.formatDegree(extent.xmin, true), nx, ny + nheight + box2 * 2.5); lbl = gisUnit.formatDegree(extent.ymin, true); strwidth = ctx.measureText(lbl).width; ctx.save(); ctx.translate(nx - box2, ny + nheight); f(-90, lbl); ctx.restore(); //右下角坐标 ctx.fillText(gisUnit.formatDegree(extent.xmax, true), nx + nwidth - strwidth - box2, ny + nheight + box2 * 2.5); ctx.save(); ctx.translate(nx + nwidth + box2 * 2.5, ny + nheight); f(-90, lbl); ctx.restore(); } //图例 var leng = $(".esri-legend__service").parent(); if ($(".esri-legend__service").length || (widgetConfig.mapborder && widgetConfig.mapborder.legend)) { ctx.save(); ctx.fillStyle = "#FFF"; var mn = 70; var lengy = ny + nheight - leng.height() + mn; var lengwidth = leng.width(); var length2 = lengwidth / 3; var lengPadd = 10, lblheight = 22; ctx.fillRect(nx + 1, lengy, lengwidth + 1, leng.height() - mn); ctx.strokeRect(nx + 1, lengy, lengwidth + 1, leng.height() - mn); ctx.restore(); ctx.save(); ctx.fillStyle = "#000"; ctx.textBaseline = "middle"; ctx.texAlign = "center"; var rowtotal = 0; var loadInt = 0; $(".esri-legend__service").each(function (i) { sleep++; var title = $(this).children()[0].innerHTML; var rows = $(this).children("div.esri-legend__layer").children().children("div.esri-legend__layer-body").children(); var txty = lengy + lengPadd; if (i > 0) { var liney = lengy + lengPadd + (lblheight * (i + 1)) + (rowtotal * 33); txty = lengy + lengPadd + (lblheight * (i + 1)) + (rowtotal * 33) + 10; ctx.beginPath(); ctx.moveTo(nx, liney); ctx.lineTo(nx + lengwidth, liney); ctx.stroke(); } ctx.font = "bold 14px SimSun"; ctx.fillText(title, nx + 5 + length2, txty); rowtotal += rows.length; ctx.font = "12px SimSun"; ctx.save(); ctx.textBaseline = "Top"; rows.map(function (index, row) { var svg = $(row).find("svg"); var svgimg = new Image(); var rowname = $($(row).children()[1]).html(); var serializer = new XMLSerializer() var toExport = svg[0].cloneNode(true); // 克隆 var bb = svg[0].getBBox(); // getBBox方法返回一个包含svg元素的最小矩形的坐标对象。 包含(x,y)、width、height 需要用来解决svg中的图超出边界时无法全部完整保存问题 toExport.setAttribute('viewBox', (bb.x - 20) + ' ' + (bb.y - 20) + ' ' + (bb.width + 40) + ' ' + (bb.height + 40)); // 重新设置svg目前的视口 toExport.setAttribute('width', bb.width + 36); // 重新设置svg目前的宽度 toExport.setAttribute('height', bb.height + 36); // 重新设置svg目前的高度 var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(toExport); svgimg.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source); svgimg.alt = escape2Html(rowname); svgimg.setAttribute("name", txty); svgimg.setAttribute("i", i); svgimg.setAttribute("index", index); svgimg.onload = function (evt) { var numser = parseInt($(evt.target).attr("name")); var iI = parseInt($(evt.target).attr("i")); var indexI = parseInt($(evt.target).attr("index")); var svgy = numser + (23 * indexI); ctx.drawImage(svgimg, nx, svgy + (indexI * 10)); //ctx.save(); ctx.fillText($(evt.target).attr("alt"), nx + svgimg.width - 8, svgy + (svgimg.height / 2) + 5 + (indexI * 10)); loadInt++; if (loadInt == rowtotal) { exportRaw("printer.png", c.toDataURL()); } } }); }); ctx.restore(); } //指北针 if (true || widgetConfig.mapborder && widgetConfig.mapborder.compass) { ctx.save(); //<img id="zhibeiz" src="images/zhibeiz64.png" style="display: none;" /> var img = document.getElementById("zhibeiz"); ctx.drawImage(img, nx + nwidth - 150, ny + 60); ctx.restore(); } //比例尺 if (true || widgetConfig.mapborder && widgetConfig.mapborder.scale) { ctx.save(); var scale = "1:" + (viewer.scale).toFixed(""); ctx.fillStyle = "#FFF"; ctx.fillRect((cWidth / 2), ny + nheight - 25, ctx.measureText(scale).width + 10, 25); ctx.strokeRect((cWidth / 2), ny + nheight - 25, ctx.measureText(scale).width + 10, 25); ctx.fillStyle = "#000"; ctx.textBaseline = "middle"; ctx.texAlign = "center"; ctx.fillText(scale, (cWidth / 2) + 5, ny + nheight - 12); ctx.restore(); } if (sleep == 0) { exportRaw("printer.png", c.toDataURL()); } function f(i, txt) { var deg = Math.PI / 180 * i ctx.rotate(deg) /** 1. 中心点移动到文字正中 2. 坐标(0,0)时,中心点为文字左下角点 3. 所以:横坐标左移一半长,纵坐标下移一半宽 */ ctx.fillText(txt, 0, 0); } }

?

/** * html编码转html字符 * @param {*} str * @returns */ function escape2Html(str) { var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"'}; return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){return arrEntities[t];}); }

?导出下载图片:

function fakeClick(obj) { var ev = document.createEvent("MouseEvents"); ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); obj.dispatchEvent(ev); selectExtent = null; } function exportRaw(name, data) { //var urlObject = window.URL || window.webkitURL || window; //var export_blob = new Blob([data]); var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a") save_link.href = data;//urlObject.createObjectURL(export_blob); save_link.download = name; fakeClick(save_link); }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #arcgis #for #js4xx #打印地图模仿GIS打印出图 #var #C