版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 畢業(yè)設計說明書論文</b></p><p> 基于VC++的電子導航系統(tǒng)</p><p><b> 摘 要</b></p><p> 地理信息系統(tǒng)(GIS)自二十世紀六十年代開始發(fā)展至今,已經(jīng)逐漸成為一門成熟的技術,其在交通、旅游、環(huán)境等諸多領域的應用使地理信息系統(tǒng)被越來越多的用戶所接受
2、,成為人們工作、生活中一個強有力的工具。</p><p> 本設計以VC++為開發(fā)平臺,以MapX控件為圖形平臺,以MSComm控件為通信平臺,設計具有電子導航的基本功能(如地圖的放大縮小、全圖、漫游等)、自定義工具測量折線距離、圖層控制、最優(yōu)路徑分析、GPS導航等功能的GIS應用軟件。</p><p> 本文介紹了電子導航系統(tǒng)設計的背景及設計中需要用到的MapX控件、VC++、MSC
3、omm控件,分析了GIS開發(fā)三種實現(xiàn)方式,提出系統(tǒng)設計方案:集成二次開發(fā)。在集成二次開發(fā)的基礎上,首先實現(xiàn)了地圖的導入、地圖放大縮小及圖層控制等電子導航的基本功能,其次以測量折線距離為例實現(xiàn)了自定義工具的功能,再次介紹了最優(yōu)路徑分析,最后實現(xiàn)GPS導航功能。</p><p> 關鍵詞:電子導航;GIS開發(fā);VC++;MapX控件;最優(yōu)路徑</p><p> Electronic Nav
4、igation Systems Based On VC++</p><p><b> Abstract</b></p><p> Since the beginning of 1960s,Geographic Information System (GIS) has gradually become a mature technology. In transpor
5、tation, tourism, environment and many other fields of application GIS has been accepted by an increasing number of users for the people working and living as a powerful tool.</p><p> The design used VC + +
6、as a development platform, MapX control as a graphics platform, MSComm control as a communications platform.It has devised the GIS applications such as electronic navigation Basic functions(zoom control,the whole map, Ro
7、aming, for example), Calculating the distance, Layer Control, Analysis of the optimal path and GPS Navigation Features.</p><p> This article has described the design of electronic navigation systems backgro
8、und, MapX control,VC++ and MSComm control. It has analyzed GIS development in three ways and proposed system design:Secondary development of integrated. First of all, It has realized the basic functions of GIS such as th
9、e insert map,Layer Control, Zoom control in the integrated development of the basis of secondary. Second, it has used a custom tool as an example to measure the distance, and then it has introduced the </p><p&
10、gt; Key words: Electronic navigation; GIS Development;VC++; MapX control; Optimal path</p><p><b> 目 錄</b></p><p><b> 摘 要I</b></p><p> AbstractII</p&
11、gt;<p><b> 第一章 引 言1</b></p><p> 1.1設計背景1</p><p> 1.2系統(tǒng)設計方案4</p><p> 1.2.1應用型GIS開發(fā)的三種實現(xiàn)方式4</p><p> 1.2.2三種實現(xiàn)方式的分析5</p><p>
12、 第二章 電子導航基本功能在VC++中的實現(xiàn)7</p><p> 2.1利用MapX實現(xiàn)GIS基本功能7</p><p> 2.1.1將MapX支持類庫加入工程7</p><p> 2.1.2地圖的顯示7</p><p> 2.2使用地圖標準工具9</p><p> 2.3圖層控制工具1
13、1</p><p> 第三章 自定義工具測量折線距離13</p><p> 3.1創(chuàng)建用戶自定義工具13</p><p> 3.2編程實現(xiàn)自定義工具的行為14</p><p> 3.3調(diào)用自定義工具16</p><p> 第四章 最優(yōu)路徑分析18</p><p> 4
14、.1實現(xiàn)過程及其算法分析18</p><p> 4.2查詢最短路徑25</p><p> 第五章 GPS導航功能30</p><p> 5.1定位信息的接收32</p><p> 5.2提取定位數(shù)據(jù)34</p><p><b> 總 結39</b></p>
15、<p><b> 參考文獻40</b></p><p><b> 附錄:源程序42</b></p><p> CVCDZDHView類源程序42</p><p><b> 致 謝52</b></p><p><b> 引 言</b
16、></p><p><b> 設計背景</b></p><p> 學科發(fā)展走向綜合是一個普遍的趨勢,比如全球定位系統(tǒng)(GPS)與地理信息系統(tǒng)(GIS)的集成應用。目前用于GIS應用軟件開發(fā)的模式有很多,其中組件式GIS軟件開發(fā)是目前較為流行、高效、快速的開發(fā)模式。隨著計算機技術的飛速發(fā)展,GIS得到了廣泛的重視和應用,GPS技術也已深入到各行各業(yè),GPS與G
17、IS的集成具有廣泛的應用需求,它可以實現(xiàn)GPS導航信息在地圖上的可視化、一體化和集成化,能夠在地圖上實時動態(tài)地跟蹤目標和顯示地理方位。VC++是目前較流行的可視化開發(fā)編程工具之一,支持面向對象和事件驅動機制的程序開發(fā),利用其強大的集成開發(fā)環(huán)境,程序員僅需要較少代碼即可生成標準的“Windows” 界面,并且能在VC開發(fā)平臺下可以較為方便的集成組件。</p><p> 本文主要介紹利用MapX控件,采用VC++編
18、程語言進行組件式GIS應用軟件開發(fā)的主要過程和基本模式,來實現(xiàn)電子導航的目的。</p><p> MapX是MapInfo公司向用戶提供的具有強大地圖分析功能的ActiveX控件產(chǎn)品。由于它是一種基于Windows操作系統(tǒng)的標準控件,因而能支持絕大多數(shù)標準的可視化開發(fā)環(huán)境如Visual C++、Visual Basic、Delphi、PowerBuilder等。</p><p> 編程
19、人員在開發(fā)過程中可以選用自己最熟悉的開發(fā)語言,輕松地將地圖功能嵌入到應用中,并且可以脫離MapInfo的軟件平臺運行。利用MapX,能夠簡單快速地在企業(yè)應用中嵌入地圖化功能,增強企業(yè)應用的空間分析能力,實現(xiàn)企業(yè)應用的增值。MapX采用基于MapInfo Professional的相同的地圖化技術,可以實現(xiàn)MapInfo Professional具有的絕大部分地圖編輯和空間分析功能。而且,MapX提供了各種工具、屬性和方法,實現(xiàn)這些功能是
20、非常容易的[1]。</p><p> MapX為開發(fā)人員提供了一個快速、易用、功能強大的地圖化組件。在VB,Delphi,PowerBuilder,VC等可視化開發(fā)環(huán)境中,只需在設計階段將MapX控件放入窗體中,并對其進行編程,設置屬性或調(diào)用方法或相應事件,即可實現(xiàn)數(shù)據(jù)可視化,專題分析,地理查詢,地理編碼等豐富的地圖信息系統(tǒng)功能。 </p><p> MapX定義了一個類體系,以有效的
21、組織圖形元素,圖層,屬性數(shù)據(jù)等對象。MapX的主要功能包括:顯示MapInfo格式的地圖;對地圖進行放大、縮小、漫游、選擇等操作;專題地圖;圖層控制;數(shù)據(jù)綁定;動態(tài)圖層和用戶繪圖圖層;生成和編輯地圖對象;簡單地理查詢:邊界查詢,地址查詢。</p><p> VC++是微軟公司開發(fā)的一個IDE(集成開發(fā)環(huán)境),換句話說,就是使用C++的一個開發(fā)平臺。有些軟件就是這個編出來的,另外還有VB、VF,只是使用不同語言。
22、但是,VC++是Windows平臺上的C++編程環(huán)境,學習VC要了解很多Windows平臺的特性并且還要掌握MFC、ALT、COM等的知識。Windows下編程需要了解Windows的消息機制以及回調(diào)(callback)函數(shù)的原理;MFC是Win32API的包裝類,需要理解文檔視圖類的結構,窗口類的結構,消息流向等等;COM是代碼共享的二進制標準,需要掌握其基本原理等等。</p><p> VC++應用程序的開
23、發(fā)主要有兩種模式,一種是WIN API方式,另一種則是MFC方式,傳統(tǒng)的WIN API開發(fā)方式比較繁瑣,而MFC則是對WIN API再次封裝,所以MFC相對于WIN API開發(fā)更具備效率優(yōu)勢。</p><p> VC基于C,C++語言,主要由是MFC組成,是與系統(tǒng)聯(lián)系非常緊密的編程工具,它兼有高級,和低級語言的雙重性,功能強大,靈活,執(zhí)行效率高,幾乎可說VC在 Windows平臺無所不能。</p>
24、<p> MSComm 作為一個串行通訊控件為程序員串口通訊編程節(jié)省了很多時間。在基于對話框的應用中加入一個MSComm控件非常簡單。只需進行以下操作即可:</p><p> 打開“Project->Add To Project->Components and Controls->Registered Activex Controls”,然后選擇控件:Microsoft Comm
25、unication Control,version 6.0插入到當前的工程中。這樣就將類 CMSComm 的相關文件 mscomm.cpp 和 mscomm.h 一并加入到了工程中。編程時只需將控件對話中的 MSComm 控件拖至你的應用對話框中就OK了。MSComm控件提供了兩種處理通信的方法:</p><p> 1. 事件驅動通信,是一種功能很強的處理串口活動的方法。例如,當在CD(Carrier Dete
26、ct)線或RTS(Request To Send)線上有字符到達或發(fā)生了改變,在這種情況下,可以使用MSComm控件的OnComm事件捕獲和處理這些通信事件。OnComm也可以捕獲和處理通信中的錯誤。</p><p> 2. 可以在每個重要的程序功能之后檢查CommEvent屬性的值來檢測事件和通信錯誤。使用的每個MSComm控件都與一個串口對應。如果在應用程序中需要訪問多個串口,必須使用多個MSComm控件,
27、可以在Windows 控制面板中修改串口地址的中斷地址。</p><p> MSComm 控件有很多重要的屬性,如:</p><p> CommPort 屬性:設置并返回通訊端口號。</p><p> RThreshold 屬性:在MSComm控件設置CommEvent屬性為comEReceive并產(chǎn)生OnComm之前,設置并返回的要接收的字符數(shù)。</p
28、><p> CTSHolding屬性:確定是否可通過查詢Clear To Send (CTS)線的狀態(tài)發(fā)送數(shù)據(jù)。Clear To Send 是調(diào)制解調(diào)器發(fā)送到相聯(lián)計算機的信號,指示傳輸可以進行。該屬性在設計時無效,在運行時為只讀。</p><p> SThreshold屬性:在MSComm控件設置CommEvent屬性為comEvSend并產(chǎn)生OnComm事件之前,設置并返回傳輸緩沖區(qū)中允
29、許的最小字符數(shù)。</p><p> CDHolding 屬性:通過查詢 Carrier Detect (CD)線的狀態(tài)確定當前是否有傳輸。Carrier Detect 是從調(diào)制解調(diào)器發(fā)送到相聯(lián)計算機的一個信號,指示調(diào)制解調(diào)器正在聯(lián)機。該屬性在設計時無效,在運行時為只讀。</p><p> DSRHolding 屬性:確定Data Set Ready (DSR)線的狀態(tài)。Data Set
30、 Ready信號由調(diào)制解調(diào)器發(fā)送到相連計算機,指示作好操作準備。該屬性在設計時無效,在運行時為只讀。</p><p> Settings屬性:設置并返回波特率、奇偶校驗、數(shù)據(jù)位、停止位參數(shù)。</p><p> InputLen屬性:設置并返回Input屬性從接收緩沖區(qū)讀取的字符數(shù)。</p><p><b> 系統(tǒng)設計方案</b></
31、p><p> 應用型GIS開發(fā)的三種實現(xiàn)方式</p><p><b> (1)獨立開發(fā)</b></p><p> 不依賴于任何GIS工具軟件,從空間數(shù)據(jù)的采集、編輯到數(shù)據(jù)的處理分析及結果輸出,所有的算法都由開發(fā)者獨立設計,然后選用某種程序設計語言,如Visual C++、Delphi等,在一定的操作系統(tǒng)平臺上編程實現(xiàn)。這種方式的好處在于無須依
32、賴任何商業(yè)GIS工具軟件,減少了開發(fā)成本,但一方面對于大多數(shù)開發(fā)者來說,能力、時間、財力方面的限制使其開發(fā)出來的產(chǎn)品很難在功能上與商業(yè)化GIS工具軟件相比,而且在購買GIS工具軟件上省下的錢可能還抵不上開發(fā)者在開發(fā)過程中絞盡腦汁所花的代價。</p><p><b> (2)單純二次開發(fā)</b></p><p> 完全借助于GIS工具軟件提供的開發(fā)語言進行應用系統(tǒng)開
33、發(fā)。GIS工具軟件大多提供了可供用戶進行二次開發(fā)的宏語言,如ESRI的ArcView提供了Avenue語言,MapInfo公司研制的MapInfo Professional提供了MapBasic語言等等。用戶可以利用這些宏語言,以原GIS工具軟件為開發(fā)平臺,開發(fā)出自己的針對不同應用對象的應用程序。這種方式省時省心,但進行二次開發(fā)的宏語言,作為編程語言只能算是二流,功能極弱,用它們來開發(fā)應用程序仍然不盡如人意。</p>&l
34、t;p><b> (3)集成二次開發(fā)</b></p><p> 集成二次開發(fā)是指利用專業(yè)的GIS工具軟件,如MapInfo、ArcView等,實現(xiàn)GIS的基本功能,以通用軟件開發(fā)工具尤其是可視化開發(fā)工具,如Visual C++、Delphi、Visual Basic、Power Builder等為開發(fā)平臺,進行二者的集成開發(fā)。</p><p> 集成二次開
35、發(fā)目前主要有兩種方式:</p><p> 1) OLE/DDE</p><p> 采用OLE Automation技術或利用DDE技術,用軟件開發(fā)工具開發(fā)前臺可執(zhí)行應用程序,以OLE自動化方式或DDE方式啟動GIS工具軟件在后臺執(zhí)行,利用回調(diào)技術動態(tài)獲取其返回信息,實現(xiàn)應用程序中的地理信息處理功能。</p><p><b> 2) GIS控件<
36、/b></p><p> 利用GIS工具軟件生產(chǎn)廠家提供的建立在OCX技術基礎上的GIS功能控件,如ESRI的MapObjects、MapInfo公司的MapX等,在VC++等編程工具編制的應用程序中,直接將GIS功能嵌入其中,實現(xiàn)地理信息系統(tǒng)的各種功能。</p><p><b> 三種實現(xiàn)方式的分析</b></p><p> 由于
37、獨立開發(fā)難度太大,單純二次開發(fā)受GIS工具提供的編程語言的限制差強人意,因此結合GIS工具軟件與當今可視化開發(fā)語言的集成二次開發(fā)方式就成為GIS應用開發(fā)的主流。它的優(yōu)點是既可以充分利用GIS工具軟件對空間數(shù)據(jù)庫的管理、分析功能,又可以利用其它可視化開發(fā)語言具有的高效、方便等編程優(yōu)點,集二者之所長,不僅能大大提高應用系統(tǒng)的開發(fā)效率,而且使用可視化軟件開發(fā)工具開發(fā)出來的應用程序具有更好的外觀效果,更強大的數(shù)據(jù)庫功能,而且可靠性好、易于移植、
38、便于維護,尤其是使用OCX技術利用GIS功能組件進行集成開發(fā),更能表現(xiàn)出這些優(yōu)勢。</p><p> 由于上述優(yōu)點,集成二次開發(fā)正成為應用GIS開發(fā)的主流方向。這種方法唯一的缺點是前期投入比較大,需要同時購買GIS工具軟件和可視化編程軟件,但“工欲善其事,必先利其器”,這種投資值得。目前許多軟件公司都開發(fā)了很多ActiveX控件,合理選擇和運用現(xiàn)成的控件,減少了開發(fā)者的編程工作量,使開發(fā)者避開某些應用的具體編程
39、,直接調(diào)用控件,實現(xiàn)這些具體應用,不僅可以縮短程序開發(fā)周期,使編程過程更簡潔,用戶界面更友好,可以使程序更加靈活、簡便。與利用OLE Automation技術作為服務器的MapInfo相比,利用控件開發(fā)速度快,占用資源少,而且易實現(xiàn)許多底層的編程和開發(fā)功能[4]。</p><p> 電子導航基本功能在VC++中的實現(xiàn)</p><p> 利用MapX實現(xiàn)GIS基本功能</p>
40、<p> 在進行MapX開發(fā)之前,首先要在計算機中正確的安裝了MapX控件和VC++應用程序。下面就用一個具體的實例,介紹在VC++中集成MapX的方法。</p><p> 將MapX支持類庫加入工程</p><p> 利用VC++環(huán)境下的應用程序生成向導創(chuàng)建一單文檔界面應用程序VCDZDH。先將位于MapX的安裝路徑下的子目錄Samples40\C++\Cpp中的Ma
41、pX.h和MapX.cpp文件拷貝到當前應用程序所在的VCDZDH文件夾下,然后從Project菜單中選擇Add to Project>Files命令,此時打開了Insert Files into Project對話框,選擇VCDZDH文件夾下的MapX.cpp和MapX.h文件加入到工程中。</p><p><b> 地圖的顯示</b></p><p>
42、在VCDZDH文件夾下新建文件夾map,map中復制MapInfo格式的地圖文件及Geoset(.GST)文件MY.GST。用戶只需要打開Geoset文件,就可以按預先定制的方式顯示各層地圖。通過以下步驟,就可以實現(xiàn)地圖的顯示[5]。</p><p> 1) 在VCDZDHView.h文件中,加入MapX.h對象的頭文件,并聲明CMapX類型的變量m_ctrlMapX。方法如下:</p><
43、p> #include“MAPX.H”</p><p> Class CVCDZDHView::publicCView</p><p><b> {</b></p><p> protected:</p><p> CMapX m_ctrlMapX;// 聲明CMapX類型的變量m_ctrlMapX&l
44、t;/p><p><b> }</b></p><p> 2) 為MapX創(chuàng)建一個資源ID。選擇View Resource Symbols,并點擊New按鈕,輸入名稱IDC_MAP,值取默認數(shù)值。</p><p> 3) 在VCDZDHView.h文件中聲明int類型的全局變量m_created和CString類型的全局變量m_tempcli
45、entpath。通過類向導創(chuàng)建消息映射函數(shù)WM_CREATE。選擇“建立類向導”或使用快捷鍵CTRL+W,可以打開類向導。從類名中選擇CVCDZDHView類,在消息框中選擇WM_CREATE消息,然后添加函數(shù),編輯代碼創(chuàng)建MapX對象。代碼如下:</p><p> int CVCDZDHView::OnCreate(LPCREATESTRUCT lpCreateStruct) </p><
46、p><b> {</b></p><p> if (!m_ctrlMapX.Create(NULL,WS_VISIBLE,CRect(0,0,100,100),this,IDC_MAP))</p><p> return -1;</p><p><b> }</b></p><p>
47、 4) 采用同樣的方法創(chuàng)建WM_SIZE消息映射函數(shù)。該函數(shù)用來調(diào)整地圖大小使其充滿客戶區(qū)。具體代碼如下:</p><p> void CVCDZDHView::OnSize(UINT nType,int cx,int cy)</p><p><b> {</b></p><p> CView::OnSize(nType,cx,cy);&
48、lt;/p><p> m_ctrlMapX.MoveWindow(0,0,cx,cy);//調(diào)整地圖大小</p><p><b> }</b></p><p> 5) 采用同樣的方法創(chuàng)建WM_SETFOCUS消息映射函數(shù)。修改函數(shù)使得當窗口獲得焦點時,地圖控件獲得焦點。具體代碼如下。</p><p> void CV
49、CDZDHView::OnSetFocus(CWnd*pOldWnd)</p><p><b> {</b></p><p> CView::OnSetFocus(pOldWnd);</p><p> m_ctrlMapX.SetFocus();//當窗口獲得焦點時,地圖控件獲得焦點</p><p><b&g
50、t; }</b></p><p> 通過以上步驟,將應用程序編譯運行就可顯示地圖。如圖2.1所示:</p><p> 圖2.1 地圖的顯示</p><p><b> 使用地圖標準工具</b></p><p> 在地圖顯示出來后,用戶通常要以各種比例查看地圖的全局、局部或細部,必須提供諸如放大、縮小和
51、漫游等功能。采用MapX通用工具,可以非常方便地實現(xiàn)上述功能。設定MapX使用標準工具的方法很簡單,只需設定地圖對象的CulrentTool屬性。下面的例子是用標準放大工具實現(xiàn)放大功能。</p><p> 添加新菜單項資源,輸入標題“工具”,在“工具”下添加子菜單,輸入標題“放大”及ID為ID_ZOOM_ IN。打開類向導,選擇視圖類CVCDZDHView,為菜單項ID_ZOOM_IN添加COMMAND消息映射
52、函數(shù)OnZoomIn(),并編輯代碼如下。</p><p> void CVCDZDHView::OnZoomIn()</p><p><b> {</b></p><p> m_ctrlMapX.SetCurrentTool(miZoomInToo1);//miZoomInTool為放大工具的常量</p><p>
53、;<b> }</b></p><p> 編譯運行程序,選擇“工具>放大”,就會看到此時光標變?yōu)榉糯箸R,單擊鼠標就會實現(xiàn)放大功能。如圖2.2所示:</p><p> 圖2.2 放大功能演示</p><p> 可用相同方法實現(xiàn)縮小、漫游、全圖等標準工具的功能。其它的功能跟上面的方法類似,只是需要修改指示常量。表 2.1中列出了部分M
54、apX工具的指示常量[9]。</p><p> 表2.1 部分MapX工具的指示常量</p><p><b> 圖層控制工具</b></p><p> 為了使用戶方便查詢各個圖層,通常要在電子導航系統(tǒng)中設計圖層控制工具。在菜單中建立圖層控制菜單,設置圖層控制ID為ID_VIEW_LAYERCONTROL,然后建立類向導,選擇CVCDZDH
55、View類,添加如下函數(shù):</p><p> void CVCDZDHView::OnViewLayercontrol() </p><p><b> {</b></p><p><b> try </b></p><p><b> {</b></p>&
56、lt;p> VARIANT vHelpFile, vHelpID;</p><p> vHelpFile.vt = VT_ERROR;</p><p> vHelpFile.scode = DISP_E_PARAMNOTFOUND;</p><p> vHelpID.vt = VT_ERROR;</p><p> vHel
57、pID.scode = DISP_E_PARAMNOTFOUND;</p><p> CMapXLayers layers = m_ctrlMapX.GetLayers();</p><p> layers.LayersDlg(vHelpFile, vHelpID);</p><p><b> }</b></p><p
58、> catch (COleDispatchException *e) </p><p><b> {</b></p><p> e->ReportError();</p><p> e->Delete();</p><p><b> }</b></p>
59、<p> catch (COleException *e) </p><p><b> {</b></p><p> e->ReportError();</p><p> e->Delete();</p><p><b> }</b></p><
60、;p><b> }</b></p><p> 這樣,就添加上了圖層控制工具,運行程序,該功能如圖2.3所示:</p><p> 圖2.3 圖層控制工具</p><p> 自定義工具測量折線距離</p><p> MapX提供的地圖標準工具能滿足一般需要,但在一些特殊地方,用戶可能需要某種特殊工具來完成某些
61、特定的地圖操作功能。因此,MapX提供了用戶自定義工具的方法,這樣可以大大擴展MapX的應用范圍??墒褂玫貓D對象的CreateCustomTool方法創(chuàng)建自定義工具。下面是用自定義工具實現(xiàn)折線距離的計算。</p><p><b> 創(chuàng)建用戶自定義工具</b></p><p> 為了滿足用戶需要,使用戶方便查詢兩地之間的距離,我們利用自定義工具在電子導航系統(tǒng)中設計了
62、折線距離計算功能。方法如下:</p><p> 首先,在VCDZDH.h文件中定義常量。</p><p> #define MYTOOL_DISTANCE 1</p><p> 然后,在VCDZDH.cpp文件中的OnCreate()函數(shù)中加入如下代碼,從而創(chuàng)建一個用戶自定義工具。</p><p> int CVCDZDHView::
63、OnCreate(LPCREATESTRUCT lpCreateStruct)</p><p><b> {</b></p><p> if(CView::OnCreate(1pCreateStruct) = = -1)</p><p> return -1;</p><p><b> ……</
64、b></p><p> m_ctrlMapX.CreateCustomTool(MYTOOL_DISTANCE,miToolTypePoly,miCrossCursor); //MYTOOL_DISTANCE代表自定義工具的常量,miToolTypePoly描述了該工具的行為是畫折線,miCrossCursor表示指定光標的形式</p><p><b> retur
65、n 0;</b></p><p><b> }</b></p><p> 編程實現(xiàn)自定義工具的行為</p><p> 在創(chuàng)建了用戶自定義工具后,需在ToolUsed事件中實現(xiàn)該工具是如何工作的。要處理MapX事件,首先需要為要處理的事件創(chuàng)建一事件槽,其方法如下。</p><p> 在VCDZDHVie
66、w.h文件中,在DECLARE_MESSAGE_MAP()行下面加入如下一行代碼。</p><p> DECLARE_EVENTSINK_MAP()</p><p> 然后在VCDZDHView.cpp文件中,加入如下代碼。</p><p> BEGIN_EVENTSINK_M AP(CVCDZDHView,CView)</p><p>
67、; ON_EVENT(CVCDZDHView,IDC_M AP,11,OnPolyTooIUsedMap,VTS_I2 VTS_I4 VTS_DISPATCH VTS_BOOL VTS_BOOL VTS_PBOOL) //11代表PolyToolused,OnPolyToolUsedMap是事件響應函數(shù)的名稱。</p><p> END_EVENTSINK_MAP()</p><p>
68、 BEGIN_EVENTSINK_MAP(CVCDZDHView,CView)和END_EVENTSINK_MAP()兩行代碼之間加入的,就是要處理的事件。切換到VCDZDHView.h文件中,聲明事件響應函數(shù),代碼如下。</p><p> void OnPolyToolUsedMap(short ToolNum,long Flags,LPDISPATCH Points,BOOL bShift,BOOL bC
69、trl,BOOL FAR*EnableDefauh)</p><p> 然后在VCDZDHView.cpp中加入函數(shù)的實現(xiàn)代碼。</p><p> void CVCDZDHView::OnPolyToolUsedMap(short ToolNum,long ags,LPDISPATCH Points,BOOL bShift,BOOL bCtrl,BOOL FAR*EnableDefau
70、lt)</p><p><b> {</b></p><p> if (ToolNum==MYTOOL_DISTANCE);</p><p><b> {</b></p><p> CMapXPoints pts;</p><p><b> long n;
71、</b></p><p><b> long i;</b></p><p><b> try</b></p><p><b> {</b></p><p> pts.AttachDispatch(Points,FALSE);</p><p
72、> double dDistanceTot=0.0;</p><p> n=pts.GetCount();</p><p> for(i=1;i<n;i++)</p><p><b> {</b></p><p> CMapXPoint pt1=pts.Item(i);</p><
73、;p> CMapXPoint pt2=pts.Item(i+1);</p><p> Double d=m_ctrlMapX.Distance(pt1.GetX(),pt1.GetY(),pt2.GetX(),pt2.GetY());</p><p> dDistanceTot+=d;</p><p><b> }</b><
74、/p><p> CString str;</p><p> str.Format("總距離為:%f公里",dDistanceTot);</p><p> ((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0,str);</p><p> //在狀
75、態(tài)欄中顯示折線距離</p><p><b> }</b></p><p> catch(COleDispatchException *e)</p><p><b> {</b></p><p> e->ReportError();</p><p> e->
76、;Delete();</p><p><b> }</b></p><p> catch(COleException *e)</p><p><b> {</b></p><p> e->ReportError();</p><p> e->Delete
77、();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> 為了在狀態(tài)欄中顯示折線距離,還必須在VCDZDH.cpp文件中添加CMainFrame類的頭文件。</p><
78、p> #include“MainFrm.h”</p><p> 并且將CMainFrame類中的mwndStatusBar由受保護的變量改為全局變量。</p><p><b> 調(diào)用自定義工具</b></p><p> 在“工具”下拉菜單中添加“折線距離”子菜單項,ID為ID_DISTANCE_TOOL。打開類向導,選擇視圖類CV
79、CDZDHView,為菜單項ID_DISTANCE_TOOL添加COMMAND消息映射函數(shù)OnPolydistancetool(),添加代碼如下。</p><p> void CVCDZDHView::OnDistanceTool() </p><p><b> {</b></p><p> // TODO: Add your comma
80、nd handler code here</p><p> m_ctrlMapX.SetCurrentTool(MYTOOL_DISTANCE);//調(diào)用自定義工具</p><p><b> }</b></p><p> 編譯并運行程序,如圖3.1所示為使用“折線距離”工具的應用程序界面。</p><p> 圖3
81、.1 折線距離演示</p><p><b> 最優(yōu)路徑分析</b></p><p> 對城市道路網(wǎng)進行最短路徑分析,需要把城市道路網(wǎng)絡實體抽象化為網(wǎng)絡圖論理論中的網(wǎng)絡圖,然后通過圖論中的網(wǎng)絡分析理論來實現(xiàn)道路網(wǎng)絡的最短路徑分析。在實際應用中,道路網(wǎng)的表現(xiàn)形式一般為數(shù)字化的矢量地圖,其網(wǎng)絡空間特征中的交叉路口坐標和道路位置坐標是在地圖上借助圖形來識別和解釋的;而為了
82、能夠高效率地進行最短路徑分析,必須首先將其按結點和弧的關系抽象為圖的結構。這就需要先對原始道路圖進行預處理,構建其相應的網(wǎng)絡拓撲關系,然后才能進行最短路徑分析等各種操作。下面介紹一種Dijkstra算法。</p><p> 實現(xiàn)過程及其算法分析</p><p> Dijkstra(迪杰斯特拉)算法是典型的最短路徑路由算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑。主要特點是以起始點為中
83、心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優(yōu)解,但由于它遍歷計算的節(jié)點很多,所以效率低。</p><p> Dijkstra算法一般的表述通常有兩種方式,一種用永久和臨時標號方式,一種是用OPEN, CLOSE表方式。</p><p> 其采用的是貪心法的算法策略,大概過程:</p><p> 創(chuàng)建兩個表,OPEN, CLOSE
84、。</p><p> OPEN表保存所有已生成而未考察的節(jié)點,CLOSED表中記錄已訪問過的節(jié)點。</p><p> 1. 訪問路網(wǎng)中距離起始點最近且沒有被檢查過的點,把這個點放入OPEN組中等待檢查。</p><p> 2. 從OPEN表中找出距起始點最近的點,找出這個點的所有子節(jié)點,把這個點放到CLOSE表中。</p><p>
85、3. 遍歷考察這個點的子節(jié)點。求出這些子節(jié)點距起始點的距離值,放子節(jié)點到OPEN表中。</p><p> 4. 重復第2和第3步,直到OPEN表為空,或找到目標點。</p><p> Dijkstra算法的基本思路是:假設每個點都有一對標號 (dj, pj),其中dj是從起源點s到點j的最短路徑的長度 (從頂點到其本身的最短路徑是零路(沒有弧的路),其長度等于零);pj則是從s到j的最
86、短路徑中j點的前一點。求解從起源點s到點j的最短路徑算法的基本過程如下:</p><p> 圖4.1 算法流程圖</p><p> 1) 初始化。起源點設置為:① ds=0, ps為空;② 所有其他點: di=∞,pi=?;③ 標記起源點s,記k=s,其他所有點設為未標記的。</p><p> 2) 檢驗從所有已標記的點k到其直接連接的未標記的點j的距離,并設
87、置:dj=min[dj, dk+lkj],式中,lkj是從點k到j的直接連接距離。</p><p> 3) 選取下一個點。從所有未標記的結點中,選取dj 中最小的一個i:di=min[dj, 所有未標記的點j],點i就被選為最短路徑中的一點,并設為已標記的。</p><p> 4) 找到點i的前一點。從已標記的點中找到直接連接到點i的點j*,作為前一點,設置:i=j*。</p&g
88、t;<p> 5) 標記點i。如果所有點已標記,則算法完全推出,否則,記k=i,轉到2)再繼續(xù)。</p><p> 為了實現(xiàn)Dijkstra算法,在程序中首先引入三個類:</p><p> class VERTEX //頂點類</p><p><b> {</b></p><p> publi
89、c int id;</p><p> public int Searched; //0表示從來沒有搜索過,表示搜索過,但沒有完成,表示搜索完成,該點的最短路徑已經(jīng)找到</p><p> public IPoint pPoint;</p><p> public VERTEX Prev;</p><p> public VERTEX
90、Next;</p><p> public Link Neighbor;//一個鏈接關系,相當于線節(jié)點</p><p> public double Weight;//權重,初始時置為無窮大,搜尋最短路徑時置為該點當前最短路徑長度</p><p> public VERTEX ShortPathPre;//在最短路徑上的前一個點</p><
91、p> public int LineID;//最短路徑中與前一個點之間的線的ID</p><p> public SearchLink SLink;//Open或Close表中的鏈接</p><p><b> }</b></p><p> class Link//點的鄰接關系</p><p><b&g
92、t; {</b></p><p> public VERTEX v1;//每個Link對象的v1都應該指向它所附屬的點節(jié)點</p><p> public VERTEX v2;//每個Link對象的v2都應該指向與它所附屬的點相鄰的那個點節(jié)點</p><p> public double weight;//線的權重</p><
93、p> public Link v1Next;</p><p> public Link v2Next;</p><p> public int LineID;}</p><p> class SearchLink//搜尋路徑時的鄰接關系,用來放入Open或Close表中</p><p><b> {</b>
94、;</p><p> public VERTEX v;</p><p> public SearchLink Prev;</p><p> public SearchLink Next;</p><p><b> }</b></p><p> VERTEX類用來存儲點節(jié)點,Link類用來
95、存儲鄰接關系,SearchLink是一個臨時的中間鄰接關系,在尋徑時替代VERTEX實例進行運算,用來維持鄰接多重表。系統(tǒng)的主要功能函數(shù)為:</p><p> private VERTEX BuildTopo(IFeatureLayer pFeatLayerP,IFeatureLayer </p><p> pFeatLayerL,IPoint pStartV,IPoint pEndV
96、,ref int PointCount,ref int</p><p> EdgeCount),主要用來建立拓撲關系</p><p> private void shortpath(),查詢最短路徑的主函數(shù)</p><p> private void InsertOrder(SearchLink vIN,ref SearchLink vTO)按權重的升序插入&
97、lt;/p><p> private void Insert(SearchLink vIN,ref SearchLink vTO)插入</p><p> private void Delete(ref SearchLink vOUT,ref SearchLink vFROM)從鏈表中刪除</p><p><b> 建立拓撲關系:</b><
98、;/p><p> VERTEX[]RoadNode=new VERTEX[NodeCount];</p><p><b> indexP=0;</b></p><p> pFeatureP=pFeatCsrP.NextFeature();</p><p> while(null!=pFeatureP)</p&g
99、t;<p><b> {</b></p><p> indexP=(int)pFeatureP.get_Value(pFeatureP.Fields.FindField("ID"));</p><p> if(indexP<0)</p><p><b> {</b></
100、p><p> pFeatureP=pFeatCsrP.NextFeature();</p><p><b> continue;</b></p><p><b> }</b></p><p> RoadNode[indexP]=new VERTEX();</p><p>
101、 RoadNode[indexP].Neighbor=null;</p><p> RoadNode[indexP].pPoint=(IPoint)pFeatureP.Shape;</p><p> RoadNode[indexP].Searched=0;</p><p> RoadNode[indexP].ShortPathPre=null;</p&
102、gt;<p> RoadNode[indexP].Weight=double.MaxValue;</p><p> pFeatureP=pFeatCsrP.NextFeature();</p><p><b> }</b></p><p> 首先建立VERTEX數(shù)組,用來存放點節(jié)點,在遍歷點層元素的過程中,根據(jù)點的ID號找
103、到數(shù)組索引號,生成點節(jié)點的實例(即VERTEX實例)。建立這一過程的時間消耗與點的數(shù)量n成正比,即時間復雜度為O(n)。</p><p> pFeatCsrL=pFeatClsL.Search(null,false);</p><p> int indexP1=0,indexP2=0;</p><p> pFeatureL=pFeatCsrL.NextFeat
104、ure();</p><p> while(null!=pFeatureL)//遍歷線對象,根據(jù)線的首尾節(jié)點ID,即點的索引,找到點,建立鏈接關系</p><p><b> {</b></p><p><b> cnt1++;</b></p><p> cntEdge++;</p>
105、;<p> vLink1=vLink2=null;</p><p> pPointCol=(IPointCollection)pFeatureL.Shape;</p><p> p1=pPointCol.get_Point(0);</p><p> p2=pPointCol.get_Point(pPointCol.PointCount-1);&
106、lt;/p><p> vWork=vHead.Next;</p><p> flag1=flag2=0;</p><p> indexP1=(int)pFeatureL.get_Value(pFeatureL.Fields.FindField("STNODEID"));</p><p> indexP2=(int)pF
107、eatureL.get_Value(pFeatureL.Fields.FindField("EDNODEID"));</p><p> indexP=(int)pFeatureL.get_Value(pFeatureL.Fields.FindField("FID"));</p><p> //依次獲得線元素的STNODEID、EDNODEID、F
108、ID三個字段的值</p><p> vLink1=new Link();</p><p> vLink1.LineID=indexP;</p><p> vLink1.weight=(double)(int)pFeatureL.get_Value(pFeatureL.Fields.FindField("Weight"));</p>
109、;<p> vLink1.v1=RoadNode[indexP1];</p><p> vLink1.v1Next=RoadNode[indexP1].Neighbor;</p><p> RoadNode[indexP1].Neighbor=vLink1;//獲得線元素的STNODEID值之后,直接可以得到點節(jié)點在數(shù)組中的位置</p><p>
110、 vLink1.v2=RoadNode[indexP2];</p><p> vLink1.v2Next=RoadNode[indexP2].Neighbor;</p><p> RoadNode[indexP2].Neighbor=vLink1;</p><p> pFeatureL=pFeatCsrL.NextFeature();</p>
111、<p><b> }</b></p><p> 點的數(shù)組建立完成之后,可以開始遍歷線層元素,每取得一個線元素,則可以得到首尾節(jié)點的ID,根據(jù)首尾節(jié)點ID(即首尾節(jié)點在數(shù)組中的索引)得到首尾節(jié)點,分別為首尾節(jié)點建立鄰接關系vLink1和vLink2,從線元素獲得首尾節(jié)點的過程的時間復雜度為O(1),而外層while循環(huán)是遍歷線層元素,時間復雜度為O(n),經(jīng)過這一過程,拓撲關系基
112、本建立完成,由于采用數(shù)組存儲VERTEX元素的目的是建立索引,減少建立拓撲關系時點的搜索時間,因此,拓撲關系建立完成后,為了方便運算,也為了盡量減少數(shù)組元素所占用的大塊內(nèi)存區(qū)域,把VERTEX元素從數(shù)組中摘下并建立環(huán)狀鏈表:</p><p> vWork=vHead;</p><p> for(indexP=1;indexP<NodeCount;indexP++)</p&g
113、t;<p><b> {</b></p><p> if(RoadNode[indexP]!=null)</p><p><b> {</b></p><p> RoadNode[indexP].Prev=vWork;</p><p> RoadNode[indexP].Ne
114、xt=vWork.Next;</p><p> vWork.Next.Prev=RoadNode[indexP];</p><p> vWork.Next=RoadNode[indexP];</p><p> vWork=RoadNode[indexP];</p><p><b> }</b></p>
115、<p><b> }</b></p><p> vWork.Next=vHead;</p><p> vHead.Prev=vWork;</p><p> 通過這一步操作,環(huán)狀的鄰接多重表建立完成。以上三次遍歷并沒有嵌套關系,因此整個建立鄰接多重表的時間復雜度為O(n)。</p><p><b
116、> 查詢最短路徑</b></p><p><b> 查詢最短路徑:</b></p><p> int flag=0;</p><p><b> int c=0;</b></p><p> vWork=vHead.Next;</p><p> wh
117、ile(c<PointCnt){//根據(jù)點節(jié)點的數(shù)量,循環(huán)設定點節(jié)點中各字段的初始值</p><p> if(vWork.id==pStartID)</p><p><b> {</b></p><p> flag++;vHead.Next=vWork;</p><p><b> }</b&
118、gt;</p><p> if(vWork.id==pEndID)</p><p><b> {</b></p><p><b> flag++;</b></p><p> vTail.Next=vWork;</p><p><b> }</b>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于AIS的電子海圖導航系統(tǒng)設計與實現(xiàn).pdf
- 基于qt的校園導航系統(tǒng)
- 基于Android的在線移動電子導航系統(tǒng)的研究與實現(xiàn).pdf
- 基于MapInfo平臺的電子地圖導航系統(tǒng)設計與實現(xiàn).pdf
- 基于Android的工程導航系統(tǒng)設計.pdf
- 基于ARM的汽車導航系統(tǒng)設計.pdf
- 基于arm-linux的gps導航系統(tǒng)
- 基于主動服務的用戶導航系統(tǒng).pdf
- 基于類目的電子商務導航系統(tǒng)設計與實現(xiàn).pdf
- 基于GML的無線室內(nèi)導航系統(tǒng).pdf
- 基于QT的GPS車載導航系統(tǒng).pdf
- 基于MapX的校園電子地圖導航系統(tǒng)的研究與設計.pdf
- 基于機器視覺的農(nóng)業(yè)導航系統(tǒng).pdf
- 57971.基于svg的移動導航系統(tǒng)
- 汽車導航系統(tǒng)電子地圖的設計與實現(xiàn).pdf
- 電子地圖在車載導航系統(tǒng)中的應用.pdf
- SINS-GPS-電子羅盤組合導航系統(tǒng)設計.pdf
- 基于armlinux的gps導航系統(tǒng)論文副本
- 基于gps的車載導航系統(tǒng)設計與實現(xiàn)
- 車載GPS-電子地圖導航系統(tǒng)的研究.pdf
評論
0/150
提交評論