API 2GIS

Один мой заказчик увидел API 2GIS demo Это API позволяет создать поиск компаний по базе 2GIS на своем сайте. И только из-за миникарты мы начали ее встраивать. 
НО, к сожалению, Эти самые миникарты будут у них готовы только осень-зима этого года, а узнали мы это только после того, как пол работы сделано.


Я успела вставить форму поиска, страницу результатов, вывод профиля фирм и ее филиалов. И как только узнали о миникарте, работу заморозили. Конечно можно воспользоваться яндекс картами, но заказчик решил мои сылы на другое перенаправить.


Короче. Хилую версию того, что сделано можно посмотреть на тестовой версии проекта b2bis.ru


Я опубликовала коды здесь Возможно тестовую версию проекта вы не откроете, она не всегда доступна.


Но суть такая. class API2GIS делает обращение к 2gis базе. Так как проект наш в кодировке window-1251, а 2gis воспринимает только utf-8  пришлось кодировать туда-сюда как запрос так и результаты. Так как работу заморозили, код довольно сумбурный, но все равно представляю вниманию.

Показать код
******************************************************************************
<?php
/**
 * Класс работы с API 2GIS поиском
 * в соответствии с документом http://api.2gis.ru/doc/firm-search/
 *
 * @created 29.09.11
 * 
 * @author olgatcpip <olgatcpip@ya.ru> http://webolga.ru 
 */

