Openlayers 3 OpenLayers 3中与除Chrome以外的任何浏览器的悬停交互非常缓慢

Openlayers 3 OpenLayers 3中与除Chrome以外的任何浏览器的悬停交互非常缓慢,openlayers-3,Openlayers 3,我有两种交互样式,一种高亮显示功能,另一种放置带有功能名称的工具提示。评论这两个版本时,它们都非常快,不管是哪一个版本,IE和Firefox中的地图应用程序都会变慢,但Chrome不会 map.addInteraction(new ol.interaction.Select({ condition: ol.events.condition.pointerMove, layers: [stationLayer], style: null // this is actuall

我有两种交互样式,一种高亮显示功能,另一种放置带有功能名称的工具提示。评论这两个版本时,它们都非常快,不管是哪一个版本,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多分。这是很多,但不是不合理的,所以我认为。放大以限制视图中的功能肯定会有所帮助。所以我想这是一个功能问题。

这是一个已知的错误,需要更多的调查。您可以在此处跟踪进度:

但是,您可以做一件事来加快速度:从map.forEachFeatureAtPixel返回一个truthy值,以便在找到功能后停止检查:

var feature=map.foreachfeatureAtPixelPixelPixel,functionf{ 如果f.get'type'='station'{ 返回特性; } };
除了@ahocevar的答案之外,一个可能的优化方法是利用select

似乎select交互和mousemove侦听器都在检查同一层上的点击,这是双重工作。每当所选特征集发生更改时,“选择”交互将触发选择事件。您可以收听它,并在选择某些功能时显示弹出窗口,在未选择时隐藏它


假设forEachFeatureAtPixel是占用系统的部分,那么这应该可以将工作量减少一半。

我也遇到了同样的问题,后来通过setInterval解决了这个问题 1每移动一个鼠标到1像素,就会触发一个事件,在停止移动之前,会有一个quee事件,quee将在calback函数中运行,并冻结 2如果您有一个样式困难的对象,画布中显示的所有元素都需要时间来计算它们是否碰到光标

决心: 1.使用设置间隔 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);
}

除了有600个点的图层之外,地图上还有其他矢量图层吗?你在哪个版本的浏览器上遇到过这种情况?操作系统呢?我有一个来自kml的CA层,我不想与之交互,因此在forEachFeatureAtPixel进行检查,以确保它是一个站点功能。现在就这样。Chrome 46.0.2490.71 m,IE 11.0.9600.18059,FF 38.01刚刚更新为41.02,同一版本。Win 7 Professional.你选择一个正确的答案并完成这篇文章怎么样?我很感谢你的帮助,但从技术上说没有解决方案,是吗?如果可能的话,我会放弃那些有用的建议,但我的名声不够好。现在,如果通常的礼仪是标记一个解决方案,即使它不是真的,因为这更像是一个我无法控制的错误,我当然会这么做,但是,天哪,我显然是一个新客户,没有必要对此采取被动的攻击态度。这是有道理的。我一定会密切关注bug跟踪,知道它不只是我一个人。对我来说,这只会发生在一些较大的多边形或线条加载到Firefox Linux时。根据分析,命中检测可能会与lines/Poly发生冲突。解决方法是在这种情况下禁用鼠标悬停,或者使用单击代替鼠标悬停。这很有意义。更新了工具提示内容以在交互的selectEvent上触发。FF中的速度差异不大,但无论哪种方式都有利于简化代码。我发现定义自己的mousehover事件比使用选择交互要好得多,因为我可以检查evt.draging属性并防止调用forEachFeatureAtPixel,这是瓶颈。据我所知,选择交互调用forEachFeatureAtPixel,无需过滤。