摘 要:本文從實踐出發,根據城市部件數據生產流程中出現的問題,使用MapBasic語言進行二次開發,擴展MapInfo系統的部分功能,極大的提高了城市部件數據生產的效率。
關鍵詞:MapBasic 城市部件數據生產 Mapinfo 二次開發
中圖分類號:TP3 文獻標識碼:A 文章編號:1672-3791(2013)07(b)-0038-02
MapInfo自身提供的二次開發環境MapBasic是Maplnfo平臺上開發用戶定制程序的理想編程語言。它類似Basic語言,語法規則和函數與通用Basic語言極其相似,有一定Basic基礎的人員能很快學會使用。利用MapBasic編程生成的*.mbx文件能在MapInfo軟件平臺上運行,MapBasic比較適合用于擴展MapInfo功能。
本文從實踐出發,根據城市部件數據生產流程中出現的問題,使用MapBasic語言進行二次開發,擴展MapInfo系統的部分功能。
1 實例介紹
1.1 城市部件點符號工具的制作
在使用MapInfo進行數據生產時,由于MapInfo自身的局限性,生產作業人員在作業時,每使用一類點符號,必須在MapInfo的菜單中提前進行設置,對于點符號種類多,需要經常進行點符號切換的數據生產,生產效率很低。此程序的作用在于將符號庫里的符號在工具條中體現,使作業人員所見即所得(如圖1),直接點擊工具條上的按鈕就可以在各符號間進行靈活切換,極大的提高了生產效率和準確率。
此程序的關鍵點在于,將符號庫TrueType字體文件中的符號轉化成工具條上的圖標。使用CorelDraw打開符號庫TrueType字體文件,將需要的符號分別保存為18*16、26*24,兩個不同大小的位圖文件(*.bmp),創建一個DLL動態鏈接庫,或使用一個已有的DLL動態鏈接庫,在Visual Studio平臺中打開該動態鏈接庫,將準備好的18*16、26*24的位圖文件成對導入到DLL中,至此,一個MapBasic的圖標庫完整建立了。實現代碼如下:
Include "icons.def"
include "mapbasic.def"
Declare Sub Main
Declare Sub draw_via_button
Sub Main
Create ButtonPad "工具條" As
ToolButton
Calling draw_via_button
ID 149
Icon 149 File "ICO32.DLL" ‘創建圖標文件
HelpMsg "\n公交站亭"
ToolButton
Calling draw_via_button
ID 151
Icon 151 File "ICO32.DLL"
HelpMsg "\n交通標志牌"
.…..
Width 2
show
End Sub
Sub draw_via_button
dim sym_maker As Symbol
dim ObjPt As object
dim x1 As Float
dim y1 As Float
dim FtWin as integer
dim MapId as integer
dim MapNm as string
dim FtID as integer
dim Tlid as integer
FtWin=FrontWindow()
MapId=MapperInfo(FtWin,MAPPER_INFO_EDIT_LAYER)
If MapId>0 then
MapNm=LayerInfo(FtWin,MapId,LAYER_INFO_NAME)
Else
Note "請將圖層設為可編輯!"
Exit Sub
End If
Tlid=CommandInfo(CMD_INFO_TOOLBTN)
Do Case Tlid
Case 149
FtId=74
Case 151
FtId=80
.......
End Case
x1=CommandInfo(CMD_INFO_X)
y1=CommandInfo(CMD_INFO_Y)
sym_maker=MakeFontSymbol(FtId,BLACK,12,"bujian07",0,0)
Create Point into Variable ObjPt(x1,y1) Symbol sym_maker
End sub
1.2 合并圖層
在城市部件生產過程中,數據需要分給不同的作業員進行處理,處理完的數據又需要重新合并。如果碰到數據量比較大,需要合并的圖層多時,很費時間。這時,將圖層合并進行批處理,會極大的提高工作效率。下面的代碼,說明了多層圖層的合并,怎樣進行批處理。
Sub Main
Create Menu "批處理表" As
"合并圖層" Calling batch_packtable
Alter Menu Bar Add "批處理表"
End Sub
Sub batch_packtable
'''循環控制變量
Dim i As integer
Dim TabNum As integer''一次打開的表的數量
Dim TabName As string''存取表名的變量
Dim NameList(1) As string
Dim ListNum As integer'' 初始表名數組大小
Run Menu Command M_File_Open
TabNum =NumTables()
ListNum=UBound(NameList)''得到數組的大小
ReDim NameList(TabNum)
'''循環訪問得到表的名字
For i=1 to TabNum ' TabName=TableInfo(i,TAB_INFO_NAME)
NameList(i)=TabName
Next
For i=1 to TabNum '''循環訪問得到表的名字
TabName=NameList(i)
Open Table"D:\合并圖層.tab" as 合并圖層
Insert Into 合并圖層
select * from TabName
Close table TabName
commit table 合并圖層
Close Table 合并圖層
Next
1.3 新增部件添加流水號
城市部件數據是一種不斷變化的數據,每年都有新增、刪除和變更。對新增的城市部件數據需要按照地理數據建設標準加上流水號,城市部件流水號是唯一的,新增的城市部件流水號必須在往年的基礎上增加,使用mapbasic的功能,找到往年流水號中的最大值,將新增部件的流水號在此基礎上增加,就不會出現號碼重復的情況,從而保證的標識碼的唯一性。下面用程序說明怎樣給新增部件添加流水號。
include "MENU.def"
include "mapbasic.def"
Declare Sub Main
Declare Sub separate_table
Sub Main
Create Menu "部件批處理" As
"加標識碼" Calling separate_table
Alter Menu Bar Add "部件批處理"
End Sub
Sub separate_table
Dim i,j,k As integer ''循環控制變量
Dim NameList(1) As string''記錄新增的部件代碼
Dim Col_Num As Integer ''查詢結果記錄數
Dim TableName As String ''創建表名
Dim Filespecname as String''部件存儲路徑
Dim MaxID as String ''記錄某類部件最大流水號
Open Table "D:\部件批處理\合并.tab" As 合并
Open Table "D:\部件批處理\新增.tab" As 新增
Select * From 新增 Where 標識碼=""
Group By 部件代碼 Into Selection
Col_Num=SelectionInfo(SEL_INFO_NROWS)
If Col_Num=0 Then''如果沒有找到標識碼為空的記錄
Note "標識碼為空的記錄數為0!"
Exit Sub
End If
ReDim NameList(Col_Num)
Fetch First From Selection
For i=1 to Col_Num ''循環訪問得到標識碼為空的部件代碼,一類標識碼為空的部件只存儲一次
NameList(i)=Selection.部件代碼
Fetch Next From Selection
Next
For i=1 to Col_Num
Select * From 合并 Where 部件代碼=NameList(i)
Order By 標識碼 Into 標識碼排序表
If TableInfo(標識碼排序表,TAB_INFO_NROWS)=0 then
Print "部件代碼為"+NameList(i)+"沒有最大標識碼!"
Else
Fetch Last From 標識碼排序表
MaxID=標識碼排序表.標識碼'''獲得該類中最大的標識碼號
Select * From 新增 Where 部件代碼=NameList(i) And 標識碼="" Into Selection '''找到該類中沒有標識碼的全部記錄
k=SelectionInfo(SEL_INFO_NROWS)
'Print "當前部件圖層"+NameList(i)+"最大標識碼為"+MaxID+"共有"+k+"為空的記錄!"
Dim LeftStr As String '''標識碼由兩部分組成,部件代碼+流水號
Dim RightStr As String
Dim IDStr As String
LeftStr=Left$(MaxID,10) ''獲得該類部件的部件代碼
For j=1 To k
RightStr="000000"+Str$(Val(Right$(MaxID,6))+j)
IDStr=LeftStr+right$(Rightstr,6)
Update Selection Set 標識碼=IDStr
Where RowID=j
Next
Commit Table 新增
End If
Next
End Sub
1.4 修改表結構
在北京市東城區網格化城市管理信息系統建設中,城市部件數據結構經常變換,特別是原崇文區和原東城區合并成一個行政區劃后,由于之前兩個區城市部件數據的數據結構不同,需要按照新的標準統一在一起。城市部件有96種,每種部件存放在一個表中,共96張表,每張表中有14個屬性字段需要修改。一個一個手動修改,需要大量時間并極容易出錯,使用mapbasic中的修改字段的功能,對96張表進行批處理,就可以提高工作效率和準確度。
以原東城區為例,說明mapbasic怎樣批量修改數據結構。
Include "mapbasic.def"
Declare Sub main
Sub Main
Dim MapCount as Integer
Dim i,j,n ,k as Integer
Dim MapNm as String
Dim colNum as Alias
i=FrontWindow()
If WindowInfo(FrontWindow(),Win_INFO_TYPE)<>WIN_MAPPER Then
Note "請打開地圖窗口!"
Exit Sub
End If
MapCount=MapperInfo(i,MAPPER_INFO_LAYERS)
If MapCount>0 then
Do while MapperInfo(i,MAPPER_INFO_LAYERS)>0
MapNm=LayerInfo(i,1,LAYER_INFO_NAME)
Alter Table MapNm(Rename 標識碼 ObjCode, 名稱 ObjName,主管部門代碼 DeptCode1,主管部門名稱 DeptName1,權屬部門代碼 DeptCode2,權屬部門名稱 DeptName2,維護部門代碼 DeptCode3,維護部門名稱 DeptName3,所在單元網格 BGCode,狀態 ObjState,初始時間 ORDate,變更時間 CHDate,數據來源 DataSource ,備注 Note)
Loop
End If
End Sub
2 結語
以上程序在MapBasic環境下,進行編譯和運行,打開圖層進行相應的操作可以實現各程序功能,本程序增加了MapInfo的系統功能,可提高工作效率,使用方便。
參考文獻
[1] 王曉武.MapBasic程序設計[M].北京:電子工業版社,2000.
[2] 關健.Maplnfo系統功能擴展幾例[J].城市勘測,2005(4):35-37.
[3] 王曉東,趙全磊,吳建民.MapBasic在Maplnfo功能擴展中的應用[J].測繪通報,2007(8):51-54.
[4] 劉光.地理信息系統二次開發教程.語言篇[M].北京:清華大學出版社,2003.