Pre-selecting an OpenLayers feature prevents easy de-selecting

29 views Asked by At

My application uses OpenLayers 9.1 and no other UI libraries. In short, if I programmatically pre-select a feature, by dispatching a 'select' event on a Select interaction, the interaction then becomes unresponsive to clicks that should clear the selection.

What I'm trying to implement is the ability to specify a Feature via the query string and have it become the sole selected Feature when the map loads. So I handle the map's 'loadend' event and programmatically dispatch a 'select' event on a Select interaction, with one Feature in 'selected' and zero in 'deselected'.

This works. However, I then expect to be able to click a portion of the map with no features and see the selection cleared. This does not happen; the starting feature remains selected. In fact, the 'select' event handler on my Select interaction does not trigger at all.

Oddly, the selection behavior returns to what I expect after I click any feature. Whether it's the starting feature, or any other feature, after it's clicked once, then further clicks on no feature clear the selection as intended.

Also, if I load the application with no starting feature (i.e., no query string), then selection behavior is completely as expected.

Code excerpts follow.

/* Map Setup */
const map = new Map({
  target: 'map'
  , layers: [
    baseLayer
    , casLayer
    , clientsLayer
    , pathsLayer
  ]
  , view: new View({
    projection: MAP_PROJECTION
    , center: CAS_POINT.getCoordinates()
    , zoom: 9
  })
});
/* End Map Setup */

/* Selection Interaction Setup */
const selected = {};
let preSelected;
const actSelect = new Select({
  layers: [clientsLayer, casLayer]
});
actSelect.on('select', function (evt) {
  if (preSelected && !evt.selected.includes(preSelected)) {
    evt.deselected.push(preSelected);
    preSelected = null;
  }
  evt.selected.forEach((feature) => {
    feature.set('isSelected', true);
    feature.setStyle(featureStyleFn);
    selected['C' + feature.get('companyId')] = feature;
  });
  evt.deselected.forEach((feature) => {
    feature.set('isSelected', false);
    feature.setStyle(featureStyleFn);
    delete selected['C' + feature.get('companyId')];
  });
  displayInfobox(selected);
  displayPath(selected);
});
map.addInteraction(actSelect);
/* End Selection Interaction Setup */

/* Select Starting Feature */
if (params && params.get('fid')) {
  const startFeatureID = params.get('fid');
  map.once('loadend', (event) => {
    console.log(map.getInteractions());
    const startFeature = clientsLayer.getSource().forEachFeature((feature) => {
      if ('C' + feature.get('companyId') === startFeatureID) return feature;
    });
    if (startFeature) {
      actSelect.dispatchEvent({
        type: 'select'
        , selected: new Collection([startFeature])
        , deselected: new Collection()
      });
      const centerCoords = olExtent.getCenter(startFeature.getGeometry().getExtent());
      map.getView().setCenter(centerCoords);
      map.getView().setZoom(17);
      preSelected = startFeature;
    }
  });
}
/* End Select Starting Feature */
0

There are 0 answers