文章版权由做者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/。html
这周利用晚上在家时间研究了下如何使用AE来开发切图工具。最初的想法是直接调用GP服务,利用CreateMapServerCache 、ManageMapServerCacheTiles 和Geoprocessor 这样三个类来作。可是这个思路有个巨大的弊端就是必须先发布地图服务。因而接下来又立刻转换思路,想可否经过瓦片选址算法以及AE的一些细粒度类来实现这个功能。在通过了三个晚上的算法编写和功能编写后,整个工具基本成型,其中包括了对算法的优化以及一些具体问题的解决。这里跟你们大体分享下。算法
若是对瓦片和瓦片寻址的相关算法不熟悉的朋友,请参考我写的从底层探究WebGIS的原理系列:http://www.cnblogs.com/naaoveGIS/category/600559.html。数组
这里我直接给出所涉及到的几个公式。微信
resolution=scale*inch2centimeter/dpi。其中scale是地图比例尺,inch2centimeter为英寸转厘米的参数,dpi为1英寸所包含的像素。工具
假设,地图切图的原点是(originX,oringinY),地图的瓦片大小是tileSize,地图屏幕上1像素表明的实际距离是resolution。计算坐标点(x,y)所在的瓦片的行列号的公式是:优化
col = floor((originX- x)/( tileSize*resolution))spa
row = floor((oringinY - y)/( tileSize*resolution))htm
本工具的目标是切出与AGS瓦片相同格式的瓦片。AGS的瓦片具备如下特色(在http://www.cnblogs.com/naaoveGIS/p/3903270.html我作了详细的讲解):blog
(a).L开头的表明了Level,R开头的表明了row,C开头的表明了Col。索引
(b). L后的数字是两位字符串,R后的是八位字符串,C后的也是八位字符串。
(c).英文后的数字均是16进制数,而后不足位数的用0补充。
咱们首先得到用户输入的切图级别数组levelScaleArr,瓦片大小(imgWidth,imgHeight),切图原点(originX,originY)还有像素值DPI。同时咱们还要经过接口得到此时地图的范围(dXMin,dYMin,dXMax,dYMax)。
流程的盒模型以下所示:
实现上,主要使用了AE作了这样几个功能:
(a).使用IMapControl类得到mxd的四角坐标。
(b).使用IActiveView、ExportPNGClass和EnvelopeClass实现将地图局部导出功能。
其余均按照上述流程图实现。
在AE中能够导出多种格式的图片。利用ExportJPEGClass(),ExportBMPClass(),ExportEMFClass(),ExportGIFClass()等便可实现。
经过上面的类直接导出的图片其背景色默认为了白色。而AGS切图中,背景色是透明的,因此这里还要作一个图片透明度优化过程。C#中转成Bitmap后,利用该类自带的MakeTransparent便可实现。
在流程中,咱们默认的切图是从切图原点开始的,这样会切成不少不少的无用图。咱们能够直接从离地图DXmin和DYmax最近处开始切图便可。
startXByLevel = (int)Math.Abs((Math.Floor((DXmin-originX) / dImageWidth)));
startYByLevel = (int)Math.Abs((Math.Floor((originY-DYMax) / dImageHeight)));
startXByLevel和startYByLevel即为X轴和Y轴的切图初始点。
咱们常常会切出整张图都是透明的空白图。可是在AGS的切图中,是看不到这样的无效图的。咱们能够在切图时先判断此范围内是否有要素存在,有的话就切,没有的话,continue掉。这样也能够减小切图的数目。
目前上面的全部过程,均只对作了投影转换的mxd有效,可是若是咱们的mxd中的坐标系无投影转换只有一个地理坐标系呢,也就是当地图为经纬度坐标时,此时该如何实现切图?
其实思路也很简单,若是咱们真正理解以上resolution的所表明实际意义,那么解决这个问题的思路就应该有了。
当地图为经纬度时,咱们切图的比例尺设置应该改成切图的分辨率设置。这样咱们就直接获得了每一个级别的resolution,而后用resolution来切图便可。不用再作以上的将比例尺转换为resolution的步骤。
在levelScaleArr中,里面的比例尺数字是随着index增长而增长的,可是比例尺数字越大,其对应的Level是越小的。因此咱们在遍历Level层时,应该是一个递减的遍历,这样生成的L文件夹的编号才是正确的。
如下是效果图:
(a).目前没法切出紧凑型(Compact)瓦片。解决思路,用上面的方法导出图后,须要把图变成二进制而后按照bundle的格式从新生成,而且还要生成索引文件bundleX。
(b).所用的AE毕竟是封装的很好的组件库了。用GDAL的话,因为封装层次低一些,效率应该会更好一些。
-----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
若是您以为本文确实帮助了您,能够微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^