CoordinateTool.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace baidu;
  3. define('X_PI',3.14159265358979324 * 3000.0 / 180.0);
  4. class CoordinateTool
  5. {
  6. private static $pi = 3.1415926535897932384626; // 圆周率
  7. private static $a = 6378245.0; // WGS 长轴半径
  8. private static $ee = 0.00669342162296594323; // WGS 偏心率的平方
  9. /**
  10. * 将火星坐标系GCJ-02 坐标 转换成百度坐标系 BD-09 坐标
  11. * @param $gc_loc 火星坐标点(Class Coordinate)
  12. * @return $bg_loc Coordinate对象,百度地图经纬度坐标
  13. */
  14. public static function gcj_bd($gc_loc)
  15. {
  16. $x_pi = X_PI;
  17. $x = $gc_loc['lng'];
  18. $y = $gc_loc['lat'];
  19. $z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * $x_pi);
  20. $theta = atan2($y, $x) + 0.000003 * cos($x * $x_pi);
  21. $bd_x = $z * cos($theta) + 0.0065;
  22. $bd_y = $z * sin($theta) + 0.006;
  23. $bg_loc = ['lng'=>$bd_x,'lat'=>$bd_y];
  24. return $bg_loc;
  25. }
  26. /**
  27. * 将百度坐标系 BD-09 坐标 转换成 火星坐标系GCJ-02 坐标
  28. * @param $bd_loc 火星坐标点(Class Coordinate)
  29. * @return $bg_loc Coordinate对象,火星坐标系经纬度坐标
  30. */
  31. public static function bd_gcj($bd_loc)
  32. {
  33. $x_pi = X_PI;
  34. $x = $bd_loc['lng'] - 0.0065;
  35. $y = $bd_loc['lat'] - 0.006;
  36. $z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $x_pi);
  37. $theta = atan2($y, $x) - 0.000003 * cos($x * $x_pi);
  38. $gc_x = $z * cos($theta);
  39. $gc_y = $z * sin($theta);
  40. $gc_loc = ['lng'=>$gc_x,'lat'=>$gc_y];
  41. return $gc_loc;
  42. }
  43. /**
  44. * 将国际通用坐标系WGS84坐标 转换成 火星坐标系GCJ-02 坐标
  45. * @param $wgs_loc WGS84坐标点(Class Coordinate)
  46. * @return $bg_loc Coordinate对象,火星坐标系经纬度坐标
  47. */
  48. public static function wgs_gcj($wgs_loc)
  49. {
  50. $wgs_lon = $wgs_loc['lng'];
  51. $wgs_lat = $wgs_loc['lat'];
  52. if (self::outOfChina($wgs_lon,$wgs_lat)){
  53. return $wgs_loc;
  54. }
  55. $x_pi = X_PI;
  56. $dLat = self::transformLat($wgs_lon - 105.0, $wgs_lat - 35.0);
  57. $dLon = self::transformLon($wgs_lon - 105.0, $wgs_lat - 35.0);
  58. $radLat = $wgs_lat / 180.0 * self::$pi;
  59. $magic = sin($radLat);
  60. $magic = 1 - self::$ee * $magic * $magic;
  61. $sqrtMagic = sqrt($magic);
  62. $dLat = ($dLat * 180.0) / ((self::$a * (1 - self::$ee)) / ($magic * $sqrtMagic) * self::$pi);
  63. $dLon = ($dLon * 180.0) / (self::$a / $sqrtMagic * cos($radLat) * self::$pi);
  64. $mgLat = $wgs_lat + $dLat;
  65. $mgLon = $wgs_lon + $dLon;
  66. $gcj_loc = ['lng'=>$mgLon,'lat'=>$mgLat];
  67. return $gcj_loc;
  68. }
  69. /**
  70. * 将火星坐标系GCJ-02坐标 转换成 国际通用坐标系WGS84坐标
  71. * @param $gcj_loc GCJ-02坐标点(Class Coordinate)
  72. * @return $wgs_loc Coordinate对象,国际通用坐标系WGS84坐标
  73. */
  74. public static function gcj_wgs($gcj_loc)
  75. {
  76. $wgs_lon = $gcj_loc['lng'];
  77. $wgs_lat = $gcj_loc['lat'];
  78. if (self::outOfChina($wgs_lon,$wgs_lat)){
  79. return $gcj_loc;
  80. }
  81. $x_pi = X_PI;
  82. $dLat = self::transformLat($wgs_lon - 105.0, $wgs_lat - 35.0);
  83. $dLon = self::transformLon($wgs_lon - 105.0, $wgs_lat - 35.0);
  84. $radLat = $wgs_lat / 180.0 * self::$pi;
  85. $magic = sin($radLat);
  86. $magic = 1 - self::$ee * $magic * $magic;
  87. $sqrtMagic = sqrt($magic);
  88. $dLat = ($dLat * 180.0) / ((self::$a * (1 - self::$ee)) / ($magic * $sqrtMagic) * self::$pi);
  89. $dLon = ($dLon * 180.0) / (self::$a / $sqrtMagic * cos($radLat) * self::$pi);
  90. $mgLat = $wgs_lat + $dLat;
  91. $mgLon = $wgs_lon + $dLon;
  92. $wgsLon = $wgs_lon*2 - $mgLon;
  93. $wgsLat = $wgs_lat*2 - $mgLat;
  94. $wgs_loc = ['lng'=>$wgsLon,'lat'=>$wgsLat];
  95. return $wgs_loc;
  96. }
  97. /**
  98. * @title: wgs坐标转百度坐标
  99. * @desc:
  100. * @param {*} $wgs_loc
  101. * @return {*}
  102. * @Author: Rock
  103. * @Date: 2022-03-26 18:50:29
  104. * @LastEditTime: Do not edit
  105. */
  106. public static function wgs_bd($wgs_loc){
  107. $gcj_loc = self::wgs_gcj($wgs_loc);
  108. $bd_loc = self::gcj_bd($gcj_loc);
  109. return $bd_loc;
  110. }
  111. private static function outOfChina($lon,$lat)
  112. {
  113. if ($lon < 72.004 || $lon > 137.8347)
  114. return true;
  115. if ($lat < 0.8293 || $lat > 55.8271)
  116. return true;
  117. return false;
  118. }
  119. private static function transformLat($x,$y)
  120. {
  121. $ret = -100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt(abs($x));
  122. $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
  123. $ret += (20.0 * sin($y * self::$pi) + 40.0 * sin($y / 3.0 * self::$pi)) * 2.0 / 3.0;
  124. $ret += (160.0 * sin($y / 12.0 * self::$pi) + 320 * sin($y * self::$pi / 30.0)) * 2.0 / 3.0;
  125. return $ret;
  126. }
  127. private static function transformLon($x, $y)
  128. {
  129. $ret = 300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt(abs($x));
  130. $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
  131. $ret += (20.0 * sin($x * self::$pi) + 40.0 * sin($x / 3.0 * self::$pi)) * 2.0 / 3.0;
  132. $ret += (150.0 * sin($x / 12.0 * self::$pi) + 300.0 * sin($x / 30.0 * self::$pi)) * 2.0 / 3.0;
  133. return $ret;
  134. }
  135. }