zoukankan      html  css  js  c++  java
  • ArcGIS紧凑型切片读取与应用1-解析(附源码)

    系列文章目录

    ArcGIS紧凑型切片读取与应用1-解析(附源码)

    ArcGIS紧凑型切片读取与应用2-webgis动态加载紧凑型切片(附源码)

    ArcGIS紧凑型切片读取与应用3-紧凑型批量转分散型(附源码)

    1.前言

         ArcGIS 发布的切片服务分为紧凑型切片和传统的分散型切片以及最新ArcGIS por新增的矢量切片。传统的分散型切片面临的问题是文件个数太多,部署拷贝过程十分的耗时,紧凑型切片是对分散型切片进行压缩处理的。一个.bundle文件可以存上万张切片,有利于部署拷贝,.bundlx文件提供切片索引。本教材分为三个模块依次是

    (1)文件解析。

    (2)webgis动态加载紧凑型切片。

    (3)紧凑型批量转分散型。

    下面是对紧凑型切片解析的过程,实现使用的c#代码。

    2.解析

        解析过程我是参考github上的一个就node.js实现的开源项目,项目地址:https://github.com/fuzhenn/tiler-arcgis-bundle,现在进入解析过程,在8级切片下面紧凑型文件的切片目录如下。

    TIM截图20190225135339

         大家可以发现所有.bundlx切片索引文件大小都是81kb,查阅资料发现每个切片索引都存放着128*128个切片的索引地址。但是并不是每个.bundle文件都有128*128个切片,例如1级切片只有4个图片,其余位置会为空字节表示。解析方式就是通过切片的X,Y,Z作为参数解析出对应的索引文件名称,然后从索引文件读取切片的索引位置,最后切片文件中读取对应字节流,保存成图片即可,流程如下。

    TIM截图20190225151354

    核心实现代码如下:

    1.通过xyz获取文件名称与路径

    /// <summary>
    /// 查找切片对应的文件路径
    /// </summary>
    /// <param name="root">路径</param>
    /// <param name="level">切片等级</param>
    /// <param name="rGroup"></param>
    /// <param name="cGroup"></param>
    /// <returns></returns>
    private string getBundlePath(string root,int level, int rGroup , int cGroup ) {
         var bundlesDir = root;
         var l = level.ToString();
         var lLength = l.Length;
         if (lLength < 2)
         {
             for (var i = 0; i < 2 - lLength; i++)
             {
                 l = "0" + l;
             }
         }
         l = "L" + l;
    
        var r = rGroup.ToString("X");
         var rLength = r.Length;
         if (rLength < 4)
         {
             for (var i = 0; i < 4 - rLength; i++)
             {
                 r = "0" + r;
             }
         }
         r = "R" + r;
    
        var c = cGroup.ToString("X");
         var cLength = c.Length;
         if (cLength < 4)
         {
             for (var i = 0; i < 4 - cLength; i++)
             {
                 c = "0" + c;
             }
         }
         c = "C" + c;
         var bundlePath=string.Format  (@"{0}\_alllayers{1}{2}{3}", bundlesDir,
             l, r, c);
         return bundlePath;
    }

    2.通过xy获取索引值

     int packSize = 128;
    
    var rGroup = Convert.ToInt32(packSize * Convert.ToInt32(y / packSize));
    var cGroup = Convert.ToInt32(packSize * Convert.ToInt32(x / packSize));
    
    context.index = packSize * (x - cGroup) + (y - rGroup);

    3.通过读取索引文件,根据索引值获取切片索引位置

    /// <summary>
    /// 读取切片
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private byte[] readTileFromBundleV1(bundlx context)
    {
         var bundlxFileName = context.bundlxFileName;
         var bundleFileName = context.bundleFileName;
         var index = context.index;
         using (FileStream file = new FileStream(bundlxFileName, FileMode.Open))
         {
             byte[] buffer = new byte [5];
             byte[] bufferfile = new byte[file.Length];
             file.Read(bufferfile,0,(int)file.Length);
             //读取bundlx文件存储该切片的位置
             buffer = bufferfile.Skip(16 + 5 * index).Take(4).ToArray();
             //偏移量
             var offset = BitConverter.ToInt32(buffer,0);
            return readTile(bundleFileName, offset);
         }
    }

    4.读取具体切片数据

      /// <summary>
            /// 读取切片对应字节
            /// </summary>
            /// <param name="bundleFileName"></param>
            /// <param name="offset"></param>
            /// <returns></returns>
            private byte[] readTile(string bundleFileName,int offset)
            {
                using (FileStream file = new FileStream(bundleFileName, FileMode.Open))
                {
                    byte[] buffer = new byte[4];
                    byte[] bufferfile = new byte[file.Length];
                    file.Read(bufferfile, 0, (int)file.Length);
                    //获取bundle具体切片文件字节数
                    buffer = bufferfile.Skip(offset).Take(4).ToArray();
                    var length = BitConverter.ToInt32(buffer,0);
                    byte[] tileData = new byte[length];
                   //根据索引和字节数读出文件位置
                    tileData = bufferfile.Skip(offset + 4).Take(length).ToArray();
                    return tileData;
                }
            }

    3.成果

    将字节流保存成.png图片输出,对应项目image项目,代码已经上传Github,下篇写一下webgis动态加载紧凑型切片。

    image

    百度网盘链接:https://pan.baidu.com/s/1I-Bj3EQSN57pQHvKZ2hBUA   提取码:lliw

    github项目地址:https://github.com/HuHongYong/TilerArcgisBundle

    作者:ATtuing

    出处:http://www.cnblogs.com/ATtuing

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。


     

  • 相关阅读:
    java数组
    java 常用类
    java 集合(一)
    mysql相关操作(一)
    记录java BigDecimal
    hxg-yw
    一个困惑我好久的问题
    关于重载和重写的一些小知识
    几个常用的HTTP状态码
    死锁产生的原因和条件简述
  • 原文地址:https://www.cnblogs.com/ATtuing/p/10432472.html
Copyright © 2011-2022 走看看