Клуб API Карт

Реализация фильтрации объектов (меню)

Пост в архиве.

Сделал карту, объекты на которой отображаются после выбора в radiobutton и checkbox (не доделал).

Необходимо еще доделать фильтрацию по выбору checkbox.

В IE медленно работает.

Подскажите я изобрел велосипед или проще это не сделать?


 
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=AGXYMUsBAAAA6wVnKQMANms1Kg8VXfDSWapB5NT1DElzOIkAAAAAAAAAAABUMNIMzES0iJtTdIF5KWEmU6z0Cw==" type="text/javascript"></script>

<script src="http://anton.shevchuk.name/wp-demo/jquery-tutorials/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){

var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);

// Установка для карты ее центра и масштаба
map.setCenter(new YMaps.GeoPoint(38.59582,53.321534), 4);

// Добавление элементов управления
map.addControl(new YMaps.TypeControl());
map.addControl(new YMaps.Zoom());
map.addControl(new YMaps.ScaleLine());
map.enableScrollZoom();

//Массивы с фильтрами
var filterCity = ["Россия", "Санкт-Петербург"];
 var filterCitys = ["Ros", "SPb"]; 
var filterType = ["Общественные", "Административные", "Авто", "Жилье", "Медицина", "Промышленность", "Торговля"];
 var filterTypes = ["Общ","Адм","Авт", "Жил", "Мед", "Про", "Тор"]; 

//Массив проектов:
 