class API2GIS {

public $version = '1.3';
public $outformat = 'json';
public $callback = 'dgCallback';
public $key = 'xxxxxxxx';


public $pagesize = 30;
public $page = 1;
public $sort = 0;

private $query_base = null;
public  $query_data = null;
private $query = null;

public $encode = null; //кодировка сайта (UTF-8, WINDOWS-1251)..... Null - кодировки совпадают

//ПАРАМЕТРЫ ОТВЕТА
public $response = null; //ответ

public $total = null; //количество найденных фирм

private $error = array();

//Cash,Visa,Mastercard,DinersClub,GoldCrown,Internet,Non-cash
public $payoptions = array(
'Cash' => 'Наличный расчет',
'Non-cash' => 'Безналичный расчет для юридических лиц',
'Visa' => 'Visa',
'Mastercard'=> 'Mastercard',
'DinersClub'=> 'DinersClub',
'GoldCrown' => 'GoldCrown',
'Internet' => 'Internet',
);

public function __construct()
{
$this->encode = 'WINDOWS-1251';
$this->query_base = array(
'key' => $this->key,
'version' => $this->version,
'output' => $this->outformat,
);
}

/**
* Формирование зарпоса профиля
* @doc http://api.2gis.ru/doc/firm-profile-output/
* @param  $id
* @param  $hash
* @return void
*/
public function formQueryProfile($id,$hash)
{
$this->query_data = array(
'id' => $id,
'hash' => $hash,
);
$this->query_data = array_merge($this->query_data,$this->query_base);
$this->query = $this->transQuery('http://catalog.api.2gis.ru/profile',$this->query_data);
echo $this->query;
}

/**
* Список филиалов одной организации
* @doc http://api.2gis.ru/doc/firm-list-id/
* @param  $firmid
* @return void
*/
public function formQueryFilials($firmid)
{
$this->query_data = array(
'firmid' => $firmid,
);
$this->query_data = array_merge($this->query_data,$this->query_base);
$this->query = $this->transQuery('http://catalog.api.2gis.ru/firmsByFilialId',$this->query_data);
echo $this->query;
}

/**
* Поиск фирм в рубрике (идентичен поиску фирм)
* @see formQuerySearch
* @param  $page
* @param  $rubric
* @param  $where
* @param  $lon
* @param  $lat
* @param  $rad
* @param  $search_condition
* @param  $sort
* @return void
*/
public function formQueryRubric($page,$rubric,$where,$lon,$lat,$rad,$search_condition,$sort)
{

$this->page = (int)$page>0?(int)$page:1;
$this->query_data = array(
'what' => $rubric,
'where' => $where,
'lon' => $lon,
'lat' => $lat,
'rad' => $rad,
'search_condition' => $search_condition,
'sort' => $this->getSort($sort),


'page' => $this->page,
'pagesize' => $this->getPageSize(),
);
$this->query_data = array_merge($this->query_data,$this->query_base);
$this->query = $this->transQuery('http://catalog.api.2gis.ru/searchinrubric',$this->query_data);
echo $this->query;
}

/**
* Формирование запроса на поиск фирм
* @param  $page
* @param  $what
* @param  $where
* @param  $lon
* @param  $lat
* @param  $rad
* @param  $search_condition
* @param  $sort
* @param int $limit
* @return void
*/
public function formQuerySearch($page,$what,$where,$lon,$lat,$rad,$search_condition,$sort)
{
$this->page = (int)$page>0?(int)$page:1;
$this->query_data = array(
'what' => $what,
'where' => $where,
'lon' => $lon,
'lat' => $lat,
'rad' => $rad,
'search_condition' => $search_condition,
'sort' => $this->getSort($sort),


'page' => $this->page,
'pagesize' => $this->getPageSize(),
);
$this->query_data = array_merge($this->query_data,$this->query_base);
$this->query = $this->transQuery('http://catalog.api.2gis.ru/search',$this->query_data);
echo $this->query;
}

public function transQuery($url,$data)
{
$query = urldecode($url.'?'.http_build_query($data));
$query = str_ireplace(' ','+',$query);
return $query;
}

public function replQuery($url,$data,$key,$val)
{
$data[$key] = $val;
return $this->transQuery($url,$data);
}
/**
* Количество результатов поиска, выводимых на одной странице должно быть в пределах от 5 до 50
* @return void
*/
public function getPageSize($ps=null)
{
if(!is_null($ps))
$this->pagesize = $ps;
if($this->pagesize < 5)
$this->pagesize=5;
elseif($this->pagesize > 50)
$this->pagesize=50;
return $this->pagesize;
}

/**
* Получить порядок сорировки
*     relevance (по умолчанию) - наилучшее соответствие запросу. В поиске участвует название фирмы и рубрики в которые фирма входит;
* rating - по популярности;
* name - по алфавиту.
* @return string
*/
public function getSort($sort)
{
$valid = array('relevance', 'name', 'rating');
if(is_numeric($sort))
if(!getElement($valid,$sort))
$this->sort = $valid[0];
else
$this->sort = $valid[$sort];

elseif(!in_array($sort,$valid))
$this->sort = $valid[0];
else
$this->sort = $sort;

return $this->sort;
}


/**
* конвертировать или нет значение, полученное в ответе на запрос от 2GIS
*
* @return string
*/
public function conv($value)
{
if(!$value)
return '';
if(is_null($this->encode))
return $value;
return iconv('UTF-8',$this->encode,$value);
}

/**
* Полуить ответ
* @return bool|int true - без ошибок, есть результаты; false - ошибочка; 404 - пусто
*/
public function getResponse()
{
if(!$this->query)
{
$this->error[] = 'No Query!';
return false;
}
if(!is_null($this->encode))
$url = iconv($this->encode,'UTF-8',$this->query);
else
$url = $this->query;
$result = @file_get_contents($url);
if($result)
$this->response = (array)json_decode($result);
if(!$this->response)
{
$this->error[] = 'No Response! ';//.json_last_error();
return false;
}

if($this->response['response_code']==404)
{
// в случае отсутствия результатов:
$this->error[] = $this->conv($this->response['error_message']);
return 404;
}
elseif($this->response['response_code']!=200)
{
$this->error[] = 'Ошибка: '.$this->conv($this->response['error_message']).' (code: '.$this->response['response_code'].')';
return false;
}

return true;
}

public function getError($sep)
{
if(!empty($this->error))
return implode($sep, $this->error);
}


}



class C_Paging
{

    public $count;      // количество элементов в списке (например список новостей)
    public $limit;      // количество выводимых элементов на странице
    public $perLine;    // количество номеров в листовке (желательно делать не четным)

    public $pkey;       // ключ, передаваемый в $_GET, хранимый номер текущей страницы

