|
23 | 23 | var PI = 3.1415926535897932384626; |
24 | 24 | var a = 6378245.0; |
25 | 25 | var ee = 0.00669342162296594323; |
| 26 | + |
| 27 | + function Rectangle(lng1, lat1, lng2, lat2) { |
| 28 | + this.west = Math.min(lng1, lng2); |
| 29 | + this.north = Math.max(lat1, lat2); |
| 30 | + this.east = Math.max(lng1, lng2); |
| 31 | + this.south = Math.min(lat1, lat2); |
| 32 | + } |
| 33 | + /** |
| 34 | + * @param {number} lon |
| 35 | + * @param {number} lat |
| 36 | + */ |
| 37 | + Rectangle.prototype.contain = function (lon, lat) { |
| 38 | + return this.west <= lon && this.east >= lon && this.north >= lat && this.south <= lat; |
| 39 | + } |
| 40 | + |
| 41 | + //China region - raw data |
| 42 | + var region = [ |
| 43 | + new Rectangle(79.446200, 49.220400, 96.330000, 42.889900), |
| 44 | + new Rectangle(109.687200, 54.141500, 135.000200, 39.374200), |
| 45 | + new Rectangle(73.124600, 42.889900, 124.143255, 29.529700), |
| 46 | + new Rectangle(82.968400, 29.529700, 97.035200, 26.718600), |
| 47 | + new Rectangle(97.025300, 29.529700, 124.367395, 20.414096), |
| 48 | + new Rectangle(107.975793, 20.414096, 111.744104, 17.871542) |
| 49 | + ]; |
| 50 | + //China excluded region - raw data |
| 51 | + var exclude = [ |
| 52 | + new Rectangle(119.921265, 25.398623, 122.497559, 21.785006), |
| 53 | + new Rectangle(101.865200, 22.284000, 106.665000, 20.098800), |
| 54 | + new Rectangle(106.452500, 21.542200, 108.051000, 20.487800), |
| 55 | + new Rectangle(109.032300, 55.817500, 119.127000, 50.325700), |
| 56 | + new Rectangle(127.456800, 55.817500, 137.022700, 49.557400), |
| 57 | + new Rectangle(131.266200, 44.892200, 137.022700, 42.569200), |
| 58 | + new Rectangle(73.124600, 35.398637, 77.948114, 29.529700) |
| 59 | + ]; |
| 60 | + |
| 61 | + function isInChina(lon, lat) { |
| 62 | + for (var i = 0; i < region.length; i++) { |
| 63 | + if (region[i].contain(lon, lat)) { |
| 64 | + for (var j = 0; j < exclude.length; j++) { |
| 65 | + if (exclude[j].contain(lon, lat)) { |
| 66 | + return false; |
| 67 | + } |
| 68 | + } |
| 69 | + return true; |
| 70 | + } |
| 71 | + } |
| 72 | + return false; |
| 73 | + } |
| 74 | + |
26 | 75 | /** |
27 | 76 | * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 |
28 | 77 | * 即 百度 转 谷歌、高德 |
29 | | - * @param bd_lon |
30 | | - * @param bd_lat |
| 78 | + * @param {number} bd_lon |
| 79 | + * @param {number} bd_lat |
31 | 80 | * @returns {*[]} |
32 | 81 | */ |
33 | | - var bd09togcj02 = function bd09togcj02(bd_lon, bd_lat) { |
34 | | - var bd_lon = +bd_lon; |
35 | | - var bd_lat = +bd_lat; |
| 82 | + function bd09togcj02(bd_lon, bd_lat) { |
36 | 83 | var x = bd_lon - 0.0065; |
37 | 84 | var y = bd_lat - 0.006; |
38 | 85 | var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI); |
|
45 | 92 | /** |
46 | 93 | * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 |
47 | 94 | * 即谷歌、高德 转 百度 |
48 | | - * @param lng |
49 | | - * @param lat |
| 95 | + * @param {number} lng |
| 96 | + * @param {number} lat |
50 | 97 | * @returns {*[]} |
51 | 98 | */ |
52 | | - var gcj02tobd09 = function gcj02tobd09(lng, lat) { |
53 | | - var lat = +lat; |
54 | | - var lng = +lng; |
| 99 | + function gcj02tobd09(lng, lat) { |
55 | 100 | var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI); |
56 | 101 | var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI); |
57 | 102 | var bd_lng = z * Math.cos(theta) + 0.0065; |
|
61 | 106 |
|
62 | 107 | /** |
63 | 108 | * WGS84转GCj02 |
64 | | - * @param lng |
65 | | - * @param lat |
| 109 | + * @param {number} lng |
| 110 | + * @param {number} lat |
66 | 111 | * @returns {*[]} |
67 | 112 | */ |
68 | | - var wgs84togcj02 = function wgs84togcj02(lng, lat) { |
69 | | - var lat = +lat; |
70 | | - var lng = +lng; |
71 | | - if (out_of_china(lng, lat)) { |
| 113 | + function wgs84togcj02(lng, lat) { |
| 114 | + if (!isInChina(lng, lat)) { |
72 | 115 | return [lng, lat] |
73 | | - } else { |
74 | | - var dlat = transformlat(lng - 105.0, lat - 35.0); |
75 | | - var dlng = transformlng(lng - 105.0, lat - 35.0); |
76 | | - var radlat = lat / 180.0 * PI; |
77 | | - var magic = Math.sin(radlat); |
78 | | - magic = 1 - ee * magic * magic; |
79 | | - var sqrtmagic = Math.sqrt(magic); |
80 | | - dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); |
81 | | - dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); |
82 | | - var mglat = lat + dlat; |
83 | | - var mglng = lng + dlng; |
84 | | - return [mglng, mglat] |
85 | 116 | } |
| 117 | + return transform(lng, lat) |
86 | 118 | }; |
87 | 119 |
|
88 | 120 | /** |
89 | 121 | * GCJ02 转换为 WGS84 |
90 | | - * @param lng |
91 | | - * @param lat |
| 122 | + * @param {number} lng |
| 123 | + * @param {number} lat |
92 | 124 | * @returns {*[]} |
93 | 125 | */ |
94 | | - var gcj02towgs84 = function gcj02towgs84(lng, lat) { |
95 | | - var lat = +lat; |
96 | | - var lng = +lng; |
97 | | - if (out_of_china(lng, lat)) { |
| 126 | + function gcj02towgs84(lng, lat) { |
| 127 | + if (!isInChina(lng, lat)) { |
98 | 128 | return [lng, lat] |
99 | | - } else { |
100 | | - var dlat = transformlat(lng - 105.0, lat - 35.0); |
101 | | - var dlng = transformlng(lng - 105.0, lat - 35.0); |
102 | | - var radlat = lat / 180.0 * PI; |
103 | | - var magic = Math.sin(radlat); |
104 | | - magic = 1 - ee * magic * magic; |
105 | | - var sqrtmagic = Math.sqrt(magic); |
106 | | - dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); |
107 | | - dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); |
108 | | - var mglat = lat + dlat; |
109 | | - var mglng = lng + dlng; |
110 | | - return [lng * 2 - mglng, lat * 2 - mglat] |
111 | 129 | } |
| 130 | + var out = transform(lng, lat) |
| 131 | + return [lng * 2 - out[0], lat * 2 - out[1]] |
112 | 132 | }; |
113 | 133 |
|
114 | | - var transformlat = function transformlat(lng, lat) { |
115 | | - var lat = +lat; |
116 | | - var lng = +lng; |
| 134 | + function transform(lng, lat) { |
| 135 | + var dlat = transformlat(lng - 105.0, lat - 35.0); |
| 136 | + var dlng = transformlng(lng - 105.0, lat - 35.0); |
| 137 | + var radlat = lat / 180.0 * PI; |
| 138 | + var magic = Math.sin(radlat); |
| 139 | + magic = 1 - ee * magic * magic; |
| 140 | + var sqrtmagic = Math.sqrt(magic); |
| 141 | + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); |
| 142 | + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); |
| 143 | + var mglat = lat + dlat; |
| 144 | + var mglng = lng + dlng; |
| 145 | + return [mglng, mglat] |
| 146 | + } |
| 147 | + |
| 148 | + function transformlat(lng, lat) { |
117 | 149 | var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); |
118 | 150 | ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; |
119 | 151 | ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; |
120 | 152 | ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; |
121 | 153 | return ret |
122 | 154 | }; |
123 | 155 |
|
124 | | - var transformlng = function transformlng(lng, lat) { |
125 | | - var lat = +lat; |
126 | | - var lng = +lng; |
| 156 | + function transformlng(lng, lat) { |
127 | 157 | var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); |
128 | 158 | ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; |
129 | 159 | ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; |
130 | 160 | ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; |
131 | 161 | return ret |
132 | 162 | }; |
133 | 163 |
|
134 | | - /** |
135 | | - * 判断是否在国内,不在国内则不做偏移 |
136 | | - * @param lng |
137 | | - * @param lat |
138 | | - * @returns {boolean} |
139 | | - */ |
140 | | - var out_of_china = function out_of_china(lng, lat) { |
141 | | - var lat = +lat; |
142 | | - var lng = +lng; |
143 | | - // 纬度3.86~53.55,经度73.66~135.05 |
144 | | - return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); |
145 | | - }; |
146 | | - |
147 | 164 | return { |
| 165 | + // 向前兼容 |
148 | 166 | bd09togcj02: bd09togcj02, |
149 | 167 | gcj02tobd09: gcj02tobd09, |
150 | 168 | wgs84togcj02: wgs84togcj02, |
151 | | - gcj02towgs84: gcj02towgs84 |
| 169 | + gcj02towgs84: gcj02towgs84, |
| 170 | + // 小驼峰命名风格 |
| 171 | + bd09ToGcj02: bd09togcj02, |
| 172 | + gcj02ToBd09: gcj02tobd09, |
| 173 | + wgs84ToGcj02: wgs84togcj02, |
| 174 | + gcj02ToWgs84: gcj02towgs84, |
| 175 | + bd09ToWgs84: function (lng, lat) { |
| 176 | + var gcj02 = bd09togcj02(lng, lat) |
| 177 | + return gcj02towgs84(gcj02[0], gcj02[1]) |
| 178 | + }, |
| 179 | + wgs84ToBd09: function (lng, lat) { |
| 180 | + var gcj02 = wgs84togcj02(lng, lat) |
| 181 | + return gcj02tobd09(gcj02[0], gcj02[1]) |
| 182 | + } |
152 | 183 | } |
153 | 184 | })); |
0 commit comments