1use geo::Coord;
2use std::f64::consts::PI;
3
4use crate::gcj02::{gcj02_to_wgs84, wgs84_to_gcj02};
5
6pub fn wgs84_to_bd09(coordinate: Coord) -> Coord {
7    gcj02_to_bd09(wgs84_to_gcj02(coordinate))
8}
9
10pub fn bd09_to_wgs84(coordinate: Coord) -> Coord {
11    gcj02_to_wgs84(bd09_to_gcj02(coordinate))
12}
13
14const BD_DLAT: f64 = 0.0060;
16const BD_DLON: f64 = 0.0065;
17
18pub fn gcj02_to_bd09(coordinate: Coord) -> Coord {
19    let x = coordinate.x;
20    let y = coordinate.y;
21
22    let r = (x * x + y * y).sqrt() + 0.00002 * (y * PI * 3000.0 / 180.0).sin();
23    let theta = (y / x).atan() + 0.000003 * (x * PI * 3000.0 / 180.0).cos();
24
25    (r * theta.cos() + BD_DLON, r * theta.sin() + BD_DLAT).into()
26}
27
28pub fn bd09_to_gcj02(coordinate: Coord) -> Coord {
29    let x = coordinate.x - BD_DLON;
30    let y = coordinate.y - BD_DLAT;
31
32    let r = (x * x + y * y).sqrt() - 0.00002 * (y * PI * 3000.0 / 180.0).sin();
33    let theta = y.atan2(x) - 0.000003 * (x * PI * 3000.0 / 180.0).cos();
34
35    (r * theta.cos(), r * theta.sin()).into()
36}