记录了通过 ArcGIS 的 PringTask 进行地图打印, 以及借助 html2canvas 实现屏幕截图的方法两个方法各有适用的情景过程中涉及的相关资源和问题给出链接, 自行查看
1. 需求背景
地图打印, 这是地图应用系统的基本工具了多数使用者都希望能够将地图, 连带着查询结果统计结果以及自己绘制的各种图形输出, 将其保存到本地, 以供他用本文描述两类情况: 一类是通过 ArcGIS Server 发布的地图服务, 一类是调用其他数据源的地图切片形成的地图
2. 通过 ArcGIS Server 发布的地图服务
这个网上很多例子啦, 官方 API 也有详细例子上个链接: https://developers.arcgis.com/javascript/3/jssamples/#search/PrintTask
这个的思路就是通过 printTask 执行一个打印任务截一段代码给大伙看看:
- arcgisPrint = function() {
- var printTask = new PrintTask("http://172.28.1.131:6080/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export web Map Task");
- var template = new PrintTemplate();
- template.layoutOptions = {
- "authorText": "paq",
- "copyrightText": "copyright info here",
- "legendLayers": [],
- "titleText": "Pool Permits",
- "scalebarUnit": "Miles"
- };
- template.exportOptions = {
- width: 800,
- height: 600,
- dpi: Number(90)
- };
- template.format = "png32";
- template.layout = "MAP_ONLY";
- template.preserveScale = false;
- var params = new PrintParameters();
- params.map = map;
- params.template = template;
- printTask.execute(params,
- function(evt) {
- window.open(evt.url, "_blank");
- });
- };
这种方法的打印对于 ArcGIS Server 发布的服务来讲方便好用, 但是如果是调用其他地方的切片 (比如通过继承 WebTiledLayer 调用天地图百度地图), 那么输出的会是空白如图, 底图是天地图, 中国范围内叠加了一个 MapServer 方便区别:
用 PrintTask 打印出来是这个样子, 底图天地图是空白的:
- /* * 题外话:
- * 如何通过 ArcGIS JS API 调用百度地图和天地图自行百度, 提供几个链接:
- *http://www.cnblogs.com/angelapaq/p/7595831.html
- *https://blog.csdn.net/oldmonkeyyu_s/article/details/53710779
- * 总结调用切片三点: 确定好级别分辨率比例尺; 调整好图片大小切图原点; 把行列号和层级号拼成能够访问的 URL, 这些做好了, 不管百度谷歌还是高德超图都是一个道理
- **/
3. 借助 html2canvas 实现屏幕截图
思考之后, 决定换方法, 不用 ArcGIS 提供的方法, 转向通用的屏幕输出, 网上有很多关于 html2canvas 截图插件的使用, 我们也拿来一用
html2canvas 官方网站: http://html2canvas.hertzen.com/
这个插件的使用详情可自行百度, 我这里贴出自己的代码, 大致流程是: 确定截图区域, 克隆一份, 把不需要截图的 dom 移除, 调用插件把 html 片段转成 canvas, 输出
- canvasPrint=function () {
- var targetDom = $("#map");
- // 克隆截图区域
- var copyDom = targetDom.clone();
- copyDom.width(targetDom.width() + "px");
- copyDom.height(targetDom.height() + "px");
- copyDom.attr("id", "copyDom");
- $("body").append(copyDom);
- // 移除不需要截图的区域
- $(".base-map").remove();
- var pathName = document.location.pathname;
- var ctxPath = pathName.substring(1, pathName.substr(1).indexOf('/') + 1);
- html2canvas(copyDom[0], {
- useCORS: true,
- imageTimeout:0
- //, proxy: "/" + ctxPath + "/proxy/proxyScreenShot"
- }).then(function (canvas) {
- var url = canvas.toDataURL();
- // 创建下载 a 标签
- var a = document.createElement("a");
- a.setAttribute("id", "download");
- document.body.appendChild(a);
- // 以下代码为下载此图片功能
- var triggerDownload = $("#download").attr("href", url).attr("download", "img.png");
- triggerDownload[0].click();
- // 移除下载 a 标签
- document.body.removeChild(a);
- // 克隆 DOM 删除
- copyDom.remove();
- });
- }
按理说, 这样就可以输出了, 奈何我们的那些个小切片, 不在一个域, 跨域了, 跨域了找了各种方法, 发现通过代理访问比较靠谱以下是操作步骤:
跨域, 首先想到 ArcGIS 提供的跨域解决方法, 详情戳链接, 参照这个方法进行配置即可:
https://blog.csdn.net/wpz0713/article/details/50245041
在继承 WebTiledLayer 的 getTileUrl 方法时, 返回图片 URL 前加上代理地址, 例如:
- getTileUrl: function (level, row, col) {
- return "http://192.168.0.117:8080/Java/proxy.jsp?"+"http://t" + row % 8 + ".tianditu.cn/cva_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=c&TILEMATRIX=" + level + "&TILEROW=" + row + "&TILECOL=" + col + "&FORMAT=tiles";
- }
现在来看看结果是什么:
看来, 这个跨域方法并没有达到我们想要的效果, 那么就改造吧, 仔细看跨域的那个 proxy.jsp, 在 fetchAndPassBackToClient 方法内 190 行添加以下一行代码, 允许跨域
clientResponse.setHeader("Access-Control-Allow-Origin","*")
好了, 大功告成, 下图是截屏输出的图片:
另外, 在简单补一补跨域和代理的问题: https://www.cnblogs.com/fanyx/p/5775939.html
来源: https://www.cnblogs.com/angelapaq/p/8708726.html