var groups = [
createPlacemark(new YMaps.GeoPoint(30.458565,59.877583), "Театр \"Буфф\"", "г. Санкт-Петербург", "Народная ул., д. 1", "проектирование, монтаж", "Общ", "505", "teather"),
createPlacemark(new YMaps.GeoPoint(30.300929,59.932193), "Здание Главного почтамта", "г. Санкт-Петербург", "ул. Почтамтская, д. 9/12", "проектирование, монтаж", "Общ", "533", "buildings"),
createPlacemark(new YMaps.GeoPoint(29.491556,60.18209), "База отдыха", "г. Санкт-Петербург, пос. Смолячково", "Приморское шоссе, д. 679", "проектирование", "Общ", "1768", "camping"),
createPlacemark(new YMaps.GeoPoint(30.220584,59.972929), "Стадион \"Зенит\"", "г. Санкт-Петербург", "Южная дорога, д. 25", "проектирование", "Общ", "2055", "stadium"),
 createPlacemark(new YMaps.GeoPoint(30.283098,59.93676), "Консульство Бразилии", "г. Санкт-Петербург", "8 линия, д. 5, литер А", "проектирование", "Адм", "1568", "buildings"),
createPlacemark(new YMaps.GeoPoint(30.353759,59.958764), "Банк \"Северная Казна\"", "г. Санкт-Петербург", "ул. Академика Лебедева, д.31", "проектирование", "Адм", "1563", "bank"),
createPlacemark(new YMaps.GeoPoint(30.41727,59.914186), "Автосалон \"Рольф\"", "г. Санкт-Петербург", "Октябрьская набережная, д. 6", "проектирование", "Авт", "1339", "car"),
createPlacemark(new YMaps.GeoPoint(30.244973,59.984503), "Автосалон \"МУЛЬТИМОТОРС\"", "г. Санкт-Петербург", "ул. Савушкина, квартал 66 Б северо - приморской части", "проектирование, монтаж", "Авт", "643", "car"),
createPlacemark(new YMaps.GeoPoint(30.222542,59.990264), "Авто-центр \"Lexus\"", "г. Санкт-Петербург", "ул.Школьная, 98", "проектирование, монтаж", "Авт", "689", "car"),
createPlacemark(new YMaps.GeoPoint(30.223297,59.989819), "Авто-центр \"TOYOTA\"", "г. Санкт-Петербург", "ул. Школьная, 96А", "проектирование, монтаж", "Авт", "398", "car"),
createPlacemark(new YMaps.GeoPoint(30.321186,60.051971), "Авто-центр \"MAZDA\"", "г. Санкт-Петербург", "ул. Хошимина, квартал 10", "проектирование, монтаж", "Авт", "1224", "car"),
 createPlacemark(new YMaps.GeoPoint(30.185594, 59.837815), "Детская Больница №1", "г. Санкт-Петербург", "ул. Авангардная, д. 14", "проектирование", "Общ", "", "hospital"),
createPlacemark(new YMaps.GeoPoint(30.312140, 59.910217), "Шоферская медкомиссия", "г. Санкт-Петербург", "наб. Обводного канала, д. 147", "проектирование", "Общ", "", "hospital"),
createPlacemark(new YMaps.GeoPoint(30.273144,60.025637), "Завод \"Эскаро Кемикал АС\"", "г. Санкт-Петербург", "ул. Маршала Новикова, д.28", "проектирование", "Про", "587", "factory"),
createPlacemark(new YMaps.GeoPoint(48.472015,54.316581), "Завод \"Miller\"", "г. Ульяновск", "7-ой Инженерный проезд, д.44", "проектирование", "Про", "1980", "factory"),
createPlacemark(new YMaps.GeoPoint(30.379792,59.808025), "Завод \"Magner\"", "г. Санкт-Петербург, пос. Шушары", "Московское шосcе, участок 7", "проектирование", "Про", "1900", "factory"),
createPlacemark(new YMaps.GeoPoint(30.271716, 60.091931), "Завод \"Ниссан Мануфэкчуринг Рус\"", "г. Санкт-Петербург, пос. Парголово", "земельный участок №3", "проектирование", "Про", "", "factory"),
createPlacemark(new YMaps.GeoPoint(30.273144, 60.025637), "Производство и склад ЛКМ", "г. Санкт-Петербург", "ул. Маршала Новикова, д. 28", "проектирование", "Про", "", "factory"),
createPlacemark(new YMaps.GeoPoint(30.644346, 60.014666), "Производственно-складской комплекс", "Ленинградская обл., г. Всеволожск", "", "проектирование", "Про", "", "factory"),
createPlacemark(new YMaps.GeoPoint(37.348743,44.898349), "Гипермаркет \"Магнит\"", "г. Анапа", "Анапское шоссе, д. 14", "проектирование, монтаж", "Тор", "1587", "magnit"),
createPlacemark(new YMaps.GeoPoint(39.058138,45.025024), "Гипермаркет \"Магнит\"", "г. Краснодар", "ул. Лизы Чайкиной, д. 2/1", "проектирование, монтаж", "Тор", "1582", "magnit"),
createPlacemark(new YMaps.GeoPoint(38.088209,44.553048), "Гипермаркет \"Магнит\"", "г. Геленжик", "ул. Советская, д. 71", "проектирование, монтаж", "Тор", "1745", "magnit"),
createPlacemark(new YMaps.GeoPoint(36.956017,56.198891), "Гипермаркет \"Магнит\"", "Московская обл., г. Солнечногорск,", "ул. Красная, д. 161", "проектирование, монтаж", "Тор", "1583", "magnit"),
  
];

var groups_t = ["Торговля","Торговля","производство","авто"]

var group1 = new YMaps.GeoObjectCollection();
var group2 = new YMaps.GeoObjectCollection();


//for (var i = 0; i < groups.length; i++) {
group1.add(groups);
//$("div[id=test]").append("вот так");
//}

 
//Создание групп по городам и типам
//Общая группа
var groupAll = new YMaps.GeoObjectCollection();
var groupFil = new YMaps.GeoObjectCollection();
//Группа Спб
var groupSpbTorg = new YMaps.GeoObjectCollection()

groupAll.add(groups);

groupAll.forEach(function (obj, objIndex, group) {
if ((groupAll.get(objIndex).metadataproperty == filterTypes[3]) && (groupAll.get(objIndex).description.indexOf('Мос') + 1)) {
groupSpbTorg.add(groupAll.get(objIndex));
$("div[id=test]").append(groupAll.get(0).metadataproperty);
}
});

