4

Using OpenLayers 3.9.0. I have two vector layers which are both desplayed on the map and can select any feature with a singleclick var select = new ol.interaction.Select();

Now I need to make it possible to remove selected feature with Del key.

I ended up with creating the folloing function and listener

var deleteFeature = function(e){
    if(e.keyCode == 46 && (select !== null)){
        layer.getSource().removeFeature(select.getFeatures());
    }
};
document.addEventListener('keydown', deleteFeature, false);

but the problem is that I don't know the layer of the selected feature to call the removeFeture method on.

Any suggestions how to find out the layer of the selected feature or another way of removing selected features?

  • I found a workaround which works based on forEachFeatureAtPixel, maybe you can combine that somehow with interaction.getFeatures(). It certainly is not the ideal solution. – chrki Sep 24 '15 at 22:18
1

UPDATED to achieve when layer is within a ol.layer.Group. Now you should pass map reference to method.

http://jsfiddle.net/jonataswalker/r242y7ke/

A method to get ol.layer.Vector from feature you can use like so:

/**
 * This is a workaround.
 * Returns the associated layer.
 * @param {ol.Map} map.
 * @return {ol.layer.Vector} Layer.
 */
ol.Feature.prototype.getLayer = function(map) {
    var this_ = this, layer_, layersToLookFor = [];
    /**
     * Populates array layersToLookFor with only
     * layers that have features
     */
    var check = function(layer){
        var source = layer.getSource();
        if(source instanceof ol.source.Vector){
            var features = source.getFeatures();
            if(features.length > 0){
                layersToLookFor.push({
                    layer: layer,
                    features: features
                });
            }
        }
    };
    //loop through map layers
    map.getLayers().forEach(function(layer){
        if (layer instanceof ol.layer.Group) {
            layer.getLayers().forEach(check);
        } else {
            check(layer);
        }
    });
    layersToLookFor.forEach(function(obj){
        var found = obj.features.some(function(feature){
            return this_ === feature;
        });
        if(found){
            //this is the layer we want
            layer_ = obj.layer;
        }
    });
    return layer_;
};

Then loop through select.getFeatures() and get ol.layer.Vector:

select.getFeatures().forEach(function(feature){
    var layer = feature.getLayer(map);
    //and so on
});

Used here - https://stackoverflow.com/a/31299728/4640499

  • Won't looping throu all layers and features cause a performance issue if there are many layers and many features? Isn't there some built in solution for this? – yaugenka Sep 27 '15 at 15:24
  • No, no built in solution. And it is a cheap looping. – Jonatas Walker Sep 28 '15 at 9:53
  • Thanks @JonatasWalker. Your getlayer function works well. – yaugenka Sep 28 '15 at 12:47
  • For those how are going to use this solution, be aware that after you remove a feature from a source you have to call select.getFeatures().remove(feature); function to remove the feature from the map. – yaugenka Sep 28 '15 at 12:50
  • The method fails if the layer is in a layer group. – yaugenka Oct 2 '15 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.