Использую RemoteObjectManager с серверной кластеризацией с
версией АПИ 2.1.47.
Все казалось-бы хорошо, но... Мне необходимо выполнять некоторые
манипуляции с объектами в видимой части карты.
И если с метками проблем нет, то с кластерами сгенерированными на
сервере начинаются проблемы:
ymaps.geoQuery(objectManager.clusters) хоть и срабатывает
без ошибок и даже что-то возвращает, но вызов searchIntersect()
у GeoQueryResult приводит к ошибке.
Оно и не мудрено, ибо объекты кластеров в GeoQueryResult по сути
никак не изменились по сравнению с тем, как они пришли из ajax.
В них нет никаких дополнительных методов, в отличие от Feature,
которые преобразовываются в Placemark.
И судя по всему GeoQueryResult тоже не готов к такому повороту событий.
Вот пример описания кластера из Ajax:
{
type: "Cluster",
bbox: [[43.58473777771, 39.728579521179], [43.584780693054, 39.728622436523]],
geometry: {type: "Point", coordinates: [43.58478, 39.728595]},
properties: {id: "szsrbn37x", iconContent: 2}
}
В теории objectManager.clusters должен быть коллекцией содержащей
элементы типа ClusterPlacemark, но увы, там Object полученный из json.
Получить Overlay для кластеров так-же не удается,
objectManager.clusters.overlays выдает пустую коллекцию.
Для того, чтобы отлавливать момент окончания загрузки очередного
тайла пришлось сделать своего наследника от RemoteObjectManager:
ymaps.modules.define('objectManager.component.ReloadOnZoomChangeControllerWithEvents', [
'util.defineClass',
'objectManager.component.ReloadOnZoomChangeController'
], function (provide, defineClass, ReloadOnZoomChangeController) {
var ReloadOnZoomChangeControllerWithEvents = function (remoteObjectManager) {
ReloadOnZoomChangeControllerWithEvents.superclass.constructor.call(this, remoteObjectManager);
};
defineClass(ReloadOnZoomChangeControllerWithEvents, ReloadOnZoomChangeController, {
loadData: function (tilesArray) {
// отправляем событие начала загрузки данных
this.events.fire('dataloadbefore');
ReloadOnZoomChangeControllerWithEvents.superclass.loadData.call(this, tilesArray);
},
onDataLoad: function (tilesArray, data) {
ReloadOnZoomChangeControllerWithEvents.superclass.onDataLoad.call(this, tilesArray, data);
// отправляем событие окончания загрузки данных
this.events.fire('dataloadafter');
}
});
provide(ReloadOnZoomChangeControllerWithEvents);
});
defineClass(MyRemoteObjectManager, RemoteObjectManager, {
_setupDataLoadController: function () {
// т.к. на событие подписываемся уже после инициализации ReloadOnZoomChangeControllerWithEvents
// то первое событие dataloadbefore мы уже не успеваем поймать, поэтому вызываем его вручную
this._onDataLoadBefore();
// указываем наш новый загрузчик, который может генерировать нужные события загрузки данных
this._dataLoadController = new ReloadOnZoomChangeControllerWithEvents(this);
this._dataLoadControllerListener = this._dataLoadController.events.group()
.add('statechange', this._onDataLoadControllerStateChange, this)
.add('pixelboundschange', this._onDataLoadControllerBoundsChange, this)
// будем просто забирать себе эти новые события загрузки данных
.add('dataloadbefore', this._onDataLoadBefore, this)
.add('dataloadafter', this._onDataLoadAfter, this);
},
_onDataLoadBefore: function () {
// просто перегенерируем событие как свое
this.events.fire('dataloadbefore');
},
_onDataLoadAfter: function () {
// просто перегенерируем событие как свое
this.events.fire('dataloadafter');
}
});
И все описанные выше манипуляции выполнялись в событии dataloadafter.
Существует-ли какой-то работающий метод получения списка серверных кластеров
в видимой области карты?