我有两种交互方式,一种突出显示功能,第二种是使用功能名称的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多分。这是很多,但不是不合理,所以我会想。放大以限制视图中的功能肯定有帮助。所以我想这是一个功能问题。答案 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);
}