//Подсчет количества объектов для России и СПб
var r=0;
var s=0;
$("div[id=cityList]").append('<p>Всего объектов на карте:<strong> ' + groupAll.length() + '</strong></p>');
groupAll.forEach(function (obj, objIndex, group) {

if (!(groupAll.get(objIndex).description.indexOf('Санкт-Петербург') + 1)) {

r=r+1;;

}
if ((groupAll.get(objIndex).description.indexOf('Санкт-Петербург') + 1)) {

s=s+1;;

}

});


jQuery.each(filterCity, function(i) {
$("div[id=cityList]").append('<input type="radio" name="City" id="' + filterCitys[i] + '"><label id="' + filterCitys[i] + '">' + this + '</label><br>');
});

//Если выбран пункт "Россия"
$(":radio[id=Ros]").click (function (){

map.setCenter(new YMaps.GeoPoint(38.59582,53.321534), 4);
map.removeAllOverlays();
groupFil.removeAll();
groupAll.forEach(function (obj, objIndex, group) {
if (!(groupAll.get(objIndex).description.indexOf('Санкт-Петербург') + 1)) {

groupFil.add(groupAll.get(objIndex));

}

});

jQuery.each(filterTypes, function(i) {

var j=0;
groupFil.forEach(function (obj, objIndex, group) {

if(groupFil.get(objIndex).metadataproperty == filterTypes[i]) {

j=j+1;

}

});
$("input:checkbox[id=filterTypes[i]] > label").text(filterType[i] + "[" + j + "]");
});

map.addOverlay(groupFil);
});

//Если выбран пункт "Санкт-Петербург"
$("input:radio[id=SPb]").click (function (){

map.setCenter(new YMaps.GeoPoint(30.313497,59.938531), 10);
map.removeAllOverlays();
groupFil.removeAll();
groupAll.forEach(function (obj, objIndex, group) {
if ((groupAll.get(objIndex).description.indexOf('Санкт-Петербург') + 1)) {

groupFil.add(groupAll.get(objIndex));

}

});
map.addOverlay(groupFil);
});

jQuery.each(filterType, function(i) {
$("div[id=typeList]").append('<input type="checkbox" disabled name="Type" id="' + filterTypes[i] + '"><label>' + this + '</label><br>').click (function (){

group1.forEach(function (obj, objIndex, group) {

var i=0;
if (groups_t[objIndex].indexOf("ав") + 1) {
group2.add(groups[objIndex]);
$("div[id=test]").append(group2[i].getStyle);
i=i+1;
}
});
map.addOverlay(group2);
});

return (this != "four"); // will stop running to skip "five"
});


$("input[type=checkbox]").change(function(){
if($(this).is(":checked")){
$("div[id=test]").append("вот так");
}
});

//Добавляем количество объектов по городам
$("label[id=Ros]").append('&nbsp <strong> [' + r + ']</strong>');
$("label[id=SPb]").append('&nbsp <strong> [' + s + ']</strong>');

//Делаем объекты Россия автивными
$(":radio[id=Ros]").click();
 
});

function createPlacemark (point, name, city, address, workType, filtred_, pr_no, pr_type) {

// Создание стиля метки
var s = new YMaps.Style();

s.iconStyle = new YMaps.IconStyle();

if (pr_type == "magnit") {
s.iconStyle.offset = new YMaps.Point(-10, -16);
s.iconStyle.size = new YMaps.Point(19, 16);
  s.iconStyle.href = "http://i070.radikal.ru/0912/90/91a7c1a099b5.png"; 
var placemark = new YMaps.Placemark(point, {style: s});
}
else if (pr_type == "o-key") {
s.iconStyle.offset = new YMaps.Point(-12, -26);
s.iconStyle.size = new YMaps.Point(24, 26);
s.iconStyle.href = "http://s50.radikal.ru/i128/0912/36/f2284c9c7d71.png";
var placemark = new YMaps.Placemark(point, {style: s});
}
else {
var placemark = new YMaps.Placemark(point, {style:"default#"+pr_type+"Icon"});
}

placemark.name = name;
placemark.description = '<p>' + city + '<br>' + address + '<br></p><p><a href="/projects/' + pr_no + '">подробнее...</a></p>' ;
placemark.metadataproperty = filtred_;
return placemark;
}
</script>

