1
1
import Point from './Point'
2
2
import Pixel from './Pixel'
3
3
4
+ // static EARTHRADIUS = 6370996.81
5
+ const EARTHRADIUS = 6378137
6
+ const MCBAND = [ 12890594.86 , 8362377.87 , 5591021 , 3481989.83 , 1678043.12 , 0 ]
7
+ const LLBAND = [ 75 , 60 , 45 , 30 , 15 , 0 ]
8
+ const MC2LL = [
9
+ [
10
+ 1.410526172116255e-8 , 0.00000898305509648872 , - 1.9939833816331 , 200.9824383106796 , - 187.2403703815547 , 91.6087516669843 , - 23.38765649603339 ,
11
+ 2.57121317296198 , - 0.03801003308653 , 17337981.2
12
+ ] ,
13
+ [
14
+ - 7.435856389565537e-9 , 0.000008983055097726239 , - 0.78625201886289 , 96.32687599759846 , - 1.85204757529826 , - 59.36935905485877 , 47.40033549296737 ,
15
+ - 16.50741931063887 , 2.28786674699375 , 10260144.86
16
+ ] ,
17
+ [
18
+ - 3.030883460898826e-8 , 0.00000898305509983578 , 0.30071316287616 , 59.74293618442277 , 7.357984074871 , - 25.38371002664745 , 13.45380521110908 ,
19
+ - 3.29883767235584 , 0.32710905363475 , 6856817.37
20
+ ] ,
21
+ [
22
+ - 1.981981304930552e-8 , 0.000008983055099779535 , 0.03278182852591 , 40.31678527705744 , 0.65659298677277 , - 4.44255534477492 , 0.85341911805263 ,
23
+ 0.12923347998204 , - 0.04625736007561 , 4482777.06
24
+ ] ,
25
+ [
26
+ 3.09191371068437e-9 , 0.000008983055096812155 , 0.00006995724062 , 23.10934304144901 , - 0.00023663490511 , - 0.6321817810242 , - 0.00663494467273 ,
27
+ 0.03430082397953 , - 0.00466043876332 , 2555164.4
28
+ ] ,
29
+ [
30
+ 2.890871144776878e-9 , 0.000008983055095805407 , - 3.068298e-8 , 7.47137025468032 , - 0.00000353937994 , - 0.02145144861037 , - 0.00001234426596 ,
31
+ 0.00010322952773 , - 0.00000323890364 , 826088.5
32
+ ]
33
+ ]
34
+
35
+ const LL2MC = [
36
+ [
37
+ - 0.0015702102444 , 111320.7020616939 , 1704480524535203 , - 10338987376042340 , 26112667856603880 , - 35149669176653700 , 26595700718403920 ,
38
+ - 10725012454188240 , 1800819912950474 , 82.5
39
+ ] ,
40
+ [
41
+ 0.0008277824516172526 , 111320.7020463578 , 647795574.6671607 , - 4082003173.641316 , 10774905663.51142 , - 15171875531.51559 , 12053065338.62167 ,
42
+ - 5124939663.577472 , 913311935.9512032 , 67.5
43
+ ] ,
44
+ [
45
+ 0.00337398766765 , 111320.7020202162 , 4481351.045890365 , - 23393751.19931662 , 79682215.47186455 , - 115964993.2797253 , 97236711.15602145 ,
46
+ - 43661946.33752821 , 8477230.501135234 , 52.5
47
+ ] ,
48
+ [
49
+ 0.00220636496208 , 111320.7020209128 , 51751.86112841131 , 3796837.749470245 , 992013.7397791013 , - 1221952.21711287 , 1340652.697009075 ,
50
+ - 620943.6990984312 , 144416.9293806241 , 37.5
51
+ ] ,
52
+ [
53
+ - 0.0003441963504368392 , 111320.7020576856 , 278.2353980772752 , 2485758.690035394 , 6070.750963243378 , 54821.18345352118 , 9540.606633304236 ,
54
+ - 2710.55326746645 , 1405.483844121726 , 22.5
55
+ ] ,
56
+ [
57
+ - 0.0003218135878613132 , 111320.7020701615 , 0.00369383431289 , 823725.6402795718 , 0.46104986909093 , 2351.343141331292 , 1.58060784298199 ,
58
+ 8.77738589078284 , 0.37238884252424 , 7.45
59
+ ]
60
+ ]
61
+
4
62
/**
5
63
* Projection used by [Baidu Map]{@link https://github.com/openlayers/openlayers/issues/3522}
6
64
*/
@@ -9,83 +67,23 @@ class BaiduMapMercatorProjection {
9
67
// super()
10
68
// }
11
69
12
- static EARTHRADIUS = 6370996.81
13
- static MCBAND = [ 12890594.86 , 8362377.87 , 5591021 , 3481989.83 , 1678043.12 , 0 ]
14
- static LLBAND = [ 75 , 60 , 45 , 30 , 15 , 0 ]
15
- static MC2LL = [
16
- [
17
- 1.410526172116255e-8 , 8.98305509648872e-6 , - 1.9939833816331 , 2.009824383106796e2 , - 1.872403703815547e2 , 91.6087516669843 , - 23.38765649603339 ,
18
- 2.57121317296198 , - 0.03801003308653 , 1.73379812e7
19
- ] ,
20
- [
21
- - 7.435856389565537e-9 , 8.983055097726239e-6 , - 0.78625201886289 , 96.32687599759846 , - 1.85204757529826 , - 59.36935905485877 , 47.40033549296737 ,
22
- - 16.50741931063887 , 2.28786674699375 , 1.026014486e7
23
- ] ,
24
- [
25
- - 3.030883460898826e-8 , 8.98305509983578e-6 , 0.30071316287616 , 59.74293618442277 , 7.357984074871 , - 25.38371002664745 , 13.45380521110908 ,
26
- - 3.29883767235584 , 0.32710905363475 , 6.85681737e6
27
- ] ,
28
- [
29
- - 1.981981304930552e-8 , 8.983055099779535e-6 , 0.03278182852591 , 40.31678527705744 , 0.65659298677277 , - 4.44255534477492 , 0.85341911805263 ,
30
- 0.12923347998204 , - 0.04625736007561 , 4.48277706e6
31
- ] ,
32
- [
33
- 3.09191371068437e-9 , 8.983055096812155e-6 , 0.00006995724062 , 23.10934304144901 , - 0.00023663490511 , - 0.6321817810242 , - 0.00663494467273 ,
34
- 0.03430082397953 , - 0.00466043876332 , 2.5551644e6
35
- ] ,
36
- [
37
- 2.890871144776878e-9 , 8.983055095805407e-6 , - 0.00000003068298 , 7.47137025468032 , - 0.00000353937994 , - 0.02145144861037 , - 0.00001234426596 ,
38
- 0.00010322952773 , - 0.00000323890364 , 8.260885e5
39
- ]
40
- ]
41
-
42
- static LL2MC = [
43
- [
44
- - 0.0015702102444 , 1.113207020616939e5 , 1.704480524535203e15 , - 1.033898737604234e16 , 2.611266785660388e16 , - 3.51496691766537e16 ,
45
- 2.659570071840392e16 , - 1.072501245418824e16 , 1.800819912950474e15 , 82.5
46
- ] ,
47
- [
48
- 8.277824516172526e-4 , 1.113207020463578e5 ,
49
- // eslint-disable-next-line no-loss-of-precision
50
- // eslint-disable-next-line @typescript-eslint/no-loss-of-precision
51
- 6.477955746671608e8 , - 4.082003173641316e9 , 1.077490566351142e10 , - 1.517187553151559e10 , 1.205306533862167e10 , - 5.124939663577472e9 ,
52
- 9.133119359512032e8 , 67.5
53
- ] ,
54
- [
55
- 0.00337398766765 , 1.113207020202162e5 , 4.481351045890365e6 , - 2.339375119931662e7 , 7.968221547186455e7 , - 1.159649932797253e8 ,
56
- 9.723671115602145e7 , - 4.366194633752821e7 , 8.477230501135234e6 , 52.5
57
- ] ,
58
- [
59
- 0.00220636496208 , 1.113207020209128e5 , 5.175186112841131e4 , 3.796837749470245e6 , 9.920137397791013e5 , - 1.22195221711287e6 , 1.340652697009075e6 ,
60
- - 6.209436990984312e5 , 1.444169293806241e5 , 37.5
61
- ] ,
62
- [
63
- - 3.441963504368392e-4 , 1.113207020576856e5 , 2.782353980772752e2 , 2.485758690035394e6 , 6.070750963243378e3 , 5.482118345352118e4 ,
64
- 9.540606633304236e3 , - 2.71055326746645e3 , 1.405483844121726e3 , 22.5
65
- ] ,
66
- [
67
- - 3.218135878613132e-4 , 1.113207020701615e5 , 0.00369383431289 , 8.237256402795718e5 , 0.46104986909093 , 2.351343141331292e3 , 1.58060784298199 ,
68
- 8.77738589078284 , 0.37238884252424 , 7.45
69
- ]
70
- ]
71
-
72
70
/**
73
71
* 根据平面直角坐标计算两点间距离;
74
72
* @param {Point } point1 平面直角点坐标1
75
73
* @param {Point } point2 平面直角点坐标2;
76
74
* @return {Number } 返回两点间的距离
77
75
*/
78
- static getDistanceByMC = function ( point1 , point2 ) {
76
+ getDistanceByMC ( point1 , point2 ) {
79
77
if ( ! point1 || ! point2 ) return 0
80
- point1 = BaiduMapMercatorProjection . convertMC2LL ( point1 )
78
+ point1 = this . inverse ( point1 )
81
79
if ( ! point1 ) return 0
82
- const x1 = BaiduMapMercatorProjection . toRadians ( point1 . lng )
83
- const y1 = BaiduMapMercatorProjection . toRadians ( point1 . lat )
84
- point2 = BaiduMapMercatorProjection . convertMC2LL ( point2 )
80
+ const x1 = toRadians ( point1 . lng )
81
+ const y1 = toRadians ( point1 . lat )
82
+ point2 = this . inverse ( point2 )
85
83
if ( ! point2 ) return 0
86
- const x2 = BaiduMapMercatorProjection . toRadians ( point2 . lng )
87
- const y2 = BaiduMapMercatorProjection . toRadians ( point2 . lat )
88
- return BaiduMapMercatorProjection . getDistance ( x1 , x2 , y1 , y2 )
84
+ const x2 = toRadians ( point2 . lng )
85
+ const y2 = toRadians ( point2 . lat )
86
+ return getDistance ( x1 , x2 , y1 , y2 )
89
87
}
90
88
91
89
/**
@@ -94,114 +92,63 @@ class BaiduMapMercatorProjection {
94
92
* @param {Point } point2 经纬度点坐标2;
95
93
* @return {Number } 返回两点间的距离
96
94
*/
97
- static getDistanceByLL = function ( point1 , point2 ) {
95
+ getDistanceByLL ( point1 , point2 ) {
98
96
if ( ! point1 || ! point2 ) return 0
99
- point1 . lng = BaiduMapMercatorProjection . getLoop ( point1 . lng , - 180 , 180 )
100
- point1 . lat = BaiduMapMercatorProjection . getRange ( point1 . lat , - 74 , 74 )
101
- point2 . lng = BaiduMapMercatorProjection . getLoop ( point2 . lng , - 180 , 180 )
102
- point2 . lat = BaiduMapMercatorProjection . getRange ( point2 . lat , - 74 , 74 )
103
- const x1 = BaiduMapMercatorProjection . toRadians ( point1 . lng )
104
- const y1 = BaiduMapMercatorProjection . toRadians ( point1 . lat )
105
- const x2 = BaiduMapMercatorProjection . toRadians ( point2 . lng )
106
- const y2 = BaiduMapMercatorProjection . toRadians ( point2 . lat )
107
- return BaiduMapMercatorProjection . getDistance ( x1 , x2 , y1 , y2 )
97
+ point1 . lng = getLoop ( point1 . lng , - 180 , 180 )
98
+ point1 . lat = getRange ( point1 . lat , - 74 , 74 )
99
+ point2 . lng = getLoop ( point2 . lng , - 180 , 180 )
100
+ point2 . lat = getRange ( point2 . lat , - 74 , 74 )
101
+ const x1 = toRadians ( point1 . lng )
102
+ const y1 = toRadians ( point1 . lat )
103
+ const x2 = toRadians ( point2 . lng )
104
+ const y2 = toRadians ( point2 . lat )
105
+ return getDistance ( x1 , x2 , y1 , y2 )
108
106
}
109
107
110
108
/**
111
109
* 平面直角坐标转换成经纬度坐标;
112
110
* @param {Point } point 平面直角坐标
113
111
* @return {Point } 返回经纬度坐标
114
112
*/
115
- static convertMC2LL = function ( point ) {
113
+ inverse ( point ) {
116
114
let factor
117
115
const temp = new Point ( Math . abs ( point . lng ) , Math . abs ( point . lat ) )
118
- for ( let i = 0 ; i < BaiduMapMercatorProjection . MCBAND . length ; i ++ ) {
119
- if ( temp . lat >= BaiduMapMercatorProjection . MCBAND [ i ] ) {
120
- factor = BaiduMapMercatorProjection . MC2LL [ i ]
116
+ for ( let i = 0 ; i < MCBAND . length ; i ++ ) {
117
+ if ( temp . lat >= MCBAND [ i ] ) {
118
+ factor = MC2LL [ i ]
121
119
break
122
120
}
123
121
}
124
- const lnglat = BaiduMapMercatorProjection . convertor ( point , factor )
125
- return new Point ( lnglat ?. lng . toFixed ( 6 ) , lnglat ?. lat . toFixed ( 6 ) )
122
+ const lnglat = convertor ( point , factor )
123
+ return new Point ( lnglat ?. lng , lnglat ?. lat )
126
124
}
127
125
128
126
/**
129
127
* 经纬度坐标转换成平面直角坐标;
130
128
* @param {Point } point 经纬度坐标
131
129
* @return {Point } 返回平面直角坐标
132
130
*/
133
- static convertLL2MC = function ( point ) {
131
+ forward ( point ) {
134
132
let factor
135
- point . lng = BaiduMapMercatorProjection . getLoop ( point . lng , - 180 , 180 )
136
- point . lat = BaiduMapMercatorProjection . getRange ( point . lat , - 74 , 74 )
133
+ point . lng = getLoop ( point . lng , - 180 , 180 )
134
+ point . lat = getRange ( point . lat , - 74 , 74 )
137
135
const temp = new Point ( point . lng , point . lat )
138
- for ( let i = 0 ; i < BaiduMapMercatorProjection . LLBAND . length ; i ++ ) {
139
- if ( temp . lat >= BaiduMapMercatorProjection . LLBAND [ i ] ) {
140
- factor = BaiduMapMercatorProjection . LL2MC [ i ]
136
+ for ( let i = 0 ; i < LLBAND . length ; i ++ ) {
137
+ if ( temp . lat >= LLBAND [ i ] ) {
138
+ factor = LL2MC [ i ]
141
139
break
142
140
}
143
141
}
144
142
if ( ! factor ) {
145
- for ( let i = BaiduMapMercatorProjection . LLBAND . length - 1 ; i >= 0 ; i -- ) {
146
- if ( temp . lat <= - BaiduMapMercatorProjection . LLBAND [ i ] ) {
147
- factor = BaiduMapMercatorProjection . LL2MC [ i ]
143
+ for ( let i = LLBAND . length - 1 ; i >= 0 ; i -- ) {
144
+ if ( temp . lat <= - LLBAND [ i ] ) {
145
+ factor = LL2MC [ i ]
148
146
break
149
147
}
150
148
}
151
149
}
152
- const mc = BaiduMapMercatorProjection . convertor ( point , factor )
153
- return new Point ( mc ?. lng . toFixed ( 2 ) , mc ?. lat . toFixed ( 2 ) )
154
- }
155
-
156
- static convertor = function ( fromPoint , factor ) {
157
- if ( ! fromPoint || ! factor ) {
158
- return
159
- }
160
- let x = factor [ 0 ] + factor [ 1 ] * Math . abs ( fromPoint . lng )
161
- const temp = Math . abs ( fromPoint . lat ) / factor [ 9 ]
162
- let y =
163
- factor [ 2 ] +
164
- factor [ 3 ] * temp +
165
- factor [ 4 ] * temp * temp +
166
- factor [ 5 ] * temp * temp * temp +
167
- factor [ 6 ] * temp * temp * temp * temp +
168
- factor [ 7 ] * temp * temp * temp * temp * temp +
169
- factor [ 8 ] * temp * temp * temp * temp * temp * temp
170
- x *= fromPoint . lng < 0 ? - 1 : 1
171
- y *= fromPoint . lat < 0 ? - 1 : 1
172
- return new Point ( x , y )
173
- }
174
-
175
- static getDistance = function ( x1 , x2 , y1 , y2 ) {
176
- return BaiduMapMercatorProjection . EARTHRADIUS * Math . acos ( Math . sin ( y1 ) * Math . sin ( y2 ) + Math . cos ( y1 ) * Math . cos ( y2 ) * Math . cos ( x2 - x1 ) )
177
- }
178
-
179
- static toRadians = function ( angdeg ) {
180
- return ( Math . PI * angdeg ) / 180
181
- }
182
-
183
- static toDegrees = function ( angrad ) {
184
- return ( 180 * angrad ) / Math . PI
185
- }
186
-
187
- static getRange = function ( v , a , b ) {
188
- if ( a != null ) {
189
- v = Math . max ( v , a )
190
- }
191
- if ( b != null ) {
192
- v = Math . min ( v , b )
193
- }
194
- return v
195
- }
196
-
197
- static getLoop = function ( v , a , b ) {
198
- while ( v > b ) {
199
- v -= b - a
200
- }
201
- while ( v < a ) {
202
- v += b - a
203
- }
204
- return v
150
+ const mc = convertor ( point , factor )
151
+ return new Point ( mc ?. lng , mc ?. lat )
205
152
}
206
153
207
154
/**
@@ -210,7 +157,7 @@ class BaiduMapMercatorProjection {
210
157
* @return Point 墨卡托
211
158
*/
212
159
lngLatToMercator ( point , curCity ?) {
213
- return BaiduMapMercatorProjection . convertLL2MC ( point )
160
+ return this . forward ( point )
214
161
}
215
162
216
163
/**
@@ -219,7 +166,7 @@ class BaiduMapMercatorProjection {
219
166
* @return Pixel 平面坐标
220
167
*/
221
168
lngLatToPoint ( point : Point ) : Pixel {
222
- const mercator = BaiduMapMercatorProjection . convertLL2MC ( point )
169
+ const mercator = this . forward ( point )
223
170
return new Pixel ( mercator . lng , mercator . lat )
224
171
}
225
172
@@ -229,7 +176,7 @@ class BaiduMapMercatorProjection {
229
176
* @returns Point 经纬度
230
177
*/
231
178
mercatorToLngLat ( point , curCity ?) {
232
- return BaiduMapMercatorProjection . convertMC2LL ( point )
179
+ return this . inverse ( point )
233
180
}
234
181
235
182
/**
@@ -239,7 +186,7 @@ class BaiduMapMercatorProjection {
239
186
*/
240
187
pointToLngLat ( point ) {
241
188
const mercator = new Point ( point . x , point . y )
242
- return BaiduMapMercatorProjection . convertMC2LL ( mercator )
189
+ return this . inverse ( mercator )
243
190
}
244
191
245
192
/**
@@ -286,4 +233,55 @@ class BaiduMapMercatorProjection {
286
233
}
287
234
}
288
235
236
+ function convertor ( fromPoint , factor ) {
237
+ if ( ! fromPoint || ! factor ) {
238
+ return
239
+ }
240
+ let x = factor [ 0 ] + factor [ 1 ] * Math . abs ( fromPoint . lng )
241
+ const temp = Math . abs ( fromPoint . lat ) / factor [ 9 ]
242
+ let y =
243
+ factor [ 2 ] +
244
+ factor [ 3 ] * temp +
245
+ factor [ 4 ] * temp * temp +
246
+ factor [ 5 ] * temp * temp * temp +
247
+ factor [ 6 ] * temp * temp * temp * temp +
248
+ factor [ 7 ] * temp * temp * temp * temp * temp +
249
+ factor [ 8 ] * temp * temp * temp * temp * temp * temp
250
+ x *= fromPoint . lng < 0 ? - 1 : 1
251
+ y *= fromPoint . lat < 0 ? - 1 : 1
252
+ return new Point ( x , y )
253
+ }
254
+
255
+ function getLoop ( v , a , b ) {
256
+ while ( v > b ) {
257
+ v -= b - a
258
+ }
259
+ while ( v < a ) {
260
+ v += b - a
261
+ }
262
+ return v
263
+ }
264
+
265
+ function getRange ( v , a , b ) {
266
+ if ( a != null ) {
267
+ v = Math . max ( v , a )
268
+ }
269
+ if ( b != null ) {
270
+ v = Math . min ( v , b )
271
+ }
272
+ return v
273
+ }
274
+
275
+ function getDistance ( x1 , x2 , y1 , y2 ) {
276
+ return EARTHRADIUS * Math . acos ( Math . sin ( y1 ) * Math . sin ( y2 ) + Math . cos ( y1 ) * Math . cos ( y2 ) * Math . cos ( x2 - x1 ) )
277
+ }
278
+
279
+ function toRadians ( angdeg ) {
280
+ return ( Math . PI * angdeg ) / 180
281
+ }
282
+
283
+ function toDegrees ( angrad ) {
284
+ return ( 180 * angrad ) / Math . PI
285
+ }
286
+
289
287
export default BaiduMapMercatorProjection
0 commit comments