用MapX與C#開發地理信息系統

轉:http://www.cnblogs.com/dachie/archive/2010/08/17/1801598.htmlhtml

第四章 MapX與C#實例... 5git

4.1 MapX圖層創建... 5程序員

4.1.1 MapX數據與地圖的組織結構... 5web

4.1.2 實例1:創建/添加一個用戶自定義圖層... 5sql

4.1.3 在MapX中使用柵格圖層... 7數據庫

4.1.4 實例2:柵格圖層的創建... 8編程

4.2 圖元自動標註... 9c#

4.2.1 實例3:給圖層加上自動標註功能... 9windows

4.3 MapX地圖集... 9api

4.3.1 什麼是MapX地圖集(Geoset)?. 9

4.3.2 實例4:打開已存在的地圖集文件... 10

4.3.3 實例5:保存地圖集... 10

4.4 內置工具的使用... 11

4.4.1 使用標準工具... 11

4.4.3 實例6:內置標準工具的使用... 11

4.5自定義工具... 12

4.5.1 建立自定義工具... 12

4.5.2 實例7:建立測量長度和麪積自定義工具... 13

4.6 MapX地圖符號樣式的定製... 14

4.7在圖層上添加自定義圖元... 15

4.7.1 實例8:鼠標點擊向圖層上添加圖元... 15

4.7.2 實例9:給定座標向圖層上自動添加圖元... 17

4.8 得到圖元屬性... 20

4.8.1實例10:獲取選定圖元的屬性... 20

4.9 圖元的選取... 21

4.9.1 實例11:實現InfoTip功能... 21

4.10 圖元屬性的修改... 22

4.10.1 實例12:修改圖元屬性... 22

4.11 實例13:圖元的查詢... 23

4.12 實例14:鷹眼圖的實現... 24

4.13 數據綁定... 26

4.14 GPS在GIS系統中的應用... 27

4.14.1定位信息的接收... 27

4.14.2定位信息的提取... 27

4.14.3定位信息在MapX中的顯示... 28

4.14.4 實例15:GPS定位系統的應用... 28

4.15 多媒體信息在GIS系統中的應用... 33

4.15.1 GIS中嵌入多媒體的方法... 33

4.15.2 實例16:在MapX系統中嵌入多媒體數據... 33

第五章 MapX與Oracle結合... 35

5.1 Oracle數據庫對GIS的支持... 35

5.1.1面向對象的數據庫支持... 35

5.1.2.Oracle spatial組件的引入... 35

5.2 按部就班學習Oracle Spatial在MapX中的應用... 36

5.2.1 oralce服務器的安裝... 36

5.2.2 準備由Oracle Spatial存儲的圖層文件... 36

5.2.3 Easyloader上載工具... 36

5.2.4 圖層信息在Oracle中的存儲結構... 38

5.2.5用程序實現MapX圖元到oracle數據庫的上載... 42

5.2.6 用程序實現oracle數據表數據下載至MapX中顯示... 44

5.2.7 圖元樣式的還原... 46

5.3 在網絡環境下實現圖層信息共享... 47

第六章 MapCtrl控件的開發方法... 57

6.1 主要功能... 57

6.2 開發步驟... 57

6.3 程序實現... 58

第七章 分發基於.net平臺的MapX應用程序.. 91

7.1 .NET Framework 概述... 91

7.2 .NET Framework 的主要組件和功能... 92

7.2.1公共語言運行庫... 92

7.2.2 .NET Framework 類庫... 92

7.3 安裝 .NET Framework. 93

7.4 Map客戶安裝... 93

7.5 製做安裝程序... 93

 

第四章 MapX與C#實例

這一章咱們經過若干專題來介紹用C#如何開發MapX應用程序。

4.1 MapX圖層創建

4.1.1 MapX數據與地圖的組織結構

MapX地圖是由一個一個圖層合成而來。 MapX 將其全部基礎信息以 MapInfo表的形式組織起來;每一表都是一組 MapInfo 文件,用來在地圖中創建一個圖層。

這一組MapInfo文件包括:

.<Somefile>.tab:圖層屬性結構定義文件,該文件描述 MapInfo 表的結構。它是描述包含數據文件格式的小文本文件。

.<Somefile>.dat(.mdb、.aid 或 .dbf):圖層屬性記錄文件,這些文件包含表格數據.可用記事本或相應的數據庫管理軟件打開瀏覽數據。

.<Somefile>.map:圖層空間記錄文件,該文件描述空間圖形對象(若是該表沒有任何地圖對象,則該文件將不存在)。

.<Somefile>.id:圖層索引文件,該文件是將數據與空間對象相連接的交叉引用文件(若是該表沒有任何地圖對象,則該文件將不存在)。

.<Somefile>.ind:它是索引文件.經過該索引文件,您可使用 Find 對象搜索地圖對象。

要建立圖層就要了解這些內部機理,方能思路清晰。下面是一個建立自定義層的例子。

4.1.2 實例1:創建/添加一個用戶自定義圖層

4.1.2.1 程序功能

在地圖上創建一個用戶自定義的圖層,該圖層上的每一個圖元包括圖元編號、圖元名稱、圖元描述、圖元座標等屬性,而且生成一個數據集與該圖層綁定。

4.1.2.2 程序實現

public bool NewUserLayer(string layerName)

//新建自定義圖層,若存在則添加到圖層集中

{

MapXLib.Layer layer;

MapXLib.Fields flds=new MapXLib.FieldsClass();

flds.AddStringField("source",50,false);

flds.AddStringField("name",50,false);

flds.AddStringField("identity",50,false);

flds.AddStringField("description",50,false);

flds.AddStringField("foundTime",50,false);

flds.AddFloatField("objX",false);

flds.AddFloatField("objY",false);

MapXLib.LayerInfo layerInfo;

layerInfo=new MapXLib.LayerInfoClass(); layerInfo.AddParameter("FileSpec",@appDirectory+"\\"+layerName+".tab");

layerInfo.AddParameter("Name",layerName);

layerInfo.AddParameter("Fields",flds);

layerInfo.AddParameter("AutoCreateDataset",1);

layerInfo.AddParameter("DatasetName","ds"+layerName);

if (!File.Exists(@appDirectory+"\\"+layerName+".tab"))

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeNewTable;

}

else

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTab;

}

try

{

layer = axMap1.Layers.Add(layerInfo,1);

axMap1.Refresh();

return true;

}

catch

{

return false;

}

}

4.1.2.3 程序說明

(1)flds是MapXLib.Fields對象,即圖層的屬性字段集,未來會出如今.tab文件中。用new MapXLib.FieldsClass()來實例化一個新的Fields對象。在對任何對象進行引用前,必須先實例化該對象。

AddStringField, AddFloatField是Fields字段集對象的兩個方法,分別用來定義字符串字段及浮點型字段,並添加到Fields字段集對象中。有關AddStringField(),AddFloatField()的語法請參考MapX文檔。

(2)MapXLib.LayerInfo對象是用來增長新層的一個很是好的方法,在layerInfo中具體定義該層的一些參數。

l layerInfo.AddParameter("FileSpec",@appDirectory+"\\userDrawLayer.tab"):指定該層的存放路徑。@爲轉義字符, appDirectory爲應用程序目錄變量,可用Directory.GetCurrentDirectory()來獲得。 userDrawLayer.tab爲該層的.tab文件名。

l layerInfo.AddParameter("Name","userDrawLayer"):指定該層的名字」userDrawLayer」,名字將會出如今圖層控制對話框中。

l layerInfo.AddParameter("Fields",flds):指定該圖層的屬性字段集對象,即上面新定義的MapXLib.Fields對象。

l layerInfo.AddParameter("AutoCreateDataset",1):指定是否自動產生數據集,1自動產生,0不產生。有關數據集的概念,在後續部分再重點做介紹。

l layerInfo.AddParameter("DatasetName","dsUserLayer");指定數據集的名字「dsUserLayer」。

l layerInfo.Type屬性:指定新層的類型。MapXLib.LayerInfoTypeConstants.miLayerInfoTypeNewTable:指定產生一新層。 MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTab:指定一存在的圖層。

l axMap2.Layers.Add(layerInfo,1)語句:增長layerInfo所定義的新層,其中「1」表明增長至圖層最上面。

這樣就獲得一個名爲userdrawlayer的圖層,而且獲得一個名爲dsUserLayer的數據集與該圖層自動綁定。利用這種方法創建數據集很是方便,也很是好用。在通常狀況下均可知足系統的需求。該數據集可理解爲一張表格,該表格的結構即爲上面定義的flds字段集對象,該表格中的每個記錄對應圖層上每個圖元的屬性記錄。

編號

名稱

描述

經度

緯度

01

北京市

中華人民共和國國首都

..

..

(3)LabelProperties用來講明如何用數據集中的數據標註圖層上每個圖元。

layer.LabelProperties.Dataset:指定數據集對象。

layer.LabelProperties.DataField:指定用數據集中哪一個字段值標註圖元。

layer.LabelProperties.Position:指定標註位置。

layer.LabelProperties.Style.TextFont.Size:指定標註的字體及大小等。

layer.LabelProperties.Offset:指定標註離圖元中心的距離。

下面咱們就能夠在剛創建好的圖層上描繪本身的內容了。

4.1.3 在MapX中使用柵格圖層
4.1.3.1什麼是柵格圖象?

柵格圖象是由多行微小的點(象素)組成的一種計算機化的圖象。若是手頭有掃描儀及掃描軟件,能夠經過掃描一幅紙張地圖來建立柵格圖象。完成地圖掃描並將其保存於文件中後,便可在MapInfo中顯示該文件。

有多種不一樣的柵格圖象文件格式。MapInfo可以處理如下格式的柵格圖象文件:JPEG、GIF、TIFF、PCX、BMP、TGA(Targa)和BIL(SPOT衛星圖片)。

4.1.3.2什麼是配準柵格圖象?

配準一幅柵格圖象時,要輸入地圖座標(如經度/緯度),並指定柵格圖象上與該座標對應的點。由於柵格圖象文件不包含地理座標信息,因此要在MapInfo Professional中顯示柵格圖象前必須進行配準,以使MapInfo Professional在顯示圖象時可以完成地理計算,如計算距離和麪積等。

在MapInfo Professional中首次打開一幅柵格圖象時,MapInfo Professional顯示「配準柵格圖象」對話框。填寫該對話框以告知MapInfo Professional如何配準圖象。MapInfo Professional將柵格圖象配準信息保存在表文件中以供之後使用。下一次打開該柵格圖象表時就沒必要再進行配準了。這樣,只須對柵格圖象進行一次配準。

柵格圖層的應用在地理信息系統中也有重要做用。通常做爲背景使用,特別是可做爲鷹眼圖的背景使用,可防止在改變視圖時引發的刷新。

4.1.3.3配準柵格圖像

若尚未在MapInfo Professional中顯示過某個柵格圖象,執行下述步驟配準該圖象:

(1) 選擇「文件」>「打開」,「打開」對話框出現。

(2) 從「文件類型」下拉列表中選擇「柵格圖象」。MapInfo Professional顯示柵格圖象文件清單。

(3) 選擇要打開的柵格圖象文件並選擇「打開」。彈出一個MapInfo Professional對話框,點擊「配準」按鈕。MapInfo Professional顯示「圖象配準」對話框。該柵格圖象的一個預覽出如今對話框的下半段。

(4) 經過選擇「投影」按鈕並完成「選擇投影」對話框來設定該圖象的地圖投影。配準柵格文件時,初始的投影方式就是表的缺省投影。

若是經過掃描紙張地圖建立柵格圖象,該紙張地圖應包含所用的地圖投影信息。若是不能肯定地圖投影,使用缺省地圖投影(經/緯度)。缺省地圖投影方式是由「地圖窗口參數設置」中的「缺省投影」設置的。若是不清楚的話,可使用經緯度。

(5) 把鼠標光標移到對話框下半段的預覽圖象上,並移到一個已知地圖座標(例如經/緯度)的點,再單擊鼠標按鈕。MapInfo Professional顯示「增長控制點」對話框。

(6) 經過輸入對應於在地圖圖象上單擊位置的地圖座標,完成「增長控制點」對話框。

記住,本初子午線以西的任何位置有負的經度,赤道以南的任何位置有負的緯度。所以,西經73度對應於X值-73。

若是以度爲單位輸入座標,必須輸入小數度而不是度/分/秒。

(7) 重複步驟5和6,直到輸入最少三個控制點。要保證精確結果,輸入五或六個控制點。所增長的每一個控制點有助於MapInfo Professional把地球座標同柵格圖象上的位置聯繫起來。理想地,在圖象的每一個角至少有一個控制點。

所需的控制點數依賴於柵格圖象的性質。若是不能肯定地圖投影或正在使用沒有實際地圖投影的圖象,例如航空照片,也許要輸入二十或更多控制點。

(8) 完成增長控制點後選擇「肯定」。MapInfo Professional把該柵格圖象顯示在地圖窗口中。

完成「圖象配準」對話框後,MapInfo Professional把配準信息保存到一個表文件(.tab)中。這樣咱們就能夠象利用普通Mapinfo表文件同樣來用這個柵格圖層了。

4.1.4 實例2:柵格圖層的創建

4.1.4.1 程序功能

裝載一柵格圖層到圖層集合的最低層。

4.1.4.2 程序實現

public bool LoadRasterLayer(string layerName)

{

int layerNumber=axMap1.Layers.Count;

try

{

axMap1.Layers.Add(layerName+".tab",layerNumber+1);

return true;

}

catch

{

return false;

}

}

4.1.4.3 程序說明

裝載柵格圖層與載載普通圖層同樣,用一樣的語法結構Layers.Add()。

4.2 圖元自動標註

對一個圖元加上標註可直觀的給用戶識別地圖上的每個地理對象,在MapX中可設置自動標註圖元和手工標註圖元。

4.2.1 實例3:給圖層加上自動標註功能

4.2.1.1 程序實現

private void autoLabel(string layerName)

{

MapXLib.Layer layer=axMap1.Layers._Item(layerName);

MapXLib.Dataset ds=axMap1.DataSets._Item(「ds」+layerName);

layer.LabelProperties.Dataset =ds;

layer.LabelProperties.DataField =ds.Fields._Item(「name」);

layer.LabelProperties.Position=MapXLib.PositionConstants.miPositionBC;

layer.LabelProperties.Style.TextFont.Size=10;

layer.LabelProperties.Offset=4;

layer.AutoLabel =true;

}

4.2.1.2 程序說明

(1)程序中假定layer層在生成時已生成與之綁定的數據集,其名稱爲」ds」+layerName。具體做法請參見實例新建自定義圖層。

(2)用LabelProperties對象來定義標註的內容,字體,位置等。例子中用數據集的name字段的內容來標註圖元,標註位置在圖元下方偏移4個單位,字體大小爲10。

(3)layer.AutoLabel =true打開自動標註功能,若要關閉全部標註可簡單地置標註的visible屬性爲false。

4.3 MapX地圖集

4.3.1 什麼是MapX地圖集(Geoset)?

地圖集即圖層的的集合,MapX控件的Geoset屬性即爲要打開的地圖集對象。地圖集對象的擴展名爲.gst。它可由MapX所帶的工具Geoset Manager來生成,請讀者本身一試。

Geoset 保留地圖圖層及其設置的集合,以便於您使用。Geoset 是由同一地理區域的標準 MapInfo 格式地圖文件 (.tab) 組成的數據集,所以命名爲 Geoset。Geoset 能夠幫助您避免在每次要做爲示例地圖處理圖層時要分別打開和顯示這些圖層的耗時的工做。

.gst 是包含若干元數據關鍵字的文本文件,告訴 MapX 顯示哪些表以及如何顯示它們。

在打開一個 Geoset 時,它自動默認顯示打開在 Geoset 中包括的全部文件。開發人員能夠更改該默認顯示以知足自身的要求。Geoset 的設置包括投影、默認縮放、對象的自動加標籤、縮放圖層以及在打開時表是否可見。MapX 也將打開開發人員指定的任何單個 (.tab) 地圖文件。Geoset 是出於方便目的提供的,不是 MapX 行使功能所必需的。

4.3.2 實例4:打開已存在的地圖集文件

4.3.3.1 程序功能

在硬盤中選擇一個地圖集文件.gst,而後在MapX中打開,並保存地圖的初始屬性如初始時的縮放比例及中心位置等。

4.3.3.2 程序實現

openFileDialog1.DefaultExt ="*.gst";

openFileDialog1.Filter="geoset file (*.gst)|*.gst";

openFileDialog1.ShowDialog();

if (openFileDialog1.FileName=="")

return;

axMap1.GeoSet=openFileDialog1.FileName;

mapZoom=axMap1.Zoom;

mapCenterX=axMap1.CenterX;

mapCenterY=axMap1.CenterY;

4.3.2.3 程序說明:

例程中由openFileDialog可在運行中任意打開所需的地圖集對象,而後把該地圖集文件名賦給地圖的GeoSet屬性便可。後面三行是用於保存地圖集的初始縮放比例及中心位置,以便可以在運行過程當中隨時恢復到起始視圖狀態下。

4.3.3 實例5:保存地圖集

4.3.3.1 程序功能

在新建或添加一個圖層後,地圖集改變,在此時應保存改變後的地圖集,以方便下次一次性打開全部圖層,發揮geoset的做用。下面的程序實現這一功能。

4.3.3.2 程序實現

string geosetFileName="";

saveFileDialog1.InitialDirectory=@appDirectory;

saveFileDialog1.Filter = "geoset files (*.gst)|*.gst";

if(saveFileDialog1.ShowDialog()==DialogResult.OK)

geosetFileName=saveFileDialog2.FileName;

else

return;

axMap1.SaveMapAsGeoset(axMap1.Title.ToString(),@geosetFileName);

4.3.3.3 程序說明

(1)appDirectory爲應用程序目錄變量,可用Directory.GetCurrentDirectory()來獲得;

(2)saveFileDialog對話框來獲得地圖集的文件名及路徑;

(3)saveMapAsGeoset()方法來保存地圖集,其語法爲void SaveMapAsGeoset ( System.String nameSystem.String fileSpec)

4.4 內置工具的使用

大多數地圖繪製應用程序提供各類工具來協助完成常見的繪圖任務(例如在地圖上繪製線條)和導航任務(例如放大)。MapX 提供若干常見地圖繪製工具,而且您還能夠建立本身的定製工具。

4.4.1 使用標準工具

使用 MapX,您能夠很容易地將常見工具欄按鈕併入應用程序中。MapX 提供對若干常見地圖繪製工具的內置支持,可實現大部分地圖功能,包括:

• 令用戶更改地圖的比例和/ 或位置的導航工具(放大、縮小、平移、居中)。

• 讓用戶單擊地圖圖元以給它加標籤的加標籤工具。

• 爲用戶提供各類方法來選擇地圖圖元的一組選擇工具。

• 對象建立工具,用於建立新的地圖圖元。

提供對修改鍵(SHIFT 鍵、CTRL 鍵)的內置支持的選擇工具:使用選擇工具的同時按住 SHIFT 鍵;該工具將取消選擇圖元;使用選擇工具的同時按住 CTRL,該工具會將圖元添加到選擇中。只要按下修改鍵 MapX 就會自動顯示不一樣的光標(加號或減號出如今該光標旁),以便用戶能夠理解該鍵的用途。

下面列出內置工具常量:

miArrowTool = 1000: 單擊標題或註釋此外,在可編輯圖層中移動選

定圖元或調整選定圖元的大小。

miPanTool = 1001:漫遊工具

miCenterTool = 1002:使…成爲中心工具

miZoomInTool = 1003:地圖放大工具

miZoomOutTool = 1004 :地圖縮小工具

miSymbolTool = 1005:符號註釋工具

miTextTool = 1006:文本註釋工具

miSelectTool = 1007 :圖元選擇工具

miRadiusSelectTool = 1008 :扇形選擇工具

miRectSelectTool = 1009 :矩形選擇工具

miPolygonSelectTool = 1010:多邊形選擇工具

miLabelTool = 1011:標註工具

miAddLineTool = 1012:畫線工具

miAddPolylineTool = 1013:畫折線工具

miAddRegionTool = 1014:畫區域工具

