最近在研究 ArcGIS 导出地图功能,折腾了许久,终于完成了。
ArcGIS 自带的打印功能
ArcGIS Server 自带了一个打印地图服务。
ArcGIS API for JS 3.31 附带了 3 个示例。
这三个示例都是调用 ArcGIS Server 自带的打印地图服务实现导出地图的。这三个示例使用的主要 API 是:
// 打印组件
使用ArcGIS自带的打印组件会受到一些限制:
(1)打印操作过程不是我想要的;
(2)打印组件界面样式不是我想要的。
(3)只能打印网页显示范围的底图。
(4)打印尺寸受限。
即使自己发布一个地图打印服务,也只能调整模板。其他的改变不了。
Arcgis API for JS地图打印服务
仔细思考解决办法:
打印服务是一个GP服务。有四个参数。自己发布的打印服务也有这 4 个参数。
通过浏览器开发者工具查看官方示例请求打印时传递的参数可以发现 4 个参数中的 3 个。
请求返回结果中带了一个 4 个参数中的 1 个。打印得到文件路径在请求结果中。
是不是可以自己调用GP服务来实现?
尝试自己创建一个 GP 请求,参数和管网刚才的请求参数完全一样,看看效果。
// 构造 GP 请求的代码 require(["esri/map","esri/layers/FeatureLayer","esri/tasks/Geoprocessor","esri/config","dojo/_base/array","dojo/dom","dojo/parser","dijit/layout/BorderContainer","dijit/layout/ContentPane","dojo/domReady!"], function (Map,FeatureLayer,Geoprocessor,esriConfig,arrayUtils,dom,parser) {parser.parse();var map = new esri.Map("map", {basemap: "topo",center: [-117.447, 33.906],zoom: 17,slider: false});var webJSON = {"mapOptions": {//..},"operationalLayers": [//..],"exportOptions": {// ..},"layoutOptions": {//..}};window.ExportWebMap = function () {var params = {"f": "json","Web_Map_as_JSON": JSON.stringify(webJSON),"Format": "jpg","Layout_Template": "A3 Landscape"};console.log("params", params);var exportMapUrl = "http://localhost:6080/arcgis/rest/services/GP/ExportWebMap3/GPServer/%E5%AF%BC%E5%87%BA%20Web%20%E5%9C%B0%E5%9B%BE";var gp = new Geoprocessor(exportMapUrl);console.log("开始调用GP...");gp.submitJob(params).then(function (data) {console.log("data", data);gp.getResultData(data.jobId, "Output_File", function (outputpath) {console.log("outputfile", outputpath);});},function (error) {console.log("error", error);},function (status) {console.log("status", status);});}});
打印结果和管网示例一样。
所以,可以自己构造 GP 请求,自己控制打印的执行过程。
接下来,要解决 GP 请求参数如何生成的问题。
示例程序中的参数生成过程完全看不到。只能仔细观察这些参数看看有什么特征。
Format 、Layout_Template、f 这三个很简单,看看文档仔细了解一下即可。关键是 Web_Map_as_JSON 这个参数。
这个参数包含 4 个部分。
"mapOptions": {//..},"operationalLayers": [//..],"exportOptions": {// ..},"layoutOptions": {//..}
mapOptions 就是导出的范围,空间参考,比例尺。
exportOptions 就是输出的文件的图像的尺寸、dpi。
layoutOptions 包含图像标题、版权、图例、比例尺等布局的参数。
查看示例代码打印的过程,确实是发送了带服务指定参数的请求。只是请求参数组织过程封装了。我们可以尝试自己组织请求参数,使用GeoProcessor发送一个GP请求。
operationalLayers 包含了图层相关的数据。
Web_Map_as_JSON 中最难的应该就是 operationalLayers 参数的生成。
底图的参数比较好生成,就是 url 、id、maxScale 之类的。
FeatureLayer 的 renderer 参数比较难,研究了很久发现可以通过
FeatureLayer.toJson().layerDefinition.drawingInfo.renderer
得到。
所以,研究到这里,可以实现自己组织参数、自己控制打印过程了。本文开头提到的问题中的前 3 个已经解决。
接下来解决打印尺寸受限问题。
经过前面的分析知道 exportOptions 和 Layout_Template 是控制打印的尺寸的。所以我们研究这个参数即可。
经过测试发现当 outputSize 为 [null, null], Layout_Template为空字符时,可以不限制尺寸打印。
到此,问题全部解决了。