Pull to refresh

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


Готово!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.