GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)[转]

WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)
GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用
BD-09:百度坐标偏移标准,Baidu Map使用

//WGS-84 to GCJ-02
GPS.gcj_encrypt();

//GCJ-02 to WGS-84 粗略
GPS.gcj_decrypt();

//GCJ-02 to WGS-84 精确(二分极限法)
// var threshold = 0.000000001; 目前设置的是精确到小数点后9位,这个值越小,越精确,但是javascript中,浮点运算本身就不太精确,九位在GPS里也偏差不大了
GSP.gcj_decrypt_exact();

//GCJ-02 to BD-09
GPS.bd_encrypt();

//BD-09 to GCJ-02
GPS.bd_decrypt();

//求距离
GPS.distance();

示例:
document.write("GPS: 39.933676862706776,116.35608315379092<br />");
var arr2 = GPS.gcj_encrypt(39.933676862706776, 116.35608315379092);
document.write("中国:" + arr2[‘lat‘]+","+arr2[‘lon‘]+‘<br />‘);
var arr3 = GPS.gcj_decrypt_exact(arr2[‘lat‘], arr2[‘lon‘]);
document.write(‘逆算:‘ + arr3[‘lat‘]+","+arr3[‘lon‘]+‘ 需要和第一行相似(目前是小数点后9位相等)‘);

1. [代码][JavaScript]代码

?


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;

    }

};

2. [代码][PHP]代码

?


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 $wgsLatelse $mLat $wgsLat;

            if ($dLon > 0) $pLon $wgsLonelse $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

时间: 2024-08-05 13:58:39

GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)[转]的相关文章

GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)(转载)

WGS-84:是国际标准,GPS坐标(Google Earth使用.或者GPS模块)GCJ-02:中国坐标偏移标准,Google Map.高德.腾讯使用BD-09:百度坐标偏移标准,Baidu Map使用//WGS-84 to GCJ-02GPS.gcj_encrypt();//GCJ-02 to WGS-84 粗略GPS.gcj_decrypt();//GCJ-02 to WGS-84 精确(二分极限法)// var threshold = 0.000000001; 目前设置的是精确到小数点后

GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)

WGS-84:是国际标准,GPS坐标(Google Earth使用.或者GPS模块)GCJ-02:中国坐标偏移标准,Google Map.高德.腾讯使用BD-09:百度坐标偏移标准,Baidu Map使用 //WGS-84 to GCJ-02GPS.gcj_encrypt(); //GCJ-02 to WGS-84 粗略GPS.gcj_decrypt(); //GCJ-02 to WGS-84 精确(二分极限法)// var threshold = 0.000000001; 目前设置的是精确到小

Google地图百度地图GPS经纬度偏移转换(JAVA)

不多说,直接代码,Java版 主要就是Google地图,百度地图,GPS经纬度偏移转换 GCJ-02转换BD-09,Google地图经纬度转百度地图经纬度 BD-09转换GCJ-02,百度转google WGS-84 到 GCJ-02 的转换(即 GPS 加偏) /** * 用于构造地图中的坐标点 * @author lw * **/ public class Point { private double lat;// 纬度 private double lng;// 经度 public Poi

google 地图 百度地图坐标互转

/**  * 地图坐标转换 google,baidu,gps  * @author lw  * @Time 2015年4月16日18:19:16  *  * */ public class CoordinateConversion {     private static final double x_pi = 3.14159265358979324 * 3000.0 / 180.0;          private static final double pi = 3.14159265358

C#的百度地图开发(三)依据坐标获取位置、商圈及周边信息

我们得到了百度坐标,现在依据这一坐标来获取相应的信息.下面是相应的代码 [html] view plaincopy public class BaiduMap { /// <summary> /// 依据坐标获取定位信息的URL模板. /// 参数1:百度地图API的KEY. /// 参数2:坐标(经度,纬度). /// </summary> public const string GEOCODING_COORDINATE_URL_TEMPLATE = "http://a

GPS定位的偏移校正(WGS84与火星坐标互转)

原文:GPS定位的偏移校正(WGS84与火星坐标互转) 地图坐标系目前包括: 地球坐标 (WGS84) WGS84:World Geodetic System 1984,是为GPS全球定位系统使用而建立的坐标系统. 国际标准,从 GPS 设备中取出的数据的坐标系 国际地图提供商使用的坐标系 火星坐标 (GCJ-02)也叫国测局坐标系 GCJ-02是由中国国家测绘局(民间说的火星坐标系)制订的地理信息系统的坐标系统. 它是一种对经纬度数据的加密算法,即加入随机的偏差. 国内出版的各种地图系统(包括

BD09坐标(百度坐标) WGS84(GPS坐标) GCJ02(国测局坐标) 的相互转换

BD09坐标(百度坐标) WGS84(GPS坐标) GCJ02(国测局坐标) 的相互转换 http://www.cnphp6.com/archives/24822 by root ⋅ Leave a Comment 谷歌地图采用的是WGS84地理坐标系(中国范围除外),谷歌中国地图.搜搜中国地图.高德地图采用的是GCJ02地理坐标系,百度采用的是BD09坐标系,而设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系,所以我们要根据得到的经纬度的坐标类型和地图厂商类型在地图上标点,

delphi 调用百度地图WEBSERVICE转换GPS坐标

百度地图的API说明 使用方法 第一步,申请密钥(ak),作为访问服务的依据: 第二步,按照请求参数说明拼写发送http请求的url,注意需使用第一步申请的ak: 第三步,接收返回的数据(json或者xml格式). 注:本接口支持回调. 服务地址 http://api.map.baidu.com/geoconv/v1/? 组成说明: 域名:http://api.map.baidu.com 服务名:geoconv 服务版本号:v1 服务参数说明 参数 含义 取值范围 是否必须 默认取值 coord

ios根据gps坐标来计算两点间的距离

//ios根据gps坐标来计算两点间的距离 //x1,y1 点1的坐标 x2,y2点2的坐标 -(double) gps2m:(double)x1 _y1:(double)y1 _x2:(double)x2 _y2:(double)y2{ double radLat1 = (x1 * 3.1416 / 180.0); double radLat2 = (x2 * 3.1416 / 180.0); double a = radLat1 - radLat2; double b = (y1 - y2)