代码名称:MapX 操作总结(下)

作者/收集者:q15587

开发环境:VB + MAPX

代码:

三、查询 


1、 属性查找。Find、Search方法:注意的是Find方法只支持TAB表文件,不支持空间数据表。 
Find :与FoxPro中Locate定位命令想类似。 
Search:支持SQL语句。写法:仅指SQL语句的WHERE 部分,且From语句中只能有一个表——仅对单表进行操作:Select * from LayerName WHERE ID LIKE “%北京%” 
示例: 
A、查找 
Dim Ftrs AS MapXlib.Features ‘图元集合 

SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) 
For I=1 to Ftrs.Count 
‘执行语句 
Next 
B、高亮显示 
Lyr.Selection.Replace Ftrs ‘将当前查询所得的结果集全部高亮显示(隐含执行:Lyr.ClearSelection语句)——加入selection集合 
闪烁:不能用Selection,否则会对整个屏幕进行整个刷新(抖动)。使用更新Style的方法进行选定图元的闪烁。 
记载图元的老样式:Set Oldsytle=Ftr.Style 

Lyr.Selection.Add Ftrs ‘将当前查询所得的结果集添加到已有的结果集中,再全部高亮显示 
C、对查询的结果集进行属性修改 
示例程序:完成的是Professional中信息工具功能 
Dim ds AS MapXlib.Dataset 
Dim Flds AS MapXlib.Fields 
Dim Ftr AS MapXlib.Feature 

Set Lyr=MainMap.Layers.Item(LayerName) 
Set ds=Lyr.Datasets.item(1) 
Set Flds=ds.Fields 
‘查找 
SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) 
If Ftrs.count=0 then exit sub 

‘读取属性值 
For I=1 to Ftrs.Count 
Set Ftr=Ftrs.Item(I) 
For j=1 to Flds.count 
FldsName(J)=Flds.Item(J).Name ‘字段列表 
Lyr.KeyField=FldsName(J) 
valueStr(I,J)=Ftr.Keyvalue ‘值列表 
Next 
Next 

‘修改属性 
MainMap.AuyoRedraw=False 
Lyr.Editable=True 

For j=1 to Flds.count 
Lyr.KeyField= Flds.Item(J).Name 
Ftrs.Item(j).Keyvalue =valueStr(J) ‘更新值列表 
Ftrs.Item(j).Update True 
Next 

Lyr.Refresh 
Lyr.Editable=False 
MainMap.AuyoRedraw=True 

‘修改样式 
Dim NewStyle AS MapXlib.Style 

With NewStyle 
‘设置样式 
End With 

MainMap.AuyoRedraw=False 
Lyr.Editable=True 

For i=1 to Ftrs.count 
Set Ftr =Ftrs.Item(I) 
SET Ftr.Style=NewStyle ‘更新样式 
Ftr.Update True 
Next 

Lyr.Refresh 
Lyr.Editable=False 
MainMap.AuyoRedraw=True 

2、 空间查找 
2 点查找:SearchAtPoint,结果集为Features类型 
Dim Pnt AS MapXlib.Point 

Pnt.Set X,Y 
Set Ftrs=Lyr.SearchAtPoint(Pnt,miSearchResultAll) 
For I=1 to Ftrs.Count 
‘执行语句 
Next 
注意:点查找时,一般情况下结果集在一个以上的图层都存在。所以取值时应分别提取 

2 园查找:在临时图层上画一个不保存的圆,然后查找被这个圆所包含的所有图层的图元对象。 
Dim Pnt AS MapXlib.Point 
Dim TempCir AS MapXlib.Feature 
Dim FeaFac AS MapXLIB.featurefactory 

Pnt.Set X,Y 
Set tempcir=FeaFac.CreateCircularRegion(miCircleTypeMap ,Pnt,1, MainMap.MapUnit,,) 

‘miSearchTypeCentroidWithin :中心点包含 
‘miSearchTypePartiallyWithin :部分包含 
‘miSearchTypeEntirelyWithin :全部包含 

Set Ftrs=Lyr.SearchWithinFeature (TempCir, miSearchTypePartiallyWithin) 

