Как осуществить поиск по своим объектам и по геокодеру?
Имеется карта со списком своих объектов, добавил туда поиск по своим объектам. Теперь встала задача осуществлять поиск не только по своим объектам но и по улицам "yandex#map" одновременно, но никак не могу понять как это осуществить. Если руками изменять провайдер, то все работает, как то нужно сделать так что бы он сам его подменял если поиск по своему провайдеру ничего не нашел.
Я пытался сделать это вот такой функцией:
searchControl.events.add('state', function (event) {
if (event.get('found') == 0) {
searchControl.options.set('provider', 'yandex#map');
} else {
searchControl.options.set('provider', 'new CustomSearchProvider(myPoints)');
}
});
но ничего не вышло, видимо где то ошибся.
Вот код карты:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Многоугольник</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=3261ce08-c60a-4114-96f8-ce820abf124a" type="text/javascript"></script>
<script type="text/javascript">
ymaps.ready(init);
function init() {
// Создаем список (массив) подсказок
var podskazki = [
"ТОС «Виктория»",
"ТОС «Максимум Света»",
];
// выполняем поиск по подсказкам
var find = function (podskazki, find) {
return podskazki.filter(function (value) {
return (value + "").toLowerCase().indexOf(find.toLowerCase()) != -1;
});
};
// создаем провайдер поиска
var myProvider = {
suggest: function (request, options) {
var res = find(podskazki, request),
arrayResult = [5],
results = Math.min(options.results, res.length);
for (var i = 0; i < results; i++) {
arrayResult.push({displayName: res[i], value: res[i]})
}
return ymaps.vow.resolve(arrayResult);
}
}
// Создание подсказок в поиске
var suggestView = new ymaps.SuggestView('poisk', {
provider: myProvider,
noSuggestPanel: false,
boundedBy: [[48.61, 134.98], [48.31, 135.29]],
strictBounds: true,
results: 19
});
// поиск по выбору подсказки
suggestView.events.add('select', function () {
Search()
})
// поиск по Enter
$("#poisk").keyup(function(event){
if(event.keyCode == 13){
Search()
}
});
// поиск по нажатию "лупы"
$('.custom-search').click(() => {
if ($('#poisk').val() != undefined) {
Search()
}
});
// Непосредственно поиск в панели
function Search () {
var request = $('#poisk').val();
searchControl.search(request);
}
// Создание экземпляра карты и его привязка к контейнеру с заданным id ("map")
var myMap = new ymaps.Map('map', {
center: [48.48, 135.08],
zoom: 14,
controls: ['zoomControl', 'typeSelector', 'fullscreenControl', 'searchControl'] // "Элементы управления (Зум, слои, фулскрин, поиск)
},
{ // Ограничение области карты Хабаровск + загород
restrictMapArea: [[48.61, 134.98], [48.31, 135.29]],
// Ограничение зума
minZoom: 10,
maxZoom: 17
}) ,
// Создание полигонов и добавление их на карту.
myObjects = ymaps.geoQuery({
type: "FeatureCollection",
features: [
{
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [[ [ 48.4872099152, 135.044750889 ], [ 48.4865858624, 135.045233687 ], [ 48.4863005786, 135.044150075 ], [ 48.4869567290, 135.043726286 ], [ 48.4872099152, 135.044750889 ] ]]
},
options: {
fillColor: '00bfbf', // Цвет заливки
fillOpacity: 0.45, // Прозрачность заливки
strokeColor: 'ff007f', // Цвет обводки
strokeWidth: 2, // Толщина обводки
strokeOpacity: 0.5, // Прозрачность обводки
fildColor: "Кировский", // Кластер объекта
filtColor: "2020" // Год объекта
},
// Содержимое балуна
properties: {
balloonContentHeader: '<a href="https://khv27.ru/projects/territorialnoe-obshchestvennoe-samoupravlenie/reestr-tos/index.php?ELEMENT_ID=106497">ТОС «Виктория»</a>', // Заголовок
balloonContent: '<b>Председатель: </b>' + 'Савинов Е.А.<br/>' + '<b>Адрес: </b>' + 'ул. Казачья гора, дом 9-7<br/>' + '<b>Район: </b>' + 'Кировский<br/>' + '<b>Дата создания: </b>' + '10 февраля 2020<br/>' + '<b>Реализованные проекты: </b>' + 'НОВЫЙ ДВОР 2021<br/>', // Содержимое
balloonContentFooter: 'Телефон: </b>' + '409144', // Футер
hintContent: "ТОС «Виктория»" // Подсказка объекта
}
},
{
type: 'Feature',
geometry: {
type: 'Polygon',
coordinates: [[ [ 48.5213356048, 135.106362622 ], [ 48.5206620838, 135.107070725 ], [ 48.5214817114, 135.108052414 ], [ 48.5216670166, 135.107526701 ], [ 48.5215850548, 135.106754225 ], [ 48.5214638935, 135.106566470 ], [ 48.5213356048, 135.106362622 ]]]
},
options: {
fillColor: '00bf00', // Цвет заливки
fillOpacity: 0.45, // Прозрачность заливки
strokeColor: 'ff007f', // Цвет обводки
strokeWidth: 2, // Толщина обводки
strokeOpacity: 0.5, // Прозрачность обводки
fildColor: "Железнодорожный", // Кластер объекта
filtColor: "2020" // Год объекта
},
// Содержимое балуна
properties: {
balloonContentHeader: '<a href="https://khv27.ru/projects/territorialnoe-obshchestvennoe-samoupravlenie/reestr-tos/index.php?ELEMENT_ID=106500">ТОС «Максимум Света»</a>', // Заголовок
balloonContent: '<b>Председатель: </b>' + 'Сергеев М.С.<br/>' + '<b>Адрес: </b>' + 'пер. Краснодарский, дом 19а<br/>' + '<b>Район: </b>' + 'Железнодорожный<br/>' + '<b>Дата создания: </b>' + '11 февраля 2020<br/>' + '<b>Реализованные проекты: </b>' + 'Спортивная площадка<br/>', // Содержимое
balloonContentFooter: 'Телефон: </b>' + '+7 (4212) 40-91-42', // Футер
hintContent: "ТОС «Максимум Света»" // Подсказка объекта
}
},
]
}).addToMap(myMap);
// Создаем коллекцию для поиска по названию объектов
myCollection = new ymaps.GeoObjectCollection(),
// Создаем массив с данными.
myPoints = [
{ coords: [48.4872099152, 135.044750889], text: 'ТОС «Виктория»' },
{ coords: [48.5213356048, 135.106362622], text: 'ТОС «Максимум Света»' },
];
// создание поисковой строки
searchControl = myMap.controls.get('searchControl');
// настройка поисковой строки Яндекса
searchControl.options.set(
{
provider: new CustomSearchProvider(myPoints),
noPlacemark: true,
placeholderContent: 'Введите адввврес ТОСа',
boundedBy: [[48.61, 134.98], [48.31, 135.29]],
strictBounds: true,
results: 10, // требуемое количество результатов
resultsPerPage: 5,
position: {
left: -400 // смещение строки поиска
}
}
);
// Проверим попадание результата поиска в один из ТОСов.
searchControl.events.add('resultshow', function (e) {
highlightResult(searchControl.getResultsArray()[e.get('index')]);
});
// Сохраняем координаты переданного объекта и находим полигон.
function highlightResult(obj) {
// Сохраняем координаты переданного объекта.
var coords = obj.geometry.getCoordinates(),
// Находим полигон, в который входят переданные координаты.
polygon = myObjects.searchContaining(coords).get(0);
if (polygon) {
polygon.options.set('fillOpacity', 0.2);
polygon.balloon.open();
}
}
// Провайдер данных осуществляет поиск геообъектов по массиву points.
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(),
// Сколько результатов нужно пропустить.
offset = options.skip || 0,
// Количество возвращаемых результатов.
limit = options.results || 20;
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);
}
}
// При формировании ответа можно учитывать offset и limit.
points = points.splice(offset, limit);
// Добавляем точки в результирующую коллекцию.
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 + '',
description: text + 'description',
boundedBy: [coords, coords]
}));
}
deferred.resolve({
// Геообъекты поисковой выдачи.
geoObjects: geoObjects,
// Метаинформация ответа.
metaData: {
geocoder: {
// Строка обработанного запроса.
request: request,
// Количество найденных результатов.
found: geoObjects.getLength(),
// Количество возвращенных результатов.
results: limit,
// Начинает поиск сразу после нажатия Энтер
skip: offset
}
}
});
// Возвращаем объект-обещание.
return deferred.promise();
searchControl.events.add('load', function (event) { // Проверяем, что это событие не "дозагрузки" результатов и по запросу найден хотя бы один результат.
if (!event.get('skip') && searchControl.getResultsCount()) {
searchControl.showResult(0);
}
});
}
}
</script>
<style>
html,
body,
#map {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div class="search">
<input type="text" id="poisk" placeholder="Введите название ТОСа" autocomplete="off" style="margin-right: 0px;">
<div class="custom-search">
</div>
</div>
<div id="map"></div>
</body>
</html>