zoukankan      html  css  js  c++  java
  • [原]使用node-mapnik和openstreetmap数据初步搭建瓦片服务

    最近依然还是有点小忙,只能挤点时间来学习点,先解决有没有的问题,再解决好不好的问题:)

    本文将承接上文《使用node-mapnik生成openstreetmap-carto风格的瓦片》的内容,用较为健壮的方式发布openstreetmap数据和样式的瓦片服务,在文章最后还提供手动切瓦片缓存的方法。

    一、部署瓦片服务环境

    Node.js未来会怎样,很多人都在思考,但是它的生态系统实在太好了,这在一个.NETer眼里简直就是无穷尽的宝藏啊!

    今要使用的就是Node.js平台上一个运用node-mapnik,并且较为成熟的瓦片服务器:TileStrata(官方地址)。

    1. 首先新建项目,并下载安装依赖项

    cd ~
    
    mkdir -p tileserver && cd tileserver
    
    npm init
    
    #输入相应的一些选项

    下面是我输入的一些选项

    2. 安装TileStrata及其插件(安装过程需要科学上网,否则很可能半天时间也装不成功,自寻出路吧。有高速稳定科学上网服务的老司机请带带我,我的水管实在太细了)

    npm install tilestrata --save
    
    npm install tilestrata-disk --save
    
    npm install tilestrata-mapnik --save

     安装完成后的情况如下:

    二、测试TileStrata

    1. 在项目根目录下创建 app.js 文件,输入以下内容:

    var tilestrata = require('tilestrata');
    var disk = require('tilestrata-disk');
    var mapnik = require('tilestrata-mapnik');
    
    var strata = tilestrata();
    
    //layer名称不能为空
    strata.layer('map')
      .route('tile.png')    //route方法中不能使用正则表达式
      .use(disk.cache({dir: './tilecache'}))    //设置瓦片缓存在当前目录的tilecache之目录中
      .use(mapnik({
        pathname: '../openstreetmap-carto/mapnik.xml'
      }));
    
    strata.listen(8080);

    2. 运行该程序(不要忘记打开防火墙端口或者关闭防火墙

    node app.js

    3. 访问瓦片的地址格式是http://yourhost:port/:layername/:z/:x/:y/:route_param,在本例中,访问地址是: http://192.168.1.99:8080/map/12/3352/1644/tile.png 效果如下:

    查看缓存目录,已经有瓦片生成了,如下:

    到目前为止,这个例子也只是重复了上一篇文章的内容,要想真正看起来像个服务器,怎么着也得加载个地图样出来,下面我们就让这个例子看起来更新一个地图。

    三、构建一个最简单的地图

    在本例中,我们将使用Express做为服务框架,使用OpenLayers做为地图,先来搭建环境

    1. 安装Express框架,Express框架可以使用国内的npm镜像安装,速度会非常快

    npm install express --registry=https://registry.npm.taobao.org --save

    2. 新建两个文件夹

    mkdir -p public && mkdir -p server

     进入public文件夹,将OpenLayers的js和css文件放到相应的位置,然后新建index.html文件,输入以下内容:

    <!Doctype html>
    <html xmlns=http://www.w3.org/1999/xhtml>
      <head>                  
          <meta http-equiv=Content-Type content="text/html;charset=utf-8">
          <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
          <meta content=always name=referrer>
          <title>OpenLayers 3地图示例</title>
          <link href="/css/ol.css" rel="stylesheet" type="text/css" />
          <script type="text/javascript" src="/js/ol.js" charset="utf-8"></script>
      </head>
      <body>
          <div id="map" style=" 100%"></div>
          <script>
            
            var tileStrataMapLayer = new ol.layer.Tile({
              source: new ol.source.XYZ({
                url: 'http://192.168.1.99:8080/t/map/{z}/{x}/{y}/tile.png'
              })
            });
            
            new ol.Map({
                  layers: [
                    tileStrataMapLayer
                  ],
                  
                  view: new ol.View({
                    center: [104.06, 30.67],   
                    projection: 'EPSG:4326',
                    zoom: 14            
                  }),
                  
                  target: 'map'    
              });
          </script>
      </body>
    </html>

    文件夹和文件内容如下图所示:

    3. 将项目根目录下的 app.js 剪贴到 server 目录中,并重命名为 server.js 

    cd ~/tileserver
    
    mv app.js ./server/server.js

    编辑server.js,内容如下:

    var tilestrata = require('tilestrata');
    var disk = require('tilestrata-disk');
    var mapnik = require('tilestrata-mapnik');
    var express = require('express');
    
    var strata = tilestrata();
    var router = express.Router();
    
    //layer名称不能为空
    strata.layer('map')
      .route('tile.png')    //route方法中不能使用正则表达式
      .use(disk.cache({dir: './tilecache'}))    //设置瓦片缓存在当前目录的tilecache之目录中
      .use(mapnik({
        pathname: '../openstreetmap-carto/mapnik.xml'
      }));
    
    router.use(tilestrata.middleware({
      server: strata
    }));
    
    module.exports = router;

    再回到项目根目录下,新建 app.js 文件,输入以下内容:

    var express = require('express');
    var path = require('path');
    var server = require('./server/server.js');
    
    var app = express();
    
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use('/t', server);
    
    app.get('/', function(req, res){
      res.sendfile('./public/index.html');
    });
    
    app.listen(8080);

    然后,使用 node app.js 启动服务,在浏览器中访问服务 http://yourhost:port/ 

    至此,瓦片服务就可以访问了。

    四、TileStrata负载均衡

    通常而言,生产环境中的瓦片服务器往往会部署多台,这样可以同时向用户提供地图瓦片,加快地图加载速度。TileStrata提供了一个负载均衡程序,帮助我们快速实现这个目标。方法如下:

    1. 安装TileStrata负载均衡

    sudo npm install tilestrata-balancer -g

    2. 在项目根目录下新建 balancer 目录,前将 server/server.js 复制到该目录下:

    cd ~/tileserver
    
    mkdir -p balancer
    
    cp ./server/server.js ./balancer

    3. 进入 balancer 目录 编辑 server.js 如下:

    var tilestrata = require('tilestrata');
    var disk = require('tilestrata-disk');
    var mapnik = require('tilestrata-mapnik');
    
    //注册到负载均衡服务器
    var strata = tilestrata({
      balancer: {
        host: '192.168.1.99:8081'
      }
    });
    
    //layer名称不能为空
    strata.layer('map')
      .route('tile.png')    //route方法中不能使用正则表达式
      .use(disk.cache({dir: './tilecache'}))    //设置瓦片缓存在当前目录的tilecache之目录中
      .use(mapnik({
        pathname: '../openstreetmap-carto/mapnik.xml'
      }));
    
    strata.listen(8083);

    4. 修改上文中的 public/index.html 文件,将请求瓦片的服务端口修改为 8082 ,将虚拟目录 t  删掉,如下:

    5. 将项目根目录下的 app.js 中关于tilestrata的相关行注释掉,如下:

    6. 启动负载均衡服务

    tilestrata-balancer --hostname=192.168.1.99 --port=8082 --private-port=8081 --check-interval=5000 --unhealthy-count=1

    7. 新开一个终端,在 balancer 目录中启动TileStrata服务

    node server.js

    8. 新开一个终端,在项目根目录中启动Express服务

    node app.js

     这时我们看三个终端的侦听情况:

    负载均衡服务端,端口号8082外,8081内(红框中代表有服务加进来):

    TileStrata服务端,端口号8083在辛苦的侦听请求

    Express服务端,端口号8080。貌似比较清闲

     

    再来看一下地图实际情况,可以看出,OpenLayers实际访问的是8082,说明是从负载均衡这边过的。 

     这里要说明一点,一定不要让不安全的网络访问8081端口,不然有可能被未授权的服务注册进来

    这里讲的负载均衡,主要是指TileStrata自带的均衡器,从网站架构以及Node.js的角度而言,还可以使用其他手段实现不同层面的负载均衡,这里还没有仔细研究过,以后研究了再说。

    五、手动切瓦片缓存

    在某些项目中,我们可能需要在项目运用之前就将所有瓦片切好,以便有更好的用户体验,最后再简单看看如何使用TileStrata实现这一目标。

    1. 安装TileMantle工具

    sudo npm install tilemantle -g

    2. 进入我们上文中建立的 balancer 目录,对 server.js 稍做修改,然后启动服务 node server.js 

    3. 为了看到效果,请将项目根目录下的 tilecache 目录中所有的目录全部删除

    4. 新开启一个终端,使用命令行切指定范围和级别的瓦片,命令如下:

    tilemantle http://192.168.1.99:8083/map/{z}/{x}/{y}/tile.png --point=39.9231,116.3725 --buffer=12mi --zoom=10-14

    TileMantle命令的详细参数请参见官网,例子中我是使用中心点来切图,也可以使用一个矩形范围来切,但是貌似有BUG,已经有人解决了,在源码的Issues中可以找到。

    小笔记本当服务器,貌似速度不咋滴

    查看缓存目录,已经有切好的瓦片图了

     OK,至此,一个非常简陋的瓦片服务器就搭建完成了,接下来继续学习如何在生产环境运用node-mapnik和openstreetmap。

    转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 

  • 相关阅读:
    面试整理之DOM事件阶段
    头疼的闭包
    Bootstrap学习
    旁门左道通过JS与纯CSS实现显示隐藏层
    关于setTimeout的妙用前端函数节流
    兼容古董级IE小结
    Mongodb配置:error:10061 由于目标计算机积极拒绝,无法连接
    webpack入门前端必备
    团队成员的分应该怎么分?
    Start
  • 原文地址:https://www.cnblogs.com/think8848/p/6262696.html
Copyright © 2011-2022 走看看