图2—5 地址匹配对象类
三、地图与图层操作
在MO中,Map Control(地图控件)是一个载体,可以在地图控件上增加一个或多个图层。Mo支持三种类型图层:矢量图层、栅格图层和动态(Tracking)图层,所对应的对象分别为MapLayer、ImageLayer和TrackingLayer。
矢量图层和栅格图层分别用于显示矢量数据和栅格数据,栅格图层和动态图层的集合所对应的对象为Layers(图层集合对象)。
动态图层用于显示动态数据,如通过GPS采集到的车辆移动中的位置数据。在TrackingLayer层显示的对象称为GeoEvent对象。当在窗体中增加一个地图控件时,就会有一个TrackingLayer层,这时,没有GeoEvent对象,GeoEvent对象的EventCount属性为0。 1、 增加矢量图层
矢量图层是和具体的数据相关联,要增加矢量图层,首先要确定(连接)对应的数据。连接的方法是利用DataConnection和GeoDataset两个对象。
DataConnection对象表示与包含shapefiles的文件夹或包含SDE数据库的服务器的连接。如要连接到包含shapefiles的文件夹,把DataConnection对象的Database属性设置为文件夹名(字符串,包括路径),然后应用Connect方法,如果返回值为True,表明连接成功。如要连接到SDE数据库,则需要设置数据库、口令、服务器和用户特性,然后应用Connect方法检查是否连接成功。
如果连接成功,就可以利用FindGeoDataset方法把文件夹中的一个shapefile文件或SDE数据库中的一个层的数据赋给新创建图层的GeoDataset。
接着,在图层集合中增加该图层。
以下的代码显示在地图控件中增加矢量图层。 Dim dConn As New MapObjects2.DataConnection Dim mLayer As New MapObjects2.MapLayer dConn.Database = \
Set mLayer.GeoDataset = dConn.FindGeoDataset(\ Map1.Layers.Add mLayer
2、增加栅格图层
增加图像文件相对简单,只要声明一个新的Imagelayer对象,利用Imagelayer对象的File属性确定对应的图像文件,再在图层集合对象中利用Add方法增加该Imagelayer对象。
Dim iLayer As New ImageLayer iLayer.File = \
Map1.Layers.Add iLayer
3、Tracking层的操作
利用AddEvent方法可在Tracking层中增加一个新的GeoEvent对象: TrackingLayer.AddEvent(shape,SymbolIndex)
Shape可以是点、线、多边形等图形对象,SymbolIndex是TrackingLayer符号列表中符
号索引,0表示缺省符号。
下面的代码将在Tracking层中增加一个新的GeoEvent对象。 Dim pt As New MapObjects2.Point pt.X = Rnd pt.Y = Rnd
Map1.TrackingLayer.AddEvent pt, 0 下面的代码将演示动态显示图形。
1)利用Timer控件的Interval属性来控制执行操作的时间间隔。Interval的单位为ms,即千分之一秒。
Private Sub Form_Load() Timer1.Interval = 1000
End Sub
Private Sub Timer1_Timer()
Dim pt As New MapObjects2.Point pt.X = Rnd pt.Y = Rnd
Map1.TrackingLayer.AddEvent pt, 0 End Sub
Rnd函数返回0和1之间的随机数。如要清除前面的点,增加Map1.TrackingLayer.ClearEvents
在窗体上设置两个按钮,可以启动和暂停动态显示。 Private Sub Command1_Click() Timer1.Enabled = True End Sub
Private Sub Command2_Click() Timer1.Enabled = False End Sub
4、利用对话框选择需要增加的图层
增加Visual Basic的CommonDialog控件(Microsoft Common Dialog Control 6.0)以便确定文件的路径和文件名。双击“增加图层”按钮进行编程。增加以下的Visual Basic语句。 Private Sub Command1_Click() Dim dc As New DataConnection
Dim gs As GeoDataset
Dim name As String
Dim layer As New MapObjects2.MapLayer CommonDialog1.Filter = \ CommonDialog1.ShowOpen dc.Database = CurDir
Name = CommonDialog1.FileTitle Set gs = dc.FindGeoDataset(name) layer.GeoDataset = gs Map1.Layers.Add layer End Sub
执行程序,点击增加图层按钮,并选择所要显示的Shape文件,选择的图层将显示在地图中。
CurDir[(Drive)],指定一个存在的驱动器。如果没有指定驱动器,或drive是零长度字符串(“”),则CurDir会返回当前驱动器的路径。
5、 利用图例操作图层
在工程/部件下选中ESRI MapObjects Legend Control,图例控件将显示在控件栏中。利用图例控件在Form上画图例框架。
1)利用legend1.setMapSource Map1使图例与相应的地图控件关联。
2)当增加图层或删除图层时,利用legend1.LoadLegend True更新图例。 3)当在图例上设置图层可见或不可见时,利用Map1.Refresh刷新地图。 Private Sub Form_Load() legend1.setMapSource Map1
End Sub
Private Sub Map1_AfterLayerDraw(ByVal index As Integer, ByVal canceled As Boolean, ByVal hDC As stdole.OLE_HANDLE)
legend1.LoadLegend True End Sub
Private Sub legend1_AfterSetLayerVisible(Index As Integer, isVisible As Boolean) Map1.Refresh
End Sub
程序运行后,在图例框架上将显示各个图层,通过拖动图层可以改变图层的显示顺序,点击图层的复选框可以设置图层是否可见。
删除选中图层
Dim n As Integer
n = legend1.getActiveLayer Map1.Layers.Remove (n)
四、坐标系
1、控件坐标和地图坐标
地图控件的坐标系与VB窗体的坐标系一样,原点在左上角,从左到右,x坐标逐渐增加;从上到下,y坐标逐渐增加。坐标的缺省单位为twip。当我们定义了一个地图控件,该控件的坐标范围将保持不变。
地图坐标系是笛卡尔坐标系,从左到右,x坐标逐渐增加;从下到上,y坐标逐渐增加。地图控件的地图坐标范围不是固定的,随着地图的放大、缩小和漫游发生变化。
根据地图控件的坐标范围以及地图的坐标范围,我们可以对控件坐标和地图坐标进行转换。
控件坐标转为地图坐标,利用ToMapPoint方法。
地图坐标转为控件坐标,利用FromMapPoint方法。
Dim mapx As Single Dim mapy As Single
Text1.Text = \
mapx = Map1.ToMapPoint(X, Y).X
mapy = Map1.ToMapPoint(X, Y).Y
Text2.Text = \
2、显示矢量图层的坐标系信息
矢量图层的坐标系信息保存在prj文件中,它记录坐标系类型(地理坐标或投影坐标)、Datum、单位等信息。
利用MapLayer的CoordinateSystem属性可得到GeoCoordSys对象或ProjCoordSys对象,可通过返回对象的IsProjected属性来判断是GeoCoordSys对象还是ProjCoordSys对象。
如是GeoCoordSys对象,通过该对象的Datum属性得到Datum对象,进一步可得到Datum的详细信息;同样可以得到Unit等其它属性的详细信息。
如是ProjCoordSys对象,通过该对象的GeoCoordSys属性得到投影前的地理坐标系信息;利用Projection属性得到有关的投影信息,同样可以得到其它属性的详细信息。
下面的代码是在文本框中显示图层的相关坐标系信息。
Dim ly As MapObjects2.MapLayer
Dim gcs As New MapObjects2.GeoCoordSys Dim pcs As New MapObjects2.ProjCoordSys Set ly = Map1.Layers(0)
If ly.CoordinateSystem.IsProjected Then Set pcs = ly.CoordinateSystem Text1.Text = \投影坐标系\
Text2.Text = pcs.GeoCoordSys.Datum.Name Text3.Text = pcs.Unit.Name
Text4.Text = pcs.Projection.Name Else
Set gcs = ly.CoordinateSystem Text1.Text = \地理坐标系\ Text2.Text = gcs.Datum.Name Text3.Text = gcs.Unit.Name Text4.Text = \ End If
3、改变Map控件的坐标系
改变Map控件的坐标系将使控件中的地图以新的坐标系来显示。
改变Map控件坐标系的方法是先定义一个坐标系对象(GeoCoordSys对象或ProjCoordSys对象),然后赋与Map控件的CoordinateSystem属性。
下面的代码是把Map控件的坐标系改变成地理坐标系(图4—1)。
Dim gcs As New MapObjects2.GeoCoordSys gcs.Type = moGeoCS_WGS1984 Map1.CoordinateSystem = gcs Text1.Text = \地理坐标系\ Text2.Text = gcs.Datum.Name Text3.Text = gcs.Unit.Name
Text4.Text = \
下面的代码是把Map控件的坐标系改变成投影坐标系(图4—2)。 Dim pcs As New MapObjects2.ProjCoordSys pcs.Type = moProjCS_World_WinkelII Map1.CoordinateSystem = pcs Text1.Text = \投影坐标系\
Text2.Text = pcs.GeoCoordSys.Datum.Name Text3.Text = pcs.Unit.Name
Text4.Text = pcs.Projection.Name
图4—1 Map控件的坐标系改变成地理坐标系
图4—2 Map控件的坐标系改变成投影坐标系
五、地图显示范围操作 1、 地图显示范围
在Map控件上显示的地图范围可以通过Map控件的Extent属性来得到和设置。Map控件的“Extent”属性返回rectangle对象,反映在Map控件中显示的地图范围,由Top(左上角y坐标)、Left(左上角x坐标)、Bottom(右下角y坐标)和Right(右下角x坐标)四