最近项目需求,需要使用leaflet封装成一个vue组件,涉及功能主要有高德自定义样式地图封装为leaflet底图图层、自定义坐标系、topjson省市区街道下钻、线面区域热力层、飞线、点聚合图标撒点等功能。记录下开发遇到的问题,欢迎一起交流学习。
本来使用leaflet主要用于客户本地部署加载离线地图,但在线使用免费的瓦片地址样式很单一,如果想改变底图样式就很麻烦,搜查资料有一个改变地图图片颜色的方法,尝试使用感觉还是不方便,而且想单独设置建筑河水等样式也不支持。高德地图有个自定义地图样式,使用高德地图方法加载就可以加载各种我们自定义的地图,有了思路就在文档查找有没有合适的插件。
效果图如下:
具体操作如下:
查看文档发现有个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中使用或者封装成组件还需要自己修改下。