百度局域网地图搭建方法 - Fri, Jan 10, 2020
百度局域网地图搭建方法
1. 概述
由于没有外网环境,所以需要搭建在内网环境需要使用的地图服务. 首选是geoserver+openlayer进行搭建,但是在国内,前端程序员习惯使用百度和高德,所以寻找搭建百度和高德离线地图的方法.
2. 搭建需求
- 不能对原有的api进行大面积变更
- 需要提供局域网服务,而不能使用本地瓦片的方式.
- 使用docker启动,方便跨平台
3. 搭建思路
- 从官方网站下载js文件,替换js文件中服务器地址
- 使用nginx对js中引用的服务器路径进行替换,变更为本地服务能够访问的地址
4. 资源下载
4.1 下载百度地图SDKjs文件
百度地图SDK官网 http://lbsyun.baidu.com/index.php?title=jspopular3.0/openlibrary
百度地图下载有两个api http://api.map.baidu.com/api?v=3.0&ak=E4805d16520de693a3fe707cdc962045 http://api.map.baidu.com/getscript?v=3.0&ak=E4805d16520de693a3fe707cdc962045&services=&t=20200109192240
第一个api内容非常简单,在html中插入一段获取js的代码
(function() {
window.BMap_loadScriptTime = (new Date).getTime();
document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=3.0&ak=E4805d16520de693a3fe707cdc962045&services=&t=20200109192240"></script>');
}
)();
第二个api是真中获取地图api的代码
使用chrome浏览器自带的pretty print,然后复制代码到文件map_api_full.js
4.2 下载百度地图modules文件
api js文件会依赖很多其他模块的js文件,否则地图只能显示,但是地图缩放,点击等任何操作都无效.
在map_api_full.js中查找代码&callback=BMap._rd._cbk
.
*** 不同的版本具体代码可能不同,但不会变化很大 ***
找到以下代码
; var Tb = {
map: "nx4gqs",
common: "5qbolj",
style: "xuda1u",
tile: "so0om1",
...
};
具体的下载路径 http://api.map.baidu.com/getmodules?v=3.0&mod=map_nx4gqs http://api.map.baidu.com/getmodules?v=3.0&mod=common_5qbolj http://api.map.baidu.com/getmodules?v=3.0&mod=style_xuda1u http://api.map.baidu.com/getmodules?v=3.0&mod=tile_so0om1 …
按照mod的名称进行保存 map_nx4gqs.js common_5qbolj.js style_xuda1u.js tile_so0om1.js …
4.2 下载百度地图图片资源
使用爬虫进行下载或者遇到缺失的进行下载.
4.3 下载百度地图瓦片数据
使用爬虫抓去百度官网的瓦片. // TODO: 使用水经注下载,(水经注只有windows版)
4.4 最终各种资源的目录结构
images\
js
├── 3.0
│ ├── map_api_full.js
│ ├── map_load.js
│ └── modules\
└── map_load.js
5. 代码修改
5.1 map_load.js
map_load.js
文件作用相当与http://api.map.baidu.com/api?v=3.0&ak=E4805d16520de693a3fe707cdc962045
,会将js文件插入到html中.
*** 为什么需要使用map_load.js
引入api的js? ***
map_api_full.js文件中会用到服务器地址,服务器地址需要在map_load.js中进行设置,否这会找不到服务器.
var bmapcfg = {
imgext: '.jpg',
};
//////////////////加载bmap api,并获取host///////////////////////////////////
var scripts = document.getElementsByTagName("script");
var MapLoadJS = scripts[scripts.length - 1].getAttribute("src");
var jsURL = new URL(MapLoadJS);
bmapcfg.hostname = jsURL.hostname;
bmapcfg.host = jsURL.host;
bmapcfg.port = jsURL.port;
bmapcfg.protocol = jsURL.protocol;
bmapcfg.origin = jsURL.origin;
(function () {
window.BMap_loadScriptTime = (new Date).getTime();
//加载地图API主文件
document.write('<script type="text/javascript" src="' + bmapcfg.origin + '/js/3.0/map_api_full.js"></script>');
})();
///////////////////////////////////////////////////////////////////
5.1 map_api_full.js
sdk主文件修改的尽量少,需要修改2个地方(或者是1个)
- 各种服务器地址配置的地方
TILE_ONLINE_URLS
修改为[bmapcfg.host, bmapcfg.host, bmapcfg.host, bmapcfg.host]
main_domain_nocdn
修改为{baidu: bmapcfg.host}
bmapcfg是在map_load.js中进行设置.
D.xX = {
TILE_BASE_URLS: ["shangetu0.map.bdimg.com", "shangetu1.map.bdimg.com", "shangetu2.map.bdimg.com", "shangetu3.map.bdimg.com", "shangetu4.map.bdimg.com"],
TILE_ONLINE_URLS: [bmapcfg.host, bmapcfg.host, bmapcfg.host, bmapcfg.host],
TIlE_PERSPECT_URLS: ["d0.map.baidu.com", "d1.map.baidu.com", "d2.map.baidu.com", "d3.map.baidu.com"],
geolocControl: "loc.map.baidu.com",
TILES_YUN_HOST: ["g0.api.map.baidu.com", "g1.api.map.baidu.com", "g2.api.map.baidu.com", "g3.api.map.baidu.com"],
traffic: "its.map.baidu.com:8002",
iw_pano: "pcsv0.map.bdimg.com",
message: "j.map.baidu.com",
baidumap: "map.baidu.com",
wuxian: "wuxian.baidu.com",
pano: ["pcsv0.map.bdimg.com", "pcsv1.map.bdimg.com", "pcsv2.map.bdimg.com"],
main_domain_nocdn: {baidu: bmapcfg.host},
main_domain_cdn: {
baidu: ["api0.map.bdimg.com", "api1.map.bdimg.com", "api2.map.bdimg.com"],
webmap: ["webmap0.map.bdimg.com"]
},
map_click: "mapclick.map.baidu.com",
vector_traffic: "or.map.bdimg.com"
};
- modules获取
load函数会进行modules的下载.当多个mod同时下载时,会是以下这种情况.
http://api.map.baidu.com/getmodules?v=3.0&mod=map_nx4gqs,common_5qbolj
nginx文件服务器,默认不能把多个文件进行分割,所以,在下载文件时,希望api单个进行下载.
http://api.map.baidu.com/getmodules?v=3.0&mod=map_nx4gqs
http://api.map.baidu.com/getmodules?v=3.0&mod=common_5qbolj
nginx有多文件合并的模块
nginx-http-concat
. 使用合并模块这里就不需要修改了.
load: function(a, b, c) {
var e = this.lb(a);
if (e.Ke == this.uj.Ep)
c && b();
else {
if (e.Ke == this.uj.HF) {
this.tJ(a);
this.JM(a);
var f = this;
f.RB == t && (f.RB = p,
setTimeout(function() {
for (var a = [], b = 0, c = f.Qd.Zm.length; b < c; b++) {
var e = f.Qd.Zm[b]
, n = "";
ja.dy.oJ(e) ? n = ja.dy.get(e) : (n = "",
a.push(e + "_" + Tb[e]));
f.Qd.uv.push({
aM: e,
ZD: n
})
}
f.RB = t;
f.Qd.Zm.length = 0;
// 0 == a.length ? f.cK() : pa(f.zF.eP + "&mod=" + a.join(","))
if (0 == a.length) {
f.cK();
} else {
a.forEach(e => {
pa(f.zF.dP + "&mod=" + e)
});
}
}, 1));
e.Ke = this.uj.WO
}
e.ru.push(b)
}
},
5.2 nginx配置文件
nginx.conf
把 user nginx;
改为user root;
,否则会没有权限.
user root;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
file.conf
文件服务配置文件,使用了rewrite,把query参数重定向为path
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/file.access.log main;
location / {
root /usr/share/nginx/html;
}
location ~ /getscript {
rewrite ^/getscript(/.*)$ /js/$arg_v/map_api_full.js last;
}
location = /tile/ {
# qt=vtile&x=198&y=72&z=10&styles=pl&scaler=1&udt=20200102
rewrite ^/tile(/.*)$ /$arg_qt/$arg_z/$arg_x/$arg_y.jpg? last;
}
location = /js/ {
root /usr/share/nginx/html;
if ($arg_qt = 'vtileQuest') {
return 200 '{}';
}
}
location ~ /vtile/(.*).jpg$ {
root /usr/share/nginx/html;
if (!-e $request_filename) {
rewrite ^(.*)$ /images/blank.jpg;
}
}
location ~ /getmodules {
rewrite ^/getmodules /js/$arg_v/modules/$arg_mod.js? last;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}