在进行GIS项目开发中,常使用Geoserver作为开源的地图服务器,Geoserver是一个JavaEE项目,常通过Tomcat进行部署。而GeoWebCache是一个采用Java实现用于缓存WMS-Tile(瓦片)的开源项目。当客户端请求一张新地图和Tile时,GeoWebCache将拦截这些调用然后返回缓存过的Tiles。如果找不到缓存再调用服务器上的Tiles,从而提高地图展示的速度。最新版本的GeoServer已经完成了GeoWebCache的内嵌。
然而,在实际的生产环境中,地图缓存服务器应当是独立部署的结点,这样的优势是可以避免集群结点开启缓存配额后的文件锁冲突;另一方面,缓存切片及耗费CPU内存等资源,配置独立的地图缓存服务器可减少切片请求对地图服务器资源的占用。
由于矢量切片(vector tile)的流行,越来越多的主流地图网站都采取了矢量切片地图的设计方案,其中mapbox基于prototype提出的mvt格式的矢量切片方案收到了较为广泛地的认可。在服务器端,能够完成矢量切片本地发布、调用的方式目前大致有三种:
(1) ArcGIS系列,在ArcGIS10.5PRO等最新版本中已经支持了矢量切片的发布,但其是商业软件,非开源,在实际项目研发使用相对困难。
(2) Mapbox studio支持本地数据的上传和发布,但其处理速度很慢,且许多地理数据涉密或体量较大,不适合采取这种方式。
(3) GeoServer2.11版本以后,安装矢量切片插件geoserver-2.11-SNAPSHOT-vectortiles-plugin便可以完成矢量切片的制作与发布。这种方式纯开源,相对实用性较高,本文主要针对这一方案进行探讨。
采取GeoServer作为矢量切片的服务器使用简单方便,利用内置的GeoWebCache可以将矢量切片完成类似栅格瓦片(png/jpeg)的本地化缓存,以提升地图服务的传输效率。但在实际项目研发过程中发现,使用内置的GeoWebCache进行矢量切片预缓存将耗费较大的CPU和内存等资源,影响geoserver服务器的运行效率,因此需要将GeoServer与GeoWebCache进行分布部署。目前网络上对这方面的研究主要停留在将GeoWebCache作为栅格瓦片缓存服务器的独立部署,没有对其在矢量瓦片方面的应用进行说明。
1.GeoServer部分
矢量瓦片地图服务的发布依旧在安装了GeoServer的服务器中完成,其发布过程与正常发布过程无差异。虽然新版本中依旧会内嵌GeoWebCache,但这里我们仅仅是发布服务,实际调用中并不使用内嵌的GeoWebCache进行矢量瓦片的缓存。
2.GeoWebCache部分
这里将GeoWebCache安装在与上述分离的另一台服务器中,将其安装在Tomcat的Webapps中即可。安装好后,在webapps中打开geowebcache/WEB-INF/web.xml,在其中完成缓存文件地址的配置。值得注意的是,网上的教程均采取添加一个<context-param>的方式完成缓存地址配置,但笔者在实际测试中发现,不能随意进行缓存地址的添加,其默认地址为C:\Users\Administrator\AppData\Local\Temp\geowebcache。因此,只可以在这个文件夹或者其子文件夹中进行设置,作为缓存文件地址。
修改好web.xml文件的配置后,重启tomcat,在上述缓存文件地址中就可以发现geowebcache.xml这个文件了。geowebcache.xml用于地图服务拦截与缓存的设置,在其中的<layers>标签中添加:
<wmsLayer>
<!--地图名称,这个会在前端调用的时候中用到-->
<name>vectorTile:BJ_LN</name>
<!--图片格式,要与geoserver发布服务时所选的格式保持一致-->
<mimeFormats>
<string>image/jpeg</string>
<string>image/png</string>
<string>application/x-protobuf;type=mapbox-vector</string>
<string>application/json;type=geojson</string>
</mimeFormats>
<!--使用的瓦片格网坐标系,这里也要与geoserver发布服务时所选坐标系保持一致-->
<gridSubsets>
<gridSubset>
<gridSetName>EPSG:4326</gridSetName>
</gridSubset>
<gridSubset>
<gridSetName>EPSG:900913</gridSetName>
</gridSubset>
</gridSubsets>
<!--wms服务地址,其中vectorTile为geoserver地图服务的工作空间-->
<wmsUrl>
<string>http://10.5.201.111:8090/geoserver/vectorTile/wms?service=WMS</string>
</wmsUrl>
<wmsLayers>vectorTile:BJ_LN</wmsLayers>
</wmsLayer>
3.WEB前端调用部分
支持矢量切片地图服务的前端框架很多,这里笔者主要介绍利用openlayers3和mapbox-gl两种前端框架对上述发布的服务进行调用的方式。
(1) OL3:(目前支持EPSG:4326/ EPSG:900913两种投影方式的geoserver服务)
var lyr ="vectorTile:BJ_LN";
var vector = newol.layer.VectorTile({
// 矢量切片的数据源
source: new ol.source.VectorTile({
projection: projection4326,
format: new ol.format.MVT(),
tileGrid:ol.tilegrid.createXYZ({
extent:ol.proj.get('EPSG:4326').getExtent(),
maxZoom: 19
}),
// 矢量切片服务地址
tileUrlFunction:function(tileCoord){
return 'http://10.5.201.29:8080/geowebcache/service/tms/1.0.0/'
+lyr+'@EPSG%3A4326@pbf/'+(tileCoord[0]-1)
+'/'+tileCoord[1] + '/' + (Math.pow(2,tileCoord[0]-1)+tileCoord[2]) +'.pbf';
}
})
});
(2) mapbox-gl:(目前仅支持EPSG:900913一种投影方式的geoserver服务)
"sources":{
"composite": {
"url":"mapbox://mapbox.mapbox-streets-v5",
"type":"vector"
},
"os": {
"type":"vector",
"scheme": "tms",
"tiles": [
"http://10.5.201.29:8080/geowebcache/service/tms/1.0.0/vectorTile:BJ_LN@EPSG:900913@pbf/{z}/{x}/{y}.pbf"
]
},
},
4.geoserver和geowebcache的CORS跨域问题处理
在前端初次调用矢量切片地图服务时,多会报错:“已阻止跨源请求:同源策略禁止读取位于 http://xxx.xxx.com 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin‘)”
这里需要我们对服务器的Tomcat以及geoserver和geowebcache进行CORS(跨域资源共享)配置,具体操作见http://www.bubuko.com/infodetail-2041942.html.上述文章仅仅介绍了geoserver的CORS配置,参照其方式可以对geowebcache进行配置。