2013-03-02 126 views
0

我正在处理cakephp问题。我知道我们如何在cakephp中进行查询。在某些情况下,您必须将sql语句本身用作查询($ sql)。以下是查询从数据库中获取最近的点。 SQL工作正常。现在,我想用cakephp风格添加常见的分页形式cakephp。很遗憾,我找不到有关如何操作的信息。一般来说,找到信息并不容易。所以我不想从你那里得到一个解决方案,我很乐意获得链接如何将一个复杂的查询转换成cakephp。cakephp风格的SQL查询

这是我的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); 
} 

感谢您的帮助

回答

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); 

不幸的是,“包含”不工作,但是这是我工作的另一个问题。如果有人有解决方案,这将是伟大的!