Клуб API Карт

Фильтрация объектов на карте API 2.0

Fry256
18 марта 2013, 23:20

Всем доброго времени суток!

первый раз обращаюсь, поэтому прошу строго не судить. Суть проблемы в следующем, перехожу с Google карт на Яндекс и требуется переделать ajax фильтрацию!

Есть некая база данных с объектами недвижимости, все они нанесены на карту, есть контрольки в виде выпадающих списков чтобы фильтровать объекты по районам города, по адресам и т.д., на каждой контрольке висит событие change которая сериализует данные и отправляет на сервак, получает ответ и загружает в блок, фильтрация по таблице работает отлично, но не могу понять как организовать фильтр по карте...

 

Понять не могу потому, что нигде не могу найти как обратиться к карте вне функции инициализации...

 

Очень прошу подскажите в какую сторону копать или мини кусочек кода, где карта инициализируется, а потом изменяется коллекция в составе карты через jquery

 

Заранее спасибо!

15 комментариев
Подписаться на комментарии к посту
Понять не могу потому, что нигде не могу найти как обратиться к карте вне функции инициализации...


При инициализации карты пишите ее не в локальную переменную, а глобальную. Тогда карта будет доступна из вне.

var myMap;
ymaps.ready(function () {
myMap = new ymaps.Map(……)
……
});


Возможно, Вам поможет этот пример: http://dimik.github.com/ymaps/examples/group-menu/menu03.html
Еще мноого разных примеров здесь: http://ymapsapi.ya.ru/posts.xml?tag=8493598

Спасибо, большое! Думаю пример номер 1 это то, что нужно, буду разбираться по нему!

что-то я совсем подвис на этой теме, может подскажете по конкретному учаску кода?

в общем вот что имеется:

ymaps.ready(function(){

            var myMap = new ymaps.Map("map", {

                    center: [59.93853, 30.313497],

                    zoom: 10,

behaviors: ['default', 'scrollZoom', 'drag']

                })

                myCollection = new ymaps.GeoObjectCollection();

 

           // $('#search_form').submit(function () {

                //var search_query = 'Санкт-Петербург ул. Марата д.12';

 

$('input[name="map"]').each(function(){

var search_query = $(this).val();

 

                ymaps.geocode(search_query, {results: 1}).then(function (res) {

                    //myCollection.removeAll();

                    myCollection = res.geoObjects;

                    myMap.geoObjects.add(myCollection);

                

});

});

 

            myMap.controls

                // Кнопка изменения масштаба

                .add('zoomControl')

                // Список типов карты

                .add('typeSelector')

                // Стандартный набор кнопок

                .add('mapTools');

                //return false;

           // });

  

$('#sort').on('change', function(){

node_alias = $('form').serialize();

node_alias = node_alias+'&ajax=1&action=sort_new_bild';

//alert(node_alias);

var query_src = '/ajax/filter.php';

$.getJSON(

query_src,

node_alias, 

function(data){

$('.cont').html(data.result);

});

});

});



В общем что тут делается: создаю карту, создаю коллекцию, заполняю коллекцию в перебором массива скрытых импутов, карта готова и работает отлично, дальше включаю инструменты карты, тоже все хорошо работает, затем обработчик, который реагирует на изменение в выпадающем списке, отправляет данный по аяксу, далее идет работа php по формированию отсортированного контента и контент возвращается, грузим контент на страницу и в соответствии с ним нужно обновить карту и вот тут вся проблема, как только не пытался, не могу ни удалить коллекцию, ни редактировать, заново создать не выходит... Просто не врубаюсь что не так делаю...

Тут написан бред ))

Вы создали коллекцию:

myCollection = new ymaps.GeoObjectCollection();

Потом, ничего в нее не добавляя, удаляете все из нее

                    //myCollection.removeAll();

Потом зачем-то перезаписываете переменную, указывающую на эту коллекцию и она теперь указывает на другую коллекцию.

Старую коллекцию при этом не удаляете (течет память) 

                    myCollection = res.geoObjects;

                    myMap.geoObjects.add(myCollection);

