手动实现arcgis的PrintTask

来源:互联网 发布:java localdate 编辑:程序博客网 时间:2024/05/29 18:59

ArcGIS Server提供的在线地图打印解决方案很简洁方便,通过ArcGIS Server发布一个PrintingTools服务,然后使用Javascript在Web前端创建一个PrintTask对象,设置好PrintParameters参数即可实现地图的在线输出.

require(["esri/tasks/PrintTask","esri/tasks/PrintTemplate", "esri/tasks/PrintParameters"], function(PrintTask, PrintTemplate, PrintParameters) {       var printurl = 'http://200.200.100.198/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task';       var printTask = new PrintTask(printurl);       var params = new PrintParameters();       var outWidth = (map.extent.xmax - map.extent.xmin) * 4600 /map.getScale();       var outHeight = (map.extent.ymax - map.extent.ymin) * 4600 /map.getScale();       var template = new PrintTemplate();       template.exportOptions = {           width: parseInt(outWidth),           height: parseInt(outHeight),           dpi: 96       };       template.format = "PNG32";//输出为png格式的图片       template.layout = "MAP_ONLY";       template.preserveScale = false;        params.map= map;       params.template = template;       printTask.execute(params, function (evt) {           window.open(evt.url, "_blank");       });});

但是当我的地图网站发布到外网的服务器时,打印功能无法正常使用,但是之前在内网测试一切都是正常的。内网和外网有什么区别呢,如果是网络问题,地图都是可以正常显示的,只是打印功能不行。

最后发现跟路由器的NAT回流有关系。有关回流的解释可以参见这篇文章【http://zhan.renren.com/cqhqhsj?gid=3602888498000970436&checked=true】,感觉写的蛮清楚。这里需要说明一下网络环境。

服务器的内网地址比如假设是192.168.10.8,映射的外网地址200.200.100.198,ArcGIS Server和IIS都安装在这台服务器上。外网用户可以正常访问200.200.100.198发布的网站,并且可以正常看到网站里面的地图。

网站里面有一个输出地图的按钮应用,客户端点击这个按钮,实际是就是调用了上面的js文件,最终由ArcGISServer实时生成图片,并返回给客户端这张图片的地址,客户端打开这个地址就能看到图片。

如果外网环境下打印功能不行的话,问题只能是这个js文件。这个js文件中的PrintTask封装的太用力,有个过程我们看不到。ArcGIS Server是怎么生成图片的呢,应该是首先根据map对象获取到对应的地图服务【http://200.200.100.198:6080/arcgis/rest/services/MapServer,因为一个地图服务就是一个mxd,ArcGIS Server基于这个mxd就可以进行切割合成图片了。

恰恰在这个过程中,因为NAT回流,获取的这个地图服务出了问题。客户端发出了请求http:// 200.200.100.198/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task,注意这个请求是带map对象的【params.map = map】;服务器收到请求后,会根据map对象获取到地图服务的地址【http://200.200.100.198:6080/arcgis/rest/services/MapServer】,然后服务器会访问这个地址,但是因为NAT回流,服务器访问不到这个地址,所以导致服务器无法正常生成图片。

这个问题可以怎么解决呢?我估计这是个常见问题,但是我在网上搜了搜,却发现GIS行业很少聊这个问题,很奇怪他(她)们是怎么解决的。

目前我发现只要绕开PrintTask,就可以解决。其一是PrintTask本质上就是向服务器发送http请求而已;其二是服务器访问200.200.100.198不可以,但是访问127.0.0.1总是可以的吧。

所以基于这两点,重新写了js文件,问题解决。

下面是代码:

function SnapshotMapFor() {    varwebMapAsJson = '{"mapOptions":{"showAttribution":true,"extent":{"xmin":{xmin},"ymin":{ymin},"xmax":{xmax},"ymax":{ymax},"spatialReference":{"wkid":21480}},"spatialReference":{"wkid":21480}},"operationalLayers":[{layers}],"exportOptions":{"outputSize":[2105,990],"dpi":96}}';    vargraphicsLayer = '{"id":"map_graphics","opacity":1,"minScale":0,"maxScale":0,"featureCollection":{"layers":[{"layerDefinition":{"name":"polygonLayer","geometryType":"esriGeometryPolygon"},"featureSet":{"geometryType":"esriGeometryPolygon","features":[{geometry}]}}]}}';    vargeometryJson = '{"geometry":{"rings":{rings},"spatialReference":{"wkid":21480}},"symbol":{"color":[3,169,244,26],"outline":{"color":[255,0,0,255],"width":1.5,"type":"esriSLS","style":"esriSLSSolid"},"type":"esriSFS","style":"esriSFSNull"}}';   webMapAsJson = webMapAsJson.replace("{xmin}",map.extent.xmin.toString());   webMapAsJson = webMapAsJson.replace("{xmax}",map.extent.xmax.toString());   webMapAsJson = webMapAsJson.replace("{ymin}",map.extent.ymin.toString());   webMapAsJson = webMapAsJson.replace("{ymax}",map.extent.ymax.toString());    varslayers = "";    for (vari = 0; i < map.layerIds.length; i++) {        if(map.layerIds[i] == 'map_graphics') {        }else {           var id = map._layers[map.layerIds[i]].id.toString();           var minScale = map._layers[map.layerIds[i]].minScale.toString();           var maxScale = map._layers[map.layerIds[i]].maxScale.toString();           var lurl = map._layers[map.layerIds[i]].url.toString();           lurl = lurl.replace('200.200.100.198', "127.0.0.1");//重点是这里做一个替换           slayers += '{"id":"';           slayers += id;           slayers += '","title":"';           slayers += id;           slayers += '","opacity":1,"minScale":';           slayers += minScale;            slayers += ',"maxScale":';           slayers += maxScale;           slayers += ',"url":"';           slayers += lurl;           slayers += '"},';        }    }    vargeostr = "";    for (vari = 0; i < map.graphics.graphics.length; i++) {        vartmpgeo = map.graphics.graphics[i];        if(tmpgeo.geometry.rings != null && tmpgeo.geometry.rings.length > 0){           var sring = RingToWKT(tmpgeo.geometry);           geostr += geometryJson.replace('{rings}', sring);           geostr += ",";        }    }    if(geostr == "") {       slayers = slayers.substring(0, slayers.length - 1);    } else{       geostr = geostr.substring(0, geostr.length - 1);       graphicsLayer = graphicsLayer.replace('{geometry}', geostr);       slayers += graphicsLayer;    }   webMapAsJson = webMapAsJson.replace("{layers}", slayers);   $.ajax({       url: 'http:// 200.200.100.198/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task/execute',       dataType: 'json',       beforeSend: function () {       },       data: {           Web_Map_as_JSON: webMapAsJson,           Format: "PNG32",           Layout_Template: 'MAP_ONLY',           returnZ: false,           returnM: false,           f: 'pjson'       },       type: 'post',       cache: false,       error: function (data) {       },       success: function (data) {           if (data != null) {                window.open(data.results[0].value.url, "_blank");           } else {           }        }    });}function RingToWKT(geometry) {    varwkt = [];    varrings = geometry.rings;    for (vari in rings) {        varring = rings[i];        for(var j in ring) {           var p = ring[j];           wkt.push('[' + p.toString() + ']');        }    }    return"[[" + wkt.join(",") + "]]";}

原创粉丝点击