(十一)WebGIS中要素(Feature)的設計

文章版權由做者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/前端

1.前言

在GIS中元素通常分爲點元素,線元素,面元素以及symbol元素(特殊的點元素)等。與此對應,圖層能夠分爲點圖層,線圖層,面圖層以及標註圖層等。從第9章到第10章,我給你們講解了什麼是矢量數據、矢量數據的來源、矢量數據的構造、以及矢量數據中的地理座標與屏幕座標之間的轉換。在瞭解了這些概念和算法以及流程後,這一章咱們將開始講解設計出一個矢量圖層前的最後一步,設計WebGIS中的要素(Feature)。算法

2.要素設計的思路

2.1 需求

要素應該具備以下功能:設計模式

(1)可以繪製出矢量數據的Shape。框架

(2)可以存儲矢量數據的atrributes。函數

(3)能夠響應鼠標事件。設計

(4)能夠響應自定義事件,如自定義的一系列地圖事件。對象

(5)可以添加入Canvas組成一個矢量圖層。blog

(6)要素是有不少種類的,好比點、線、面等。繼承

2.2 基本分析

(1)在前面咱們已經闡述了要素的本質,即UIComponent。由於UIComponent是前端語言中已經封裝好了的類,咱們只用繼承其便可,如此咱們便同時能實現上面所說的第三個需求以及第五個需求。接口

(2) 需求中要求要素中可以繪製出矢量數據的Shape。因此得定義相似於Draw這樣的功能函數,以解決第一個需求。

(3)要素中還須要有個一變量存放attributes,即FeatureInfo以解決第二個需求。

(4)設計的類中還要定義一個監聽事件的函數和一個移除監聽事件的函數,即:addMapEventListener和removeMapEventListener,以解決第四個需求。

 

2.3 擴展分析

2.3.1重繪

當地圖刷新,好比放大和縮小時,此時的UIComponent必須重繪,不然地圖上的Shape將再也不在地圖上表示正確的位置,因而這裏對Feature的設計有兩點須要注意:

(1)對地圖放大和縮小進行監聽。

(2)增長重繪函數,即reDraw函數。當地圖放大和縮小時觸發重繪函數。

2.3.2 基類

需求中提到了要素具備多種類型,咱們設計時須要將這幾種類型均涉及到的屬性和函數抽象出來做爲一個基類,即Feature類。能夠抽象出來的屬性和類有:

(1)reDraw和Draw函數

(2)FeatureInfo屬性

(3)addMapEventListener和removeMapEventListener函數

(4)對地圖放大縮小事件的監聽,此功能的實現能夠放在Feature的構造函數中。

2.3.3 hook到主框架

在繪製shape時,咱們須要用到地理座標與平面座標互相轉換的函數,即上一章提到過的geoXYToScreenXY和screenXYToGeoXY。可是這兩種方法是不可能封裝到Feature類中的。由於這兩種方法爲系統中通用方法,不是專爲Feature類而存在。因此這兩個方法是放在主框架類中,這裏我將這個主框架定義爲FrameMap。因而,咱們的Feature類中還應該有能夠注入主框架的屬性,即Map。

3.UML設計

基於上述分析,咱們如今要開始真正的設計要素了。咱們首先定義一個Feature類,其繼承於UIComponent,而後再根據需求定義一系列具體的基礎要素類,好比PointFeature、LineFeature和PolygonFeature等。而且若是需求出現變動,原有的基礎要素已經不能知足需求時,能夠在基礎要素上進行繼承從而進一步擴展基礎要素類。

以下是最後設計出的要素類的UML圖:

 

4.問題及解決方法

4.1如何控制每種基礎要素類中要求shape以不一樣樣式展示的需求?

在實際應用中,對同一個要素,用戶須要的展示方式可能不盡相同。好比對面要素,有時候須要展示成黃色,有時候須要展示成藍色等,而有時候須要面要素內的填充爲網格狀,有時候須要面在移動上去時變色,有時候又不須要等等。

