[GIS] Failure removing layer in OpenLayers

openlayers-2

I'm adding some layers on a base map using OpenLayers 2. The aim is to create a layer with some features in it and later when user changes his prefered query, some other features need to be shown, so its the same layer but with different features. Therefore, I need to remove the layer and create it again with new features and then show it on the map.

I'm using the following code for defining and adding the layer:

var Selected_Buildings;
Selected_Buildings = new OpenLayers.Layer.Vector("MyLayer",  { eventListeners:{
            'featureselected':function(evt){        
//some actions here
            }, 
            'featureunselected':function(evt){
//some other actions here
            }},
        strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({
                url: "url to php code that runs query and return geo-data in kml format",
                format: new OpenLayers.Format.KML({
                    extractStyles: false,
                    extractAttributes: true,
                    maxDepth: 2})
            }),
                styleMap: new OpenLayers.StyleMap({
                    "default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
                       strokeWidth: 2,
                     strokeColor: "Gold",
                     fillColor: "Gray"
                    }, OpenLayers.Feature.Vector.style["default"])),
                    "select": new OpenLayers.Style({
                     fillColor: "Blue"
                    })
                })
            });

And the code for defining SelectControl:

var selectControl;
selectControl = new OpenLayers.Control.SelectFeature(
                [Selected_Buildings],
                {
                    clickout: true, toggle: false,
                    multiple: false, hover: false
                }
            );
                map.addControl(selectControl);
                selectControl.activate();

and then when user clicks on a button, I try the following code for removing my layer and then again the above code is executed to add new layer:

var mLayers = map.layers;
var remLayers = [];

for (var i=0; i<mLayers.length; i++) {
    if (mLayers[i].name == "MyLayer") {
        remLayers.push(mLayers[i]);
    }
}

for (var i2=0; i2<remLayers.length; i2++) {
    map.removeLayer(remLayers[i2]);
}

map.removeControl(selectControl);

I receive no error, but also the layer is not removed from the base map.

Any suggestion how to solve this problem?

In the above code MyLayer is the name of layer I would like to remove. selectControl is the name of the map control that was created before for the map.

Best Answer

The provided example works if the SelectControl is created with a Layer, not with an array of Layer:

var selectControl;
selectControl = new OpenLayers.Control.SelectFeature(
    Selected_Buildings,
    {
        clickout: true, toggle: false,
        multiple: false, hover: false
    }
 );
 map.addControl(selectControl);
 selectControl.activate();

Final answer

There is an an open bug with the SelectFeature control used on multiple layers: the control creates a "root" layer with a copy of the rendered features, so when you remove a layer from the map, the features are still visible on the map, since you are not removing the "hidden" root layer.

I didn't understand very well your use-case, but I think that there are 2 possible solutions:

  1. You can apply the patch proposed by the link above (it's easier to patch OpenLayers.debug.js, or you can build your own version of OL)
  2. You can use something like the following workaround (I understood that you have multiple kml layers on which you want the user to perform a select, I didn't understand if the user can remove only one of them, or all together....):

var pippo = new OpenLayers.Layer.Vector(...); // Layer1
var pluto = new OpenLayers.Layer.Vector(...); // Layer2
map.addLayers([pippo, pluto]);

// Creates the control on all the layers, activate and add it to the map 
selectControl = new OpenLayers.Control.SelectFeature([pippo, pluto]); 
map.addControl(selectControl);
selectControl.activate()

Then, to remove a layer, remove first the selectControl, then the layer

function removeLayer(layer) {

    // remove the control
    selectControl.deactivate();
    map.removeControl(selectControl);
    selectControl.destroy();

    // remove one layer
    map.removeLayer(pippo);

    // Re-create the control with the other layers or wathever
    selectControl = new OpenLayers.Control.SelectFeature(pluto);
    map.addControl(selectControl);
    selectControl.activate();

}