mapinfo是什麽軟件?能簡單介紹壹下麽?
壹、利用MapBasic開發
MapBasic是Mapinfo自帶的二次開發語言,它是壹種類似Basic的解釋性語言,利用MapBasic編程生成的*.mbx文件能在Mapinfo軟件平臺上運行,早期的Mapinfo二次開發都是基於MapBasic進行的。MapBasic學起來容易,用起來卻束縛多多,無法實現較復雜的自定義功能,用它來建立用戶界面也很麻煩,從現在角度看,MapBasic比較適合用於擴展Mapinfo功能。
二、利用OLE自動化開發
1. 建立Mapinfo自動化對象
基於OLE自動化的開發就是編程人員通過標準化編程工具如VC、VB、Delphi、PB等建立自動化控制器,然後通過傳送類似MapBasic語言的宏命令對Mapinfo進行操作。實際上是將Mapinfo用作進程外服務器,它在後臺輸出OLE自動化對象,供控制器調用它的屬性和方法。
OLE自動化開發的首要壹步就是建立Mapinfo自動化對象,以Delphi為例(後面都是如此),妳可設定壹個Variant類型的全程變量代表OLE自動化對象,假設該變量名為olemapinfo,那麽有:
oleMapinfo := CreateOleObject('Mapinfo.Application')
壹旦OLE自動化對象建立,也就是後臺Mapinfo成功啟動,妳就可以使用該對象的Do方法向Mapinfo發送命令,如:
oleMapinfo.Do('Set Next Document Parent' + WinHand + 'Style 1')
這壹命令使Mapinfo窗口成為應用程序的子窗口,WinHand是地圖窗口句柄,style 1 是沒有邊框的窗口類型。妳還可以使用自動化對象的Eval方法返回MapBasic表達式的值,如下面語句返回當前所打開的表數:
TablesNum:=olemapinfo.eval('NumTables()')
妳也可以直接調用Mapinfo菜單或按鈕命令對地圖窗口進行操作,如地圖放大顯示:
oleMapinfo.RunMenuCommand(1705)
2. 建立客戶自動化對象觸發CallBack
基於OLE自動化開發的難點在於所謂的CallBack,Mapinfo服務器對客戶程序地圖窗口的反應叫CallBack,假如妳在地圖窗口中移動地圖目標,Mapinfo能返回信息告訴妳地圖目標當前的坐標位置,這就是CallBack功能。如果妳想定制自己的地圖操作工具或菜單命令,妳必須依靠CallBack。但是想捕獲CallBack信息,妳的客戶程序必須具備接收CallBack信息的能力,為此需要在客戶程序中定義自己的OLE自動化對象,如:
//定義界面
IMyCallback = interface(IDispatch)
['{2F4E1FA1-6BC7-11D4-9632-913682D1E638}']
function WindowContentsChanged(var WindowID: Integer):SCODE;safecall;
function SetStatusText(var StatusText: WideString): SCODE; safecall;
//定義界面實現
TMyCallback = class(TAutoObject, IMyCallback)
function SetStatusText(var StatusText: WideString): SCODE; safecall;
function WindowContentsChanged(var WindowID: Integer): SCODE;safecall;
其中WindowContentsChanged函數用於返回變化窗口的ID號,即當地圖窗口變化時(如放大、縮小),讓Mapinfo將地圖窗口的ID號返回給客戶程序; 另壹個SetStatusText函數返回Mapinfo狀態條變化信息。編程人員不能隨意定義這些函數,因為只有在三種情況下Mapinfo服務器的CallBack才會被觸發:(1)地圖窗口發生變化,觸發函數為WindowContentsChanged;(2)Mapinfo狀態條信息改變,觸發函數為SetStatusText;(3)用戶選擇自定義工具或菜單命令在地圖窗口上操作,如用戶定制的畫線工具,當用戶在地圖窗口畫線時觸發Mapinfo的CallBack返回線的坐標位置。
建立客戶自動化對象後,調用MapInfo自動化對象的SetCallback方法將客戶自己定義的自動化對象告訴Mapinfo,只要程序壹運行,客戶自動化對象就會自動在註冊表中註冊,然後就能收到CallBack信息了,如:
My:=MyCallBack.Create
oleMapInfo.SetCallBack(My)
這裏打壹個比方我想會有助於理解上述機制,客戶程序與Mapinfo之間的交互就像舞臺指揮與木偶演員的交流,客戶程序中的地圖窗口或說Mapinfo子窗口只不過是壹個牽線木偶,後臺的Mapinfo才是真正操縱木偶的演員,所以客戶程序必須與後臺Mapinfo建立正向、反向的聯系機制,才能操縱地圖窗口中的圖形目標。
三、利用MapX開發
1. 掌握使用MapX
MapX是Mapinfo公司最新推出的ActiveX控件產品,目前已經發展到MapX4.5。由於MapX是基於Windows操作系統的標準控件,因而能支持VC、VB、Delphi、PB等標準化編程工具,使用時只需將控件裝入開發環境,裝入控件後,開發環境ActiveX工具條上會增加壹個控件按鈕Map,把它拖放到窗體上就可建立壹個TMap類型的ActiveX地圖對象Map,通過設置或訪問該Map對象的屬性、調用該Map對象的方法及事件,便能快捷地將地圖操作功能溶入到妳的應用程序中。
MapX由壹系列Object(對象)和Collection(對象集合)組成,Map是最基本的對象,每個Map由Layer(層)、Dataset(數據集)和Annotation(標註)這三個對象及對象集合(Layers、Datasets、Annotations)來定義, 其中Layer用於操作地圖圖層,Dataset用於訪問空間對象的屬性數據,Annotation用於在地圖上添加文本、符號等標註,掌握上述三個主要對象的特征後,再順藤摸瓜掌握下壹級對象的特征,如每個Layer又由Feature(點、線、面、文本圖形目標)對象及對象集合(Features)定義,每個Dataset由Field(屬性數據域)對象及對象集合(Fields)定義......,這樣很快就能把MapX學到手。
2. 定義地圖坐標系
在MapX開發中需要特別註意地圖坐標系問題,MapX地圖坐標系分為地圖顯示坐標系和內部計算坐標系,兩者互為獨立,在GIS應用開發中根據應用需要設置好這兩種坐標系非常重要,因為坐標系壹方面影響軟件系統的內部坐標處理,另壹方面影響地圖的外觀顯示。Map對象的坐標系及投影通過CoordSys對象的Set方法定義:
Set(Type, [Datum], [Units], [OriginLongitude], [OriginLatitude],
[StandardParallelOne], [StandardParallelTwo], [Azimuth], [ScaleFactor],
[FalseEasting], [FalseNorthing], [Range], [Bounds], [AffineTransform])
其中主要參數:Type表示投影類型,Type為1時地圖坐標以經緯度表示,後面都為可選參數,其中Datum為地球基準面;Units為坐標單位,如Units為7表示以米為單位;OriginLongitude、OriginLatitude分別為起始經度和緯度;StandardParallelOne、StandardParallelTwo為第壹、第二標準緯線,該參數與地圖投影相關。
通過設置Map對象的DisplayCoordSys和NumericCoordSys屬性返回的CoordSys對象,就可設定地圖顯示坐標系和內部計算坐標系。舉例如下:
procedure TMain.DefineMapParam();
var
MapDatum: Variant;//地球基準面
begin
try
MapDatum := CreateOleObject('MapX.Datum.4'); //建立基準面對象
//定義北京54坐標系基準面
// (Ellipsoid, ShiftX, ShiftY, ShiftZ, RotateX, RotateY, RotateZ, ScaleAdjust, PrimeMeridian)
MapDatum.set(3, 24, -123, -94, -0.02, 0.25, 0.13, 1.1, 0);
//定義北京54坐標系經緯度作為內部計算坐標系
Map1.NumericCoordSys.Set_(1, MapDatum);
//定義北京54坐標系30度標準緯線麥卡托投影作為顯示坐標系,單位為米
Map1.DisplayCoordSys.Set_(26,MapDatum,7,0,0,30);
finally
VarClear(MapDatum);
end;
坐標系是GIS系統的基石,正確設置坐標系是系統成敗的關鍵。
3. 操縱地圖對象
妳可以簡單地加載壹個GeoSet文件,給Layers對象集合賦予具體的內容,隨之在Map對象中就能看到地圖顯示,GeoSet文件類似MapInfo中的工作空間,MapX中帶有Geoset文件的編輯器GeosetMangater.exe,用戶可在編輯器中組合及設置圖層,然後保存生成壹個 *.gst 文件直接調入Map對象,這樣可以節省時間。妳也可以通過Layers對象的Add 或 Remove 方法添加或移走地圖圖層,如:
Map.layers.Add(FileName); // 添加圖層,FileName為文件全路徑名
Map.Layers.Remove(3); // 移走地圖第三層
Layers對象由壹組Layer對象組成,通過Layer對象的Features和Selection對象集合妳可以操縱和選擇圖層上的圖形目標,如:
Map.Layers.Item(1).AddFeature(Newobj); //將新建對象Newobj添加到圖層壹
4. 地圖數據捆綁
數據捆綁是將不同來源的數據對應到地圖層的過程,捆綁結果會產生壹個Dataset對象,Dataset對象的集合組成Datasets Collection,它定義了Map對象的數據集屬性。 妳可以通過Datasets將不同來源的數據捆綁到地圖上實現圖文互動,或創建專題圖,如下例ODBC Access數據的捆綁及專題分析:
procedure TMapForm.ODBC1Click(Sender: TObject);
var
param: ODBCQueryInfo ;
ds: Dataset; //定義數據集
Datafields: Fields; //定義數據域
begin
param.SqlQuery := 'select * from China'; //選擇Access數據庫中的China表
param.DataSource := 'MapChina'; //ODBC 數據源名
param.ConnectString := 'ODBC;'; //或是user = ... Pwd = ... , 定義ODBC連接
Datafields.Add('GEONAME','GEONAME', miAggregationAuto,miTypeString); //添加數據域GEONAME
Datafields.Add('POPU','POPU', miAggregationAuto,miTypeNumeric); //添加數據域POPU
//將Access數據捆綁到Mapinfo China表
ds := Map.Datasets.Add(miDataSetODBC, param, unassigned, unassigned, unassigned, 'CHINA', Datafields, unassigned);
ds.Themes.Add(miThemeRanged, 'POPU', 'MyTheme'); //添加壹個範圍專題圖
end;
5. 建立客戶定制工具
妳還可以定制自己的地圖操作工具,下面通過定制壹個名為Info的信息按鈕工具簡述方法步驟:
(1)定義客戶工具常量
Const CUSTOM_INFO_TOOL = 1
(2)利用Map對象的CreateCustomTool方法定義客戶工具,方法為:
CreateCustomTool (ToolNumber, Type, Cursor, [ShiftCursor] , [CtrlCursor], [InfoTips])
其中ToolNumber為工具號,即上面定義的常量;Type為工具類型;Cursor為光標形狀,其他參數可選。
//定義Info工具為十字光標點觸發工具
Map.CreateCustomTool(CUSTOM_INFO_TOOL, miToolTypePoint, miCrossCursor, miArrowCursor, miArrowCursor, unassigned)
(3)在Map對象事件ToolUsed中編寫工具的Handler(操作內容)
procedure TMain.MapToolUsed(Sender: TObject; ToolNum: Smallint; X1, Y1, X2, Y2, Distance: Double;
Shift, Ctrl: WordBool; var EnableDefault: WordBool);
begin
Case ToolNumber of
CUSTOM_INFO_TOOL : //信息工具Info
try
……
end;
(4)定義信息按鈕的Click事件
procedure TMain.InfoClick(Sender: TObject);
begin
Map.CurrentTool:=CUSTOM_INFO_TOOL;
end
四、小結
基於MapBasic的開發簡單但受限制較多,比較適合Mapinfo功能擴展編程。而基於OLE自動化的開發比較繁瑣,因為需要來回向後臺的Mapinfo發送MapBasic字符串命令,所建立的應用程序運行速度也相對較慢,但這種開發方法能隨心所欲制作出美觀友好的界面,將地理操作與非地理操作溶為壹體,並且能實現幾乎100%的Mapinfo功能,這是目前的MapX4.5也不能比擬的。與傳統GIS專業性開發環境相比,像MapX這類組件式GIS系統的出現可說是壹種質的飛躍,它小巧靈活,開發簡捷,價格便宜,以後會越來越大眾化。 用MapX開發的GIS系統運行速度快,因為它不需要在Mapinfo軟件平臺上運行。但從目前MapX4.5看,MapX並沒能實現所有的Mapinfo功能(據稱95%以上),使用過程中發現其生成或編輯地圖能力及地理分析能力不足,而且裏面Bug也不少,當然隨著今後新版的推出,MapX會越來越穩定、完美。