For I=1 to Ftrs.Count 
‘执行语句 
Next 

SET Pnt =Nothing 
set TempCir =Nothing 
set FeaFac =Nothing 

3、 相交 
判断两个图元是否有交点以及交点坐标信息。 
(1)判断是否相交 
IF Lyr.IntersectionTest( ftr1, ftr2, miIntersectFeature ) THEN 
‘交点 
END IF 

(2)获取相交点坐标信息 
‘交点 
Dim Ftr AS MapXlib.Feature 

SET Ftr=MainMap.FeatureFactory. IntersectFeatures(Ftr1,Ftr2) 
‘交点坐标信息 
For J=1 to Ftr.parts.item(1).count 
X1= Ftr.parts.item(1).Item(J).X 
Y1= Ftr.parts.item(1).Item(J).Y 
Next 

4、 测距 
使用Map对象的Distance方法。如何测量任意多边形的周长? 
使用累加的方法,还要使用图元节点集合。 
Distancevalue=0 
‘第一个点 
Pnt.Set Ftr.Parts.Item(1).Item(1).X, Ftr.Parts.Item(1).Item(1).Y 
For j=2 TO Ftr.Parts.Item(1).Count 
‘累加 
X1= Ftr.Parts.Item(1).Item(j-1).X 
Y1= Ftr.Parts.Item(1).Item(j-1).Y 
X2= Ftr.Parts.Item(1).Item(j).X 
Y2= Ftr.Parts.Item(1).Item(j).Y 
Distancevalue = Distancevalue +MainMap.Distance(X1, Y1, X2, Y2) 
Next 
‘多边形周长 
Msgbox Distancevalue+” ”+MainMap.MapUnit 

四、对象编辑 

(1)、对属性的编辑 
主要使用Fields对象。示例: 
Dim Flds AS MapXlIB.Fields 

‘修改当前图层的每一个字段 
For J=1 to Flds.Count 
Lyr.KeyField= Flds.Item(j).Name ‘使当前图层指向J字段 
‘更新当前图元的J字段值 
Ftr.Keyvalue=NewvalueStr(J) 
Ftr.Update True ‘并未写入硬盘 
Next 
Lyr.Refresh ‘保存修改到硬盘 

(2)、移动地图 
首先创建一个移动工具句柄 
MainMap.CreateCustomTool MoveFeature, miToolTypeLine, miPanCursor 
在Map对象的ToolUsed事件的ToolNum参数为当前所激活的工具 
捕捉MoveFeature工具句柄 
‘传过来的参数:X1,Y1,X2,Y2 
Select case ToolNum 
…….. 
Case MoveFeature 
Dim Lyr AS MapXlib.Layer 
Dim Ftr AS MapXlib.Feature 
Dim Ftrs AS MapXlib.Features 

Dim Xe,Ye AS Double ‘坐标偏移量 

Xe=X2-X1 
Ye=Y2-Y1 

Set Lyr=Mainmap.Layers.Item(LayerName) 
Set Ftrs=Lyr.Selection.Clone ‘将当前图层中选定的集合复制到Ftrs变量中 
MainMap.AutoRedraw=False 
Lyr.Editable=True 
For J=1 to Ftrs.Count 
Set Ftr=Ftrs.Item(J) 
Ftr.Offset Xe,Ye 
Ftr.Update True 
Next 
Lyr.Refresh 
Lyr.Editable=False 
MainMap.AutoRedraw=True 

SET lyr=Nothing 
SET Ftr=Nothing 
End Select 
(3)、样式更新 
Dim NewStyle AS MapXLib.Style 

‘初始赋值 
Set Lyr=MainMap.Layers.Item(LayerName) 
Set Ftrs=Lyr.AllFeatures 
Set NewStyle=Ftrs.Item(1).Style 
‘设置样式 
With NewStyle 
.SymbolType = miSymbolTypeBitmap 
.SymbolBitmapSize = 24 
.SymbolBitmapTransparent = False 
.SymbolBitmapName = "YIEL2-32.BMP" 
End With 
‘更新 
MainMap.AutoRedraw=False 
Lyr.Editable=True 
SET Ftr.Style=NewStyle 
Ftr.Update True 
Lyr.Refresh 
Lyr.Editable=False 
MainMap.AutoRedraw=True 

