1、前言git
衆所周知,二維GIS技術發展了近四十年,伴隨着計算機軟硬件以及關係型數據庫的飛速發展,二維GIS技術已日臻完善。在對地理信息的分析功能上有着無可比擬的優點。一些宏觀的地理信息,一維的地理信息,如河流、公路等,以及二維的地理信息,如植被、湖泊、人口數量等,在對這些地理信息的分析和處理上,比較適合採用二維GIS系統。二維GIS始於20世紀60年代的機助製圖,今天它已經深刻社會的各行各業,如土地管理、電力、電信、水利、消防、交通、規劃等,但二維GIS有其自身難以克服的缺陷,它本質上是基於抽象符號的系統,不能真實的再現三維客觀世界。隨着信息技術的快速發展特別是數字地球(Digital Earth)的提出與實施,以及GIS應用深度和廣度的不斷擴大,二維GIS已經沒法知足用戶的需求,用戶對三維GIS的需求愈發迫切。伴隨着計算機顯示設備以及存儲設備的進步,三維GIS也獲得了必定的發展,GIS正在經歷一個由二維向三維發展的過程。算法
三維GIS最大優勢是能夠真實的再現現實環境中的地理信息,如地形、地貌等。利用三維GIS技術和DEM、紋理數據能夠實現真實感地形地貌的生成功能,以及實時漫遊功能等,對於一些只有三維GIS技術才能實現的功能,也必須由三維GIS技術實現,如爲了更加直觀地理解空間查詢和分析的結果、提升空間分析的水平,有必要恢復三維空間關係,並進行透視顯示。可是三維GIS才起步不久,並無成熟的空間數據模型給予其強有力的支撐,空間數據庫也並不能徹底表達空間實體的複雜關係。三維GIS的核心便是地形三維可視化及其查詢分析,地形三維可視化技術自20世紀90年代以來一直是地理信息系統領域開發和應用的熱點方向之一,地形三維可視化是一門利用數字化高程模型(DEM)顯示仿真內容的學科,是圖形學研究方向的熱門課題,而DEM數據的三維顯示是地形三維可視化的基礎。近年來,地形三維可視化技術愈來愈普遍地運用於地理信息系統、防洪決策系統、虛擬環境仿真、國土資源管理等領域。隨着科學技術的發展,地形三維可視化逐漸成爲當前對河道、湖泊和港口等進行防洪預測、河牀演變分析研究的前沿及主要手段,同時也是快速、及時再現地形三維信息及分析的有效手段。現有的三維GIS系統中,系統功能在三維場景可視化、實時漫遊等方面取得了較好的成果,但查詢分析功能比較弱。然而查詢分析功能在三維GIS的實現和應用中具備十分重要的地位,它使三維GIS具備輔助決策支持能力。數據庫
綜合考慮上述狀況及因素,做者認爲目前應以開發二維爲主、三維爲輔的混合型GIS爲主要目標,不宜單純開發三維GIS。在當前GIS產業界,二維GIS已經可以知足大部分實際需求,對三維GIS的需求仍然只佔少部分。當前三維GIS在三維數據獲取、大數據量處理與存儲、三維可視化、三維空間分析方面還不能以較好的性價比知足大規模商業應用的須要。若是徹底採用三維GIS,勢必將花費高昂的系統建設費用,在二維GIS可以知足須要的狀況下,用戶沒有必要去一味追求高性能。固然,這裏並不排除部分單位研製徹底的三維GIS以知足一些行業的特定須要,如軍事、採礦、石油勘探、地質結構研究等工做。因此發揮二維GIS與三維GIS的優點,進行矢量數據與地形三維可視化的結合性研究有很大的實用價值。若是採用三維可視化的方法集成矢量數據,並實現其相關屬性的查詢分析,將二維GIS的優點用在地形三維可視化中,使二維GIS與三維GIS獲得良好的結合,對軍事、民航、氣象等行業有很是重要的現實意義。安全
目前不一樣的應用目的每每須要二維GIS與三維GIS兩種方式交替運做,而不是單一的某一種。所以,結合二維GIS與三維GIS於一體,充分發揮二者的優點,是一個即經濟又實用的思想,這也正是本研究的宗旨所在。因此研發一個使矢量數據與地形三維可視化集成的系統,具備重要的現實意義,本研究系統將分爲二維和三維兩個部分,二維部分採用MFC與ArcGIS Engine實現,三維部分則採用ATL與OpenGL設計成ActiveX控件,ActiveX控件的集成性很是好,能夠發佈到任何聯網的用戶終端使用。所以,本論文將三維部分集成到二維部分中,使二維視圖與三維視圖造成一體化系統,採用的方式是動態加載ActiveX控件,該方式很是靈活,當ActiveX控件版本變化時,沒必要手動的更新。固然,不能簡單的堆砌爲一個集二維GIS與三維GIS於一身的顯示系統,更重要的是使二維與三維兩個部分得以互動,因此,本論文將二維與三維有機的結合,實現了二維與三維的互動。下圖說明了本系統的整體設計思路。函數
本系統是由二維與三維兩個部分共同構建的,以下圖所示的系統主界面。系統分爲左右兩個視圖,左視圖是二維部分,右視圖是三維部分,下面將詳細闡述二維部分、三維部分以及二維與三維互動的設計與實現,並用某地數據進行了測試。工具
2、技術路線和功能簡介性能
一、二維部分測試
本系統二維部分使用VC提供的MFC與ArcGIS Engine組件實現。在MFC中使用ArcGIS Engine的控件、接口和方法必須遵循必定的步驟,並不像VB、DoNet中那樣方便,下面詳細介紹在MFC中應用ArcGIS Engine的步驟。大數據
一、引入ArcGIS Engine控件庫文件(*.ocx)和組件庫文件(*.olb)。控件庫中定義了與控件相關的接口,組件庫中定義了與控件無關的接口。引用語句以下,其中除庫文件名(如:esriGeometry.olb)外其他各參數均採用默認便可;ui
#import <esriGeometry.olb>_ //庫文件名
raw_interfaces_only_
raw_native_types_
no_namespace_
named_guids_
exclude("OLE_COLOR", "OLE_HANDLE")
二、加載ArcGIS Engine控件。VC控件工具箱中有一些默認加載的控件,這些控件能夠在對話框中進行所見即所得的繪製,但ArcGIS Engine控件並無加載進去,所以須要手動加載,使得能夠在對話框中繪製Map、Scene、Toorbal等控件,VC中提供了兩種加載控件的方法;
第一種本論文稱之爲COM方式,該方式加載的控件圖標並不出如今工具箱中。首先右擊對話框,選擇「插入ActiveX控件」;而後選擇「插入ActiveX控件」對話框中要加載的控件,如:ESRI MapControl,這樣MapControl即出如今對話框中。
第二種本論文稱之爲C++方式,該方式加載的控件圖標出如今工具箱中,而且向VC工程中添加該控件的VC源文件(*.cpp)和頭文件(*.h)。首先,選擇工程->增長到工程->Components and Controls菜單,打開「Components and Controls」對話框,選擇Registered ActiveX Controls中要插入到工程的控件,如:ESRI MapControl,這樣MapControl即出如今VC工具箱中,即可以像默認控件那樣,在對話框中繪製MapControl。
三、定義ArcGIS Engine的類對象。ArcGIS Engine包含三種類[62]:抽象類(abstract class)、可實例化類(class)和組件類(cocalss)。抽象類不能用以建立新對象,但能夠指定子類;可實例化類不可以直接建立新對象,由於它的構造函數是私有的,但能夠經過其餘類對象的屬性或其餘類的方法實例化;組件類指的是可以直接使用經過開發環境中的對象定義語法來建立對象的類,組件類能夠直接被建立或者實例化。
VC中均採用智能指針來聲明ArcGIS Engine接口,能夠被實例化的類在VC中具備三種實例化方式:
第一種本論文稱之爲類標識方式。在類對象聲明時,直接使用類惟一標識(CLSID)進行構造,如:IFieldsPtr pFlds(CLSID_Fields);
第二種本論文稱之爲ATL方式。在類對象聲明時,使用CocreateInstance方法進行構造,如:CComPtr<IFields> pFlds;pFlds.CoCreateInstance(CLSID_Fields);
第三種本論文稱之爲COM方式。在類對象聲明時,使用CreateInstance方法進行構造,如:IFeatureLayerPtr pFlds;HRESULT hr = pFlds.CreateInstance(CLSID_Fields)。
通過以上步驟,便可以應用ArcGIS Engine提供的接口、方法進行本系統二維部分的程序設計。二維的功能以下圖所示,其中數據轉換部分實現了由Shapefile向TIN及Raster的轉換和由TIN或Raster生成等高線。二維AE部分實現了DEM及SHP文件的顯示,以及對DEM分層設色、生成坡度、通視分析、TIN的三維顯示、誇張係數設置等功能。
下面是二維的一些貼圖。
二、三維部分
本系統三維部分使用VC提供的ATL與OpenGL實現。ATL是活動模板庫(Active Template Library)的簡稱,是VC中爲了支持COM而提供的輕便類庫,用ATL能夠容易的定製COM組件,並不須要本身寫模塊定義文件(*.def)。在ATL中使用OpenGL的步驟以下。
一、引入OpenGL函數庫。首先,選擇工具->選項菜單,分別選擇目錄->Include files和目錄->Library files,將相應目錄添加進去;而後,在stdafx.h文件中加入以下語句,引入OpenGL頭文件和庫文件(*.lib)。
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#include <gl"gl.h>
#include <gl"glu.h>
#include <gl"glaux.h>
二、在具體的實現過程當中,因爲OpenGL函數經過「繪製場景」(Rendring ContextRC)完成三維圖形的繪製。Windows下的窗口和設備場景支持位圖格式屬性,該屬性與RC存在位圖結構上的一致。只要在建立RC時將它與一個DC(Device Context)相關聯(RC只能由一個已經創建了位圖格式的DC來建立),OpenGL的函數就能夠經過RC對應的DC繪製到相應的顯示設備上,相應的步驟以下:
1)設置顯示設備DC的位圖格式屬性。經過填寫一個PIXELFORMATDESCRIPTOR的結構來完成,該結構決定了OpenGL繪圖的物理設備屬性,另外,DC有可能只支持部分位圖格式,所以首先使用函數ChoosePixelFormat選擇與DC支持的指定位圖格式最接近的位圖格式,而後使用函數SetPixelFormt設置DC的位圖格式。
2)建立繪製環境RC與DC的聯繫,利用DC建立繪製場景RC(wglCreateContext),以便在DC與RC之間建立關聯,此時須要使用函數wglMakeContexte。
3)調用OpenGL函數進行繪製。
4)釋放相關內存。繪圖完備後,須要調用函數wglMakeContext設置當前線程的RC爲NULL,從而斷開當前線程和該RC的關聯,並由此斷開與DC的關聯。
通常地,在使用單個RC的應用程序中,相應的WM_CREATE消息時建立RC,當WM_CLOSE或WM_DESTROY到來時再刪除它。在使用OpenGL命令往窗口中繪製圖形以前,必須先創建一個RC,並使之成爲現行RC。OpenGL命令無需提供RC,OpenGL將簡單地忽略全部的繪圖命令。
通過以上步驟,便可以應用ATL及OpenGL從底層實現本系統三維部分的程序設計。三維OpenGL部分的功能以下圖所示,三維部分採用Roam算法實現DEM的三維可視化以及紋理的疊加,並實現了在三維場景中的實時漫遊和Shapefile疊加到紋理表面,能夠清晰的看到Shapefile疊加到紋理表面後的是有起伏的,這是由於Shapefile是繪製在紋理圖像上的,避免了低於地形或高於地形的狀況,爲有關部門的規劃管理提供了支持。
下面是一些三維貼圖。
一、疊加shapefile的效果圖
二、漫遊瀏覽的效果圖(不知爲什麼變成黑白色了,暈)
三、Roam算法生成的Dem格網圖
3、二維與三維集成及互動1三維ActiveX控件集成到二維部分
欲將ActiveX控件集成到二維部分,首先必須將二維部分分割成左右兩個視圖,而後將ActiveX控件插入到其中一個視圖中,詳細實現以下。
一、分割MFC視圖(View)。首先創建一個繼承自CFormView的視圖COpenGL,該視圖便是三維ActiveX控件的載體;而後創建一個繼承自CSplitterWnd的類CMySplitter,該類用來建立左右兩個視圖;最後重載CMainFrame的OnCreateClient函數,在該函數中調用CSplitterWnd的CreateStatic函數建立兩個視圖,並用RUNTIME_CLASS將COpenGL做爲其中一個視圖顯示。
二、動態加載ActiveX控件。首先如上節的方法插入三維ActiveX控件;而後在COpenGL類的OnCreate函數中使用CWnd類的CreateControl動態的加載ActiveX控件。
2 二維與三維互通訊
二維視圖與三維視圖的互通訊是實現二維與三維的互動的基礎,二維與三維互通訊分爲如下兩步。
一、視圖間互通訊。它不是簡單的函數調用問題,由於MFC的默認視圖類(CView)並不能安全的與除文檔類(CDocument)之外的其他視圖類進行通訊,因此,必須使得全部視圖類均先與文檔類進行通訊,這就須要重載CDocument::OnOpenDocument函數,將COpenGL類的指針加入其中便可以實現視圖間的通訊。
二、MFC視圖與ActiveX控件通訊。ActiveX控件所提供的方法均沒有返回值,而實現MFC視圖與ActiveX控件的通訊又必須獲得方法的返回值,解決這個矛盾有三種方法:
一是將方法的參數設置爲指針類型;
二是提供相應方法的屬性,在屬性內部調用ActiveX的類函數;
三是將方法聲明成事件,並能夠與默認的ActiveX事件掛鉤。
這三種方法各有千秋,須要結合應用,如:坡度坡向計算時,須要獲得該點的坡度坡向兩個數值,便可將該方法的參數聲明爲指針類型;距離量算時,只需獲得距離一個參數值,便可將其聲明爲屬性;座標查詢時,須要在MFC視圖中截獲鼠標單擊的消息,所以要將該方法聲明爲響應鼠標單擊的事件。
添加ActiveX事件是一項很是困難的工做,須要用接口定義語言—IDL(Interface Definition Language)手動編寫接口定義文件(*.idl)。下面以添加鼠標單擊事件Click爲例說明添加事件的步驟。首先,應用guidgen.exe得到一個惟一標識碼做爲Click事件的接口_IEvent的ID,而後將_IEvent聲明爲[default, source]dispinterface,編譯idl文件,並添加該_IEvent的Click事件的鏈接點(Connection Point),系統會自動產生一個繼承自IConnectionPointImpl接口的CProxy_IEvents類,並在該類中加入Fire_Click方法,該方法即爲Click事件。這樣只是添加了Click事件,還必須將其與ActiveX默認的鼠標單擊事件OnLButtonDown掛接,才能響應鼠標單擊的消息,所以必須在OnLButtonDown中調用Fire_Click方法,一切處理均在OnLButtonDown中實現,然後傳入Fire_Click中。
本研究的核心思想便是有機的結合二維GIS與三維GIS,並將二者統一應用到一個系統中,使在三維中難以實現或算法複雜的功能應用二維GIS實現,而在二維中不能實現或不夠精確的功能應用三維GIS實現,使二維GIS與三維GIS優點互補。
本文即應用該思想設計一個二維與三維結合的系統,在本系統中,要達到矢量數據和三維場景之間的一一映射,必須創建二者之間座標系的惟一對應或對應地理目標名稱[63](惟一的ID)的一一對應,一旦得到對象的惟一標識,就能夠得到對象實體的所有信息。本論文選擇座標對應方式,得到三場景中任意一點對應的地面點座標是進行有關空間信息的查詢操做和地形分析的前提,所以在三維部分中最爲重要的就是如何得到三維座標,對點的空間位置查詢是其他地形空間信息查詢的基礎,本論文改進了現有的三維座標查詢算法(見3.3.4節),使查詢三維座標更加方便準確。經過創建二維與三維兩部分座標的對應和消息響應機制能夠實現矢量數據與三維場景的互動。如:
一、用戶在三維場景中漫遊時,在二維場景中顯示出相應的位置和視野(FOV);
二、在二維場景中改變觀察者位置的時候,相應地在三維場景中跳到對應的位置。在三維場景中改變觀察者的位置,在二維場景中視點也跳到對應的位置;
三、二維中進行目標屬性信息查詢的時候,三維場景的對應目標高亮度顯示;
四、三維中進行目標屬性信息查詢的時候,二維場景的對應目標高亮度顯示;
五、因爲二維GIS宏觀性、總體性、簡潔性的特色,在二維中實現剖面圖繪製、通視分析、坡度圖繪製等宏觀的功能;
六、因爲三維GIS局部性、現實性、直觀性的特色,在三維中實現地形的真實再現、面積量算、距離量算、單點坡度坡向計算等微觀功能;
二維GIS與三維GIS結合應用,即克服了二維GIS的抽象多義性,又避免了三維場景漫遊的方向迷失感。本研究充分發揮了二者的優點,經過二維GIS與三維GIS的互動實現GIS功能,而不侷限於用單一的方式來實現,這樣即加強了系統的靈活性,又使問題簡單化。
通過以上兩步,二維與三維互動的準備工做已經完成,二維與三維互動的根本思想便是經過二維與三維的互通訊,使得二維與三維互相關聯,造成一個有機的總體。實現了二維與三維的互動的功能。其中座標查詢是最爲關鍵的功能,是實現其餘功能的基礎與前提。下面詳細說明這些功能實現的主要思想。
4.一、座標查詢。二維中只具備 座標,三維中具備 座標,所以欲獲得二維中鼠標點擊位置的三維座標,必須將二維中的 傳入三維中,通過改進算法的計算便可;而三維中座標與二維中對應只需將三維中的 座標傳入二維中。這樣就實現了二維與三維互動的座標查詢功能,以下圖所示,經驗證得到的座標正確,且實現了二維與三維的座標對應。
4.二、場景定位。在二維中想了解某個位置的詳細狀況時,能夠直接將二維座標傳入三維中,計算出三維座標後,在進行局部放大到相應位置的三維視圖。若是想得到二維中某條線路或某個區域的具體信息,能夠將該線路或區域傳入三維中繪製在地形紋理上進行仔細觀察,其中區域繪製有透明和非透明兩種,透明採用遍歷活性邊表的掃描線算法進行填充,非透明採用GDI的FillRgn函數進行填充;而三維中漫遊時,若是迷失方向,則能夠將三維座標傳入二維中進行定位標識,以下圖所示,二維中的任意位置、線路及區域都可在三維中做相應的繪製,均具有有地形相符的起伏;而三維中漫遊時亦可隨時定位到二維中。
4.三、距離量算。若是在三維GIS中測量曲面距離,必須與網格線進行屢次求交,獲得相應的交點再計算,這樣勢必大大增長系統負擔,而二維GIS中剛好能夠應用IPointCollection接口直接得到與網格線的交點集合,但二維GIS中的距離是投影距離,而曲面距離中每一段距離是空間距離,因此,若是是三維中兩點的曲面距離,首先需將起終點傳入二維GIS中,得到與網格線的交點集合再傳回三維GIS中進行計算便可;而若是是二維中兩點間的曲面距離,便可首先獲得交點(x,y)座標集合,而後傳入三維中,得到網格點集合的(x,y,z)座標,再進行計算便可。下圖即爲按照該方法獲得的投影、直線、曲面三種距離。
還有體積、剖面圖、三維二維加載shapefile等功能,此處就再也不一一贅述。完結啦,^_^