[原]使用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="width: 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) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM