GIS地圖開發
一、 地圖是怎么做出來的
首先說一下地圖是怎么出來的,可能你感覺是廢話,但實際上很多人并不知道如何下手。我覺得這里需要先給你個思路準備:地圖就是使用繪圖語句畫出來的!
從底層繪制地圖,能使用的就是繪圖函數,在.NET里,就是用Graphics類的方法,在窗口中繪制點、線、面、標準、柵格等,組合起來,就是一張地圖(瓦片圖方式除外)。
關于.NET的繪圖,本文不進行講解,如果你還還不熟悉,建議你先看看這方面資料。
二、 坐標轉換-地圖繪制的關鍵
.NET提供了大量繪圖方法,基本上都是以Graphics類的函數形式提供,包括各類幾何形狀、圖像、文字的繪制,靈活運用這些方法,就可以畫出精美的圖出來。假設你已熟悉.NET的繪圖,這樣就只有有一個問題要解決:圖我會畫了,但拿到地圖元素一般為地理坐標(經緯度),應該畫在地圖上什么位置?這就需要涉及到坐標轉換問題。
先不考慮怎么實現,首先需要這么一個函數:
/// 《summary》
/// 經緯度轉換為屏幕坐標
/// 《/summary》
/// 《param name=“xy”》經緯度《/param》
/// 《returns》屏幕坐標《/returns》
public Point WorldToScreen(PointF xy)
再一個,有時,還需要根據屏幕上點位置反算出它的經緯度,如在需要顯示鼠標指針處的經緯度,所以還需要這么一個函數:
/// 《summary》
/// 屏幕坐標轉換為經緯度
/// 《/summary》
/// 《param name=“xy”》屏幕坐標《/param》
/// 《returns》經緯度《/returns》
public PointF ScreenToWorld(Point xy)
有了這兩個函數,就可以將以經緯度表示的地理坐標轉換為屏幕坐標,然后再屏幕繪圖了。
為了完成坐標轉換,需要使用幾個地圖參數的變量:地圖縮放倍數、地圖中心點經緯度、地圖大小,關于地圖參數,可參考這篇文章:
http://hi.baidu.com/geochenyj/blog/item/6b5c5c1294057557f819b835.html
另外,還需要對地圖進行縮放、平移,這些操作實質上也是對地圖參數的操作,如放大就是對地圖縮放倍數操作,平移就是對地圖中心點進行操作,我們將這些操作也寫Coordinator類的方法。投影變換也作為坐標轉換的一部分,Coordinator類還增加了投影方面方法,這個后面再講。
將上面兩個坐標轉換函數和三個地圖參數封裝為一個類Coordinator。,的類如下所示:
?
三、 繪圖
有了坐標轉換類Coordinator,就可以用經緯度數據來繪圖了,如拿到某省的行政邊界經緯度坐標數據,就可以將經緯度數據轉換為屏幕坐標,然后用Graphics的方法來畫出來了,Graphics對象又從哪里來呢?可以從一個Image對象創建,也可以從一個控件的Paint事件中取得,總之,有了坐標,發揮你的想象力,自己畫吧。
在氣象數據分析中,除了要繪制點、線、面、文字、柵格外,還需要繪制一些特殊符號,如風、天氣現象、云等。這些符號,可以用圖片、天氣字庫、符號庫來實現,圖片方式實現簡單,色彩豐富,但縮放效果不好;字庫方式,需要安裝字庫,程序部署比較麻煩;符號庫方式代碼編寫較麻煩。FreeMicaps的天氣現象符號采用符號庫方式,祥見: http://blog.csdn.net/HZGJF/archive/2009/05/27/4220508.aspx
風符號和云量符號采用計算坐標繪制方式。
為了使用方便,FreeMicaps把符號繪制功能封裝到三個符號類中,以靜態方法提供。
?
.NET的繪圖是對GDI+的封裝,包括了對點、線、面等各種圖形元素的封裝,圖形圖像的繪制、坐標旋轉,各種反走樣和平滑等功能,功能十分強大(當然,效率不太高),利用它可以繪出漂亮的圖形。
根據OGC標準,GIS系統首先需要對地圖元素進行抽象和封裝,但FreeMicaps中,經再三考慮,放棄了這種方式,一個是因為工作量比較大,另一個是因為我不敢保證能很好地進行封裝,可能給插件開發帶來麻煩,不如把繪圖權完全交給圖層,大家自由發揮。
四、 圖層
為了使繪圖過程便于管理,可將繪圖過程分為組,如可以將一張地圖的繪制分為:繪制世界地圖、繪制中國地圖、繪制河流、填地名幾個過程,每次繪圖好像就是在一張玻璃上繪制,疊加起來就形成了一張地圖圖,這里把每次繪圖過程形象地稱為一個圖層。地圖分層后,圖層可以增刪,每個圖層可以單獨進行隱藏、設置屬性等,更重要的是可以將利用面向對象技術把每個圖層當做一個對象進行管理。詳細介紹見:http://blog.csdn.net/HZGJF/archive/2008/10/03/3014558.aspx
對圖層進行抽象,它應該有一個圖層繪制方法(Render),一個圖層標題(LayerName),一個用于表示數據源的字符串(DataSource),一個用于表示繪圖樣式的設置的LayerStyle,加上一些輔助方法屬性,最終形成如下抽象圖層類(CustomLayer),各種圖層均從它繼承:
?
FreeMicaps中,每種數據對應一種圖層類,為了使圖層類編寫方便,使用了設計模式中的模板方法,定義繪制流程,主程序在調用圖層的Render()方法時,會自動判斷是否已經讀入數據,根據需要讀數據繪圖。
對于一種類型數據,需要從CustomLayer繼承新建一個圖層類。各種類型數據圖層的工作方式完全一樣,僅在數據讀取和繪制方面不同,所以,寫新圖層類時,僅需實現DoLoad()和DoRender()兩個抽象方法,完成讀取數據和繪制圖層代碼即可。FreeMicaps里使用了字符串作為數據源標識,通用GIS系統對數據源進行了抽象,我也嘗試這么做,但代碼過于復雜,增加圖層開發難度,最終增大插件開發難度,所以放棄了。
前面說了,一張地圖有多個圖層,所以還需要將圖層放入一個列表,繪制地圖時遍歷圖層,調用每個圖層的Render()方法,畫出一張完整的地圖。對于圖層列表,大家馬上會想到使用List類,但圖層繪制是需要有順序的,如在衛星云圖上面疊加地名,需要先畫衛星云圖,再填地名,否則云圖會把地名蓋住,所以在圖層的樣式(LayerStyle)中放了一個ZOrder屬性,通過它來控制圖層順序。但由于List本身的排序方法是一種“非穩固排序”,也就是說當兩個圖層的ZOrder相等時,它們的順序是不確定的,為了避免這個問題,FreeMicaps從CollectionBase繼承了一個類LayerList,實現對圖層的管理,并實現了IXmlSerializable接口,完成圖層序列化功能。另外,還增加了添加圖層、刪除圖層事件。LayerList類如下:
FreeMicaps中,每種數據對應一種圖層類,為了使圖層類編寫方便,使用了設計模式中的模板方法,定義繪制流程,主程序在調用圖層的Render()方法時,會自動判斷是否已經讀入數據,根據需要讀數據繪圖。
對于一種類型數據,需要從CustomLayer繼承新建一個圖層類。各種類型數據圖層的工作方式完全一樣,僅在數據讀取和繪制方面不同,所以,寫新圖層類時,僅需實現DoLoad()和DoRender()兩個抽象方法,完成讀取數據和繪制圖層代碼即可。FreeMicaps里使用了字符串作為數據源標識,通用GIS系統對數據源進行了抽象,我也嘗試這么做,但代碼過于復雜,增加圖層開發難度,最終增大插件開發難度,所以放棄了。
前面說了,一張地圖有多個圖層,所以還需要將圖層放入一個列表,繪制地圖時遍歷圖層,調用每個圖層的Render()方法,畫出一張完整的地圖。對于圖層列表,大家馬上會想到使用List類,但圖層繪制是需要有順序的,如在衛星云圖上面疊加地名,需要先畫衛星云圖,再填地名,否則云圖會把地名蓋住,所以在圖層的樣式(LayerStyle)中放了一個ZOrder屬性,通過它來控制圖層順序。但由于List本身的排序方法是一種“非穩固排序”,也就是說當兩個圖層的ZOrder相等時,它們的順序是不確定的,為了避免這個問題,FreeMicaps從CollectionBase繼承了一個類LayerList,實現對圖層的管理,并實現了IXmlSerializable接口,完成圖層序列化功能。另外,還增加了添加圖層、刪除圖層事件。?
- 第 1 頁:GIS地圖開發
- 第 2 頁:GIS地圖開發(二)
本文導航
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%
相關閱讀:
- [電子說] 中易云GIS場景信息管理平臺提供強大的空間分析功能 2023-10-21
- [可編程邏輯] 基于FPGA系統Register和Memory的復位 2023-10-09
- [電子說] GIS組合電器安裝事項 2023-09-26
- [電子說] 潤和軟件HopeStage與超圖軟件 GIS平臺完成產品兼容性互認證 2023-09-25
- [電子說] 淺析C語言中的regiseter關鍵字 2023-08-25
- [電子說] 變電站GIS室內六氟化硫氣體泄露報警監測系統的應用方案 2023-08-16
- [電子說] 分布式應急指揮中心方案 2023-08-16
- [電子說] 助力GIS配電室氣體減排--六氟化硫SF6氣體在線監測報警系統 2023-07-19
( 發表人:彭菁 )