JavaScript

CoordinateTransform.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
155
156
/**
* Created by Daniel on 2016/7/27.
*
* 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
*
* 会有偏差,但是偏差在可接受范围之内
*/
(function (root, factory) {
root.CoordinateTransform = factory();
}(this, function () {
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
var PI = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;
/**
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
* 即 百度 转 谷歌、高德
* @param bd_lon
* @param bd_lat
* @returns {[]} GCJ-02 坐标:[经度,纬度]
*/
var transformBD09ToGCJ02 = function (bd_lon, bd_lat) {
var x = bd_lon - 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);
return [gg_lng, gg_lat]
};

/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* 即谷歌、高德 转 百度
* @param lng
* @param lat
* @returns {[]} BD-09 坐标:[经度,纬度]
*/
var transformGCJ02ToBD09 = function (lng, lat) {
var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
var bd_lng = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
return [bd_lng, bd_lat]
};

/**
* WGS84转GCj02
* @param lng
* @param lat
* @returns {[]} GCj02 坐标:[经度,纬度]
*/
var transformWGS84ToGCJ02 = function (lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat]
} else {
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;
return [mgLng, mgLat]
}
};

/**
* GCJ02 转换为 WGS84
* @param lng
* @param lat
* @returns {[]} WGS84 坐标:[经度,纬度]
*/
var transformGCJ02ToWGS84 = function (lng, lat) {
if (outOfChina(lng, lat)) {
return [lng, lat]
} else {
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;
return [lng * 2 - mgLng, lat * 2 - mgLat]
}
};

/**
* 百度坐标BD09 转 WGS84
*
* @param lng 经度
* @param lat 纬度
* @return {[]} WGS84 坐标:[经度,纬度]
*/
var transformBD09ToWGS84 = function (lng, lat) {
var lngLat = transformBD09ToGCJ02(lng, lat);
return transformGCJ02ToWGS84(lngLat[0], lngLat[1]);
};


/**
* WGS84 转 百度坐标BD09
*
* @param lng 经度
* @param lat 纬度
* @return {[]} BD09 坐标:[经度,纬度]
*/
var transformWGS84ToBD09 = function (lng, lat) {
var lngLat = transformWGS84ToGCJ02(lng, lat);

return transformGCJ02ToBD09(lngLat[0], lngLat[1]);
};


var transformLat = function (lng, lat) {
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));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret
};

var transformLng = function (lng, lat) {
var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret
};

/**
* 判断是否在国内,不在国内则不做偏移
* @param lng
* @param lat
* @returns {boolean}
*/
var outOfChina = function (lng, lat) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
};

return {
transformBD09ToWGS84: transformBD09ToWGS84,
transformWGS84ToBD09: transformWGS84ToBD09,
transformGCJ02ToWGS84: transformGCJ02ToWGS84,
transformWGS84ToGCJ02: transformWGS84ToGCJ02,
transformBD09ToGCJ02: transformBD09ToGCJ02,
transformGCJ02ToBD09: transformGCJ02ToBD09
}
}));

示例

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>坐标转换JS使用例子</title>
</head>
<body>
<h1>提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换,会有偏差,但是偏差在可接受范围之内</h1>
<h1>结果请在控制台查看(Results please view the console)</h1>

</body>
<script type="text/javascript" src="../disk/CoordinateTransform.js"></script>
<script type="text/javascript">

//百度地图 BD09 坐标 转 WGS84
var lngLat_wgs84 = CoordinateTransform.transformBD09ToWGS84(120.644049,31.285887);
console.log(lngLat_wgs84);

//WGS84 坐标 转 百度地图 BD09
var lngLat_bd09 = CoordinateTransform.transformWGS84ToBD09(lngLat_wgs84[0],lngLat_wgs84[1]);
console.log(lngLat_bd09);

//火星坐标(GCJ02) 坐标 转 WGS84
lngLat_wgs84 = CoordinateTransform.transformGCJ02ToWGS84(120.644049,31.285887);
console.log(lngLat_wgs84);

//WGS84 转 火星坐标(GCJ02)
var lngLat_gcj02 = CoordinateTransform.transformWGS84ToGCJ02(lngLat_wgs84[0],lngLat_wgs84[1]);
console.log(lngLat_gcj02);

//百度地图 BD09 坐标 转 火星坐标(GCJ02)
lngLat_gcj02 = CoordinateTransform.transformBD09ToGCJ02(120.644049,31.285887);
console.log(lngLat_gcj02);

//火星坐标(GCJ02) 坐标 转 百度地图 BD09
lngLat_bd09 = CoordinateTransform.transformGCJ02ToBD09(lngLat_gcj02[0],lngLat_gcj02[1]);
console.log(lngLat_bd09);
</script>
</html>

Java

CoordinateTransform.java

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
package com.gaeainfo.crawler.util;

