简体   繁体   中英

Debounce feature selection in OpenLayers

I am working with a map that uses a large set of vector features. In some browsers, there is significant lag when the OpenLayers is handling pointermove events interactions. For example:

function selectOnHover(map, handler, styleFn) {
    var selectMove = new ol.interaction.Select({
        condition: ol.events.condition.pointerMove,
        style: styleFn
    });

    map.addInteraction(selectMove);
    selectMove.on('select', handler);
}

In other situations that handle continuous input (eg handling scroll events) and require significant processing, I would normally debounce the handler for the event - so that significant work is only done when the input has paused (in this case, determining the intersecting features). Is there a way to insert a debounce between browser event dispatch and OpenLayers checking intersections without circumventing OpenLayers interaction handling?

I've tried handling the pointermove/mousemove events directly, debouncing them (redispatching manually created synthetic events) and then using the interaction's condition to handle only the synthetic ones. This worked except that Internet Explorer's synthetic events weren't picked up by OpenLayers.

I'm considering circumventing OpenLayers interaction - for example by using forEachFeatureAtPixel and manually updating the style.

In fact, even using the standard API you can wrap a select interaction into a custom interaction and debounce the handleEvent function:

var app = {};
app.DebounceSelect = function() {
  this.selectInteraction = new ol.interaction.Select({
    condition: ol.events.condition.pointerMove
  });

  var handleEventDebounce = debounce(function(evt) {
    return ol.interaction.Select.handleEvent.call(this.selectInteraction, evt);
  }.bind(this), 100);

  ol.interaction.Interaction.call(this, {
    handleEvent: function(evt) {
        handleEventDebounce(evt);
      // always return true so that other interactions can
      // also process the event
      return true;
    }
  });
};
ol.inherits(app.DebounceSelect, ol.interaction.Interaction);

app.DebounceSelect.prototype.setMap = function(map) {
  this.selectInteraction.setMap(map);
};

var select = new app.DebounceSelect();
map.addInteraction(select);

http://jsfiddle.net/n9nbrye8/3/

For reference an example on how to write custom interactions: http://openlayers.org/en/master/examples/custom-interactions.html

And the documentation for ol.interaction.Select.handleEvent

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM