2015-03-04 3 views
0

У меня есть база данных событий, которая имеет несколько событий, каждое событие имеет разную широту и долготу, если моя текущая широта 30.7263962 и долгота 76.7664144, как я могу получать события из базы данных, которые являются до 100 км от моего местоположения? Может ли кто-нибудь предложить мне запрос? Спасибополучить рядом с базой данных mysql с широтой и долготой

+0

Вам нужна гаверсинус формула –

+0

По соображениям производительности вы можете сначала сделать неточный запрос с дельтой широтой и дельтой долготой, а затем проверить найденные события с формула гаверсина. Взгляните на этот [ответ] (http://gis.stackexchange.com/a/19762) в gis.stackexchange. – martinstoeckli

ответ

0

Некоторый пример кода, который вы могли бы сгибать, будет (я попытался адаптироваться для ваших нужд, но сделал некоторые дикие догадки).
Это версия алгоритма гаверсинуса, используя Rhumb линии (или локсодромия)

<?php 
function search($device_latitude, $device_longitude, $radius, $radius_type) 
{ 
    $events = array(); 

    $sql = "SELECT `event_id`, `last_updated`, `location_lat`, `location_long` FROM `event`"; 
    $query = $this->db->query($sql); 

    if ($query->num_rows() > 0) 
    { 
     foreach ($query->result() as $row) 
     { 
      $geo_data = $this->_bearing_distance_calc($device_latitude, $device_longitude, $row->location_lat, $row->location_long, $radius_type); 
      $geo_data['radius_type'] = $radius_type; 
      // $geo_data contains => 'distance', 'bearing' 
      if($geo_data['distance'] <= $radius) 
      { 
       $events[] = $this->event->load($row->event_id); 
      } 
     } 
     return $events; 
    } 
    $this->error_msg = "Search failed."; 
    return NULL; 
} 

function _bearing_distance_calc($device_latitude, $device_longitude, $event_latitude, $event_longitude, $radius_type) 
{ 
    // using Rhumb lines(or loxodrome) 
    // convert to rads for php trig functions 
    $device_latitude = deg2rad($device_latitude); 
    $device_longitude = deg2rad($device_longitude); 
    $event_latitude = deg2rad($event_latitude); 
    $event_longitude = deg2rad($event_longitude); 

    // calculate delta of lat and long 
    $delta_latitude = $event_latitude-$device_latitude; 
    $delta_longitude = $event_longitude-$device_longitude; 

    // earth radius 
    if ($radius_type == 'Miles') 
    { 
     $earth_radius = 3959; 
    } 
    else 
    { 
     $earth_radius = 6371; 
    } 

    // now lets start mathing !! 
    $dPhi = log(tan($event_latitude/2+M_PI/4)/tan($device_latitude/2+M_PI/4)); 
    if ($dPhi != 0) 
    { 
     $q = $delta_latitude/$dPhi; 
    } 
    else 
    { 
     $q = cos($device_latitude); 
    } 
    //$q = (!is_nan($delta_latitude/$dPhi)) ? $delta_latitude/$dPhi : cos($device_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; 
} 
0

Что вам нужно перевести расстояние в градусах долготы и широты, фильтр на основе тех связанных записей, которые примерно находятся в ограничивающей рамке, затем сделайте более точный фильтр расстояния. Вот большой документ, который объясняет, как все это сделать:

http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

Смежные вопросы