最近项目需求,需要使用leaflet封装成一个vue组件,涉及功能主要有高德自定义样式地图封装为leaflet底图图层、自定义坐标系、topjson省市区街道下钻、线面区域热力层、飞线、点聚合图标撒点等功能。记录下开发遇到的问题,欢迎一起交流学习。

 

本来使用leaflet主要用于客户本地部署加载离线地图,但在线使用免费的瓦片地址样式很单一,如果想改变底图样式就很麻烦,搜查资料有一个改变地图图片颜色的方法,尝试使用感觉还是不方便,而且想单独设置建筑河水等样式也不支持。高德地图有个自定义地图样式,使用高德地图方法加载就可以加载各种我们自定义的地图,有了思路就在文档查找有没有合适的插件。

效果图如下:

android 高德 绘制自定义 marker 高德自定义图层_高德地图

具体操作如下:

查看文档发现有个Leaflet.CustomLayer.js插件可以自定义图层满足我们的需求。https://github.com/iDerekLi/Leaflet.CustomLayer

leaflet 初始化 (options 的inertia 需要设为false,后面会有说明)

const map = L.map("map", {
			center: [32.050678, 118.792199], // 地图中心
			zoom: 8.5, //缩放比列
			zoomControl: false, //禁用 + - 按钮
			doubleClickZoom: true, 
			attributionControl: true ,
			minZoom: 3,
			maxZoom: 20, 
			inertia:false  
		});

 动态创建高德地图容器

   需要注意的是高德地图容器样式要取消所有的鼠标事件 pointer-events: none

   高德地图初始化也要关闭所有动画以及禁用拖拽缩放等功能。

  这样是为了避免leaflet 和高德地图冲突,高德地图我们只需要加载出自定义样式,其余的操作交给leaflet

var amap=null;
		$(`<div id="contaion" style="width: 1920px;height: 800px;pointer-events: none;" ></div>`).appendTo('body')
		addAmap();

 function	addAmap(){
		window._AMapSecurityConfig = {
				      securityJsCode:'高德地图的安全秘钥',
				  }
		 AMapLoader.load({
		     "key": "高德地图key",              
		     "version": "2.0",   
		     "plugins": [],          
		 }).then((AMap)=>{
		         amap= new AMap.Map('contaion',
				 {
					 zoomEnable:true,
                     dragEnable:true,
					 resizeEnable: false,
					 animateEnable:false,
					 jogEnable:false,
					 terrain:true,
					  }
					);
	 var position = new AMap.LngLat(118.792199,32.050678); 
				 amap.setCenter(position); 
				 amap.setZoom(8.5); 
       amap.setMapStyle('amap://styles/高德地图分享的样式ID')
			 }).catch((e)=>{
		         console.error(e);  
		     });   
		 	
	 }

  将高德地图转成leaflet 自定义图层

    Leaflet.CustomLayer.js 有加载canvas svg 和 Dom,我们使用加载Dom的方法

    layer-render监听每次地图的拖拽缩放去设置高德地图的缩放,但操作时发现高德地图有延迟不同步卡顿问题,体验感非常不好,翻看文档将inertia 设为false后就可以了。

var customLayer = new L.customLayer({
          container: $('#contaion')[0], // The DomElement object to display.
          minZoom: 3, // Minimum zoom level of the layer.
          maxZoom: 20, // Maximum zoom level of the layer.
          opacity: 1, // Opacity of the layer.
          visible: true, // Visible of the layer.
          zIndex: 100 // The explicit zIndex of the layer.
        });
        
        customLayer.on("layer-beforemount", function() {
          console.log("layerBeforeMount");
        });
        
        customLayer.on("layer-mounted", function() {
          console.log("layerMounted");
        })
        
        customLayer.on("layer-render", function(e) {
        
          if(!!amap){
      let azoom = amap.getZoom();
     amap.setZoomAndCenter(e.target._zoom,[e.target._center.lng,         e.target._center.lat],true) 
             } 
             });

        customLayer.on("layer-beforedestroy", function() {
          console.log("layerBeforeDestroy");
        });
        
        customLayer.on("layer-destroyed", function() {
          console.log("layerDestroyed");
        });
        
        customLayer.addTo(map);

 至此高德自定义地图加载完成了,上面是html做的demo,如果想vue中使用或者封装成组件还需要自己修改下。