ArcGIS Server 切片数学关系阐释,小区域切图频繁出错解决方法

直击:

Tile|SuperTile|Bundle的关系

1、紧凑型切片中Tile|SuperTile|Bundle关系为:

1
2
3
4
5
6
7
8
9
如果:
    Tile = 256 × 256 pixel             # 256×256 是ArcGIS Server默认的切片大小
    Supertile = 4096 × 4096 pixel      # 未开抗锯齿情况下是 4096×4096
那么:
	Supertile = 16 × 16 Tile           
已知:
	Bundle = 128 × 128 Tile            
因此:
	Bundle 范围是 N-3 级的 Supertile 范围

2、矢量切片中Tile|SuperTile|Bundle关系为:

                已知: Supertile = 128 × 128 Bundle

                因此:Bundle 范围是 N-7 级的 Supertile 范围.

展开:

supertile和bundle

       要深入了解ArcGIS在切图时的工作机制,有两个概念必须明白,就是supertile和bundle。
  假设一个tile(切片)的大小是256*256,在切图时如果按照这个大小直接exportmap,开启了动态标注的地图服务上线图层和面图层就会有很多重复的标注。因为exportmap时,每个tile都会包含一个要素的标注,如果一个要素横跨了多个tile(这在大比例尺下基本是肯定的),那么这些tile上就会出现相同的标注,exportmap时并不知道相邻的tile上已经有了该要素的标注。

 为了解决这个问题,ArcGIS在切图时引入了supertile的概念,开启抗锯齿时supertile大小为2048*2048,反之为4096*4096。真正切图时会首先exportmap出一个supertile,然后将它们分割成指定大小的tile。对于每个要素,每个supertile中只包含一次标注,这样保证一个superfile大小的范围内不会出现重复标注。事实上在绘制supertile时,会尽可能多地包含周围的标注,所以在每个supertile的边界周围仍会有重复标注。解决重复标注的根本办法就是使用annotation,而不是label。
  ArcGIS 10中推出了新的compact缓存格式,将原来离散的每个tile图片(exploded格式),保存成连续的二进制文件(.bundle),每个.bundle文件最多可存储128*128个tile。相比以前成千上万的tile文件,这样做有明显的好处:易于缓存迁移,减少占用磁盘空间,减少硬盘i/o等,esri在任何时候都推荐使用compact格式来创建缓存,除非你需要自己读取每个tile(技术上来说这点可以不成立)。ArcGIS 10在切图时,也采用了bundle的概念:对于每一级比例尺,首先从tiling scheme origin开始,将切图范围分成若干个bundle,每个bundle覆盖的范围是128*128个tile大小。比如在1:4096比例尺时,如果tile大小是256*256,DPI为96,那么每个bundle范围的大小是:((4096*2.54/96)/100/1000*256*128)^2=1261.086平方千米。之后,有且仅有(这么做是为了避免多个进程同时读写一个磁盘文件)一个服务实例/一个arcsoc.exe进程(如果是high isolated)来负责此bundle范围的切图,先输出supertile,然后再切成tile。即使选择了exploded缓存格式,ArcGIS 10中也会采用这种机制来切图。

9.3.1及以前版本中,每个服务实例工作的单位是supertile。即一个arcsoc.exe负责生成一个supertile,然后切成tile,再继续生成下一个supertile……相比supertile这种处理单位来说,采用bundle作为处理单位的ArcGIS 10中的服务实例可以将更多精力投入到连续切图中去,而不是频繁切换自己负责的范围。在大比例尺切图中,这种新机制能很大程度上减少切图时间;但在小比例尺切图中,这种新机制有可能反而增加切图时间。因为小比例尺时可能全图范围只有不到一个bundle范围大小,这样只会有一个服务实例来切图,其他实例都处于空闲状态,而9.3.1及以前版本中,所有服务实例都会“蜂拥而上”。

网格切图和按featureclass范围切图

  有过大比例尺范围切图经验的朋友肯定会知道,一般切图策略是:小比例尺全图直接切,较小比例尺可能按照某个featureclass范围来切,而大比例尺一般是按照包含网格(grid)的featureclass范围来切。以我国全范围切图为例,小比例尺时全图切没有问题,大比例尺时如果仍然全图范围(包络矩形)切的话,会将周边其他的国家也包含进来,这并不需要的额外工作量在大比例尺时会是一场噩梦。

image

而之所以不仅要按指定featureclass范围切图,而且featureclass里要包含网格的原因在于,便于细化和跟踪切图进度。切图工具会给你指定的featureclass创建一个新的Cached字段,将已经切好的feature标记为YES,以便在选择Recreate Empty Cache时避免重复切图,从而可以将切图工作分为多次来进行,或者以便在切图失败后排查原因,继续切图工作。
  在指定featureclass范围切图时,是顺序处理该featureclass中的所有feature的。所有的服务实例会首先集体处理一个feature范围,切出该feature范围内所有要求的比例尺级别的结果。此时ArcGIS Server会重启该服务。然后所有服务实例再去切下一个feature范围……所以与每个feature边界相交的supertile可能会被创建两次或多次(多个feature的相交处),这也是为什么在使用featureclass切图前,需要分别对它进行GeneralizeAggregateDissolve的原因。

