geo_helper.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. public 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. static $key = '5MINsIU8ukWmTn48t9fcGpEUafoQF8Kg';
  45. static $url = 'http://api.map.baidu.com/geocoder/v2/';
  46. public function call_map($city,$address)
  47. {
  48. //http://api.map.baidu.com/geocoder/v2/?address=&output=json&ak=&callback=showLocation
  49. $params = ['ak' => self::$key,'address' => "{$city}{$address}",'output' => 'json', 'coordtype' => 'bd09ll' ];
  50. $resp = http_request(self::$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. public function getReverse($location)
  67. {
  68. $params = [
  69. 'ak' => self::$key,
  70. 'location' => $location,
  71. 'output' => 'json',
  72. 'coordtype' => 'bd09ll',
  73. 'pois' => 0
  74. ];
  75. $resp = http_request(self::$url, $params);
  76. $data = json_decode($resp,true);
  77. if($data['status'] != 0) {
  78. return false;
  79. }
  80. else {
  81. return $data;
  82. }
  83. }
  84. }
  85. class geo_helper
  86. {
  87. static private $stInstance = null;
  88. private function __construct() {
  89. }
  90. static public function instance()
  91. {
  92. if (self::$stInstance == null) {
  93. self::$stInstance = new geo_helper();
  94. }
  95. return self::$stInstance;
  96. }
  97. public function geocodes($city,$address)
  98. {
  99. $amap = new amap();
  100. return $amap->geocodes($city,$address);
  101. }
  102. public function getdistance($lng1,$lat1,$lng2,$lat2)
  103. {
  104. $fEARTH_RADIUS = 6378137;
  105. $radLat1 = deg2rad($lat1);
  106. $radLat2 = deg2rad($lat2);
  107. $radLng1 = deg2rad($lng1);
  108. $radLng2 = deg2rad($lng2);
  109. $a = abs($radLat1-$radLat2);
  110. $b = abs($radLng1-$radLng2);
  111. $fP = pow(sin($a/2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2), 2);
  112. return intval($fEARTH_RADIUS * 2 * asin(sqrt($fP)) + 0.5);
  113. }
  114. public function update_store($store_id)
  115. {
  116. $model_store = Model('store');
  117. $store_info = $model_store->getStoreInfo(['store_id' => $store_id]);
  118. if(empty($store_info)) return false;
  119. $area_info = $store_info['area_info'];
  120. if(empty($area_info)) return false;
  121. $regxp = '/(\S+)[\s]*(\S+)*/u';
  122. $val = preg_match_all($regxp,$area_info,$match);
  123. if($val <= 0 || $val == false) return false;
  124. if(count($match) != 3) return false;
  125. if(empty($match[2][0])) {
  126. $city = $match[1][0];
  127. }
  128. else {
  129. $city = $match[2][0];
  130. }
  131. $cityids = $this->cityids($city);
  132. if(empty($cityids)) return false;
  133. $city_id = $cityids['city_id'];
  134. $prov_id = $cityids['prov_id'];
  135. if(empty($store_info['store_address'])) return false;
  136. $lng_lat = $this->geocodes($city,$store_info['store_address']);
  137. if($lng_lat != false) {
  138. $store_latlng = implode(',',$lng_lat);
  139. return $model_store->editStore(['province_id' => $prov_id,"city_id" => $city_id,"store_latlng" => $store_latlng],['store_id' => $store_id]);
  140. }
  141. else {
  142. return false;
  143. }
  144. }
  145. static public function asc_dis($left,$right)
  146. {
  147. $t_l = intval($left['distance']);
  148. $t_r = intval($right['distance']);
  149. if($t_l > $t_r) return 1;
  150. elseif($t_l < $t_r) return -1;
  151. else return 0;
  152. }
  153. public function asc_stores($car_stores,$usrloc,$city)
  154. {
  155. if(empty($car_stores)) return [];
  156. $cityids = $this->cityids($city);
  157. if($cityids !== false) {
  158. $cityid = $cityids['city_id'];
  159. }
  160. else {
  161. $cityid = 0;
  162. }
  163. $car_stores = $this->store_infos($car_stores,$cityid);
  164. $local_stores = $car_stores['local_city'];
  165. $other_stores = $car_stores['other_city'];
  166. if(!empty($local_stores))
  167. {
  168. foreach ($local_stores as &$item) {
  169. $s_loc = explode(',',$item['store_latlng']);
  170. $dis = $this->getdistance($usrloc[0],$usrloc[1],$s_loc[0],$s_loc[1]);
  171. $item['distance'] = $dis;
  172. }
  173. uasort($local_stores,['geo_helper','asc_dis']);
  174. $match_stores = $local_stores;
  175. }
  176. else
  177. {
  178. foreach ($other_stores as &$item) {
  179. $s_loc = explode(',',$item['store_latlng']);
  180. $dis = $this->getdistance($usrloc[0],$usrloc[1],$s_loc[0],$s_loc[1]);
  181. $item['distance'] = $dis;
  182. }
  183. usort($other_stores,['geo_helper','asc_dis']);
  184. $match_stores = $other_stores;
  185. }
  186. return $match_stores;
  187. }
  188. private function store_infos($stores,$cityid)
  189. {
  190. $store_ids = [];
  191. foreach ($stores as $store) {
  192. $store_ids[] = intval($store);
  193. }
  194. $mod_store = Model('store');
  195. $stores = $mod_store-> getStoreList(['store_id' => ['in',$store_ids]]);
  196. $result = [];
  197. $result['local_city'] = [];
  198. $result['other_city'] = [];
  199. if($cityid > 0)
  200. {
  201. foreach ($stores as $store)
  202. {
  203. if($cityid == intval($store['city_id'])) {
  204. $result['local_city'][] = $store;
  205. }
  206. else {
  207. $result['other_city'][] = $store;
  208. }
  209. }
  210. }
  211. else {
  212. $result['other_city'] = $stores;
  213. }
  214. return $result;
  215. }
  216. public function cityids($city)
  217. {
  218. if(empty($city)) return false;
  219. $mod_area = Model('area');
  220. $info = $mod_area->getAreaInfo(['area_name' => $city]);
  221. if(empty($info)) return false;
  222. $parent_id = intval($info['area_parent_id']);
  223. if($parent_id === 0) {
  224. $ret['city_id'] = 0;
  225. $ret['prov_id'] = $info['area_id'];
  226. }
  227. else {
  228. $ret['city_id'] = $info['area_id'];
  229. $ret['prov_id'] = $info['area_parent_id'];
  230. }
  231. return $ret;
  232. }
  233. public function city_info($city_id)
  234. {
  235. $city_id = intval($city_id);
  236. if($city_id <= 0) return false;
  237. $mod_area = Model('area');
  238. $info = $mod_area->getAreaInfo(['area_id' => $city_id]);
  239. if(empty($info)) return false;
  240. $parent_id = intval($info['area_parent_id']);
  241. if($parent_id === 0) {
  242. $ret['city_id'] = 0;
  243. $ret['prov_id'] = $info['area_id'];
  244. $ret['prov_name'] = $info['area_name'];
  245. $ret['city_name'] = '';
  246. }
  247. else {
  248. $ret['city_id'] = $info['area_id'];
  249. $ret['prov_id'] = $parent_id;
  250. $ret['city_name'] = $info['area_name'];
  251. $prov = $mod_area->getAreaInfo(['area_id' => $parent_id]);
  252. $ret['prov_name'] = $prov['area_name'];
  253. }
  254. return $ret;
  255. }
  256. }