ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
用户纬度 * PI() / 180 - 纬度字段名* PI() / 180
) / 2
),
2
) + COS(用户纬度 * PI() / 180) * COS(纬度字段名 * PI() / 180) * POW(
SIN(
(
用户经度 * PI() / 180 - 经度字段名 * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS juli
创建函数:
drop function if exists calc_rice;
create function calc_rice(lng1 varchar(20), lat1 varchar(20), lng2 varchar(20), lat2 varchar(20)) returns int
begin
return ROUND(6378.138 * 2 * ASIN(SQRT(
POW(SIN(( lat1 * PI() / 180 - lat2 * PI() / 180 ) / 2), 2) +
COS( lat1 * PI() / 180) * COS(lat2 * PI() / 180) *
POW(SIN(( lng1 * PI() / 180 - lng2 * PI() /180) / 2), 2)
)) * 1000 );
end ;
注释:
(当前经度, 当前纬度, 需要比对的经度,需要比对的纬度)
测试
select calc_rice(127, 33, 127, 34) as rice
如果创建时报错:
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
请在root账号下执行:
set global log_bin_trust_function_creators=TRUE;
SELECT
id,
name,
lat,
lng,
ROUND(
6378.138 * 2 * ASIN(
SQRT(
POW(
SIN(
(
40.042307 * PI() / 180 - lat * PI() / 180
) / 2
),
2
) + COS(40.042307 * PI() / 180) * COS(lat * PI() / 180) * POW(
SIN(
(
116.317205 * PI() / 180 - lng * PI() / 180
) / 2
),
2
)
)
) * 1000
) AS juli
FROM
fa_shop
ORDER BY
juli DESC
$sql =" SELECT id, name, lat, lng, ";
$sql .=latlngfield("40.042307", "116.317205") ;
$sql .= " FROM fa_shop ORDER BY juli DESC";
//距离排序 字段生成
function latlngfield($lat, $lng,$latfield="lat", $lngfield="lng", $returnfield="juli") {
$sql=" ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN( ( ";
$sql.= $lat." * PI() / 180 - ".$latfield." * PI() / 180 ) / 2 ), 2 ) + COS( ";
$sql.= $lat." * PI() / 180) * COS( ".$latfield." * PI() / 180) * POW( SIN( ( ";
$sql.= $lng." * PI() / 180 - ". $lngfield." * PI() / 180 ) / 2 ), 2 ) ) ) * 1000 ) AS " .$returnfield."";
return $sql;
}
tp用法
//距离排序 字段生成
function latlngfield($lat, $lng,$latfield="lat", $lngfield="lng", $returnfield="juli") {
$sql=" ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN( ( ";
$sql.= $lat." * PI() / 180 - ".$latfield." * PI() / 180 ) / 2 ), 2 ) + COS( ";
$sql.= $lat." * PI() / 180) * COS( ".$latfield." * PI() / 180) * POW( SIN( ( ";
$sql.= $lng." * PI() / 180 - ". $lngfield." * PI() / 180 ) / 2 ), 2 ) ) ) * 1000 ) AS " .$returnfield."";
return $sql;
}
Db::name("user")
->field("id, name, lat, lng,".latlngfield("40.042307", "116.317205"))
->where(["juli","<","1000000"])
->order("juli desc")
->select();
php算距离
/**
* 根据经纬度算距离,返回结果单位是公里,先纬度,后经度
* @param $lat1
* @param $lng1
* @param $lat2
* @param $lng2
* @return float|int
*/
public function GetDistance($lat1, $lng1, $lat2, $lng2)
{
$EARTH_RADIUS = 6378.137;
$radLat1 = $this->rad($lat1);
$radLat2 = $this->rad($lat2);
$a = $radLat1 - $radLat2;
$b = $this->rad($lng1) - $this->rad($lng2);
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
$s = $s * $EARTH_RADIUS;
$s = round($s * 10000) / 10000;
return $s;
}
private function rad($d)
{
return $d * M_PI / 180.0;
}