1、前言
最近公司要给政府机关做项目要用到地图但是只限局域网所以要用到离线地图,在网上搜索了一些有用的文章并成功制作成功百度离线地图,希望能帮助到大家。
2、百度离线地图制作思路
制作百度离线地图,分为6步:
- 下载百度JS API文件为本地文件;
- 屏蔽百度ak验证;
- 引用本地模块资源;
- 下载所需城市或地区瓦片;
- 按照想要的地区或城市切片;
- 加载瓦片改为本地离线瓦片;
2.1、下载百度JS API文件为本地文件
访问baidu map api地址,代码如下:
(function(){ window.BMap_loadScriptTime = (new Date).getTime(); document.write('');})();
然后复制上面代码中的http://api.map.baidu.com/gets...,并访问该网址,如图所示:
打开之后我们格式化代码并下载该文件,文件暂时命名为:map_offline_api_v3.0_min.js
2.2、屏蔽百度ak验证
打开map_offline_api_v3.0_min.js文件,如下:
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
为了便于修改主文件里的一些内容,先创建一个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('');
在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; //添加本地工具资源引用(离线路径)
如图:
然后再通过 &mod 进行定位,注释掉其所在行,做如下修改:
// 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
下载的时候可以选择层级,越往下下载的瓦片图片越多,下载完成后,如图所示:
2.5、按照想要的地区或城市切片
略
如果想知道如何切片可以参考此文章
2.6、加载瓦片改为本地离线瓦片
将刚才下载的瓦片tiles文件夹下的图片复制到本项目的titles文件夹下,如图所示:
复制完成之后,按照下图修改代码:
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文件并预览
Hello, World
目录大致如下所示:
在浏览器中打开index.html文件,如下所示:
这样就算你关掉wifi或者有线也是可以访问的。
4、制作python爬虫爬取POI兴趣点到数据库
POI是“Point of Interest”的缩写,中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。
POI一般都是上市公司最宝贵的数据,所以一般不会外泄,因此要自己爬取并保存到数据库即可。爬取过程这里就不详细介绍了,可以参考此文章
需要特别注意的是:
- 百度地图为了保护数据,单次请求total最多为400,也就是只能搜出400个结果,如果搜索结果大于400个的时候只显示400条记录;
- 百度地图为开发者提供的配额为2000次请求/每天,并发访问的限制为120。 。
5、总结
1)做到这三点:1、下载百度api、modules在线文件成离线文件;2、修改下载后的离线文件并配置从之前网上下载瓦片到从本地加载瓦片;3、下载瓦片并复制到自己项目中的tiles文件夹;
2)这里我没有做切片的说明,有兴趣的可以参考上面的地址;
3)虽然离线地图制作完成了,但是最重要的还是POI兴趣点的获取,比如,获取餐饮、街道、小区、商店等等POI数据,这些才是离线地图的核心。
4)项目代码 密码:v5dv
6、引用
- 百度离线地图JS API V3.0
- 百度离线地图下载和叠加层瓦片切割
- 百度POI数据抓取-BeautifulSoup
- 百度地图POI数据获取并转为Excel文件
- 利用百度地图api通过城市地址等信息取经纬度
- POI