<style type="text/css">
div .city_List
{
  border: 0px solid black;
  padding: 5px; 
  margin-bottom: 5px; 
height: 130px;
width: 200px;
}
div .type_List
{
  border: 0px solid black; 
  padding: 5px; 
  margin-bottom: 5px;
height: 130px;
width: 200px;
}
</style>
<table>
<tr><td>
<div id="cityList" class="city_List"></div></td>
<td>
<div id="typeList" class="type_List"></div></td>
</tr>
</table>
<div id="YMapsID" style="width:590px;height:400px"></div>
 

 


11 комментариев
1. Необязательно грузить jQuery. Этот фреймоврк доступен после загрузки API в поле YMaps.jQuery.
2. Взгляните на пример работы с группами. Он может вам помочь:
http://api.yandex.ru/maps/jsapi/doc/dg/tasks/how-to-group-objects.xml

У меня почему-то циклы не работают. Не запускается for и все тут.

Мне бы живой пример как можно было с фильтрами работать.

Допустим есть group, и применить к нему фильтры в зависимости от активных radiobutton и checkbox. В руководстве мало информации.

Опишите более подробно процесс фильтрации, который вы хотите осуществить.

Есть группа объектов и, например, набор флажков.
Что из себя представляет объект? Это обычная метка?
По каким параметрам должна происходить фильтрация?

По поводу "Не запускается for" могу посоветовать отлаживать JavaScript.
http://yandex.ru/yandsearch?text=отладка+JavaScript
Спасибо за участие. Да есть группа объектов в массиве:

createPlacemark(new YMaps.GeoPoint(30.458565,59.877583), "Театр \"Буфф\"", "г. Санкт-Петербург", "Народная ул., д. 1", "проектирование, монтаж", "Общ", "505", "teather"),
По порядку:

0. Координаты метки.
1. Название метки placemark.name и заголовок баллуна.
2 - 4. Используются в формировании описания для баллуна в placemark.description.
5. Тип здания (Общественное, торговое и т.п.) для фильтрации placemark.metadataproperty = filtred_;
6. Порядковый номер объекта. Используется для формирования ссылки на страницу с описанием.
7. Часть наименования стандартного значка объекта, для оформления.

Это обычная метка как в ваших пример, за тем исключением, что я добавил ей атрибут:
placemark.metadataproperty = filtred_;
Он определяет тип обекта для фильтрации с помощью checkbox.

Мысль была такая:
1. Radio-кнопки фильтруют объекты на карте - для этого в placemark.description ищется совпадение со словом "Санкт-Петербург" или его отсутствие.
2. Далее Чекбоксы фильтруют объекты по атрибуту placemark.metadataproperty.
3. При смене Radio-кнопки меняется и набор объектов. При этом желательно, чтоб чекбоксы оставались на местах - т.е тип объектов не менялся.
4. К каждому обозначению чекбокса приписывается поличество объектов в группе, при разной выбранной местности.

Надеюсь не очень путанно.

Похоже, да не то.

В примере сразу происходит группировка по объектам в массиве.

А мне надо, чтоб объекты были в массиве без группировки, а сразу скопом.

А затем уже происходила фильтрация.

Могу посоветовать использовать метод filter(). С помощью него можно будет отобрать объекты по заданным параметрам.

Не совсем понимаю синтаксис работы этого метода.

Можете показать его работу на моем примере?

 Что делает эта строка:

return obj.property == "filter"

 

Это условие. Если поле propery объекта obj (одного из объектов, находящихся в группе) равно "filter", то значит этот объект отбирается (окажется в результирующем массиве, возвращаемой методом filter()), иначе игнорируется.
Т.е. объект (obj) это placemark? Если посмотреть на http://api.yandex.ru/maps/jsapi/doc/ref/reference/placemark.xml . То у него есть поля - description, id, metaDataProperty, name . К ним и следует обращаться?
Вот небольшой пример использования метода filter():
http://rodlex.narod2.ru/search-from-ymapsml.htm?id=2

Если в строке был передан параметр id, то на карте отображается только один объект, а если параметров не было передано, то все объекты.

Поиск осуществляется в загруженном YMapsML-файле.