• 百度地图离线化(API v=1.3)


      毕设(北斗导航项目)进行了一段时间,近日在实验室给老师汇报进展时,由于网络不畅,加载百度在线地图及其各种操作时,时间过长,于是想将百度地图离线化。查阅网上很多资料,有的是广告(卖GIS应用的),有的版本太久......最后参考网上两位前辈的博客内容,加以实践,实现了地图完全离线且能进行基本操作。趁周末整理了实践过程并记录下来,希望能帮到有需要的朋友。

      :感谢两位前辈,其原文为:开源中国:Web版百度地图加载离线瓦片 ;csdn:使用百度地图JS API构建离线地图应用(完整教程)

      原文附带Demo,大家可以参考下,注意版本:百度离线地图Demo

    具体实现步骤:

      前期工作:构建在线地图应用(版本API v1.3,其他版本未测试,如需要可自行研究)。

    准备好放源码的文件夹(可为中文),在其中建立三个文件夹:js、css、images,用于存放下面的文件。(基础API下载地址:apiv1.3.min.js ;css文件下载地址:bmap.css )

      先建立一个简单的在线地图应用,如下:

     1     <!DOCTYPE html>  
     2     <html>  
     3     <head>  
     4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
     5     <title>DEMO</title>  
     6     <!--script type="text/javascript" src="js/apiv1.3.min.js"></script-->  
     7     <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script>  
     8     <link rel="stylesheet" type="text/css" href="bmap.css"/>  
     9     </head>  
    10     <body>  
    11     <div style="520px;height:340px;border:1px solid gray" id="container"></div>  
    12     </body>  
    13     </html>  
    14     <script type="text/javascript">  
    15     var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP});  
    16     var point = new BMap.Point(116.404, 39.915);    // 创建点坐标  
    17     map.centerAndZoom(point,5);             // 初始化地图,设置中心点坐标和地图级别。  
    18       
    19     //map.addControl(new BMap.MapTypeControl());  
    20     map.addControl(new BMap.NavigationControl());  
    21     map.enableScrollWheelZoom();                  // 启用滚轮放大缩小。  
    22     map.enableKeyboard();                         // 启用键盘操作。   
    23     </script>  

    以上代码运行效果如图:

    观察其向网络请求的文件:(我使用的是Firefox浏览器的Firbug插件)

     

    这些需离线的资源文件主要有三类:图标素材、依赖模块API文件、瓦片地图文件,后面会写到详细步骤。

    接下来,进入正式工作。


      第一步:访问前期工作中的第一个入口:http://api.map.baidu.com/api?v=1.3,其内容如下:

    1 function(){window.wise=1;window.netSpeed=254;window.netType=1; window.BMap_loadScriptTime = (new Date).getTime(); 
    2 document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=1.3&ak=&services=&t=20150527115231"></script>');
    3 document.write('<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/13/bmap.css"/>');})();

    这一步将获得一个js文件的位置和一个css文件的位置,然后分别下载下来,放在准备好的文件夹里面,我分别存储在/js和/css里面。js的路径后面有若干参数,不管,下载下来的文件重新命名就好,比如js文件命名为apiv1.3.min.js

      第二步:修改这个js中的代码。由于代码是压缩在一行上的,可通过网上的代码在线格式化。

    (我是使用了这个网站的工具JS/HTML/CSS格式化:http://tool.chinaz.com/tools/jsformat.aspx

    注意:修改文件的时候,建议与提供的Demo中的文件对比,并非全按以下的修改方式

    1、搜索变量:“imgPath”,直到找到一段代码

    1 var x=m?"https://sapi.map.baidu.com/":"http://api.map.baidu.com/";
    2 var cd={imgPath:x+"images/",cityNames:{"u5317u4eac":"bj",

      把imgPath:x+"images/"中的x去掉即可,这样就变成了跟网络地址无关的相对位置了。这里指出的images文件夹,是与将来的html文件夹平行的目录里面的。

    2、搜索变量:“_baseUrl”,直到找到这样的一段代码

    preLoaded:{},Config:{_baseUrl:x+"getmodules?v=1.3",_timeout:5000},

      同样,要去掉x,这个x也是前面这段代码中的x。同时,不仅要去掉x,更要把地址指向js目录。

    1 preLoaded:{},Config:{_baseUrl:"js/",_timeout:5000},

      这个地址用来动态加载组件。系统中用到哪些组件,就下载加载哪些组件。最终系统会访问类似于“http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control,marker”的url加载组件。

     3、继续搜索下一个“_baseUrl”,得到下面的代码:

    1 window.setTimeout(function(){var cP=cN.Config._baseUrl+"&mod="+cN.Module._arrMdls.join(",");cy.request(cP);cN.Module._arrMdls.length=0;cN.delayFlag=false},1)

      直接修改cP变量,注意:这里把加载地址直接写死

    1 var cP=cN.Config._baseUrl+"modules";cy.request(cP);

      这样,我们把动态加载编程手动加载了。我们访问这个地      址“http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control,marker,poly”就可以拿到一个js文件了。把它重命名为上面指定的“modules”,丢在js文件夹里面即可。后面会详细说明加载模块这个问题。

      注意:如果需要更多的功能,我是通过重新加载以上的地址,其它的教程写说不需要自动加载,通过另外配置参数获取相关的功能就好,我没亲自配置过,有配置过的小伙伴可以讲讲配置过程。

    4、关键的一步:搜索“getTilesUrl”直到找到这样的一段(参照物也可以另选,比如“BMAP_NORMAL_MAP”):

     1  aU.getTilesUrl = function(cN, cQ) {
     2         var cR = cN.x;
     3         var cO = cN.y;
     4         var T = "20150518";
     5         var cP = "pl";
     6         if (this.map.highResolutionEnabled()) {
     7             cP = "ph"
     8         }
     9         var cM = j[Math.abs(cR + cO) % j.length] + "?qt=tile&x="
    10                 + (cR + "").replace(/-/gi, "M") + "&y="
    11                 + (cO + "").replace(/-/gi, "M") + "&z=" + cQ + "&styles=" + cP
    12                 + (a9.browser.ie == 6 ? "&color_dep=32&colors=50" : "")
    13                 + "&udt=" + T;
    14         return cM.replace(/-(d+)/gi, "M$1")
    15     };
    16     window.BMAP_NORMAL_MAP = new cv("u5730u56fe", aU, {
    17         tips : "u663eu793au666eu901au5730u56fe"
    18     });

      “getTilesUrl”这个方法,这里就是返回瓦片未知的关键方法。两个参数中,第一个参数是{x,y},第二个参数就是z,这样xyz就都有了。

      直接把它计算出来的cM的结果重新计算一下,改成:

    1 //这个地方废弃了上面的计算结果,直接采用本地图片
    2 cM = "tiles/" + cQ + "/" + cR + "/" + cO + ".jpg";

      开始建立第四个文件夹,tiles。这个文件夹里面的内容和后面的资源文件请在附件中下载。至于如何下载瓦片,问百度。至此,该文件的处理结束。

      第三步:下载资源文件。(终于到资源文件的详细介绍了,前期工作中提到)

      1、图片文件:可以通过前期工作的第二张图的方式获取素材的下载地址,也可从Demo文件/images路径下获取,还有一种方式,引用前辈教程中的话:

    查找bmap.css里面所有的图片文件,下载下来放在指定的文件夹里面就好了。里面总共不超过两三个文件,下载下来放在 images文件夹里面就行了。另外,刚才的这个js里面也有一些资源文件,也下载下来放在images文件夹里面。这个通过搜索imgPath就能找 到,有png,有gif,有点文件可能需要通过https的地址才能下载的到。

      得到基本的图标素材后,将之前所下载的bmap.css文件里面图片的url修改为本地路径。

      2、依赖模块API文件(very very important!)

      如果缺少某个依赖模块,则无法使用相应的API。以下为引用前辈教程的原话:

    这个请求文件的原理是根据你在自己页面中使用的API来向官网请求相应的依赖模块API,参数的字符串格式是根据所使用依赖模块的顺序生成“模块名”以“,”分隔。

      在运行前期工作中的在线地图时,就可发现,依赖的库参数是什么。例如:以下的代码运行,所请求的依赖库参数是http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control

     1 <script type="text/javascript">  
     2 var map = new BMap.Map("container",{mapType:BMAP_NORMAL_MAP});  
     3 var point = new BMap.Point(116.404, 39.915);    // 创建点坐标  
     4 map.centerAndZoom(point,5);                     // 初始化地图,设置中心点坐标和地图级别。  
     5       
     6 //map.addControl(new BMap.MapTypeControl());  
     7 map.addControl(new BMap.NavigationControl());  
     8 map.enableScrollWheelZoom();                  // 启用滚轮放大缩小。  
     9 map.enableKeyboard();                         // 启用键盘操作。    
    10 //map.setCurrentCity("北京");          // 设置地图显示的城市 此项是必须设置的  
    11 </script>  

      我在自己操作过程中的依赖库命名为modules(可修改,但与前面修改的JS文件要匹配),在Demo文件/js路径下,里面已有map,oppc,tile,control,menu,marker,infowindow这些模块,如第二步的第3小步所述,后期可根据需要重新下载,或重新配置,我是直接重新下载。

      再强调一次,地址为:http://api.map.baidu.com/getmodules?v=1.3&mod=模块名,根据自己需要,将内容添加到modules文件中,或重新下载,也可以全部下载下来放入modules文件中。

      以下为前辈文章中提到的依赖模块名称、下载瓦片地图文件方法。(我没试过他的,有兴趣的可尝试)

    1、所有依赖模块名称如下:(引前辈教程中的图和内容,有谁知道这个图是哪来的么?)


    2、Demo文件中的modules文件中在map模块部分已经去掉了百度版权信息


    如有需要,可以直接使用此文件的map部分去除百度版权。

    然后将此资源文件的请求路径改为本地,需要在之前下载的apiv1.3.min.js中修改,由于细节较多这里就不详细描述了,建议直接使用Demo文件中已修改好的apiv1.3.min.js文件。(如有兴趣的话可以通过“代码比较软件”与之前下载apiv1.3.min.js进行比较找到修改之处)

    3、下载瓦片地图文件(tile)

    这里提供一个下载瓦片地图的软件——全能电子地图下载器1.9.5.zip ,里面包含有注册机,安装过程就不描述了。

    这里是使用说明——使用说明(虽然软件声明能下载的地图类型比较多,但好像只有百度地图能正常使用)

    根据自己需要下载瓦片地图后直接拷贝到Demo文件/maptile路径下(将原有的文件删除)

    最后:经历了几天,从查阅资料到完成初步的离线地图的功能,和自己的软件融合后,有些标注的功能还不太完善,如下图,瓦片地图因为没注册机,所以图上很多广告,且没下载完整的瓦片地图。暂时先总结了这部分离线操作,分享下自己的成果。

    第一次写博客,写好久呀。。。^_^

  • 相关阅读:
    检查所有资产的剩余折旧年限
    如何返回standard API 的错误信息
    Host concurrent的建立方法
    Project的目录结构
    计划外折旧(unplanned deprn)API开发例程
    UML学习笔记
    ASP.Net2.0使用Log4Net(二)
    NBear学习笔记(一)
    ASP.Net2.0使用Log4Net(一)
    ASP.net前后台调用
  • 原文地址:https://www.cnblogs.com/wmcnblogs/p/5398724.html
Copyright © 2020-2023  润新知