OpenLayers 3中除了Chrome之外的任何浏览器都有非常缓慢的悬停交互

时间:2015-10-20 20:19:19

标签: openlayers-3

我有两种交互方式,一种突出显示功能,第二种是使用功能名称的tooltop。评论两者,它们非常快,留下,地图应用程序在IE和Firefox(但不是Chrome)中减慢。

map.addInteraction(new ol.interaction.Select({
    condition: ol.events.condition.pointerMove,
    layers: [stationLayer],
    style: null // this is actually a style function but even as null it slows
}));

$(map.getViewport()).on('mousemove', function(evt) {
    if(!dragging) {
        var pixel = map.getEventPixel(evt.originalEvent);
        var feature = null;
        // this block directly below is the offending function, comment it out and it works fine
        map.forEachFeatureAtPixel(pixel, function(f, l) {
            if(f.get("type") === "station") {
                feature = f;
            }
        });
        // commenting out just below (getting the feature but doing nothing with it, still slow
        if(feature) {
            target.css("cursor", "pointer");
            $("#FeatureTooltip").html(feature.get("name"))
              .css({
                top: pixel[1]-10,
                left: pixel[0]+15
              }).show();
        } else {
            target.css("cursor", "");
            $("#FeatureTooltip").hide();
        }
    }
});

我的意思是这似乎是OpenLayers-3的一个问题,但我只是想确定我没有在这里忽略别的东西。

噢,是的,大约有600多分。这是很多,但不是不合理,所以我会想。放大以限制视图中的功能肯定有帮助。所以我想这是一个功能问题。

3 个答案:

答案 0 :(得分:3)

这是一个已知的错误,需要更多调查。您可以在此处跟踪进度:https://github.com/openlayers/ol3/issues/4232

但是,有一件事可以让事情变得更快:从map.forEachFeatureAtPixel返回一个真值,一旦找到一个就停止检查功能:

var feature = map.forEachFeatureAtPixel(pixel, function(f) {
  if (f.get('type') == 'station') {
    return feature;
  }
});

答案 1 :(得分:0)

除了@ ahocevar的答案之外,可能的优化是使用选择interaction's select event

看来,选择互动和你的mousemove听众都在检查同一层上的点击,做双重工作。每当所选要素集更改时,选择交互将触发select事件。您可以收听它,并在选择某个功能时显示弹出窗口,并在没有时隐藏它。

假设forEachFeatureAtPixel正在占用系统,那么这应该会减少一半的工作量。

答案 2 :(得分:0)

我有同样的问题,通过setInterval解决了一个问题,稍后会讨论这个问题 1)每个鼠标移动到1个像素点火事件,你将有一个事件的quee直到你停止移动,并且quee将以calback函数运行,并冻结 2)如果你有一个样式很难的对象,画布中显示的所有元素都需要时间来计算它们是否击中了光标

解析:  1.使用setInterval  2.检查从预览中移动的像素大小,如果小于N,则返回  3.对于多个样式的图层,尝试通过划分为多个样式来简化它们,并且只允许一个图层通过交互移动光标

function mouseMove(evt) {
  clearTimeout(mm.sheduled);
  function squareDist(coord1, coord2) {
    var dx = coord1[0] - coord2[0];
    var dy = coord1[1] - coord2[1];
    return dx * dx + dy * dy;
  }

  if (mm.isActive === false) {
    map.unByKey(mm.listener);
    return;
  }

  //shedules FIFO, last pixel processed after 200msec last process
  const elapsed = (performance.now() - mm.finishTime);

  const pixel = evt.pixel;
  const distance = squareDist(mm.lastP, pixel);
  if (distance > 0) {
    mm.lastP = pixel;
    mm.finishTime = performance.now();
    mm.sheduled = setTimeout(function () {
      mouseMove(evt);
    }, MIN_ELAPSE_MSEC);
    return;
  } else if (elapsed < MIN_ELAPSE_MSEC || mm.working === true) {
    // console.log(`distance = ${distance} and elapsed = ${elapsed} mesc , it never should happen`);
    mm.sheduled = setTimeout(function () {
      mouseMove(evt);
    }, MIN_ELAPSE_MSEC);
    return;
  }

  //while multithreading is not working on browsers, this flag is unusable
  mm.working = true;
  let t = performance.now();
  //region drag map
  const vStyle = map.getViewport().style;
  vStyle.cursor = 'default';

  if (evt.dragging) {
    vStyle.cursor = 'grabbing';
  }//endregion
  else {
    //todo replace calback with cursor=wait,cursor=busy
    UtGeo.doInCallback(function () {
      checkPixel(pixel);
    });
  }
  mm.finishTime = performance.now();

  mm.working = false;
  console.log('mm finished', performance.now() - t);
}