miAddPointTool = 1015:畫點圖元工具

4.4.3 實例6:內置標準工具的使用

4.4.3.1 程序功能

實現地理信息系統中常見的工具欄按鈕功能,併入應用程序中。

4.4.3.2 程序實現

//放大按鈕

axMap2.CurrentTool=ToolConstants.miZoomInTool;

//恢復到初始視圖按鈕

axMap2.ZoomTo(this.mapZoom,this.mapCenterX,this.mapCenterY);

//漫遊按鈕

axMap2.CurrentTool=MapXLib.ToolConstants.miPanTool;

//增長點圖元按鈕

MapXLib.Style style=new MapXLib.StyleClass();

style.PickSymbol();

axMap2.DefaultStyle =style;

layerInsertion.Editable=true;

axMap2.Layers.InsertionLayer=layerInsertion;

axMap2.CurrentTool=MapXLib.ToolConstants.miAddPointTool;

//增長折線圖元按鈕

MapXLib.Style stylePolyLine=new MapXLib.StyleClass();

stylePolyLine.PickLine();

axMap2.DefaultStyle =stylePolyLine;

layerInsertion.Editable=true;

axMap2.Layers.InsertionLayer=layerInsertion;

axMap2.CurrentTool=MapXLib.ToolConstants.miAddPolylineTool;

//增長區域圖元按鈕

MapXLib.Style styleRegion=new MapXLib.StyleClass();

styleRegion.PickRegion();

axMap2.DefaultStyle =styleRegion;

layerInsertion.Editable=true;

axMap2.Layers.InsertionLayer=layerInsertion;

axMap2.CurrentTool=MapXLib.ToolConstants.miAddRegionTool;

4.4.2.3 程序說明

(1)currentTool屬性用來選擇當前工具;

(2)在上面增長圖元的例程中, style.PickSymbol ()方法用來取得新圖元的樣式,包括大小.線型.顏色.填充方案等,以增長程序的靈活性;

(3)特別注意在增長圖元時,不只要設置當前圖層爲可編輯,並且要把當前層指定爲圖層集合的可插入層,即要指定圖層集的insertionLayer屬性。

4.5自定義工具

MapX內置工具給咱們編程提供了很大的方便,但在一些狀況下還遠遠不能知足用戶需求,在這種狀況下,咱們就要進行自定義工具了。

4.5.1 建立自定義工具

在您爲任何應用程序建立一個定製工具時,一般要執行三步:

(1) 建立工具。

(2) 編寫工具處理程序(工具實際執行功能的代碼)。

(3) 使用該工具(令用戶開始使用工具)。

4.5.2 實例7:建立測量長度和麪積自定義工具

在GIS系統中,長度及面積的測量是一項重要功能,它也是典型的自定義工具的使用的例子,各類書中都有相應介紹,在這裏就在c#下建立自定義長度測量及面積測量工具的例程介紹以下。

4.5.3.1 程序功能

建立兩個自定義工具:測量長度及測量面積。

4.5.3.2 程序實現

//首先聲明長度測量及面積測量工具常量

private const int miGetLength =100;//自定義用戶工具:測量長度

private const int miGetArea =101;//自定義用戶工具:測量面積

//而後建立長度測量及面積測量工具

axMap2.CreateCustomTool(miGetLength,MapXLib.ToolTypeConstants.miToolTypePoly,MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,false);

axMap2.CreateCustomTool(miGetArea,MapXLib.ToolTypeConstants.miToolTypePolygon,MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,false);

//最後在PolyToolUsed實現兩個工具

private void axMap1_PolyToolUsed(object sender, AxMapXLib.CMapXEvents_PolyToolUsedEvent e)

{

if(e.toolNum==miGetLength)

{

MapXLib.Points pts=(MapXLib.Points)e.points;

MapXLib.Point pt1,pt2;

double d=0.0;

for(int i=1;i<pts.Count;i++)

{

pt1=pts._Item(i);

pt2=pts._Item(i+1);

d+=axMap2.Distance(pt1.X,pt1.Y,pt2.X,pt2.Y);

}

statusBarPanel2.Text="距離:"+d.ToString();

}

else if(e.toolNum==miGetArea)

{

MapXLib.Points pts=(MapXLib.Points)e.points;

MapXLib.FeatureFactory dd=axMap2.FeatureFactory;

MapXLib.Style style=axMap2.DefaultStyle;

statusBarPanel2.Text="面積:"+dd.CreateRegion(pts,style).Area.ToString();

}

}

4.5.2.3 程序說明

注意:這些代碼必定要在polytoolused事件中實現,由於每種工具使用都要在多點下才能完成。這裏用了Distance及Area來得到其長度和麪積,其它代碼請讀者本身仔細品味,相信讀者會讀懂它,再也不作解釋。

4.6 MapX地圖符號樣式的定製

在mapinfo中,圖元分爲點線面三種,每種圖元都有本身的樣式庫。咱們用內置工做miAddLine,miAddPoint,miAddRegion時,都是使用各自的默認樣式畫出相應的點線面圖元。咱們能夠在畫以前更改其樣式,以達到本身所須要的樣式。這就是咱們前面畫圖元時首先調用style.pickSymbol(),style.pickLine(),style.pickRegion()的緣由,也能夠在圖層對話框中更改其樣式,圖層對話框的調用方法爲layerDialog();

然而,mapinfo所帶樣式庫仍是很是有侷限,不可能提供全部的符號和樣式,來知足各行各業的應用。若是可以對符號庫進行擴充那麼就很是完美了。可喜的是mapinfo professinal自帶的mapbasic程序symbol.mbx能夠幫助咱們完成這一工做。下面給出點符號樣式的擴充方法:

如圖在mapinfo中運行mapbasic程序,選擇symbol.mbx。

clip_image002

clip_image004

工具菜單下將會出現「建立新符號」,單擊子菜單「新建一個」,出現符號編輯器,對新符號建立完成後按保存出現保存成功對話框。

clip_image006

clip_image008

注意:本人用的是mapinfo professional 7.0,若爲之前的版本,可能會有所不一樣,具體請參考相關資料。

Mapinfo也支持位圖形式的點符號,位圖做爲一個點顯示在圖層某個位置上。位圖存放在"Program Files\Common Files\MapInfo Shared\MapX Common\CUSTSYMB"子目錄下。MapX存放在」Program Files\MapInfo\MapX 5.0\CUSTSYMB」子目錄下。咱們只須要獲得符號的位圖文件而後存在CUSTSYMB下就可完成位圖號的擴充。這樣,咱們基本能夠達到須要什麼就能畫什麼的程度。

4.7在圖層上添加自定義圖元

下面咱們實現這樣一個功能,在例程1新建的圖層上畫一個位圖形式的點符號。分兩種狀況:(1)給出點的位置座標,自動出如今圖層上;(2)未給出位置座標,由用戶在圖層上用鼠標點擊出現。Form上有若干文本輸入框,用於輸入圖元各信息number(圖元編號),caption(圖元名稱),descr(圖元描述),下面一肯定按鈕點擊出現:

4.7.1 實例8:鼠標點擊向圖層上添加圖元

4.7.1.1 程序功能

4.7.1.2 程序實現

private const int miAddSymbol =106;//自定義用戶工具:添加用戶圖元到圖層,在類的變量聲明部分定義

axMap2.CreateCustomTool(miAddSymbol,MapXLib.ToolTypeConstants.miToolTypePoint,MapXLib.CursorConstants.miSizeAllCursor,MapXLib.CursorConstants.miSizeAllCursor,MapXLib.CursorConstants.miSizeAllCursor,false);//建立該自定義工具,在form load事件中定義

private void axMap1_ToolUsed(object sender, AxMapXLib.CMapXEvents_ToolUsedEvent e)

//在toolUsed實現該添加點圖元自定義工具

{

if(e.toolNum==miAddSymbol)

{

//取得點擊外的位置座標

x=e.x1;

y=e.y1;

MapXLib.Point pnt=new MapXLib.PointClass();

MapXLib.RowValue rv=new MapXLib.RowValueClass();

MapXLib.RowValues rvs=new MapXLib.RowValuesClass();

MapXLib.Feature ftr;

MapXLib.FeatureFactory feaFac;

MapXLib.Style newStyle=new MapXLib.StyleClass();

feaFac = axMap2.FeatureFactory;

//定義點圖元的樣式

newStyle.SymbolType =MapXLib.SymbolTypeConstants.miSymbolTypeBitmap;//指定爲位圖樣式

newStyle.SymbolBitmapSize=20;//指定圖元大小

newStyle.SymbolBitmapName=bitmapfilename;//指定位圖文件名

newStyle.SymbolBitmapTransparent=true;//指定位圖透明,和圖層融爲一體

axMap2.AutoRedraw = false;

userLayer.Editable =true;

pnt.Set(x,y);

ftr= feaFac.CreateSymbol(pnt,newStyle);//用featuerFactory生成該位圖圖元

//******************************************************

//如下代碼經過rowvalue和rowvalues來爲新建圖元設置全部屬性

//******************************************************

dsUserLayer=axMap2.Layers._Item(1).DataSets._Item(1);//例程1中自動生成的dataset.

fldsUserLayer=dsUserLayer.Fields;

rv.Dataset =dsUserLayer;

for(int j=1;j<=fldsUserLayer.Count;j++)

{

if(j==1)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=number.ToString();

}

if(j==2)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=caption;

}

if(j==3)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =descr;

}

if(j==4)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =x;

}

if(j==5)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =y;

}

rvs.Add(rv);

}

userLayer.AddFeature(ftr,rvs);//向圖層增長該圖元

userLayer.Refresh();

}

//下面是對確認按鈕的編程,調用剛纔實現的miAddSybol用戶自定義工具

public void addUserSymbol(string infoBitmapname,string infoNumber,string infoCaption,string infoDescr)//

{

bitmapfilename=infoBitmapname;

number=infoNumber;

caption=infoCaption;

descr=infoDescr;

axMap2.CurrentTool=(MapXLib.ToolConstants)miAddSymbol;

}

另一種不需自定義用內置的miAddTool添加。

4.7.2 實例9:給定座標向圖層上自動添加圖元

4.7.3.1 程序功能

4.7.3.2 程序實現

這種狀況下不須要自定義miAddSymbol工具,直接編程實現,代碼大體相同,示例以下:

public void AddUserSymbol(ref FeatureInfo featureInfo,string layerName)

//增長到userlayer後插入oracle表中,userName必須爲工做層

{

try

{

MapXLib.Point pnt=new MapXLib.PointClass();

MapXLib.RowValue rv=new MapXLib.RowValueClass();

MapXLib.RowValues rvs=new MapXLib.RowValuesClass();

MapXLib.Feature ftr;

MapXLib.FeatureFactory feaFac;

MapXLib.Layer layer=axMap1.Layers._Item(layerName);

MapXLib.Style newStyle=new MapXLib.StyleClass();

feaFac = axMap1.FeatureFactory;

newStyle.SymbolType =MapXLib.SymbolTypeConstants.miSymbolTypeBitmap;

newStyle.SymbolBitmapSize=20;

if (featureInfo.identity=="1")

{ newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorBlue;

newStyle.SymbolBitmapOverrideColor=true;

}

else if(featureInfo.identity=="2")

{

newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorGreen;

newStyle.SymbolBitmapOverrideColor=true;

}

else

{ newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorRed ;

newStyle.SymbolBitmapOverrideColor=true;

}

newStyle.SymbolBitmapName=featureInfo.symbolFileName;

newStyle.SymbolBitmapTransparent=true;

axMap1.AutoRedraw = false;//禁止圖層自動刷新

layer.Editable =true;

pnt.Set(featureInfo.point_x,featureInfo.point_y);

ftr= feaFac.CreateSymbol(pnt,newStyle);

//******************************************************

//如下代碼經過rowvalue和rowvalues來爲新建圖元設置全部屬性

//******************************************************

MapXLib.Dataset dsUserLayer;

MapXLib.Fields fldsUserLayer;

dsUserLayer=axMap1.DataSets._Item("ds"+layerName);

fldsUserLayer=dsUserLayer.Fields;

rv.Dataset =dsUserLayer;

//MI_PRINX索引構成規則:number前2位加yymmddhhmmss

DateTime myDataTime=DateTime.Now;

if (featureInfo.source==null) featureInfo.source="6";

string rownumber=featureInfo.source.PadLeft (2,'0')+myDataTime.Year.ToString()+myDataTime.Month.ToString()

+myDataTime.Day.ToString()+myDataTime.Hour.ToString()+myDataTime.Minute.ToString()+myDataTime.Second.ToString();

for(int j=1;j<=fldsUserLayer.Count;j++)

{

if(fldsUserLayer._Item(j).Name.ToUpper() =="MAINID")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.featureID;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="SOURCE")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.source;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="NAME")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.name;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="IDENTITY")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.identity;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="DESCRIPTION")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.description;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="FOUNDTIME")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.foundTime;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="MEDIA")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.media;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="X")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.point_x;

}

if(fldsUserLayer._Item(j).Name.ToUpper() =="Y")

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.point_y;

}

rvs.Add(rv);

}

layer.AddFeature(ftr,rvs);

layer.Refresh();

this.InsertIntoOracle(featureInfo,rownumber,ftr.Style,"symbol",ftr,layerName);

DeleteAllfeatures(userLayerName);

}

catch{}

axMap1.AutoRedraw = true;

}

4.7.2.3 程序說明

1.位圖必須放在custSymb子目錄下,且位圖不支持24位以上真彩色, 大小最大48點。

2.本例程不只畫出了位圖圖元,還給出了設置圖元屬性的方法: (1)指定rowvaluer 數據集:rv.dataset= dsUserLayer; (2)經過rowvalue.field指定要修改的字段: rv.Field=fldsUserLayer._Item(j);

(3)經過rowvalue.value指定該字段的值: rv.Value=caption;

(4)把每一個rowvalue增長到rowvalues集合中去,該rowvalues表明該圖元的所用屬性;

(5)利用圖層的addfeature(feature,rowvalues)方法增長新的圖元。

這樣咱們能夠用記事打開相應圖層的.dat文件查看咱們增長的新圖元的全部屬性。

4.8 得到圖元屬性

在地理信息系統獲取某個圖元的屬性是最基本的功能之一,實現起來也比較簡單。

4.8.1實例10:獲取選定圖元的屬性

4.8.1.1 程序功能

用內置選擇工具選擇某一圖元,而後返回該圖元的全部屬性。

4.8.1.2 程序實現

public string[] GetSymbolProperty(string layerName)

