首先介绍一下ArcGIS10.0的缓存机制: 切片方案切片方案包括缓存的比例级别、切片尺寸和切片原点。这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要。图像格式和抗锯齿等其他属性也会写入切片方案,但对于客户端应用程序能否成功叠加切片没有影响。
切片方案原点切片方案原点是指切片方案格网的左上角,默认原点为地图文档定义的坐标参考的左上点。原点不一定代表创建切片的起始点;只有在达到地图全图范围时才是这样。进行缓存时使用公用切片方案原点可确保所创建的缓存能够在 Web 应用程序中相互叠加。注意,切片是从地图的全图开始切的,不是从切片方案原点(切片方案原点落在地图原点右下方另算)。
另外一点,我经过试验,发现切片的行列号是从0开始算起的。 切片宽度和高度切片的默认宽度和高度为 256 像素。 DPI每英寸点数 (Dot Per Inch) ,是指服务器将生成的缓存切片的分辨率。即生成的图片每英寸长度内的像素点数。默认为96。
切片方案缓存文件结构缓存目录 -> 地图服务名 ->地图数据框名称(DataFrame) ->如果是所有图层一起切割就是_alllayers,否则就是各个图层的名称 -> 各比例尺等级文件夹。如下图
地图数据框文件夹里放着conf.cdi和conf.xml两个标识缓存范围、以及切片方案的配置信息:
conf.cdi存储了切片的范围: conf.xml存储了切片方案配置信息: TileOrigin表示切片方案原点。 TileCols和TileRows表示单张切片所占的像素长度。 DPI表示生成切片的一英寸长度的像素数。 LODInfos里则存储了切片的各级信息。 PacketSize表示单个bundle文件(下一小节将介绍)里存储的行/列数。 LODInfo的Resolution表示的是地图上每个像素表示的实际长度(地图单位)。比如说50万的比例尺,96的dpi,可以这么计算: 500000 / 100 * 2.54 / 96 = 132.2913125052919
bundle和bundlx文件bundle文件中存储的是图片文件,bundlx文件中则存储了各个图片文件在bundle文件中的偏移量。 命名规则bundle文件的命名都是:R数字C数字。R代表起始的Row,C代表起始的Column。数字均为16进制。 行和列如果不满4位,则前面补0,位数多了不限。如R22e80C14400,表示这个bundle文件的起始切片是0x22e80行0x14400列。 bundlx文件结构每个bundlx文件的大小都是81,952 字节(我这里PacketSize是128),前面16字节 + 每个图片偏移量5字节 * (128 * 128)个切片 + 结尾16字节。 这里注意一下,不管是bundlx还是bundle文件里写位置信息都是从低位到高位写的,比如说你看见这样一段代表位置的字节:10 32 a8 d7 54,这个代表的就是16进制的0x54d7a83210 我比较了一下各个bundlx文件,发现起止16字节都一样,开始和结束字节分别是: byte[] bdxBts = new byte[16] { 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 }; byte[] bdlxEndBts = new byte[16] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; bundlx文件切片的写入顺序是按列写入的。也就是说,先是1列1行、1列2行……2行1行、2列2行……这样写的位置。还拿R22e80C14400来说: 先是开始16字节,然后5个字节22e80行14400列、5个字节的22e81行14400列…… bundle文件结构这个文件我比较了好半天才找到这些规则。 首先是文件的开头,从0x00到0x3b的这些位置都是bundle文件的描述信息:(还是以R22e80C14380.bundle为例)
这里多谢不做懒人的改正: “ 为了让arcgis能读取我们生成的紧凑型格式,bundle文件的前60个字节的数据,还需要完善。 ” 开头以后紧接着从0x3c开始就定入图像文件。 但如果某一处不在地图的全图范围内,也就是说我这个bundle文件中是包含很多块切片的,其中有好多是正好是空的,没有图像。这时会怎么办呢,难不成全写成空Image存进去? 开始我是这么写的,但写了一个就感觉不对了,一级的切片里一个bundle几十兆大小了,后来我比对发现,所有bundle文件从0x3c到0x1003c都是空的,正好=4*16384个字节。然后找到arcgis生成的bundlx文件验证一下,第一级的开始一列切片正好都是空的,bundlx里的偏移量是从0x3c开始的。也就是说,bundle文件里从0x3c->0x1003c这些位置是为空切片预留了偏移位置,依次按照bundlx里的位置顺序开始写切片,如果遇到空的,就指向这里的空位置段,比如第r行第c列切片是空的,对应的位置就是 0x3c + ((c - colStart) * this.m_packetSize + (r - rowStart)) * 4。 非空切片在bundle文件里是从0x1003c开始写的。 找到非空切片存储的偏移位置,接下来的4个字节是该image的长度,然后在这4个字节之后取这些长度的字节就组合成了一副图像,如果要查找的话返回即可。
简单写入算法读取时直接按照level和row、column计算出bundle文件名,按照上面的计算方法找到对应Image返回即可,这里只说明一下我自己的切片的方法。针对单个LODInfo
经测试,我用DotSpatial的DotSpatial.Controls.Map控件 按照已经用ArcGIS发布好的服务的参数来配置 来切割一副地图,切割好后删除ArcGIS的切片并替换成我自己切割的,展现效果完全相同。 |
|
来自: 昵称25340375 > 《arcgis》