2015-10-20 48 views
3

我有兩種交互風格,一種突出顯示此功能,另一種突出顯示此功能,第二種顯示特徵名稱爲tooltop。評論都出來了,它們非常快,離開,地圖應用程序在IE和Firefox(但不是Chrome)中變慢。使用任何瀏覽器在OpenLayers 3中進行非常緩慢的懸停交互除了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

地圖上的任何其他矢量圖層都比600點的圖層還要多嗎? –

+0

您遇到過哪些版本的瀏覽器?和操作系統? –

+0

我有一個CA縣的層(從kml),我不想交互(因此在forEachFeatureAtPixel檢查,以確保它是一個站功能)。現在就是這樣。 Chrome 46.0.2490.71 m,IE 11.0.9600.18059,FF 38.01(剛更新到41.02,同一問題)。 Win 7專業版。 – wowohweewah

回答

3

這是一個已知的錯誤,需要更多的調查。您可以在此跟蹤進度:https://github.com/openlayers/ol3/issues/4232

然而,有一兩件事可以做,以使事情更快:從map.forEachFeatureAtPixel返回truthy值停止檢查功能,一旦一個發現:

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

有道理。我一定會密切關注錯誤跟蹤,瞭解它不僅僅是我。 – wowohweewah

+0

對於我來說,這隻會在加載一些較大的多邊形或線時纔會發生(Firefox Linux)。據分析,這是可能與線/多邊形鬥爭的命中檢測。解決方案是在這種情況下禁用鼠標,或者在點擊時使用而不是鼠標懸停。 –

0

除了@ ahocevar的答案,可能爲您優化的是利用選擇interaction's select event

看來,選擇交互和你的mousemove監聽器都檢查在同一層上的命中,做雙重工作。只要所選功能組發生更改,選擇交互就會觸發select事件。您可以聽它,並在選擇某個功能時顯示彈出窗口,如果沒有,則將其隱藏。

這應該減少一半的工作,假設forEachFeatureAtPixel是什麼佔用系統。

+0

具有很多意義。更新了工具提示內容,以便在交互的selectEvent上觸發。不是FF中的主要速度差異,但可以很好地簡化代碼。 – wowohweewah

+0

我發現定義我自己的mousehover事件要比使用Select交互要好得多,因爲我可以檢查evt.dragging屬性,並防止調用forEachFeatureAtPixel(),這是瓶頸。就我所見,Select interaction調用forEachFeatureAtPixel()而不進行過濾。 – wlf

0

我有同樣的問題,通過setInterval解決了一個問題,關於這個稍後 1)每一個鼠標移動到1個像素觸發事件,並且你將有一個事件,直到你停止移動,並且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); 
} 
相關問題