geo_helper.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2018/3/7
  6. * Time: 下午2:46
  7. * amap 是调用高德地图接口,baidu 是调用百度接口
  8. */
  9. require_once(BASE_ROOT_PATH . '/core/framework/function/http.php');
  10. class amap
  11. {
  12. private function call_map($city,$address)
  13. {
  14. $key = 'a284df4b8cef6aa5144f43ad5753b7d4'; //高德地图访问key,账号:13911129867,密码:jyc2018168.
  15. $url = "http://restapi.amap.com/v3/geocode/geo";
  16. $params = ['key' => $key,'address' => $address,'city' => $city];
  17. $resp = http_request($url,$params);
  18. $data = json_decode($resp,true);
  19. if($data['status'] != 1) {
  20. return false;
  21. }
  22. else {
  23. return $data;
  24. }
  25. }
  26. public function geocodes($city,$address)
  27. {
  28. $resp = $this->call_map($city,$address);
  29. if($resp === false) return false;
  30. $geocodes = $resp['geocodes'];
  31. if(count($geocodes) <= 0 || count($geocodes) > 1) {
  32. return false;
  33. }
  34. else
  35. {
  36. $location = $geocodes[0]['location'];
  37. $lng_lat = mb_split(',',$location);
  38. return $lng_lat;
  39. }
  40. }
  41. }
  42. class baidu
  43. {
  44. public function call_map($city,$address)
  45. {
  46. //http://api.map.baidu.com/geocoder/v2/?address=&output=json&ak=&callback=showLocation
  47. $key = '5MINsIU8ukWmTn48t9fcGpEUafoQF8Kg'; // 百度访问key
  48. $url = "http://api.map.baidu.com/geocoder/v2/";
  49. $params = ['ak' => $key,'address' => "{$city}{$address}",'output' => 'json'];
  50. $resp = http_request($url,$params);
  51. $data = json_decode($resp,true);
  52. if($data['status'] != 0) {
  53. return false;
  54. }
  55. else {
  56. return $data;
  57. }
  58. }
  59. public function geocodes($city,$address)
  60. {
  61. $resp = $this->call_map($city,$address);
  62. if($resp === false) return false;
  63. $loc = $resp['result']['location'];
  64. return [ $loc['lng'],$loc['lat'] ];
  65. }
  66. }
  67. class geo_helper
  68. {
  69. static private $stInstance = null;
  70. private function __construct() {
  71. }
  72. static public function instance()
  73. {
  74. if (self::$stInstance == null) {
  75. self::$stInstance = new geo_helper();
  76. }
  77. return self::$stInstance;
  78. }
  79. public function geocodes($city,$address)
  80. {
  81. $amap = new baidu();
  82. return $amap->geocodes($city,$address);
  83. }
  84. public function getdistance($lng1,$lat1,$lng2,$lat2)
  85. {
  86. $fEARTH_RADIUS = 6378137;
  87. $radLat1 = deg2rad($lat1);
  88. $radLat2 = deg2rad($lat2);
  89. $radLng1 = deg2rad($lng1);
  90. $radLng2 = deg2rad($lng2);
  91. $a = abs($radLat1-$radLat2);
  92. $b = abs($radLng1-$radLng2);
  93. $fP = pow(sin($a/2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2), 2);
  94. return intval($fEARTH_RADIUS * 2 * asin(sqrt($fP)) + 0.5);
  95. }
  96. public function update_store($store_id)
  97. {
  98. $model_store = Model('store');
  99. $store_info = $model_store->getStoreInfo(['store_id' => $store_id]);
  100. if(empty($store_info)) return false;
  101. $area_info = $store_info['area_info'];
  102. if(empty($area_info)) return false;
  103. $regxp = '/(\S+)[\s]*(\S+)*/u';
  104. $val = preg_match_all($regxp,$area_info,$match);
  105. if($val <= 0 || $val == false) return false;
  106. if(count($match) != 3) return false;
  107. if(empty($match[2][0])) {
  108. $city = $match[1][0];
  109. }
  110. else {
  111. $city = $match[2][0];
  112. }
  113. $cityids = $this->cityids($city);
  114. if(empty($cityids)) return false;
  115. $city_id = $cityids['city_id'];
  116. $prov_id = $cityids['prov_id'];
  117. if(empty($store_info['store_address'])) return false;
  118. $lng_lat = $this->geocodes($city,$store_info['store_address']);
  119. if($lng_lat != false) {
  120. $store_latlng = implode(',',$lng_lat);
  121. return $model_store->editStore(['province_id' => $prov_id,"city_id" => $city_id,"store_latlng" => $store_latlng],['store_id' => $store_id]);
  122. }
  123. else {
  124. return false;
  125. }
  126. }
  127. static public function asc_dis($left,$right)
  128. {
  129. $t_l = intval($left['distance']);
  130. $t_r = intval($right['distance']);
  131. if($t_l > $t_r) return 1;
  132. elseif($t_l < $t_r) return -1;
  133. else return 0;
  134. }
  135. public function asc_stores($car_stores,$usrloc,$city)
  136. {
  137. if(empty($car_stores)) return [];
  138. $cityids = $this->cityids($city);
  139. if($cityids !== false) {
  140. $cityid = $cityids['city_id'];
  141. }
  142. else {
  143. $cityid = 0;
  144. }
  145. $car_stores = $this->store_infos($car_stores,$cityid);
  146. $local_stores = $car_stores['local_city'];
  147. $other_stores = $car_stores['other_city'];
  148. if(!empty($local_stores))
  149. {
  150. foreach ($local_stores as &$item) {
  151. $s_loc = explode(',',$item['store_latlng']);
  152. $dis = $this->getdistance($usrloc[0],$usrloc[1],$s_loc[0],$s_loc[1]);
  153. $item['distance'] = $dis;
  154. }
  155. uasort($local_stores,['geo_helper','asc_dis']);
  156. $match_stores = $local_stores;
  157. }
  158. else
  159. {
  160. foreach ($other_stores as &$item) {
  161. $s_loc = explode(',',$item['store_latlng']);
  162. $dis = $this->getdistance($usrloc[0],$usrloc[1],$s_loc[0],$s_loc[1]);
  163. $item['distance'] = $dis;
  164. }
  165. uasort($other_stores,['geo_helper','asc_dis']);
  166. $match_stores = $other_stores;
  167. }
  168. return $match_stores;
  169. }
  170. private function store_infos($stores,$cityid)
  171. {
  172. $store_ids = [];
  173. foreach ($stores as $store) {
  174. $store_ids[] = intval($store);
  175. }
  176. $mod_store = Model('store');
  177. $stores = $mod_store-> getStoreList(['store_id' => ['in',$store_ids]]);
  178. $result = [];
  179. $result['local_city'] = [];
  180. $result['other_city'] = [];
  181. if($cityid > 0)
  182. {
  183. foreach ($stores as $store)
  184. {
  185. if($cityid == intval($store['city_id'])) {
  186. $result['local_city'][] = $store;
  187. }
  188. else {
  189. $result['other_city'][] = $store;
  190. }
  191. }
  192. }
  193. else {
  194. $result['other_city'] = $stores;
  195. }
  196. return $result;
  197. }
  198. public function cityids($city)
  199. {
  200. if(empty($city)) return false;
  201. $mod_area = Model('area');
  202. $info = $mod_area->getAreaInfo(['area_name' => $city]);
  203. if(empty($info)) return false;
  204. $ret['city_id'] = $info['area_id'];
  205. $ret['prov_id'] = $info['area_parent_id'];
  206. return $ret;
  207. }
  208. }