Я сделал что-то симуляционное в PHP, используя алгоритм Lumb.
Вы должны быть в состоянии получить что-то из кода ниже (сидит в моей модели, но вы можете вставить в любом месте).
public function search($start_latitude, $start_longitude, $radius, $radius_type, $offset, $limit)
{
$results = array();
$locations = array();
$sql = "SELECT `location_id`, `latitude`, `longitude` FROM `table`";
$query = $this->db->query($sql);
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
$geo_data = $this->_bearing_distance_calc($start_latitude, $start_longitude, $row->latitude, $row->longitude, $radius_type);
$geo_data['radius_type'] = $radius_type;
if($geo_data['distance'] <= $radius)
{
// radial serach results
$locations[] = $row->location_id;
}
}
// return amount requested
$results['total'] = count($locations);
$results['locations'] = array_slice($locations, $offset, $limit);
return $results;
}
else
{
// no results
return FALSE;
}
}
/**
* Calculate Distance Between two points.
*
* This method is used to calculate the distance between to geographical points. <br />
* Used by the search method.
*
* @access private
*
* @param float $device_latitude
* @param float $device_longitude
* @param float $beach_latitude
* @param float $beach_longitude
* @param integer $radius_type
*
* @return array
*/
private function _bearing_distance_calc($start_latitude, $start_longitude, $building_latitude, $building_longitude, $radius_type)
{
// using Rhumb lines(or loxodrome)
// convert to rads for php trig functions
$start_latitude = deg2rad($start_latitude);
$start_longitude = deg2rad($start_longitude);
$building_latitude = deg2rad($building_latitude);
$building_longitude = deg2rad($building_longitude);
// testing variables
//$start_latitude = deg2rad(39.4422);
//$start_longitude = deg2rad(-122.0307);
//$building_latitude = deg2rad(49.4422);
//$building_longitude = deg2rad(-112.0307);
// calculate delta of lat and long
$delta_latitude = $building_latitude-$start_latitude;
$delta_longitude = $building_longitude-$start_longitude;
// earth radius
if ($radius_type == 'miles') // using miles
{
$earth_radius = 3959;
}
else // using kilometers
{
$earth_radius = 6371;
}
// now lets start mathing !!
// cast types
$dPhi = log(tan($building_latitude/2+M_PI/4)/tan($start_latitude/2+M_PI/4));
if ($dPhi != 0)
{
$q = $delta_latitude/$dPhi;
}
else
{
$q = cos($start_latitude);
}
//$q = (!is_nan($delta_latitude/$dPhi)) ? $delta_latitude/$dPhi : cos($start_latitude); // E-W line gives dPhi=0
// if dLon over 180° take shorter rhumb across 180° meridian:
if (abs($delta_longitude) > M_PI)
{
$delta_longitude = $delta_longitude>0 ? -(2*M_PI-$delta_longitude) : (2*M_PI+$delta_longitude);
}
$geo_data = array();
$geo_data['distance'] = sqrt($delta_latitude*$delta_latitude + $q*$q*$delta_longitude*$delta_longitude) * $earth_radius;
$bearing = rad2deg(atan2($delta_longitude, $dPhi));
if($bearing < 0)
{
$bearing = 360 + $bearing;
}
$geo_data['bearing'] = $bearing;
return $geo_data;
}