Клуб API Карт

Не могу сделать фильтр меток

red@serdi.ru
6 ноября, 20:00

Есть готовый код пытаюсь в него вставить фильтр , но ничего не выходит. Данные формируются geoObjects = [] как сделать самый простой фильтр не пойму

<script type="text/javascript">
	ymaps.ready(init);
	var myMap2, 
		myPlacemark,
		default_coord = [44.131553, 43.450316],
		default_zoom = 12;

	function init(){ 
		myMap2 = new ymaps.Map("map", {
			center: default_coord,
			zoom: default_zoom,
			controls: ["typeSelector", "zoomControl", "fullscreenControl"]
		}, {
			buttonMaxWidth: 150
		}); 
		
		myMap2.geoObjects.options.set({balloonAutoPanMargin: [70, 0, 0, 0]});
		
		clusterer = new ymaps.Clusterer({
			zoomMargin: 50
		}),

		
		 
mapData = [{"num":"8","adres":"\u041f\u0440\u0438\u0432\u043e\u043b\u044c\u043d\u0430\u044f 25 \u043a\u0430\u043c\u0435\u0440\u0430 8","stream":"https:\/\/cam.serdi.ru\/Privolbnaya_25_8\/index.m3u8","access":"","coord":["44.140102090298","43.451210393182"],"available":true,"metka":"facetime-video","typeObgect":"\u041f\u0440\u0438\u0432\u043e\u043b\"},..еще код..}],        geoObjects = [];
		
		var i = 0;
		$(mapData).each(function(){
			var color;
			
			if(this.access){
				color = "gray";
			} else if(!this.available){
				color = "red";
			} else {
				color = "blue";
			}

			geoObjects[i] = new ymaps.Placemark([this.coord[0], this.coord[1]], {
       
                             balloonContentSize: [270, 99], // размер нашего кастомного балуна в пикселях
	balloonLayout: "default#imageWithContent", // указываем что содержимое балуна кастомная херь
	balloonImageHref: '/files/markers/wifiufanet.png', // Картинка заднего фона балуна
				balloonContent: this.num, 
				hintContent: this.adres
            }, {
				   preset: 'islands#glyphIcon', 
      iconGlyph: this.metka,
      iconGlyphColor: color,
                              
                                iconColor: color,
				stream: this.stream,
				adres: this.adres,
				access: this.access,
				available: this.available
			});
			i++;
		});
		
		myMap2.geoObjects.events.add('balloonopen', function (e) {
            var stream = e.get('target').options.get("stream"),
				adres = e.get('target').options.get("adres"),
				access = e.get('target').options.get("access"),
				available = e.get('target').options.get("available");
				
			var content;
			if(access){
				content = '<h3>'+adres+'</h3><p>Доступ к камере ограничен</p>';
				e.get('target').properties.set("balloonContent", content);
			} else if(!available){ 
				content = '<h3>'+adres+'</h3><p>Извините данная камера не доступна, ведутся работы по восстановлению доступа</p>';
				e.get('target').properties.set("balloonContent", content);
			} else {
				content = '<h3>'+adres+'</h3><div id="fpplayer" style="width:400px;height:250px"></div>';
	 
				e.get('target').properties.set("balloonContent", content);
				
				flowplayer("#fpplayer", {
					clip: { sources: [
						{ type: 'application/x-mpegurl', src: stream, suffix: 'm3u8' }
					]
					},
					autoplay: true,
					live: true,
					embed: false,
					facebook: false
				}).play();
			}

        });

		clusterer.add(geoObjects);
		myMap2.geoObjects.add(clusterer);


  var listBoxItems = ['параметр1', 'параметр2']
        .map(function(title) {
            return new ymaps.control.ListBoxItem({
                data: {
                    content: title
                },
                state: {
                    selected: true
                }
            })
        }),
        // Теперь создадим список, содержащий 5 пунктов.
        listBoxControl = new ymaps.control.ListBox({
            data: {
                content: 'Фильтр',
                title: 'Фильтр'
            },
            items: listBoxItems,
            state: {
                // Признак, развернут ли список.
                expanded: true,
                filters: listBoxItems.reduce(function(filters, filter) {
                    filters[filter.data.get('content')] = filter.isSelected();
                    return filters;
                }, {})
            }
        });
    myMap2.controls.add(listBoxControl);

    // Добавим отслеживание изменения признака, выбран ли пункт списка.
    listBoxControl.events.add(['select', 'deselect'], function(e) {
        var listBoxItem = e.get('target');
        var filters = ymaps.util.extend({}, listBoxControl.state.get('filters'));
        filters[listBoxItem.data.get('content')] = listBoxItem.isSelected();
        listBoxControl.state.set('filters', filters);
    });

    var filterMonitor = new ymaps.Monitor(listBoxControl.state);
    filterMonitor.add('filters', function(filters) {
        // Применим фильтр.
        myMap2.geoObjects.setFilter(getFilterFunction(filters));
    });

    function getFilterFunction(categories){
        return function(obj){
            var content = obj.properties.typeObgect;
            return categories[content]
        }
    }
		
		myMap2.setBounds(myMap2.geoObjects.getBounds(), {
			zoomMargin: [60, 0, 0, 0],
			checkZoomRange:true
		});

		$("#filter_map_block_wrap #filter button").click(function(){
			var cur = $(this);
			if(cur.data("type")=="all"){
				myMap2.setBounds(myMap2.geoObjects.getBounds(), {
					zoomMargin: [60, 0, 0, 0],
					checkZoomRange:true
				});
			} else {
				myMap2.panTo([cur.data("c1"), cur.data("c2")], {
					flying: 1
				}).then(function () {
					myMap2.setZoom(cur.data("z")); 
				});
			}
		});

	}



	$(function(){
		$("#filter_map_block_wrap #filter button").click(function(){
			$("#filter_map_block_wrap #filter button").removeClass("active");
			$(this).addClass("active");
		});
	});
</script>
	

12 комментариев
Эта фильтрация из примера про ObjectManager, она не будет работать с геоколлекциями или кластеризатором, у них нет метода setFilter
dimik,
а как быть тогда, что применить?
red@serdi.ru,
В случае с кластеризатором – удалять старый кластеризатор, фильтровать исходные данные (массив geoObjects) и добавлять новый кластеризатор с новыми данными
dimik,
Примеров нет ни каких?
red@serdi.ru,
Вы можете использовать ObjectManager с опцией clusterize: true, вместо кластеризатора, как в оригинальном примере


https://tech.yandex.ru/maps/jsbox/2.1/object_manager_filter
dimik,
попробовала ObjectManager с опцией clusterize  я так поняла мне нужно изменить формирование Mapdata, с тем что сейчас не работает, если подставляю из примера все хорошо.
 Есть еще вопросы. У меня цвет маркеров задается в зависимости от свойства  access   и  в content  добавляется разный текст, вот как их передать пока не пойму в ObjectManager




сейчас  в коде есть такой фрагмент 
var i = 0;
$(mapData).each(function(){
var color;

if(this.access){
color = "gray";
} else if(!this.available){
color = "red";
} else {
color = "blue";
}
geoObjects[i] = new ymaps.Placemark([this.coord[0], this.coord[1]], { .....
...




то что он в конце формирует, не отображается если я ставлю 
objectManager.add(geoObjects);








Я у себя фильтрацию коллекций сделал следующим образом:

var my_filters = {};for (var i = 0; i < courier.length; i++){
listBoxItems[i+1] = new ym.control.ListBoxItem({
data: {
content: urldecode(courier[i].name),
id: urldecode(courier[i].id)
},
state: {
selected: true
}
});
my_filters[courier[i].id] = true;
}
listBoxControl = new ym.control.ListBox({
data: {
content: 'Курьеры',
title: 'Курьеры'
},
items: listBoxItems,
state: {
// Признак, развернут ли список.
expanded: true,
filters: listBoxItems.reduce(function(filters, filter) {
filters[filter.data.get('id')] = filter.isSelected();
return filters;
},{})
}
});

myMap.controls.add(listBoxControl);
listBoxControl.events.add(['select', 'deselect'], function(e) {
var listBoxItem = e.get('target');
my_filters = ym.util.extend({}, listBoxControl.state.get('filters'));
my_filters[listBoxItem.data.get('id')] = listBoxItem.isSelected();
listBoxControl.state.set('filters', my_filters);
});
var filterMonitor = new ymaps.Monitor(listBoxControl.state);
filterMonitor.add('filters', function(filters) {
AddRemoveCollections(filters)
});


function AddRemoveCollections(filters) {
for (courier_id in arrayMyCollection) {
if (my_filters[courier_id] && arrayMyCollection[courier_id].getMap() === null){
myMap.geoObjects.add(arrayMyCollection[courier_id]);
}
if (!my_filters[courier_id] && arrayMyCollection[courier_id].getMap() !== null){
myMap.geoObjects.remove(arrayMyCollection[courier_id]);
}
}
}
Пробовала сделать так https://jsfiddle.net/fhd6gy3g/8/  знаний не хватает
red@serdi.ru,
Да тут вроде и знаний особых не надо. Фильтрация гео-объектов подробно расписано в песочнице. Единственно, что не гибкие они в отличии от коллекций...
iKest,
 у меня  там кластеры.
red@serdi.ru,
А какая разница?
iKest,
я не пойму как данные берутся из данной переменной

mapData = [{"num":"8","adres":"\u041f\u0440\u0438\u0432\u043e\u043b\u044c\u043d\u0430\u044f 25 \u043a\u0430\u043c\u0435\u0440\u0430 8","stream":"https:\/\/cam.serdi.ru\/Privolbnaya_25_8\/index.m3u8","access":"","coord":["44.140102090298","43.451210393182"],"available":true,"metka":"facetime-video","typeObgect":"\u041f\u0440\u0438\u0432\u043e\u043b\"},..еще код..}], geoObjects = [];


их формирует битрикс из компонента, в типовых api яндекса  мар data.json.