    public $pCount;     // количество получившихся страниц
    public $curPage;    // номер текущей страницы
    public $offset;     // определенный offset в запросе

    public $firstPage;  // номер первой страницы в листовке
    public $lastPage;   // номер последней страницы в личтовке

    public $step    = 1;


    public function __construct($count,$limit,$p,$perline=5) {
        $this->count    = $count;
        $this->limit    = $limit<1?10:$limit;
        $this->curPage    = $p;
        $this->perLine    = $perline;
    }

    // формируем базовые параметры листовки
    public function pagingBaseForm(){

        $this->pCount = intval($this->count/$this->limit);
        if ($this->count%$this->limit)
            ++$this->pCount;
        if (!$this->curPage || ($this->curPage > $this->pCount))
            $this->curPage = 1;
        $this->offset=($this->curPage-1)*$this->limit;
    }
    // формируем параметры страниц в листовке
    public function pageParamsForm(){
        if ($this->pCount <= 1)
            return false;

        $this->firstPage = $this->curPage - intval($this->perLine/2);
        if ($this->firstPage < 1 || $this->pCount <= $this->perLine)
            $this->firstPage = 1;

        $this->lastPage = $this->firstPage + $this->perLine - 1;
        if ($this->lastPage > $this->pCount)
        {
            $this->lastPage = $this->pCount;
            $this->firstPage = $this->lastPage - $this->perLine + 1;
            if ($this->firstPage < 1)
                $this->firstPage = 1;
        }
        return true;
    }

//-- частности --//
    public function templ(){
        $this->pagingBaseForm();
        if(!$this->pageParamsForm())
            return false;

        $paging = array();
        $inx=0;
        if($this->curPage!=$this->firstPage)
        {
            $paging[$inx]['num']    = 1;
            $paging[$inx]['name']    = 'первая';
            $paging[$inx]['cur']    = false;
            $inx++;

            $paging[$inx]['name']    = '<<';
            $paging[$inx]['cur']    = false;
            $paging[$inx]['num']    = $this->curPage-$this->step;
            if($paging[$inx]['num']<1)
                $paging[$inx]['num'] = 1;
            $inx++;
        }
        for ($i = $this->firstPage; $i <= $this->lastPage; ++$i)
        {
            if ($i == $this->curPage)
                $paging[$inx]['cur']=true;
            else
                $paging[$inx]['cur']=false;
            $paging[$inx]['num'] = $paging[$inx]['name'] = $i;
            $inx++;
        }
        if($this->curPage!=$this->lastPage)
        {
            $paging[$inx]['num']    = $this->lastPage+$this->step;
            if($paging[$inx]['num']>$this->pCount)
                $paging[$inx]['num']=$this->pCount;
            $paging[$inx]['name']    = '>>';
            $paging[$inx]['cur']    = false;
            $inx++;

            $paging[$inx]['num']    = $this->pCount;
            $paging[$inx]['name']    = 'последняя';
            $paging[$inx]['cur']    = false;
        }

        return $paging;

    }
}

?>

ПРИМЕР использования

<?php
/**
 * Поиск по базе 2GIS
 * Использование API 2GIS
 * @doc http://api.2gis.ru/doc/firm-search/
 *
 * @created 29.09.11
 *
 * @author olgatcpip <olgatcpip@ya.ru> http://webolga.ru
 */
if(GET('firm_id'))
$API2GIS->formQueryFilials($_GET['firm_id']);
elseif(GET('rubric'))
$API2GIS->formQueryRubric(GET('page'), GET('rubric'), GET('where'), GET('lon'), GET('lat'), GET('rad'), GET('search_condition'), GET('sort'));
else
$API2GIS->formQuerySearch(GET('page'), GET('what'), GET('where'), GET('lon'), GET('lat'), GET('rad'), GET('search_condition'), GET('sort'));
$API2GIS->getResponse();

$API2GIS->total = getElement($API2GIS->response,'total');


$curURL = '/2gis';
$curGET = $_GET;
$num = 0;
$filialURL = '/2gis/profile/';

