作者:LX
MVT全称是Mapbox Vector Tile,是Mapbox标准的矢量切片。矢量瓦片具有创建效率高、传输和渲染速度快、数据和风格样式独立,更改配图方案无需重新创建瓦片、高显示质量,能够很好地支持高分辨率显示屏等特点。SuperMap iClient产品很好的支持了MVT矢量瓦片在Web端的加载,本文主要以iClient for OpenLayers为例给大家展示一下如何在Web实现MVT瓦片的展示、查询和编辑。
iClient for Openlayer默认支持4326,3857坐标系MVT矢量瓦片的对接,对于非4326和3857的坐标系需要先通过proj4.defs()来定义,再进行对接,如China2000坐标系定义:
proj4.defs(“EPSG:4490”,"+proj=longlat +ellps=GRS80 +no_defs");
PS:proj4的使用方法可以参考博客《JavaScript利器分享之Proj4js》
SuperMap iServer 提供了矢量瓦片图层源,以下面两种方式提供:
1) iServer发布的地图服务的矢量切片(tileFeature)资源的mvt表述
2) iServer发布的矢量瓦片服务(vectortile)资源
Web端加载MVT瓦片其实就是从服务端获取矢量瓦片资源然后在客户端实现解析数据和完成绘制。主要思路就是:
1、解析iServer提供的服务
2、实现在客户端的绘制
3、瓦片要素的查询
4、图层风格的修改
下面我将以China2000坐标系的MVT瓦片服务为例展示一下iClient for Openlayers实现对MVT瓦片的对接、要素查询以及瓦片风格的修改。
1、引入Mapbox风格库
PS:如果不需要自定义坐标系,可以不引入proj4
2、定义坐标系(对于4326和3857的坐标系,此步骤可以省略)
//定义China2000坐标系
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs");
var projection = ol.proj.get('EPSG:4490');
projection.setExtent([-180,-85.05,180,85.05]);
3、定义Openlayers的map对象
//计算分辨率
//MVT 矢量瓦片第0级分辨率为全球范围宽度除以瓦片宽度512.
//常见坐标系第0级分辨率 WebMercator(3857):2*6378137*Math.PI/512 WGS84(4326):360.0/512 China2000(4490):360.0/512 Beijing54(4214):360.0/512 Xian80(4610):360.0/512
var topResolution = 360.0 / 512;
var resolutions = [];
for (var zoom = 0; zoom < 9; zoom++) {
resolutions.push(topResolution / Math.pow(2, zoom));
}
//定义Openlayers的map对象
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: [0,0],
zoom:0,
minZoom:0,
maxZoom:8,
projection: projection,
resolutions:resolutions
})
});
4、定义矢量瓦片风格
//Mapbox 矢量瓦片风格
var style = new ol.supermap.MapboxStyles({
map: map,
url: url,
source: 'testdata',
resolutions: resolutions
})
5、定义矢量瓦片图层源
var source=new ol.source.VectorTileSuperMapRest({
url: url,
projection: projection,
format: new ol.format.MVT() //MVT格式
})
6、创建矢量瓦片图层,并添加到地图上
var vectorLayer;
//监听styleloaded,等style加载完再进行瓦片渲染,不然会瓦片丢失风格
style.on('styleloaded', function () {
vectorLayer = new ol.layer.VectorTile({
//设置避让参数
declutter: true,
source:source,
style: style.getStyleFunction()
});
map.addLayer(vectorLayer);
})
map.on('click', function (e) {
map.forEachFeatureAtPixel(e.pixel, function (feature) {
style.setSelectedId(feature.getId(),feature.getProperties().layer);
return true;
}, {hitTolerance: 5});
vectorLayer.changed();
})
map.on('pointermove', function (e) {
var features = map.getFeaturesAtPixel(e.pixel);
if (features) {
var paint;
var layername=features[0].get('layer'); //获取瓦片图层名称
//判断图层,不同的图层设置不同的样式
if(layername=="World_Continent_txt@China"){
paint={
"text-halo-color":"rgba(236,233,216,1.00)",
"text-color":"rgba(224, 17, 17,1.00)",
"text-halo-width":4
}
changestyle(layername,paint);
}else if(layername=="World_Continent_pg@China"){
paint={
"fill-antialias": true,
"fill-color": "rgba(105, 100, 100,1.00)"
}
changestyle(layername,paint);
}else if(layername=="World_Division_pg@China"){
paint= {
"fill-antialias": true,
"fill-color": "rgba(0,0,0,1.00)"
}
changestyle(layername,paint);
}
}
});
//图层样式改变方法
function changestyle(layername,paint){
layerStyleArr = style.getStylesBySourceLayer(layername);
style.updateStyles([{
"id": layerStyleArr[0].id,
"paint": paint
}]);
source.changed();
//在popup中显示图层名称
content.innerHTML = "Layer: " + layername;
container.style.opacity = 1;
return;
}
图层样式修改结果:
测试数据及完整代码:
https://download.csdn.net/download/supermapsupport/11209359