轉自:http://blog.csdn.net/hzgjf/article/details/3014558
最近,已有幾位朋友在問關於圖形繪制中的圖層管理的問題,語言表達能力有限,電話里解釋半天,對方可能讓我攪得更糊塗了。整理一下思路,寫出來可能會更清楚一些。
在Gis軟件和一些圖像處理軟件中經常會有圖層這個概念,如PhotoShop。使用圖層的好處是可以將繪制的圖像圖形分層,對某層的操作不會影響其他層,並能增加刪除隱藏圖層,給人的感覺好像是在一層一層的玻璃上繪圖,然后將這些玻璃疊起來形成一副完整的圖像。
但在各類編程語言中並沒有圖層這個概念,圖層只是程序員腦中虛擬的東西。最簡單的,將每類圖形的繪制過程單獨寫成一個過程,增刪等圖層管理就是對這些繪圖過程進行控制,如畫一副天氣圖寫成偽代碼就是這樣子:
- 繪圖
- {
- 清屏();
- if(顯示地圖) 畫地圖();
- if(顯示填圖) 填圖();
- if(顯示等高線) 畫等高線();
- if(顯示等溫線) 畫等溫線();
- }
主程序里就可以控制繪制條件來畫需要的圖層了.是不是很簡單,呵呵
但是,有問題出來了,如果我改變了繪圖條件,如將"顯示填圖"由"True"變為了"False",也就是隱藏了填圖圖層,怎么才能擦除填圖層呢?擦掉已畫出來的圖是不可能的了,就像我們手工畫天氣圖一樣,本想用橡皮擦掉等溫線,但一擦連下面的等高線也擦掉了,計算機繪圖更不允許出現這樣的情況.解決的辦法很簡單,重繪!你可能會說,"我只想去掉一層,你卻將所有圖層都重畫一遍,多麻煩呀!",其實計算機最擅長做的就是這種麻煩而且重復的工作,重繪一次僅花費不到1秒的時間.就像老板說你的等溫線畫的難看,與其擦掉等溫線,還不如重拿一張空圖再畫一遍.
再就是圖層管理問題了,上面的辦法只能解決有限個圖層的情況,圖層不能增刪,只能隱藏,如果我需要不斷在上面添加新圖層,像再加一層雲圖.這就要用到面向對象了.我們可以將繪圖過程封裝成一個個類,如"地圖圖層類"/"填圖圖層類"/"等值線圖層類",主程序里用一個列表或動態數組,要添加那種圖層就向這個列表里加上這個類的對象,在繪圖過程中遍歷列表中的圖層對象,調用它們的繪圖方法,增刪圖層只是對圖層列表中的對象進行增刪.寫成偽代碼:
- 繪圖
- {
- for(int i=0;i<圖層列表.count;i++)
- {
- 圖層列表[i].繪圖;
- }
- }
這個是不是更簡單?沒學過面向對象的朋友可能還是不太理解,我還是用手工畫天氣圖作為例子:老板給我們一張白紙說:“把今天的地面圖畫好給我!”,我則先來找來地球儀,描出東亞地圖,再找到地面資料,一站一站填好要素,再畫等壓線,三小時變壓,天氣區、槽線、鋒面...畫好后拿給老板一看,老板說:“誰讓你分析槽線和鋒面了(水平不夠),拿去重畫!”暈倒!現實中這樣肯定是不科學的,於是,我們定了一個預報流程,將工作分給了多個人,首先,印刷廠工人給我們印好天氣圖底圖,然后我們用填圖機填好要素,預報員分析好等高線,槽線和鋒面可讓首席給我們定,於是一張天氣圖很快就畫好了。程序中,印刷廠/填圖機/預報員/首席就是一個個圖層對象,預報流程就是列表,我們可以在列表中增刪對象以滿足不通需要。面向對象博大精深,還需要在實際中多實踐...
FreeMicaps使用面向對象技術,不僅將讀數據和繪圖封裝成類,還將他們用插件方式實現,這樣增加一種數據類型只需要實現給定的接口並掛入主程序即可,道理和上面類似。