1use std::f64::consts::PI;
2const LL2MC: [[f64; 10]; 6] = [
4 [
5 -0.0015702102444,
6 111320.7020616939,
7 1704480524535203.0,
8 -10338987376042340.0,
9 26112667856603880.0,
10 -35149669176653700.0,
11 26595700718403920.0,
12 -10725012454188240.0,
13 1800819912950474.0,
14 82.5,
15 ],
16 [
17 0.0008277824516172526,
18 111320.7020463578,
19 647795574.6671607,
20 -4082003173.641316,
21 10774905663.51142,
22 -15171875531.51559,
23 12053065338.62167,
24 -5124939663.577472,
25 913311935.9512032,
26 67.5,
27 ],
28 [
29 0.00337398766765,
30 111320.7020202162,
31 4481351.045890365,
32 -23393751.19931662,
33 79682215.47186455,
34 -115964993.2797253,
35 97236711.15602145,
36 -43661946.33752821,
37 8477230.501135234,
38 52.5,
39 ],
40 [
41 0.00220636496208,
42 111320.7020209128,
43 51751.86112841131,
44 3796837.749470245,
45 992013.7397791013,
46 -1221952.21711287,
47 1340652.697009075,
48 -620943.6990984312,
49 144416.9293806241,
50 37.5,
51 ],
52 [
53 -0.0003441963504368392,
54 111320.7020576856,
55 278.2353980772752,
56 2485758.690035394,
57 6070.750963243378,
58 54821.18345352118,
59 9540.606633304236,
60 -2710.55326746645,
61 1405.483844121726,
62 22.5,
63 ],
64 [
65 -0.0003218135878613132,
66 111320.7020701615,
67 0.00369383431289,
68 823725.6402795718,
69 0.46104986909093,
70 2351.343141331292,
71 1.58060784298199,
72 8.77738589078284,
73 0.37238884252424,
74 7.45,
75 ],
76];
77
78const LLBAND: [f64; 6] = [75.0, 60.0, 45.0, 30.0, 15.0, 0.0];
79
80const MCBAND: [f64; 6] = [
81 12890594.86,
82 8362377.87,
83 5591021.0,
84 3481989.83,
85 1678043.12,
86 0.0,
87];
88const MC2LL: [[f64; 10]; 6] = [
89 [
90 1.410526172116255e-8,
91 0.00000898305509648872,
92 -1.9939833816331,
93 200.9824383106796,
94 -187.2403703815547,
95 91.6087516669843,
96 -23.38765649603339,
97 2.57121317296198,
98 -0.03801003308653,
99 17337981.2,
100 ],
101 [
102 -7.435856389565537e-9,
103 0.000008983055097726239,
104 -0.78625201886289,
105 96.32687599759846,
106 -1.85204757529826,
107 -59.36935905485877,
108 47.40033549296737,
109 -16.50741931063887,
110 2.28786674699375,
111 10260144.86,
112 ],
113 [
114 -3.030883460898826e-8,
115 0.00000898305509983578,
116 0.30071316287616,
117 59.74293618442277,
118 7.357984074871,
119 -25.38371002664745,
120 13.45380521110908,
121 -3.29883767235584,
122 0.32710905363475,
123 6856817.37,
124 ],
125 [
126 -1.981981304930552e-8,
127 0.000008983055099779535,
128 0.03278182852591,
129 40.31678527705744,
130 0.65659298677277,
131 -4.44255534477492,
132 0.85341911805263,
133 0.12923347998204,
134 -0.04625736007561,
135 4482777.06,
136 ],
137 [
138 3.09191371068437e-9,
139 0.000008983055096812155,
140 0.00006995724062,
141 23.10934304144901,
142 -0.00023663490511,
143 -0.6321817810242,
144 -0.00663494467273,
145 0.03430082397953,
146 -0.00466043876332,
147 2555164.4,
148 ],
149 [
150 2.890871144776878e-9,
151 0.000008983055095805407,
152 -3.068298e-8,
153 7.47137025468032,
154 -0.00000353937994,
155 -0.02145144861037,
156 -0.00001234426596,
157 0.00010322952773,
158 -0.00000323890364,
159 826088.5,
160 ],
161];
162
163pub fn bd2gcj(bd: (f64, f64)) -> (f64, f64) {
171 let (x, y) = bd;
173 let x_pi = PI * 3000.0 / 180.0;
174 let gcj_x = x - 0.0065;
175 let gcj_y = y - 0.006;
176 let z = (gcj_x.powi(2) + gcj_y.powi(2)).sqrt() - 0.00002 * ((gcj_y * x_pi).sin());
177 let theta = gcj_y.atan2(gcj_x) - (gcj_x * x_pi).cos() * 0.000003;
178 (theta.cos() * z, theta.sin() * z)
180}
181
182pub fn gcj2bd(gcj: (f64, f64)) -> (f64, f64) {
190 let (x, y) = gcj;
192 let x_pi = PI * 3000.0 / 180.0;
193 let z = (x.powi(2) + y.powi(2)).sqrt() + (y * x_pi).sin() * 0.00002;
194 let theta = y.atan2(x) + (x * x_pi).cos() * 0.000003;
195 (theta.cos() * z + 0.0065, theta.sin() * z + 0.006)
197}
198pub fn wgs2gcj(wgs: (f64, f64)) -> (f64, f64) {
206 let (x, y) = wgs;
207 if x < 72.004 || x > 137.8347 || y < 0.8293 || y > 55.8271 {
209 return wgs;
210 }
211 let a = 6378245.0;
212 let ee = 0.00669342162296594323;
213 let delta_x = x - 105.0;
215 let delta_y = y - 35.0;
216
217 let mut d_lat = -100.0
218 + 2.0 * delta_x
219 + 3.0 * delta_y
220 + 0.2 * delta_y.powi(2)
221 + 0.1 * delta_x * delta_y
222 + 0.2 * (delta_x.abs().sqrt())
223 + (20.0 * ((6.0 * delta_x * PI).sin()) + 20.0 * ((2.0 * delta_x * PI).sin())) * 2.0 / 3.0
224 + (20.0 * ((delta_y * PI).sin()) + 40.0 * ((delta_y / 3.0 * PI).sin())) * 2.0 / 3.0
225 + (160.0 * ((delta_y / 12.0 * PI).sin()) + 320.0 * ((delta_y * PI / 30.0).sin())) * 2.0
226 / 3.0;
227
228 let mut d_lon = 300.0
229 + delta_x
230 + 2.0 * delta_y
231 + 0.1 * delta_x.powi(2)
232 + 0.1 * delta_x * delta_y
233 + 0.1 * delta_x.abs().sqrt()
234 + (20.0 * ((6.0 * delta_x * PI).sin()) + 20.0 * ((2.0 * delta_x * PI).sin())) * 2.0 / 3.0
235 + (20.0 * ((delta_x * PI).sin()) + 40.0 * ((delta_x / 3.0 * PI).sin())) * 2.0 / 3.0
236 + (150.0 * ((delta_x / 12.0 * PI).sin()) + 300.0 * ((delta_x / 30.0 * PI).sin())) * 2.0
237 / 3.0;
238
239 let rad_lat = y / 180.0 * PI;
240 let mut magic = rad_lat.sin();
241 magic = 1.0 - ee * magic * magic;
242 let magic_sqrt = magic.sqrt();
243
244 d_lon = (d_lon * 180.0) / (a / magic_sqrt * (rad_lat.cos()) * PI);
245 d_lat = (d_lat * 180.0) / ((a * (1.0 - ee)) / (magic * magic_sqrt) * PI);
246 (x + d_lon, y + d_lat)
247}
248pub fn gcj2wgs(gcj: (f64, f64)) -> (f64, f64) {
256 let (gcj_x, gcj_y) = gcj;
257 let (x, y) = wgs2gcj(gcj);
258
259 let d_lon = x - gcj_x;
260 let d_lat = y - gcj_y;
261 (gcj_x - d_lon, gcj_y - d_lat)
262}
263
264pub fn bd2wgs(bd: (f64, f64)) -> (f64, f64) {
272 gcj2wgs(bd2gcj(bd))
274}
275pub fn wgs2bd(wgs: (f64, f64)) -> (f64, f64) {
283 gcj2bd(wgs2gcj(wgs))
285}
286
287fn get_loop(mut lon: f64, min_v: f64, max_v: f64) -> f64 {
288 while lon > max_v {
289 lon -= max_v - min_v;
290 }
291 while lon < min_v {
292 lon += max_v - min_v;
293 }
294 lon
295}
296fn get_range(mut lat: f64, min_v: f64, max_v: f64) -> f64 {
297 lat = lat.max(min_v);
298 lat = lat.min(max_v);
299 lat
300}
301pub fn bd_wgs2mkt(bdwgs: (f64, f64)) -> (f64, f64) {
309 let (mut x, mut y) = bdwgs;
310 x = get_loop(x, -180.0, 180.0);
311 y = get_range(y, -74.0, 74.0);
312 let mut cf: Option<[f64; 10]> = None;
313 let mut i: usize = 0;
314 for item in LLBAND {
315 if y >= item {
316 cf = Some(LL2MC[i]);
317 break;
318 }
319 i += 1;
320 }
321 if let None = cf {
323 for item in LLBAND {
324 if y <= -item {
325 cf = Some(LL2MC[i]);
326 break;
327 }
328 i -= 1;
329 }
330 }
331 match cf {
333 Some(_cf)=> {
334 x = _cf[0] + _cf[1] * x.abs();
335 let cc = y.abs() / _cf[9];
336 y = _cf[2]
337 + _cf[3] * cc
338 + _cf[4] * cc * cc
339 + _cf[5] * cc * cc * cc
340 + _cf[6] * cc * cc * cc * cc
341 + _cf[7] * cc * cc * cc * cc * cc
342 + _cf[8] * cc * cc * cc * cc * cc * cc;
343 return (x.abs(), y.abs());
344 }
345 _ => {
346 panic!("error occured");
347 }
348 }
349}
350pub fn bd_mkt2wgs(bdmkt: (f64, f64)) -> (f64, f64) {
358 let (mut x, mut y) = bdmkt;
359 x = x.abs();
360 y = y.abs();
361 let mut cf: Option<[f64; 10]> = None;
362 let mut i: usize = 0;
363 for item in MCBAND {
364 if y >= item {
365 cf = Some(MC2LL[i]);
366 break;
367 }
368 i += 1;
369 }
370 match cf {
371 Some(_cf) => {
372 x = _cf[0] + _cf[1] * (x.abs());
373 let cc = y.abs() / _cf[9];
374 y = _cf[2]
375 + _cf[3] * cc
376 + _cf[4] * cc * cc
377 + _cf[5] * cc * cc * cc
378 + _cf[6] * cc * cc * cc * cc
379 + _cf[7] * cc * cc * cc * cc * cc
380 + _cf[8] * cc * cc * cc * cc * cc * cc;
381 return (x.abs(), y.abs());
382 }
383 _ => {
384 panic!("error occured");
385 }
386 }
387}
388
389pub fn wgs2bdmkt(wgs:(f64, f64)) -> (f64, f64) {
397 bd_wgs2mkt(wgs2bd(wgs))
398}
399pub fn bdmkt2wgs(bdmkt:(f64, f64)) -> (f64, f64) {
407 bd2wgs(bd_mkt2wgs(bdmkt))
408}
409
410
411#[cfg(test)]
412mod tests {
413 use super::*;
414
415 #[test]
416 fn bd2gcj_test() {
417 let (x, y) = bd2gcj((118.0, 32.0));
418 assert_eq!(x, 117.99349542486605);
419 assert_eq!(y, 31.994068010063465);
420 }
421 #[test]
422 fn gcj2bd_test() {
423 let (x, y) = gcj2bd((118.0, 32.0));
424 assert_eq!(x, 118.00653128313961);
425 assert_eq!(y, 32.00581846664105);
426 }
427
428 #[test]
429 fn wgs2gcj_test() {
430 let (x, y) = wgs2gcj((118.0, 32.0));
431 assert_eq!(x, 118.00543101383846);
432 assert_eq!(y, 31.997964381055795);
433 }
434
435 #[test]
436 fn gcj2wgs_test() {
437 let (x, y) = gcj2wgs((118.0, 32.0));
438 assert_eq!(x, 117.99456898616154);
439 assert_eq!(y, 32.002035618944205);
440 }
441 #[test]
442 fn bd2wgs_test() {
443 let (x, y) = bd2wgs((118.0, 32.0));
444 assert_eq!(x, 117.98808485929571);
445 assert_eq!(y, 31.996121973877745);
446 }
447
448 #[test]
449 fn wgs2bd_test() {
450 let (x, y) = wgs2bd((118.0, 32.0));
451 assert_eq!(x, 118.01198481069936);
452 assert_eq!(y, 32.00370423982076);
453 }
454
455 #[test]
456 fn bd_wgs2mkt_test() {
457 let (x, y) = bd_wgs2mkt((118.0, 32.0));
458 assert_eq!(x, 13135842.840674074);
459 assert_eq!(y, 3740459.445338771);
460 }
461
462 #[test]
463 fn bd_mkt2wgs_test() {
464 let (x, y) = bd_mkt2wgs((13135842.840674074,3740459.445338771));
465 assert_eq!(x, 117.99999999999993);
466 assert_eq!(y, 32.00000001036519);
467 }
468
469 #[test]
470 fn wgs2bdmkt_test() {
471 let (x, y) = wgs2bdmkt((118.0,32.0));
472 assert_eq!(x, 13137176.998214714);
473 assert_eq!(y, 3740943.32810748);
474 }
475
476 #[test]
477 fn bdmkt2wgs_test() {
478 let (x, y) = bdmkt2wgs((13137176.998214714,3740943.32810748));
479 assert_eq!(x, 117.9999832373631);
480 assert_eq!(y, 31.999983711526742);
481 }
482}