五、输出 


1、属性的输出 输出到EXCEL表: 
For I=1 to Flds.Count 
Lyr.KeyFields=Flds.Item(i).Name 
Excel(1,I).Cell=Ftr.Keyvalue 
Next 
2、复制、粘贴 
Global CopyFtrs AS MapXlib.Features 

Set lyr=mainmap.Layers.item(LayerName) 
Set Ftrs=Lyr.Selection.Clone ‘复制选中集合 
‘复制 
For I=1 to Ftrs.Count 
CopyFtrs.add Ftrs.Item(I) 
Next 

‘粘贴(图形) 
Set lyr_1=mainmap.Layers.item(LayerName_1) 
Mainmap.AutoRedraw=False 
Lyr_1.Editabled=True 
For J=1 to CopyFtrs.Count 
Lyr_1.AddFeature CopyFtrs.Item(J) 
Next 
Lyr_1.Refresh 
Mainmap.AutoRedraw=True 
Lyr_1.Editabled=False 

3、地图的打印 
Dim iScaleMode As Integer 

iScaleMode = MainMap.Container.ScaleMode 
MainMap.Container.ScaleMode = 6 

On Error GoTo PrinterError 

Printer.Print " " 
Printer.CurrentX = 0 
Printer.CurrentY = 0 
MainMap.PrintMap Printer.hDC, 0, 0, MainMap.Width * 100, MainMap.Height * 100 
Printer.NewPage 
Printer.EndDoc 
MainMap.Container.ScaleMode = iScaleMode 
Exit Sub 

PrinterError: 
If Err.Number = 482 Then 
On Error Resume Next 
CommonDialog1.Flags = &H40 
CommonDialog1.ShowPrinter 
Else 
MsgBox " 打印机存在错误,请更正后重试。错误号:" + (Str(Err.Number)), , "失败" 
End If 


4、另存为图片文件 
MainMap.ExportMap(App.Path+”Images”, miFormatJPEG) ‘输出当前地图窗口 
参数设置:MainMap.ExportSelection=True ‘将选中部分以不同于其他未选中地图部分形式输出 

六、专题图 


6种专题图:除独立值专题图绑定的字段类型可以是字符的以外,都必须是数字类型。与其他数据源绑定时,使用ODBC 
调用ThemeDlg对话框可以让用户自己定义专题图。示例: 
For Each ftr In lyr.Selection 

′ The children of the layer are the individual 

′ features 

Set ftrNode = QueryTree.Nodes.Add(lyrNode, tvwChild,lyr.Name _ 

& ftr.Name & Str$(ftr.FeatureID), ftr.Name) 

For Each fld In ds.Fields 

′ Each feature has data attached to it; add 

′ this data as a child of the feature 

lyr.KeyField = fld.Name 

QueryTree.Nodes.Add ftrNode, tvwChild, , lyr.KeyField _ 

& ": " & ftr.Keyvalue 

Next 

Next 

七、在MapX下紧缩表 

在Professional里面,紧缩表用 Pack Table 语句完成。而在MapX中则需要使用临时图层,并用复制技术来完成。示例: 
‘紧缩当前Map对象中的所有图层 
Dim LayerInfo As New MapXLib.LayerInfo 
Dim Lyr As MapXLib.Layer 
Dim LyrTemp As MapXLib.Layer 
Dim Flds As MapXLib.Fields 
Dim Ds As MapXLib.Dataset 

Dim I As Integer 
Dim LayerName, FilePath As String 

On Error Resume Next 

For I = MainMap.Layers.Count To 1 Step -1 
′复制源表数据到临时表 
Set Lyr = MainMap.Layers.Item(I) 
Set Ds = Lyr.Datasets.Item(1) 
Set Flds = Ds.Fields 

LayerName = Lyr.Name 

LayerInfo.Type = miLayerInfoTypeTemp 
LayerInfo.AddParameter "FileSpec", LayerName 
LayerInfo.AddParameter "NAME", LayerName 
LayerInfo.AddParameter "Features", Lyr.AllFeatures‘复制所有有效图元 
LayerInfo.AddParameter "Fields", Flds ’复制字段列表 