{

MapXLib.Layer layer=null;

MapXLib.Dataset ds=null;

MapXLib.Fields fields=null;

try

{

layer=axMap1.Layers._Item(layerName);

ds=axMap1.DataSets._Item("ds"+layerName);

fields=ds.Fields;

symbolInfo=new string[fields.Count];

}

catch

{

return null;

}

foreach(MapXLib.Feature ftr in layer.Selection)

{

for(int i=1;i<=fields.Count;i++)

{

layer.KeyField=fields._Item(i).Name;

symbolInfo[i-1]=ftr.KeyValue.ToString();

}

}

return symbolInfo;

4.8.1.3 程序說明

1.屬性值的得到:首先設置圖層的KeyField關鍵字段屬性:layer.KeyField= ds.Fields._Item(j).Name;

而後利用圖元的keyvalue便可獲得圖元該字段的值: ftr.KeyValue

2.循環全部字段就取得圖元的全部屬性:

for(int i=1;i<=fields.Count;i++)

3.在本例中將全部屬性全轉化爲string類型存於字符串數組symbolInfo[]中。

4.9 圖元的選取

圖元選取利用MapX內置的各類選取工具便可,咱們對地圖的操做每每都是針對地圖上所選取的圖元進行的,因此許多操做都要在這個選取上做文章了。

圖元的選取利用selection集合,很是方便,同selectionchanaged事件結合能夠作不少使人興奮的效果。下面舉得例子是利用selection集合及selectionchanged事件實現相似infoTip的功能,即當鼠標指在當前選中圖元上時,會自動出現該圖元的全部提示.這個功能固然能夠用圖層的labelproperty屬性和數據集綁定實現,但我以爲下面的方法會更好。

4.9.1 實例11:實現InfoTip功能

//too1tip屬性定義,在form load事件中

toolTip1.AutoPopDelay = 5000;

toolTip1.InitialDelay = 1000;

toolTip1.ReshowDelay = 500;

toolTip1.ShowAlways = true;

// SelectionChanged事件中實現提示功能

private void axMap1_SelectionChanged(object sender, System.EventArgs e)

{

MapXLib.Layer layer=axMap2.Layers._Item(1);

MapXLib.Dataset ds=axMap2.DataSets._Item(1);

foreach(MapXLib.Feature ftr in layer.Selection)

{

selectedFea=ftr;

string msg="";

for(int j=1;j<=ds.Fields.Count;j++)

{

layer.KeyField =ds.Fields._Item(j).Name;

symbolProperty[j-1]=ftr.KeyValue.ToString();

msg+= layer.KeyField+":"+ symbolProperty[j-1]+"\n";

}

toolTip1.SetToolTip(this.axMap1,msg);

}

}

注: (1)symbolProperty[]爲一字符串數組,存儲圖元全部屬性。

(2)例子中用了c#工具箱中的toolTip對象,巧妙的實現了信息提示.關於tooltip對象詳細說明建議讀者查幫助。

4.10 圖元屬性的修改

4.10.1 實例12:修改圖元屬性

4.10.1.1 程序功能

  修改已知圖元的屬性。

4.10.1.2 程序實現

public void modiUserSymbol(MapXLib.Feature ftr,string infoNumber,string infoCaption, string infoDescr,double xIn,double yIn)

{

if (ftr==null) return;

number=infoNumber;

caption=infoCaption;

descr=infoDescr;

x=xIn;

y=yIn;

MapXLib.RowValues rvs=new MapXLib.RowValuesClass();

MapXLib.Layer layer=axMap2.Layers._Item(1);

MapXLib.Dataset ds=axMap2.DataSets._Item("dsUserLayer");

for(int j=1;j<=ds.Fields.Count;j++)

{

layer.KeyField =ds.Fields._Item(j).Name;

if (j==1)

ftr.KeyValue=number;

if (j==2)

ftr.KeyValue=caption;

if (j==4)

ftr.KeyValue=descr;

if (j==6)

ftr.KeyValue=x.ToString();

if (j==7)

ftr.KeyValue=y.ToString();

ftr.Update(true,rvs);

}

MessageBox.Show("目標屬性修改爲功!");

}

圖元屬性修改用圖元的update方法。

4.11 實例13:圖元的查詢

圖層的search(strWhere, , [Variables])方法中以方便的實現圖元的查詢,具備相似SQL查詢的強大能力。其中參數strWhere爲檢索圖元的條件表達式,至關於sql的where子句。該語句執行結果返回查找到的圖元集合。

下面的例程實現一個萬能模糊查詢,即給定一個查找關鍵字keyStr,而後可查出圖元屬性中包含有有關鍵字keyStr的圖元,而無論是哪一個屬性字段。

public void searchSymbols(string keyStr)

{

MapXLib.Features ftrs;

MapXLib.Features ftrs1;

MapXLib.Layer layer=axMap2.Layers._Item(1);

layer.Selection.ClearSelection();//清空selection集合

MapXLib.Variables vs=new MapXLib.VariablesClass();

ftrs=layer.Search("objName LIKE"+" "+"\"%"+keyStr+"%\"",vs);

//查找名稱屬性中包含keyStr的的圖元,並存於ftrs集合中

ftrs1=layer.Search("objNumber LIKE"+" "+"\"%"+keyStr+"%\"",vs);

//查找編號屬性中包含keyStr的的圖元,並存於ftrs1集合中

ftrs.Add(ftrs1);//把ftrs1集合合併到ftrs集合中

MessageBox.Show("共有知足條件的圖元"+ftrs.Count.ToString()+"個!");

layer.Selection.Add(ftrs);

//把查找到的全部圖元存到selection集合中,以便使其高亮顯示,處於選中狀態。

}

4.12 實例14:鷹眼圖的實現

鷹眼圖的實現能使電子地圖在功能及界面上錦上添花,各類媒體上都有一些介紹,下面介紹用C#實現的鷹眼圖功能。

4.12.1 程序實現

//初始時,產生鷹眼圖矩形框繪畫層

private void mapsmall()

{

if (!File.Exists(@appDirectory+"\\mapSmall.tab"))

m_Layer=mapSmall.Layers.CreateLayer("RectLayer",@appDirectory+

"\\mapSmall.tab",1,32,mapSmall.NumericCoordSys);

else

m_Layer = mapSmall.Layers.Add(@appDirectory+"\\mapSmall.tab",1);

m_Layer.Editable=true;

mapSmall.Layers.InsertionLayer=m_Layer;

}

private void axMap1_MapViewChanged(object sender, System.EventArgs e)

{

if(mapSmall==null) return;

MapXLib.Feature tempFea;

MapXLib.Feature m_Fea;

MapXLib.FeatureFactory feaFact;

feaFact=mapSmall.FeatureFactory;

MapXLib.Points tempPnts=new MapXLib.PointsClass();

MapXLib.Style tempStyle=new MapXLib.StyleClass();

MapXLib.Features ftrs;

ftrs=m_Layer.AllFeatures;

double MapX=0,mapY=0,mapWidth=0,mapHeight=0,MapX1=0,mapY1=0;

float screenX,screenY,screenWidth,screenHeight,screenX1,screenY1;

screenX=axMap2.Bounds.X;

screenY=axMap2.Bounds.Y;

screenWidth=axMap2.Bounds.Width;

screenHeight=axMap2.Bounds.Height;

screenX1=screenX+screenWidth;

screenY1=screenY+screenHeight;

axMap2.ConvertCoord(ref screenX,ref screenY,ref MapX,ref mapY,

MapXLib.ConversionConstants.miScreenToMap);

axMap2.ConvertCoord(ref screenX1,ref screenY1,ref MapX1,ref mapY1,

MapXLib.ConversionConstants.miScreenToMap);

mapWidth=MapX1-MapX;

mapHeight=mapY1-mapY;

if (ftrs.Count==0)

{ tempStyle.RegionPattern=MapXLib.FillPatternConstants.miPatternNoFill; tempStyle.RegionColor=(uint)MapXLib.ColorConstants.miColorRed;

tempStyle.RegionBorderColor=255;

MapXLib.Points pts=new MapXLib.PointsClass();

pts.AddXY(MapX,mapY,1);

pts.AddXY(MapX+mapWidth,mapY,2);

pts.AddXY(MapX+mapWidth,mapY+mapHeight,3);

pts.AddXY(MapX,mapY+mapHeight,4);

tempFea = feaFact.CreateRegion(pts,tempStyle);

m_Fea = m_Layer.AddFeature(tempFea,new MapXLib.RowValuesClass());

m_Layer.Refresh();

mapSmall.AutoRedraw = true;

}

else

{

m_Fea=ftrs._Item(1);

m_Fea.Parts._Item(1).RemoveAll();

m_Fea.Parts._Item(1).AddXY(MapX,mapY,1);

m_Fea.Parts._Item(1).AddXY(MapX+mapWidth,mapY,2);

m_Fea.Parts._Item(1).AddXY(MapX+mapWidth,mapY+mapHeight,3);

m_Fea.Parts._Item(1).AddXY(MapX,mapY+mapHeight,4);

m_Fea.Update(true,new MapXLib.RowValuesClass());

m_Layer.Refresh();

mapSmall.AutoRedraw = true;

}

}

void axMap2_MouseDownEvent(object sender,AxMapXLib.CMapXEvents_MouseDownEvent e)

{

if(mapLarge==null)return;

double MapX=0;

double MapY=0;

axMap2.ConvertCoord(ref e.x,ref e.y,ref MapX,ref MapY,

MapXLib.ConversionConstants.miScreenToMap);

mapLarge.CenterX=MapX;

mapLarge.CenterY=MapY;

}

4.12.3程序說明

(1)由主圖視圖改變影響鷹眼圖矩形框的重繪,代碼實如今主圖的viewchanged事件中。

(2)在鷹眼圖中單擊鼠標,把單擊處的位置點做爲主圖的中心點重繪主圖。代碼實如今鷹眼圖的mousedownevent事件中。

(3)M_layer爲鷹眼圖中繪製矩形框的圖層。

(4)mapSmall表明鷹眼圖控件,mapLarge表明主圖控件。

(5)主圖與鷹眼圖同步的關鍵是主圖的可視區域地理範圍與鷹眼圖的矩形框所包含的地理範圍同樣。 首先獲得主圖的Boundsr的各個頂點的屏幕座標用函數axMap1.ConvertCoord()將bounds的各頂點屏幕座標轉化爲地理座標。最後在鷹眼圖中根據主圖中各頂點的地理座標畫出矩形區域。

(6)注意convertCoord()函數的用法,請參考相關資料,注意其中第五個參數的用法。

請讀者仔細領會其中的機理。本例子只給了視圖範圍同步問題,沒有給出編輯同步問題,即在主圖中增長一個圖元,在鷹眼圖中同步增長一個點。留給讀者本身練習,相信必定不會難住聰明的讀者。

4.13 數據綁定

數據綁定的問題是MapX很重要的一個內容,是MapX具備生命力的重要體現。有了數據綁定,咱們能夠給地圖賦予意義,能夠給基於地理位置的空間對象以各類意義,知足各行各業的須要。然而,就是這個數據綁定,在C#下用得確不盡人意,這再一次體現了MapX對.net的支持不力。可是咱們能夠避過對咱們不利的地方,來解決這個問題。下面就本人成功實現的一些數據綁定的例子,介紹以下:

(1)用layerinfo對象增長層時自動產生與之綁定的數據集 其中相應語句爲

layerInfo.AddParameter("AutoCreateDataset",1);

layerInfo.AddParameter("DatasetName","dsUserLayer");

具體參見例程1部分。利用這種方法簡單也很是方便,能夠知足大部分應用。

(2)利用axMap1.DataSets.Add方法創建數據綁定

程序代碼摘要以下:

//定義Fields字段集

MapXLib.Fields flds=new MapXLib.FieldsClass(); flds.Add("objNumber","objNumber",MapXLib.AggregationFunctionConstants.miAggregationIndividual,MapXLib.FieldTypeConstants.miTypeString);

flds.Add("objName","objName",MapXLib.AggregationFunctionConstants.miAggregationIndividual,MapXLib.FieldTypeConstants.miTypeString);

flds.Add("objDscr","objDscr",MapXLib.AggregationFunctionConstants.miAggregationIndividual,MapXLib.FieldTypeConstants.miTypeString);

flds.Add("objX","objX",MapXLib.AggregationFunctionConstants.miAggregationIndividual,MapXLib.FieldTypeConstants.miTypeFloat);

flds.Add("objY","objY",MapXLib.AggregationFunctionConstants.miAggregationIndividual,MapXLib.FieldTypeConstants.miTypeFloat);

//數據綁定與自動標識

userLayer=axMap1.Layers._Item(1);

dsUserLayer=axMap1.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer,userLayer,"userdrawlayer",0,0,0,flds,false);

userLayer.LabelProperties.Dataset =dsUserLayer;

userLayer.LabelProperties.DataField =dsUserLayer.Fields._Item(2);

userLayer.AutoLabel =true;

上面代碼的關鍵部分是dsUserLayer=axMap1.DataSets.Add(

MapXLib.DatasetTypeConstants.miDataSetLayer,userLayer,"userdrawlayer",0,

0,0,flds1,false);

其中MapXLib.DatasetTypeConstants.miDataSetLayer爲綁定層類型;第二個參數爲要綁定的層名,第三個參數爲數據集名稱,其它參數在vb,Delphi,powerBuilder中是可選的,然而在於c#中參數必須寫全,咱們如上面處理,flds爲該層的字段集對象。

(3)與外部數據庫綁定

與外部數據庫綁定的的方法根據數據源的不一樣有不少種方法,請參看MapX幫助文檔。下面以與oracle數據庫綁定爲例爲介紹,但願能起到拋磚引玉的效果,具體綁定辦法見下一章節」MapX與oracle的結合」。

4.14 GPS在GIS系統中的應用

近年來,衛星定位技術的飛速發展,衛星定位系統已廣泛運用於物理勘探、電離層測量和航天器導航等諸多民用高新技術領域,並日益在人們的平常生活中獲得普及,如移動手機定位,車載導航等。在軍事領域,彈道導彈、野戰指揮系統、精確彈道測量以及軍用地圖快速測繪等領域均大量採用了衛星導航定位技術。衛星導航技術對國民經濟的發展具備極其重要意義,2000年10月31日和12月21日我國前後成功發射了兩顆導航定位試驗衛星並創建了我國第一代衛星導航定位系統—「北斗導航系統」。

GPS與GIS結合主要需解決兩個問題:

(1) GPS定位信息的獲取

(2) GPS定位信息在GIS中的顯示

4.14.1定位信息的接收

GPS定位信息接收系統主要由GPS接收天線、變頻器、信號通道、微處理器、存儲器以及電源等部分組成。GPS定位信息通常用RS-232串口將定位信息從GPS接收機傳送到計算機中進行信息提取處理。

GPS接收機只要處於工做狀態就會源源不斷地把接收並計算出的GPS導航定位信息經過串口傳送到計算機中。從串口接收數據並將其放置於緩存,在沒有進一步處理以前緩存中是一長串字節流,這些信息在沒有通過分類提取以前是沒法加以利用的。所以,必須經過程序將各個字段的信息從緩存字節流中提取出來,將其轉化成有實際意義的,可供高層決策使用的定位信息數據。同其餘通信協議相似,對GPS進行信息提取必須首先明確其幀結構,而後才能根據其結構完成對各定位信息的提取。

4.14.2定位信息的提取

本文以GARMIN GPS天線板爲例來介紹GPS幀結構。GARMIN GPS接收到的數據幀主要由幀頭、幀尾和幀內數據組成,根據數據幀的不一樣,幀頭也不相同,主要有"$GPGGA"、"$GPGSA"、"$GPGSV"以及"$GPRMC"等。這些幀頭標識了後續幀內數據的組成結構,各幀均以回車符和換行符做爲幀尾標識一幀的結束。對於一般的狀況,咱們所關心的定位數據如經緯度、速度、時間等都可以從"$GPRMC"幀中獲取獲得,該幀的結構及各字段釋義以下:

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh

<1> 當前位置的格林尼治時間,格式爲hhmmss

<2> 狀態, A 爲有效位置, V爲非有效接收警告,即當前天線視野上方的衛星個數少於3顆。

<3> 緯度, 格式爲ddmm.mmmm

<4> 標明南北半球, N 爲北半球、S爲南半球

<5> 經度,格式爲dddmm.mmmm

<6> 標明東西半球,E爲東半球、W爲西半球

<7> 地面上的速度,範圍爲0.0到999.9

<8> 方位角,範圍爲000.0到 359.9 度

<9> 日期, 格式爲ddmmyy

<10> 地磁變化,從000.0到 180.0 度

<11> 地磁變化方向,爲E 或 W

至於其餘幾種幀格式,除了特殊用途外,平時並不經常使用,雖然接收機也在源源不斷地向主機發送各類數據幀,但在處理時通常先經過對幀頭的判斷而只對"$GPRMC"幀進行數據的提取處理。若是狀況特殊,須要從其餘幀獲取數據,處理方法與之也是徹底相似的。因爲幀內各數據段由逗號分割,所以在處理緩存數據時通常是經過搜尋ASCII碼"$"來判斷是不是幀頭,在對幀頭的類別進行識別後再經過對所經歷逗號個數的計數來判斷出當前正在處理的是哪種定位導航參數,並做出相應的處理。

4.14.3定位信息在MapX中的顯示

在MapX應用程序中咱們只需把接收到的經緯度值賦給所定位圖元的位置屬性,便可觀察到圖元的移動軌跡。

4.14.4 實例15:GPS定位系統的應用

4.14.4.1程序功能

演示GPS定位信息的接收提取。

4.14.4.2 程序實現

在Form上添加串口通訊控件及若干按鈕和輸入框,以下圖:

clip_image009

而後編寫各功能代碼,代碼以下:

namespace GPS

{

public struct GPSInfo

{

public double latitude; //緯度(分)

public char southornorth; //北緯(true)或南緯(false)

public double longitude; //經度(分)

public char eastorwest; //東經(true)或西經(false)

public string height; //高度(米)

public DateTime acceptTime; //接收時間

public string speed; //車輛的速度

public bool valid; //是否可信

}

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.TextBox textBox4;

private System.Windows.Forms.TextBox textBox3;

private System.Windows.Forms.TextBox textBox2;

private System.Windows.Forms.TextBox textBox1;

private System.Windows.Forms.Label label4;

private System.Windows.Forms.Label label3;

private System.Windows.Forms.Label label2;

private System.Windows.Forms.Label label5;

private AxMSCommLib.AxMSComm axMSComm1;

private System.Windows.Forms.Button startRecieve;

private System.Windows.Forms.Button stopRecieve;

GPSInfo gif=new GPSInfo ();

private System.Windows.Forms.RichTextBox richTextBox1;

private System.Windows.Forms.Label label1;

private System.Windows.Forms.TextBox textBox5;

private System.ComponentModel.Container components = null;

public GPSInfo GetGPSInfo()

{

return gif;

}

//開始接收

private void startRecieve_Click(object sender, System.EventArgs e)

{

if(!axMSComm1.PortOpen)

axMSComm1.PortOpen=true;

axMSComm1.Update();

}

////中止接收

private void stopRecieve_Click(object sender, System.EventArgs e)

{

if(axMSComm1.PortOpen)

axMSComm1.PortOpen=false;

axMSComm1.Update();

}

//對接收到的GPS信息進行提取,並顯示在表單中

private void axMSComm1_OnComm(object sender, System.EventArgs e)

{

string m_comdata ="";

m_comdata=(string)axMSComm1.Input;

int length,i;

byte []data=new byte [1024];

length=m_comdata.Length;

string m_zjz;

m_zjz=m_comdata ;

//尋找GPS信號的頭標誌

int s;

s=m_zjz.IndexOf("$GPRMC,");

string m_gps;

//NUM爲所提取GPS信號的長度

m_gps=m_zjz.Substring (s,m_zjz.Length -s);

int x;

x=m_gps.Length ;

string m_sTime="",m_sPositionY="",m_sPositionX="",m_sDate="";

char ns=' ',ew=' ';

string spd="";

bool valid=false;

int index=0;

for(i=0;(index<11) && (m_gps[i]!=10);i++) //幀尾

{

if(m_gps[i]==',') //逗號計數

index++;

else

{

switch(index)

{

case 1: //提取出時間

m_sTime+=m_gps[i];

break;

case 2:

//判斷數據是否可信(當GPS天線能接收到有3顆GPS衛星時爲A,可信)

if(m_gps[i]=='A')

{

valid=true;

}

else

valid=false;

break;

case 3: //提取出緯度

m_sPositionY+=m_gps[i];

break;

case 4://南北緯

ns=m_gps[i];

break;

case 5: //提取出經度

m_sPositionX+=m_gps[i];

break;

case 6://東西經

ew=m_gps[i];

break;

case 7:

spd+=m_gps[i];

break;

case 9: //提取出日期

m_sDate+=m_gps[i];

break;

default:

break;

}

}

}

//時間

int day=Int32.Parse (m_sDate.Substring (0,2));

int month=Int32.Parse (m_sDate.Substring (2,2));

int year=Int32.Parse (m_sDate.Substring (4,2))+2000;

int hour1=Int32.Parse (m_sTime.Substring (0,2));

int minute1=Int32.Parse (m_sTime.Substring (2,2));

int second1=Int32.Parse (m_sTime.Substring (4,2));

int hour=23-hour1;

int minute=59-minute1;

int second=60-second1;

gif.acceptTime =new DateTime (year,month,day,hour,minute,second);

gif.acceptTime .AddHours (8);

//有效性

gif.valid =valid;

if(!gif.valid)

{

MessageBox.Show("接收衛星太少,不能定位!");

}

//南北緯

gif.southornorth =ns;

gif.speed=spd;

//東西經

gif.eastorwest =ew;

//緯度

gif.latitude=Int32.Parse (m_sPositionY.Substring (0,2))+double.Parse (m_sPositionY.Substring (2,7))/60; //前面是度,後面是分

//經度

if(m_sPositionX.Length ==10) //超過九十度

{

gif.longitude=Int32.Parse (m_sPositionX.Substring (0,3))+double.Parse (m_sPositionX.Substring (3,7))/60;

}

if(m_sPositionX.Length ==9) //小於九十度

{

gif.longitude=Int32.Parse (m_sPositionX.Substring (0,2))+double.Parse (m_sPositionX.Substring (2,7))/60;

}

textBox2.Text=gif.latitude.ToString().Substring(0,7)+" "+gif.southornorth.ToString();

textBox1.Text=gif.longitude.ToString().Substring(0,8)+" "+gif.eastorwest.ToString();

textBox3.Text=gif.acceptTime.ToString();

textBox4.Text=gif.speed.ToString();

int s2;

s2=m_zjz.IndexOf("$GPGGA,");

string m_gpsheigth=m_zjz.Substring (s2,m_zjz.Length -s2);

int index1=0;

int l=0;

string gps_height="";

for(l=0;(index1<11) && (m_gps[l]!=10);l++) //幀尾

{

if(m_gps[l]==',')

index1++;

else

{

switch(index1)

{

case 1:

break;

case 2:

break;

case 3:

break;

case 4:

break;

case 5:

break;

case 6:

break;

case 7:

break;

case 8:

break;

case 11:

gps_height+=m_gps[l];

break;

}

}

}

gif.height=gps_height;

textBox5.Text=gif.height.ToString();

}

//串口配置初始化

private void Form1_Load(object sender, System.EventArgs e)

{

axMSComm1.CommPort=1;

axMSComm1.Settings="4800,N,8,1";

axMSComm1.InputLen=0;

axMSComm1.RThreshold=100;

}

}

}

4.15 多媒體信息在GIS系統中的應用

將多媒體數據嵌入GIS系統,必將大大提高GIS系統的功能,同時提升了用戶的音視覺效果。

4.15.1 GIS中嵌入多媒體的方法

在電子地圖系統體中嵌入多媒體信息的方法有兩種:

1.在數據庫中存儲多媒體數據所對應文件的路徑和文件名,在須要時檢索出該多媒體文件,而後用內置功能或外掛程序來播放。

2.直接存儲多媒體數據的二進制格式到數據庫,在須要時將該數據讀出進行處理。

下面咱們利用比較簡便的第一種方法,將地圖上的圖元同多媒體數據文件關聯起來,多媒體信息限定爲文字、圖片、視頻和聲音四種。

4.15.2 實例16:在MapX系統中嵌入多媒體數據

4.15.2.1 實現思路

在新建圖層時增長一字段,專門存儲多媒體數據的路徑,在訪問圖元時,讀取該多媒體字段內容,根據文件類型,啓動相應的打開程序來打開多媒體文件。

4.15.2.2 程序實現

using System.Diagnostics

//創建多媒體功能的圖層

MapXLib.Fields flds=new MapXLib.FieldsClass();

flds.AddStringField("name",50,false);

……

flds.AddStringField("media",50,false);//存儲多媒體文件路徑

……

layerInfo.AddParameter("Fields",flds);

layer = axMap1.Layers.Add(layerInfo,1);

//讀取多媒體文件並用相應程序打開

……

layer.KeyField=fields._Item(「media」).Name;

string mediaFileName=ftr.KeyValue;

int startindex=symbol.IndexOf(".")+1;

if (substring(mediaFileName, startindex,3)==」txt」)//讀取多媒體文件擴展名

Process.Start(「notepad.exe」, mediaFileName);

elseif(substring(mediaFileName, startindex,3)==」.jpg」)

Process.Start(「mspaint.exe」, mediaFileName);

else

Process.Start(「msplayer2.exe」, mediaFileName);

4.15.2.3 程序說明

1. substring(mediaFileName, startindex,3):用來判斷多媒體文件的類型,根據不一樣類型,用不一樣的應用程序打開。

2. Process Start (String fileName , String arguments ):經過指定應用程序的名稱和一組命令行參數來啓動進程資源,並將該資源與新的 System.Diagnostics.Process 組件關聯。注意在使用該組件時必定要添加對System.Diagnostics的引用。