解決此問題的方法,並非去爲每種需求從新將基礎要素繼承,而後修改draw方式,若是這樣的話,代碼的重複量太大。在設計模式中,咱們有一個原則是能用組合時儘可能用組合,能不用繼承時儘可能不用繼承,由於繼承是種高度的耦合,派生類和基類被牢牢的綁在一塊兒,靈活性大大下降,並且,濫用繼承,也會使繼承樹變得又大又複雜,很難理解和維護。在這個需求裏,目前用不上組合,可是繼承就更不須要了。

咱們的解決方法通常是:

(1)首先將需求分類。外觀上:一類是改變顏色的,一類是改變要素內部構造的。行爲上:一類是須要某些監聽而且作出相關變化的,一類是不須要某些監聽的。這樣咱們能夠在具體要素類,好比polygon類中添加兩個共有屬性,一個是DrewType,一個是ActionType。若是不但願把控制行爲的重擔都放在polygon類中,咱們也能夠不用定義ActionType,此類中原本就設計有addMapEventListener和removeMapEventListener。能夠開放給調用者,讓其自行判斷。

(2)而後咱們在Draw函數中,經過判斷DrawType來進行繪製方面的控制。每一個具體要素類中有本身定義的內部透明度(Sopacity)、外部透明度(opacity)以及內部填充色(SColor)和外部填充色(color)以及填充圖標(Symbol)等等繪製方面的屬性。回到上面的需求中,咱們一類是想改變要素顏色,一類是想改變內部構造。仍是假設這是一個對於polygon要素的需求,咱們把DrawType定義爲0和1。當DrawType爲0時,咱們將使用Sopacity,opacity、Scolor和color等繪畫要素進行繪製,這些要素均是有默認值的公有屬性,調用者能夠本身設定。可是當DrawType是1時,這時候會將Symbol進行加載,而後改變繪製polygon的方式,將Symbol做爲內部填充物進行填充。一樣,Symbol也是有默認值的公有屬性,調用者能夠本身設定。

4.2地圖發平生移時,Canvas的左上角座標也出現平移,如何解決此時要素重繪時要素偏移問題?

 在後面探討設計WebGIS的地圖平移功能時,咱們會講到每次地圖被拖拽後,矢量圖層(Canvas)的左上角座標均會加減相同的屏幕平移量。這時候若是僅僅是將要素中的地理座標轉換爲屏幕座標後就直接將其繪製在UIComponent,而後添加到該Canvas裏,便會出現繪製的要素不在地圖上實際的地點的現象,即發生了偏移。這個問題是一個有必定難度的問題,我會在之後的WebGIS基礎功能設計篇裏專門花一個章節跟你們探討這個問題。

5.經過設計模式再次探討咱們的設計

以上的設計基本上是遵循了面向對象的設計思惟。不過,依據設計模式的原則,此中依然有能夠改進的地方。

(1)根據依賴倒轉原則,咱們能夠定義一個接口,好比IFeature,而後基類繼承於此接口,這樣能夠經過接口來規範基類應該實現哪些方法。

(2)咱們能夠考慮使用簡單工廠模式,從而進一步減小界面層類和Feature類中的耦合度。

不過,設計模式除非真有效用時再用才比較好,目前的元素設計在實際的編寫代碼中已經很好用了,當用到工廠類時,須要再次編寫不少類出來,並且效果也不必定好。

6.總結

這一章裏咱們將設計矢量圖層前的最後一個障礙克服了,可是,我在這個章節中仍是留下了一個沒有解答的問題:地圖平移後的要素重繪問題。這個問題,我會在之後的章節中專門跟你們一塊兒探討。下一章,咱們就開始走完WebGIS柵格圖層和矢量圖層設計這個系列的最後一站了,但願你們持續關注。

 

                                                                                     ——歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS

相關文章
相關標籤/搜索