Как стать автором
Обновить

Геокодирование на практике (Google API)

Привет хабр! Хочу рассказать несколько слов о геокодирование.

Что такое геокодирование? (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);
}


Готово!
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.