ArcGIS 切片缓存紧凑文件格式分析与使用
在ArcGIS 10中出现了一种新的切片缓存文件格式:紧凑型存储(Compact)。与之前的松散型存储(Exploded)相比,它有迁移方便、创建更快、减少存储空间等诸多优点,已经成为了创建切片缓存的默认格式。对于本身ArcGIS的产品而言,访问紧凑型存储与访问松散型存储没有任何区别,但是,如果第三方应用想访问新的切片格式,目前官方给出了“不可以”的答复:
The internal architecture of the bundle is not publicly documented by ESRI. If you've coded your own logic to pull tiles out of a virtual directory, you should continue to use the "exploded" format which stores each tile as a single file and was the only option at ArcGIS Server versions 9.3.1 and previous.
我Google了一下,也没有任何相关的资料,因此索性自力更生,自己分析一下紧凑型存储的格式,相信这是目前可以找到的关于紧凑型存储内部格式的唯一资料。
紧凑型存储的原理
紧凑型存储最主要的两种文件是bundle和bundlx文件,其中bundle文件用以存储切片数据,bundlx是bundle文件中切片数据的索引文件。
一个bundle文件中最多可以存储128×128(16384)个切片,但是创建切片缓存并不是一张张切片单独生成,而是以4096像素(无抗锯齿)或2048像素(有抗锯齿)为边长渲染的,如果我们选择的切片边长为256像素并开启了抗锯齿,那么每次ArcSOC进程创建的是一张以8×8(64)个切片拼接成的大图,然后切割后存入bundle文件中。
下图中,蓝色边框代表的是bundle文件,黑色格子是生成切片时拼接的大图,具体的每个切片在黑色格子中,图中并没有显示出来。
存储格式的分析
在分析紧凑型存储格式之前,我首先问自己,如果你要在一个bundle文件中存储内容,同时通过一个bundlx文件中存放索引应该怎么做?中规中矩的做法就是参考数据库的位图索引方式,在bundlx文件中用固定的几个字节标识一个切片在bundle文件中的状态(存储的偏移量和长度)。
观察ArcGIS生成的bundlx文件,每个文件都是一样的大小:81952字节。上面已经提到,每个bundle文件中最多存储16384个切片,虽然bundle文件中可能并没有这么多切片,但是,我猜测bundlx文件中必然是保留了所有者16384个切片的索引位置。粗略估计每个切片会占据大约5个字节,16384×5=81920字节,还多出32字节,猜测存储bundlx文件的标识信息。
通过对一个很存储切片很稀疏的bundlx文件的规律进行观察和猜测,确定了bundlx中文件起始16字节和文件结束16字节与索引无关,剩余的81920字节数据以5个字节的频率重复,构成了一个对bundle文件的索引。
本来以为这5个字节会保存bundle文件中切片数据的偏移和长度,但是发现5个字节表达的信息量可能不够,因此,我同时对bundle中的切片数据进行了一个分析。
我猜想文件并没有进行压缩处理,因此在文件中搜索PNG文件的文件头0x89504E47(我在创建缓存时选择了PNG24格式),发现果然如此。同时,每2个切片数据之间相隔了4个字节(切片数据我是用Exploded的图片直接进行比较的),通过猜想、尝试,发现这4个字节正好是以低位到高位的方式标示了后续这个切片数据的长度。
既然切片数据长度是在bundle文件中记录的,那么在bundlx文件中索引的必然只包括切片数据的偏移量,经过实验发现,bundlx中的5个字节也是以低位到高位的方式标示了数据的偏移量。
切片数据长度和数据偏移猜想应该是无符号的整数,后面的实践证明了这一点。
还有一个问题,bundlx中的每5个字节标示的到底是哪个切片的数据偏移?我的实验的结果是:按列排序:
1 |
129 |
… |
… |
2 |
130 |
||
3 |
131 |
||
… |
… |
||
… |
… |
||
128 |
256 |
16384 |
从上面的分析,我们如果知道了一个切片的级别、行号、列号,就可以通过bundlx首先找到bundle中切片内容的偏移,然后从bundle文件中取出4个字节的长度数据,再随后根据这个长度读取真实的切片数据。关于如何计算切片的行号、列号,以及bundle文件的命名方式,相对比较简单,这里就不详细叙述了。
使用第三方代码访问切片
基于对紧凑型切片存储格式的分析,我用Java写了一个服务进行验证。我这个服务接受3个参数,和ArcGIS Server Rest接口保持,分别是level、row、col,通过下面的代码从紧凑型切片存储中提取切片数据:
String l = "0" + level; int lLength = l.length(); if (lLength > 2) { l = l.substring(lLength - 2); } l = "L" + l; int rGroup = 128 * (row / 128); String r = "000" + Integer.toHexString(rGroup); int rLength = r.length(); if (rLength > 4) { r = r.substring(rLength - 4); } r = "R" + r; int cGroup = 128 * (col / 128); String c = "000" + Integer.toHexString(cGroup); int cLength = c.length(); if (cLength > 4) { c = c.substring(rLength - 4); } c = "C" + c; String bundleBase = String .format("%s/%s/%s%s", bundlesDir, l, r, c); String bundlxFileName = bundleBase + ".bundlx"; String bundleFileName = bundleBase + ".bundle"; int index = 128 * (col - cGroup) + (row - rGroup); FileInputStream isBundlx = new FileInputStream(bundlxFileName); isBundlx.skip(16 + 5 * index); byte[] buffer = new byte[5]; isBundlx.read(buffer); 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; FileInputStream isBundle = new FileInputStream(bundleFileName); isBundle.skip(offset); byte[] lengthBytes = new byte[4]; isBundle.read(lengthBytes); 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);
然后通过Flex API写了一个自定义的切片图层,重写了getTileURL方法:
override protected function getTileURL(level:Number, row:Number,col:Number):URLRequest { var url:String = "http://localhost:8777/restserver/tile/"+level+"/"+row+"/"+col; return new URLRequest(url); }
看个效果吧,算是对上述分析的验证:
ArcGIS 切片缓存紧凑文件格式分析与使用相关推荐
- ArcGIS 用渔网做数据偏移并切片缓存
渔网数据偏移 打开ArcMap,并打开数据 右击地块,选择数据框属性 在坐标系中选择WGS 1984(地理坐标系-World-WGS 1984),可进行搜索,点击应用再确定即可 点击数据管理工具-要素 ...
- arcgis xml 下载 切片_生成切片缓存切片方案
语法GenerateTileCacheTilingScheme_management (in_dataset, out_tiling_scheme, tiling_scheme_generation_ ...
- ArcGIS切片生成工具-ArcGIS缓存管理
文章目录 前言 使用说明 系统主界面 ArcGIS缓存切片生成步骤 设置 服务初始化 生成切片 更新缓存切片文件 系统版本 下载地址 系统支持 前言 通过ArcGIS平台进行地理信息系统开发的人员 ...
- arcgis中切片缓存(方案)的制作
在发布地图服务的时候,我们需要针对我们的数据制作一个切片缓存(方案).在arcgis中切片缓存(方案)格式为.xml.下面我们来看一下在arcgis中是如何制作切片缓存(方案). 首先需要将我们的数据 ...
- React框架+cesium加载GeoWebCache发布4326WMTS服务的ArcGIS切片图层请求400问题
前言 由于业务的要求,需要在前端展示个性化美化的地图底图,尝试使用mapbox的配置和其它方案去搞Geojson格式的,但是个性化比较麻烦,而且门槛较高,不好配置,于是本菜鸟使用arcMap来美化底图 ...
- arcgis制作瓦片地图_【转】ArcGIS地图缓存制作简介
ArcGIS地图缓存制作简介 制作好的电子地图只有发布为服务后才能为更多的用户所查看与使用.ArcGIS Server 为共享 GIS 资源(如地图)提供了一个平台,无论您是坐在同一间办公室使用 Ar ...
- arcgis xml 下载 切片_vue/cli3整合Cesium,加载离线arcgis 切片
最開始使用webpack進行cesium 集成, 出现了问题一大堆,最后只好选择传统的方法直接引入了,具体操作如下 一.安装cesium 首选创建一个测试项目 vue create vue-join- ...
- PE文件和COFF文件格式分析——导出表的应用——一种插件模型
可能在很多人想想中,只有DLL才有导出表,而Exe不应该有导出表.而在<PE文件和COFF文件格式分析--导出表>中,我却避开了这个话题.我就是想在本文中讨论下载Exe中存在导出表的场景. ...
- PE文件和COFF文件格式分析——RVA和RA相互计算
之前几节一直是理论性质的东西非常多.本文将会讲到利用之前的知识得出一个一个非常有用的一个应用.(转载请指明来源于breaksoftware的csdn博客) 首先我们说下磁盘上A.exe文件和正在内存中 ...
最新文章
- 学习linux要会mysql吗_linux 学习 mysql安装到连接
- yum与rpm的使用
- javaweb课程PSP(1)
- 离散数学及其应用第六版中文电子书和答案
- 汇编语言 - 实验 - 计算 (X+(Y*Z-100))/W
- python把工作簿拆分为工作表_使用Python和Pandas将Excel工作表拆分为单独的工作表...
- C/C++实现大数模指数运算-二进制算法(a^e mod m 当e特别巨大时...)
- 2020计算机行业就业职位及分析
- 互联网推荐系统比较研究
- 运算符、表达式和语句
- Git上传本地文件到服务器,git上传文件到远程服务器
- 海量向量搜索引擎 Milvus 开源啦
- 90% 前端都会的 ES6 简化代码技巧,你用过哪些
- bzoj 3238 差异
- openssl bio
- 计算机进位制转换方法,计算机进位数制及其转换方法和技巧
- C语言(APL指令)对mysql数据库的操作-----连接、读取、写入、修改、删除(保姆级讲解)
- JS判断客户端是Android还是iOS
- java wmf格式图片转png
- 带你深入了解Java!十七、超市会员管理系统!