龙空技术网

Web端MVT矢量瓦片加载之OpenLayers篇

SuperMap技术控 241

前言:

现时小伙伴们对“proj4js 平面坐标”大约比较关注,大家都需要分析一些“proj4js 平面坐标”的相关内容。那么小编同时在网上收集了一些关于“proj4js 平面坐标””的相关文章,希望大家能喜欢,小伙伴们快快来了解一下吧!

作者:LX

前言

MVT全称是MapboxVectorTile,是Mapbox标准的矢量切片。矢量瓦片具有创建效率高、传输和渲染速度快、数据和风格样式独立,更改配图方案无需重新创建瓦片、高显示质量,能够很好地支持高分辨率显示屏等特点。SuperMapiClient产品很好的支持了MVT矢量瓦片在Web端的加载,本文主要以iClientfor OpenLayers为例给大家展示一下如何在Web实现MVT瓦片的展示、查询和编辑。

一、 支持的MVT矢量瓦片坐标系

iClient forOpenlayer默认支持4326,3857坐标系MVT矢量瓦片的对接,对于非4326和3857的坐标系需要先通过proj4.defs()来定义,再进行对接,如China2000坐标系定义:
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80+no_defs");
PS:proj4的使用方法可以参考博客《JavaScript利器分享之Proj4js》

二、 支持的MVT服务来源

SuperMap iServer 提供了矢量瓦片图层源,以下面两种方式提供:
1)iServer发布的地图服务的矢量切片(tileFeature)资源的mvt表述
2)iServer发布的矢量瓦片服务(vectortile)资源

三、 实战演练

Web端加载MVT瓦片其实就是从服务端获取矢量瓦片资源然后在客户端实现解析数据和完成绘制。主要思路就是:
1、解析iServer提供的服务
2、实现在客户端的绘制
3、瓦片要素的查询
4、图层风格的修改

下面我将以China2000坐标系的MVT瓦片服务为例展示一下iClientfor Openlayers实现对MVT瓦片的对接、要素查询以及瓦片风格的修改。

开发代码:

1、引入Mapbox风格库

PS:如果不需要自定义坐标系,可以不引入proj4

2、定义坐标系(对于4326和3857的坐标系,此步骤可以省略)

//定义China2000坐标系
proj4.defs("EPSG:4490","+proj=longlat+ellps=GRS80 +no_defs");
varprojection =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矢量瓦片风格
varstyle = new ol.supermap.MapboxStyles({
map: map,
url: url,
source: 'testdata',
resolutions: resolutions
})

5、定义矢量瓦片图层源

varsource=new ol.source.VectorTileSuperMapRest({
url: url,
projection: projection,
format: new ol.format.MVT() //MVT格式
})

6、创建矢量瓦片图层,并添加到地图上

varvectorLayer;
//监听styleloaded,等style加载完再进行瓦片渲染,不然会瓦片丢失风格
style.on('styleloaded', function () {
vectorLayer = new ol.layer.VectorTile({
//设置避让参数
declutter: true,
source:source,
style: style.getStyleFunction()
});
map.addLayer(vectorLayer);
})

MVT瓦片对接结果展示:

7、要素查询

map.on('click',function (e) {
map.forEachFeatureAtPixel(e.pixel, function (feature) {
style.setSelectedId(feature.getId(),feature.getProperties().layer);
return true;

}, {hitTolerance: 5});

vectorLayer.changed();
})

查询结果:

8、修改瓦片图层样式

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;
}

图层样式修改结果:

测试数据及完整代码:

标签: #proj4js 平面坐标