微信公众号
打赏作者
Leaflet教程

Leaflet加载高德地图默认使用火星坐标系,国内地图除百度外,应该都是使用该坐标系,如果要使用wgs84等坐标,会出现偏移,所以需要扩展Leaflet实现高德地图纠偏。这时就需要用到插件mapCorrection.js

Leaflet如何加载高德地图,请参照 Leaflet入门教程

引用mapCorrection.js

<script type="text/javascript" src="leaflet/mapCorrection.js"></script>

mapCorrection.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//坐标转换
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

实例
1
2
3
4
5
L.tileLayer('tiles/{z}/{x}/{y}.png', {
  attribution: 'Leaflet高德离线地图',
  corrdType: "gcj02",
  tms: true
}).addTo(map);

这样就可以直接使用WGS84等坐标,不会出现偏移了。

联系我们