第五章 MapX與Oracle結合

把MapX與oracle的結合做爲單獨一章節,由於筆者以爲它很是重要。Oracle做爲數據庫界的泰斗,其強大面向對象的數據庫功能若是能和MapX結合起來,將起到珠聯璧合的做用。

咱們知道,地理信息系統處理的數據包括包括兩部分,一是與該圖元所佔據的空間位置相關的空間數據,另外一個是該圖元的屬性數據。通常做法是將兩部分分開處理:空間數據以文件形式存儲,如mapinfo的.map文件;屬性數據以關係數據庫形式存儲或以文本文件形式存儲,如mapinfo的.dat文件。這種方式在單用戶的狀況下,基本上能夠知足要求,然而對於多用戶下,在分佈式網絡平臺上使用的GIS系統,就難以知足地理信息共享,併發控制及安全性的要求。若是能找到一種數據庫,把空間數據和屬性數據統一存儲管理,將會對GIS系統的應用提升到一個更加高的水平上來。咱們稱具備這種功能的數據庫爲空間數據庫。而Oracle數據庫就有這樣一種能力來實現空間數據的存儲。

5.1 Oracle數據庫對GIS的支持

爲何要在MapX用Oracle,避開其卓越性能及縝密的安全性不談,我認爲它只少有兩點很是適合mapinfo產品。

5.1.1面向對象的數據庫支持

Oracle數據庫支持面向對象的功能,即其中表的一個單元格可存儲一個對象,打破了數據庫表中字段不可再分的傳統理論。剛好地圖上的每一個圖元它是一個空間對象。oracle具備GEO數據類型支持,爲存儲圖元空間點線面屬性提供了支持。

5.1.2.Oracle spatial組件的引入

Oracle Spatial 是部署企業範圍的空間信息系統和基於 web 以及基於位置的無線應用程序的基礎。它爲位置信息提供數據管理,容許用戶直接在他們的應用程序和服務中輕鬆插入位置信息, 操做地理和位置數據的語法與應用於 CHAR、DATE 或 INTEGER 類型的相同。

Oracle9i 和 Oracle Spatial 的具體特性包括(摘自oracle官方網站):

l 針對全部函數和操做的開放、標準的 SQL 訪問

l 空間對象類型存儲,可容納幾何類型和線性引用

l 空間操做和函數,包括層限制和集合(例如,並集和用戶定義的集合)

l 快速參考樹和四叉樹索引

l 綜合存儲、管理和使用測量數據

l 空間索引分區支持

l 強大的線性引用系統

l 支持異種數據無縫集成(融合)的工具,包括投影管理和座標轉換

l 與 Oracle9i Application Server 無線版本集成

本章將分幾個專輯完整介紹MapX與oracle如何鏈接、MapX數據如何存入oracle以及oracle數據如何顯示到MapX中等一系列應用,並經過由淺入深的方法,一步一步引領你們進入MapX與oracle聯合後產生的神奇境界,但願能給讀者有所幫助。

5.2 按部就班學習Oracle Spatial在MapX中的應用

Oracle8是面向對象的關係型數據庫管理系統,做爲一個對象能夠放在表的一格中,Oracle Spatial提供了對空間幾何對象的存儲機制。面向對象的數據庫應用以及空間幾何對象的存儲對於未接觸過的讀者都感受很是陌生,不知從何入手,本章節將經過一個實例帶領你們一步一步走進這個世界,由表入裏,由淺入深,從實踐到理論,再從理論到實踐,使你們把握問題的本質,掌握解決問題的方法。

5.2.1 oralce服務器的安裝

安裝oralce服務器,注意選擇oracle spatial組件,默認爲選擇。本人安裝的是oracle 8i enterprise edition 8.2.7.0.0,創建一用戶全局數據庫caiqin,system賬戶口令manager。

5.2.2 準備由Oracle Spatial存儲的圖層文件

以第四章例程1的方法創建一新層,並在新層上加入一些圖元,並輸入其屬性數據。這樣會獲得.tab,.dat,.map等文件。打開.tab文件可看到自定義的圖層屬性字段結構定義,打開.dat文件可看到圖層上各圖元的屬性信息按前後順序存放。

5.2.3 Easyloader上載工具

在網上下載一個與oracle版本相對應的圖層數據上載軟件Easyloader,下載地址www.mapinfo.com 。Mapinfo Professional中也會自帶。

Easyloader是用來實現把Mapinfo地圖數據一次性向oracle數據庫上載的軟件,建議讀者在命令行帶參數運行該程序,以下所示C:\easyload\easyloader /y。爲何帶參數y運行後面再作解釋。運行後界面以下:

clip_image011

要上載地圖數據須要採起如下步驟:

5.2.3.1 鏈接服務器

鏈接服務器有種方式:ODBC和Oracle8i。在這裏咱們選擇用Oracle8i來鏈接Oracle Spatial服務器,單擊Oracle8i button,將會提示輸入Oracle8i鏈接信息以下圖(若爲客戶機,機器上必定要有Oracle8i客戶端程序)。

clip_image013

User ID:system

Password:manager

Server:caiqin

確認輸入正確後,單擊ok button,鏈接信息將會填充到DBMS,Database及user域。

5.2.3.2 選擇要上載的mapinfo表文件

單擊Tables button,選擇例程1建立的新圖層的userdrawlayer.tab文件,該文件將會出如今MapInfo列表框中,server域爲該文件上載到Oralce數據庫後的表名,默認與.tab文件名同樣。

5.2.3.3 選擇上載參數 (1)Append to Table/Replace(Create) Table:追加到已有表仍是新建表或替代已有表。選擇第二項新建或替表明。

(2)Append All to One:把全部mapinfo表追加到數據庫中的一個表中,前提是全部的表結構要一致,默認。

(3)Grant Public Access:對服務器數據表授予公開訪問權限,默認。

(4)Exclusive Use of Tables:加速表的上載時間,默認。

(5)Create Unique Index:爲上載後的表建立惟一索引,該索引列的字段名爲mi_prinx;選擇該選項。

(6)Create Spatial Index:建立空間索引,加速空間對象的查找,默認。

(7)Add to Mapcatlog:Mapcatlog是位於服務器中的一個表,它爲上載後的各個表建立了一個目錄,上載後的各個表均在此表中註冊。若是該目錄表不存在, Easyloader將會自動產生一個。

5.2.3.4 上載表

單擊Upload button開始上載過程,並顯示上載進度,若完成,顯示完成信息。

5.2.4 圖層信息在Oracle中的存儲結構

上載成功後,Oracle數據庫將會新增一個MAPCATALOG表和一個圖層數據表。

5.2.4.1 MAPINFO_MAPCATALOG表

Oracle數據庫新增了MAPINFO表空間,該空間中多了一個MAPINFO_MAPCATALOG表。該表的結構以下: SPATIALTYPE FLOAT(126) 空間對象類型

TABLENAME CHAR(32) oracle表名

OWNERNAME CHAR(32) 表的屬主

SPATIALCOLUMN CHAR(32) 表中存儲空間對象的那一列的列名

DB_X_LL FLOAT(126) 圖層邊界左下x座標

DB_Y_LL FLOAT(126) 圖層邊界左下y座標

DB_X_UR FLOAT(126) 圖層邊界右上x座標

DB_Y_UR FLOAT(126) 圖層邊界右上y座標

COORDINATESYSTEM CHAR(254) 指定圖層使用的座標系統

SYMBOL CHAR(254) 描述圖元的樣式子句

XCOLUMNNAME CHAR(32) 包含X座標的列名

YCOLUMNNAME CHAR(32) 包含Y座標的列名

該表部分部分關鍵內容爲:

TYPE

TABLENAME

OWNER

SPATIALCOLUMN

COOR

SYMBOL

13.3

ASIACAPS

SYSTEM

GEOLOC

Pen (1, 2, 0)

13.3

USERDRAWLAYER

SYSTEM

GEOLOC

Symbol ("zhs.bmp",0,20,0)

其中第一行爲筆者先前用easyloader做實驗時上載的一個表,在此做了註冊。第二行即上一章節例程1所建的userdrawlayer層上載後的表在此自動註冊。symbol列存儲了空間對象的樣式,關於symbol列的語法之後再詳細介紹。咱們之後會知道,這個表是必須的,由於這個表包含了每個要地圖化的oracle數據表中空間對象如何顯示的信息。

咱們再看一下第二個變化即咱們上載了userdrawlayer層後的所獲得的userdrawlayer

表。

5.2.4.2 圖層數據表

在SYSTEM表空間新增了userdrawlayer圖層數據表。打開SYSTEM表空間,找到userdrawlayer數據表,該表的結構爲:

OBJNUMBER VARCHAR2(6)

OBJNAME VARCHAR2(12)

OBJDSCR VARCHAR2(50)

OBJX NUMBER

OBJY NUMBER

MI_RENDITION VARCHAR2(254)

MI_PRINX VARCHAR2(20)

GEOLOC MDSYS.SDO_GEOMETRY

該表的部份內容以下:

OBJNUMBER

OBJNAME

OBJDSCR

MI_RENDITION

MI_PRINX

GEOLOC

01001

市中心醫院

大型中西醫結合醫院…

symbol ("hospial.bmp",0,20,1)

1

 

01002

解放路

全長4千米,西起…

pen (1,1,0)

2

 

01003

西湖

著名旅遊勝地,總面積…

Pen (1, 2, 0) Brush (2, 16777215, 16777215)

3

 

     

由該表結構咱們一眼就能夠看出,前五個字段就是咱們在新建層時自定義的圖元編號、圖元名稱、圖元描述及圖元位置,上載時把它們所有搬移過來。另外又增長了三個字段MI_RENDITION,MI_PRINX,GEOLOC。下面較詳細解釋這三個字段:

1.MI_PRINX:索引字段,爲每一個圖元產生一惟一索引,這是咱們用easyloader上載時指定參數create unique index的結果。

2.MI_RENDITION:從表數據能夠看出,它是用來描述圖元的樣式的。表中是三個表明性圖元的樣式,分別是醫院(點圖元),街道(線樣式)和水域(面樣式)。下面就點線面樣式定義語法介紹以下: 

(1) 點符號樣式

點符號樣式用symbol子句來指定,symbol子句有三種形式:一種是指爲MapInfo 3.0-style符號;一種是指定爲TrueType字體符號;一種是指定爲採用位圖的符號。其語法列於下表:

符號類型

語法

例子

MapInfo 3.0-style

Symbol(shape, color, size)

Symbol(35,0,12)

TrueType font

Symbol(shape,color,size,font,fontstyle,rotation)

Symbol(64,255,12,"MapInfo Weather" ,17,0)

bitmap

Symbol(bitmapname,color,size,customstyle)

Symbol("sign.bmp", 255, 18, 0)

(2)線符號樣式 線符號樣式採用pen子句,其語法爲:

Pen(thickness, pattern, color),例如:Pen(1, 2, 0)。

(3)區域樣式

區域樣式用brush子句指定閉合區域的填充方案,其語法爲:

Brush(pattern,color,backgroundcolor),例如:Brush(2, 255, 65535)。

注意:若是要繪製一個區域圖元時,要把pen子句和brush子句結合起來使用,用pen子句指定區域邊界樣式,用brush子句指定區域內的填充樣式。

至於各子句中用到的樣式常量,顏色常量請參見MapX5.0幫助文檔中「MapX reference information」-「appendix D:constants」中的Color Constants,FillPatternConstants,PenStyleConstants等。

3.GEOLOC: 存儲圖元的空間信息,關於GEOLOC字段請看下一節「空間對象類型SDO_GEOMETRY」專題。

從上面SYSTEM.USERDRAWLAYER數據表的內容能夠看出,每一行的前面幾個字段表明圖元的屬性數據,後面的MI_RENDITION字段及GEOLOC字段表明圖元的空間對象數據,Oracle數據庫完美地把二者統一了起來,用一致的方式來管理,這就是Oracle提供的對象關係模型。

5.2.4.3 空間對象類型SDO_GEOMETRY

在上一節咱們用表數據編輯器打開圖層數據表後,你們並無看到上面表格中畫出的GEOLOC列,這是由於該列是SDO_GEOMETRY空間對象類型,是真正存儲圖元空間數據的部分,在表中隱藏。咱們能夠經過sql語句觀察每一個圖元的空間數據的值倒底是什麼樣子。

在sql plus中用sql語句查看GEOLOC字段的值:

SQL>select GEOLOC from USERDRAWLAYER;

回車後將會顯示圖層中每個圖元的空間數據,下面選出的是點、線、面三種典型圖元的GEOLOC值。

點圖元:

GEOLOC(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

-----------------------------------------------------------------------------

SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(-137.5192, 32.969427, NULL), NULL, NULL)

線圖元:

