手动实现arcgis的PrintTask

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(",") + "]]";
}

你可能感兴趣的:(ArcGIS)