标签:
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
|
var GPS = { PI : 3.14159265358979324, x_pi : 3.14159265358979324 * 3000.0 / 180.0, delta : function (lat, lon) { // Krasovsky 1940 // // a = 6378245.0, 1/f = 298.3 // b = a * (1 - f) // ee = (a^2 - b^2) / a^2; var a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 var ee = 0.00669342162296594323; // ee: 椭球的偏心率。 var dLat = this .transformLat(lon - 105.0, lat - 35.0); var dLon = this .transformLon(lon - 105.0, lat - 35.0); var radLat = lat / 180.0 * this .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) * this .PI); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this .PI); return { ‘lat‘ : dLat, ‘lon‘ : dLon}; }, //WGS-84 to GCJ-02 gcj_encrypt : function (wgsLat, wgsLon) { if ( this .outOfChina(wgsLat, wgsLon)) return { ‘lat‘ : wgsLat, ‘lon‘ : wgsLon}; var d = this .delta(wgsLat, wgsLon); return { ‘lat‘ : wgsLat + d.lat, ‘lon‘ : wgsLon + d.lon}; }, //GCJ-02 to WGS-84 gcj_decrypt : function (gcjLat, gcjLon) { if ( this .outOfChina(gcjLat, gcjLon)) return { ‘lat‘ : gcjLat, ‘lon‘ : gcjLon}; var d = this .delta(gcjLat, gcjLon); return { ‘lat‘ : gcjLat - d.lat, ‘lon‘ : gcjLon - d.lon}; }, //GCJ-02 to WGS-84 exactly gcj_decrypt_exact : function (gcjLat, gcjLon) { var initDelta = 0.01; var threshold = 0.000000001; var dLat = initDelta, dLon = initDelta; var mLat = gcjLat - dLat, mLon = gcjLon - dLon; var pLat = gcjLat + dLat, pLon = gcjLon + dLon; var wgsLat, wgsLon, i = 0; while (1) { wgsLat = (mLat + pLat) / 2; wgsLon = (mLon + pLon) / 2; var tmp = this .gcj_encrypt(wgsLat, wgsLon) dLat = tmp.lat - gcjLat; dLon = tmp.lon - gcjLon; if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold)) break ; if (dLat > 0) pLat = wgsLat; else mLat = wgsLat; if (dLon > 0) pLon = wgsLon; else mLon = wgsLon; if (++i > 10000) break ; } //console.log(i); return { ‘lat‘ : wgsLat, ‘lon‘ : wgsLon}; }, //GCJ-02 to BD-09 bd_encrypt : function (gcjLat, gcjLon) { var x = gcjLon, y = gcjLat; var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this .x_pi); var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this .x_pi); bdLon = z * Math.cos(theta) + 0.0065; bdLat = z * Math.sin(theta) + 0.006; return { ‘lat‘ : bdLat, ‘lon‘ : bdLon}; }, //BD-09 to GCJ-02 bd_decrypt : function (bdLat, bdLon) { var x = bdLon - 0.0065, y = bdLat - 0.006; var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this .x_pi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this .x_pi); var gcjLon = z * Math.cos(theta); var gcjLat = z * Math.sin(theta); return { ‘lat‘ : gcjLat, ‘lon‘ : gcjLon}; }, //WGS-84 to Web mercator //mercatorLat -> y mercatorLon -> x mercator_encrypt : function (wgsLat, wgsLon) { var x = wgsLon * 20037508.34 / 180.; var y = Math.log(Math.tan((90. + wgsLat) * this .PI / 360.)) / ( this .PI / 180.); y = y * 20037508.34 / 180.; return { ‘lat‘ : y, ‘lon‘ : x}; /* if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90)) return null; var x = 6378137.0 * wgsLon * 0.017453292519943295; var a = wgsLat * 0.017453292519943295; var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a))); return {‘lat‘ : y, ‘lon‘ : x}; //*/ }, // Web mercator to WGS-84 // mercatorLat -> y mercatorLon -> x mercator_decrypt : function (mercatorLat, mercatorLon) { var x = mercatorLon / 20037508.34 * 180.; var y = mercatorLat / 20037508.34 * 180.; y = 180 / this .PI * (2 * Math.atan(Math.exp(y * this .PI / 180.)) - this .PI / 2); return { ‘lat‘ : y, ‘lon‘ : x}; /* if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90) return null; if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892)) return null; var a = mercatorLon / 6378137.0 * 57.295779513082323; var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0); var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323; return {‘lat‘ : y, ‘lon‘ : x}; //*/ }, // two point‘s distance distance : function (latA, lonA, latB, lonB) { var earthR = 6371000.; var x = Math.cos(latA * this .PI / 180.) * Math.cos(latB * this .PI / 180.) * Math.cos((lonA - lonB) * this .PI / 180); var y = Math.sin(latA * this .PI / 180.) * Math.sin(latB * this .PI / 180.); var s = x + y; if (s > 1) s = 1; if (s < -1) s = -1; var alpha = Math.acos(s); var distance = alpha * earthR; return distance; }, outOfChina : function (lat, lon) { if (lon < 72.004 || lon > 137.8347) return true ; if (lat < 0.8293 || lat > 55.8271) return true ; return false ; }, transformLat : function (x, y) { var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * this .PI) + 20.0 * Math.sin(2.0 * x * this .PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(y * this .PI) + 40.0 * Math.sin(y / 3.0 * this .PI)) * 2.0 / 3.0; ret += (160.0 * Math.sin(y / 12.0 * this .PI) + 320 * Math.sin(y * this .PI / 30.0)) * 2.0 / 3.0; return ret; }, transformLon : function (x, y) { var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); ret += (20.0 * Math.sin(6.0 * x * this .PI) + 20.0 * Math.sin(2.0 * x * this .PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(x * this .PI) + 40.0 * Math.sin(x / 3.0 * this .PI)) * 2.0 / 3.0; ret += (150.0 * Math.sin(x / 12.0 * this .PI) + 300.0 * Math.sin(x / 30.0 * this .PI)) * 2.0 / 3.0; return ret; } }; |
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
157
158
159
160
161
162
163
164
|
<?php class GPS { private $PI = 3.14159265358979324; private $x_pi = 0; public function __construct() { $this ->x_pi = 3.14159265358979324 * 3000.0 / 180.0; } //WGS-84 to GCJ-02 public function gcj_encrypt( $wgsLat , $wgsLon ) { if ( $this ->outOfChina( $wgsLat , $wgsLon )) return array ( ‘lat‘ => $wgsLat , ‘lon‘ => $wgsLon ); $d = $this ->delta( $wgsLat , $wgsLon ); return array ( ‘lat‘ => $wgsLat + $d [ ‘lat‘ ], ‘lon‘ => $wgsLon + $d [ ‘lon‘ ]); } //GCJ-02 to WGS-84 public function gcj_decrypt( $gcjLat , $gcjLon ) { if ( $this ->outOfChina( $gcjLat , $gcjLon )) return array ( ‘lat‘ => $gcjLat , ‘lon‘ => $gcjLon ); $d = $this ->delta( $gcjLat , $gcjLon ); return array ( ‘lat‘ => $gcjLat - $d [ ‘lat‘ ], ‘lon‘ => $gcjLon - $d [ ‘lon‘ ]); } //GCJ-02 to WGS-84 exactly public function gcj_decrypt_exact( $gcjLat , $gcjLon ) { $initDelta = 0.01; $threshold = 0.000000001; $dLat = $initDelta ; $dLon = $initDelta ; $mLat = $gcjLat - $dLat ; $mLon = $gcjLon - $dLon ; $pLat = $gcjLat + $dLat ; $pLon = $gcjLon + $dLon ; $wgsLat = 0; $wgsLon = 0; $i = 0; while (TRUE) { $wgsLat = ( $mLat + $pLat ) / 2; $wgsLon = ( $mLon + $pLon ) / 2; $tmp = $this ->gcj_encrypt( $wgsLat , $wgsLon ); $dLat = $tmp [ ‘lat‘ ] - $gcjLat ; $dLon = $tmp [ ‘lon‘ ] - $gcjLon ; if (( abs ( $dLat ) < $threshold ) && ( abs ( $dLon ) < $threshold )) break ; if ( $dLat > 0) $pLat = $wgsLat ; else $mLat = $wgsLat ; if ( $dLon > 0) $pLon = $wgsLon ; else $mLon = $wgsLon ; if (++ $i > 10000) break ; } //console.log(i); return array ( ‘lat‘ => $wgsLat , ‘lon‘ => $wgsLon ); } //GCJ-02 to BD-09 public function bd_encrypt( $gcjLat , $gcjLon ) { $x = $gcjLon ; $y = $gcjLat ; $z = sqrt( $x * $x + $y * $y ) + 0.00002 * sin( $y * $this ->x_pi); $theta = atan2 ( $y , $x ) + 0.000003 * cos ( $x * $this ->x_pi); $bdLon = $z * cos ( $theta ) + 0.0065; $bdLat = $z * sin( $theta ) + 0.006; return array ( ‘lat‘ => $bdLat , ‘lon‘ => $bdLon ); } //BD-09 to GCJ-02 public function bd_decrypt( $bdLat , $bdLon ) { $x = $bdLon - 0.0065; $y = $bdLat - 0.006; $z = sqrt( $x * $x + $y * $y ) - 0.00002 * sin( $y * $this ->x_pi); $theta = atan2 ( $y , $x ) - 0.000003 * cos ( $x * $this ->x_pi); $ $gcjLon = $z * cos ( $theta ); $gcjLat = $z * sin( $theta ); return array ( ‘lat‘ => $gcjLat , ‘lon‘ => $gcjLon ); } //WGS-84 to Web mercator //$mercatorLat -> y $mercatorLon -> x public function mercator_encrypt( $wgsLat , $wgsLon ) { $x = $wgsLon * 20037508.34 / 180.; $y = log(tan((90. + $wgsLat ) * $this ->PI / 360.)) / ( $this ->PI / 180.); $y = $y * 20037508.34 / 180.; return array ( ‘lat‘ => $y , ‘lon‘ => $x ); /* if ((abs($wgsLon) > 180 || abs($wgsLat) > 90)) return NULL; $x = 6378137.0 * $wgsLon * 0.017453292519943295; $a = $wgsLat * 0.017453292519943295; $y = 3189068.5 * log((1.0 + sin($a)) / (1.0 - sin($a))); return array(‘lat‘ => $y, ‘lon‘ => $x); //*/ } // Web mercator to WGS-84 // $mercatorLat -> y $mercatorLon -> x public function mercator_decrypt( $mercatorLat , $mercatorLon ) { $x = $mercatorLon / 20037508.34 * 180.; $y = $mercatorLat / 20037508.34 * 180.; $y = 180 / $this ->PI * (2 * atan ( exp ( $y * $this ->PI / 180.)) - $this ->PI / 2); return array ( ‘lat‘ => $y , ‘lon‘ => $x ); /* if (abs($mercatorLon) < 180 && abs($mercatorLat) < 90) return NULL; if ((abs($mercatorLon) > 20037508.3427892) || (abs($mercatorLat) > 20037508.3427892)) return NULL; $a = $mercatorLon / 6378137.0 * 57.295779513082323; $x = $a - (floor((($a + 180.0) / 360.0)) * 360.0); $y = (1.5707963267948966 - (2.0 * atan(exp((-1.0 * $mercatorLat) / 6378137.0)))) * 57.295779513082323; return array(‘lat‘ => $y, ‘lon‘ => $x); //*/ } // two point‘s distance public function distance( $latA , $lonA , $latB , $lonB ) { $earthR = 6371000.; $x = cos ( $latA * $this ->PI / 180.) * cos ( $latB * $this ->PI / 180.) * cos (( $lonA - $lonB ) * $this ->PI / 180); $y = sin( $latA * $this ->PI / 180.) * sin( $latB * $this ->PI / 180.); $s = $x + $y ; if ( $s > 1) $s = 1; if ( $s < -1) $s = -1; $alpha = acos ( $s ); $distance = $alpha * $earthR ; return $distance ; } private function delta( $lat , $lon ) { // Krasovsky 1940 // // a = 6378245.0, 1/f = 298.3 // b = a * (1 - f) // ee = (a^2 - b^2) / a^2; $a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。 $ee = 0.00669342162296594323; // ee: 椭球的偏心率。 $dLat = $this ->transformLat( $lon - 105.0, $lat - 35.0); $dLon = $this ->transformLon( $lon - 105.0, $lat - 35.0); $radLat = $lat / 180.0 * $this ->PI; $magic = sin( $radLat ); $magic = 1 - $ee * $magic * $magic ; $sqrtMagic = sqrt( $magic ); $dLat = ( $dLat * 180.0) / (( $a * (1 - $ee )) / ( $magic * $sqrtMagic ) * $this ->PI); $dLon = ( $dLon * 180.0) / ( $a / $sqrtMagic * cos ( $radLat ) * $this ->PI); return array ( ‘lat‘ => $dLat , ‘lon‘ => $dLon ); } private function outOfChina( $lat , $lon ) { if ( $lon < 72.004 || $lon > 137.8347) return TRUE; if ( $lat < 0.8293 || $lat > 55.8271) return TRUE; return FALSE; } private function transformLat( $x , $y ) { $ret = -100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt( abs ( $x )); $ret += (20.0 * sin(6.0 * $x * $this ->PI) + 20.0 * sin(2.0 * $x * $this ->PI)) * 2.0 / 3.0; $ret += (20.0 * sin( $y * $this ->PI) + 40.0 * sin( $y / 3.0 * $this ->PI)) * 2.0 / 3.0; $ret += (160.0 * sin( $y / 12.0 * $this ->PI) + 320 * sin( $y * $this ->PI / 30.0)) * 2.0 / 3.0; return $ret ; } private function transformLon( $x , $y ) { $ret = 300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt( abs ( $x )); $ret += (20.0 * sin(6.0 * $x * $this ->PI) + 20.0 * sin(2.0 * $x * $this ->PI)) * 2.0 / 3.0; $ret += (20.0 * sin( $x * $this ->PI) + 40.0 * sin( $x / 3.0 * $this ->PI)) * 2.0 / 3.0; $ret += (150.0 * sin( $x / 12.0 * $this ->PI) + 300.0 * sin( $x / 30.0 * $this ->PI)) * 2.0 / 3.0; return $ret ; } } |
转载地址:http://www.oschina.net/code/snippet_260395_39205
GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)[转]
标签:
原文地址:http://www.cnblogs.com/vvonline/p/4435141.html