如何使用Laravel判断坐标是否在Google Map绘制的圆形范围内
判断坐标是否在Google Map圆形区域内(Laravel实现)
要判断一个坐标是否在Google Map绘制的圆形范围内,核心是计算目标点与圆心的球面距离,再和圆的半径比较。下面是两种常见场景的实现方式:
一、应用层单一点判断(PHP代码)
使用Haversine公式计算两点间的球面距离(单位:米),然后判断距离是否小于等于半径:
/** * 判断坐标是否在圆形区域内 * @param float $centerLat 圆心纬度 * @param float $centerLng 圆心经度 * @param float $pointLat 目标点纬度 * @param float $pointLng 目标点经度 * @param float $radiusMeters 圆半径(单位:米) * @return bool */ function isPointInCircle(float $centerLat, float $centerLng, float $pointLat, float $pointLng, float $radiusMeters): bool { $earthRadius = 6371000; // 地球平均半径,单位米 // 将角度转换为弧度 $latDiff = deg2rad($pointLat - $centerLat); $lngDiff = deg2rad($pointLng - $centerLng); // Haversine公式计算 $a = sin($latDiff / 2) ** 2 + cos(deg2rad($centerLat)) * cos(deg2rad($pointLat)) * sin($lngDiff / 2) ** 2; $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $distance = $earthRadius * $c; return $distance <= $radiusMeters; }
使用示例
// 圆心:旧金山坐标,半径1000米,判断目标点是否在圆内 $isInside = isPointInCircle(37.7749, -122.4194, 37.7755, -122.4185, 1000); var_dump($isInside); // 输出 true/false
二、数据库批量筛选(Laravel Eloquent/Query Builder)
如果需要从数据库中批量查询在圆形范围内的坐标,可以直接在SQL中嵌入Haversine公式,避免全表遍历:
用Query Builder实现
use Illuminate\Support\Facades\DB; $centerLat = 37.7749; $centerLng = -122.4194; $radiusMeters = 1000; $locations = DB::table('locations') ->whereRaw( '(6371000 * acos(cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat)))) <= ?', [$centerLat, $centerLng, $centerLat, $radiusMeters] ) ->get();
用Eloquent模型实现
假设你有Location模型对应locations表(含lat、lng字段):
$locations = \App\Models\Location::whereRaw( '(6371000 * acos(cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat)))) <= ?', [$centerLat, $centerLng, $centerLat, $radiusMeters] )->get();
注意事项
- 单位统一:示例中半径单位是米,若Google Map返回的半径是千米,需将
6371000改为6371,或把半径转换为米。 - 字段精度:数据库中
lat、lng建议用DECIMAL(10,8)类型,保证坐标精度。 - 性能优化:如果数据量较大,给
lat、lng字段添加SPATIAL空间索引,可大幅提升查询速度。
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