LayerInfo.AddParameter "AutoCreateDataset", 1 
LayerInfo.AddParameter "datasetname", LayerName 
Set LyrTemp = MapTemp.Layers.Add(LayerInfo, 1) ‘复制到另外Map对象 

′删除源表 
Set Lyr = Nothing 
FilePath = MainMap.Layers.Item(I).Filespec 
LayerName = Mid(FilePath, InStr(1, FilePath, "Maps" + 6, Len(FilePath) - InStr(1, FilePath, "Maps") 
FilePath = Mid(FilePath, 1, InStr(1, FilePath, "Maps" + 5) 
LayerName = Mid(LayerName, 1, Len(LayerName) - 4) 

MainMap.Layers.Remove (I) 
MainMap.Refresh 

Kill FilePath + LayerName + ".TAB" 

′复制临时表数据到源表 
Set LyrTemp = MapTemp.Layers.Item(LayerName) 

LayerInfo.Type = miLayerInfoTypeNewTable 
LayerInfo.AddParameter "FileSpec", FilePath + LayerName + ".TAB" 
LayerInfo.AddParameter "NAME", LayerName 
LayerInfo.AddParameter "Features", LyrTemp.AllFeatures 
LayerInfo.AddParameter "Fields", Flds 

LayerInfo.AddParameter "AutoCreateDataset", 1 
LayerInfo.AddParameter "datasetname", LayerName 
Set Lyr = MainMap.Layers.Add(LayerInfo, 1) 

′删除临时表 
MapTemp.Layers.Remove (MapTemp.Layers.Count) 
MapTemp.Refresh 
Next 

Set Lyr = Nothing 
Set Ds = Nothing 
Set Flds = Nothing 
Set LayerInfo = Nothing 

八、如何和大型数据库关联 


系统是混合结构:对地图的访问使用的是文件访问方式,对属性数据的访问使用的是大型数据库形式使用ID关联:在TAB表和数据库中有ID字段,两个字段作为唯一值关联字段。(一对一的关系)。示例: 

Lyr.KeyField=”ID” 
Set Ftr=Ftrs.Item(J) 

‘SQL语句查找对应的属性信息 
SampleAdo.RecordSource =”Select a.id as id,b.name as name from Table1 a, Table2 b WHERE (a.id=b.id) AND ( a.id LIKE ‘%“ +Ftr.Keyvalue+“%’)” 

九、空间数据库 

2 空间数据库中的索引技术用的是R_Tree技术,而不是原来一般意义上的B_Tree索引技术。 
2 空间数据在Spatial中以地理属性信息形式存放。 
2 在Oracle的版本中有如下需要注意事项: 
a) Oracle 8.1.5这个版本中,首次引入Spatial组件。使用上非常不好:图形的样式非常单一,且为黑白的而非彩色,上载地图数据时,数据丢失非常严重。存取数据时非常慢。在Spatial中自动创建prinx字段作为地图索引主关键字段 
b) Oracle 8.1.6版本:图形为彩色的,增加了样式的支持,但不支持同一图层下的多样式(主要指点对象)。创建地图数据时,地图的坐标常发生偏移。属性数据更新时,需要两次刷新才能完整提交;地图数据数据提交时,其坐标发生偏移:向原点偏移,需要认为地单独将其移动到其初始创建位置。存取速度上还是比较慢,离实用尚有一定距离。在Spatial中自动创建mi_prinx字段作为地图索引主关键字段 
2 Oracle 8.1.7版本:支持多样式,数据上载丢失非常小(只有文本对象存在丢失的记录)。在地图数据存取不是很大的时候,速度上可以被用户接受。 
2 如何将MapInfo 的TAB表内容上传到Oracle 中? 
a) 免费工具:easyloader6.7(Oracle 8.1.7),下载地址http://www.mapinfo.com.cn /;
b) 如何上载?注意:上载之前对Tab表进行紧缩。 
c) 在程序中如何使用空间数据库中的地图数据? 
d) 添加地图时,必须指定字段mi_prinx的明确值,且该值不能为表中已存在的值。写入地图数据时,应将其全部NOT NULL 字段值赋给,否则保存失败。 
e) 示例:Tab表+空间数据表 的数据分布形式。 