image

 结合之前bundle的机制我们知道,如果一个feature范围恰好只包含一个bundle,那么就杯具了,因为对该feature切图时,只会有一个服务实例进行工作(一个bundle同时由且仅由一个服务实例处理),其他服务实例全部处于空闲状态。因此,比较理想的情况是,每个feature至少包含比服务实例数更多的bundle时,才能充分利用硬件资源来对其切图。
  这就会引出一个问题,就是如何来确定某个比例尺下一个bundle的大小,从而生成这样的featureclass呢?ArcGIS 10中,给我们提供了一个新的GP工具Map Server Cache Tiling Scheme To Polygons,利用它,我们可以针对某个地图服务,生成每个需要切图比例尺下所有的supertile,进而得到以每个supertile为一个feature的featureclass。以全国地图为例,在1:288,895比例尺(ArcGIS Online Tiling Scheme的第12级)下生成的supertile是这样的:

image

我们需要的是某个比例尺下bundle的范围,如何根据supertile来确定bundle的大小呢?在N级比例尺时,一个supertile是16*16个tile,第N+1级比例尺时,该supertile会覆盖32*32个tile,第N+2级比例尺时,覆盖64*64个tile,第N+3级比例尺时,这个第N级的supertile会覆盖128*128个tile,眼熟吧,这正是一个bundle的大小。由于supertile和bundle都是从tiling scheme origin往右下角算起的,因此第N级一个supertile的范围正是第N+3级一个bundle的范围。由此如果我们要生成第15级的bundle网格,只需要用Map Server Cache Tiling Scheme To Polygons工具生成第12级supertile的网格即可,如上图。
  以此为例,我们来说明如何有效进行大比例尺切图的问题。假设我们需要对1:36,111(ArcGIS Online Tiling Scheme的第15级)这个比例尺进行切图,我们首先生成该范围的bundle网格,恰好是第12级的supertile网格,如上图。为了简便起见,我们只取其中8个feature来做说明,地图服务的最大实例数是4个(机器是单cpu,4核)。如果每个feature恰好是一个bundle,那么一个feature只能被一个arcsoc.exe处理,而其他3个服务实例均处在空闲状态(占用内存最少的那个arcsoc.exe是用来清空工作目录的,与具体服务无关):

image

而我们对这个featureclass做一个处理,将4个feature(恰好是一个bundle)合并成一个feature(bundle cluster),这样每个feature就恰好包含了4个bundle,如此我们所开启的4个服务实例就可全速工作了,发挥了机器的最大性能:

image

ps:Map Server Cache Tiling Scheme To Polygons工具生成的supertile是从tiling scheme origin开始计算的,而不是地图服务的fullextent左上角,因此利用它生成的supertile合并出来的bundle是最合理的,恰好与理想的bundle分界处一致。因此在大比例尺下利用featureclass切图时,应当利用Map Server Cache Tiling Scheme To Polygons来生成网格,而不是fishnet工具。在ArcGIS 10.1中,将会推出新的GP工具,会根据cpu核数来生成合理的包含bundle cluster大小feature的featureclass。
  其他方面还有一些问题,比如切图时最大服务实例数设置多少为好(一般是cpu核数+1),即使所有实例全部工作cpu占用率依然低于90%(有可能是内存不足)等问题,与切图机制无关,就不在此讨论了。
  总之,切图是一个技术活,要求还比较高,需要考虑的问题很多。

小区域切图频繁出错解决方法

