Location.Class.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace JinDouYun\Model\Common;
  3. /**
  4. * @copyright Copyright (c) https://www.qianniaovip.com All rights reserved
  5. * Description:
  6. * Class Location
  7. * @package JinDouYun\Model\Common
  8. */
  9. class Location
  10. {
  11. public function __construct()
  12. {
  13. $this->_geo_conf = array(
  14. 'pi' => pi(),
  15. 'EARTH_RADIUS' => 6378.137,
  16. );
  17. }
  18. /**
  19. * 求两个地理位置之间的距离
  20. *
  21. * @param string $latitude_a a坐标纬度
  22. * @param string $longitude_a a坐标经度
  23. * @param $latitude_b b坐标纬度
  24. * @param $longitude_b b坐标经度
  25. * @return bool|float|int
  26. */
  27. public function get_distance_by_geo($latitude_a, $longitude_a, $latitude_b, $longitude_b)
  28. {
  29. if (!$longitude_a || !$latitude_a || !$longitude_a || !$longitude_b) {
  30. return false;
  31. }
  32. $earthRadius = 6367000; //approximate radius of earth in meters
  33. $lat1 = ($latitude_a * pi() ) / 180;
  34. $lng1 = ($longitude_a * pi() ) / 180;
  35. $lat2 = ($latitude_b * pi() ) / 180;
  36. $lng2 = ($longitude_b * pi() ) / 180;
  37. $calcLongitude = $lng2 - $lng1;
  38. $calcLatitude = $lat2 - $lat1;
  39. $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
  40. $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
  41. $calculatedDistance = $earthRadius * $stepTwo;
  42. return round($calculatedDistance);
  43. /*$latitude_a_radian = $this->_angle_to_radian($latitude_a);
  44. $latitude_b_radian = $this->_angle_to_radian($latitude_b);
  45. $longitude_a_radian = $this->_angle_to_radian($longitude_a);
  46. $longitude_b_radian = $this->_angle_to_radian($longitude_b);
  47. $latitude_radian_diff = $latitude_a_radian - $latitude_b_radian;
  48. $longitude_radian_diff = $longitude_a_radian - $longitude_b_radian;
  49. $S = 2 * asin(sqrt(pow(sin($latitude_radian_diff / 2), 2) + cos($latitude_a_radian) * cos($latitude_b_radian) * pow(sin($longitude_radian_diff / 2), 2))) * $this->_geo_conf['EARTH_RADIUS'];
  50. return $S;*/
  51. }
  52. /**
  53. * Doc: (des="")
  54. * User: XMing
  55. * Date: 2020/12/10
  56. * Time: 2:30 下午
  57. * @param $value
  58. * @return string
  59. */
  60. public static function toMeters($value): string
  61. {
  62. if ($value > 1000) {
  63. return sprintf("%.2f", $value / 1000) . 'km';
  64. }
  65. return $value.'m';
  66. }
  67. /**
  68. * 根据某个经纬度和距离范围,求范围内到经纬度最大最小值
  69. * @param $latitude
  70. * @param $longitude
  71. * @param $distance
  72. * @return array|bool
  73. */
  74. public function get_geo_by_distance($latitude, $longitude, $distance)
  75. {
  76. if (!$latitude || !$longitude) {
  77. return false;
  78. }
  79. $lat_a = $this->_angle_to_radian($latitude);
  80. $lng_D = asin(sin($distance / (2 * $this->_geo_conf['EARTH_RADIUS'])) / cos($lat_a)) * 2;
  81. $lat_D = asin(sin($distance / (2 * $this->_geo_conf['EARTH_RADIUS']))) * 2;
  82. $lat_D = $this->_radian_to_angle($lat_D);
  83. $lon_D = $this->_radian_to_angle($lng_D);
  84. $lat_res = array('lat_min' => ($latitude - $lat_D), 'lat_max' => ($latitude + $lat_D));
  85. $lon_res = array('lon_min' => ($longitude - $lon_D), 'lon_max' => ($longitude + $lon_D));
  86. return array($lat_res, $lon_res);
  87. }
  88. /**
  89. * 角度转弧度
  90. * @param $angle
  91. * @return float
  92. */
  93. private function _angle_to_radian($angle)
  94. {
  95. return $angle * $this->_geo_conf['pi'] / 180.0;
  96. }
  97. /**
  98. * 弧度转角度
  99. * @param $radian
  100. * @return float|int
  101. */
  102. private function _radian_to_angle($radian)
  103. {
  104. return abs($radian * 180 / $this->_geo_conf['pi']);
  105. }
  106. }