/**
* 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
*
* @author Daniel
* @since 2016/7/27 0027
*/
public class CoordinateTransform {
private static final double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
private static final double PI = 3.1415926535897932384626;
private static final double a = 6378245.0;
private static final double ee = 0.00669342162296594323;


/**
* 百度坐标(BD09)转 GCJ02
*
* @param lng 百度经度
* @param lat 百度纬度
* @return GCJ02 坐标:[经度,纬度]
*/
public static double[] transformBD09ToGCJ02(double lng, double lat) {
double x = lng - 0.0065;
double y = lat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
double gcj_lng = z * Math.cos(theta);
double gcj_lat = z * Math.sin(theta);
return new double[]{gcj_lng, gcj_lat};
}

/**
* GCJ02 转百度坐标
*
* @param lng GCJ02 经度
* @param lat GCJ02 纬度
* @return 百度坐标:[经度,纬度]
*/
public static double[] transformGCJ02ToBD09(double lng, double lat) {
double z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
double theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
double bd_lng = z * Math.cos(theta) + 0.0065;
double bd_lat = z * Math.sin(theta) + 0.006;
return new double[]{bd_lng, bd_lat};
}

/**
* GCJ02 转 WGS84
*
* @param lng 经度
* @param lat 纬度
* @return WGS84坐标:[经度,纬度]
*/
public static double[] transformGCJ02ToWGS84(double lng, double lat) {
if (outOfChina(lng, lat)) {
return new double[]{lng, lat};
} else {
double dLat = transformLat(lng - 105.0, lat - 35.0);
double dLng = transformLng(lng - 105.0, lat - 35.0);
double radLat = lat / 180.0 * PI;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
double mgLat = lat + dLat;
double mgLng = lng + dLng;
return new double[]{lng * 2 - mgLng, lat * 2 - mgLat};
}
}

/**
* WGS84 坐标 转 GCJ02
*
* @param lng 经度
* @param lat 纬度
* @return GCJ02 坐标:[经度,纬度]
*/
public static double[] transformWGS84ToGCJ02(double lng, double lat) {
if (outOfChina(lng, lat)) {
return new double[]{lng, lat};
} else {
double dLat = transformLat(lng - 105.0, lat - 35.0);
double dLng = transformLng(lng - 105.0, lat - 35.0);
double redLat = lat / 180.0 * PI;
double magic = Math.sin(redLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(redLat) * PI);
double mgLat = lat + dLat;
double mgLng = lng + dLng;
return new double[]{mgLng, mgLat};
}
}

/**
* 百度坐标BD09 转 WGS84
*
* @param lng 经度
* @param lat 纬度
* @return WGS84 坐标:[经度,纬度]
*/
public static double[] transformBD09ToWGS84(double lng, double lat) {
double[] lngLat = transformBD09ToGCJ02(lng, lat);

return transformGCJ02ToWGS84(lngLat[0], lngLat[1]);
}

/**
* WGS84 转 百度坐标BD09
*
* @param lng 经度
* @param lat 纬度
* @return BD09 坐标:[经度,纬度]
*/
public static double[] transformWGS84ToBD09(double lng, double lat) {
double[] lngLat = transformWGS84ToGCJ02(lng, lat);

return transformGCJ02ToBD09(lngLat[0], lngLat[1]);
}

private static double transformLat(double lng, double lat) {
double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret;
}

;

private static double transformLng(double lng, double lat) {
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret;
}

;

/**
* 判断坐标是否不在国内
*
* @param lng 经度
* @param lat 纬度
* @return 坐标是否在国内
*/
public static boolean outOfChina(double lng, double lat) {
return (lng < 72.004 || lng > 137.8347) || (lat < 0.8293 || lat > 55.8271);
}
}

示例

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
public static void main(String[] args) {
//百度地图 BD09 坐标 转 WGS84
double[] lngLat_wgs84 = CoordinateTransform.transformBD09ToWGS84(120.644049, 31.285887);
System.out.println("lng :" + lngLat_wgs84[0] + ",lat :" + lngLat_wgs84[1]);

//WGS84 坐标 转 百度地图 BD09
double[] lngLat_bd09 = CoordinateTransform.transformWGS84ToBD09(lngLat_wgs84[0], lngLat_wgs84[1]);
System.out.println("lng :" + lngLat_bd09[0] + ",lat :" + lngLat_bd09[1]);

//火星坐标(GCJ02) 坐标 转 WGS84
lngLat_wgs84 = CoordinateTransform.transformGCJ02ToWGS84(120.644049, 31.285887);
System.out.println("lng :" + lngLat_wgs84[0] + ",lat :" + lngLat_wgs84[1]);

//WGS84 转 火星坐标(GCJ02)
double[] lngLat_gcj02 = CoordinateTransform.transformWGS84ToGCJ02(lngLat_wgs84[0], lngLat_wgs84[1]);
System.out.println("lng :" + lngLat_gcj02[0] + ",lat :" + lngLat_gcj02[1]);

//百度地图 BD09 坐标 转 火星坐标(GCJ02)
lngLat_gcj02 = CoordinateTransform.transformBD09ToGCJ02(120.644049, 31.285887);
System.out.println("lng :" + lngLat_gcj02[0] + ",lat :" + lngLat_gcj02[1]);

//火星坐标(GCJ02) 坐标 转 百度地图 BD09
lngLat_bd09 = CoordinateTransform.transformGCJ02ToBD09(lngLat_gcj02[0], lngLat_gcj02[1]);
System.out.println("lng :" + lngLat_bd09[0] + ",lat :" + lngLat_bd09[1]);
}