[GIS] How to fire a function after all features have been selected by a box in OpenLayers

featuresjavascriptopenlayers-2openstreetmapselect

I have a map rendering with Polygons on a Vector layer set up as features. I set up the features so they fire off a function when the feature is selected and this works fine. The issue I'm having is when I try to allow users to select multiple features using a box. This causes the function to fire for each feature that is selected. I understand why this is, but what I really need is to have a function that fires once all of the features are selected so I can run a function using all selected features instead of having it run once for each.
Here is my selectFeature code:

window[mapName].addControl(control);
                        control.activate();
                        var selectCtrl = new OpenLayers.Control.SelectFeature(layerVector, {
                            clickout: true,
                            onSelect: onFeatureSelect,
                            onUnselect: onFeatureUnselect,
                            box: true
                        });
                        window[mapName].addControl(selectCtrl);
                        selectCtrl.activate();
                    }
                });

It looks like there's away to attach Handlers to Boxes but so far I've been unsuccessful. Also, I'm afraid that if the function runs after the box selection is finished, it might not be getting the full list of selectedFeatures.

Any help would be GREATLY appreciated.
Thanks

Best Answer

You could modify selectBox method of SelectFeature control:

OpenLayers.Control.SelectFeature.prototype.selectBox = function(position) {
if (position instanceof OpenLayers.Bounds) {
    var minXY = this.map.getLonLatFromPixel(
        new OpenLayers.Pixel(position.left, position.bottom)
    );
    var maxXY = this.map.getLonLatFromPixel(
        new OpenLayers.Pixel(position.right, position.top)
    );
    var bounds = new OpenLayers.Bounds(
        minXY.lon, minXY.lat, maxXY.lon, maxXY.lat
    );

    // if multiple is false, first deselect currently selected features
    if (!this.multipleSelect()) {
        this.unselectAll();
    }

    // because we're using a box, we consider we want multiple selection
    var prevMultiple = this.multiple;
    this.multiple = true;
    var layers = this.layers || [this.layer];
    var layer;
    var selectedFeatures = []; // <-- Modification of original function (1/3)
    for(var l=0; l<layers.length; ++l) {
        layer = layers[l];
        for(var i=0, len = layer.features.length; i<len; ++i) {
            var feature = layer.features[i];
            // check if the feature is displayed
            if (!feature.getVisibility()) {
                continue;
            }

            if (this.geometryTypes == null || OpenLayers.Util.indexOf(
                this.geometryTypes, feature.geometry.CLASS_NAME) > -1) {
                    if (bounds.toGeometry().intersects(feature.geometry)) {
                        if (OpenLayers.Util.indexOf(layer.selectedFeatures, feature) == -1) {
                            this.select(feature);
                            selectedFeatures.push(feature); // <-- Modification of original function (2/3)
                        }
                    }
                }
            }
    }
    onFeatureSelect(selectedFeatures); // <-- Modification of original function (3/3)
    this.multiple = prevMultiple;
    }
}

Live example