1、MapObejcts 组件应用设计 (地图数据的创建与编辑)2.6.1 Recordset 对象Recordset 是 MapObjects 中的一个对象,它为图层(MapLayer)提供地图数据,又是地图数据的管理者与操作者,因此,地图数据的创建和编辑在 Recordset 上进行。每个 MapLayer 对应一个 Recordset,仅对应一个 Recordset,是 Recordset 的可视化。从数据库的观点看,Recordset 是一个数据表,概念与数据表一致,图形数据储存在表的一个字段(shape)中。Recordset 是记录的集合 ,提供了对记录及字段的操作方法。ShapeFi
2、le 是 ESRI 公司定义的一种无拓扑关系的地理信息文件格式,是MapObjects 固有数据格式,在这种格式上实现了读写、修改、编辑功能。ShapeFile 用一组文件储存一个图层数据,同一图层各文件的主名相同,用作图层名。扩展名标识文件的内容,分别是:.shp 储存几何要素.shx 储存几何要素索引.dbf 储存几何要素的属性数据,是 dBase 文件,可用 FoxPro 软件操作这一组文件映射成一个 Recordset 表。表中含有.dbf 文件的全部字段,还有两个由 Recordset 对象添加的字段:Shape 和 FeatureID。两个添加字段的值来自于文件.shp 和.shx
3、。例如,china 图层的三个组成文件是:china.shp,china.shx,china.dbf。china.dbf的字段名是:name , gdp1990 , gdp1995 ,那么,Recordset 形成的表是:Shape FeatureID Name gdp1990 gdp1995Polygon 1 新疆 121 190Polygon 3 河北 221 440Recordset 对象封装了表及在表上的操作,在 Recordset 中,表的一行称为一个记录,表的一列称为一个字段,列的名称称为字段名。在这个例子中,有5 个字段,2 个记录。第一行是字段名行,不是记录。shape 字段的
4、每一个值是一个几何图形元素,用几何对象定义。FeatureID是图形元素的索引号。Shape 、FeatureId 是 Recordset 对象生成的标准字段,对于Coverage、SDE、CAD、VPF 等格式数据形成的 Recordset 表也是如此。1 Recordset 表的记录指针Recordset 表从概念上看,是记录的集合。记录是集合中的成员,用指针确定在表中的位置。在表中移动指针可以定位记录。例 1 Map1 中含有 china 图层,属性如前表所示。编程显示属性表中的数据(完整程序见 recordPointer 目录)。Private Sub Command1_Click()
5、 记录指针定位Dim recs As MapObjects2.RecordsetSet recs = Map1.Layers(“china”).Recordsrecs.MoveFirst 指针指向记录 1Debug.Print recs.Fields(“name”).Value, recs.Fields(“gdp1995”).Value 输出: 新疆190recs.MoveNext 指针指向记录 2recs.MoveNext 指针指向记录 3Debug.Print recs.Fields(“name”).Value, recs.Fields(“gdp1995”).Value 输出:河北 440
6、End SubRecordset 的指针定位方法:recs.MoveFirst 指针指向记录 1 开始位置recs.MoveNext 指针指向下一条记录开始位置recs.MovePrevious 指针指向前一条记录开始位置recs.EOF 指针指向最后一条记录的末端时返回 TRUE,否则返回 FALSE2 编辑属性表已有数据编辑记录在 Recordeset 对象上进行,每次编辑一条记录,程序设计顺序依次是:(1) 移动记录指针到要编辑的记录(2) 读取当前记录到缓冲区中(3) 编辑修改当前记录字段的值(4) 更新当前记录(5) 全部记录编辑完后,停止编辑例 2 编辑 China 属性表,将 g
7、dp1995 字段的值增加 1(完整程序见recordPointer 目录)。Private Sub Command2_Click() 编辑记录中的属性数据Dim recs As MapObjects2.RecordsetDim fld As MapObjects2.FieldSet recs = Map1.Layers(“china”).RecordsSet fld = recs.Fields.Item(“gdp1995”) 引用记录的字段recs.MoveFirst 定位到记录 1If recs.Updatable Then recs 是可编辑的吗?Do Until recs.EOF 记录
8、指针指向最后记录的末尾了吗?recs.Edit 读取一条记录到缓冲区中fld.Value = fld.Value + 1 修改缓冲区中记录的的一个字段值recs.Update 更新修改的记录recs.MoveNext 记录指针移到下一条记录Looprecs.StopEditing 停止编辑End IfEnd Sub将上面的 recs.Update 语句替换成 recs.CancelUpdate ,则记录编辑无效。3 添加新记录添加新记录在 MapLayer.Rcords 属性上进行,此属性的数据类型是 Recordset,实际是在 Recordset 对象上进行。使用 Recordset.Ad
9、d 方法每次编辑一条记录,程序设计顺序依次是:(1) 移动记录指针到给定的记录。(3) 添加一条新记录 ,这时记录在内存记录缓冲区中。(2) 为新记录字段赋值。(3) 用 Update 方法更新数据表,这时缓冲区的数据写入文件缓冲区。(4) 全部添加完后,用 StopEding 方法停止编辑。这时文件缓冲区的数据写入文件。例 3 手工将 Chian 图层的文件复制成 EditData 图层。设计程序,用鼠标输入一个 Polygon,在 EditData 图层中添加一个新记录,将新记录的 shape 字段值设置成输入的 Polygon,将 name 字段值设置成”新记录”。完整程序见 NewDe
10、lRd 目录,重要代码如下:Private Sub Command1_Click() 添加新记录Dim recs As MapObjects2.RecordsetDim fld As MapObjects2.FieldSet recs = Map1.Layers.Item(“EditData”).Records 获得记录集的引用Set fld = recs.Fields(“Shape”) 获得图形字段的引用Dim poly As MapObjects2.PolygonSet poly = Map1.TrackPolygon 用鼠标画一个多边形If recs.Updatable Thenrecs
11、.MoveFirstrecs.AddNew 添加一个新记录Set fld.Value = poly 将新记录的图形字段设置为画的多边形recs.Fields.Item(“Name”).Value = “新记录” 设置新记录 Name 字段的值recs.Update 更新数据表recs.StopEditing 编辑结束Map1.Refresh 地图窗口刷新End IfEnd Sub4 删除记录例 4 删除上例中添加的记录(完整程序在 NewDelRd 目录中)。Private Sub Command2_Click() 删除 name = “新记录” 的记录Dim recs As MapObjec
12、ts2.RecordsetSet recs = Map1.Layers.Item(“EditData”).Records 获得记录集的引用If recs.Updatable Thenrecs.MoveFirst 移动记录指针到第一个记录Do Until recs.EOF 遍历记录集If recs.Fields.Item(“Name”).Value = “新记录” Then 判断删除条件recs.Edit 使当前记录可编辑recs.Delete 删除当前记录End Ifrecs.MoveNext 移动记录指针到下一个记录Looprecs.StopEditing 编辑结束Map1.Refresh
13、地图窗口刷新End IfEnd Sub5 FeatureIDFeatureID 是 Recordset 表的字段名,是 shape 字段中几何图形元素的编号,编号是从 1 开始的自然数。在 Recordset 表中,可以读出 FeatureID 的值,例如:recs.MoveFirstDebug.Print recs.Fileds.Item(“FeatureID”).Value 输出: 12.6.2 创建数据库表1 定义并创建一个新表例 1 在 Form_Load 中建立了 dc 与数据库”china2”的连接。创建一个数据库表,命名为 MyTable,除了两个标准字段以外,表中还含有三个附加
14、字段,字段定义如下:字段名 类型 宽度 小数位数Name 字符型 16Area 数值型 15 3Perimeter 数值型 15 13在表中添加两个记录,给三个属性字段赋值。用鼠标绘制两个 Polygon, 赋给表的 Shape 字段。最后将 MyTable 保存在 China2 数据库中( 完整程序见 CreatTable目录中工程)。Dim dc As MapObjects2.DataConnectionPrivate Sub Command1_Click() 创建数据库表Dim gds As MapObjects2.GeoDatasetDim desc As New TableDesc
15、数据库表字段描述Dim lyr As New MapObjects2.MapLayerDim poly As MapObjects2.PolygonWith desc 定义表的三个附加属性域.FieldCount = 3.FieldName(0) = “Name” 分别设置 3 个域的名称.FieldName(1) = “Area”.FieldName(2) = “Perimeter”.FieldType(0) = moString 域的数据类型.FieldType(1) = moDouble.FieldType(2) = moDouble.FieldLength(0) = 16 字符串的长度
16、.FieldPrecision(1) = 15 数字的位数.FieldPrecision(2) = 15.FieldScale(1) = 3 小数点之后的位数.FieldScale(2) = 3End WithSet gds = dc.AddGeoDataset(“MyTable”, moPolygon, desc) 在数据源中加入表If gds Is Nothing Then Exit Sub 文件非法,则退出Set lyr.GeoDataset = gds 设置图层的地理数据集Map1.MousePointer = moCrossFor i = 1 To 2Set poly = Map1.
17、TrackPolygon 用鼠标在地图窗口中画一个多边形With lyr.Records.AddNew 添加一个记录.Fields(“Shape”).Value = poly 为图形字段赋值.Fields(“Name”).Value = “多边形 “ & i.Fields(“Area”).Value = poly.Area.Fields(“Perimeter”).Value = poly.Perimeter.UpdateEnd WithNextlyr.Records.StopEditing 记录集修改完毕,保存表记录的数据Map1.MousePointer = moDefaultMap1.La
18、yers.Add lyr Map1.Refresh 在地图窗口中显示绘制的两个多边形End Sub从上段程序中摘取的语句:Set gds = dc.AddGeoDataset(“MyTable”, moPolygon, desc) Set lyr.GeoDataset = gds lyr.Records .AddNew lyr.Records.StopEditing 代表了完成这个例题的基本步骤。注意其中揭示的 GeoDataset 与 Recordset 之间的关系。2 创建子集数据库表例 2 用鼠标画一个矩形,从 China 图层上提取位于矩形区中的记录集,保存提取的记录集,形成一个数据库
19、表(完整程序见 SubTable 目录中的工程)。Private Sub Command1_Click() 创建子集数据库表Dim gds As MapObjects2.GeoDatasetDim rect As MapObjects2.RectangleDim recs As MapObjects2.RecordsetDim lyr As New MapObjects2.MapLayerMap1.MousePointer = moCrossSet rect = Map1.TrackRectangle 用鼠标拖拉出一个矩形Map1.MousePointer = moDefaultSet rec
20、s = Map1.Layers.Item(“Province”).SearchShape(rect, moAreaInTersectt, “”) 提取矩形区中的记录集Set gds = recs.Export(“c:/temp/SubTable”) 保存,形成子集数据库表 (ShapeFile 格式)Set lyr.GeoDataset = gds 图层引用地理数据集lyr.Symbol.Color = moRed 用红颜色显示此图层Map1.Layers.Add lyr 图层添加到地图窗口中Map1.Refresh 地图窗口刷新End Sub习题1 编写程序实现例 1、例 2 的功能2.6.
21、3 TrackingLayer 图层与 GeoEvent 对象1 TrackingLayer 图层与前面讲述的 MapLayer 及 ImageLayer 不同,跟踪图层 TrackingLayer 不属于 Layers 集合。在绘制完 Layers 集合中的全部图层后,才绘制 TrackingLayer图层中的内容。TrackingLayer 图层是 Map 控件的属性,可在其中动态显示不断改变位置的的图形,每个图形是一个 GeoEvent 实例,不必重绘 Layers 集合中的图层,即可实现 GeoEvent 实例在图上移动,因此具有很高的更新速度。通过TrackingLayer.Refr
22、esh 方法可以触发跟踪层的重绘,同时还触发BeforeTrackingLayerdraw 和 AferTrackingLayerDraw 事件。跟踪层中的 GeoEvent 实例没有保存在数据文件中,程序退出后立即消失。2 GeoEvent 对象保存在 TrackingLayer 图层中的图形元素是 GeoEvent 对象的实例。MapObjects Shape 的实例均可作为 TrackingLayer 上的 GeoEvent 实例,因此TrackingLayer 图层可以同时储存显示多种类型的图元。 GeoEvent 实例绘图使用TrackingLayer 中自定义的 Symbol 属性
23、数组中的符号,每个 GeoEvent 实例可以储存一个标记,用来在运行时与其它 GeoEvent 实例区别。这个标记还可以用于连接外部数据库中的记录。GeoEvent 实例在 TrackingLayer 层中显示,位置可以快速动态改变而不影响地图窗口中的其它图层,特别适用于在地图窗口中显示汽车、飞机、GPS 接收机等的动态位置。3 TrackingLayer 图层的属性和方法以下描述中的例句假设 Map1 是 VB 窗体上的 MapObjects2.Map 实例(1) Function Trackinglayer.AddEvent(Object As Object,SymbolIndex As
24、 Long) As GeoEvent函数向跟踪层中加入一个几何要素。下面的语句在 TrackingLayer 层中加入一个点,创建 GeoEven 点事件。Dim pt As MapObjects2.PointMap1.TackingLager.AddEvent pt , 0 用 AddEvent 方法加入一个事件时,同时指定了事件使用的数组TrackingLayer.Symbol 中的符号,如上面的代码所示,AddEvent 的第二个参数SymbolIndex 为 pt 指定了显示用的符号 TrackingLayer.Sybmol(0)。(2) Property Event(Index As
25、 Long) As GeoEvect只读属性,返回跟踪层中 GeoEvent 的引用。Event 数组中的元素是 GeoEvet 实例,使用 GeoEvent 的方法编程,例如:Map1.TrackLingLayer.Event(3).Move x,y 使用相对坐标移动Map1.TrackLingLayer.Event(2).MoveTo x ,y 使用绝对坐标移动Map1.TrackLingLayer.Event(3).SymbolIndex = 1 设置使用的绘图符号在Symbo 数组中的索引Geoevents 存储在 TrackingLayer.Event(n)数组中, n 的值是属性T
26、rackingLayer.EventCount,数组索引从 0 开始。GeoEvent 在数中的索引号按加入跟踪层的顺序从小到大排列,删除一个之后,后续元素的索引号全部减 1。(1) Property Symbol(Index As Long) As Symbol只读属性,返回 Symbol 实例的引用,(4) SymbolCout As Long属性 SymbolCout 表示 Symbol 数组中元素的个数。执行语句Map1.TrackingLayer.SymbolCount = 10将为跟踪层创建含有 10 个元素的 Symbol 数组,在使用 Symbol 数组之前,必须执行此语句。(
27、5) 删除跟踪层中的 GeoEvent 实例Map1.TrackingLayer.RemoveEvent 2 删除索引号为 2 的 GeoEventMap1.TackingLayer.ClearEvents 删除全部 GeoEvent例 1:创建两个点符号,储存在跟踪层的 Symbol 数组中,在鼠标光标点击位置创建 GeoEvent 点实例,用 Symbol(0)显示。1) 创建 Symbol数组Private Sub SetTrackingLayerSymbol() 建立跟踪层显示符号设置 PointEvents 在跟踪层中得显示符号Map1.TrackingLayer.SymbolCou
28、nt = 2 定义 Symbol 数组为 2 个元素,下标从 0 开始Map1.TrackingLayer.Symbol(0).Color = moRedMap1.TrackingLayer.Symbol(0).Style = moCircleMarkerMap1.TrackingLayer.Symbol(0).SymbolType = moPointSymbolMap1.TrackingLayer.Symbol(0).Size = 6Map1.TrackingLayer.Symbol(1).Color = moDarkMap1.TrackingLayer.Symbol(1).Style =
29、moCircleMarkerMap1.TrackingLayer.Symbol(1).SymbolType = moPointSymbolMap1.TrackingLayer.Symbol(1).Size = 6End Sub2) 创建 GeoEvent点事件Sub AddEvent(x As Single, y As Single) 在跟踪层中加入一个点Set pt = Map1.ToMapPoint(x, y) 屏幕坐标变成地图坐标点Map1.TrackingLayer.AddEvent pt, 0 在跟踪层中加入一点,显示符号使用Symbol(0)End Sub3) 调用顺序在 Form
30、_Load() 中调用SetTrackingLayerSymbol()在 Map1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)中调用SelectEvents x, y例 2 利用上例中形成的点事件及 TrackingLayer.Symbol 数组,在 TackingLayer图层中,找出距离鼠标点击位置小于 55000 的点事件,用 Symbol(1)显示找出的点事件。Sub SelectEvents(x, y) 在当前鼠标位置查找距离 55000 的点事件Dim pt As MapObjec
31、ts2.PointSet pt = Map1.ToMapPoint(x, y)nEventCount = Map1.TrackingLayer.EventCount 跟踪层中的事件总数Dim testPt As New PointFor i = 0 To nEventCount - 1 遍历跟踪层事件Set evt = Map1.TrackingLayer.Event(i)testPt.x = evt.xtestPt.y = evt.yIf pt.DistanceTo(testPt) 55000 Then 距离使用地图坐标单位,若找到evt.SymbolIndex = 1 则使用 Symbol
32、(1)显示End IfNext iEnd Sub例 3 创建两个线符号,储存在跟踪层的 Symbol 数组中,在 Map1 地图窗口中用鼠标光标画折线,将折线加入到跟踪层中(称为 LineEvent),用Map1.Tracklayer.Symbol(3)显示。程序语句如下:1) 在跟踪层中建立 Symbol(2)Map1.TrackingLayer.Symbol(2).Color = moDarkMap1.TrackingLayer.Symbol(2).Style = moSolidLineMap1.TrackingLayer.Symbol(2).SymbolType = moLineSymb
33、olMap1.TrackingLayer.Symbol(2).Size = 32) 在 Map1 窗口中画线并加入跟踪层中Private Sub Map1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)AddLineEventA 在地图窗口中添加线事件End SubSub AddLineEventA() 在跟踪层中加入一条线Dim oLine As MapObjects2.LineSet oLine = Map1.TrackLine 画一条线If oLine Is Nothing Then Exi
34、t Sub在跟踪层中加入一以条线,显示符号使用 Symbol(2)Map1.TrackingLayer.AddEvent oLine, 2 End Sub例 4 在 Map1 窗口中用鼠标选择例 3 加入的线,用绿色显示选中的线。程序语句如下:1) 在跟踪层中建立显示用的 SymbolMap1.TrackingLayer.Symbol(3).Color = moGreen 绿色Map1.TrackingLayer.Symbol(3).Style = moSolidLineMap1.TrackingLayer.Symbol(3).SymbolType = moLineSymbolMap1.TrackingLayer.Symbol(3).Size = 32) 在 Map1.TrackingLayer 中查找距离鼠标点55000 的线,用绿色显示查到的线。Private Sub Map1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)SelectLineEvents x, y 查找与点(x,y)距离 55000 的线事件End SubSub SelectLineEvents(x, y) 在当前鼠标位置查找距离 55000 的线事件Dim pt As MapObjects2.Point
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。