banner
陈不易

陈不易

没有技术想聊生活
twitter
medium
tg_channel

矢量瓦片高亮選中 Openlayers[1]

自己做的小 Demo 中有這樣一個小需求:通過數據庫檢索,獲取指定屬性的要素,然後高亮顯示。

如果採用 WFS 常規方式加載,不存在問題,遍歷layerfeature source即可,不考慮效率,邏輯是沒有問題的,但有個需求是圖層feature非常多(因為是全球範圍海岸線生成的緩衝區),所以地圖加載的過程中使用了矢量瓦片的形式,矢量瓦片類型的source沒有getFeatures()方法,給需要高亮顯示的要素進行遍歷造成了麻煩。

圖層的靜態樣式使用openlayers最新例子的方式設置:

//顏色表
const colorTable = {
  "No": "rgba(200, 54, 54, 0)",
  "type1": "#FF0000",
  "type2": "#E69800",
  ...
  "": "#00FFFFFF",
};
export function createRiskLevelStyle(feature) {

  const riskLevel = feature.get('props_X');
  let selected = !!selection[feature.getId()];
  return new Style({
    fill: new Fill({
      //color: colorTable[riskLevel],
      color: selected ? 'rgba(200,20,20,0.8)' : colorTable[riskLevel],
      //color: 
    }),
    stroke: new Stroke({
      color: '#FFFFFF',
      width: 0.1,
    })
  })
}

其中selected用於滑鼠點擊的高亮顯示,邏輯大概是點擊後將以featureid作為鍵值存儲,標識該要素被選中。

自然的在考慮這個需求的時候,我的首先想法是遍歷featureCollection找到相應的要素對應的Id,存進selection全局變量中。但因為矢量瓦片的source沒有getFeatures()方法所以這個想法就破產了。之後甚至想再新建一個普通的 WFS 層用來遍歷數據,但數據量實在太大了,一次加載要 50 幾 M,這種方式也就徹底破產了。

之後,考慮到既然加載的時候樣式可以用這種形式的styleFunc,在檢索的時候,給圖層賦新的Func會不會有效呢,性能又如何?於是對styleFun微調後如下:

export function createRiskLevelStyleSearch(names) {
  return function (feature) {
    const riskLevel = feature.get('props_X');
    let properties = feature.getProperties();
    let zh = properties['label'];
    let en = properties['name'];
    let searched = false;
    if (zh === undefined || en === undefined) {
      searched = false;
    } else {
      names.forEach((v) => {
        if (en === v.key)
          searched = true;
      });
    }
    return new Style({
      fill: new Fill({
        //color: colorTable[riskLevel],
        color: searched ? 'rgba(200,20,20,0.8)' : colorTable[riskLevel],
        //color:
      }),
      stroke: new Stroke({
        color: '#FFFFFF',
        width: 0.1,
      })
    });
  }

}

參數names是一個國家名的數組,itemkey對應需要檢索的值。

這種方法在這個數據量下,效果還可以,如下圖:

image

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。