制作百度离线地图

1、前言

最近公司要给政府机关做项目要用到地图但是只限局域网所以要用到离线地图,在网上搜索了一些有用的文章并成功制作成功百度离线地图,希望能帮助到大家。

2、百度离线地图制作思路

制作百度离线地图,分为6步:

  1. 下载百度JS API文件为本地文件;
  2. 屏蔽百度ak验证;
  3. 引用本地模块资源;
  4. 下载所需城市或地区瓦片;
  5. 按照想要的地区或城市切片;
  6. 加载瓦片改为本地离线瓦片;

2.1、下载百度JS API文件为本地文件

访问baidu map api地址,代码如下:

(function(){ window.BMap_loadScriptTime = (new Date).getTime(); document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=3.0&ak=&services=&t=20190527152033"></script>');})();

然后复制上面代码中的http://api.map.baidu.com/gets...,并访问该网址,如图所示:

clipboard.png

clipboard.png

打开之后我们格式化代码并下载该文件,文件暂时命名为:map_offline_api_v3.0_min.js

2.2、屏蔽百度ak验证

打开map_offline_api_v3.0_min.js文件,如下:

clipboard.png

    if (/^http/.test(a)) return; //修改  屏蔽ak验证,若调用外部资源直接返回
    if (b) {
      var c = (1e5 * Math.random()).toFixed(0);
      D._rd["_cbk" + c] = function(a) {
        b && b(a);
        delete D._rd["_cbk" + c];
      };
      a += "&callback=BMap._rd._cbk" + c;
    }

2.3、引用本地模块资源

百度地图提供的各种图层类,标记类,控件类等等都可以看作是modules,当你在地图中用到这些模块时,它会自动加载,因此我们需要先把这些模块的js文件下载下来,保存到本地。定位到下面代码,没数错的话,一共是41个模块。

var Tb = {
    map: "i5s0dw", //map_i5s0dw
    common: "jrzmva", //common_jrzmva
    style: "mqdswt", //style_mqdswt
    tile: "wetykw", //tile_wetykw
    groundoverlay: "zel1ht", //groundoverlay_zel1ht
    pointcollection: "52rldj", //pointcollection_52rldj
    marker: "15ipzq", //marker_15ipzq
    symbol: "bxzn24", //symbol_bxzn24
    canvablepath: "yjpor5", //canvablepath_yjpor5
    vmlcontext: "41oars", //vmlcontext_41oars
    markeranimation: "q1bipf", //markeranimation_q1bipf
    poly: "3zcxhi", //poly_3zcxhi
    draw: "fkup43", //draw_fkup43
    drawbysvg: "ijy5nj", //drawbysvg_ijy5nj
    drawbyvml: "aoibi5", //drawbyvml_aoibi5
    drawbycanvas: "aewn4o", //drawbycanvas_aewn4o
    infowindow: "anxyp0", //infowindow_anxyp0
    oppc: "upzuz4", //oppc_upzuz4
    opmb: "3awlxd", //opmb_3awlxd
    menu: "szrz5h", //menu_szrz5h
    control: "j4hynd", //control_j4hynd
    navictrl: "4m4vf2", //navictrl_4m4vf2
    geoctrl: "qesj1s", //geoctrl_qesj1s
    copyrightctrl: "nafalt", //copyrightctrl_nafalt
    citylistcontrol: "ppkbbr", //citylistcontrol_ppkbbr
    scommon: "wwss1q", //scommon_wwss1q
    local: "hptci0", //local_hptci0
    route: "5f530m", //route_5f530m
    othersearch: "txcc0b", //othersearch_txcc0b
    mapclick: "xh0ipo", //mapclick_xh0ipo
    buslinesearch: "cvs3i2", //buslinesearch_cvs3i2
    hotspot: "r1fl3s", //hotspot_r1fl3s
    autocomplete: "smbpgf", //autocomplete_smbpgf
    coordtrans: "dl5jov", //coordtrans_dl5jov
    coordtransutils: "4gcmt1", //coordtransutils_4gcmt1
    convertor: "p2frek", //convertor_p2frek
    clayer: "omtot3", //clayer_omtot3
    pservice: "4cfn3c", //pservice_4cfn3c
    pcommon: "f13wqp", //pcommon_f13wqp
    panorama: "pothz4", //panorama_pothz4
    panoramaflash: "3lrn0o" //panoramaflash_3lrn0o
  };

这时候就可以创建modules文件夹,添加所需模块的js文件,注意命名格式,js代码可以这么获取:

http://api0.map.bdimg.com/getmodules?v=3.0&mod=map_i5s0dw

保存js文件时文件名也是这样如:map_i5s0dw.js
clipboard.png

为了便于修改主文件里的一些内容,先创建一个map_load.js文件,加入下面代码:

var bmapcfg = {
  'imgext'      : '.jpg',   //瓦片图的后缀  根据需要修改,一般是 .png .jpg
  'tiles_dir'   : '',       //普通瓦片图的地址,为空默认在tiles/ 目录
};
 
var scripts = document.getElementsByTagName("script");
var JS__FILE__ = scripts[scripts.length - 1].getAttribute("src");  //获得当前js文件路径
bmapcfg.home = JS__FILE__.substr(0, JS__FILE__.lastIndexOf("/")+1); //地图API主目录
(function(){
  window.BMap_loadScriptTime = (new Date).getTime();
  //加载地图API主文件
  document.write('<script type="text/javascript" src="'+bmapcfg.home+'bmap_offline_api_v3.0_min.js"></script>');

在bmap_offline_api_v3.0_min.js文件中定位到

D.oa = D.url.proto + ("2" == D.Nt ? D.url.domain.main_domain_cdn.other[0] : D.url.domain.main_domain_cdn.baidu[0]) + "/";

将其所在行注释掉,加上这行

  D.oa = bmapcfg.home; //添加本地工具资源引用(离线路径)

如图:

clipboard.png

然后再通过 &mod 进行定位,注释掉其所在行,做如下修改:

clipboard.png

//   0 == a.length ? f.XJ() : pa(f.tF.$O + "&mod=" + a.join(","));
              if (a.length > 0) {
                for (i = 0; i < a.length; i++) {
                  mf = bmapcfg.home + "modules/" + a[i] + ".js";
                  pa(mf);
                  console.log("加载模块文件:" + mf);
                }
              } else {
                f.XJ();
              }

2.4、下载所需城市或地区瓦片

下载瓦片可以使用网上下载工具,百度密码:db49

clipboard.png

clipboard.png

下载的时候可以选择层级,越往下下载的瓦片图片越多,下载完成后,如图所示:

clipboard.png

2.5、按照想要的地区或城市切片


如果想知道如何切片可以参考此文章

2.6、加载瓦片改为本地离线瓦片

将刚才下载的瓦片tiles文件夹下的图片复制到本项目的titles文件夹下,如图所示:

clipboard.png

复制完成之后,按照下图修改代码:

clipboard.png

  Hd.getTilesUrl = function(a, b, c) {
    var e = a.x,
      a = a.y,
      f = Sb("normal"),
      g = 1,
      c = Gd[c];
    // this.map.Yw() && (g = 2);
    // e = this.map.oh.Uv(e, b).Ol;
    // return (
    //   Fd[Math.abs(e + a) % Fd.length] +
    //   "?qt=vtile&x=" +
    //   (e + "").replace(/-/gi, "M") +
    //   "&y=" +
    //   (a + "").replace(/-/gi, "M") +
    //   "&z=" +
    //   b +
    //   "&styles=" +
    //   c +
    //   "&scaler=" +
    //   g +
    //   (6 == z.ga.ma ? "&color_dep=32&colors=50" : "") +
    //   "&udt=" +
    //   f
    // ).replace(/-(\d+)/gi, "M$1");
    let tdir = bmapcfg.tiles_dir.length ? bmapcfg.tiles_dir : bmapcfg.home + "tiles";
    return tdir + "/" + b + "/" + e + "/" + a + bmapcfg.imgext;
  };

3、编写index.html文件并预览

<!DOCTYPE html>  
<html>  
    <head>  
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />  
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
        <title>Hello, World</title>  
        <style type="text/css">  
        html{height:100%}  
        body{height:100%;margin:0px;padding:0px}  
        #container{height:100%}  
        </style>  
        
        <script type="text/javascript" src="map_load.js"></script>
        
    </head>  
 
    <body>  
        <div id="container"></div> 
        <script type="text/javascript"> 
            
            var map = new BMap.Map("container")
            var point = new BMap.Point(116.404, 39.915);  // 创建点坐标  
            map.centerAndZoom(point, 6);                 // 初始化地图,设置中心点坐标和地图级别  
        </script>  
    </body>  
</html>

目录大致如下所示:

clipboard.png

在浏览器中打开index.html文件,如下所示:

clipboard.png

clipboard.png

这样就算你关掉wifi或者有线也是可以访问的。

4、制作python爬虫爬取POI兴趣点到数据库

POI是“Point of Interest”的缩写,中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。

clipboard.png

POI一般都是上市公司最宝贵的数据,所以一般不会外泄,因此要自己爬取并保存到数据库即可。爬取过程这里就不详细介绍了,可以参考此文章

需要特别注意的是:

  1. 百度地图为了保护数据,单次请求total最多为400,也就是只能搜出400个结果,如果搜索结果大于400个的时候只显示400条记录;
  2. 百度地图为开发者提供的配额为2000次请求/每天,并发访问的限制为120。 。

5、总结

1)做到这三点:1、下载百度api、modules在线文件成离线文件;2、修改下载后的离线文件并配置从之前网上下载瓦片到从本地加载瓦片;3、下载瓦片并复制到自己项目中的tiles文件夹;
2)这里我没有做切片的说明,有兴趣的可以参考上面的地址;
3)虽然离线地图制作完成了,但是最重要的还是POI兴趣点的获取,比如,获取餐饮、街道、小区、商店等等POI数据,这些才是离线地图的核心。
4)项目代码 密码:v5dv

6、引用

  1. 百度离线地图JS API V3.0
  2. 百度离线地图下载和叠加层瓦片切割
  3. 百度POI数据抓取-BeautifulSoup
  4. 百度地图POI数据获取并转为Excel文件
  5. 利用百度地图api通过城市地址等信息取经纬度
  6. POI
阅读 3.2k

推荐阅读
全栈工程师进阶
用户专栏

日常学习总结与分享,包括:前端、后台与运维,讲解的知识点包括:javascript、vuejs、reactjs、springb...

78 人关注
39 篇文章
专栏主页