Привет хабр! Хочу рассказать несколько слов о геокодирование.
Что такое геокодирование? (developers.google.com)
Геокодирование – процесс преобразования адресов (таких как 1600 Amphitheatre Parkway, Mountain View, CA) в географические координаты (такие как широта 37.423021 и долгота -122.083739). API геокодирования Google предоставляет через HTTP-запрос прямой доступ к геокодеру.
Зачем это нам?
Задача: есть социальная сеть. Есть поиск групп. При результате «0» групп — отображать группы расположены в радиусе 50 км. от пользователя. (При создании группы и профиля указывается город).
CMS: Dolphin 7.
Записываем координаты пользователей и групп
Сделаем себе «сервис» для удобного дальнейшего использования:
Обращение к Google API:
Широта и долгота есть! Запись в БД:
Теперь можем вызвать «сервис» в удобном для нас месте:
Таким же образом создаем для групп.
«Сервис» вызываем при регистрации пользователя и создании группы.
Как у нас дела?
По большому счету — у нас все готово. Остается поставить простое условие в поиске на пустой массив (когда групп найдено «0») и обратиться к своей фнкции которая будет вычислять по формуле 50 км. по данным lat and lng и извлекать группы из БД.
Готово!
Что такое геокодирование? (developers.google.com)
Геокодирование – процесс преобразования адресов (таких как 1600 Amphitheatre Parkway, Mountain View, CA) в географические координаты (такие как широта 37.423021 и долгота -122.083739). API геокодирования Google предоставляет через HTTP-запрос прямой доступ к геокодеру.
Зачем это нам?
Задача: есть социальная сеть. Есть поиск групп. При результате «0» групп — отображать группы расположены в радиусе 50 км. от пользователя. (При создании группы и профиля указывается город).
CMS: Dolphin 7.
Записываем координаты пользователей и групп
Сделаем себе «сервис» для удобного дальнейшего использования:
public function serviceAddProfileLocation($iProfileId = 0, $aProfileData = []) {
if (empty($aProfileData))
$aProfileData = getProfileInfo();
if (empty($aProfileData['zip']) && empty($aProfileData['country']) && empty( $aProfileData['city'] )) {
return false;
}
$iProfileId = $iProfileId ? $iProfileId : $this->_iProfileId;
$aGeoData = $this->googleSearchLatLng($aProfileData['zip'], $aProfileData['city'], $aProfileData['country']);
$res = $this->_oDb->addProfileLocation(
$iProfileId,
$aGeoData->results[0]->geometry->location->lat,
$aGeoData->results[0]->geometry->location->lng
);
return $res;
}
Обращение к Google API:
private function googleSearchLatLng( $address, $city, $country)
{
$address = str_replace(" ", "+", "$address");
$city = str_replace(" ", "+", "$city");
$country = str_replace(" ", "+", "$country");
$sUri = 'http://maps.googleapis.com/maps/api/geocode/json?address=' . urlencode($address . ',+' . $city ',+' . $country);
$sContent = file_get_contents($sUri);
return json_decode($sContent);
}
Широта и долгота есть! Запись в БД:
public function addProfileLocation($iProfileId, $lat, $lng) {
$sSql = " UPDATE `Profiles` "
. " SET `lat` = '{$lat}' , `lng` = '{$lng}' "
. " WHERE `id` = '{$iProfileId}' ";
return $this->query($sSql);
}
Теперь можем вызвать «сервис» в удобном для нас месте:
BxDolService::call('groups', 'add_profile_location');
Таким же образом создаем для групп.
«Сервис» вызываем при регистрации пользователя и создании группы.
Как у нас дела?
По большому счету — у нас все готово. Остается поставить простое условие в поиске на пустой массив (когда групп найдено «0») и обратиться к своей фнкции которая будет вычислять по формуле 50 км. по данным lat and lng и извлекать группы из БД.
function getClubAroundMe($lat, $long){
$clubAroundMe= "SELECT *, ( '3959' * acos( cos( radians('$lat') ) * cos( radians( `lat` ) ) *
cos( radians( `lng` ) - radians('$long') ) + sin( radians('$lat') ) *
sin( radians( `lat` ) ) ) ) AS distance FROM `bx_groups_main` HAVING
`distance` < '50' ORDER BY `distance` LIMIT 0 , 20 ";
return $this->getAll($clubAroundMe);
}
Готово!