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


    系列文章目录

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

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

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

    1.前言

            上篇介绍了webgis动态加载解析紧凑型切片的例子,现在我们使用逆向思维实现紧凑型切片转分散型切片,在实际工作中很有用处,紧凑型切片易于拷贝,但读取只有部署到Arcgis Server才行。相比分散型切片很通用可以部署在类似Geoewebcache的地图缓存服务器或者也可以直接部署到web服务器下。

           软件核心功能:

    image

    (1)支持切片等级范围选择。

    (2)支持切图范围的选择,有利于局部数据的更新。

    (3)支持多线程解析,充分利用系统资源,加快解析速率。

    (4)文件命名格式与Arcgis分散型切片相同。

    2.核心代码解析

            1.首先要解析将输入的坐标转为切片对应x、y、z值

    /// <summary>
    /// 通过经纬度获取切片位置
    /// </summary>
    /// <param name="lat_deg">纬度</param>
    /// <param name="lon_deg">经度</param>
    /// <param name="zoom">切片等级</param>
    private double[] ConvertTile(double lat_deg, double lon_deg, int zoom)
    {
         double lat_rad = (Math.PI / 180) * lat_deg;
         double n = Math.Pow(2, zoom);
         double xtile = Math.Floor((lon_deg + 180.0) / 360.0 * n);
         double ytile = Math.Floor((1.0 - Math.Log(Math.Tan(lat_rad) + (1 / Math.Cos(lat_rad))) / Math.PI) / 2.0 * n);
         return new double[2] { xtile, ytile };
    }

           2.通过左上角坐标和右上角坐标,解析出指定切片等级下的所有紧凑型切片文件

    /// <summary>
    /// 获取某一切片等级下的文件对象
    /// </summary>
    /// <param name="level"></param>
    /// <param name="xy">【x1,y1,x2,y2】</param>
    /// <returns></returns>
    private List<BundleModel> GetLevelBundle(int level, int[] xy)
    {
         List<BundleModel> bundleModelList = new List<BundleModel>();
         int minx = ((xy[0] + 1) / 128) * 128;
         int maxx = ((xy[1] + 1) / 128) * 128;
         int miny = ((xy[2] + 1) / 128) * 128;
         int maxy = ((xy[3] + 1) / 128) * 128;
         int xcount = (maxx - minx) / 128 + 1;
         int ycount = (maxy - miny) / 128 + 1;
         for (int x = 0; x < xcount; x++)
         {
             for (int y = 0; y < ycount; y++)
             {
                 BundleModel bm = new BundleModel();
                 bm.StartX = minx + (x) * 128;
                 bm.StartY = miny + (y) * 128;
                 var rGroup = Convert.ToInt32(128 * Convert.ToInt32(bm.StartX / 128));
                 var cGroup = Convert.ToInt32(128 * Convert.ToInt32(bm.StartY / 128));
                 var bundleBase = getBundlePath(textBox1.Text, level, rGroup, cGroup);
                 bm.Level = level;
                 bm.BundlxDire = bundleBase + ".bundlx";
                 bm.BundleDire = bundleBase + ".bundle";
                 bm.BundleName = Path.GetFileNameWithoutExtension(bm.BundleDire);
                 bundleModelList.Add(bm);
             }
         }
         return bundleModelList;
    }

        3.多线程切片实现,将文件平均分给不同线程

    //将文件平均分给各个线程
    int count = bundleModelList.Count() / threadcount;
    int yu = bundleModelList.Count() % threadcount;
    
    if (count == 0)
    {
         for (int i = 0; i < bundleModelList.Count; i++)
         {
             List<BundleModel> model = bundleModelList.Skip(i).Take(1).ToList();
             System.Threading.ThreadPool.QueueUserWorkItem((state) =>
             {
                 foreach (var item in model)
                 {
                     ToImg(item);
                 }
                 this.BeginInvoke(new Action(() =>
                 {
    
                }));
             }, model);
         }
    }
    else
    {
         for (int i = 0; i < threadcount; i++)
         {
             List<BundleModel> model = bundleModelList.Skip(i * count).Take(count).ToList();
             if (i < yu)
             {
                 model.AddRange(bundleModelList.Skip(threadcount * count + i).Take(1).ToList());
             }
             System.Threading.ThreadPool.QueueUserWorkItem((state) =>
             {
                 foreach (var item in model)
                 {
                     ToImg(item);
                 }
                 this.BeginInvoke(new Action(() =>
                 {
    
                }));
             }, model);
         }
    }

        4.Arcgis散片文件路径格式的生成

    string L="L"+ zeroPad(z, 2);
    string C = "C" + zeroPad(x, 8,1);
    string R = "R" + zeroPad(y, 8,1);
    
    //保存路径
    string path = textBox2.Text+"\"+L+"\"+R+"\"+C+ ".png";
    
    //文件命名函数
    
    private string zeroPad(int num, int len,int type=0)
    {
         string str = num.ToString();
         if (type==1)
         {
              str = num.ToString("X");
         }
         while (str.Length < len)
         {
             str = "0" + str;
         }
         return str;
    }

    解析结果展示

    image

    3.结束

         开启多线程模式切片的速率比较满意,通过比较简单的代码理解了紧凑型切片的所有的细节,我们现在完全可以实现散片型装紧凑型的文件,有兴趣可以反推一下。所有的源代码已近上传到了GitHub,欢迎大家指教。

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

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

    作者:ATtuing

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

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

  • 相关阅读:
    HashMap原理
    高并发架构系列:MQ消息队列的12点核心原理总结
    大话程序员系列:一张图道尽程序员的出路
    java面试题
    SpringBoot框架的使用
    java开发定时任务执行时间
    OpenLayers 3 扩展插件收集
    Vue-cli webpack模板
    Spring的属性文件properties使用注意
    FullBg-网页图片背景自适应大小
  • 原文地址:https://www.cnblogs.com/ATtuing/p/10438713.html
Copyright © 2020-2023  润新知