"在距离内"查询是指基于地理位置的距离范围查询,通常用于查找某个坐标点周围一定半径内的记录。在CodeIgniter中使用活动记录(Active Record)实现这种查询需要结合数据库的地理空间函数。
MySQL提供了地理空间函数来计算两点之间的距离(以米为单位):
$this->db->select("id, name, address,
(6371 * acos(cos(radians($latitude)) * cos(radians(latitude)) *
cos(radians(longitude) - radians($longitude)) +
sin(radians($latitude)) * sin(radians(latitude)))) AS distance")
->from('locations')
->having('distance <=', $radius)
->order_by('distance', 'ASC');
PostgreSQL使用PostGIS扩展提供更专业的地理空间函数:
$this->db->select("id, name, address,
ST_Distance(
ST_GeographyFromText('POINT(' || longitude || ' ' || latitude || ')'),
ST_GeographyFromText('POINT($longitude $latitude)')
) AS distance")
->from('locations')
->where('ST_DWithin(
ST_GeographyFromText('POINT(' || longitude || ' ' || latitude || ')'),
ST_GeographyFromText('POINT($longitude $latitude)'),
$radius)')
->order_by('distance', 'ASC');
// 先筛选大致范围内的记录
$this->db->where('latitude >=', $minLat);
$this->db->where('latitude <=', $maxLat);
$this->db->where('longitude >=', $minLng);
$this->db->where('longitude <=', $maxLng);
问题1:查询性能慢
问题2:距离计算不准确
问题3:跨时区问题
function getNearbyLocations($lat, $lng, $radius) {
$this->db->select("id, name, address,
(6371 * acos(cos(radians($lat)) * cos(radians(latitude)) *
cos(radians(longitude) - radians($lng)) +
sin(radians($lat)) * sin(radians(latitude)))) AS distance");
$this->db->from('locations');
$this->db->having('distance <=', $radius);
$this->db->order_by('distance', 'ASC');
$query = $this->db->get();
return $query->result();
}
这个示例返回指定经纬度周围指定半径(公里)内的所有位置,按距离排序。
没有搜到相关的文章