十、GIS应用的分发 


1、 制作你自己的系统的安装盘:可执行文件、必要系统文件、运行库文件、其他数据文件。 
2、 单独的MapX安装盘:MapInfo MapX Runtime安装程序,实际上是MapX控件安装程序(存在于MapX sdk包) 
3、 注册:安装完成以后,运行GeosetManager40.exe程序获得硬件ID号,然后通过EMAIL的形式将该ID号发送到MapX产品供应商申请正式的许可文件(mapx40.lic)。获得后覆盖原mapx40.lic文件即可。注意:硬盘格式化后该ID号失效。 

十一、构造一个GIS应用系统 


需求:鹰眼功能、拓扑关系、不同图形不同颜色表现、数据绑定、系统性能。 

结构分析:做基于TAB文件的GIS系统 
1、 鹰眼功能 
(1) 建立两个Form对象,将两个Map对象分别放在这两个窗口对象中。 
(2) 一个小窗口作为鹰眼窗口,大 窗口作为主地图窗口。鹰眼窗口中的Map对象的视野应很大,而主地图窗口的视野根据需要设置。 
(3) 两个窗口中加载不同的GST文件。需要的是主地图窗口的显示范围应为鹰眼窗口中某个矩形所包含的地图对象范围。 
(4) A、在鹰眼窗口中画一个矩形(Rect为矩形对象),B、主地图窗口执行 Set MainMap.Bounds = Rect 
(5) 需要注意的是:鹰眼窗口与主地图窗口两者间的坐标投影系统应完全一致。 

2、 拓扑关系 
实际上就是图元与图元的空间关系。说历史:原来建立拓扑关系使用的是属性关联。 
点查询、圆查询、矩形查询、多边形查询等这些是属于简单空间关系的对比。而对拓扑关系的查询多数情况下使用Parts对象来解决。 
Ftr1与另一个Ftr2的空间关联:先找到Ftr1的其止节点,然后以这个节点为中心画一个非常小的圆,在这个圆范围内的某个设备可认为与该Ftr1相连。 
判断某个图元在指定图层上的相交对象集合: 
Set Ftrs=Lyr.SearchWithinFeature (SearchFtr, miSearchTypePartiallyWithin) 

3、 不同图形不同颜色表现 
(1)更新样式 再结合临时图层就可以很好解决(使用图层刷新)。而且刷新时不会引起整个Map对象的刷新(屏幕抖动) 
(2)专题图 存在更新属性值后不能实时刷新专题图的问题。 
4、 数据绑定 
对未绑定的属性集合使用 MainMap.Datasets.ADD 
地图集合和属性集合为一个数据集合的不可分割的两个部分 
5、 系统性能 
速度是否为用户所接受、系统是否稳定(界面要求)、修改数据数据的时候是否存在数据一致性维护问题、造价是否合理。 
(1)速度:使用数据分布可以较好地解决:地图数据:地形图数据以文件形式存放,业务地图数据存放在空间数据库中;属性数据:全部存放在大型数据库中。 

(2)系统是否稳定(界面要求):A、字段全部用英文,B、地图拓扑关系在进入系统以前进行必要的验证,C、文件地图数据中字段数减少到最小,可使访问属性频率大大减少,可有效保证其他用户访问时不会大量出现访问拒绝的现象;D、数据提交时尽可能采用事务机制: 事务开始: Lyr.BeginAccess,事务结束:Lyr.EndAccess;E、数据修改提交时尽可能采用批量提交。至于界面要求,应主要满足从地图对象获取相关的要求。 
(3)数据一致维护:遵循图元优先的原则。图形对象必须首先存在,其他相关信息在此基础上建立。注意: 
2 修改时应先修改地图对象,后提交属性信息 
2 删除时应先删除其他信息,最后删除图形信息 
(4)造价 这里主要指平台费用。A、现有数据格式,B、功能要求:空间分析是否复杂、地图图层是否分散、系统中地图输出的质量要求、系统中统计分析复杂程度是否较繁琐、直接的平台使用用户数(并发数)。