You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.9 KiB

5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
  1. <?php
  2. namespace App\Service\v3\Implementations;
  3. use App\Constants\v3\ErrorCode;
  4. use App\Exception\ErrorCodeException;
  5. use App\Model\v3\UserCollection;
  6. use App\Service\v3\Interfaces\LocationServiceInterface;
  7. use App\Model\v3\Area;
  8. use App\Model\v3\Market;
  9. class LocationService implements LocationServiceInterface
  10. {
  11. public function do()
  12. {
  13. // TODO: Implement do() method.
  14. }
  15. public function check()
  16. {
  17. // TODO: Implement check() method.
  18. }
  19. public function undo()
  20. {
  21. // TODO: Implement undo() method.
  22. }
  23. public function getMarketListByLocation($lng,$lat)
  24. {
  25. $cityIds = Market::query()->pluck('city_id');
  26. $res = Area::query()->with('markets')->whereIn('id',$cityIds)->get();
  27. foreach ($res as &$v){
  28. foreach ($v->markets as &$m)
  29. {
  30. if(!empty($lng) && !empty($lat)){
  31. $m->Distance = ($this->getDistance($m->lng,$m->lat,$lng,$lat)).' km';
  32. }else{
  33. $m->Distance = '';
  34. }
  35. }
  36. }
  37. return $res;
  38. }
  39. public function searchMarket($keywords,$lng,$lat,$cityId = 2163)
  40. {
  41. $res = Market::query()->where([
  42. ['name','like','%'.$keywords.'%'],
  43. ['city_id','=',$cityId]
  44. ])
  45. ->get();
  46. foreach ($res as &$v){
  47. if(!empty($lng) && !empty($lat)){
  48. $v->Distance = ($this->getDistance($v->lng,$v->lat,$lng,$lat)).' km';
  49. }else{
  50. $v->Distance = '';
  51. }
  52. }
  53. return $res;
  54. }
  55. public function getNearestMarket($lng,$lat)
  56. {
  57. $markets = Market::query()->get()->toArray();
  58. $result = [];
  59. $distinctMin = 0;
  60. foreach ($markets as &$market){
  61. $distinct = $this->getDistance($lng,$lat,$market['lng'],$market['lat'],1);
  62. $market['distinct'] = round(($distinct/1000),2).' km';
  63. if($distinct < $distinctMin || $distinctMin === 0) {
  64. $distinctMin = $distinct;
  65. $result = $market;
  66. }
  67. }
  68. return $result;
  69. }
  70. /**
  71. * @param $lng1
  72. * @param $lat1
  73. * @param $lng2
  74. * @param $lat2
  75. * @param int $unit 单位 1: 2:公里
  76. * @param int $decimal 精度 保留小数位数
  77. * @return false|float
  78. */
  79. public function getDistance($lng1, $lat1, $lng2, $lat2, $unit = 2, $decimal = 2)
  80. {
  81. $EARTH_RADIUS = 6370.996; // 地球半径系数
  82. $PI = 3.1415926535898;
  83. $radLat1 = $lat1 * $PI / 180.0;
  84. $radLat2 = $lat2 * $PI / 180.0;
  85. $radLng1 = $lng1 * $PI / 180.0;
  86. $radLng2 = $lng2 * $PI / 180.0;
  87. $a = $radLat1 - $radLat2;
  88. $b = $radLng1 - $radLng2;
  89. $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
  90. $distance = $distance * $EARTH_RADIUS * 1000;
  91. if ($unit === 2) {
  92. $distance /= 1000;
  93. }
  94. return round($distance, $decimal);
  95. }
  96. //获取服务站信息
  97. function getMarketsInfo()
  98. {
  99. return Market::where('status',1)->get();
  100. }
  101. //获取骑行距离
  102. public function getDistanceByTencent($lng1, $lat1, $lng2, $lat2)
  103. {
  104. $url = 'https://apis.map.qq.com/ws/direction/v1/';
  105. /**
  106. * $tyep driving 驾车 walking 步行 bicycling 骑行 transit 公交
  107. */
  108. $type = 'bicycling';
  109. $key = 'GB3BZ-7W2CU-LW3VH-B7ZIF-XRKSF-D3FOL';
  110. $result = file_get_contents($url.$type.'/?from='.$lat1.','.$lng1.'&to='.$lat2.','.$lng2.'&output=json&key='.$key);
  111. $resultArr = json_decode($result,true);
  112. if($resultArr['status'] > 0)
  113. {
  114. return 1000;
  115. //throw new ErrorCodeException(ErrorCode::LOCATION_ERROR,$resultArr['message']);
  116. }
  117. $distance = $resultArr['result']['routes'][0]['distance'];
  118. return $distance;
  119. }
  120. }