說明:番外篇是對正篇矢量切片(Vector tile)中提到的一些值得繼續延伸的關注點繼續進行探索和學習,所涉及的內容以解決實際問題爲主要導向。javascript
1、新的需求?html
在完成了矢量切片的工做後,新的需求出現了, 也就是我在上一篇中所提到的:我所擁有的歷史數據都是基於某一個特定的Projection,那麼如何利用GeoServer以及OpenLayers去制定一個針對特定座標系的矢量切片呢?java
其實很簡單,回顧一下咱們上一篇文章是如何實現並調用矢量切片的:git
發佈數據 --> 配置參數【選擇數據格式(GeoJSON/TopoJSON/MapBox Vector tile(MVT))、選擇tile size(256*256)、選擇gridsets】 --> 預覽數據 --> OL3調用數據github
那在哪個環節會出問題?web
1)數據發佈和切片的生成:你能夠把數據想象成爲蛋糕,不一樣座標系下的數據就是不一樣形狀的蛋糕,按照同一種方法去切割不一樣形狀的蛋糕,那確定會出問題。json
面對不一樣形狀的蛋糕,也應該採起不一樣的策略去制定切法框架
2)數據調用:每一塊不一樣形狀的蛋糕在完成切片後,留下的最小存在單元的形狀也確定是不同的,若是是橢圓,所切出來的小塊確定是有着平滑邊緣的蛋糕塊,而五角星的每一小塊頗有多是有着尖銳邊緣的蛋糕塊,因此咱們想要把切出來的蛋糕塊完美的放在某一個容器中端出來,那這個容器確定須要和蛋糕塊的形狀契合,因此,在調用數據的時候,也須要爲數據提供一個契合的數據框架。學習
經過上述分析,咱們已經知道了應該在哪裏進行補充工做了,那麼接下來就讓咱們一塊兒去實現吧。編碼
2、基於某一個特定的座標系實現的矢量切片
首先在發佈數據時,咱們應當找到當下準備發佈數據的座標系信息,你能夠經過ArcGIS加載該數據來查看,在此我使用的是深圳市綠道數據,基於EPSG:4490,即China Geodetic Coordinate System 2000。
1) 進入GeoServer的發佈數據頁面
還記得在發佈數據過程當中,爲切片數據配置的頁面嗎?咱們須要在頁面上完成數據格式(GeoJSON/TopoJSON/MapBox Vector tile(MVT))、tile size(256*256)、gridsets等配置。
但這裏要注意的是,你會發現在gridset這一欄裏默認的只有EPSG:4326和EPSG:900913的切片格網方案,而我這裏使用的數據是EPSG:4490,蛋糕形狀變了, 切的刀法也應該有所變化。因此咱們須要針對EPSG:4490定製一個切蛋糕方案:
2)自定義gridset
從GeoServer面板左邊的菜單欄中進入Tile Caching的Gridsets子菜單,而後在Gridsets的管理頁面中選擇新建一個gridset,接下來你就能看到這樣一個頁面:
在這個頁面,你有不少參數須要配置,配置完以後點擊保存便可:
- Name
- Coordinate Reference System : 與之對應的座標系編碼
- Gridset bounds:範圍(會影響到切片的參數)
- tile size:256*256
- Tile Matrix Set:根據你的數據和須要設置縮放級別
最後,在上一個配置參數的頁面,將新配置的gridset添加進去
好了,咱們如今已經用合適而恰當的方法把蛋糕切好了,接下來咱們須要爲這些數據蛋糕找到合適的容器。
3、在OL3中自定義座標系
1)OpenLayers中的座標系
在OpenLayers3中,提供了好幾種默認已經定義好的座標系,這其中就有咱們熟悉的EPSG:4326,EPSG:900913 or EPSG:3857等等,可以保證通常狀況下的使用,但對於特定需求,可能就須要藉助外力的幫助,而這個外力就是:Proj4js
2)Proj4js
在github上,關於Proj4js的定義是這樣的:
Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.
// Proj4js主要是一個用來將點座標從源座標系統轉換到另外一個目標座標系統的JS庫,包括基準轉換
Originally a port of PROJ.4 and GCTCP C it is a part of the MetaCRS group of projects.
// 本項目起源於PROJ.4和GCTCP C
PS:定義中提到的基準轉換,應該是大地測量學裏面的術語,我也不是很瞭解,稍微查了一下資料,在此做爲冷知識補充一下:
咱們一般所說的座標系統,是由座標系和基準構成的,所謂的基準指的是爲了描述空間位置而定義的點、線、面,在大地測量中,基準指的是描述地球形狀的地球橢球參數。
回到正題,這裏是Proj4js在github中的地址:https://github.com/proj4js/proj4js, 在proj4js中提到了兩種用途:
1)轉換座標點;
//其中fromProjection是源座標系,toProjection指的是目標座標系
//若是你沒有提供fromProjection,則默認fromProjection爲WGS84座標系
//fromProjection,toProjection等參數能夠是ol中的projection對象,也能夠是一個WKT String
proj4(promProjection,toProjection,coordinates);
2)定義命名一個自定義座標系統
//定義一個新的座標系統
proj4.defs('WGS84', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees");
須要補充一點,在Proj4js中已經預約義了幾種projection:
- 'EPSG:4326' or 'WGS84'
- 'EPSG:4269'
- 'EPSG:3857' or 'EPSG:3785' or 'GOOGLE' or 'EPSG:900913' or 'EPSG:102113'
根據文檔中的介紹,咱們使用Proj4js去定義一個新的ol3中的projection對象:
a)首先,和全部的JS庫同樣,請不要忘記在頁面完成對庫的引用,
<script type="text/javascript" src="lib/proj4js/dist/proj4.js"></script>
b)其次,在你的JS文件中加入如下代碼:
function loadVectorTile_4490(){
//定義EPSG:4490,具體的字符串參數你能夠在:http://epsg.io中查詢到,只需輸入你的projection的EPSG碼或者座標系的名稱
//便可得到相應座標系的字符串參數,直接將其複製到代碼中便可
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs");
//得到定義的座標系
var projection4490 = new ol.proj.get('EPSG:4490');
//給定義的座標系統限定範圍,此處4490的範圍與4326相似,由於他們的單位都是degree
projection4490.setExtent([-180,-90,180,90]);
var layerName2 = 'szdata:greenway';
var layerProjection2 = '4490';
//矢量切片圖層 var vectorTile_GreenWay = new ol.layer.VectorTile({ title:"深圳綠道-VectorTile", style: new ol.style.Style({
stroke: new ol.style.Stroke({
color:'#548B54'
})
}), projection: projection4490,
//矢量切片數據 source: new ol.source.VectorTile({
projeciton: projection4490, format: new ol.format.GeoJSON(), tileGrid: ol.tilegrid.createXYZ({
extent: ol.proj.get('EPSG:4490').getExtent(),
maxZoom: 13 }),
tilePixelRatio:1,
//發出獲取切片的請求
tileUrlFunction: function(tileCoord){
return '/geoserver/gwc/service/tms/1.0.0/' +layerName+'@EPSG%3A'+layerProjection+'@geojson/'+(tileCoord[0]-1) + '/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) + '.geojson'; }
})
});
//須要注意的是,要給view設定一個合適的Projection屬性,否則數據沒法正常顯示
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM();
}),
vectorTile_GreenWay
],
view: new ol.View({
//view中的projection
projection: projection4490,
center: [114.15, 22.65]
})
});
}
c) 其實最後的實現很簡單,只不過在上一篇文章的內容中添加了一個Proj4js定義新座標系的內容,實現過程也比預想要順利,所以做爲一個小番外添加進來,也是對上一篇文章末尾提到的問題進行一個補充。實現結果以下: