Элемент управления «Поиск по карте»

Общие сведения

Элемент управления «Поиск по карте» предоставляет пользователям возможность искать на карте интересующие их объекты. Когда пользователь вводит запрос в поисковую строку, API выполняет поиск и отображает на карте результат.

Добавление элемента «Поиск по карте» на страницу

Элемент управления «Поиск по карте» реализуется классом control.SearchControl. Добавить элемент на карту можно двумя способами:

При создании карты

var myMap = new ymaps.Map('map', {
    center: [55.75, 37.57],
    zoom: 9,
    controls: ['searchControl']
}, {
    // Будет производиться поиск по топонимам и организациям.
    searchControlProvider: 'yandex#search'
});

Добавив на существующую карту

var searchControl = new ymaps.control.SearchControl({
    options: {
    // Будет производиться поиск по топонимам и организациям.
    provider: 'yandex#search'
   }
});
myMap.controls.add(searchControl);
<div id="map1" style="width:680px;height:250px"></div>

Провайдеры поиска

Для поиска по карте доступно два провайдера данных:

  • yandex#map — поиск только по топонимам. Позволяет настроить отображение результатов.
  • yandex#search — поиск по топонимам и организациям.

Провайдер поиска задается с помощью опции provider при создании поисковой строки:

var searchControl = new ymaps.control.SearchControl({
    options: {
        provider: 'yandex#map'
    }
});          

Программный поиск по карте

Программно выполнить поиск какого-нибудь объекта можно с помощью функции search().

searchControl.search('Дворцовая площадь, 2');
<div id="map2" style="width:680px;height:250px;margin-bottom:15px"></div>

Настройка элемента «Поиск по карте»

При создании элемента управления можно задать следующие параметры поиска:

boundedBy

Опция, ограничивающая поиск по карте указанной областью. Область задается двумя точками, указывающими координаты левого верхнего и правого нижнего углов прямоугольника. Доступно только при использовании провайдера yandex#map. Если эта опция не задана, поиск ведется в видимой области.

noPlacemark

Если указано true, для найденного объекта не будет добавляться метка. Доступно только при использовании провайдера yandex#map.

noPopup

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

noSuggestPanel

Если указано true, не будет показываться панель с поисковыми подсказками.

placeholderContent

Опция, определяющая текст заглушки в строке поиска в текстовом формате.

kind

Опция, определяющая вид искомого топонима. Только для обратного геокодирования. Возможные значения:

  • house — дом;
  • street — улица;
  • metro — станция метро;
  • district — район города;
  • locality — населенный пункт (город/поселок/деревня/село/...).

Подробнее про параметры поиска можно прочитать в справочнике.

Работа с результатами поиска

Для работы с результатами поиска доступны следующие методы:

getResult

Возвращает найденный объект по заданному индексу. Метод работает асинхронно. Он возвращает Promise-объект, который разрешится найденным объектом, либо отклонится с ошибкой:

var searchControl = new ymaps.control.SearchControl({
    options: {
        // Будет производиться поиск только по топонимам.
        provider: 'yandex#map'
    }
});

var result = searchControl.getResult(0);
result.then(function (res) {
    console.log("Результат " + res );
}, function (err) {
    console.log("Ошибка");
});
getResultsArray

Возвращает массив, содержащий все результаты поиска:

var searchControl = new ymaps.control.SearchControl({
    options: {
        // Будет производиться поиск только по топонимам.
        provider: 'yandex#map'
    }
});

// Подписка на событие выбора результата поиска.
searchControl.events.add('resultselect', function (e) {
    // Получает массив результатов.
    var results = searchControl.getResultsArray();
    // Индекс выбранного объекта.
    var selected = e.get('index');
    // Получает координаты выбранного объекта.
    var point = results[selected].geometry.getCoordinates();
})
getResponseMetaData

Возвращает метаданные геопоиска:

var searchControl = new ymaps.control.SearchControl({
    options: {
        // Задает поиск только по топонимам.
        provider: 'yandex#search'
    }
});

searchControl.search('Шоколадница');

searchControl.events.add('resultselect', function (e) {
    var index = e.get('index');
    var results = searchControl.getResponseMetaData();
    console.log(results.SearchRequest.request); // Шоколадница
    console.log(results.SearchRequest.results); // 20
})
getResultsCount

Возвращает количество найденных результатов:

var searchControl = new ymaps.control.SearchControl({
    options: {
        // Задает поиск только по топонимам.
        provider: 'yandex#map'
    }
});

// Подписывается на событие получения результатов поиска с сервера.
searchControl.events.add('load', function (e) {
    var count = searchControl.getResultsCount();
    console.log("Количество найденных результатов поиска: " + count);
})
getSelectedIndex

Возвращает индекс выбранного элемента:

