Web版百度地图加载离线瓦片

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web版百度地图加载离线瓦片相关的知识,希望对你有一定的参考价值。

注:本文参考网络教程,瓦片也是通过网络下载。向原作者致敬!原作地址:http://download.csdn.net/download/dkm8873/9233731

原作版本已久,由于代码混淆压缩,无法添加标记等特性。本文通过修改最新的 代码达到离线版的目的,而且功能可以任意扩充。本文每一个步骤都经过试验,万无一失。

 

点此直接下载完整版Demo代码

先准备好一个放置源码的文件夹,然后将获取的文件放进去。建立三个文件夹:js、css、images。

第一步,自然是访问一个入口:http://api.map.baidu.com/api?v=1.3

里面的内容是这样的(原本没有换行,为了阅读方便一点,加了两个回车):

(function(){ window.BMap_loadScriptTime = (new Date).getTime(); 
document.write(‘<script type="text/javascript" src=" 
document.write(‘<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/13/bmap.css"/>‘);})();

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

接下来要修改这个js中的一点代码了。由于代码是压缩在一行上的,因此修改起来有点麻烦。

  1. 搜索变量:“imgPath”,直到找到一段代码(同样加了一个回车):

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

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

 

2. 搜索变量:“_baseUrl”,直到找到这样的一段代码(这个比较简单)

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

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

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

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

下面会看到,我更直接的把加载地址都写死了。看第三步

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

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变量吧,写死好了,我就是这样做的:

var cP=cN.Config._baseUrl+"getmodules.js";cy.request(cP);

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

如果需要更多的功能,也不需要自动加载,反正都是本地的,另外配置参数获取相关的功能就好了。

3. 关键的一步,也是最复杂的一步:搜索“getTilesUrl”直到找到这样的一段(参照物也可以另选,比如“BMAP_NORMAL_MAP”):

if(this.map.highResolutionEnabled()){cP="ph"}var cM=j[Math.abs(cR+cO)%j.length]+"?qt=tile&x="+(cR+"").replace(/-/gi,"M")+"&y="+(cO+"").replace(/-/gi,"M")+"&z="+cQ+"&styles="+cP+(a9.browser.ie==6?"&color_dep=32&colors=50":"")+"&udt="+T;return cM.replace(/-(\d+)/gi,"M$1")};window.BMAP_NORMAL_MAP=

这段代码这么长,我格式化一下来看好了(代码截取比上面更长一些)

    aU.getTilesUrl = function(cN, cQ) {
        var cR = cN.x;
        var cO = cN.y;
        var T = "20150518";
        var cP = "pl";
        if (this.map.highResolutionEnabled()) {
            cP = "ph"
        }
        var cM = j[Math.abs(cR + cO) % j.length] + "?qt=tile&x="
                + (cR + "").replace(/-/gi, "M") + "&y="
                + (cO + "").replace(/-/gi, "M") + "&z=" + cQ + "&styles=" + cP
                + (a9.browser.ie == 6 ? "&color_dep=32&colors=50" : "")
                + "&udt=" + T;
        return cM.replace(/-(\d+)/gi, "M$1")
    };
    window.BMAP_NORMAL_MAP = new cv("\u5730\u56fe", aU, {
        tips : "\u663e\u793a\u666e\u901a\u5730\u56fe"
    });

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

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

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

这里意味着我们要建立第四个文件夹,tiles了。这个文件夹里面的内容和后面的资源文件请在附件中下载。至于如何下载瓦片,请自行百度吧。

OK了,这个文件的处理就结束了。

第二步:下载图片等资源文件。

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

 

第三步,写demo.html吧。这个直接贴代码。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>百度离线版DEMO</title>
<script type="text/javascript" src="js/apiv1.3.min.js"></script>
<!--script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script-->
<link rel="stylesheet" type="text/css" href="css/bmap.css"/>
</head>
<body>
<div style="width:520px;height:340px;border:1px solid gray" id="container"></div>
</body>
</html>
<script type="text/javascript">
var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP});      //设置卫星图为底图
var point = new BMap.Point(111.40440.915);    // 创建点坐标
map.centerAndZoom(point,5);                     // 初始化地图,设置中心点坐标和地图级别。

//map.addControl(new BMap.MapTypeControl());
map.addControl(new BMap.NavigationControl());
map.enableScrollWheelZoom();                  // 启用滚轮放大缩小。
map.enableKeyboard();                         // 启用键盘操作。  
//map.setCurrentCity("北京");          // 设置地图显示的城市 此项是必须设置的
var marker = new BMap.Marker(point);
map.addOverlay(marker); 
</script>

效果图:

技术分享

 

补记:

由于这个离线版的百度地图对IE支持不佳,现在已经查明原因,在于图片的格式和声明上。百度提供的tiles图片声称都是jpg格式的,但图片实际是png格式的,因此在IE下面就死板的认为要用jpg解码,结果无法解析。但IE对于网络的图片则按照实际的内容进行区分和解析,这个是没问题的,因为图片在网上完全可能是动态的,比如authcode.do之类的,就没有扩展名只说。看起来这是IE的问题了。

这样看来解决这个问题就好办了,更改文件扩展名!

这个可以通过cmd命令来完成。比如我的命令就是:

for /F %i in (‘dir /A:D /S /B‘) do copy "%i\*.jpg" "%i\*.png"

之所以用了拷贝,而不是直接重命名,还是想保留原文件。

这样前面第三步把扩展名改为“.png”,就ok了。

技术分享

以上是关于Web版百度地图加载离线瓦片的主要内容,如果未能解决你的问题,请参考以下文章

openlayers应用:加载百度离线瓦片

最全面的百度地图JavaScript离线版开发

百度地图api可以加载本地瓦片吗

离线地图解决方案:加载瓦片地图

基于cesium的百度、腾讯、高德数据访问

百度离线地图发布源代码