手动实现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(",") + "]]";}
- 手动实现arcgis的PrintTask
- 单链表的手动实现
- LinkedList的手动实现
- ARCGIS 点抽稀的实现
- ArcGIS手动汉化方法
- 手动删除ArcGis
- 手动HashMap的简单实现
- 动态代理的手动实现
- 手动实现string类的方法实现
- ArcGIS 10 影像分析工具及ArcGIS Engine的实现
- ArcGIS 10 影像分析工具及ArcGIS Engine的实现
- 手动绑定下的实现事件
- 带头结点的单链表类C++手动实现
- 手动实现cookie 的python3代码
- 手动实现的客户端输入校验
- 手动实现简单的ArrayList底层
- 手动实现cocos2dx里的lua-binding
- ArcGIS Server专题图的实现
- 深度前馈网络【DeepLearningBook读书笔记】
- 【spring】事务
- 28.输入两个链表,找出它们的第一个公共结点。
- java实现全排列
- 降噪 (Noise Reduction)对于图像边缘检测 (Edge Detection)的意义
- 手动实现arcgis的PrintTask
- HTTP协议详解
- JSP基础元素
- iOS设置导航栏navigationBar大小、颜色、透明度等一切操作(WRNavigationBar)
- 第十三章:事件类型(HTML5事件、设备事件、触摸与手势事件)
- Java中的抽象接口类,你还知道哪个?
- 脚本化文档
- 10个优秀的jQuery Mobile主题
- vue新建项目(一)vue-cli新建模板项目