一、 前言
我用MapInfo公司的MapX開(kāi)發(fā)過(guò)幾個(gè)項目。在項目的開(kāi)發(fā)過(guò)程中,也接觸了一些使用相同技術(shù)的公司和開(kāi)發(fā)人員,感覺(jué)到他們的開(kāi)發(fā)過(guò)程常常被一些問(wèn)題所困擾,卻得不到很好的解決。在這里,我把我在開(kāi)發(fā)過(guò)程中積累的一些經(jīng)驗寫(xiě)出來(lái),希望能起到拋磚引玉的作用。
二、開(kāi)發(fā)經(jīng)驗
1、如何在MapX下讀取屬性值,這里介紹三種方法:
1)由Layer對象的KeyField屬性來(lái)設立要讀取屬性值的字段名。接著(zhù),由Feature對象的keyValue讀取此行的屬性值。
2)將圖層加入到Datasets,由Dataset對象的Value(x,y)屬性,通過(guò)設置行號,列號來(lái)獲得屬性值。
3)將圖層加入到Datasets之后由RowValues(ftr)獲取整行的值。
Dim ds As MapXLib.Dataset, lyr As MapXLib.layer
Dim ftrs As Features
Dim ftr As Feature
Dim rv As RowValue
Dim rvs As RowValues
Dim DsName As String '數據集名
Dim DsRows As Long, DsCols As Long
Dim i As Long, j As Long
Set ds = Formmain.Map1.Datasets.Item(DsName)
Set lyr = ds.layer
Set ftrs = lyr.AllFeatures
DsCols = ds.Fields.Count
DsCols = DsCols + 1
DsRows = ftrs.Count
Grid1.Rows = DsRows + 1
Grid1.Cols = DsCols
Grid1.Row = 0
For i = 0 To DsCols - 1
Grid1.Col = i
Grid1.Text = ds.Fields.Item(i + 1).Name
Next i
Grid1.Col = DsCols - 1
Grid1.Text = "Fkey"
lyr.BeginAccess miAccessRead
i = 1
For Each ftr In ftrs
Set rvs = ds.RowValues(ftr)
j = 0
For Each rv In rvs
If Not IsNull(rv.Value) Then Grid1.TextArray(i * DsCols + j) = Trim(rv.Value)
j = j + 1
Next
Grid1.TextArray(i * DsCols + j) = ftr.FeatureKey
i = i + 1
Next
lyr.EndAccess miAccessEnd
Set ftr = Nothing
Set ftrs = Nothing
Set ds = Nothing
Set rv = Nothing
Set rvs = Nothing
Set lyr = Nothing
注意:BeginAccess,以及EndAccess可以明顯的提高屬性讀取的速度。
2、自定義范圍專(zhuān)題圖
MapX的專(zhuān)題圖用戶(hù)可以進(jìn)行完全的定制,下面是自定義范圍專(zhuān)題圖的例子。
Dim ds As New MapXLib.Dataset
Dim thm As New MapXLib.Theme
Set ds = Formmain.Map1.Datasets(ToolBars.Combo2.Text)
Set thm = ds.Themes.add(0, "aa", "aa", False)
thm.Legend.Compact = False
thm.AutoRecompute = False
'thm.ComputeTheme = False
thm.DataMax = 700
thm.DataMin = 100
thm.ThemeProperties.AllowEmptyRanges = True
thm.ThemeProperties.NumRanges = 7
thm.ThemeProperties.DistMethod = miCustomRanges
thm.ThemeProperties.RangeCategories(1).Max = 150
thm.ThemeProperties.RangeCategories(1).Min = 50
thm.ThemeProperties.RangeCategories(2).Max = 250
thm.ThemeProperties.RangeCategories(2).Min = 150
thm.ThemeProperties.RangeCategories(3).Max = 350
thm.ThemeProperties.RangeCategories(3).Min = 250
thm.ThemeProperties.RangeCategories(4).Max = 450
thm.ThemeProperties.RangeCategories(4).Min = 350
thm.ThemeProperties.RangeCategories(5).Max = 550
thm.ThemeProperties.RangeCategories(5).Min = 450
thm.ThemeProperties.RangeCategories(6).Max = 650
thm.ThemeProperties.RangeCategories(6).Min = 550
thm.ThemeProperties.RangeCategories(7).Max = 750
thm.ThemeProperties.RangeCategories(7).Min = 650
'thm.ComputeTheme = True
thm.AutoRecompute = True
thm.Visible = True
3、在Mapx中查找對象有兩種方式
1)使用Find對象的Search方法。在MapX3.5中只能作到完全匹配查找,在MapX4.0中SearchEx方法則可以找到多個(gè)匹配的記錄,其結果由 FindResult.Matches獲取。詳細請參看有關(guān)Find.SearchEx 方法的文檔以及示例。
2)使用Layer 對象的OBJECT.Search (strWhere)方法。其參數為SQL查詢(xún)的WHERE子句。例如:
Set ftrs = lyr.Search("Character_Name = ""北京市""") ;
Set ftrs = lyrUSA.Search("TOTPOP > 1000000")
注意:
1)字符串外加兩個(gè)雙引號;
2)首先將圖層加入數據集Datasets 才能使用查詢(xún)。
模糊查詢(xún)最方便的方法是使用第二種方法,例如:
Set ftrs = lyr.Search("Character_Name like ""%市""")
4、在MapX中如何緊縮表
在Mapx4.51下可以使用LayerInfo 的創(chuàng )建帶結構的臨時(shí)表和新表的功能來(lái)完成緊縮:
Set lyr = Formmain.Map1.Layers(ToolBars.combo1.Text)
Set ds = Formmain.Map1.Datasets.add(6, lyr)
'獲取被緊縮表的路徑及表名
filespec = Formmain.Map1.Layers.Item(ToolBars.combo1.Text).filespec
layername = lyr.Name '將表臨時(shí)存放于內存
LayerInfo.Type = 6 'miLayerInfoTypeTemp
LayerInfo.AddParameter "TableStorageType", "MemTable" '臨時(shí)文件保存在磁盤(pán)上還是內存。
LayerInfo.AddParameter "Name", "lyrpack"
LayerInfo.AddParameter "Fields", ds.Fields
LayerInfo.AddParameter "Features", lyr.AllFeatures
Formmain.Map1.Layers.add LayerInfo, LayerPos
Set LayerInfo = Nothing
'從地圖窗口刪除原表
Formmain.Map1.Datasets.Remove (ds.Name)
Formmain.Map1.Layers.Remove (lyr.Name)
Formmain.Map1.Refresh
Set lyr = Nothing
Set ds = Nothing
Set lyr = Formmain.Map1.Layers("lyrpack")
Set ds = Formmain.Map1.Datasets.add(6, lyr)
'從磁盤(pán)刪除原表
Kill filespec
5、在MapX中如何使用自定義柵格符號
使用自定義符號首先需要設定style.SymbolType 為miSymbolTypeBitmap,然后指定SymbolBitmapName 為柵格圖像名即可。
下面的代碼演示了如何在delphi中使用自定義的柵格符號
首先調用自定義工具畫(huà)點(diǎn)
Procedure TForm1.new1Click(Sender: TObject);
Begin
map1.ControlInterface.CurrentTool :=111;
End;
在tooluses事件中如下:
procedure TForm1.Map1ToolUsed(Sender: TObject; ToolNum: Smallint; X1, Y1,X2, Y2, Distance: Double; Shift, Ctrl: WordBool;
var EnableDefault: WordBool);
var
ssymbol :cmapxstyle;
p: CMapXPoint;
f: cmapxfeature;
begin
ssymbol:=costyle.create;
ssymbol.SymbolType :=1;
ssymbol.SymbolBitmapSize:=25;
{請注意將test.bmp文件考到mapx “共有文件路徑”+“\CUSTSYMB”路徑下,例如C:\Program Files\Common Files\MapInfo Shared\MapX Common 是 MapX 共有文件的缺省安裝路徑}
ssymbol.SymbolBitmapName:='test.BMP';
p := CoPoint.Create;
f :=cofeature.Create ;
p.Set_(x1,y1);
if toolnum=111 then begin
f:=map1.ControlInterface.FeatureFactory.CreateSymbol(p,ssymbol);
map1.ControlInterface.Layers.Item(1).AddFeature(f,EmptyParam);
end;
end;
6、在MapX中如何使用自定義鼠標
在MapX4.0,及以上版本中允許用戶(hù)自定義鼠標。程序如下:
Map1.MousePointer = miCustomCursor
Map1.MouseIcon = "c:\windows\cursors\globe.ani"
MapX中還對鼠標滾動(dòng)輪提供支持,屬性如下:
Map.MouseWheelSupport=miMousewheelNoAutoScroll