在上一篇博客中,本文通过参考GeoServer示例代码,实现了GeoJSON格式的矢量切片展示。但在主要存在以下两个方面的问题,
该篇博客将对其进行进一步的改进和说明。
本文没有具体探究PBF格式行列号计算方法,只是通过改用tms服务,并手工计算行列号的方式修正了PBF展示异常的问题。主要还是参考了“矢量切片”一文。
function initMVT()
{
//图层名
var layerName = 'VTPK:Line2_VTPK';
//投影1 Geoserver和OpenLayer都支持的4326坐标系
var projection4326 = new ol.proj.Projection({code: 'EPSG:4326',units: 'degrees',axisOrientation: 'neu'});
//切片资源1 基于4326坐标系统
var source4326 = new ol.source.VectorTile
({
format: new ol.format.MVT(),
projection: projection4326,
//切片格网直接有4326坐标系统的坐标范围与缩放大小指定,因此每一级的都是固定的
tileGrid: ol.tilegrid.createXYZ({extent: ol.proj.get('EPSG:4326').getExtent() , maxZoom: 22}),
tilePixelRatio:1,
tileUrlFunction: function(tileCoord)
{
return '/geoserver/gwc/service/tms/1.0.0/'+layerName+'@EPSG%3A4326@pbf/'+(tileCoord[0]-1)
+ '/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) + '.pbf';
}
})
//控制器
var defaultView = new ol.View
({
projection: projection4326,
center: [114.15, 22.65],
zoom: 12
});
//地图样式
var initStyle = new ol.style.Style({stroke: new ol.style.Stroke({color: 'rgb(163,204,25)',width: 5})});
//图层
var vectorTile = new ol.layer.VectorTile
({
style: initStyle,
projection: projection4326,
source: source4326
});
//地图
map = new ol.Map
({
target: 'map',
layers: [vectorTile],
view:defaultView,
controls:[new ol.control.Zoom()],
});
}
1. 格网方案创建,在此实例中本文采用了更为通用ol.tilegrid.createXYZ()方法构建格网方案,这里只需要提供格网范围和切片层数连个参数就可以,进而大大的简化了ol.tilegrid.WMTS()方法构建的参数量。
2. tileUrlFunction回调,在此实例中本文没有使用还有{z}/{y}{x}占位符的静态URL,而改用了调用tileUrlFunction回调拼接一个切片满足wms服务格式URL。
而为什么在tileUrlFunction中这样计算行列号,通过参考“矢量切片”一文,并利用OpenLayer自身的TileDebug图层进行了如下测试。
为了简化测试过程,方便结果查看,测试用例使用了调用的时PNG格式栅格切片,TileDebug的图层创建代码下:
//资源
var source= new ol.source.XYZ
(
{
projection: projection4326,
tileGrid: ol.tilegrid.createXYZ({extent: projection4326.getExtent() , maxZoom: 22}),
tileUrlFunction: function(tileCoord)
{
return '/geoserver/gwc/service/tms/1.0.0/'+layerName+'@EPSG%3A4326@png/'+(tileCoord[0]-1)
+ '/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) + '.png';
}
}
);
//图层
var layer= new ol.layer.Tile
(
{
source:source,
projection: projection4326
}
);
//测试图层
var layer_Debug = new ol.layer.Tile
(
{
source: new ol.source.TileDebug
({
projection: 'EPSG:3857',
tileGrid: source.getTileGrid()
})
}
)
firebug获取的结果来看:
从图层结果中可以分析出以下结果:
function initMVT2000()
{
//图层名
var layerName = 'VTPK:Line2_VTPK';
//投影2 Geoserver支持但OpenLayer不支持的4490(即国家2000)坐标系
proj4.defs("china2000","+proj=longlat +ellps=GRS80 +no_defs");
var projection4490 = new ol.proj.get('china2000');
projection4490.setExtent([-180,-90,180,90]);
//切片资源2 基于4490坐标系统
var source4490 = new ol.source.VectorTile
({
format: new ol.format.MVT(),
projection: projection4490,
//切片格网直接有4326坐标系统的坐标范围与缩放大小指定
tileGrid: ol.tilegrid.createXYZ({extent: projection4490.getExtent() , maxZoom: 22}),
tilePixelRatio:1,
tileUrlFunction: function(tileCoord)
{
//这里使用的是tms服务而不是wmts服务
//注意URL中的格网名应该是Geoserver中配置给切片的格网名而不是坐标系名
return '/geoserver/gwc/service/tms/1.0.0/'+layerName+'@CGSC2000@pbf/'+(tileCoord[0]-1)
+ '/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) + '.pbf';
}
})
//控制器
var defaultView = new ol.View
({
projection: projection4490,
center: [114.15, 22.65],
zoom: 12
});
//地图样式
var initStyle = new ol.style.Style({stroke: new ol.style.Stroke({color: 'rgb(163,204,25)',width: 5})});
//图层
var vectorTile = new ol.layer.VectorTile
({
style: initStyle,
projection: projection4490,
source: source4490
});
//地图
map = new ol.Map
({
target: 'map',
layers: [vectorTile],
view:defaultView,
controls:[new ol.control.Zoom()],
});
}
本例中VTPK:Line2_VTPK采用了EPSG:4490(即国家2000)坐标系统,因为OpenLayer不支持该坐标系统因此必须通过ProJ4定义,这里China2000只是一个自定义名称,具体的坐标系统定义准则字符串可以在http://epsg.io/网页获取
本例通过CreateXYZ创建了一个格网准则,但具体的准则数值是由URL中的CGSC2000常量标志的标志的,而CGSC2000常量所对应的具体格网方案准则已经在Geoserver中成功定义,并配置给了VTPK:Line2_VTPK地图服务。具体情况如图所示:
本文主要通过采用了TMS服务的方式,解决了PBF格式矢量切片加载异常的问题,同时,对自定义坐标系统和格网方案的使用进行了进一步的梳理。
但目前仍然没有调试出基于WMTS服务方式的PBF格式矢量切片加载用例,后期也将继续进行测试。
最后十分感谢矢量切片(http://www.cnblogs.com/escage/p/6387529.html)一文作者在该项技术上的前驱探究与总结。