GEOLOC(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

-----------------------------------------------------------------------------

SDO_GEOMETRY(2002, NULL, SDO_POINT_TYPE(0, 0, NULL), SDO_ELEM_INFO_ARRAY(1, 2, 1), SDO_ORDINATE_ARRAY(-114.9666, .61627203, -114.9666, .61627203))

面圖元:

GEOLOC(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

-----------------------------------------------------------------------------

SDO_GEOMETRY(2003, NULL, SDO_POINT_TYPE(56.7574949, 3.18633104, NULL), SDO_ELEM_

INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARRAY(35.8301621, 16.007866, 67.6552619, -1

4.205263, 77.6848291, 16.577925, 35.8301621, 16.007866))

能夠看出,空間實體的空間信息是存儲在一個字段名爲GEOLOC的列中,該列的類型爲SDO_GEOMETRY。下面對這種存儲空間對象的列的類型定義做出語法解釋。

GEOLOC空間對象的結構定義爲:

GEOLOC(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)即該對象類型字段由SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES五個子屬性構成,下面分別做一解釋:

SDO_GTYPE:指定該空間實體的類型,數值型,長度4位。第一位表示維數(2-2維空間,3-3維空間) ,第二位指定線性參考度量維(指定權值的維數),缺省爲0,第三四位表示圖元類型(00-未定義,01-點,02-直線或曲線,03-多邊形,04-多種形狀集合,05-多點,06-多線,07-多個多邊形) ,例如:2001表示二維空間中的點。

SDO_SRID:指定座標系統代碼,數值型。如8307,表明Longitude / Latitude (WGS 84)座標系統。null值表示沒有指定座標系統。

SDO_POINT(X, Y, Z):以三維組元指定點圖元的空間位置。對於線圖元和麪圖元,該屬性被忽略。

SDO_ELEM_INFO:可變長數組,用來代表如何解釋存儲在SDO_ORDINATES中的數據。若爲點圖元,賦值爲NULL;直線圖元賦值爲SDO_ELEM_INFO_ARRAY(1, 2, 1);矩形圖元賦值爲SDO_ELEM_ INFO_ARRAY(1, 1003, 1)。

SDO_ORDINATES:可變長數組,用來存儲空間實體邊界頂點的座標。如直線SDO_ORDINATE_ARRAY(-114.9666, .61627203, -114.9666, .61627203);三角區域SDO_ORDINATE_ARRAY(35.8301621, 16.007866, 67.6552619, -1 4.205263, 77.6848291, 16.577925, 35.8301621, 16.007866);若爲點圖元賦值爲NULL。

經過上面的解釋,你們就不難看懂每一個圖元的GEOLOC字段的值的含義了,同時咱們也能夠經過編程實現空間對象向Oracle數據庫的存儲了。

還有,上面提到建議讀者帶參數/y運行Easyloader工具,緣由是帶了參數/y後,該工具在上載時,可以自動提取出每一個圖元的樣式,即會提取出圖元symbol子句,pen子句,brush子句,表現爲上載完畢後獲得的Oracle數據表中增長了MI_RENDITION列,該列存儲了每一個圖元的樣式,相信你們一看就明白。

5.2.4.4 手工建立MapCataLog表及在OracleSpatial下的圖層表

上面咱們用上載工具Easyloader, 很方便獲得了必須的MAPINFO_MAPCATALOG目錄表以及圖層MapInfo表在Oracle中存儲的表結構。而這兩個表,在咱們之後的編程以及應用程序的運行中都離不開,因此Easyloader給咱們提供了很大的方便,可是咱們最終要放棄它,咱們用它的目的,正如你們所看到的,是由它引出一系列關於空間對象數據在Oracle中存儲必須掌握的一些概念。由於這些概念比較抽象,咱們沒有先講這些抽象概念,而是先讓讀者看到結果,獲得感性認識,而後再上升至理性認識,我想這樣的方式應該更符合咱們的認知習慣,更容易理解。

若是沒有Easyloader這個工具,咱們就要手工方式來建立這兩個表了,表結構同上面所講,而後用sql語句建立,並作必要的權限控制。如下爲建立腳本:

//mapinfo.sql

//建立用戶mapinfo

CREATE USER "MAPINFO" PROFILE "DEFAULT" IDENTIFIED BY

"********" DEFAULT

TABLESPACE "SYSTEM" TEMPORARY

TABLESPACE "SYSTEM" ACCOUNT UNLOCK;

//建立mapinfo.mapinfo_mapcatalog表

CREATE TABLE "MAPINFO"."MAPINFO_MAPCATALOG"("SPATIALTYPE" FLOAT(

126), "TABLENAME" CHAR(32), "OWNERNAME" CHAR(32),

"SPATIALCOLUMN" CHAR(32), "DB_X_LL" FLOAT(126), "DB_Y_LL" FLOAT(

126), "DB_X_UR" FLOAT(126), "DB_Y_UR" FLOAT(126),

"COORDINATESYSTEM" CHAR(254), "SYMBOL" CHAR(254), "XCOLUMNNAME"

CHAR(32), "YCOLUMNNAME" CHAR(32))

TABLESPACE "SYSTEM" PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS

255

STORAGE ( INITIAL 64K NEXT 64K MINEXTENTS 1 MAXEXTENTS

2147483645 PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1)

LOGGING;

//建立索引

CREATE UNIQUE INDEX "MAPINFO"."MAPCATALOG_IDX"

ON "MAPINFO"."MAPINFO_MAPCATALOG"("TABLENAME", "OWNERNAME")

TABLESPACE "SYSTEM" PCTFREE 10 INITRANS 2 MAXTRANS 255

STORAGE ( INITIAL 64K NEXT 64K MINEXTENTS 1 MAXEXTENTS

2147483645 PCTINCREASE 50 FREELISTS 1)

LOGGING;

//受權訪問mapinfo.mapinfo_mapcatalog表

grant select, insert, update on mapinfo.mapinfo_mapcatalog to public;

CREATE TABLE "SYSTEM"."USERLAYER"("SOURCE" VARCHAR2(50), "NAME"

VARCHAR2(50), "IDENTITY" VARCHAR2(50), "DESCRIPTION" VARCHAR2(

50), "FOUNDTIME" VARCHAR2(50), "OBJX" NUMBER, "OBJY" NUMBER,

"MI_RENDITION" VARCHAR2(254), "MI_PRINX" NUMBER, "GEOLOC"

"MDSYS"."SDO_GEOMETRY", "MEDIA" VARCHAR2(100))

TABLESPACE "TOOLS" PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE ( INITIAL 32K NEXT 32K MINEXTENTS 1 MAXEXTENTS 4096

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1)

LOGGING;

5.2.5用程序實現MapX圖元到oracle數據庫的上載

上面你們已經看出,用Easyloader工具能夠一次性把MapX圖元上載至數據庫保存,很是方便。然而,咱們在應用程序的運行中,不可能調用Easyloader工具上載全部數據,每每是在運行過程當中只上載那些剛增長的新的圖元。由於圖層在Oracle中的數據表的字段定義咱們已經知道,咱們只須要按照字段定義把圖元的相應值插入到Oracle數據表中便可,下面這個函數就以這種思路實現。

5.2.5.1 程序功能

程序實現將圖元的全部信息上載至Oracle圖層數據表。

5.2.5.2 程序實現:

public void insertIntoOracle(string number,string name,string dscr,double x,double y,string prinx,MapXLib.Style style,string featureType,MapXLib.Feature ftr)

{

string rendition="";

string geoloc="";

if (featureType=="symbol")

{

rendition="symbol ("+"\""+style.SymbolBitmapName+"\""+","+

style.SymbolBitmapColor.GetHashCode()+","+

style.SymbolBitmapSize+","+style.SymbolType.GetHashCode()+")";

// geoloc="MDSYS.SDO_GEOMETRY(2001,NULL,MDSYS.SDO_POINT_TYPE("+

x.ToString()+","+y.ToString()+","+"NULL),"+"NULL,NULL)";

}

if (featureType=="pen")

{

rendition="pen ("+style.LineWidth+","+style.LineStyle.GetHashCode()+

","+style.LineColor+")";

geoloc="MDSYS.SDO_GEOMETRY(2002,NULL,MDSYS.SDO_POINT_TYPE(0,0,NULL),

MDSYS.SDO_ELEM_INFO_ARRAY(1, 2, 1),MDSYS.SDO_ORDINATE_ARRAY(";

for(int i=1;i<=ftr.Parts._Item(1).Count;i++)

geoloc+=ftr.Parts._Item(1)._Item(i).X.ToString()+","+

ftr.Parts._Item(1)._Item(i).Y.ToString()+",";

geoloc=geoloc.Substring(0,geoloc.Length-1);

geoloc+="))";

}

if (featureType=="region")

{

rendition="Pen (1,2,0) Brush (2,16777215,16777215)"; geoloc="MDSYS.SDO_GEOMETRY(2002,NULL,MDSYS.SDO_POINT_TYPE("+

x.ToString()+","+y.ToString()+","+"NULL),"+

"MDSYS.SDO_ELEM_INFO_ARRAY(1, 2,1),"+"MDSYS.SDO_ORDINATE_ARRAY(";

for(int j=1;j<=ftr.Parts._Item(1).Count;j++)

geoloc+=ftr.Parts._Item(1)._Item(j).X.ToString()+","+ftr.Parts._Item(1)._Item(j).Y.ToString()+",";

geoloc=geoloc.Substring(1,geoloc.Length-1);

geoloc+="))";

}

OracleConnection myConn = new OracleConnection(myConnString);

string myInsertQuery = "INSERT INTO USERDRAWLAYER (OBJNUMBER,OBJNAME,OBJRELATION,OBJDSCR,OBJTIME,OBJX,OBJY,MI_RENDITION,MI_PRINX,GEOLOC) Values('"+number+"','"+name+"','"+relation+"','"+dscr+"','"+time+"',"+x.ToString()+","+y.ToString()+",'"+rendition+"','"+prinx+"',"+geoloc+")";

OracleCommand myOracleCommand = new OracleCommand(myInsertQuery);

myOracleCommand.Connection = myConn;

myConn.Open();

myOracleCommand.ExecuteNonQuery();

myConn.Close();

}

5.2.5.3程序說明

(1)函數傳入參數: string number,string name,string dscr,double x,double y爲圖元的屬性數據傳入; string prinx爲圖元的惟一索引,這裏由用戶按照某種方式編程獲得,將會賦給表的MI_PRINX字段; MapXLib.Style style爲圖元的類型,是點(用symbol表示),線(用pen表示),仍是區域(用region表示); MapXLib.Feature ftr爲欲插入的圖元。 (2)局部變量: string rendition存儲圖元的樣式,將會賦給表的MI_RENDITION字段; string geoloc存儲圖元的空間對象數據,將會賦給表的GEOLOC字段。

(3)圖元的rendition及geoloc變量的計算:根據咱們前面對字段MI_RENDITION及GEOLOC的語法定義獲得。ftr.Parts._Item(1)是爲計算折線及區域圖元的頂點個數。請讀者對照語法仔細研讀以上代碼,相信不難看懂。

(4)Oracle數據庫的鏈接:用OracleConnection來鏈接Oracle服務器,注意使用該方式鏈接時必定要引用命名空間System.Data.OracleClient,若是沒有請在「項目」菜單中點擊「添加引用」,而後在NET選項卡中單擊System.Data.OracleClient.dll,單擊選擇按鈕後肯定便可;

5.2.6 用程序實現oracle數據表數據下載至MapX中顯示

5.2.6.1程序功能

在MapX中生成一新的圖層,該圖層的全部圖元信息均來自Oracle圖層數據表。

5.2.6.2 程序實現

//*********************************************

//從Oracle Spatial加載空間數據以生成新的圖層

//*********************************************

private void oracleToLayer()

{

MapXLib.Layer layer;

string conn="UID=system;PWD=manager;srvr=caiqin";

string querystr="select * from SYSTEM.USERDRAWLAYER";

MapXLib.LayerInfo LayerInfoObject=new MapXLib.LayerInfoClass(); LayerInfoObject.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeServer;

LayerInfoObject.AddParameter("name","DrawLayerFromDB");

LayerInfoObject.AddParameter("ConnectString",conn);

LayerInfoObject.AddParameter("Query",querystr);

LayerInfoObject.AddParameter("toolkit","ORAINET");

LayerInfoObject.AddParameter("AutoCreateDataset",1); LayerInfoObject.AddParameter("DatasetName","DrawLayerFromDB");

layer=axMap2.Layers.Add(LayerInfoObject,1);

userLayer=layer;

axMap2.Refresh();

axMap2.AutoRedraw=true;

userLayer.Editable =true;

//this.getSymbolStyle();

layer.LabelProperties.Dataset =layer.DataSets._Item(1);

layer.LabelProperties.DataField =layer.DataSets._Item(1).Fields._Item(2);

layer.LabelProperties.Position=MapXLib.PositionConstants.miPositionBC;

layer.LabelProperties.Style.TextFont.Size=10;

layer.LabelProperties.Offset=4;

layer.AutoLabel =true;

}

5.2.6.3程序說明

(1)Layerinfo對象:

這裏咱們再次利用Layerinfo對象來實現從MapX訪問oracle數據,並進行顯示。下面針對Layerinfo對象做一簡單介紹。

Layerinfo對象描述了將要被添加層的一些信息,Layerinfo將被做爲layers.add()的第一個參數應用,以實現把新層增長到layers集合中。它有一個type屬性,定義新層的類型,取值爲LayerTypeConstants常量,其含義以下:

Layerinfo.type

Value

description

miLayerInfoTypeTab

0

已存在的mapinfo tab表

miLayerInfoTypeUserDraw

1

用戶繪製圖層

miLayerInfoTypeRaster

2

柵格圖層

miLayerInfoTypeShape

3

Shape文件(.shp)

miLayerInfoTypeServer

4

數據庫服務器

miLayerInfoTypeGeodictUserName

5

由geodictionaty管理的圖層

miLayerInfoTypeTemp

6

建立臨時圖層

miLayerInfoTypeNewTable

7

建立新的mapinfo圖層

另外,Layerinfo對象有許多參數來具體描述欲添加的圖層,這些參數隨type取值的不一樣而不一樣,具體請參見MapX5.0幫助文檔。

本例是訪問Oracle數據庫中的地理信息,因此type取值應爲miLayerInfoTypeServer,在這種方式下,layerinfo應包含以下參數:

參數名稱

必填

參數說明

Name

Yes

新增圖層的名稱

ConnectString

Yes

DBMS鏈接字符串

Query

Yes

Sql查詢語句

ToolKit

Yes

工具包名稱,取值ODBC或ORAINET

Cache

No

是否啓用緩存管理

MBRSearch

No

是否利用最小外接矩形查找

AutoCreateDataset

No

是否自動產生數據集實現數據綁定

DatasetName

No

數據集的名稱

Visible

No

新層是否可見,默承認見

這些參數的添加方法爲:

LayerInfoObject.AddParameter(參數名稱,參數取值);

針對oracle數據庫,參數ConnectString="UID=system;PWD=manager;SRVR=caiqin",其中UID,PWD,SRVR爲必須的鏈接關鍵字,針對其它ODBC數據源,鏈接關鍵字請使用DSN,DRIVER,UID,PWD。格式均爲「key=value」,它們之間以「;」號隔開。其它參數請參見示例代碼。

(2)本例程中使用了AutoCreateDataset參數取值爲1,自動產生一數據集DrawLayerFromDB,實現新層與Oracle數據庫的數據綁定。

(3)例程最後一段代碼實現自動標註功能。

5.2.7 圖元樣式的還原

你們可能會發現,利用上面的方法,當MapX把上載表讀入顯示時,全部圖元都變成了同同樣式,本來各式各樣的圖元其原本面目都被丟失。這是由於,咱們上面提到的目錄表MAPINFO_MAPCATALOGG,它只爲每一個上載表(圖層)保存了一種樣式做爲其缺省樣式,保存在其symbol字段。因此當將上載表再次讀入顯示時,該表中每個圖元便恢復成這種缺省樣式了。明白了機理,咱們就能夠用其它方法把丟失的樣式找回來。

前面在上載圖元時,咱們已經把每一個圖元的樣式保存在了表的MI_RENDITION字段中,因此讀出時咱們就可利用這個字段把每一個圖元的樣式還原出來。下面的函數就是還原圖元樣式的代碼。

5.2.7.1 程序功能

實現把丟失的圖元樣式找回來。

5.2.7.2 程序實現

private void getSymbolStyle()

{

MapXLib.Dataset dsUserLayer=axMap2.DataSets._Item("DrawLayerFromDB");

MapXLib.Fields fldsUserLayer=dsUserLayer.Fields;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

foreach(MapXLib.Feature fea in axMap2.Layers._Item("DrawLayerFromDB").AllFeatures)

{

rvs=dsUserLayer.get_RowValues(fea);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

if (symbol.Substring(0,3)=="sym")

{

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

fea.Style.SymbolBitmapName=bitmapfile;

fea.Update(true,rvs);

}

if (symbol.Substring(0,3)=="pen")

{

int startindex1=symbol.IndexOf(",");

int lastindex1=symbol.LastIndexOf(",");

int len1=lastindex1 - startindex1-1;

int startindexkh=symbol.IndexOf("(");

int lastindexkh=symbol.LastIndexOf(")");

int len2=lastindexkh - lastindex1-1; fea.Style.LineStyle=(MapXLib.PenStyleConstants)(Convert.ToInt16(symbol.Substring(startindex1+1,len1))); fea.Style.LineWidth=Convert.ToInt16(symbol.Substring(startindexkh+1,1)); fea.Style.LineColor=(uint)Convert.ToInt16(symbol.Substring(lastindex1+1,len2));

fea.Update(true,rvs);

}

}

}

5.2.7.3 程序說明

(1) DrawLayerFromDB爲從Oracle Spatial加載空間數據以生成新的圖層的數據集,見上一例; (2) foreach(MapXLib.Feature fea in axMap2.Layers._Item("DrawLayerFromDB").AllFeatures)爲窮舉圖層中的每個圖元;

(3) rvs=dsUserLayer.get_RowValues(fea):獲得每一個圖元的全部字段信息rowvalues();

rv=rvs._Item("MI_RENDITION"):獲得每一個圖元的樣式;

(4)用字符串運算函數提取出樣式SymbolBitmapName,LineStyle,linewidth,lineColor等。

(5)用提取出的值修改圖元的樣式:fea.style;

(6)樣式修改後,用feature.update()更新圖元;

5.3 在網絡環境下實現圖層信息共享

在網絡環境下,可以實現地理信息的共享將會在某些特殊場合發揮重大做用,好比,多人在不一樣的地域只標繪本區域內的地理信息,而你們可互相看到他人標繪的地理信息,即實現地理信息的共享,這種方法可稱做協同標繪。如前所述,咱們能夠利用MapX同OracleSpatial結合來解決這一問題。然而咱們在實踐中發現,這種方法有一些不太使人滿意的地方,主要有兩點:一是樣式丟失,須要手工還原,二是當數據集刷新時,大大增長數據庫的負擔,運行效率低。爲此咱們想繞過OracleSpatial的機制,經過另外一種方法來解決。

下面咱們以位圖符號圖元爲例來介紹這種協同標繪的實現方法。

5.3.1 實現思路

1.建一數據表,存儲圖元的屬性,其結構以下:

ID

source

filename

x

y

C1

C2

C3

C4

1

C1

Home.bmp

old

new

new

new

2

C1

Hospital.bmp

...

old

new

old

old

3

C1

Home.bmp

old

modified

modified

modified

4

C1

Hospital.bmp

old

deleted

deleted

deleted

各字段意義以下:

ID:圖元的featureID。

Source:圖元的來源即標繪方,表示該圖元是由哪一個標繪方標繪的。表中第一行表示該圖元是由C1標繪的。字段ID就是由標繪方生產出該圖元后提供的FeatureID。

Filename:位圖符號圖元的文件名。該文件必須存於MapX應用程序的CustSymbol目錄下。

x,y:符號圖元的經緯度。

Ci:表示各標繪方(客戶端)對於該圖元的訪問狀態。訪問狀態有如下四種——

old表示標繪方Ci已處理該圖元;

new表示該圖元爲新加圖元,標繪方Ci還未在本地添加該新圖元;

modified表示該圖元被修改,標繪方Ci還未在本地做相應修改;

deleted表示該圖元已被刪除,該標繪方還未在本地做相應刪除。

表中第一行表示該圖元是由C1標繪的,其featureID爲1,C2,C3,C4等各標繪方還未在其本地添加該圖元。

2.本地編輯圖元:

在本地標繪出圖元並輸入圖元各屬性信息,在數據表中按上表結構插入該圖元各屬性信息,並置本方訪問標誌爲old,其它各方訪問標誌爲new。

在本地修改圖元屬性信息後,同時在數據表中修改該圖元相應信息,並置本方訪問標誌爲old,其它各方訪問標誌爲modified。

在本地刪除圖元后,同時在數據表中查找到該圖元,並置本方訪問標誌爲old,其它各方訪問標誌爲deleted。

3.圖元信息異地同步:

各標繪方定時在數據表中查找該標繪方訪問標誌字段爲new的圖元,讀取該圖元的各類信息,在本地添加該圖元;查找該標繪方訪問標誌字段爲modified的圖元,讀取該圖元的各類信息,並在本地做相應修改;查找該標繪方訪問標誌字段爲deleted的圖元,並在本地刪除該圖元;

這樣定時刷新時只讀取新添加的或已修改的圖元,不只實現了網絡環境下異地信息的共享,並且大大提升了系統運行速度。

5.3.3 程序實現

public bool NewUserLayer(string layerName)

//新建自定義圖層,若存在則添加到圖層集中

{

MapXLib.Layer layer;

MapXLib.Fields flds=new MapXLib.FieldsClass();

flds.AddIntegerField("mainID",false);

//該圖元在生產方圖層中的ID,如由本機產生則爲featureID。

//不然由數據庫的ID字段獲得

flds.AddStringField("source",50,false);

flds.AddStringField("name",50,false);

flds.AddStringField("identity",50,false);

flds.AddStringField("description",50,false);

flds.AddStringField("foundTime",50,false);

flds.AddStringField("media",100,false);

flds.AddFloatField("X",false);

flds.AddFloatField("Y",false);

MapXLib.LayerInfo layerInfo;

layerInfo=new MapXLib.LayerInfoClass();

layerInfo.AddParameter("FileSpec",@appDirectory+"\\"+layerName+".tab");

layerInfo.AddParameter("Name",layerName);

layerInfo.AddParameter("Fields",flds);

layerInfo.AddParameter("AutoCreateDataset",1);

layerInfo.AddParameter("DatasetName","ds"+layerName);

if (!File.Exists(@appDirectory+"\\"+layerName+".tab"))

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeNewTable;

}

else

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTab;

}

try

{

layer = axMap1.Layers.Add(layerInfo,1);

axMap1.Refresh();

axMap1.AutoRedraw=true;

return true;

}

catch

{

return false;

}

}

public void InsertIntoOracle(FeatureInfo featureInfo)

{

string c1="new",c2="new",c3="new",c4="new",c5="new",c6="new";

if (locate==1){c1="old";}

if (locate==2){c2="old";}

if (locate==3){c3="old";}

if (locate==4){c4="old";}

if (locate==5){c5="old";}

if (locate==6){c6="old";}

string str="INSERT INTO SYSTEM.INFO(ID, SOURCE, NAME, IDENTITY,

DESCRIPTION, FOUNDTIME, MEDIA, X, Y, BMP,C1,C2,C3,C4,C5,C6)";

str+=" Values(";str+=featureInfo.featureID.ToString()+","+featureInfo.source+",'"

+featureInfo.name+"','"+featureInfo.identity+"','"+featureInfo.description+"','"

+featureInfo.foundTime+"','"+featureInfo.media+"',"+featureInfo.point_x.ToString()+","

+featureInfo.point_y.ToString()+",'"+featureInfo.symbolFileName+"','"+c1+"','"+c2+"','"

+c3+"','"+c4+"','"+c5+"','"+c6+"'"+")";

//OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

//myConn.Open();

myOracleCommand.ExecuteNonQuery();

//myConn.Close();

}

public void ModifyUserSymbol(FeatureInfo featureInfo,string selectedFeatureKey,string layerName)//layerName爲viewlayer層的name

{

string c1="modified",c2="modified",c3="modified",c4="modified",c5="modified",c6="modified";

if (locate==1){c1="old";}

if (locate==2){c2="old";}

if (locate==3){c3="old";}

if (locate==4){c4="old";}

if (locate==5){c5="old";}

if (locate==6){c6="old";}

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

MapXLib.Feature selectedFeature=layer.GetFeatureByKey(selectedFeatureKey);

if (selectedFeature==null) return;

MapXLib.RowValues rvs=new MapXLib.RowValuesClass();

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.Fields fldsUserLayer=ds.Fields;

MapXLib.Style style=selectedFeature.Style;

if (featureInfo.identity=="1")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorBlue;

style.SymbolBitmapOverrideColor=true;

}

else if(featureInfo.identity=="2")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorGreen;

style.SymbolBitmapOverrideColor=true;

}

else

{

style.SymbolBitmapColor=0;

style.SymbolBitmapOverrideColor=false;

}

selectedFeature.Style=style;

for(int j=1;j<=ds.Fields.Count;j++)

{

layer.KeyField =fldsUserLayer._Item(j).Name;

if (fldsUserLayer._Item(j).Name.ToUpper() =="SOURCE")

selectedFeature.KeyValue=featureInfo.source;

if (fldsUserLayer._Item(j).Name.ToUpper() =="NAME")

selectedFeature.KeyValue=featureInfo.name;

if (fldsUserLayer._Item(j).Name.ToUpper() =="IDENTITY")

selectedFeature.KeyValue=featureInfo.identity;

if (fldsUserLayer._Item(j).Name.ToUpper() =="DESCRIPTION")

selectedFeature.KeyValue=featureInfo.description;

if (fldsUserLayer._Item(j).Name.ToUpper() =="FOUNDTIME")

selectedFeature.KeyValue=featureInfo.foundTime;

if (fldsUserLayer._Item(j).Name.ToUpper() =="MEDIA")

selectedFeature.KeyValue=featureInfo.media;

if (fldsUserLayer._Item(j).Name.ToUpper() =="X")

selectedFeature.KeyValue=featureInfo.point_x.ToString();

if (fldsUserLayer._Item(j).Name.ToUpper() =="Y")

selectedFeature.KeyValue=featureInfo.point_y.ToString();

selectedFeature.Update(true,rvs);

}

//selectedFeature.Update(true,rvs);

axMap1.AutoRedraw=true;

//

string str="UPDATE SYSTEM.INFO SET ";

str+="NAME='"+featureInfo.name+"'";

str+=",IDENTITY='"+featureInfo.identity+"'";

str+=",DESCRIPTION='"+featureInfo.description+"'";

str+=",FOUNDTIME='"+featureInfo.foundTime+"'";

str+=",MEDIA='"+featureInfo.media+"'";

str+=",X="+featureInfo.point_x.ToString();

str+=",Y="+featureInfo.point_y.ToString();

str+=",C1='"+c1+"'";

str+=",C2='"+c2+"'";

str+=",C3='"+c3+"'";

str+=",C4='"+c4+"'";

str+=",C5='"+c5+"'";

str+=",C6='"+c6+"'";

str+=" WHERE ID="+selectedFeature.FeatureID.ToString()+" AND SOURCE='"+locate.ToString()+"'";

//OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

//myConn.Open();

myOracleCommand.ExecuteNonQuery();

