Яндекс Карты: Поиск произвольных объектов

в 12:54, , рубрики: API карт, Веб-разработка, поиск, Яндекс API, яндекс карты, метки: , ,

imageНедавно понадобилось написать скрипт, который по заданному списку ищет магазины на Яндекс Картах и показывает имеющиеся в зависимости от местоположения пользователя.
Например, нужно найти все магазины «Травы и приправы», находящиеся в городе пользователя, при этом, не используя базу точных адресов и координат магазинов.
Тщательное изучение API не дало результатов, поэтому было принято решение изобрести свой способ поиска.
Заинтересовавшихся прошу под кат.

В документации сказано, что поиск по карте можно осуществить с помощью функции geocode, передав ей топоним, соответствующий задаче. Например, чтобы найти улицу нужно передать топоним street и тд. подробнее тут.
При изучении таблицы возможных значений было обнаружено значение other. Но проверка ответа геодекодера выявила, что объекты вида 'Москва магазин Травы приправы ' он искать не умеет.

Запрос:

'http://geocode-maps.yandex.ru/1.x/?geocode=Москва, улица Новый Арбат, дом 24'

выдаст корректную информацию, а вот такой:

'http://geocode-maps.yandex.ru/1.x/?geocode=Москва, магазин Травы и приправы'

выдаст кучу информации, мало относящейся к предмету поиска

Было принято решение посмотреть, что можно вытащить со странички Яндекс Карт, так как там возможен поиск практически любых объектов.
При разборе страницы был найден JSON, начинается он со строки {«request»:{«args»:
заканчивается тегом '</script>'. Он содержит все необходимые данные, в том числе все найденные объекты, их координаты, маршруты, адреса, метки и прочее. Остается получить нужные данные, чтобы в дальнейшем можно было их использовать. Делать это будем с помощью PHP.
Итак, в результате получаем массив, содержащий координаты, адрес и названия объектов поиска. Затем, преобразуем его в JSON, который потом будет запрашивать скрипт с картой.

<?php
$array_shops=array('Магазин_1','Магазин_2');
$coords_file=array();
$geo_objects=array();
for($i=0;$i<count($array_shops);$i++)
{  
        $coords_file[$i]=file_get_contents("http://maps.yandex.ru/?text=".urlencode($_GET['town']." магазин ".$array_shops[$i]));
	$start=strpos($coords_file[$i],'{"request":{"args":');
	$end=strpos($coords_file[$i],'</script>',$start);
	$lenght=$end-$start;
	$js=json_decode(substr($coords_file[$i],$start,$lenght),1);
	$js=$js['vpage']['data']['businesses']['GeoObjectCollection']['features'];
	foreach($js as $value)
	{
		$geo_objects[]=array(
		'coordinates' =>array($value['geometry']['coordinates'][1], $value['geometry']['coordinates'][0]),
		'address'=>$value['properties']['CompanyMetaData']['address'],
		'name_shop'=>$array_shops[$i]
		);
	}
}
$js_array=json_encode($geo_objects);
echo $js_array;
?>

Не буду подробно расписывать код для самой карты, подробно можно почитать тут.

ymaps.ready(init);
function init () {
    var myMap = new ymaps.Map("map", {
    //определяем местоположение пользователя 
    center: [ymaps.geolocation.latitude, ymaps.geolocation.longitude], zoom: 12})
    //определяем город пользователя
    var town=ymaps.geolocation.city;
    var data_send=new Object();
    data_send.town = town;
    var coords=[];
    var address=[];
    var names_shop=[];
    var json_array;
    jQuery.ajax(
    {
     	url:"json_response.php",
     	data: data_send,
        dataType: 'json',
     	success: function(data){
     		json_array=data;
     		for(key in json_array){
     		coords.push(json_array[key].coordinates);
     		address.push(json_array[key].address);
     		names_shop.push(json_array[key].name_shop);
     		}
        //Ставим метки	  	
        var myCollection = new ymaps.GeoObjectCollection({}, {preset: 'twirl#shopIcon'});
	        for (var i = 0; i < coords.length; i++){
    		myCollection.add(new ymaps.Placemark(coords[i],
            {
                   balloonContentHeader:names_shop[i],
                   balloonContent: address[i],
             }));
	 }
    myMap.geoObjects.add(myCollection);
     }
   });
//настройки карты
myMap.controls.add(new ymaps.control.ZoomControl());
myMap.controls.add('mapTools');
myMap.controls.add('typeSelector');
}

Итог:
можем искать объекты по названию, без базы данных с координатами и адресами, которую необходимо поддерживать и обновлять.

Результат можно посмотреть тут. Надеюсь, в API Яндекс Карт будет добавлена возможность поиска по произвольным объектам.
Спасибо за внимание.

Автор: gentoonofb

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js