var searchControl = new ymaps.control.SearchControl({
    options: {
        // Будет производиться поиск только по топонимам.
        provider: 'yandex#map'
    }
});

// Подписывается на событие получения результатов поиска с сервера.
searchControl.events.add('resultselect', function (e) {
    var index = searchControl.getSelectedIndex(e);
    console.log("Индекс выбранного элемента: " + index);
})
showResult

Отображает результат на карте:

// Пример всегда показывает первый результат,
// вне зависимости от количества найденных
// объектов на карте.
var searchControl = new ymaps.control.SearchControl({
   options: {
       noSelect: true
   }
});

searchControl.events.add('load', function (event) {
    // Проверяет, что это событие не "дозагрузка" результатов и
    // по запросу найден хотя бы один результат.
    if (!event.get('skip') && searchControl.getResultsCount()) {
        searchControl.showResult(0);
    }
});
hideResult

Скрывает результат, показанный на карте:

var myButton = new ymaps.control.Button("Скрыть результаты");
myButton.events.add('click', function () {
    searchControl.hideResult();
}, this);

myMap.controls.add(myButton, {
    selectOnClick: false
});

Список всех доступных методов приведен в справочнике.

Решение типовых задач

Как искать организации на карте?

Чтобы произвести поиск по организациям нужно указать yandex#search в качестве провайдера поиска.

var searchControl = new ymaps.control.SearchControl({
  options: {
    // Будет производиться поиск и по топонимам, и по организациям.
    provider: 'yandex#search'
  }
});

// Добавляем элемент управления на карту.
myMap.controls.add(searchControl);
searchControl.search('Шоколадница');

В песочнице можно посмотреть интерактивный пример.

Как сделать поиск по своим объектам?

Чтобы выполнить поиск по своим объектам, выполните следующее:

  1. Создайте коллекцию объектов GeoObject и заполните её координатами и названиями нужных объектов:

    // Создает коллекцию.
    myCollection = new ymaps.GeoObjectCollection(),
    // Создает массив с данными.
    myPoints = [
    { coords: [55.77, 37.46], text: 'Трактир' },
    { coords: [55.85, 37.41], text: 'Стадион' },
    { coords: [55.67, 37.24], text: 'Вокзал' }
    ];
    
    // Заполняет коллекцию данными.
    for (var i = 0, l = myPoints.length; i < l; i++) {
    var point = myPoints[i];
    myCollection.add(new ymaps.Placemark(
    point.coords, {
    balloonContentBody: point.text
    }
    ));
    
  2. Добавьте коллекцию на карту:

    myMap.geoObjects.add(myCollection);
    
  3. Создайте собственного провайдера данных для поиска. Провайдер должен реализовывать интерфейс IGeocodeProvider:

    function CustomSearchProvider(points) {
    this.points = points;
    }
    
    // Провайдер ищет по полю text стандартным методом String.ptototype.indexOf.
    CustomSearchProvider.prototype.geocode = function (request, options) {
    var deferred = new ymaps.vow.defer(),
    geoObjects = new ymaps.GeoObjectCollection();
    
    var points = [];
    // Ищет в свойстве text каждого элемента массива.
    for (var i = 0, l = this.points.length; i < l; i++) {
    var point = this.points[i];
    if (point.text.toLowerCase().indexOf(request.toLowerCase()) != -1) {
    points.push(point);
    }
    }
    
    // Добавляет точки в результирующую коллекцию.
    for (var i = 0, l = points.length; i < l; i++) {
    var point = points[i],
    coords = point.coords,
    text = point.text;
    
    geoObjects.add(new ymaps.Placemark(coords, {
    name: text + ' name',
    description: text + ' description',
    balloonContentBody: '<p>' + text + '</p>',
    boundedBy: [coords, coords]
    }));
    }
    
    deferred.resolve({
    // Геообъекты поисковой выдачи.
    geoObjects: geoObjects,
    // Метаинформация ответа.
    metaData: {
    geocoder: {
    // Строка обработанного запроса.
    request: request,
    // Количество найденных результатов.
    found: geoObjects.getLength()
    }
    }
    });
    
    // Возвращает объект-обещание.
    return deferred.promise();
    };
    
  4. Добавьте элемент SearchControl на карту и укажите созданный ранее провайдер с помощью опции provider:

    // Создает экземпляр класса ymaps.control.SearchControl.
    var mySearchControl = new ymaps.control.SearchControl({
    options: {
    // Заменяет стандартный провайдер данных собственным.
    provider: new CustomSearchProvider(myPoints),
    // Скрывает еще одну метку при выборе результата поиска,
    // т.к. метки коллекции myCollection уже добавлены на карту.
    noPlacemark: true,
    resultsPerPage: 5
    }});
    
    myMap.controls.add(mySearchControl);
    

В песочнице доступен интерактивный пример.

Примеры в песочнице