Сбой OpenLayers 3 removeLayer?

#javascript #openlayers-3

#javascript #openlayers-3

Вопрос:

Я конвертировал картографическое приложение OpenLayers 2 в OpenLayers 3. Карта состоит из двух групповых слоев (базовых карт и наложений), которые определены в коде Javascript. Однако, когда страница загружается (или обновляется автоматически), она считывает данные из XML-файла и динамически загружает слои объектов на карту.

Эта часть работает нормально. С чем у меня проблема, так это с процедурой, которая, как часть функции автоматического обновления страницы, должна удалять все динамически добавляемые слои.

Мой исходный код:

 function erase_and_reload(){
		console.log("erase_and_reload has fired!");
		map.getLayers().forEach(function(layer){
			console.log("Existing layer that needs to be removed ?:");
			console.log(layer);
			
	  		var name = layer.get('name');
	  		var title = layer.get('title');
	  		console.log("layer name = "   name    "   layer title = "   title);
          
	  		if (name){
	  			console.log("Found layer named = "   name);
	  			console.log("Removing layer named: "   name);
	  			map.removeLayer(layer);
	  		}
	  		
	  		
	  	});

// reload
	read_WW_xml();
}  

(Да, у меня есть журнал консоли.регистрируйте записи здесь, чтобы попытаться разобраться.)

Итак, если я запущу это как есть… запись в журнале «Существующий слой, который необходимо удалить?» записывается 10 раз, указывая мне, что существует 10 слоев. Когда я смотрю на объекты слоя, я вижу базовые карты, наложения и несколько других. Но некоторые другие слои, которые на самом деле имеют свойства «name», полностью отсутствуют.

Но если я выполню это с закомментированной строкой «map.removeLayer (layer)», теперь строка «Существующий слой» записывается 17 раз! Отображаются еще семь объектов слоя!

(К вашему сведению: фраза «title» все еще там, потому что сначала я подумал, что проблема как-то связана со свойством «name», поэтому я временно попытался сопоставить свойство «title» вместо этого … «если заголовок не «Базовые карты» или «наложения», тогда removeLayer. Но это вело себя точно так же.)

Даже если .removeLayer не удается удалить слой, я думаю, я не уверен, почему все это каким-то образом прерывает цикл на 7 итераций… до такой степени, что он даже не записывает первые две консоли.журналы??

Спасибо!

-= Дэйв =-

Комментарии:

1. Вы пытались использовать map.getOverlays().clear(); и map.getLayers().clear(); ?

2. Похоже, что если я сделаю «layer.getSource().clear();»…. но обходите слои с заголовком «Базовые карты» и «Наложения» (который, следовательно, обходит их вложенные слои)… кажется, что это эффективно удаляет объекты из каждого слоя для перерисовки. НО может измениться, будет ли необходим данный динамически загружаемый слой при следующем обновлении страницы. Итак, если я запускаю эту штуку в течение нескольких дней, может произойти накопление ненужных слоев. Я бы хотел, чтобы removeLayer работал!

Ответ №1:

На самом деле это не прерывает эти 7 итераций, это просто пропускает эти элементы массива.

В вашем цикле forEach есть массив ссылок на слои карты. Если вы берете элемент этого массива (ссылка «layer») и удаляете его с карты как есть, вы удаляете ссылку, поэтому ее больше нет ни на карте, ни в вашем массиве, и случайно в этом индексе есть другая ссылка.

Итак, если у вас есть массив:

0: layer0, имя «layer0»

1: layer1, имя «layer1»

2: layer2

после этого forEach останется

0: layer1, имя «layer1»

1: layer2

потому что после удаления layer0 в индексе 0 есть layer1, и после этого forEach перемещается (к индексу 1), где он уже находит слой без имени.

Чтобы решить эту проблему, просто используйте функции getArray() и slice() (для дублирования ссылочного массива), что-то вроде этого:

 var refArray = map.getLayers().getArray().slice();
ref.forEach(function(layer)
{
  //your stuff
}
  

Комментарии:

1. Похоже, это работает! Большое спасибо за объяснение!

Ответ №2:

Вы могли бы попробовать

 function erase_and_reload(){
   map.getOverlays().clear();
   map.getLayers().clear();

   // reload
   read_WW_xml();
}
  

Комментарии:

1. Ну, я бы предпочел не тратить ресурсы на перерисовку базовой группы слоев карты и группы слоев наложений. Это не изменится. map.getLayers().clear(), похоже, стирает все слои… все….