//myConn.Close();

MessageBox.Show("modified successfully");

}

public void DeleteUserSymbol(string layerName,string selectedFeatureKey)

//刪除viewlayer層圖元,layerName爲viewLayer圖層的name

{

string c1="deleted",c2="deleted",c3="deleted",c4="deleted",c5="deleted",c6="deleted";

if (locate==1){c1="old";}

if (locate==2){c2="old";}

if (locate==3){c3="old";}

if (locate==4){c4="old";}

if (locate==5){c5="old";}

if (locate==6){c6="old";}

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

MapXLib.Feature selectedFeature=layer.GetFeatureByKey(selectedFeatureKey);

if (selectedFeature==null) return;

//

string str="UPDATE SYSTEM.INFO SET ";

str+="C1='"+c1+"',C2='"+c2+"',C3='"+c3+"',C4='"+c4+"',C5='"+c5+"',C6='"+c6+"' ";

str+="WHERE ID="+selectedFeature.FeatureID.ToString()+" AND SOURCE="+locate.ToString();

//OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

//myConn.Open();

myOracleCommand.ExecuteNonQuery();

//myConn.Close();

layer.DeleteFeature(selectedFeature);

}

private void timer1_Tick(object sender, System.EventArgs e)

{

FeatureInfo featureInfo=new FeatureInfo();

MapXLib.Variables vs=new MapXLib.VariablesClass();

MapXLib.Features features;

MapXLib.Feature feature=null;

string whereCondition,colStr="",type;

//查詢數據庫中新增長的圖元加到本地圖層中

locate=4;

switch(locate)

{

case 1:

{

whereCondition="C1='new' or C1='modified' or C1='deleted'";

colStr="C1";

break;

}

case 2:

{

whereCondition="C2='new' or C2='modified' or C2='deleted'";

colStr="C2";

break;

}

case 3:

{

whereCondition="C3='new' or C3='modified' or C3='deleted'";

colStr="C3";

break;

}

case 4:

{

whereCondition="C4='new' or C4='modified' or C4='deleted'";

colStr="C4";

break;

}

case 5:

{

whereCondition="C5='new' or C5='modified' or C5='deleted'";

colStr="C5";

break;

}

case 6:

{

whereCondition="C6='new' or C6='modified' or C6='deleted'";

colStr="C6";

break;

}

default:whereCondition="C6=''";

break;

}

string str="SELECT ID,SOURCE,NAME,IDENTITY,DESCRIPTION,

FOUNDTIME,MEDIA,X,Y,BMP,"+colStr+" FROM SYSTEM.INFO ";

str+="WHERE "+whereCondition;

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

OracleDataReader myReader=myOracleCommand.ExecuteReader();

while(myReader.Read())

{

featureInfo.featureID=myReader.GetInt32(0);

featureInfo.source=myReader.GetValue(1).ToString();

try{featureInfo.name=myReader.GetString(2);}

catch{featureInfo.name="";}

featureInfo.identity=myReader.GetString(3);

try{featureInfo.description=myReader.GetString(4);}

catch{featureInfo.description="";}

try{featureInfo.foundTime=myReader.GetString(5);}

catch{featureInfo.foundTime="";}

try{featureInfo.media=myReader.GetString(6);}

catch{featureInfo.media="";}

featureInfo.point_x=myReader.GetDouble(7);

featureInfo.point_y=myReader.GetDouble(8);

featureInfo.symbolFileName=myReader.GetString(9);

type=myReader.GetString(10);

string str1;

if (type=="new")

{

this.AddUserSymbolOnLayer(featureInfo,"userLayer");

}

if (type=="modified")

{

string searchStr="mainID="+featureInfo.featureID.ToString()+

" and source like "+"\"%"+featureInfo.source+"%\"";

features=axMap1.Layers._Item("userLayer").Search(searchStr,vs);

if (features.Count>0)

{

feature=features._Item(1); this.ModifyUserSymbol(featureInfo,feature.FeatureKey,"userLayer");

}

}

if(type=="deleted")

{

string searchStr="mainID="+featureInfo.featureID.ToString()+

" and source like "+"\"%"+featureInfo.source+"%\"";

features=axMap1.Layers._Item("userLayer").Search(searchStr,vs);

if (features.Count>0)

{

feature=features._Item(1);

this.DeleteUserSymbol("userLayer",feature.FeatureKey);

}

}

//修改對應列的標誌爲old,表示新增的或新修改的或新刪除的圖元在本機已作同步更改

str1="UPDATE SYSTEM.INFO SET "+colStr+"='old'";

OracleCommand myOracleCommand1 = new OracleCommand(str1);

myOracleCommand1.Connection = myConn;

myOracleCommand1.ExecuteNonQuery();

}

myReader.Close();

//MessageBox.Show(axMap1.Layers._Item(1).AllFeatures.Count.ToString());

}

5.3.3 程序說明:略

 

 

第六章 MapCtrl控件的開發方法

在這一章節咱們對MapX進行二次封裝,實現地理信息系統的大部分功能,從而從總體上把握地理信息系統的開發方法。

6.1 主要功能

1.地圖基本功能:放大、縮小、居中、漫遊、測量

2.新建圖層、刪除圖層、圖層控制

3.增長圖元、修改圖元、刪除圖元、查找圖元

4.利用OracleSpatial把圖元存於空間數據庫中以便網絡共享

5.鷹眼圖功能

6.2 開發步驟

1.選擇「菜單文件」—「新建項目」,打開新建項目對話框。

2.在項目類型中選擇「visual C#」類型,在模板中選擇「windows控件庫」,輸入控件庫名稱「mapCtrl」,單擊「肯定」,出現用戶控件設計窗體。

3.在設計窗體中添加MapX5.0控件,StatusBar控件,ToolTip控件,TooBar控件等,設計效果以下圖:

clip_image015

4.打開代碼編輯器,定義各類控件接口,添加各類變量定義,功能函數,自定義事件及事件處理程序等,完成以上所需的各類功能。

5.設計完成後,另存爲mapCtrl.cs。

6.選擇菜單「生成」—「生成mapCtrl」,生成mapCtrl控件庫。

6.3 程序實現

整個控件的原代碼摘要以下:

using System;

using System.Collections;

using System.ComponentModel;

using System.Drawing;

using System.Data;

using System.Data.OracleClient;

using System.Windows.Forms;

using MapXLib;

using System.IO;

namespace mapCtrl

{

public delegate void AddSymbolDelegate ();

public delegate void ChangeMapDelegate ();

public delegate void MeasureDelegate(int mode,string[] value1);

public delegate void MapRefreshDelegate();

public struct FeatureInfo

{

//數據屬性

public int featureID; //圖元的惟一標示符(只讀)

public string source; //圖元來源(提供者)

public string name; //圖元名稱

public string description; //圖元描述

public string media; //與圖元關聯的多媒體信息

public string identity; //圖元身份(類型)

public string foundTime; //時間

//符號屬性

public string symbolFileName; //圖元符號bmp文件名

//幾何屬性

public int featureType; //圖元類型:0點圖元,1線圖元,2面圖元

public double point_x; //點圖元的經度

public double point_y; //點圖元的緯度

public double[] line_xy; //線圖元的頂點座標序列:x1,y1,x2,y2....

public double[] polygon_xy; //面圖元的頂點座標序列

//擴展屬性

public string property1;

public string property2;

public string property3;

public string property4;

public string property5;

}

public struct featureRefreshProp

{

public string featureKey;

public string symbol;

}

public class mapCtrl : System.Windows.Forms.UserControl

{

public AxMapXLib.AxMap axMap1;

private AxMapXLib.AxMap mapSmall;//對鷹眼圖控件的引用

private MapXLib.Layer m_Layer;

private double mapZoom,mapCenterX,mapCenterY;

//保存初始縮放比例、中心點座標

private const int miGetLength =100;//自定義用戶工具:測量長度

private const int miGetArea =101;//自定義用戶工具:測量面積

private const int miAddSymbol=102;//

private string geoset;

private string appDirectory;//應用程序目錄

private string connectString;//數據庫鏈接字符串

private string connStringForLayerInfo;//layerinfo對象對數據庫的鏈接參數

private string[] symbolProperty;//

private string selectedFeatureKey;//當前具備焦點的圖元

private string userLayerName;

private System.Windows.Forms.ToolTip toolTip1;

private System.Windows.Forms.OpenFileDialog openFileDialog1;

private System.Windows.Forms.ContextMenu mapMenu;

private System.Windows.Forms.MenuItem menuItemChangeGST;

private System.Windows.Forms.MenuItem menuItemSaveGST;

private System.Windows.Forms.MenuItem menuItemLayerCTL;

private System.ComponentModel.IContainer components;

public RunInfo rif=new RunInfo ();

public event AddSymbolDelegate addSymbolDelegate;

public event ChangeMapDelegate changeMapDelegate;

public event MeasureDelegate measureDelegate;

public event MapRefreshDelegate mapRefreshDelegate;

public featureRefreshProp []frp=new featureRefreshProp [1];

public FeatureInfo currentFeatureInfo=new FeatureInfo ();

public mapCtrl()

{

// 該調用是 Windows.Forms 窗體設計器所必需的.

InitializeComponent();

// TODO: 在 InitComponent 調用後添加任何初始化

}

/// <summary>

/// 清理全部正在使用的資源.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if( components != null )

components.Dispose();

}

base.Dispose( disposing );

}

#region 組件設計器生成的代碼

/// <summary>

/// 設計器支持所需的方法 - 不要使用代碼編輯器

/// 修改此方法的內容.

/// </summary>

private void InitializeComponent()

{

this.components = new System.ComponentModel.Container();

System.Resources.ResourceManager resources=

new System.Resources.ResourceManager(typeof(mapCtrl));

this.axMap1 = new AxMapXLib.AxMap();

this.toolTip1= new System.Windows.Forms.ToolTip(this.components);

this.openFileDialog1= new System.Windows.Forms.OpenFileDialog();

this.mapMenu = new System.Windows.Forms.ContextMenu();

this.menuItemChangeGST= new System.Windows.Forms.MenuItem();

this.menuItemSaveGST = new System.Windows.Forms.MenuItem();

this.menuItemLayerCTL = new System.Windows.Forms.MenuItem();

((System.ComponentModel.ISupportInitialize)(this.axMap1)).BeginInit();

this.SuspendLayout();

this.axMap1.Dock = System.Windows.Forms.DockStyle.Fill;

this.axMap1.Enabled = true;

this.axMap1.Location = new System.Drawing.Point(0,0);

this.axMap1.Name = "axMap1";

this.axMap1.OcxState= ((System.Windows.Forms.AxHost.State)(resources.GetObject("axMap1.OcxState")));

this.axMap1.Size = new System.Drawing.Size(360, 296);

this.axMap1.TabIndex = 0;

this.axMap1.PolyToolUsed+=new AxMapXLib.CMapXEvents_PolyToolUsedEventHandler(this.axMap1_PolyToolUsed);

this.axMap1.SelectionChanged+=new System.EventHandler(this.axMap1_SelectionChanged);

this.axMap1.ToolUsed+=new AxMapXLib.CMapXEvents_ToolUsedEventHandler(this.axMap1_ToolUsed);

this.axMap1.MouseUpEvent+=new AxMapXLib.CMapXEvents_MouseUpEventHandler(this.axMap1_MouseUpEvent);

this.axMap1.MouseDownEvent+=new AxMapXLib.CMapXEvents_MouseDownEventHandler(this.axMap1_MouseDownEvent);

this.axMap1.MouseMoveEvent+=new AxMapXLib.CMapXEvents_MouseMoveEventHandler(this.axMap1_MouseMoveEvent);

this.axMap1.MapViewChanged+=new System.EventHandler(this.axMap1_MapViewChanged);

//

// mapMenu

//

this.mapMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {

this.menuItemChangeGST, this.menuItemSaveGST, this.menuItemLayerCTL});

//

// menuItemChangeGST

//

this.menuItemChangeGST.Index = 0;

this.menuItemChangeGST.ShowShortcut = false;

this.menuItemChangeGST.Text = "更換地圖";

this.menuItemChangeGST.Click+=new System.EventHandler(this.menuItemChangeGST_Click);

//

// menuItemSaveGST

//

this.menuItemSaveGST.Index = 1;

this.menuItemSaveGST.ShowShortcut = false;

this.menuItemSaveGST.Text = "保存地圖設置";

this.menuItemSaveGST.Click+=new System.EventHandler(this.menuItemSaveGST_Click);

//

// menuItemLayerCTL

//

this.menuItemLayerCTL.Index = 2;

this.menuItemLayerCTL.ShowShortcut = false;

this.menuItemLayerCTL.Text = "地圖圖層控制";

this.menuItemLayerCTL.Click+=new System.EventHandler(this.menuItemLayerCTL_Click);

//

// mapCtrl

//

this.Controls.Add(this.axMap1);

this.Name = "mapCtrl";

this.Size = new System.Drawing.Size(360, 296);

this.Load += new System.EventHandler(this.mapCtrl_Load);

((System.ComponentModel.ISupportInitialize)(this.axMap1)).EndInit();

this.ResumeLayout(false);

}

#endregion

//屬性獲取

public string SelectedFeatureKey

{

get

{

return selectedFeatureKey;

}

}

public string Geoset

{

get

{

return geoset;

}

set

{

geoset = value;

}

}

public string ConnectString

{

get

{

return connectString;

}

set

{

connectString=value;

}

}

public string UserLayerName

{

get

{

return userLayerName;

}

set

{

userLayerName=value;

}

}

public string ConnStringForLayerInfo

{

get

{

return connStringForLayerInfo;

}

set

{

connStringForLayerInfo=value;

}

}

public string AppDirectory

{

get

{

return appDirectory;

}

set

{

appDirectory=value;

}

}

//電子地圖基本操做:放大、縮小、漫遊、恢復

public void MapZoomIn()

{

axMap1.CurrentTool=ToolConstants.miZoomInTool;

}

public void MapZoomOut()

{

axMap1.CurrentTool=ToolConstants.miZoomOutTool;

}

public void MapPan()

{

axMap1.CurrentTool=ToolConstants.miPanTool;

}

public void MapCenter()

{

axMap1.CurrentTool=ToolConstants.miCenterTool;

}

public void MapArrow()

{

axMap1.CurrentTool=ToolConstants.miArrowTool;

}

public void MapReset()

{

axMap1.ZoomTo(this.mapZoom,this.mapCenterX,this.mapCenterY);

}

//圖元選擇

public void FeaturePointSelect()

{

axMap1.CurrentTool=ToolConstants.miSelectTool;

axMap1.AutoRedraw=true;

}

public void FeaturePolygonSelect()

{

axMap1.CurrentTool=ToolConstants.miPolygonSelectTool;

axMap1.AutoRedraw=true;

}

public void FeatureRadiusSelect()

{

axMap1.CurrentTool=ToolConstants.miRadiusSelectTool;

axMap1.AutoRedraw=true;

}

public void FeatureRectSelect()

{

axMap1.AutoRedraw=false;

axMap1.CurrentTool=ToolConstants.miRectSelectTool;

//axMap1.CurrentTool=ToolConstants.miRadiusSelectTool;

}

//地圖測量

public void GetLength()

{

axMap1.CurrentTool=(MapXLib.ToolConstants)miGetLength;

}

public void GetArea()

{

axMap1.CurrentTool=(MapXLib.ToolConstants)miGetArea;

}

private void mapCtrl_Load(object sender, System.EventArgs e)

{

//每一個圖元有7個屬性

symbolProperty=new string[7];//僅用於selectionchanged事件中顯示tooltip

//保存應用程序目錄

appDirectory = Directory.GetCurrentDirectory();

//保存地圖初始值

mapZoom=axMap1.Zoom;

mapCenterX=axMap1.CenterX;

mapCenterY=axMap1.CenterY;

//產生自定義地圖測量工具

axMap1.CreateCustomTool(miGetArea,MapXLib.ToolTypeConstants.miToolTypePolygon,

MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,

MapXLib.CursorConstants.miCrossCursor,false);

axMap1.CreateCustomTool(miGetLength,MapXLib.ToolTypeConstants.miToolTypePoly,

MapXLib.CursorConstants.miCrossCursor,MapXLib.CursorConstants.miCrossCursor,

MapXLib.CursorConstants.miCrossCursor,false);

}

private void axMap1_PolyToolUsed(object sender, AxMapXLib.CMapXEvents_PolyToolUsedEvent e)

{

double length=0,area=0;

string []value1=new string [1];

if(e.toolNum==miGetLength)

//長度及面積爲只讀屬性從控件的length和area屬性中讀取

{

MapXLib.Points pts=(MapXLib.Points)e.points;

MapXLib.Point pt1,pt2;

for(int i=1;i<pts.Count;i++)

{

pt1=pts._Item(i);

pt2=pts._Item(i+1);

length+=axMap1.Distance(pt1.X,pt1.Y,pt2.X,pt2.Y);

}

value1[0]=length.ToString() ;

measureDelegate(0,value1);

}

else if(e.toolNum==miGetArea)

{

MapXLib.Points pts=(MapXLib.Points)e.points;

MapXLib.FeatureFactory dd=axMap1.FeatureFactory;

MapXLib.Style style=axMap1.DefaultStyle;

area=dd.CreateRegion(pts,style).Area;

value1[0]=area.ToString() ;

measureDelegate(1,value1);

}

}

//地圖控制

public bool OpenGeoset(ref string geosetFileName)//參數要帶擴展名.gst

{

openFileDialog1.DefaultExt ="*.gst";

openFileDialog1.Filter="geoset file (*.gst)|*.gst";

openFileDialog1.ShowDialog();

geosetFileName=openFileDialog1.FileName;

if (!File.Exists(geosetFileName))

return false;

else

{

geoset=geosetFileName;

axMap1.GeoSet=openFileDialog1.FileName;

axMap1 .TitleText ="";

mapZoom=axMap1.Zoom;

mapCenterX=axMap1.CenterX;

mapCenterY=axMap1.CenterY;

return true;

}

}

public bool OpenGeoset(string geosetFileName)//參數要帶擴展名.gst

{

if (!File.Exists(geosetFileName))

return false;

else

{

try

{

geoset=geosetFileName;

axMap1.GeoSet=geosetFileName;

axMap1 .TitleText ="";

mapZoom=axMap1.Zoom;

mapCenterX=axMap1.CenterX;

mapCenterY=axMap1.CenterY;

return true;

}

catch

{

return false;

}

}

}

public void SaveGeoset(string geosetFileName)

{

try

{

axMap1.SaveMapAsGeoset(axMap1.Title.ToString(),@geosetFileName);

}

catch{}

}

public void LayerCtrl()//圖層控制

{

axMap1.Layers.LayersDlg(1,1);

}

public bool NewUserLayer(string layerName)

//新建自定義圖層,若存在則添加到圖層集中

{

MapXLib.Layer layer;

MapXLib.Fields flds=new MapXLib.FieldsClass();

flds.AddStringField("source",50,false);

flds.AddStringField("name",50,false);

flds.AddStringField("identity",50,false);

flds.AddStringField("description",50,false);

flds.AddStringField("foundTime",50,false);

flds.AddFloatField("objX",false);

flds.AddFloatField("objY",false);

MapXLib.LayerInfo layerInfo;

layerInfo=new MapXLib.LayerInfoClass();

layerInfo.AddParameter("FileSpec",@appDirectory+"\\"+layerName+".tab");

layerInfo.AddParameter("Name",layerName);

layerInfo.AddParameter("Fields",flds);

layerInfo.AddParameter("AutoCreateDataset",1);

layerInfo.AddParameter("DatasetName","ds"+layerName);

if (!File.Exists(@appDirectory+"\\"+layerName+".tab"))

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeNewTable; }

else

{

layerInfo.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTab;

}

try

{

layer = axMap1.Layers.Add(layerInfo,1);

axMap1.Refresh();

return true;

}

catch

{

return false;

}

}

public bool LoadRasterLayer(string layerName)//裝載柵格圖層

{

int layerNumber=axMap1.Layers.Count;

try

{

axMap1.Layers.Add(layerName+".tab",layerNumber+1);

return true;

}

catch

{

return false;

}

}

public void DeleteLayer(string layerName)