function api2gis_paging($paging_form)
{ global $curURL,$API2GIS;
if(!$paging_form) return; ?>
<div class="paging">
Страницы: &nbsp;&nbsp;
<?php
$curGET = $_GET;
unset($curGET['page']);
foreach($paging_form as $page)
{ $curGET['page'] = $page['num'];
if ($page['cur'])
echo '<b>'.$page['name'].'</b>&nbsp; ';
else
echo '<a href="'.$API2GIS->transQuery($curURL,$curGET).'" >'.$page['name'].'</a>&nbsp; ';
}?>
</div>
<?php }
//dump($API2GIS->response); die();

?>
<div class="mainbar2" style="margin-left:-10px;">
<div class="content">
<h1>НАЗВАНИЕ СТРАНИЦЫ например результаты поиска</h1>
<table border="0">
<tr>
<td width="100%">
<div style="color:#cc0000"><?php echo $API2GIS->getError("<br/>");?></div>
<div>
<?php
if($API2GIS->total)
{
echo '<div style="font-size:; margin-bottom:10px">Вы искали: "<b>'.$API2GIS->conv($API2GIS->response['what']).'</b>" в "<b>'.$API2GIS->conv($API2GIS->response['what']).'</b>"</div>';
$did_you_mean = getElement($API2GIS->response,'did_you_mean')?(array)$API2GIS->response['did_you_mean']:array();
if(getElement($did_you_mean,'rubrics'))
{
echo '<div style="font-size:120%; margin-bottom:10px">Возможно, вы искали:';
foreach($did_you_mean['rubrics'] as $obj)
{ //dump($obj); die();
$curGET = $_GET;
unset($curGET['what']);
$curGET['rubric'] = $API2GIS->conv($obj->name);
$keyword = isset($obj->keyword)?$obj->keyword:'';
echo '<br><a href="'.$API2GIS->transQuery($curURL,$curGET).'">'.$curGET['rubric'].'</a> <span class="rubrics">'.$API2GIS->conv($keyword).'</span>';
}
echo '</div>';
}
if(getElement($did_you_mean,'geo'))
{
echo '<div style="font-size:120%; margin-bottom:10px">Возможно вы искали в:';
foreach($did_you_mean['geo'] as $obj)
{
$curGET = $_GET;
$curGET['where'] = $API2GIS->conv($obj->name);
echo '<br><a href="'.$API2GIS->transQuery($curURL,$curGET).'">'.$curGET['where'].'</a>';
}
echo '</div>';
}
$paging = new C_Paging($API2GIS->total,$API2GIS->pagesize,$API2GIS->page);
$paging_form = $paging->templ();
}
?>
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td valign="top">
<?php
if(getElement($API2GIS->response,'advertising'))
{
foreach($API2GIS->response['advertising'] as $adv)
{

$data = array(
'id' => $adv->firm_id,
'hash' => $adv->hash,
);
echo '<div style="width:100%; border: 1px solid black; margin: 5px; padding: 4px;">
<div style="padding:0 0 5px 10px;"><a href="'.$API2GIS->transQuery($filialURL,$data).'" class="fname"><b>'.$API2GIS->conv($adv->title).'</b></a>                    </div>
<div style="padding: 0 0 0px 10px;">'.$API2GIS->conv($adv->text).'</div>
</div>';
}
}

