zoukankan      html  css  js  c++  java
  • 移动端H5地图离线瓦片方案(1)(2)

    2在作者另一篇

    移动端H5地图离线瓦片方案

     

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

    1.背景

    移动端的网速和流量耗费是移动开发必须考虑的两个点。常规的瓦片展示方案是移动端实时请求在线瓦片服务(瓦片放在服务器端供直接读取,或者瓦片由地理服务器发布成WMTS服务等)。这个方案存在两个问题:

    * 瓦片实时请求加载受限于移动端网速,容易导致加载卡顿现象

    * 瓦片请求耗费手机流量。

    试想,如果我们将切图瓦片提前存放到移动设备上,每次瓦片请求时直接读取设备缓存瓦片,不仅可以提高瓦片加载效率,也可以规避流量的耗费。目前各大地图厂商也都提供了地图下载功能,使得手机即使在无网环境下依然可以照常使用地图。

    2.方案研究点

    • JS无法直接读取移动端本地文件,如何进行本地瓦片获取
    • 避免下载全部瓦片导致的数据量过大,如何实现瓦片基于单元网格(最小打包单元,相对稳定,避免使用责任网格打包后由于网格变动导致的重复工作量)的打包,如何基于单元网格瓦片生成责任网格的打包,并实现上传更新。
    • 瓦片为规则矩形,如何实现在移动端只显示不规则面(责任网格)内的地图信息,即裁剪显示

    3.JS读取手机本地瓦片文件的解决方法

    3.1方法描述

    • 与手机研发定义读取本地瓦片时的固定URL前缀,手机程序监听所有请求,当匹配上该固定前缀时,则表明手机程序需进行文件读取,如:
      var offlineURL = "http://mobile.test.com.cn/tile? "
    • 请求参数带有瓦片级别、行、列、文件名参数。手机程序解析这些参数,读取本地对应瓦片,并将数据返回

    3.2优化

    请求参数中增加瓦片服务端获取URL,当手机本地没有寻找到对应瓦片时,则触发服务端获取的URL,从服务端获取瓦片后再缓存至手机本地,如:

    var offlineURL = "http://mobile.test.com.cn/tile?raw="
    url = offlineURL+encodeURIComponent(url)+"&level="+level+
    "&row="+row+"&col="+col+"&layername="+(this.get("mobileCacheName")||"");

    对在线URL进行编码(可将URL中的特殊符号转换),便于手机程序获取raw参数对应的值。

    4.基于网格图层的瓦片打包工具

    4.1工具设计思路

    • 获取瓦片切图的具体参数:包含各级别比例尺、切图原点、瓦片大小
    • 遍历网格图层获取图层各要素,获得各要素的四角范围
    • 通过切图参数以及要素的四角范围,算出该范围所对应的所有瓦片,将这些瓦片保留原有文件组织结构拷贝至目录文件夹下。遍历处理所有要素对应的四角范围瓦片。

    • 将目标文件夹压缩成一个文件

            

        public static int getXTileIndex(double x,double originx,double resolution,double size)
            {
                double d = (x - originx) / (resolution * size);
                int index = (int)Math.Floor(Math.Abs(d));
                return index;
            }
    
            public static int getYTileIndex(double y, double originy, double resolution, double size)
            {
                double d = (y - originy) / (resolution * size);
                int index = (int)Math.Floor(Math.Abs(d));
                return index;
            }
    
            public static String calcPath(String dir,int level,int yindex,int xindex)
            {
                StringBuilder sb = new StringBuilder(dir).Append("\").Append("L");
                sb.Append(padLeft(Convert.ToString(level, 16), 2, '0'));
                sb.Append("\").Append("R").Append(padLeft(Convert.ToString(yindex, 16), 8, '0'));
                sb.Append("\").Append("C").Append(padLeft(Convert.ToString(xindex, 16), 8, '0'));
                sb.Append(".png");
                return sb.ToString();
            }
    
            private static String padLeft(String str, int size, char symbol)
            {
                if (str == null)
                    str = "";
                int str_size = str.Length;
                int pad_len = size - str_size;
                StringBuilder retvalue = new StringBuilder();
                for (int i = 0; i < pad_len; i++)
                {
                    retvalue.Append(symbol);
                }
                return retvalue.Append(str).ToString();
            }

    4.2工具展示

    5.手机服务端进行瓦片整合以及上传

    5.1基于单元网格切片合成责任网格切片

    单元网格的切片组织如下:

    即:网格编码_alllayerslevel owcol.png
    所以,服务端进行责任网格瓦片合并方法如下:

    • 读取责任网格与单元网格的对应关系表,获取每个责任网格编码对应的所有单元网格编码
    • 在单元网格切片文件夹中找到所有对应的单元网格编码切片文件夹
    • 以增量覆盖方式,将各单元网格文件夹中的文件(从_allLayers文件夹至下)进行合并,合并后的文件存放至责任网格编码的文件夹下
    • 将各责任网格文件分别压缩

    5.2责任网格瓦片打包上传

    服务端修改更新配置,当移动端再次启动时,依据不同移动端所属的责任网格区域进行对应的瓦片下载和解压。

    6.成果展示

     

    7.前端优化展示效果——遮罩展示

    由于瓦片是规则四边形,而区域是不规则多边形,所以全图浏览时会出现太多不在区域范围内的数据。 这里可以使用遮罩的思想进行处理:制作一个很大的四边形,然后以区边界要素为内环,两者结合构成一个环状要素。叠加在地图上时,把多边形环要素设置为背景色,这可以变相实现遮罩效果。

     

                                                                                     -----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

  • 相关阅读:
    开工--行胜于言
    操作系统之内存管理
    C陷阱与缺陷读书笔记(一)
    关于复杂度的一些基本的定义
    归并排序
    快速排序
    前序中序后序非递归遍历
    直接插入排序
    冒泡排序
    程序内存映像
  • 原文地址:https://www.cnblogs.com/yelongsan/p/8690076.html
Copyright © 2011-2022 走看看