logo资料库

天地图如何转成ARCGIS紧凑型切片.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
天地图如何转成ARCGIS
1.切片方案
3.1切片方案原点
3.2切片宽度和高度
3.3DPI
2.切片方案缓存文件结构
3.bundle和bundlx文件
3.1命名规则
3.2bundlx文件结构
3.3bundle文件结构
4.简单写入算法
天地图如何转成 ARCGIS 紧凑型切片 1. 切片方案 切片方案包括缓存的比例级别、切片尺寸和切片原点。这些属性定义缓 存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要。图 像格式和抗锯齿等其他属性也会写入切片方案,但对于客户端应用程序能否 成功叠加切片没有影响。 3.1 切片方案原点 切片方案原点是指切片方案格网的左上角,默认原点为地图文档定义的 坐标参考的左上点。原点不一定代表创建切片的起始点;只有在达到地图全 图范围时才是这样。进行缓存时使用公用切片方案原点可确保所创建的缓存 能够在 Web 应用程序中相互叠加。注意,切片是从地图的全图开始切的,不 是从切片方案原点(切片方案原点落在地图原点右下方另算)。 另外一点,我经过试验,发现切片的行列号是从 0 开始算起的。
3.2 切片宽度和高度 切片的默认宽度和高度为 256 像素。 3.3 DPI 每英寸点数 (Dot Per Inch) ,是指服务器将生成的缓存切片的分辨 率。即生成的图片每英寸长度内的像素点数。默认为 96。
2. 切片方案缓存文件结构 缓存目录 -> 地图服务名 ->地图数据框名称(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 3. bundle 和 bundlx 文件 bundle 文件中存储的是图片文件,bundlx 文件中则存储了各个图片文 件在 bundle 文件中的偏移量。
3.1 命名规则 bundle 文件的命名都是:R 数字 C 数字。R 代表起始的 Row,C 代表 起始的 Column。数字均为 16 进制。 行和列如果不满 4 位,则前面补 0,位数多了不限。如 R22e80C14400,表示这个 bundle 文件的起始切片是 0x22e80 行 0x14400 列。 3.2 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 列……
3.3 bundle 文件结构 这个文件我比较了好半天才找到这些规则。 首先是文件的开头,从 0x00 到 0x3b 的这些位置都是 bundle 文件的描 述信息:(还是以 R22e80C14380.bundle 为例) 其中:16-19 位,表示非空文件个数*4 开头以后紧接着从 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 个字节之后取这些长度的字节就组合成了一副图像,如果要查找 的话返回即可。 4. 简单写入算法 读取时直接按照 level 和 row、column 计算出 bundle 文件名,按照上 面的计算方法找到对应 Image 返回即可,这里只说明一下我自己的切片的方 法。针对单个 LODInfo 计算 map 的 Tile 范围 int startCol = (int)Math.Floor((double)(((envelope.XMin - x) + (lod.Resolution * 0.5)) / (resolution * this.TileInfo.Width))); int startRow = (int)Math.Floor((double)(((y - envelope.YMax) + (lod.Resolution * 0.5)) / (resolution * this.TileInfo.Height))); int endCol = (int)Math.Floor((double)(((envelope.XMax - x) - (lod.Resolution * 0.5)) / (resolution * this.TileInfo.Width))); int endRow = (int)Math.Floor((double)(((y - envelope.YMin) - (lod.Resolution * 0.5)) / (resolution * this.TileInfo.Height)));map跨越的bundle文件范围 //左上角的 bundle 文件开始行列号 long ltBundleRow = this.m_packetSize * (startRow / this.m_packetSize); long ltBundleCol = this.m_packetSize * (startCol / this.m_packetSize); //右下角(最后一个)的 bundle 文件开始行列号(由于上面的第 9.0 行 已经归为第 9 行,所以直接算就是对的) long rbBundleRow = this.m_packetSize * (startRow / this.m_packetSize);
分享到:
收藏