if($API2GIS->total){?>
<p>Найдено фирм: <?php echo (int)$API2GIS->total?> на <?php echo $paging->pCount?> страницах </p>

<p>Сортировать:
<?php
if($API2GIS->sort=='relevance')
{
echo '<b>по лучшему найденному</b>, <a href="'.$API2GIS->replQuery($curURL,$_GET,'sort','name').'">по алфавиту</a>';
}
else
{
echo '<a href="'.$API2GIS->replQuery($curURL,$_GET,'sort','relevance').'">по лучшему найденному</a>, <b>по алфавиту</b>';
}
?>
</p>

<?php api2gis_paging($paging_form);
$num = (($paging->curPage-1)*$paging->limit);
}
if(count(getElement($API2GIS->response,'result')))
{
foreach($API2GIS->response['result'] as $res)
{ $res = (array)$res;
$num +=1;
$data = array(
'id' => $res['id'],
'hash' => $API2GIS->conv($res['hash'])
);
//$curGET = array_merge($_GET,$data); //id="f9804975940000"
echo '
<div style="float:left; margin-right: 6px;">'.$num.'</div>
<div style="float: left; width: 540px; padding-bottom: 15px;">
<div><a href="'.$API2GIS->transQuery($filialURL,$data).'"  class="fname" >'.$API2GIS->conv(getElement($res,'name')).'</a></div>
<div style="padding-top: 5px;">'.$API2GIS->conv(getElement($res,'city_name')).', '.$API2GIS->conv(getElement($res,'address')).'</div>';
if(getElement($res,'rubrics') && is_array($res['rubrics']))
{
$temp = array();
foreach($res['rubrics'] as $r)
{
$temp[] = $API2GIS->conv($r);
}
echo '<div class="rubrics">'.implode(", ",$temp).'</div>';
}


if(getElement($res,'firm_group'))
{// появляется если у фирмы несколько филиалов
$data = array('firm_id'=>$res['firm_group']->id);
echo '<div><a href="'.$API2GIS->transQuery($curURL,$data).'" class="fname rubrics">Посмотреть все филиалы ['.$res['firm_group']->count.']</a></div>';
}
echo '<div class="ads_info2 rubrics" style="font-size:11px;">'.$API2GIS->conv(getElement($res,'micro_comment')).'</div>';
echo'
</div>
<div style="clear:both;">';


}
}
if($API2GIS->total)
api2gis_paging($paging_form);
?>

</td>
<td valign="top" align="right">

</td>
</tr>
<tr>
</tr>
</table>
<!--br clear="all"/-->
</div>

</td>
<td>&nbsp;</td>
<td class="rightbar" width="210">
</td>
</tr>
</table>
</div>
</div>
**********************************************************************


А так же есть альтернативное решение тут.

Комментарии

  1. Что-то не работает Ваш код((((

    ОтветитьУдалить
  2. Если скачивать архив, я там не все-все выложила, только для посмотреть. Т.е. его в лоб не запустить. Там как пример того, как использовать опубликованный в посте класс

    ОтветитьУдалить
  3. Есть ещё решение, наткнулась случайно
    http://webmap-blog.ru/obzors/znakomstvo-s-api-2gis

    ОтветитьУдалить
  4. Ольга здравствуйте. Хотел бы с Вами переговорить. Как с Вами можно связаться?

    ОтветитьУдалить
  5. свяжитесь со мной ICQ: 141 шесть 8 шесть

    ОтветитьУдалить
    Ответы
    1. Зачем? Если есть интимные вопросы или предложения о работе пишите письма.
      Прям под постом есть картинка письма ;) Я так среагирую быстрее :)

      Удалить
  6. Что то я не допонял, что скачал.
    Сейчас сам воюю с АПИ
    плохо документировано, приходится высасывать всё из пальца. Да и код, который насоздавал - не работает, а спросить не у кого.

    Вот думаю, форум, что ли поднять на эту тему.
    Может кто и поможет.

    ОтветитьУдалить
    Ответы
    1. Не отчаивайся. Документировано хорошо. Я с первого раза поняла.
      То, что ты скачал у меня - это только часть. Сам класс работы с апи опубликован тут в статье. Т.е. его нужно к себе скопировать и вставить. В архиве то, как с ним работать. Руки не доходят собрать в наглядную кучку, чтоб работало сразу.
      + очень хорошо расписано альтернативное решение тут http://webmap-blog.ru/obzors/znakomstvo-s-api-2gis-–-dopolnenie.

      Удалить
  7. Ольга, не нашел в вашей реализации регистрацию просмотров профилей http://api.2gis.ru/doc/firms/profiles/register/ что то мало об этом написано

    ОтветитьУдалить
  8. А мы установили API2Гис на своём портале. Оцените:
    http://строй-россия.рф/москва/компании/категории/двери/все/

    ОтветитьУдалить
  9. Добрый день.

    Кто сможет приделать api 2gis на движок DLE. Прошу написать на почту info(друг человека)dzerlive.ru

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения