底圖往往是一些基礎信息,比如行政區、街道、水系,它們變動較少,一般放在圖層最下方。底圖一般使用柵格瓦片,柵格瓦片有其自身侷限性:
- 地理信息內容改變,柵格瓦片無法做到實時更新。柵格瓦片需要預生成,生成以後不能改變,如果地理信息有變動,那麼需要重新生成瓦片
- 樣式改變,如果需要不同樣式的底圖,需要額外生成一份瓦片。不同樣式,存儲多份相同的數據。
於是矢量瓦片的概念被提出,矢量瓦片也是瓦片,是矢量,在瀏覽器端渲染,可以只請求一次,渲染出不同樣式。因此解決了柵格瓦片的2問題。然而,多份底圖的需求是真實需求嗎?這得分兩方面:
- 對於toC來說,意義不大,用戶對底圖甚至都不會太關注
- 對於toB,或者研究機構來說,意義較大,用戶用特色鮮明的底圖,來襯托要說明的數據。
當前來說,GIS一般是toB的,所以底圖最好使用矢量瓦片。然而,矢量瓦片也沒有解決地理信息內容改變,瓦片實時更新的問題,或者說一天一更新也可以接受,能想到的思路可能就是,將新數據與原數據對比,只更新數據庫中涉及的條目,並生成內容有改變的區域涉及的瓦片。
還有一個問題沒有考慮到,如果後端返回矢量瓦片,那麼渲染到任務就交到了前端做,那麼那些複雜到樣式就需要用戶來做,要簡化操作,就必須做SDK,如果使用你提供的底圖還需要再學習一個SDK,感覺這也不是很好,好的做法應該是返回柵格切片,讓用的比較多的SDK都可以順利調用,比如openlayers、leaflet。
可用的技術
- 生成
PostGIS可以將PostgreSQL中存儲的地理數據生成矢量瓦片;
Tippecanoe,可以將GeoJSON直接生成矢量瓦片,並存儲在sqlite中,稱爲mbtiles;
Mapnik既可以將PostGIS中數據生成矢量瓦片,也可以將矢量瓦片作爲輸入,生成柵格地圖切片;
MapServer可以將PostGIS中將數據生成矢量瓦片,但不能將矢量瓦片作爲輸入,生成柵格地圖切片。
- 緩存
將請求過的矢量切片緩存起來,下次請求直接返回緩存中的結果。
發佈一個道路底圖
這裏我們使用MapServer發佈一個道路地圖。發佈底圖不僅僅需要渲染線狀道路,還要添加道路名稱,即地圖標註。標註需要的中文字體,系統中可能沒有,因此,我們首先需要添加需要的中文字體到系統中。