Клуб API Карт

Удаление всех объектов с карты. Баг removeAll

Пост в архиве.
На карту добавлено несколько меток (Placemark) и ломаная (Polyline).

Вызывая метод map.geoObjects.removeAll удаляется только ломаная, а метки как были так и остались на местах.

В API 1.x помнится был метод  map.removeAllOverlays() работающий безотказно и удаляющий ВСЕ объекты с карты.

В доке же removeAll и у карты и у map.GeoObjects вообще не описан, зато есть простой remove...
Хотите сказать нужно теперь все в цикле удалять по одному объекту?  Какое то некрасивое решение...
20 комментариев

добавьте в группу, после чего можно цеплять\отцеплять от карты одну только группу.

А если мне группа просто не нужна? итак объектов на карте немало, ресурсы не безграничны) браузер к слову хорошо ЦП загружает с API2

У map.geoObjects нет метода removeAll. Как у вас получается удалить с помощью него ломаную я не понимаю, т.к. я получаю
TypeError: Object [object Object] has no method 'removeAll'

Теперь почему нет. Потому, что map.geoObjects используется очень разными компонентами для добавления своих геообъектов. Линейка, маршрутизатор например. Такой метод очень небезопасен.

Вы можете сделать свою коллекцию и добавлять в нее. У коллекций есть removeAll.

 

Алексей Yarrr!
28 января 2016, 03:59

Wish: removeAllGeoObjects ;-)

В смысле? в map.geoObjects нет ничего кроме геообъектов. removeAll, removeAllGeoObjects - одно и то же.

Алексей Yarrr!
28 января 2016, 03:59

Я про Map

Map.removeAllGeoObjects() или Map.removeGeoObjects(function filter() { return Math.rand()>0.5; })

ну это противоречит нашей концепции модульности. Карта ничего о предметной области геообъектов не знает.

У map.geoObjects есть each - через него сделать обработку всех геообъектов не сложно. Можно и удалить, но вы должны понимать, что делаете, т.к. еще раз скажу - это не безопасно.

Алексей Yarrr!
28 января 2016, 03:59

Не с чем спорить даже) Согласен, не нужен он там. Спасибо.

Вообще-то есть: https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/map.GeoObjects.xml

 

А если действительно нет - поправьте документацию.

В 2.1 есть, а 2.0 нет.

Суть в том, что в 2.0 в map.geoObjects добавлялись и служебные геообъекты, такие как линейка например. И вызов romoveAll прибил бы ее в том числе. В 2.1 эти объекты добавляются в другую, служебную коллекцию, а в map.geoObjects добавляются только пользовательские геообъекты.

Алексей Yarrr!
28 января 2016, 03:59

Группа создается в памяти. Там же и живет, никакой проекции в дом дерево (а значит и не становится видимой) не имеет, но имеет ссылку на алгоритм удаления, и список из ссылок на объекты. Неужели вам жалко пару килобайт? CPU от этого не пострадает нисколько, может пару миллисекунд - это ничто, по сравнению с тем, сколько ms это все будет рисоваться.

Я себе сделал специальные функции для очистки.

Предварительно все маркеры помещаются в массив markersArray, а линии в linesArray.

Когда нужно все почистить, вызываю эти две функции.

 

 

function clearOverlays() {

  if (markersArray) {

    for (i in markersArray) {

     map.geoObjects.remove(markersArray[i]);

    }

  }

  markersArray = [];

}

 

function clearLines() {

  if (linesArray) {

    for (i in linesArray) {

     map.geoObjects.remove(linesArray[i]);

    }

  }

  linesArray = [];

}

Виталий С.
28 января 2016, 03:59

А если нужно не удалить, а просто скрыть на время.

Что бы показать, подсветить только одну какую-то конкретную метку к примеру.

 

Раньше у меня работал вот такой код на 1.х

 

 

_this.mapl.removeAllOverlays();_this.mapl.addOverlay(_this.placemarkL[i]);_this.mapl.setCenter(_this.placemarkL[i].getGeoPoint());_this.mapl.setZoom(13);

 

на что его сейчас нужно заменить?

 

Можно выставлять опцию visible = false

всем, что хотим скрыть

myPlacemark.options.set("visible", false);

Виталий С.
28 января 2016, 03:59

Спасибо, решение не плохое.

Сделал так:

_this.clusterer.options.set('visible', false);

_this.placemark[i].options.set('visible', true)

 и вроде как все хорошо, одних махом скрыл все маркеры и показал только нужный

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

Вы в изначальном вопросе ничего про кластер не написали.

Можно удалять метку из кластера, и добавлять ее просто в myMap.geoObjects, а сам кластер скрывать и наоборот

Виталий С.
28 января 2016, 03:59

Спасибо. Вы предложили не плохой способ.

Но остался неясный момент.

Я делаю

_this.clusterer.options.set('visible', false);

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

Виталий С.
28 января 2016, 03:59

Нашел решение, но не очень красивое.

 

Достаточно подвеситься на событие зума. И после каждого зума выполнять такой код:

 

map.clusterer.options.set('visible', true);

map.clusterer.options.set('visible', false);


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

Виталий С.
28 января 2016, 03:59

К сожалению вы не дали ответа на мои вопросы. Пришлось изобретать велосипед. С вашей подскзки.

 

Восспользовался методом removeAll для кластера. И потом в колекцию добавил один маркер.

 

А при восстановлении, удалил этот один маркер removeAll'ом, а кластер опять добавил на карту.

 

Когда на карте более пяти тысячь объектов. Небольшие тормоза присутствуют.

 

В любом случае спасибо за идею.

Извините, видимо закрутился и забыл.

Вполне нормальное решение.

 

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