iClient for Leaflet加载MVT矢量瓦片并注册鼠标事件

作者:刘大

使用背景

需要在前端动态更改地图样式,并高效进行鼠标交互获取要素的业务场景时,我们会采取MVT矢量瓦片来解决此类问题,但是web应用开发已经选用Leaflet地图框架的情况下怎么办呢,这时,我们便可以引入“leaflet-mapbox-gl”插件,那具体怎么实现捏,接下来我们就详细阐述下具体的使用流程

具体使用流程

1.引入相关库

在原有引入的leaflet先关库的基础上,还需引入mapboxgl的js以及css文件以及leaflet-mapbox-gl的js文件

//引入mapbox-gl-enhance,解决原生只支持3857坐标系的限制
<link rel="stylesheet" href="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.0/mapbox-gl-enhance.css">
<script type="text/javascript" src="https://iclient.supermap.io/web/libs/mapbox-gl-js-enhance/1.12.0/mapbox-gl-enhance.js">< /script>
// 引入leaflet-mapbox-gl 加载mvt矢量瓦片
<script type="text/javascript" src="https://iclient.supermap.io/web/libs/leaflet-mapbox-gl/0.0.15/leaflet-mapbox-gl.min.js">< /script>

同样也可以通过 https://iclient.supermap.io/download/download.html 该地址下载离线的三方库,获取离线文件进行加载

2.加载矢量瓦片

这块可参考iClinet范例 https://iclient.supermap.io/examples/leaflet/editor.html#mvt_mapboxgl
就不多加讲述,主要是注意以下两点

2.1设定Leaflet的crs

我们都知道MVT矢量瓦片是按照一定的比例尺级别出图的,那么为与mapboxgl的级别相匹配,leaflet的分辨率应设置为第0级为全球范围宽度除以瓦片宽度256
以4326坐标系为例:

// 常见坐标系第0级分辨率   WebMercator(3857):2*6378137*Math.PI/256    WGS84(4326):360.0/256    China2000(4490):360.0/256    Beijing54(4214):360.0/256     Xian80(4610):360.0/256
var topResolution = 360.0 / 256;
        var resolutions = [];
        for (var zoom = 0; zoom < 22; zoom++) {
            resolutions.push(topResolution / Math.pow(2, zoom));
        }
        var crs = L.Proj.CRS('EPSG:4326', {
            origin: [-180, 90],
            resolutions: resolutions
        });
2.2mapboxGL里的minZoom和maxZoom的设置

mapboxgl zoom 和leaflet zoom 相差一级

//leaflet:
 map = L.map('map', {
                center: [30, 105],
                zoom: 5,
                crs: crs,
                minZoom: 5,
                maxZoom: 14
            })
//mapboxGL:
//设置图层背景为透明
style.layers[0].paint['background-color'] = 'rgba(168,209,221,0)';
var gl = L.mapboxGL({
              renderWorldCopies: false,
              style: style,
              crs: 'EPSG:4326',
              minZoom:4,
              maxZoom: 13
                    }).addTo(map);
  // 获取 mapboxgl 地图
    mapboxglMap = gl.getMapboxMap();
3.鼠标交互,获取要素

有下面两种方式都可以实现

3.1 使用Leaflet的事件

使用时,需注意使用传入点的像素坐标为e.originalEvent.offsetXe.originalEvent.offsetY
直接使用layerPoint会有偏移 导致获取的要素不准确

            map.on('click',function (e){
                console.log(e)
                var features = mapboxglMap.queryRenderedFeatures([e.originalEvent.offsetX,e.originalEvent.offsetY])
                if(mapboxglMap.getLayer('ss') === undefined){
                   mapboxglMap.addLayer({
            "id": "ss",
            "type": "fill",
            "source": features[0].source,
            "source-layer":  features[0].sourceLayer,
            "paint":{
                "fill-color":'rgba(255,0,0,1)',
                "fill-opacity":0.6
            }
        })  
                }
                //也可根据其他属性字段进行过滤
              mapboxglMap.setFilter("ss",["in", "$id", features[0].id])
3.2使用mapboxGL的事件

这里需要在初始化时,设置interactive为true

L.mapboxGL({
              renderWorldCopies: false,
              style: style,
              crs: 'EPSG:4326',
              interactive:true,
              minZoom:4,
              maxZoom: 13
                    }).addTo(map);
mapboxglMap.on('click',function (e){
      var features = mapboxglMap.queryRenderedFeatures(e.point)
        if(mapboxglMap.getLayer('ss') === undefined){
           mapboxglMap.addLayer({
            "id": "ss",
            "type": "fill",
            "source": features[0].source,
            "source-layer":  features[0].sourceLayer,
            "paint":{
                "fill-color":'rgba(255,0,0,1)',
                "fill-opacity":0.6
            }
        })  
                }
                  //也可根据其他属性字段进行过滤
mapboxglMap.setFilter("ss",["in", "$id", features[0].id])
            })

注册mouseover等其他鼠标交互事件 也同样如此

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值