Add layer also for programmatically selected features

This commit is contained in:
Andreas Hocevar
2021-12-21 08:23:56 +01:00
parent e5a32f533e
commit 4f7cadd17d
4 changed files with 62 additions and 6 deletions

View File

@@ -664,6 +664,25 @@ class PluggableMap extends BaseObject {
return features;
}
/**
* Get all layers from all layer groups.
* @return {Array<import("./layer/Layer.js").default>} Layers.
*/
getAllLayers() {
const layers = [];
function addLayersFrom(layerGroup) {
layerGroup.forEach(function (layer) {
if (layer instanceof LayerGroup) {
addLayersFrom(layer.getLayers());
} else {
layers.push(layer);
}
});
}
addLayersFrom(this.getLayers());
return layers;
}
/**
* Detect layers that have a color value at a pixel on the viewport, and
* execute a callback with each matching layer. Layers included in the

View File

@@ -6,6 +6,7 @@ import CollectionEventType from '../CollectionEventType.js';
import Event from '../events/Event.js';
import GeometryType from '../geom/GeometryType.js';
import Interaction from './Interaction.js';
import VectorLayer from '../layer/Vector.js';
import {TRUE} from '../functions.js';
import {clear} from '../obj.js';
import {createEditingStyle} from '../style/Style.js';
@@ -308,10 +309,8 @@ class Select extends Interaction {
}
/**
* Returns the associated {@link module:ol/layer/Vector~Vector vectorlayer} of
* the (last) selected feature. Note that this will not work with any
* programmatic method like pushing features to
* {@link module:ol/interaction/Select~Select#getFeatures collection}.
* Returns the associated {@link module:ol/layer/Vector~Vector vector layer} of
* a selected feature.
* @param {import("../Feature.js").FeatureLike} feature Feature
* @return {import('../layer/Vector.js').default} Layer.
* @api
@@ -378,6 +377,24 @@ class Select extends Interaction {
if (this.style_) {
this.applySelectedStyle_(feature);
}
if (!this.getLayer(feature)) {
const layer = /** @type {VectorLayer} */ (
this.getMap()
.getAllLayers()
.find(function (layer) {
if (
layer instanceof VectorLayer &&
layer.getSource() &&
layer.getSource().hasFeature(feature)
) {
return layer;
}
})
);
if (layer) {
this.addFeatureLayerAssociation_(feature, layer);
}
}
}
/**
@@ -475,8 +492,8 @@ class Select extends Interaction {
*/
function (feature, layer) {
if (this.filter_(feature, layer)) {
selected.push(feature);
this.addFeatureLayerAssociation_(feature, layer);
selected.push(feature);
return !this.multi_;
}
}.bind(this),
@@ -511,8 +528,8 @@ class Select extends Interaction {
function (feature, layer) {
if (this.filter_(feature, layer)) {
if ((add || toggle) && !includes(features.getArray(), feature)) {
selected.push(feature);
this.addFeatureLayerAssociation_(feature, layer);
selected.push(feature);
} else if (
(remove || toggle) &&
includes(features.getArray(), feature)

View File

@@ -233,6 +233,19 @@ describe('ol/Map', function () {
});
});
describe('#getAllLayers()', function () {
it('returns all layers, also from inside groups', function () {
const map = new Map({});
const layer = new TileLayer();
const group = new LayerGroup({layers: [layer]});
map.addLayer(group);
const allLayers = map.getAllLayers();
expect(allLayers.length).to.be(1);
expect(allLayers[0]).to.be(layer);
});
});
describe('#setLayers()', function () {
it('adds an array of layers to the map', function () {
const map = new Map({});

View File

@@ -375,6 +375,13 @@ describe('ol.interaction.Select', function () {
// Select again to make sure the style change does not break selection
simulateEvent('singleclick', 10, -20);
});
it('returns a layer from a programmatically selected feature', function () {
const feature = source.getFeatures()[0];
interaction.getFeatures().push(feature);
const layerWithSelectedFeature = interaction.getLayer(feature);
expect(layerWithSelectedFeature).to.equal(layer);
});
});
describe('#setActive()', function () {