vue中使用leaflet实现地图卷帘功能

背景

最近在做一个vue项目里面需要实现一个地图卷帘功能,本来是打算使用arcgis api 来实现这个功能,后来发现leaflet中的有一个leaflet-side-by-side的插件可以直接使用,于是决定尝试使用leaflet的插件来实现。本以为有插件的存在,肯定可以很快实现,没想到每一步都是坑(主要原因我是菜鸡)。下面讲一下我的爬坑之路。

卷帘效果图.gif

官网使用方法

var map = L.map('map').setView([51.505, -0.09], 13);

var myLayer1 = L.tileLayer(...).addTo(map);

var myLayer2 = L.tileLayer(...).addTo(map)

L.control.sideBySide(myLayer1, myLayer2).addTo(map);

1.创建一个map实例
2.加载左边的地图
3.加载右边的地图
4.将两个地图放入到sideByside的控件中就可以了。

就是这么简单。然而实际的操作中却是一步一坑啊。为了实现它,在这个过程中用到了很多其他的插件,下面具体介绍。

用到的插件

leaflet,
esri-leafle,
proj4, 
proj4leaflet,
leaflet-side-by-side

实现流程

引入插件

    import L from 'leaflet';#通过npm安装
    import'leaflet/dist/leaflet.css';#
    import"../../assets/sliderbyslider/leaflet-side-by-side.js";#通过git地址下载直接引用
    import "proj4";#通过npm安装
    import "proj4leaflet";#通过npm安装
    var esri = require('esri-leaflet')#通过npm安装,直接使用import不起作用,只能通过这种方式。

leaflet, Proj4Leaflet这些都可以使用npm直接安装,为了使用Proj4leaflet时候不出现问题,把proj4也直接引用到了工程中。leaflet-side-by-side.js通过git官网下载,记得把样式拷入到工程文件中。我一开始就是忘记引入样式问题,地图一直出不来,控件错乱。因为我的地图服务是通过arcgis server发布的地图服务,所以用到了esri-leaflet。使用的时候犯了难,不清楚是什么原因,直接import,使用其中的方法都是实现未定义,最后在网上找到了上述的进行引用。

地图参数配置

leaflet中默认加载的地图只有以下几种,本项目中使用的地图是CGCS2000的坐标系,需要使用proj4.js和Proj4leaflet.js来自定义坐标系。具体可参考https://blog.csdn.net/aliasone/article/details/80355184,这种方法我只能实现标准的坐标系,但是地方自定义坐标系,没有成功,如果有大神有更好的方法,希望热心告知。

leaflet默认坐标系

本文参数配置如下:

origin: [-400.0, 399.9999999999998], //
EPSG: "EPSG:4490", //地图空间参考值
epsginfo: '+proj=longlat +ellps=GRS80 +no_defs', //proj4描述
resolutions: [
        1.5228550437313792E-4,
        7.614275218656896E-5,
        3.807137609328448E-5,
        1.903568804664224E-5,
        9.51784402332112E-6,
        4.75892201166056E-6,
        2.37946100583028E-6,
        1.18973050291514E-6,
        5.9486525145757E-7,
        2.97432625728785E-7,
    ], //分辨率
 center: [32.05898506104946, 118.83657915219665], //地图中心点
const  CRS = new L.Proj.CRS(mapConfig.EPSG,mapConfig.epsginfo,// EPSG:4490的PROJ.4描述
                        {
                            origin: mapConfig.origin,
                            resolutions: mapConfig.resolutions,
                        }
                    );

地图实例化

this.Lmap = L.map('leafletmap',{
     crs: CRS,  // 定义的坐标系
     center: mapConfig.center,
     zoom: 3,
});

图层添加

使用esri-leaflt中的方法加载arcgis 发布的地图服务,具体可以参考eari-leaflet网站。本文加载切片服务

this.leftlayer =  esri.tiledMapLayer({url:lefturl}).addTo(this.Lmap);
this.rightlayer = esri.tiledMapLayer({url:righturl}).addTo(this.Lmap);
this.sidecontrol = L.control.sideBySide(this.leftlayer,this.rightlayer).addTo(this.Lmap);
this.Lmap.on('layeradd', function(params) {
    setTimeout(function update() {
        this.sidecontrol._updateClip();
    }, 100)
})

实现左右地图动态切换

动态切换地图服务,实现多个地图的对比。

var that = this;
var sidecontrol =that.sidecontrol;
var Lmap =that.Lmap;
var leftlayer =that.leftlayer;
if (sidecontrol && Lmap && leftlayer) {
    if ( that.lefturl== that.righturl) {
           return;
     }
    if (Lmap.hasLayer(leftlayer)) {
        Lmap.removeLayer(leftlayer);
    }
    leftlayer = esri.tiledMapLayer({url:that.lefturl});
    Lmap.addLayer(leftlayer);
    that.leftlayer = leftlayer
    that.sidecontrol.setLeftLayers(leftlayer);
};

实现效果

实现效果.png

参考

1.https://github.com/digidem/leaflet-side-by-side
2.https://blog.csdn.net/aliasone/article/details/80355184
3.https://blog.csdn.net/liyuanxiang1984/article/details/54947345
4.https://blog.csdn.net/qq_34790644/article/details/89308133
5.https://epsg.io/2439
6.http://esri.github.io/esri-leaflet/


You may also like...