Вы что хотите сделать то?

ну.... как вы наверное можете заметить когда я удаляю коллекцию, этот код закомментирован, я просто тестировал, я с яндекс картами занимаюсь 2 дня, до этого с гугл работал.

сделать мне нужно элементарное:

1) формируется контент в виде таблицы с адресами, все адреса подхватываем по общему классу и закидываем адреса в коллекцию

2) отображаем коллекцию на карте

3) добавляем в контент элемент  "выпадающий список" в нем районы города

4) в соответствии с выбранным районом отображаются точки на карте из этого района

 

новую таблицу, я формирую без проблем, а обновить данные на карте не выходит...

 

в гугл все решалось проще, я просто заново пробегался по DOM модели, снова считывал все адреса и заново грузил на карту, там нет такого понятия "коллекции"

Посмотрите этот пример

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

нужен механизм перезагрузки коллекции с учетом новых данных в DOM...

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

вы еще хотите геокодировать все эти данные сначала?

да, это обязательно, потому что по задумке данные на сайт могут поступать и от пользователей сайта, а не каждому пользвателю будет удобно вводить широту и долготу, гораздо проще ввести адрес. поэтому геокодирование обязательно...

 

причем в гугл картах все сделанор намного удобнее, у него нет отдельного ready, он работает в составе jquery, обращение элементарное, обновление тоже, яндекс перемудрил, как мне кажется, но яндекс нужен потому что для россии яндекс карты более подробные

У гугла синхронная загрузка, может и удобнее, но вот лучше ли это вопрос.

И в составе jQuery в нем ничего не работает, это совсем разные библиотеки,

хотя бы потому что у гугла свой событийный интерфейс через addDomListener.


В любом случае, - 2 строчки написать это не тянет на "намного удобнее".

Теперь по существу, - ваши проблемы не от плохого знания коллекций и АПИ, а скорее от недостаточных знаний javascript, Вы видимо к пэхапэ больше привыкли.

 

В javascript многое происходит асинхронно и отложенно и от того может казаться что "неправильно" и непривычно.

Соответственно с геокодированием, таже самая проблема.

Вы геокодируете список адресов (это каждый раз новый http-запрос) ответы могут приходить не в том порядке что вы их отправили, и каждый раз их добавляя на карту и перерирая на них ссылку, вы теряете возможность удалить их с карты.

Поэтому тут нужен несколько другой подход.

Вам нужно сначала собрать все что вы хотите прогеокодировать в отдельный массив, затем использовать специальный класс множественного геокодирования,

передать ему массив и получить из него упорядоченную коллекцию, ссылку на которую сохранить в замыкании, и затем при необходимости сделать новый запрос, первым делом удалить эту ссылку с карты через myMap.geoObjects.remove(_ссылка_);

В этой статье есть пример использования

 

Да, вы абсолютно правы, я не фронтендщик, моя специализация серверное программирование, с js имею дело постольку поскольку, а сейчас вот возникла необходимость для проекта вникнуть в вопрос и я увяз... спасибо за терпение к проблеме начинающего=) 

изучу материалы, на который вы дали ссылки, надеюсь это меня прведет к результату!

еще один маленький вопрос.. 

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

Перебрать и удалить.
myMap.geoObjects.each(function (geoObj)     
   myMap.geoObjects.remove(geoObj);
}, this);
   

На всякий случай:
http://api.yandex.ru/maps/doc/jsapi/2.x-stable/ref/reference/map.GeoObjects.xml

в вашем слушае надо сделать так:

создать ссылку на коллекцию

 

var myMap = new ymaps.Map("map", {

        center: [59.93853, 30.313497],

        zoom: 10,

        behaviors: ['default', 'scrollZoom', 'drag']

    }),

    myCollection;

затем проверять ее существование, удалять с карты перед добавлением новой,

и менять ссылку.

 

myCollection && myMap.geoObjects.remove(myCollection);
myMap.geoObjects.add(myCollection = res.geoObjects);

ОГРОМНОЕ СПАСИБО за помощь! Все работает и по срокам  почти не отстал!