问题
Im trying to build a small CakePHP website which has some lat and longitudes in the DB. A user performs a search query to locations (with giving her/his address) and the results needs to be ordered by distance from user to the location. I can already get the lat en lng when providing an adress (using the Google Maps API). I'm not sure how to build a CakePHP find with an distance order. Any ideas?
I'm using CakePHP 2.3.
回答1:
I prefer to use virtualFields for this purpose. The implementation depends on DB you use. For Postgres it will look like following:
MyModel.php
public function findSortedByDistanse($long, $lat){
$distanceValue = "calc_distance($lat, $long, MyModel.lat, MyModel.lon)";
$this->virtualFields['distance'] = $distanceValue;
return $this->find('all', array('conditions' => array(
'order' => 'MyModel.distance ASC'
)));
}
where calc_distance is a stored procedure for Postgres
Params: IN source_lat numeric, IN source_lon numeric, IN target_lat numeric, IN target_lon numeric
Code:
SELECT ( 3956 * 2 *
ASIN (
SQRT (
POWER ( SIN ( ( $1 - abs($3) ) * pi()/180/2 ),2 ) +
COS ( $1 * pi()/180 ) *
COS ( abs($3) * pi()/180 ) *
POWER ( SIN ( ( $2 - $4 ) * pi()/180 / 2 ), 2 )
)
)
)
If you prefer raw query, use following:
$distanceValue = "3956 * 2 * ASIN(SQRT(POWER(SIN(({$lat}-abs(MyModel.lat))*pi()/180/2),2)+COS({$lat} * pi()/180)*COS(abs(MyModel.lat) * pi()/180)*POWER(SIN(({$long} - MyModel.lon)*pi()/180 / 2), 2)))";
回答2:
Rangeable can be used to find near-by based on user's chosen GeoLocation. However, this plugin is deprecated because it is made to support CakePHP 1.x and may not work with CakePHP 2.x .
You might need to convert it.
来源:https://stackoverflow.com/questions/15448763/search-distance-between-2-points-cakephp