[OpenLayers] 面可以有幾種樣式

The different styles of Polygon

Shan
C.Shan
Feb 7, 2021

--

前言

既上一篇 [OpenLayers] 線可以有幾種類型的實作之後,這篇要來分享面可以有幾種樣式。如果希望面狀無邊框、填滿飽和或透明顏色,這是可以單純透過修改圖層的 style (ol.style.Style) 去達到其效果。但若希望面狀是能以斜線、網狀填滿或是面狀上能加上圖示,這類需求如何實踐?

The different styles of Polygon

一些工具

IDE : Visual Studio Code

CDN:

  • openlayers v6.5.0
  • jquery v3.5.1
  • popper.js v1.16.1
  • bootstrap v4.5.2
  • math.js v5.4.1

動手實作

看完長長的程式碼之後,有清楚 vector、feature 和 style 之間的關係了嗎?Canvas 是什麼?地圖上面狀的樣式,是怎麼形成的?如果跟我有同樣的疑問,建議可以參考這個網路資源: Advanced styles in OpenLayers 3,儘管文章採用的 OpenLayers 版本稍舊,但個人覺得還是能幫助新手學習。

關於圖層樣式

所以說在地圖上畫一個形狀之後,形狀是如何帶有不同樣式呈現在地圖上?讓我們看一下這張圖:

Vector layer & tile layer

看完這張圖,可以再回到 openlayers-faceStyles.js 程式碼仔細對照一下。第322 行初始化地圖,包含 faceVectorLayer 的圖層。faceVectorLayer 的圖層在第 160 行被初始化,其中圖層的 style 會因判斷結果不同,而有可能是 stlye 或 getStackedStlye 這兩個變數。

兩者的差異在於, style 是單純改變官方 API 屬性,調整框線及面狀粗細或顏色; getStackedStlye 需要用到 canvas 畫布,當所需的樣式,單靠官方 API 無法達成需求時,就必須靠 Canvas API 自刻樣式。例如,程式碼中,第 97 行即是在 canvas 上,先畫滿網格。當在地圖的圖層上,畫出 一面狀 feature,其就會帶有網格樣式。

其中一部分的程式碼,是參考 ol-ext 套件,也因研究其實作方法,才進一步認識 Canvas API。

關於面狀加上圖示

起初實作這個需求的時候,我看到 ol.style.Style 物件中,有 image 這個屬性,很開心的想說,就是它了!但事實 ol/style/Image~ImageStyle 是:

Base class for module:ol/style/Icon~Icon, module:ol/style/Circle~CircleStyle and module:ol/style/RegularShape~RegularShape.

後來摸索一陣子發現,faceVectorLayer 中的 style 屬性可以是陣列。如同 openlayers-faceStyles.js 程式碼第 222–257 行,含註解的部分。可以看出,註解的那塊是含有 icon 的 style,將其放在 geometry 取得的座標位置。這樣的結果,雖成功在面狀加上圖示,可是圖示會隨著地圖縮放,而我想要屏除這樣的問題。

所以又再摸索一陣子,來到程式碼第 339–354 行,這段是在 drawend 的時候,也就是畫完一面狀的瞬間,去執行 callback function。其產生一張靜態圖示在新的圖層上,這個新的圖層,最後被加在地圖上。換句話說,就是面狀跟圖示屬不同圖層。如此的圖示便不會隨地圖縮放,但因圖層是分開的,所以面狀有更新的時候,圖示要另外做處理。

附上 GitHub 位置,感謝各位(・∀・)つ

參考

--

--

Shan
C.Shan

過去學習機械理論,現在撰寫網頁程式。我喜歡唱歌,喜歡畫畫,喜歡旅遊,存在藝術的感性,也兼具工程師的理性。腦容量87%,未來期望用文字、影像紀錄經歷。