tmap的使用_MapInfo教程--二次开发入门
摘要:MapBasic是Mapinfo自帶的二次開發(fā)語言,它是一種類似Basic的解釋性語言,利用MapBasic編程生成的*.mbx文件能在Mapinfo軟件平臺上運(yùn)行,早期的Mapinfo二次開發(fā)都是基于MapBasic進(jìn)行的。MapBasic學(xué)起來容易,用起來卻束縛多多,無法實現(xiàn)較復(fù)雜的自定義功能,用它來建立用戶界面也很麻煩,從現(xiàn)在角度看,MapBasic比較適合用于擴(kuò)展Mapinfo功能。
一、利用MapBasic開發(fā)
MapBasic是Mapinfo自帶的二次開發(fā)語言,它是一種類似Basic的解釋性語言,利用MapBasic編程生成的*.mbx文件能在Mapinfo軟件平臺上運(yùn)行,早期的Mapinfo二次開發(fā)都是基于MapBasic進(jìn)行的。MapBasic學(xué)起來容易,用起來卻束縛多多,無法實現(xiàn)較復(fù)雜的自定義功能,用它來建立用戶界面也很麻煩,從現(xiàn)在角度看,MapBasic比較適合用于擴(kuò)展Mapinfo功能。
二、利用OLE自動化開發(fā)
1. 建立Mapinfo自動化對象
基于OLE自動化的開發(fā)就是編程人員通過標(biāo)準(zhǔn)化編程工具如VC、VB、Delphi、PB等建立自動化控制器,然后通過傳送類似MapBasic語言的宏命令對Mapinfo進(jìn)行操作。實際上是將Mapinfo用作進(jìn)程外服務(wù)器,它在后臺輸出OLE自動化對象,供控制器調(diào)用它的屬性和方法。
OLE自動化開發(fā)的首要一步就是建立Mapinfo自動化對象,以Delphi為例(后面都是如此),你可設(shè)定一個Variant類型的全程變量代表OLE自動化對象,假設(shè)該變量名為olemapinfo,那么有:
oleMapinfo := CreateOleObject('Mapinfo.Application')
一旦OLE自動化對象建立,也就是后臺Mapinfo成功啟動,你就可以使用該對象的Do方法向Mapinfo發(fā)送命令,如:
oleMapinfo.Do('Set Next Document Parent' + WinHand + 'Style 1')
這一命令使Mapinfo窗口成為應(yīng)用程序的子窗口,WinHand是地圖窗口句柄,style 1 是沒有邊框的窗口類型。你還可以使用自動化對象的Eval方法返回MapBasic表達(dá)式的值,如下面語句返回當(dāng)前所打開的表數(shù):
TablesNum:=olemapinfo.eval('NumTables()')
你也可以直接調(diào)用Mapinfo菜單或按鈕命令對地圖窗口進(jìn)行操作,如地圖放大顯示:
oleMapinfo.RunMenuCommand(1705)
2. 建立客戶自動化對象觸發(fā)CallBack
基于OLE自動化開發(fā)的難點在于所謂的CallBack,Mapinfo服務(wù)器對客戶程序地圖窗口的反應(yīng)叫CallBack,假如你在地圖窗口中移動地圖目標(biāo),Mapinfo能返回信息告訴你地圖目標(biāo)當(dāng)前的坐標(biāo)位置,這就是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;
//定義界面實現(xiàn)
TMyCallback = class(TAutoObject, IMyCallback)
function SetStatusText(var StatusText: WideString): SCODE; safecall;
function WindowContentsChanged(var WindowID: Integer): SCODE;safecall;
其中WindowContentsChanged函數(shù)用于返回變化窗口的ID號,即當(dāng)?shù)貓D窗口變化時(如放大、縮小),讓Mapinfo將地圖窗口的ID號返回給客戶程序; 另一個SetStatusText函數(shù)返回Mapinfo狀態(tài)條變化信息。編程人員不能隨意定義這些函數(shù),因為只有在三種情況下Mapinfo服務(wù)器的CallBack才會被觸發(fā):(1)地圖窗口發(fā)生變化,觸發(fā)函數(shù)為WindowContentsChanged;(2)Mapinfo狀態(tài)條信息改變,觸發(fā)函數(shù)為SetStatusText;(3)用戶選擇自定義工具或菜單命令在地圖窗口上操作,如用戶定制的畫線工具,當(dāng)用戶在地圖窗口畫線時觸發(fā)Mapinfo的CallBack返回線的坐標(biāo)位置。
建立客戶自動化對象后,調(diào)用MapInfo自動化對象的SetCallback方法將客戶自己定義的自動化對象告訴Mapinfo,只要程序一運(yùn)行,客戶自動化對象就會自動在注冊表中注冊,然后就能收到CallBack信息了,如:
My:=MyCallBack.Create
oleMapInfo.SetCallBack(My)
這里打一個比方我想會有助于理解上述機(jī)制,客戶程序與Mapinfo之間的交互就像舞臺指揮與木偶演員的交流,客戶程序中的地圖窗口或說Mapinfo子窗口只不過是一個牽線木偶,后臺的Mapinfo才是真正操縱木偶的演員,所以客戶程序必須與后臺Mapinfo建立正向、反向的聯(lián)系機(jī)制,才能操縱地圖窗口中的圖形目標(biāo)。
三、利用MapX開發(fā)
1. 掌握使用MapX
MapX是Mapinfo公司最新推出的ActiveX控件產(chǎn)品,目前已經(jīng)發(fā)展到MapX4.5。由于MapX是基于Windows操作系統(tǒng)的標(biāo)準(zhǔn)控件,因而能支持VC、VB、Delphi、PB等標(biāo)準(zhǔn)化編程工具,使用時只需將控件裝入開發(fā)環(huán)境,裝入控件后,開發(fā)環(huán)境ActiveX工具條上會增加一個控件按鈕Map,把它拖放到窗體上就可建立一個TMap類型的ActiveX地圖對象Map,通過設(shè)置或訪問該Map對象的屬性、調(diào)用該Map對象的方法及事件,便能快捷地將地圖操作功能溶入到你的應(yīng)用程序中。
MapX由一系列Object(對象)和Collection(對象集合)組成,Map是最基本的對象,每個Map由Layer(層)、Dataset(數(shù)據(jù)集)和Annotation(標(biāo)注)這三個對象及對象集合(Layers、Datasets、Annotations)來定義, 其中Layer用于操作地圖圖層,Dataset用于訪問空間對象的屬性數(shù)據(jù),Annotation用于在地圖上添加文本、符號等標(biāo)注,掌握上述三個主要對象的特征后,再順藤摸瓜掌握下一級對象的特征,如每個Layer又由Feature(點、線、面、文本圖形目標(biāo))對象及對象集合(Features)定義,每個Dataset由Field(屬性數(shù)據(jù)域)對象及對象集合(Fields)定義......,這樣很快就能把MapX學(xué)到手。
2. 定義地圖坐標(biāo)系
在MapX開發(fā)中需要特別注意地圖坐標(biāo)系問題,MapX地圖坐標(biāo)系分為地圖顯示坐標(biāo)系和內(nèi)部計算坐標(biāo)系,兩者互為獨立,在GIS應(yīng)用開發(fā)中根據(jù)應(yīng)用需要設(shè)置好這兩種坐標(biāo)系非常重要,因為坐標(biāo)系一方面影響軟件系統(tǒng)的內(nèi)部坐標(biāo)處理,另一方面影響地圖的外觀顯示。Map對象的坐標(biāo)系及投影通過CoordSys對象的Set方法定義:
Set(Type, [Datum], [Units], [OriginLongitude], [OriginLatitude],
[StandardParallelOne], [StandardParallelTwo], [Azimuth], [ScaleFactor],
[FalseEasting], [FalseNorthing], [Range], [Bounds], [AffineTransform])
其中主要參數(shù):Type表示投影類型,Type為1時地圖坐標(biāo)以經(jīng)緯度表示,后面都為可選參數(shù),其中Datum為地球基準(zhǔn)面;Units為坐標(biāo)單位,如Units為7表示以米為單位;OriginLongitude、OriginLatitude分別為起始經(jīng)度和緯度;StandardParallelOne、StandardParallelTwo為第一、第二標(biāo)準(zhǔn)緯線,該參數(shù)與地圖投影相關(guān)。
通過設(shè)置Map對象的DisplayCoordSys和NumericCoordSys屬性返回的CoordSys對象,就可設(shè)定地圖顯示坐標(biāo)系和內(nèi)部計算坐標(biāo)系。舉例如下:
procedure TMain.DefineMapParam();
var
MapDatum: Variant;//地球基準(zhǔn)面
begin
try
MapDatum := CreateOleObject('MapX.Datum.4'); //建立基準(zhǔn)面對象
//定義北京54坐標(biāo)系基準(zhǔn)面
// (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坐標(biāo)系經(jīng)緯度作為內(nèi)部計算坐標(biāo)系
Map1.NumericCoordSys.Set_(1, MapDatum);
//定義北京54坐標(biāo)系30度標(biāo)準(zhǔn)緯線麥卡托投影作為顯示坐標(biāo)系,單位為米
Map1.DisplayCoordSys.Set_(26,MapDatum,7,0,0,30);
finally
VarClear(MapDatum);
end;
坐標(biāo)系是GIS系統(tǒng)的基石,正確設(shè)置坐標(biāo)系是系統(tǒng)成敗的關(guān)鍵。
3. 操縱地圖對象
你可以簡單地加載一個GeoSet文件,給Layers對象集合賦予具體的內(nèi)容,隨之在Map對象中就能看到地圖顯示,GeoSet文件類似MapInfo中的工作空間,MapX中帶有Geoset文件的編輯器GeosetMangater.exe,用戶可在編輯器中組合及設(shè)置圖層,然后保存生成一個 *.gst 文件直接調(diào)入Map對象,這樣可以節(jié)省時間。你也可以通過Layers對象的Add 或 Remove 方法添加或移走地圖圖層,如:
Map.layers.Add(FileName); // 添加圖層,FileName為文件全路徑名
Map.Layers.Remove(3); // 移走地圖第三層
Layers對象由一組Layer對象組成,通過Layer對象的Features和Selection對象集合你可以操縱和選擇圖層上的圖形目標(biāo),如:
Map.Layers.Item(1).AddFeature(Newobj); //將新建對象Newobj添加到圖層一
4. 地圖數(shù)據(jù)捆綁
數(shù)據(jù)捆綁是將不同來源的數(shù)據(jù)對應(yīng)到地圖層的過程,捆綁結(jié)果會產(chǎn)生一個Dataset對象,Dataset對象的集合組成Datasets Collection,它定義了Map對象的數(shù)據(jù)集屬性。 你可以通過Datasets將不同來源的數(shù)據(jù)捆綁到地圖上實現(xiàn)圖文互動,或創(chuàng)建專題圖,如下例ODBC Access數(shù)據(jù)的捆綁及專題分析:
procedure TMapForm.ODBC1Click(Sender: TObject);
var
param: ODBCQueryInfo ;
ds: Dataset; //定義數(shù)據(jù)集
Datafields: Fields; //定義數(shù)據(jù)域
begin
param.SqlQuery := 'select * from China'; //選擇Access數(shù)據(jù)庫中的China表
param.DataSource := 'MapChina'; //ODBC 數(shù)據(jù)源名
param.ConnectString := 'ODBC;'; //或是user = ... Pwd = ... , 定義ODBC連接
Datafields.Add('GEONAME','GEONAME', miAggregationAuto,miTypeString); //添加數(shù)據(jù)域GEONAME
Datafields.Add('POPU','POPU', miAggregationAuto,miTypeNumeric); //添加數(shù)據(jù)域POPU
//將Access數(shù)據(jù)捆綁到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為光標(biāo)形狀,其他參數(shù)可選。
//定義Info工具為十字光標(biāo)點觸發(fā)工具
Map.CreateCustomTool(CUSTOM_INFO_TOOL, miToolTypePoint, miCrossCursor, miArrowCursor, miArrowCursor, unassigned)
(3)在Map對象事件ToolUsed中編寫工具的Handler(操作內(nèi)容)
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
四、小結(jié)
基于MapBasic的開發(fā)簡單但受限制較多,比較適合Mapinfo功能擴(kuò)展編程。而基于OLE自動化的開發(fā)比較繁瑣,因為需要來回向后臺的Mapinfo發(fā)送MapBasic字符串命令,所建立的應(yīng)用程序運(yùn)行速度也相對較慢,但這種開發(fā)方法能隨心所欲制作出美觀友好的界面,將地理操作與非地理操作溶為一體,并且能實現(xiàn)幾乎100%的Mapinfo功能,這是目前的MapX4.5也不能比擬的。與傳統(tǒng)GIS專業(yè)性開發(fā)環(huán)境相比,像MapX這類組件式GIS系統(tǒng)的出現(xiàn)可說是一種質(zhì)的飛躍,它小巧靈活,開發(fā)簡捷,價格便宜,以后會越來越大眾化。 用MapX開發(fā)的GIS系統(tǒng)運(yùn)行速度快,因為它不需要在Mapinfo軟件平臺上運(yùn)行。但從目前MapX4.5看,MapX并沒能實現(xiàn)所有的Mapinfo功能(據(jù)稱95%以上),使用過程中發(fā)現(xiàn)其生成或編輯地圖能力及地理分析能力不足,而且里面Bug也不少,當(dāng)然隨著今后新版的推出,MapX會越來越穩(wěn)定、完美。
總結(jié)
以上是生活随笔為你收集整理的tmap的使用_MapInfo教程--二次开发入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cdr文件怎么写入u盘 &quo
- 下一篇: python基础题面试_python常见