{

int index;

for(int i=1;i<=axMap1.Layers.Count;i++)

{

if (axMap1.Layers._Item(i).Name==layerName)

{

index=i;

axMap1.Layers.Remove(index);

return;

}

}

}

private void OpenDatabase(string connectString)//打開到數據庫的鏈接

{

OracleConnection myConn = new OracleConnection(connectString);

myConn.Open();

}

public bool NewLayerTable(string layerName)

//在oracle中創建圖層對應的表,表名等於層名,可由easyloader工具實現

{

MapXLib.Fields fields=new MapXLib.FieldsClass();

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

if (layer==null) return false;

}

fields=layer.DataSets._Item("ds"+layerName).Fields;

int fieldCount=layer.DataSets._Item("ds"+layerName).Fields.Count;

string [] fieldSet=new string[fieldCount+3];//後面爲圖元空間屬性字段

for(int i=1;i<=fieldCount;i++)

{

fieldSet[i]=fields._Item(i).Name;

}

string str="";

for(int j=1;j<=fieldCount-2;j++)

{

str+=fieldSet[j]+" VARCHAR2(50) NULL"+",";

}

str+="OBJX NUMBER,OBJY NUMBER,";

str+="MI_RENDITION VARCHAR2(50) NULL,

MI_PRINX NUMBER,GEOLOC MDSYS.SDO_GEOMETRY NULL";

string creatLayerTable="CREATE TABLE "+"SYSTEM" +"."+layerName +"("+str+")";

string id=rif.dataBaseMap .id ;

string password=rif.dataBaseMap .password ;

string dataSource=rif.dataBaseMap.server ;

connectString="user id="+id+" ;data source="+dataSource +";password="+password;

OracleConnection myConn = new OracleConnection(connectString);

myConn.Open();

OracleCommand myOracleCommand =

new OracleCommand(creatLayerTable);

myOracleCommand.Connection = myConn;

try

{

myOracleCommand.ExecuteNonQuery();

myConn.Close();

return true;

}

catch

{

myConn.Close();

return false;

}

return true;

}

public void AddUserSymbol(ref FeatureInfo featureInfo,string layerName)

//增長到userlayer後插入oracle表中

{

try

{

MapXLib.Point pnt=new MapXLib.PointClass();

MapXLib.RowValue rv=new MapXLib.RowValueClass();

MapXLib.RowValues rvs=new MapXLib.RowValuesClass();

MapXLib.Feature ftr;

MapXLib.FeatureFactory feaFac;

MapXLib.Layer layer=axMap1.Layers._Item(layerName);

MapXLib.Style newStyle=new MapXLib.StyleClass();

feaFac = axMap1.FeatureFactory;

newStyle.SymbolType =MapXLib.SymbolTypeConstants.miSymbolTypeBitmap;

newStyle.SymbolBitmapSize=20;

//根據圖元身份不一樣圖元用不一樣的顏色區分

if (featureInfo.identity=="0")

{ newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorBlue;

newStyle.SymbolBitmapOverrideColor=true;

}

else if(featureInfo.identity=="1")

{

newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorGreen;

newStyle.SymbolBitmapOverrideColor=true;

}

else

{

newStyle.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorRed ;

newStyle.SymbolBitmapOverrideColor=true;

}

newStyle.SymbolBitmapName=featureInfo.symbolFileName;

newStyle.SymbolBitmapTransparent=true;

axMap1.AutoRedraw = false;//禁止圖層自動刷新

layer.Editable =true;

pnt.Set(featureInfo.point_x,featureInfo.point_y);

ftr= feaFac.CreateSymbol(pnt,newStyle);

//******************************************************

//如下代碼經過rowvalue和rowvalues來爲新建圖元設置全部屬性

//******************************************************

MapXLib.Dataset dsUserLayer;

MapXLib.Fields fldsUserLayer;

dsUserLayer=axMap1.DataSets._Item("ds"+layerName);

fldsUserLayer=dsUserLayer.Fields;

rv.Dataset =dsUserLayer;

//MI_PRINX索引構成規則:number前2位加yymmddhhmmss

DateTime myDataTime=DateTime.Now;

if (featureInfo.source==null) featureInfo.source="6";

string rownumber=featureInfo.source.PadLeft (

2,'0')+myDataTime.Year.ToString()+myDataTime.Month.ToString()

+myDataTime.Day.ToString()+myDataTime.Hour.ToString()+myDataTime.Minute.ToString()+myDataTime.Second.ToString();

for(int j=1;j<=fldsUserLayer.Count;j++)

{

if(j==1)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.source;

}

if(j==2)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.name;

}

if(j==3)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value=featureInfo.identity;

}

if(j==4)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.description;

}

if(j==5)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.foundTime;

}

if(j==6)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.point_x;

}

if(j==7)

{

rv.Field=fldsUserLayer._Item(j);

rv.Value =featureInfo.point_y;

}

rvs.Add(rv);

}

layer.AddFeature(ftr,rvs);

layer.Refresh();

this.InsertIntoOracle(featureInfo,rownumber,ftr.Style,"symbol",ftr,layerName);

DeleteAllfeatures(userLayerName);

}

catch{}

axMap1.AutoRedraw = true;

}

public void ModifyUserSymbol(FeatureInfo featureInfo,string layerName)

//修改圖元屬性,layerName爲viewlayer層的name

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

MapXLib.Feature selectedFeature=layer.GetFeatureByKey(featureInfo.featureKey );

if (selectedFeature==null) return;

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.RowValues rowValues=ds.get_RowValues(selectedFeature);

MapXLib.RowValue rowValue=rowValues._Item("MI_PRINX");

string prinx=rowValue.Value.ToString();//取得該圖元在數據庫中行的索引值

string rendition="";

string geoloc="";

MapXLib.Style style=selectedFeature.Style;

if (featureInfo.identity=="0")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorBlue;

style.SymbolBitmapOverrideColor=true;

}

else if(featureInfo.identity=="1")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorGreen;

style.SymbolBitmapOverrideColor=true;

}

else

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorRed ;

style.SymbolBitmapOverrideColor=true;

}

rendition="symbol("+"\""+style.SymbolBitmapName+"\""

+","+style.SymbolBitmapColor+","+style.SymbolBitmapSize+","+style.SymbolType+")"; geoloc="MDSYS.SDO_GEOMETRY(2001,NULL,

MDSYS.SDO_POINT_TYPE("+featureInfo.point_x.ToString()+",

"+featureInfo.point_y.ToString()+","+"NULL),"+"NULL,NULL)";

MapXLib.Fields fields=new MapXLib.FieldsClass();

fields=axMap1.DataSets._Item("ds"+layerName).Fields;

int fieldCount=fields.Count;

string [] fieldSet=new string[fieldCount+1];

for(int i=1;i<=fieldCount;i++)

{

fieldSet[i-1]=fields._Item(i).Name;

}

fieldSet[fieldCount-1]="GEOLOC";

string tableName=layerName.Substring(0,layerName.Length-6);

string str="UPDATE SYSTEM."+tableName +" SET ";

str+=fieldSet[0]+"='"+featureInfo.source+"'";

str+=","+fieldSet[1]+"='"+featureInfo.name+"'";

str+=","+fieldSet[2]+"='"+featureInfo.identity+"'";

str+=","+fieldSet[3]+"='"+featureInfo.description+"'";

str+=","+fieldSet[4]+"='"+featureInfo.foundTime+"'";

str+=","+fieldSet[5]+"="+featureInfo.point_x.ToString();

str+=","+fieldSet[6]+"="+featureInfo.point_y.ToString();

str+=","+fieldSet[7]+"='"+rendition+"'";

str+=","+fieldSet[8]+"="+geoloc+"";

str+=" WHERE MI_PRINX="+prinx;

OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

myConn.Open();

myOracleCommand.ExecuteNonQuery();

myConn.Close();

}

public void ModifyUserSymbol(string featureKey,double X,double Y,string layerName)

//修改圖元屬性,layerName爲viewlayer層的name

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

FeatureInfo featureInfo=new FeatureInfo ();

GetFeaturePropertyByFeatureKey(layerName,ref featureInfo,featureKey);

featureInfo.point_x =X;

featureInfo .point_y =Y;

MapXLib.Feature selectedFeature=layer.GetFeatureByKey(featureInfo.featureKey );

if (selectedFeature==null) return;

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.RowValues rowValues=ds.get_RowValues(selectedFeature);

MapXLib.RowValue rowValue=rowValues._Item("MI_PRINX");

string prinx=rowValue.Value.ToString();//取得該圖元在數據庫中行的索引值

string rendition="";

string geoloc="";

MapXLib.Style style=selectedFeature.Style;

if (featureInfo.identity=="0")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorBlue;

style.SymbolBitmapOverrideColor=true;

}

else if(featureInfo.identity=="1")

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorGreen;

style.SymbolBitmapOverrideColor=true;

}

else

{

style.SymbolBitmapColor=(uint)MapXLib.ColorConstants.miColorRed ;

style.SymbolBitmapOverrideColor=true;

}

rendition="symbol ("+"\""+featureInfo.symbolFileName +"\""+","+

style.SymbolBitmapColor+","+style.SymbolBitmapSize+","+style.SymbolType+")";

geoloc="MDSYS.SDO_GEOMETRY(2001,NULL,MDSYS.SDO_POINT_TYPE("+

featureInfo.point_x.ToString()+","+featureInfo.point_y.ToString()+","+"NULL),"+

"NULL,NULL)";

MapXLib.Fields fields=new MapXLib.FieldsClass();

fields=axMap1.DataSets._Item("ds"+layerName).Fields;

int fieldCount=fields.Count;

string [] fieldSet=new string[fieldCount+1];

for(int i=1;i<=fieldCount;i++)

{

fieldSet[i-1]=fields._Item(i).Name;

}

fieldSet[fieldCount-1]="GEOLOC";

string tableName=layerName.Substring(0,layerName.Length-6);

string str="UPDATE SYSTEM."+tableName +" SET ";

str+=fieldSet[0]+"='"+featureInfo.source+"'";

str+=","+fieldSet[1]+"='"+featureInfo.name+"'";

str+=","+fieldSet[2]+"='"+featureInfo.identity+"'";

str+=","+fieldSet[3]+"='"+featureInfo.description+"'";

str+=","+fieldSet[4]+"='"+featureInfo.foundTime+"'";

str+=","+fieldSet[5]+"="+featureInfo.point_x.ToString();

str+=","+fieldSet[6]+"="+featureInfo.point_y.ToString();

str+=","+fieldSet[7]+"='"+rendition+"'";

str+=","+fieldSet[8]+"="+geoloc+"";

str+=" WHERE MI_PRINX="+prinx;

OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

myConn.Open();

myOracleCommand.ExecuteNonQuery();

myConn.Close();

}

public void DataSetRefresh(string layerName)

//與圖層關聯的數據集刷新

{

MapXLib.Layer layer=axMap1.Layers._Item(layerName+"FromDB");

MapXLib.Dataset ds;

ds=layer.DataSets._Item("ds"+layerName+"FromDB");

ds.Refresh();

}

//將圖元的各類屬性插入Oracle數據表

public void InsertIntoOracle(FeatureInfo featureInfo,string prinx,MapXLib.Style style,string featureType,MapXLib.Feature ftr,string layerName)

{

string rendition="";

string geoloc="";

if (featureType=="symbol")

{

rendition="symbol ("+"\""+featureInfo.symbolFileName +"\""+","+

style.SymbolBitmapColor+","+style.SymbolBitmapSize+","+style.SymbolType+")"; geoloc="MDSYS.SDO_GEOMETRY(2001,NULL,MDSYS.SDO_POINT_TYPE("+featureInfo.point_x.ToString()+","+featureInfo.point_y.ToString()+","+"NULL),"+"NULL,NULL)";

}

MapXLib.Fields fields=new MapXLib.FieldsClass();

fields=axMap1.DataSets._Item("ds"+layerName).Fields;

int fieldCount=fields.Count;

string [] fieldSet=new string[fieldCount+4];

for(int i=1;i<=fieldCount;i++)

{

fieldSet[i-1]=fields._Item(i).Name;

}

fieldSet[fieldCount+1]="MI_REDITION";

fieldSet[fieldCount+2]="MI_PRINX";

fieldSet[fieldCount+3]="GEOLOC";

string str="INSERT INTO "+layerName +"(";

str+=fieldSet[0];

for(int j=1;j<fieldCount;j++)

{

str+=","+fieldSet[j];

}

str+=",MI_RENDITION,MI_PRINX,GEOLOC) Values(";

str+="'"+featureInfo.source+"','"+featureInfo.name+"','"+featureInfo.identity+"','"+

featureInfo.description+"','"+featureInfo.foundTime+"',"+featureInfo.point_x.ToString()+

","+featureInfo.point_y.ToString()+",'"+rendition+"',"+prinx+","+geoloc+")";

OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

myConn.Open();

myOracleCommand.ExecuteNonQuery();

myConn.Close();

}

//*********************************************

//從Oracle Spatial加載空間數據以生成新的圖層

//*********************************************

public void OracleToLayer(string tableName)

//tableName爲oracle數據庫表名與其對應的圖層名同樣

{

axMap1 .AutoRedraw =false;

try

{

bool flag=false;

for(int i=1;i<=axMap1.DataSets.Count ;i++)

{

if(axMap1.DataSets._Item(i).Name =="ds"+tableName+"FromDB")

{

flag=true;

break;

}

}

MapXLib.Layer layer;

if(flag)

{

DataSetRefresh(tableName);

axMap1.Refresh();

getSymbolStyle(tableName+"FromDB");

}

else

{

string querystr="select * from SYSTEM."+tableName.ToUpper();

MapXLib.LayerInfo LayerInfoObject=new MapXLib.LayerInfoClass();

LayerInfoObject.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeServer;

LayerInfoObject.AddParameter("name",tableName+"FromDB");

LayerInfoObject.AddParameter("ConnectString",ConnStringForLayerInfo);

LayerInfoObject.AddParameter("Query",querystr);

LayerInfoObject.AddParameter("toolkit","ORAINET");

LayerInfoObject.AddParameter("AutoCreateDataset",1);

LayerInfoObject.AddParameter("DatasetName","ds"+tableName+"FromDB");

layer=axMap1.Layers.Add(LayerInfoObject,1);

axMap1.DataSets._Item("ds"+tableName+"FromDB").Refresh();

axMap1.Refresh();

layer.Editable =true;

this.getSymbolStyle(tableName+"FromDB");

}

}

catch

{

}

}

public void getSymbolStyle(string layerName)

//恢復圖元樣式,層名與表名一致

{

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.Fields fldsUserLayer=ds.Fields;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

featureRefreshProp []frptemp=

new featureRefreshProp [axMap1.Layers._Item(layerName).AllFeatures.Count ];

foreach(MapXLib.Feature fea in axMap1.Layers._Item(layerName).AllFeatures)

{

try

{

rvs=ds.get_RowValues(fea);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

//判斷相同featureKey是否有變化

int i=0;

if (symbol.Substring(0,3)=="sym")

{

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

startindex=symbol.IndexOf(",")+1;

string str="";

for(i=startindex;symbol[i]!=',';i++)

{

str+=symbol[i];

}

uint SymbolBitmapColor=(uint)Convert.ToInt32(str);

bool SymbolBitmapOverrideColor=true;

if (str!="0")

{

SymbolBitmapColor=(uint)Convert.ToInt32(str);

SymbolBitmapOverrideColor=true;

}

else

{

SymbolBitmapOverrideColor=false;

}

string SymbolBitmapName=bitmapfile;

bool SymbolBitmapTransparent=true;

fea.Style .SymbolBitmapName =SymbolBitmapName;

fea.Style.SymbolBitmapTransparent =SymbolBitmapTransparent;

fea.Style.SymbolBitmapOverrideColor =SymbolBitmapOverrideColor;

fea.Style .SymbolBitmapColor =SymbolBitmapColor;

fea.Update(true,rvs);

}

}

catch

{}

}

frp=frptemp;

mapRefreshDelegate(); //已經刷新

}

private void getSymbolStyle(string layerName,string featureKey)//層名與表名一致

{

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.Fields fldsUserLayer=ds.Fields;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

try

{

MapXLib.Feature fea=axMap1.Layers._Item(layerName).GetFeatureByKey (featureKey);

rvs=ds.get_RowValues(fea);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

if (symbol.Substring(0,3)=="sym")

{

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

//

startindex=symbol.IndexOf(",")+1;

string str="";

for(int i=startindex;symbol[i]!=',';i++)

{

str+=symbol[i];

}

uint SymbolBitmapColor=(uint)Convert.ToInt32(str);

bool SymbolBitmapOverrideColor=true;

if (str!="0")

{

SymbolBitmapColor=(uint)Convert.ToInt32(str);

SymbolBitmapOverrideColor=true;

}

else

{

SymbolBitmapOverrideColor=false;

}

string SymbolBitmapName=bitmapfile;

bool SymbolBitmapTransparent=true;

fea.Style .SymbolBitmapName =SymbolBitmapName;

fea.Style .SymbolBitmapTransparent =SymbolBitmapTransparent;

fea.Style .SymbolBitmapOverrideColor =SymbolBitmapOverrideColor;

fea.Style .SymbolBitmapColor =SymbolBitmapColor;

fea.Update(true,rvs);

}

}

catch

{}

}

public void DeleteAllfeatures(string layerName)

//刪除用戶工做層userLayer中全部圖元

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

if (layer==null) return;

}

foreach(MapXLib.Feature feature in axMap1.Layers._Item(layerName).AllFeatures)

{

axMap1.Layers._Item(layerName).DeleteFeature(feature);

}

axMap1.Layers._Item(layerName).Pack(MapXLib.LayerPackConstant.miPackAll);

}

private void axMap1_SelectionChanged(object sender, System.EventArgs e)

//用於生成viewlayer圖層圖元InfoTip

{

string layerName="userLayer";

MapXLib.Layer layer=axMap1.Layers._Item(layerName+"FromDB");

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName+"FromDB");

foreach(MapXLib.Feature ftr in layer.Selection)

{

selectedFeatureKey=ftr.FeatureKey;

string msg="";

for(int j=1;j<=ds.Fields.Count;j++)

{

layer.KeyField =ds.Fields._Item(j).Name;

msg+=ftr.KeyValue.ToString();

}

toolTip1.SetToolTip(this.axMap1,msg);

}

}

public void GetSymbolPropertyOnUserLayer(string layerName,ref FeatureInfo featureInfo)

//獲取全部選中的圖元的屬性

{

MapXLib.Layer layer=null;

MapXLib.Dataset ds=null;

try

{

layer=axMap1.Layers._Item(layerName);

ds=axMap1.DataSets._Item("ds"+layerName);

}

catch

{

if (layer==null) return;

}

foreach(MapXLib.Feature ftr in layer.AllFeatures )

{

featureInfo .featureKey =ftr.FeatureKey ;

featureInfo .point_x =ftr.CenterX ;

featureInfo .point_y =ftr.CenterY ;

featureInfo .symbolFileName =currentFeatureInfo.symbolFileName;

featureInfo.source =rif.netStatu.localNetIndex.ToString () ;

featureInfo .name ="點擊操做點";

featureInfo .identity =currentFeatureInfo.identity ;

featureInfo .foundTime =DateTime.Now .ToString ();

}

}

public void GetSelectedFeatureProperty(string layerName,ref FeatureInfo []featureInfo)

//獲取和數據庫關聯的圖層的全部選中圖元的屬性(數據庫相關)

{

MapXLib.Layer layer=null;

MapXLib.Dataset ds=null;

MapXLib.Fields fields=null;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

try

{

layer=axMap1.Layers._Item(layerName);

ds=axMap1.DataSets._Item("ds"+layerName);

fields=ds.Fields;

}

catch

{

if (layer==null) return;

}

try

{

int count=layer.Selection .Count ;

if(count==0)

featureInfo =null;

else

featureInfo =new FeatureInfo [count];

int i=0;

foreach(MapXLib.Feature ftr in layer.Selection)

{

featureInfo [i].featureKey =ftr.FeatureKey ;

featureInfo [i].point_x =ftr.CenterX ;

featureInfo [i].point_y =ftr.CenterY ;

eatureInfo [i].symbolFileName =ftr.Style .SymbolBitmapName;

layer.KeyField=fields._Item(1).Name;

featureInfo [i].source =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(2).Name;

featureInfo [i].name =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(3).Name;

featureInfo [i].identity =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(4).Name;

featureInfo [i].description =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(5).Name;

featureInfo [i].foundTime =ftr.KeyValue.ToString();

rvs=ds.get_RowValues(ftr);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

featureInfo[i].symbolFileName =bitmapfile;

i++;

}

}

catch{}

}

