百度局域网地图搭建方法

百度局域网地图搭建方法

1. 概述

由于没有外网环境,所以需要搭建在内网环境需要使用的地图服务.
首选是geoserver+openlayer进行搭建,但是在国内,前端程序员习惯使用百度和高德,所以寻找搭建百度和高德离线地图的方法.

2. 搭建需求

  1. 不能对原有的api进行大面积变更
  2. 需要提供局域网服务,而不能使用本地瓦片的方式.
  3. 使用docker启动,方便跨平台

3. 搭建思路

  1. 从官方网站下载js文件,替换js文件中服务器地址
  2. 使用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个)

  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"
    };
  1. 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;
    #}
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wind.kaisa@gmail.com

💰

×

Help us with donation