一、介绍
leaflet使用百度地图,叠加层使用谷歌坐标;leaflet默认使用硬件/谷歌坐标,使用百度地图需要进行坐标偏移,就是把谷歌坐标转换成百度坐标,此方法是直接在地图投影方法出设置偏移。
具体如下:
- 1、引入支持leaflet的proj4(https://github.com/kartena/Proj4Leaflet)
- 2、引入自定义百度地图层 BDLayer.js
- 3、leaflet地图初始化时crs参数设置为L.CRS.Baidu,layers设置为L.tileLayer.baidu
BDLayer.js
//请引入 proj4.js 和 proj4leaflet.js
L.CRS.Baidu = new L.Proj.CRS('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=1440 +y_0=255 +datum=WGS84 +units=m +no_defs', {
resolutions: function () {
level = 19
var res = [];
res[0] = Math.pow(2, 18);
for (var i = 1; i < level; i++) {
res[i] = Math.pow(2, (18 - i))
}
return res;
}(),
origin: [0, 0],
bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
});
L.tileLayer.baidu = function (option) {
option = option || {};
var layer;
var subdomains = '0123456789';
switch (option.layer) {
//单图层
case "vec":
default:
//'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl&b=0&limit=60&scaler=1&udt=20170525'
layer = L.tileLayer('http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'ph' : 'pl') + '&scaler=1&p=1', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "img_d":
layer = L.tileLayer('http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "img_z":
layer = L.tileLayer('http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'sh' : 'sl') + '&v=020', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "custom"://Custom 各种自定义样式
//可选值:dark,midnight,grayscale,hardedge,light,redalert,googlelite,grassgreen,pink,darkgreen,bluish
option.customid = option.customid || 'midnight';
layer = L.tileLayer('http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=' + option.customid, {
name: option.name, subdomains: "012", tms: true
});
break;
case "time"://实时路况
var time = new Date().getTime();
layer = L.tileLayer('http://its.map.baidu.com:8002/traffic/TrafficTileService?x={x}&y={y}&level={z}&time=' + time + '&label=web2D&v=017', {
name: option.name, subdomains: subdomains, tms: true
});
break;
//合并
case "img":
layer = L.layerGroup([
L.tileLayer.baidu({ name: "底图", layer: 'img_d', bigfont: option.bigfont }),
L.tileLayer.baidu({ name: "注记", layer: 'img_z', bigfont: option.bigfont })
]);
break;
}
return layer;
};
二、案例
案例代码——点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.3/leaflet.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.3/leaflet-src.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/proj4js/2.8.0/proj4.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.min.js"></script>
<style>
* {
padding: 0;
margin: 0;
}
#location {
position: fixed;
padding: 5px;
left: 0;
bottom: 0;
background-color: #fff;
z-index: 999;
font-size: 12px;
border-top-right-radius: 5px;
width: 255px;
}
.leaflet-grab {
cursor: default;
}
</style>
</head>
<body>
<div id="mapdiv" style="width:100vw;height:100vh"></div>
<div id="location"></div>
<script>
L.CRS.Baidu = new L.Proj.CRS('EPSG:3395', '+proj=merc +lon_0=0 +k=1 +x_0=1440 +y_0=255 +datum=WGS84 +units=m +no_defs', {
resolutions: function () {
level = 19
re = 18
var res = [];
res[0] = Math.pow(2, re);
for (var i = 1; i < level; i++) {
res[i] = Math.pow(2, (re - i))
}
return res;
}(),
origin: [0, 0],
bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
});
L.tileLayer.baidu = function (option) {
option = option || {};
var layer;
var subdomains = '0123456789';
switch (option.layer) {
//单图层
case "vec":
default:
//'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl&b=0&limit=60&scaler=1&udt=20170525'
// layer = L.tileLayer('http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'ph' : 'pl') + '&scaler=1&p=1', {
// name: option.name, subdomains: subdomains, tms: true
// });
layer = L.tileLayer('https://maponline0.bdimg.com/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&scaler=2&udt=20230105&from=jsapi2_0', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "img_d":
layer = L.tileLayer('http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "img_z":
layer = L.tileLayer('http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'sh' : 'sl') + '&v=020', {
name: option.name, subdomains: subdomains, tms: true
});
break;
case "custom"://Custom 各种自定义样式
//可选值:dark,midnight,grayscale,hardedge,light,redalert,googlelite,grassgreen,pink,darkgreen,bluish
option.customid = option.customid || 'midnight';
layer = L.tileLayer('http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=' + option.customid, {
name: option.name, subdomains: "012", tms: true
});
break;
case "time"://实时路况
var time = new Date().getTime();
layer = L.tileLayer('http://its.map.baidu.com:8002/traffic/TrafficTileService?x={x}&y={y}&level={z}&time=' + time + '&label=web2D&v=017', {
name: option.name, subdomains: subdomains, tms: true
});
break;
//合并
case "img":
layer = L.layerGroup([
L.tileLayer.baidu({ name: "底图", layer: 'img_d', bigfont: option.bigfont }),
L.tileLayer.baidu({ name: "注记", layer: 'img_z', bigfont: option.bigfont })
]);
break;
}
return layer;
};
$(document).ready(function () {
var options = {
center: [22.532934684, 114.0547117002], // The initial center(baidu BD-09 format) of map
zoom: 15, // initial zoom of map
crs: L.CRS.Baidu,
layers: [new L.tileLayer.baidu({layer:'vec'})]
};
var map = L.map("mapdiv", options);
L.marker([22.532934684, 114.0547117002]).addTo(map).bindTooltip("会展中心").openTooltip();
map.on('click', (e) => {
let lnglat = e.latlng.lng + ',' + e.latlng.lat;
$('#location')[0].innerText = lnglat;
})
window.map= map;
});
</script>
</body>
</html>