Leaflet教程
Leaflet加载高德地图默认使用火星坐标系,国内地图除百度外,应该都是使用该坐标系,如果要使用wgs84等坐标,会出现偏移,所以需要扩展Leaflet实现高德地图纠偏。这时就需要用到插件mapCorrection.js
Leaflet如何加载高德地图,请参照 Leaflet入门教程
引用mapCorrection.js
<script type="text/javascript" src="leaflet/mapCorrection.js"></script>
mapCorrection.js
//坐标转换
L.CoordConver = function () {
/**百度转84*/
this.bd09_To_gps84 = function(lng, lat) {
var gcj02 = this.bd09_To_gcj02(lng, lat);
var map84 = this.gcj02_To_gps84(gcj02.lng, gcj02.lat);
return map84;
}
/**84转百度*/
this.gps84_To_bd09 = function (lng, lat) {
var gcj02 = this.gps84_To_gcj02(lng, lat);
var bd09 = this.gcj02_To_bd09(gcj02.lng, gcj02.lat);
return bd09;
}
/**84转火星*/
this.gps84_To_gcj02 = function (lng, lat) {
var dLat = transformLat(lng - 105.0, lat - 35.0);
var dLng = transformLng(lng - 105.0, lat - 35.0);
var radLat = lat / 180.0 * pi;
var magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
var sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
var mgLat = lat + dLat;
var mgLng = lng + dLng;
var newCoord = {
lng: mgLng,
lat: mgLat
};
return newCoord;
}
/**火星转84*/
this.gcj02_To_gps84 = function (lng, lat) {
var coord = transform(lng, lat);
var lontitude = lng * 2 - coord.lng;
var latitude = lat * 2 - coord.lat;
var newCoord = {
lng: lontitude,
lat: latitude
};
return newCoord;
}
/**火星转百度*/
this.gcj02_To_bd09 = function (x, y) {
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
var bd_lng = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
var newCoord = {
lng: bd_lng,
lat: bd_lat
};
return newCoord;
}
/**百度转火星*/
this.bd09_To_gcj02 = function (bd_lng, bd_lat) {
var x = bd_lng - 0.0065;
var y = bd_lat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
var gg_lng = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
var newCoord = {
lng: gg_lng,
lat: gg_lat
};
return newCoord;
}
var pi = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;
var x_pi = pi * 3000.0 / 180.0;
var R = 6378137;
function transform(lng, lat) {
var dLat = transformLat(lng - 105.0, lat - 35.0);
var dLng = transformLng(lng - 105.0, lat - 35.0);
var radLat = lat / 180.0 * pi;
var magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
var sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
var mgLat = lat + dLat;
var mgLng = lng + dLng;
var newCoord = {
lng: mgLng,
lat: mgLat
};
return newCoord;
}
function transformLat(x, y) {
var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
function transformLng(x, y) {
var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
}
L.coordConver = function () {
return new L.CoordConver()
}
L.GridLayer.include({
_setZoomTransform: function (level, _center, zoom) {
var center = _center;
if (center != undefined && this.options) {
if (this.options.corrdType == 'gcj02') {
center = L.coordConver().gps84_To_gcj02(_center.lng, _center.lat);
} else if (this.options.corrdType == 'bd09') {
center = L.coordConver().gps84_To_bd09(_center.lng, _center.lat);
}
}
var scale = this._map.getZoomScale(zoom, level.zoom),
translate = level.origin.multiplyBy(scale)
.subtract(this._map._getNewPixelOrigin(center, zoom)).round();
if (L.Browser.any3d) {
L.DomUtil.setTransform(level.el, translate, scale);
} else {
L.DomUtil.setPosition(level.el, translate);
}
},
_getTiledPixelBounds: function (_center) {
var center = _center;
if (center != undefined && this.options) {
if (this.options.corrdType == 'gcj02') {
center = L.coordConver().gps84_To_gcj02(_center.lng, _center.lat);
} else if (this.options.corrdType == 'bd09') {
center = L.coordConver().gps84_To_bd09(_center.lng, _center.lat);
}
}
var map = this._map,
mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
scale = map.getZoomScale(mapZoom, this._tileZoom),
pixelCenter = map.project(center, this._tileZoom).floor(),
halfSize = map.getSize().divideBy(scale * 2);
return new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
}
})
加载高德瓦片设置
需要增加属性 corrdType 为 gcj02
实例
L.tileLayer('tiles/{z}/{x}/{y}.png', {
attribution: 'Leaflet高德离线地图',
corrdType: "gcj02",
tms: true
}).addTo(map);
这样就可以直接使用WGS84等坐标,不会出现偏移了。
全部教程