我正在研究cakephp问题。我知道我们如何在cakephp中进行查询。在某些情况下,您必须使用sql语句本身作为查询($ sql)。以下是从数据库中获取最近点的查询。 SQL工作正常。现在,我希望以cakephp风格添加常见的分页形式cakephp。很遗憾,我找不到任何有关如何操作的信息。一般来说,要找到这样的信息并不容易。所以我不想要你的解决方案,我很乐意获得如何将复杂的查询转换为cakephp的链接。
这是我的codesnippet(正如前面提到的那样)。
public function getRestAroundMe($lat, $lng, $radius, $limit) { // Get some data to validate login.
/* Source: http://funkjedi.com/technology/308-search-using-geolocation-data-in-mysql/ */
// Constants related to the surface of the Earth
$earths_radius = 6371;
$surface_distance_coeffient = 111.320;
// Spherical Law of Cosines
$distance_formula = sprintf('%s * ACOS( SIN(RADIANS(geolatitude)) * SIN(RADIANS(%s)) + COS(RADIANS(geolongitude - %s)) * COS(RADIANS(geolatitude)) * COS(RADIANS(%s)) )', $earths_radius, $lat, $lng, $lat);
// Create a bounding box to reduce the scope of our search
$lng_b1 = $lng - $radius / abs(cos(deg2rad($lat)) * $surface_distance_coeffient);
$lng_b2 = $lng + $radius / abs(cos(deg2rad($lat)) * $surface_distance_coeffient);
$lat_b1 = $lat - $radius / $surface_distance_coeffient;
$lat_b2 = $lat + $radius / $surface_distance_coeffient;
// Construct our sql statement
$sql = sprintf('SELECT *, (%s) AS distance FROM restaurants AS Restaurant WHERE (geolatitude BETWEEN %s AND %s) AND (geolongitude BETWEEN %s AND %s) HAVING distance < %s ORDER BY distance ASC LIMIT 0, %s', $distance_formula, $lat_b1, $lat_b2, $lng_b1, $lng_b2, $radius, $limit);
return $this->query($sql);
}
感谢您的帮助
答案 0 :(得分:1)
现在我有了解决方案:
public function geoRest($lat, $lng, $radius, $limit) {
/* Source: http://funkjedi.com/technology/308-search-using-geolocation-data-in-mysql/ */
// Constants related to the surface of the Earth
$earths_radius = 6371;
$surface_distance_coeffient = 111.320;
// Spherical Law of Cosines
//$distance_formula ='$earths_radius * ACOS( SIN(RADIANS(geolatitude)) * SIN(RADIANS($lat)) + COS(RADIANS(geolongitude - $lng)) * COS(RADIANS(geolatitude)) * COS(RADIANS($lat)) )';
$distance_formula = sprintf('%s * ACOS( SIN(RADIANS(geolatitude)) * SIN(RADIANS(%s)) + COS(RADIANS(geolongitude - %s)) * COS(RADIANS(geolatitude)) * COS(RADIANS(%s)) )', $earths_radius, $lat, $lng, $lat);
// Create a bounding box to reduce the scope of our search
$lng_b1 = $lng - $radius / abs(cos(deg2rad($lat)) * $surface_distance_coeffient);
$lng_b2 = $lng + $radius / abs(cos(deg2rad($lat)) * $surface_distance_coeffient);
$lat_b1 = $lat - $radius / $surface_distance_coeffient;
$lat_b2 = $lat + $radius / $surface_distance_coeffient;
// Construct our sql statement
//$sql = sprintf('SELECT *, (%s) AS distance FROM restaurants AS Restaurant WHERE (geolatitude BETWEEN %s AND %s) AND (geolongitude BETWEEN %s AND %s) HAVING distance < %s ORDER BY distance ASC LIMIT 0, %s', $distance_formula, $lat_b1, $lat_b2, $lng_b1, $lng_b2, $radius, $limit);
//return $this->query($sql);
//$options['fields'] = array('*',$distance_formula.' AS distance');
$this->virtualFields['distance'] = $distance_formula;
$options['fields'] = array('*');
$options['conditions'] = array(
'Restaurant.geolatitude BETWEEN ? AND ?' => array($lat_b1, $lat_b2),
'AND' => array('Restaurant.geolongitude BETWEEN ? AND ?' => array($lng_b1, $lng_b2)),
'AND' => array('NOT' => array('Restaurant.geolongitude' => 0)),
'AND' => array('NOT' => array('Restaurant.geolatitude' => 0)),
'AND' => array('NOT' => array('Restaurant.geolongitude' => null)),
'AND' => array('NOT' => array('Restaurant.geolatitude' => null))
);
$options['contain'] = array(
'Menu' => array(
'conditions' => array(
'Menu.active' => '1'
)
)
);
$options['order'] = 'Restaurant.distance ASC';
$options['limit'] = $limit;
//return $options;
return $this->find('all', $options);
不幸的是'包含'不起作用,但那是我正在研究的另一个问题。如果有人有解决方案那就太棒了!
答案 1 :(得分:0)
看看Custom query pagination。有一些方法可以使用自定义查询进行分页。