Openlayers 3 OpenLayers 3中与除Chrome以外的任何浏览器的悬停交互非常缓慢
我有两种交互样式,一种高亮显示功能,另一种放置带有功能名称的工具提示。评论这两个版本时,它们都非常快,不管是哪一个版本,IE和Firefox中的地图应用程序都会变慢,但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
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,无需过滤。