SATURDAY, 21 MARCH
1-Preface
前幾天閱讀學習了OpenLayers'Cookbook中的第四章——Working with events。
從AFDS系統的開發項目進行至今,大部分時間都花費在了一些簡單的關系數據查詢實現以及網頁設計與改版上,真正應用到地圖部分的核心業務設計幾乎還沒有 起步。目前系統僅僅只實現了基於OpenLayers和Geoserver的地圖數據展示,簡單要素的獲取,基礎要素的樣式整飾。用戶與地圖部分的交互基本沒有設計,所以,希望通過學習OpenLayers庫中提供的事件實現接口,完成用戶與地圖數據的交互部分。
2-What?How?
Events are the heart of JavaScript.
這是Cookbook.Chapter 4中的第一句話。由此可見事件對於JS來說是多么的重要。每當用戶使用地圖工具,比如放大、縮小或者點擊選中要素、添加圖層等功能時,我們希望系統能夠給予用戶一定的反饋,比如說提示用戶操作是否有效,或者引導用戶對數據進行更深入的探索。
那么事件是如何進行反饋的呢?正如其他JS庫中的事件一樣,OpenLayers提供的事件的實現過程也是經典三部曲:Define event(定義)——Register Listeners(注冊)——Trigger events to notify all listeners(等待觸發)。
在OpenLayers提供的許多類中,Map、Layer等等,都擁有events屬性。而這些屬性都是OpenLayers.Events的實例。下面列舉一些OpenLayers.Map中常用的事件類型:
EVENT_TYPES: ["preaddlayer", "addlayer","preremovelayer", "removelayer","changelayer", "movestart","move", "moveend", "zoomend", "popupopen", "popupclose","addmarker", "removemarker", "clearmarkers", "mouseover","mouseout", "mousemove", "dragstart", "drag", "dragend","changebaselayer"]
通過上面列舉的事件類型,我們可以看到,一些基礎的地圖操作都已經被列舉出來了:添加、刪除、更改圖層;地圖視角移動/前/后;popup打開/關閉;增/刪/改標記;鼠標滑過、移出;拖拽地圖等等。
3-Instances
其實看到這里我們就應該知道如何使用這些事件了,聯想到我的AFDS數據庫系統,我第一個想起的就是popup功能,AFDS中實現了一個根據地名定位查詢的功能,具體界面類似於:
問題:通過地名選中地點,具體實現:提供名稱信息,執行SQL查詢,重新生成臨時圖層tempLayer,並更改臨時圖層中要素的樣式,使其與監測點圖層 monitSite區分開。但由於temp-Layer覆蓋住了監測點圖層monitSite,導致執行定位查詢之后,無法選中監測點圖層中的點要素。
在沒有接觸到OpenLayers中的events之前,我是通過使用OpenLayers.Control.Select-Feature的 onUnselect屬性實現的,當tempLayer中的要素未被選中時,調整tempLayer的index屬性。但由此導出的問題在 於,tempLayer在調整順序之后,要素仍處於選中狀態,而此時monitSite圖層已經覆蓋住,再選中monitStie圖層中的點要素之后,就 會出現這種情況:
解決方案:可以通過使用事件popupopen、popupclose作為指標判斷要素點是否被選中,然后根據popup的開閉,當tempLayer中 popup開啟的時候,tempLayer調整到所有圖層之上,當popup關閉的時候,將tempLayer調整到所有圖層之下。從而實現了根據 popup事件的發生控制圖層順序的調換。
存在問題:其實通過之前的解決方案,OpenLayers.Control.Select-Feature的onUn-select和onSelect 屬性也可以實現,但事件處理的出現,為我們提供了新的解決問題的方法,由於目前對於事件的使用經驗有限,未能在提高系統的業務效率方面有所發現,希望在之 后的學習中能夠繼續深入。