Geoserver发布矢量切片服务及使用openlayer调用展示
矢量切片概述
矢量切片技术是一种控制可交互的动态的地图显示方法,通过紧凑的格式包含所有相对应的几何图形和元数据,是一种高效性能的格式,在样式和输出格式以及交互性方面有很高的灵活性,可以在移动端和浏览器上自定义地图样式。相比栅格切片,矢量切片从创建、配置、发布都能体现其快速的特点。
矢量切片相关研究
目前,矢量切片工具有ESRI公司的ArcGIS pro、Geoserver等。其中ArcGiS矢量切片遵守MapBox矢量切片规范,只支持Web Mercator 投影。Geoserver是共享地理空间数据的开源服务器,专为互操作性而设计,它使用开放标准发布来自任何主要空间数据源的数据。
在Geoserver使用中,可以通过udig等提前配置好图层的样式,形成模板,方便部署样式、geoserver可以在Geowebcache中配置好对矢量切片格式的支持,并且可以分别设置是否处理或者实时切片等,减少工程实施时需要预处理的耗时。
矢量切片格式
常用的矢量切片数据格式有GeoJson、TopJson、Mapbox Vector TIle。
GeoJson 是基于Json格式的地理空间表示格式,而且继承了Json容易被JavaScript解析,比XL更加轻量的优点。
TopJson是编码拓扑的GeoJson的扩展,TopJson消除冗余,允许相关的几何图形高效的存储在同一个文件中,和GeoJson一样,TopJson文件可以在文本编辑器中轻松修改,并且适合gzip压缩,因此TopJson比GeoJson更加紧凑。
MapBox Vector Tile 是MapBox提出了Vector Tile的开放规范,该规范用到了Google的Protocol Buffer 作为数据编码规范,可以做到压缩率更高,体积更小。
Geoserver发布矢量切片服务
1、下载插件
本文采用Geoserver发布矢量切片服务,由于Geoserver本身不支持发布矢量切片服务,所以我们需要去geoserver官网下载与之对应版本的的矢量切片插件。
注意:一定要版本与之对应!!。
2、安装插件
将 geoserver-2.14.2-vectortiles-plugin解压到 C:\Program Files (x86)\GeoServer 2.14.2\webapps\geoserver\WEB-INF\lib中
重新启动GeoServer,看是否正常运行。
3、发布矢量切片服务
前面添加数据存储部分因为较容易,网上可查阅资源很多,就不做赘述。只是如果你用到查询要素字段属性表中有中文的话,建议数据储存时DBF的字符集选项选择GB2312或者GBK,否则查询结果中文可能会是乱码。下面是矢量切片图层设置一栏介绍。
发布完服务之后可以在Layer Preview 中浏览查看,点击Tile Layers 可以查看你发布的矢量切片服务。
可以看到我们可以通过两种切片方案和不同格式去查看矢量切片。这里我们选择第一种,我们可以在浏览器上预览效果。
同时我们可以F12查看源代码是如何实现预览效果的,其实实现本身也是基于openlayer的,geoserver和openlayer结合度比较高。
4、如何切片
当我们预览时,我们可以查看自己的文件夹是否生成切片数据
C:\Program Files (x86)\GeoServer 2.14.2\data_dir\gwc\waterEutrophication_wenjiangshape
同时我们也可以点击Seed/Truncate
选择参数后点击submit ,同样也可以生成本地切片
openlayer实现前端展示
我是在前端框架vue中引入openlayer的,现在ol官网也是采用import方式引入的。和之前的方式有少许变化。可以通过学习官网查看demo
安装ol
执行代码
npm install ol --save
实现展示
方法1:可以直接查看源码 F12
var gridsetName = 'EPSG:4326'; //格网方案名称
var gridNames = ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2', 'EPSG:4326:3', 'EPSG:4326:4', 'EPSG:4326:5', 'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8', 'EPSG:4326:9', 'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13', 'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17', 'EPSG:4326:18', 'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21'];//格网层次名称
var baseUrl = 'http://localhost:8080/geoserver/gwc/service/wmts';//基础请求URL
//var style = '';
var format = 'application/json;type=geojson';//切片格式
var infoFormat = 'text/html';
var layerName = 'waterEutrophication:wenjiangshape';//图层名
var projection = new Projection({
code: 'EPSG:4326',
units: 'degrees',
axisOrientation: 'neu'
});//投影
var resolutions = [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7];//层次分辨率
var params = {
'REQUEST': 'GetTile',
'SERVICE': 'WMTS',
'VERSION': '1.0.0',
'LAYER': layerName,
// 'STYLE': style,
'TILEMATRIX': gridsetName + ':{z}',
'TILEMATRIXSET': gridsetName,
'FORMAT': format,
'TILECOL': '{x}',
'TILEROW': '{y}'
};//构造参数 xyz 瓦片行列数
function constructSource() {
var url = baseUrl+'?'
for (var param in params) {
url = url + param + '=' + params[param] + '&';
}
url = url.slice(0, -1); //构造请求url
var source = new SVectorTile({
url: url,
format: new MVT(),
projection: projection,
tileGrid: new Tilegrid({
tileSize: [256,256],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: gridNames
}),//切片方案相关参数, 使用new Tilegrid必须具有这些参数
wrapX: true,
});
return source;
}
var layer = new LVectorTile({
source: constructSource(),
style: function (feature)
{
console.log(feature.get("Name"))
return feature.get("Name")=="温江区"?style_highlighted:style_simple
}
});
var view = new View({
center: [0, 0],
zoom: 2,
projection: projection,
extent: [-180.0,-90.0,180.0,90.0]
});
map = new Map({
layers: [layer],
target: 'map',
view: view
});
map.getView().fit([103.68561500000004,30.616134000000045,103.94078100000007,30.88669900000008], map.getSize());
}
方法2 :可以查看各种服务的相关基础请求地址。自行构造请求地址。
点击其中一种服务,找到你发布的矢量切片服务,例如我们点击tms。
如图,我们可以再加上格网方案中的取值。便可以构造请求url。
例如我们调用tms服务,
var projection4326 = new Projection({
code: 'EPSG:4326',
units: 'degrees',
axisOrientation: 'neu'
});
var layerName ='waterEutrophication:wenjiangshape'
map = new Map({
controls:[new Zoom()],
target: 'map',
view: new View({
projection: projection4326,
center: [0,0],
zoom: 12
}),
layers: [new LVectorTile({
style: style_simple,
projection: projection4326,
source: new SVectorTile({
projection: projection4326,
tilePixelRatio: 1,
format: new MVT(),
tileGrid: createXYZ({extent: get('EPSG:4326').getExtent() , maxZoom: 21}),
tileUrlFunction: function(tileCoord)
{
return 'http://localhost:8080/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';
},
})
})]
})
map.getView().fit([103.68561500000004,30.616134000000045,103.94078100000007,30.88669900000008], map.getSize());
注意:
1、在格网创建时,更为通用createXYZ方法构建格网方案,因为只需要提供格网范围和切片层数,简化了Tilegrid方法构建的参数量。
createXYZ的调用:createXYZ({extent: ol.proj.get(‘EPSG:4326’).getExtent() , maxZoom: 22}),
Tilegrid的调用:Tilegrid ({ tileSize: [256, 256], origin: [-180.0, 90.0], resolutions: resolutions, matrixIds: gridNames })
2、在使用url 和tileUrlFunction时,因为使用tileUrlFunction实现回调拼接url满足请求地址。
其中WMTS服务的URL格式:
http://localhost:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=waterEutrophication:wenjiangshape&STYLE=&TILEMATRIX=EPSG:4326:12&TILEMATRIXSET=EPSG:4326&FORMAT=application/json;type=geojson&TILECOL=6457&TILEROW=1347
其中TMS服务的URL格式:
http://localhost:8080/geoserver/gwc/service/tms/1.0.0/waterEutrophication:wenjiangshape@EPSG%3A4326@pbf/12/6456/2746.pbf
易错点:图层加载不出来的原因大多是因为格网方案的参数设置和坐标系统不匹配导致。
.