最近依然還是有點小忙,只能擠點時間來學習點,先解決有沒有的問題,再解決好不好的問題:)
本文將承接上文《使用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)