<?php // 地球赤道半径 define('EARTH_RADIUS', 6378137); define('PI', pi()); ///# GPS工具类 zjfree@2017-03-29 class GpsTool { private static function get_rad($d) { return $d * PI / 180.0; } /// 获取两个GPS距离 public static function get_distance($gps1, $gps2) { $radLat1 = self::get_rad($gps1['lat']); $radLat2 = self::get_rad($gps2['lat']); $a = $radLat1 - $radLat2; $b = self::get_rad($gps1['lon']) - self::get_rad($gps2['lon']); $s = 2*asin(sqrt(pow(sin($a/2),2) + cos($radLat1)*cos($radLat2)*pow(sin($b/2),2))); $s = round($s * EARTH_RADIUS, 2); return $s; } /// GPS向指定方向移动指定距离 public static function go_angle($gps, $deg, $dist) { // 经纬度比例 $rate = cos($gps['lat'] * PI / 180); // 1纬度多少米 $lat_meter = 111111; $r = $deg * PI / 180.0; $x = sin($r) * $dist; $y = cos($r) * $dist; $x = $x / $lat_meter / $rate; $y = $y / $lat_meter; $new_gps = array( 'lon' => round($gps['lon'] + $x, 8), 'lat' => round($gps['lat'] + $y, 8), ); return $new_gps; } /// 判断GPS是否在指定区域内 public static function check_in_area($gps, $gps_list) { $px = $gps['lon']; $py = $gps['lat']; $flag = false; for($i = 0, $l = count($gps_list), $j = $l - 1; $i < $l; $j = $i, $i++) { $sx = $gps_list[$i]['lon']; $sy = $gps_list[$i]['lat']; $tx = $gps_list[$j]['lon']; $ty = $gps_list[$j]['lat']; // 点与多边形顶点重合 if(($sx === $px && $sy === $py) || ($tx === $px && $ty === $py)) { return true; } // 判断线段两端点是否在射线两侧 if(($sy < $py && $ty >= $py) || ($sy >= $py && $ty < $py)) { // 线段上与射线 Y 坐标相同的点的 X 坐标 $x = $sx + ($py - $sy) * ($tx - $sx) / ($ty - $sy); // 点在多边形的边上 if($x === $px) { return true; } // 射线穿过多边形的边界 if($x > $px) { $flag = !$flag; } } } // 射线穿过多边形边界的次数为奇数时点在多边形内 return $flag; } }