ArcGIS 10.3开始,启动了一种新的切片管理方式。将缓存的索引信息.bundlx包含在了缓存的切片文件.bundle中。
利用C#对新的缓存数据进行读取的方式如下:
/// <summary>
/// 从本地切片文件读取相应的层行列对应的切片,针对Arcgis v2.0切片数据格式
/// </summary>
/// <param name="level"></param>
/// <param name="row"></param>
/// <param name="column"></param>
/// <returns></returns>
public byte[] GetTileBytesDot3(int mLevel, int mRow, int mColumn)
{
int size = 128;
byte[] tileBytes = null;
FileStream isBundle = null;
string bundlesDir = input_path + "\\_alllayers";
try
{
string level = mLevel.ToString();
int levelLength = level.Length;
if (levelLength == 1)
{
level = "0" + level;
}
level = "L" + level;
int rowGroup = 128 * (mRow / 128);
string row = rowGroup.ToString("X");
int rowLength = row.Length;
if (rowLength < 4)
{
for (int i = 0; i < 4 - rowLength; i++)
{
row = "0" + row;
}
}
row = "R" + row;
int columnGroup = 128 * (mColumn / 128);
string column = columnGroup.ToString("X");
int columnLength = column.Length;
if (columnLength < 4)
{
for (int i = 0; i < 4 - columnLength; i++)
{
column = "0" + column;
}
}
column = "C" + column;
string bundleName = bundlesDir + "\\" + level + "\\" + row + column + ".bundle";
int index = 128 * (mRow - rowGroup) + (mColumn - columnGroup);
if (!File.Exists(bundleName) )
return null;
isBundle = new FileStream(bundleName, FileMode.Open, FileAccess.Read);
isBundle.Seek(64 + 8 * index, SeekOrigin.Begin);
//获取位置索引并计算切片位置偏移量
byte[] indexBytes = new byte[4];
isBundle.Read(indexBytes, 0, 4);
long offset = (long)(indexBytes[0] & 0xff) + (long)(indexBytes[1] & 0xff) * 256 + (long)(indexBytes[2] & 0xff) * 65536
+ (long)(indexBytes[3] & 0xff) * 16777216;
//获取切片长度索引并计算切片长度
long startOffset = offset - 4;
isBundle.Seek(startOffset, SeekOrigin.Begin);
byte[] lengthBytes = new byte[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;
//根据切片位置和切片长度获取切片
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
tileBytes = new byte[length];
int bytesRead = 0;
if (length > 4)
{
bytesRead = isBundle.Read(tileBytes, 0, tileBytes.Length);
}
else
{
tileBytes = null;
}
}
catch (Exception ex)
{
return null;
}
finally
{
if (isBundle != null)
{
isBundle.Close();
}
}
return tileBytes;
}