<?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;
}
}