public void GetAllFeatureProperty(string layerName,ref FeatureInfo []featureInfo)

//獲取和數據庫關聯的圖層的全部圖元的屬性(數據庫相關)

{

MapXLib.Layer layer=null;

MapXLib.Dataset ds=null;

MapXLib.Fields fields=null;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

try

{

layer=axMap1.Layers._Item(layerName);

ds=axMap1.DataSets._Item("ds"+layerName);

fields=ds.Fields;

}

catch

{

if (layer==null) return;

}

try

{

int count=layer.AllFeatures .Count ;

featureInfo =new FeatureInfo [count];

int i=0;

foreach(MapXLib.Feature ftr in layer.AllFeatures )

{

featureInfo [i].featureKey =ftr.FeatureKey ;

featureInfo [i].point_x =ftr.CenterX ;

featureInfo [i].point_y =ftr.CenterY ;

featureInfo [i].symbolFileName =ftr.Style .SymbolBitmapName;

layer.KeyField=fields._Item(1).Name;

featureInfo [i].source =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(2).Name;

featureInfo [i].name =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(3).Name;

featureInfo [i].identity =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(4).Name;

featureInfo [i].description =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(5).Name;

featureInfo [i].foundTime =ftr.KeyValue.ToString();

rvs=ds.get_RowValues(ftr);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

featureInfo[i].symbolFileName =bitmapfile;

i++;

}

}

catch{}

}

public void GetFeaturePropertyByFeatureKey(string layerName,ref FeatureInfo featureInfo,string featureKey)

//獲取肯定featurekey的圖元屬性(數據庫相關)

{

MapXLib.Layer layer=null;

MapXLib.Dataset ds=null;

MapXLib.Fields fields=null;

MapXLib.RowValues rvs;

MapXLib.RowValue rv;

try

{

layer=axMap1.Layers._Item(layerName);

ds=axMap1.DataSets._Item("ds"+layerName);

fields=ds.Fields;

}

catch

{

if (layer==null) return;

}

try

{

MapXLib.Feature ftr =layer.GetFeatureByKey (featureKey);

featureInfo.featureKey =ftr.FeatureKey ;

featureInfo.point_x =ftr.CenterX ;

featureInfo.point_y =ftr.CenterY ;

layer.KeyField=fields._Item(1).Name;

featureInfo.source =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(2).Name;

featureInfo.name =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(3).Name;

featureInfo.identity =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(4).Name;

featureInfo.description =ftr.KeyValue.ToString();

layer.KeyField=fields._Item(5).Name;

featureInfo.foundTime =ftr.KeyValue.ToString();

rvs=ds.get_RowValues(ftr);

rv=rvs._Item("MI_RENDITION");

string symbol=rv.Value.ToString();

int startindex=symbol.IndexOf("\"")+1;

int lastindex=symbol.LastIndexOf("\"");

int len=lastindex - startindex;

string bitmapfile=symbol.Substring(startindex,len);

featureInfo.symbolFileName =bitmapfile;

}

catch{}

}

public void DeleteUserSymbol(string layerName,string selectedFeatureKey)

//刪除viewlayer層圖元,layerName爲viewLayer圖層的name

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

MapXLib.Feature selectedFeature=layer.GetFeatureByKey(selectedFeatureKey);

if (selectedFeature==null) return;

MapXLib.Dataset ds=axMap1.DataSets._Item("ds"+layerName);

MapXLib.RowValues rowValues=ds.get_RowValues(selectedFeature);

MapXLib.RowValue rowValue=rowValues._Item("MI_PRINX");

string prinx=rowValue.Value.ToString();

string str="delete from system."+layerName.Substring(0,layerName.Length-6);

str+=" where MI_PRINX="+prinx;

OracleConnection myConn = new OracleConnection(connectString);

OracleCommand myOracleCommand = new OracleCommand(str);

myOracleCommand.Connection = myConn;

myConn.Open();

myOracleCommand.ExecuteNonQuery();

myConn.Close();

}

public void DeleteDBLayerSelectedFeature()

//刪除數據庫關聯的全部選中的圖元

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(userLayerName+"FromDB");

}

catch

{

return;

}

try

{

foreach(MapXLib.Feature selectedFeature in layer.Selection )

{

DeleteUserSymbol(userLayerName+"FromDB",selectedFeature .FeatureKey );

}

}

catch{}

}

public void DeleteDBLayerAllFeature()

//刪除數據庫關聯的全部圖元

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(userLayerName+"FromDB");

}

catch

{

return;

}

foreach(MapXLib.Feature selectedFeature in layer.AllFeatures)

{

DeleteUserSymbol(userLayerName+"FromDB",selectedFeature .FeatureKey );

}

OracleToLayer (userLayerName);

}

public void AddSymbolTool(string layerName,string bitmapFileName,string Identity)

//用mouse增長圖元至工做圖層上

{

axMap1.AutoRedraw =false;

MapXLib.Layer layer=null;

currentFeatureInfo.identity =Identity;

currentFeatureInfo.symbolFileName =bitmapFileName;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

if (layer==null) return;

}

MapXLib.Style style=new MapXLib.StyleClass();

style.SymbolType =MapXLib.SymbolTypeConstants.miSymbolTypeBitmap;

style.SymbolBitmapSize=20;

style.SymbolBitmapName=bitmapFileName;

style.SymbolBitmapTransparent=true;

layer .OverrideStyle =true;

layer .Style =style ;

layer.Editable=true;

axMap1.Layers.InsertionLayer=layer;

axMap1.CurrentTool=MapXLib.ToolConstants.miAddPointTool;

}

private void menuItemChangeGST_Click(object sender, System.EventArgs e)

{

string geoset1="";

bool flag=OpenGeoset(ref geoset1);

if(flag)

{

geoset=geoset1;

rif.mapInfoSet .GeoSet =geoset1;

changeMapDelegate();

mapSmall.GeoSet =geoset1.Substring (0,geoset1.Length -4)+"eye.gst";

mapSmall.TitleText ="";

SetEyeMap(mapSmall);

}

}

private void menuItemSaveGST_Click(object sender, System.EventArgs e)

{

SaveGeoset (Geoset );

}

private void menuItemLayerCTL_Click(object sender, System.EventArgs e)

{

LayerCtrl ();

}

private void axMap1_MouseDownEvent(object sender,

AxMapXLib.CMapXEvents_MouseDownEvent e)

{

if(e.button ==2)

{

System.Drawing .Point pt=new System.Drawing .Point ((int)e.x ,(int)e.y);

mapMenu.Show (this,pt);

}

}

private void axMap1_MouseUpEvent(object sender,AxMapXLib.CMapXEvents_MouseUpEvent e)

{

if(e.button ==1 && axMap1 .CurrentTool ==MapXLib.ToolConstants.miAddPointTool)

{

FeatureInfo featureInfo=new FeatureInfo ();

GetSymbolPropertyOnUserLayer(userLayerName ,ref featureInfo);

AddUserSymbol(ref featureInfo ,userLayerName);

OracleToLayer (userLayerName );

addSymbolDelegate();

}

}

//設置數據庫關聯層的可選狀態,其餘都不可選

public void SetDBLayerSelectable()

{

foreach(MapXLib.Layer layer1 in axMap1 .Layers )

{

layer1.Selectable =false;

}

MapXLib.Layer layer=axMap1 .Layers ._Item (userLayerName+"FromDB");

layer.Selectable =true;

}

//獲取全部選中的圖元

private void GetSelectedFeatureKey(string layerName,ref string []featureKey)

{

MapXLib.Layer layer=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

int count =layer.Selection .Count;

featureKey =new string [layer.Selection .Count ];

int i=0;

foreach(MapXLib.Feature selectedFeature in layer.Selection )

{

featureKey [i]=selectedFeature .FeatureKey ;

i++;

}

}

//設置圖元的選中狀態

private void SetSelectedFeatureKey(string layerName,string []featureKey)

{

MapXLib.Layer layer=null;

MapXLib.Feature feature=null;

try

{

layer=axMap1.Layers._Item(layerName);

}

catch

{

return;

}

for(int i=0;i<featureKey .Length ;i++)

{

feature=layer.GetFeatureByKey (featureKey[i]);

int id=feature .FeatureID;

layer.Selection.AddByID (1 );

}

}

public void SetEyeMap(AxMapXLib.AxMap mapEye)

{

try

{

m_Layer=mapSmall.Layers.CreateLayer("RectLayer",@"d:\mapSmall",1,

32,mapSmall.NumericCoordSys);

mapSmall = mapEye;

//初始時,產生鷹眼圖矩形框繪畫層

if (!File.Exists(Application.StartupPath +"\\mapSmall.tab")) m_Layer=mapSmall.Layers.CreateLayer("RectLayer",Application.StartupPath+

"\\mapSmall.tab",1,32,mapSmall.NumericCoordSys);

else

m_Layer = mapSmall.Layers.Add(Application.StartupPath+"\\mapSmall.tab",1);

m_Layer.Editable=true;

}

catch{}

}

private void axMap1_MapViewChanged(object sender, System.EventArgs e)

{

if(mapSmall==null) return;

mapSmall.AutoRedraw = false;

MapXLib.Feature tempfea=new MapXLib.FeatureClass();

MapXLib.Style tempsty=new MapXLib.StyleClass();

MapXLib.FeatureFactory feaFact;

MapXLib.Feature m_fea=new MapXLib.FeatureClass();

feaFact=mapSmall.FeatureFactory;

tempsty.RegionPattern=MapXLib.FillPatternConstants.miPatternNoFill;

tempsty.RegionBorderColor=255;

tempsty.RegionBorderWidth=2;

MapXLib.Features ftrs;

ftrs=m_Layer.AllFeatures;

MapXLib.PointsClass ps=new MapXLib.PointsClass ();

MapXLib.PointClass p=new MapXLib.PointClass ();

if(ftrs.Count==0)//矩形邊框尚未

{

float a=0 ;

float b=(float)axMap1.Width ;

float c=0 ;

float d=(float)axMap1.Height ;

double x=0,y=0;

axMap1.ConvertCoord(ref a,ref c ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

p.Set (x,y) ;

ps.Add (p,1);

axMap1.ConvertCoord(ref b,ref c ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

p.Set (x,y) ;

ps.Add (p,2);

axMap1.ConvertCoord(ref b,ref d ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

p.Set (x,y) ;

ps.Add (p,3);

axMap1.ConvertCoord(ref a,ref d ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

p.Set (x,y) ;

ps.Add (p,4);

tempfea = feaFact.CreateRegion(ps, tempsty);

m_fea=m_Layer.AddFeature(tempfea,new MapXLib.RowValuesClass());

}

else

{

m_fea=ftrs._Item(1);

m_fea.Parts._Item(1).RemoveAll();

float a=0 ;

float b=(float)axMap1.Width ;

float c=0 ;

float d=(float)axMap1.Height ;

double x=0,y=0;

axMap1.ConvertCoord(ref a,ref c ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

m_fea.Parts ._Item (1).AddXY (x,y,1);

axMap1.ConvertCoord(ref b,ref c ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

m_fea.Parts ._Item (1).AddXY (x,y,2);

axMap1.ConvertCoord(ref b,ref d ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

m_fea.Parts ._Item (1).AddXY (x,y,3);

axMap1.ConvertCoord(ref a,ref d ,ref x,ref y,MapXLib.ConversionConstants .miScreenToMap );

m_fea.Parts ._Item (1).AddXY (x,y,4);

m_fea.Update (true,new MapXLib.RowValuesClass());

}

}

}

}

第七章 分發基於.net平臺的MapX應用程序

7.1 .NET Framework 概述

.NET Framework 是一種新的計算平臺,它簡化了在高度分佈式 Internet 環境中的應用程序開發。.NET Framework 旨在實現下列目標:

提供一個一致的面向對象的編程環境,而不管對象代碼是在本地存儲和執行,仍是在本地執行但在 Internet 上分佈,或者是在遠程執行的。

提供一個將軟件部署和版本控制衝突最小化的代碼執行環境。

提供一個保證代碼(包括由未知的或不徹底受信任的第三方建立的代碼)安全執行的代碼執行環境。

提供一個可消除腳本環境或解釋環境的性能問題的代碼執行環境。使開發人員的經驗在面對類型大不相同的應用程序(如基於 Windows 的應用程序和基於 Web 的應用程序)時保持一致。按照工業標準生成全部通訊,以確保基於.NET Framework 的代碼可與任何其餘代碼集成。

.NET Framework 具備兩個主要組件:公共語言運行庫和.NET Framework 類庫。公共語言運行庫是 .NET Framework 的基礎。您能夠將運行庫看做一個在執行時管理代碼的代理,它提供核心服務(如內存管理、線程管理和遠程處理),並且還強制實施嚴格的類型安全以及可確保安全性和可靠性的其餘形式的代碼準確性。事實上,代碼管理的概念是運行庫的基本原則。以運行庫爲目標的代碼稱爲託管代碼,而不以運行庫爲目標的代碼稱爲非託管代碼。.NET Framework 的另外一個主要組件是類庫,它是一個綜合性的面向對象的可重用類型集合,您可使用它開發多種應用程序,這些應用程序包括傳統的命令行或圖形用戶界面 (GUI) 應用程序,也包括基於 ASP.NET 所提供的最新創新的應用程序(如 Web 窗體和 XML Web services)。

.NET Framework 可由非託管組件承載,這些組件將公共語言運行庫加載到它們的進程中並啓動託管代碼的執行,從而建立一個能夠同時利用託管和非託管功能的軟件環境。.NET Framework 不但提供若干個運行庫宿主,並且還支持第三方運行庫宿主的開發。

下面的插圖顯示公共語言運行庫和類庫與應用程序之間以及與整個系統之間的關係。該插圖還顯示託管代碼如何在更大的結構內運行。

clip_image017

clip_image018

7.2 .NET Framework 的主要組件和功能

7.2.1公共語言運行庫

公共語言運行庫管理內存、線程執行、代碼執行、代碼安全驗證、編譯以及其餘系統服務。這些功能是在公共語言運行庫上運行的託管代碼所固有的。至於安全性,取決於包括託管組件的來源(如 Internet、企業網絡或本地計算機)在內的一些因素,託管組件被賦予不一樣程度的信任。這意味着即便用在同一活動應用程序中,託管組件既可能可以執行文件訪問操做、註冊表訪問操做或其餘須當心使用的功能,也可能不可以執行這些功能。

運行庫強制實施代碼訪問安全。例如,用戶能夠相信嵌入在 Web 頁中的可執行文件可以在屏幕上播放動畫或唱歌,但不能訪問他們的我的數據、文件系統或網絡。這樣,運行庫的安全性功能就使經過 Internet 部署的合法軟件可以具備特別豐富的功能。

運行庫還經過實現稱爲通用類型系統 (CTS) 的嚴格類型驗證和代碼驗證基礎結構來增強代碼可靠性。CTS 確保全部託管代碼都是能夠自我描述的。各類 Microsoft 和第三方語言編譯器生成符合 CTS 的託管代碼。這意味着託管代碼可在嚴格實施類型保真和類型安全的同時使用其餘託管類型和實例。

此外,運行庫的託管環境還消除了許多常見的軟件問題。例如,運行庫自動處理對象佈局並管理對對象的引用,在再也不使用它們時將它們釋放。這種自動內存管理解決了兩個最多見的應用程序錯誤:內存泄漏和無效內存引用。

運行庫還提升了開發人員的工做效率。例如,程序員能夠用他們選擇的開發語言編寫應用程序,卻仍能充分利用其餘開發人員用其餘語言編寫的運行庫、類庫和組件。任何選擇以運行庫爲目標的編譯器供應商均可以這樣作。以 .NET Framework 爲目標的語言編譯器使得用該語言編寫的現有代碼可使用 .NET Framework 的功能,這大大減輕了現有應用程序的遷移過程的工做負擔。

儘管運行庫是爲將來的軟件設計的,可是它也支持如今和之前的軟件。託管和非託管代碼之間的互操做性使開發人員可以繼續使用所需的 COM 組件和 DLL。

運行庫旨在加強性能。儘管公共語言運行庫提供許多標準運行庫服務,可是它從不解釋託管代碼。一種稱爲實時 (JIT) 編譯的功能使全部託管代碼可以以它在其上執行的系統的本機語言運行。同時,內存管理器排除了出現零碎內存的可能性,並增大了內存引用區域以進一步提升性能。

最後,運行庫可由高性能的服務器端應用程序(如 Microsoft® SQL Server™ 和 Internet 信息服務 (IIS))承載。此基礎結構使您在享受支持運行庫宿主的行業最佳企業服務器的優越性能的同時,可以使用託管代碼編寫業務邏輯。

7.2.2 .NET Framework 類庫

.NET Framework 類庫是一個與公共語言運行庫緊密集成的可重用的類型集合。該類庫是面向對象的,並提供您本身的託管代碼可從中導出功能的類型。這不但使 .NET Framework 類型易於使用,並且還減小了學習 .NET Framework 的新功能所須要的時間。此外,第三方組件可與 .NET Framework 中的類無縫集成。例如,.NET Framework 集合類實現一組可用於開發您本身的集合類的接口。您的集合類將與 .NET Framework 中的類無縫地混合。

正如您對面向對象的類庫所但願的那樣,.NET Framework 類型使您可以完成一系列常見編程任務(包括諸如字符串管理、數據收集、數據庫鏈接以及文件訪問等任務)。除這些常見任務以外,類庫還包括支持多種專用開發方案的類型。例如,可以使用 .NET Framework 開發下列類型的應用程序和服務:

控制檯應用程序

.Windows GUI 應用程序(Windows 窗體)

.ASP.NET 應用程序

.XML Web services

.Windows 服務

例如,Windows 窗體類是一組綜合性的可重用的類型,它們大大簡化了 Windows GUI 的開發。若是要編寫 ASP.NET Web 窗體應用程序,可以使用 Web 窗體類。

7.3 安裝 .NET Framework

爲 .NET Framework 編寫的應用程序和控件要求 .NET Framework 安裝在運行它們的計算機上。Microsoft 提供了可再發行的安裝程序 (Dotnetfx.exe),其中包含運行 .NET Framework 應用程序所必需的公共語言運行庫和 .NET Framework 組件。能夠從Microsoft MSDN下載中心或Microsoft windows update web 站點下載 Dotnetfx.exe 的最新版本。若是您之前安裝了 .NET Framework SDK 或 Microsoft Visual Studio .NET,則不須要安裝 Dotnetfx.exe。

尤爲要注意的是,您沒法在運行 Microsoft Windows 95 操做系統的計算機上安裝 .NET Framework。若是達不到最低配置要求,Dotnetfx.exe 安裝程序將中止安裝可再發行組件包。

7.4 Map客戶安裝

要使MapX應用程序可以在客戶機器上運行,必須安裝MapX支撐文件,一般有如下兩種方法在客戶端安裝:

(1) 安裝程序自動安裝的文件

運行MapX控件安裝程序將在默認的 MapX 安裝目錄中安裝如下內容:

C:\Program Files\MapInfo\MapX 5.0

• MapX 控件 mapx50.dll

• 它的支持的 dll

• 光柵和網格 dll 以及處理程序

• 默認的數據集驅動程序

這是最簡單的分發方法, MapX 開發人員只需進行很是少的工做,由於某些過程和任務已自動化。

(2) 在用戶端註冊必須的文件

將MapX DLL 及其相關 DLL數據集驅動程序(用於數據綁定)及其它全部支撐文件拷貝到用戶機器上而後運行 regsvr32.exe 實用程序進行註冊。

7.5 製做安裝程序

建立windows 安裝項目,創建安裝程序,請參照MSDN中windows應用程序安裝部署一節。

相關文章
相關標籤/搜索