从bundle的存储机制和这种基于bundle的切图机制出发,我们不难想到一种基于先按bundle区域分块切片,再合并的切片的想法。这种想法很自然地也会引出一个问题,我们如何来确定某个比例尺级别一个bundle的大小,又如何生成以为bundle大小为单位的要素图层?为了解决这个问题,我们现需要了解supertile的概念。supertile的概念最早的引入是为了解决重复标注的问题,此处我们暂且不讲它为何能一定程度上解决标注重复的问题(有兴趣的朋友可以去阅读菩提老王的旧文或者查阅相关资料),只来谈谈它和bundle的关系以及我们怎么从supertile要素图层来获得bundle要素图层。我们知道一个瓦片(tile)的大小是256x256 px,而supertile(可以称之为超切片吧)在抗锯齿和非抗锯齿下有不同大小:在开启抗锯齿时大小为2048x2048 px,未开启时为4096x4096 px。此处我们以未开启抗锯齿为例,我们可以计算得到一个supertile对应16x16个瓦片。据此,我们可以进一步计算出某一比例级别的一个bundle含有该级别的8x8个supertile。那么我们怎么获得supertile和bundle呢?从ArcGIS 10开始提供了一个Map Server Cache Tiling Scheme to Polygon的工具,使用该工具可以针对某个切片方案,生成该切片方案所有比例尺的supertile。那么已知比例尺级别之间的关系是:n级的比例尺x2 = n+1级别的比例尺和1个bundle = 8x8 supertile,我们不难推断出n级的supertile所覆盖的区域就是n+3级的一个bundle覆盖的区域。至此,我们已经清楚如何获得的表示bundle的要素图层了:为了获得m级的bundle的要素图层,我们只需使用Map Server Cache Tiling Scheme to Polygon工具来获得m-3级supertile的要素图层即可。 
有了bundle要素图层后,我们可以分别导出要素图层成中的每个bundle作为一个独立的要素图层。之后,我们可以使用Manage Tile Cache工具根据每个独立bundle要素图层进行感兴趣区切图。在获得了不同bundle区域的切片后,我们只需要将它们复制粘贴到同一个mxd发布的空切片服务下的相应文件夹即可。
12级Supertileåºå

上图内影像为东北地区一景landsat8影像,使用Map Server Cache Tiling Scheme根据默认的ArcGIS Online切片方案对第12级生成的supertile要素图层,当然也就是15级bundle要素图层。

上图为导出的每个bundle区域的要素图层,使用这些单个bundle要素图层对15级进行感兴趣区分块切图。

è¿éåå¾çæè¿°

上图为导入分块切的bundle文件,可以注意到每个框内的三个文件来自于一个bundle区域(测试环境为10.3.1,其他版本文件名可能不同)。在分块切图之后,将生成的bundle文件复制粘贴到一个空的切片服务相应的L15(15级)文件夹内,重新启动服务即可完成。

附件 :

关于像素、分辨率、DPI等术语,请参考:关于像素、分辨率、PPI、DPI等概念的分析

按照ArcGIS切图方案配置(Schemes)文件进行切图,成果包括:地图瓦片(缓存)和conf.xml、conf.cdi文件。

conf.xml存储了切片方案配置信息:

        TileOrigin表示切片方案原点。

        TileCols和TileRows表示单张切片所占的像素长度。

        DPI表示切片图片的一英寸长度的像素数。

        LODInfos里则存储了切片的各级信息。

        PacketSize表示单个bundle文件里存储的行/列数。

        Scale表示切片各个级别的地图比例尺。

        LODInfo的Resolution表示的是地图上每个像素表示的实际长度(地图单位)。

conf.cdi存储了切片的范围

 

        其他参数比较好理解,下面分析一下Scale与Resolution的关系。

Scale:地图比例尺,比例尺是表示图上距离比实地距离缩小的程度,也叫缩尺。公式为:比例尺=图上距离/实地距离。

Resolution:地图分辨率。表示当前地图范围内(一定的Scale条件下),1像素代表多少实际地图单位(N地图单位/像素),地图单位取决于数据本身的空间参考(平面座标的单位是米,地理座标的单位是度)。Resolution跟dpi(dpi代表每英寸的像素数)有关,跟scale有关。

1.如果地图的座标单位是米

        假设切图设置dpi=96,

        那么,1英寸 =  2.54厘米 = 0.0254米 = 96像素

        即 1像素 = 0.0254/96 米

公式:Scale = 1 : (96 * Resolution / 0.0254)

即Resolution = 0.0254 / (Scale * dpi)     地图分辨率跟比例尺和切图dpi有关

         如果Scale =1:500,dpi=96

         那么,Resolution =0.0254/ ((1/500)*96) =0.13229166666米,即图上1像素代表实地距离是0.13229166666米。        

         ArcGIS为了高精度,一般1英寸 = 0.0254000508米

2. 如果地理座标系是WGS84,地图的单位是度       

        公式:Scale = 1 : (dpi * 2 * Math.PI * 6378137 * Resolution / 360 / 0.0254); 

        那么:Resolution = (360*0.0254) /  (Scale * dpi * 2 *  Math.PI * 6378137)   ,

        其中,

        2 *  Math.PI * 6378137 = 地球的周长,这里有一个常识需要讲解:赤道上经度的每度大约相当于111km,经度的每度的距离从0km到111km不等。它的距离随纬度的不同而变化,等于111km乘纬度的余弦。不过这个距离还不是相隔一经度的两点之间最短的距离,最短的距离是连接这两点之间的大圆的弧的距离,它比上面所计算出来的距离要小一些。

        假设切图设置dpi=96

        其中,1度 = 111194.872221777米;

        如果Scale =1:500,

        那么,Resolution = 0.13229166666米,即图上1像素代表实地距离是0.13229166666米。

        将米换成度:0.13229166666/111194.872221777 = 0.00000118972度

        即图上1像素代表实地是0.00000118972度
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章