现在的位置: 首页 > 综合 > 正文

arcgis server 紧促(bundle)格式缓存文件的读取

2014年04月05日 ⁄ 综合 ⁄ 共 3444字 ⁄ 字号 评论关闭

一:自10.0出来后,增加了另外一种缓存文件格式bundle,紧促型。比起以往的松散型格式。

         对两种不同的存储格式,最大的区别在于紧蹙格式保存的切片小文件少,一个bundle可以保存128张切片,易于缓存的迁移,节约空间等。

二:server bundle格式图片的读取

         网上已经有大神放出了bundle的存储格式,esri官方资料说的是不提供其读取方法,想要脱离server自己写的只有动手咯。

         具体格式解析:http://blog.csdn.net/warrenwyf/article/details/6069711

         Bundle存储有两个文件

         .bundle存储图片数据

         .bundlx存储图片在dundle文件中的偏移量

 

        

 

                   每个bundlx文件都一样大81920+32字节,前后16个描述信息,剩下的是可用信息,并且以每5个字节重复,存储了对应的图片在bundle文件中的偏移量。并且bundlx文件存储图片偏移量信息的顺序是按列存储。

              Bundle文件就相对简单了,4个字节图片存储长度+真是在图片信息;如此循环;

              具体的参看上面链接。

1.    Bundle文件的命名格式

因为在一个层级下面,如果图很大,而一个bundle只能存128*128个,所以可能会有多个bundle文件存在,这样就需要对其按所在区域分类命名。

         “R0080C0180” 以R+4位16进制数字+C+4位16进制数字组成。对于4个16进制计算规则。128*(row/128),然后转换成16进制即可。举例:1-128行的是R0000,129-256的是R0080。列的计算同理。

 

贴上读取一个贴片代码:C#本地读取代码

       public byte[] getTile(int level, int row, int col)

        {

            int size = 128;

            byte[] result = null;

            FileStream isBundle = null;

            FileStream isBundlx = null;

            try

            {

                string bundlesDir ="F:\\data\\test1\\Layers\\_alllayers";

                string l = "0" +level;

                int lLength = l.Length;

                if (lLength > 2)

                {

                    l = l.Substring(lLength -2);

                }

                l = "L" + l;

 

                int rGroup = size * (row /size);

                string r = "000" +rGroup.ToString("X");

                int rLength = r.Length;

                if (rLength > 4)

                {

                    r = r.Substring(rLength -4);

                }

                r = "R" + r;

 

                int cGroup = size * (col /size);

                string c = "000" +cGroup.ToString("X");

                int cLength = c.Length;

                if (cLength > 4)

                {

                    c = c.Substring(cLength -4);

                }

                c = "C" + c;

 

                string bundleBase = bundlesDir+ "//" + l + "//" + r + c;

                string bundlxFileName =bundleBase + ".bundlx";

                string bundleFileName =bundleBase + ".bundle";

 

                int index = size * (col -cGroup) + (row - rGroup);

                             //行列号是整个范围内的,在某个文件中需要先减去前面文件所占有的行列号(都是128的整数)这样就得到在文件中的真是行列号

                isBundlx = newFileStream(bundlxFileName, FileMode.Open, FileAccess.Read);

                isBundlx.Seek(16 + 5 * index,SeekOrigin.Begin);

                byte[] buffer = new byte[5];

                isBundlx.Read(buffer, 0, 5);

                long offset = (long)(buffer[0]& 0xff) + (long)(buffer[1] & 0xff)

                        * 256 + (long)(buffer[2]& 0xff) * 65536

                       + (long)(buffer[3] &0xff) * 16777216

                        + (long)(buffer[4]& 0xff) * 4294967296L;

 

                isBundle = newFileStream(bundleFileName, FileMode.Open, FileAccess.Read);

                isBundle.Seek(offset,SeekOrigin.Begin);

                byte[] lengthBytes = newbyte[4];

                isBundle.Read(lengthBytes, 0,4);

                int length =(int)(lengthBytes[0] & 0xff)

                        + (int)(lengthBytes[1] & 0xff) * 256

                        + (int)(lengthBytes[2]& 0xff) * 65536

                        + (int)(lengthBytes[3]& 0xff) * 16777216;

                result = new byte[length];

                isBundle.Read(result, 0,length);

            }

            catch (Exception ex)

            {

                return null;

            }

            finally

            {

                if (isBundle != null)

                {

                    isBundle.Close();

                    isBundlx.Close();

                }

            }

            return result;

        }

 

返回结果是一个byte数组,流里面包含了生成一个图片的全部信息,直接放入内存流里面,可以直接得到图片。

抱歉!评论已关闭.