|||
一:自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数组,流里面包含了生成一个图片的全部信息,直接放入内存流里面,可以直接得到图片。
————————————————
版权声明:本文为CSDN博主「李白上明月」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/abc553226713/article/details/8668839
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-24 14:04
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社